Tank-bot
- Войдите на сайт для отправки комментариев
Представляю вам своего робота .
Робот умеет обходить препятствия (ИК датчик радарного типа).
Не падать со стола /лестницы и т.д. (датчик поверхности).
Включать/выключать фары автоматически (фоторезистор).
Так же на борту есть индикатор заряда аккумов - три светодиода.
Когда уровень заряда выше 60% - горит зеленый , когда ниже - горит желтый , когда ниже 15% - горит
красный , когда ниже 5% - красный мигает , отключаются маршевые двигатели , головня серва устанавливается по центру.
В таком состоянии логика и светодиоды будут работать около 3часов.
Так же реализовано управление по ИК (пульт от телека) , правда программа ИК на отдельном МК ,
но скоро я совмещу две программы .
Остальные фото здесь foto.mail.ru/mail/heruvim219/Tank-bot
Видео здесь video.mail.ru/mail/heruvim219/Tank-Bot
Если кому интересно , схему и программу выложу позже.
участник конкурса "Arduino 2012"
>Если кому интересно
Да как вы могли предположить, что на таком сайте не найдется хотя-бы одного человека которому будет интерестно?
Конечно интерестно.
А аккумы заряжаются где-то снаружи или могут "прямо на месте"?
А по поводу проекта: однозначно "браво"!
Аккумы заряжаются внешним зарядником (потому сверху и стоят).
Просто на плате уже особо места не было , что бы ставить , какой нибудь , lm317 для заряда.
А прогу выложу позже (откоментирую и выложу).
Кстати , подскажите какую нибудь простенькую прогу для рисования схем.
"Arduino 2012"
Это очень очень круто! Даже немного завидно (по хорошему) прямоте рук.
Если выложишь код для ознакомления, будет просто здорово.
Я правильно понял, что ИК датчик закреплен на поворачивающейся платформе?
Класс! Вы не против если я помещу краткое резюме, одну из фоток и ссылку на эту ветку в раздел проекты?
>Я правильно понял, что ИК датчик закреплен на поворачивающейся платформе?<
Датчик вращается на серве.
И по положению сервы определяет с какой стороны препятствие , если препятствие прямо перед ним - сдает назад и разворачивается.
>Вы не против если я помещу краткое резюме, одну из фоток и ссылку на эту ветку в раздел проекты? <
Нет , не против .
Только я , немного , не понял где именно вы хотите ее поместить ?
Спасибо. Сюда http://arduino.ru/projects
Почему то в сети мало проектов роботов на дуино.
Изначально мой ездил с дуиной на борту , потом я развел плату (только с шестого раза сделал рабочюю плату) и дуину убрал.
Выложу схему и прогу и на одного дуино бота станет больше.
Вот программа робота.
Довольно сыровата , но , по мере апгрейда робота , буду выкладывать новые версии.
В прграмме довольно много рандомных значений это дает небольшую непредсказуемость в движениях.
Дело в том что машина с "жесткой" программой движения часто , надолго , зависала
в неудобных местах - узких проходах и т.д.
001
#include <Servo.h> //библиотека для серво
002
Servo myservo;
//объект серво
003
volatile
int
state = LOW;
//пременная обрабатываемая прерыванием
004
005
006
int
pos=0;
//угол поворота сервы
007
int
val=0;
//время маневра в зависимости от заряда аккума
008
int
napravlenie=0;
//направление для разворота назад
009
int
povorot=0;
//задержка поворота
010
int
servospeed=0;
//скорость движения сервы
011
012
013
014
void
setup ()
015
{ pinMode(3,INPUT);
//датчик поверхности
016
pinMode(1,OUTPUT);
//сигнальный светодиод
017
pinMode(13,OUTPUT);
//мотор1
018
pinMode(12,OUTPUT);
//мотор1
019
pinMode(11,OUTPUT);
//мотор2
020
pinMode(10,OUTPUT);
//мотор2
021
pinMode(9,OUTPUT);
//частота на ИК светодиоды
022
pinMode(6,OUTPUT);
//индикатор заряда аккума желтый
023
pinMode(7,OUTPUT);
//индикатор заряда аккума красный
024
pinMode(8,OUTPUT);
//индикатор заряда аккума зеленый
025
pinMode(2,INPUT);
//головной TSOP
026
pinMode(19,INPUT);
//вход аккума - измерение уровня заряда
027
pinMode(17,INPUT);
//вход фоторезистора - включение фар
028
pinMode(18,OUTPUT);
//фары
029
attachInterrupt(0, blink, CHANGE);
//инициализация нулевого прерывания
030
031
randomSeed(analogRead(0));
//выбор случайного значения
032
myservo.attach(5);
//инициализация сервы
033
}
034
void
loop ()
035
036
{
037
038
039
if
(analogRead(17)<11)
//если на фоторезисторе меньше 9 то...
040
{
041
digitalWrite(18,HIGH);
//включаем фары
042
043
}
044
else
//если на фоторезисторе больше 9 то...
045
{
046
digitalWrite(18,LOW);
//выключаем фары
047
048
}
049
050
//************АККУМУЛЯТОР*************************//
051
052
053
if
(analogRead(19)>615)
//Если напруга выше 50%(3в на АЦП и выше) то...
054
{
055
digitalWrite(6,LOW);
056
digitalWrite(7,LOW);
057
digitalWrite(8,HIGH);
//включаем зеленый светодиод
058
val=0;
//время маневра + 0 мс
059
}
060
061
if
(analogRead(19)<615)
//Если напруга ниже 50%(от3 до 2.5в на АЦП) то...
062
{
063
digitalWrite(6,HIGH);
//включаем желтай светодиод
064
digitalWrite(7,LOW);
065
digitalWrite(8,LOW);
066
val=150;
//время маневра + 150 мс
067
068
069
070
if
(analogRead(19)<512)
//Если напруга ниже 15%(от2.5 до 2.37в на АЦП) то...
071
{
072
digitalWrite(6,LOW);
073
digitalWrite(7,HIGH);
//включаем красный светодиод
074
digitalWrite(8,LOW);
075
val=500;
//время маневра + 500 мс
076
}
077
078
}
079
//*****************МИНИМАЛЬНЫЙ ЗАРЯД**********************//
080
if
(analogRead(19)<=490)
//если напруга ниже 5% (2.35в и ниже)
081
{
082
digitalWrite(6,LOW);
083
digitalWrite(7,HIGH);
//мигаем красным светодиодом
084
digitalWrite(8,LOW);
085
086
digitalWrite(13,LOW);
087
digitalWrite(12,LOW);
//отключаем маршевые
088
digitalWrite(11,LOW);
//двигатели
089
digitalWrite(10,LOW);
090
091
delay(500);
092
digitalWrite(6,LOW);
093
digitalWrite(7,LOW);
//мигаем красным светодиодом
094
digitalWrite(8,LOW);
095
delay(500);
096
097
myservo.write(90);
//устанавливаем головной сервопривод
098
//в среднее положение
099
}
100
else
101
{
102
tone(9,38000);
//генерируем частоту для TSOPов 36Кгц
103
digitalWrite(1,LOW);
//сигнальный светодиод выключен
104
105
106
if
(analogRead(17)<11)
//если на фоторезисторе меньше 9 то...
107
{
108
digitalWrite(18,HIGH);
//включаем фары
109
110
}
111
else
//если на фоторезисторе больше 9 то...
112
{
113
digitalWrite(18,LOW);
//выключаем фары
114
115
}
116
117
118
119
//***********************ДВИЖЕНИЕ************************//
120
121
digitalWrite(13,HIGH);
//едем вперед
122
digitalWrite(12,LOW);
123
digitalWrite(11,LOW);
124
digitalWrite(10,HIGH);
125
126
127
//********************************************************************************//
128
//*******************ДВИЖЕНИЕ СЕРВЫ С ПРАВА НА ЛЕВО*******************************//
129
//*******************************************************************************//
130
131
servospeed=random(10,17);
//случайно выбираем скорость движения головной сервы
132
for
(pos = 30; pos < 150; pos +=3)
// с права на лево
133
{
134
myservo.write(pos);
//установка сервы на заданный угол
135
delay(servospeed);
//движение головной сервы
136
137
138
139
140
if
(digitalRead(3)==HIGH)
//если датчик поверхности не видит поверхности то ...
141
{
142
digitalWrite(1,HIGH);
//включаем сигнальный светодиод
143
144
145
digitalWrite(13,LOW);
//едем назад 500мс
146
digitalWrite(12,HIGH);
147
digitalWrite(11,HIGH);
148
digitalWrite(10,LOW);
149
delay(500+val);
//если уровень заряда аккума ниже 50% едем назад 650мс , если ниже 15% - 1000мс
150
151
152
napravlenie=random(0,6);
//случайно выбираем направление поворота
153
if
( napravlenie>3)
//если больше 3 то...
154
{
155
digitalWrite(13,HIGH);
//поворачиваем влево
156
digitalWrite(12,LOW);
157
digitalWrite(11,HIGH);
158
digitalWrite(10,LOW);
159
delay(500+val);
//если уровень заряда аккума ниже 50% едем назад 650мс , если ниже 15% - 1000мс
160
}
161
else
//если меньше 3 то...
162
{
163
digitalWrite(13,LOW);
//поворачиваем вправо
164
digitalWrite(12,HIGH);
165
digitalWrite(11,LOW);
166
digitalWrite(10,HIGH);
167
delay(500+val);
//если уровень заряда аккума ниже 50% едем назад 650мс , если ниже 15% - 1000мс
168
}
169
170
171
}
172
173
174
175
176
177
if
(state==HIGH&&(pos>=30&&pos<=85))
//если сработал TSOP и угол сервы от 30 до 85град. то...
178
{
179
180
povorot=random(0,100);
//случайно выбираем время завершения поворота
181
digitalWrite(13,LOW);
//поворачиваем вправо
182
digitalWrite(12,HIGH);
183
digitalWrite(11,LOW);
184
digitalWrite(10,HIGH);
185
delay(povorot);
//время поворота
186
187
}
188
189
if
(state==HIGH&&(pos>=85&&pos<=95))
//если сработал TSOP и угол сервы от 85 до 95град. то...
190
191
{
192
193
194
digitalWrite(13,LOW);
//сдаем назад
195
digitalWrite(12,HIGH);
196
digitalWrite(11,HIGH);
197
digitalWrite(10,LOW);
198
delay(1000+val);
//если уровень заряда аккума ниже 50% едем назад 650мс , если ниже 15% - 1000мс
199
200
201
digitalWrite(13,HIGH);
//поворачиваем влево
202
digitalWrite(12,LOW);
203
digitalWrite(11,HIGH);
204
digitalWrite(10,LOW);
205
delay(500+val);
//если уровень заряда аккума ниже 50% едем назад 650мс , если ниже 15% - 1000мс
206
207
208
}
209
210
if
(state==HIGH&&(pos>=95&&pos<=150))
//если сработал TSOP и угол сервы от 95 до 150град. то...
211
212
{
213
povorot=random(0,100);
//случайно выбираем время завершения поворота
214
digitalWrite(13,HIGH);
//поворачиваем влево
215
digitalWrite(12,LOW);
216
digitalWrite(11,HIGH);
217
digitalWrite(10,LOW);
218
delay(povorot);
//время поворота влево
219
}
220
221
222
223
}
224
225
226
227
228
//********************************************************************************//
229
//*******************ДВИЖЕНИЕ СЕРВЫ С ЛЕВА НА ПРАВО*******************************//
230
//*******************************************************************************//
231
232
233
234
servospeed=random(10,17);
//случайно выбираем скорость движения сервы
235
for
(pos = 150; pos >30; pos -=3)
// с лева на право
236
{
237
myservo.write(pos);
//угол поворота сервы
238
delay(servospeed);
//время поворота сервы
239
240
241
242
if
(digitalRead(3)==HIGH)
//если датчик поверхности не видит поверхности то ...
243
{
244
digitalWrite(1,HIGH);
//включаем сигнальный светодиод
245
246
247
digitalWrite(13,LOW);
//едем назад 500мс
248
digitalWrite(12,HIGH);
249
digitalWrite(11,HIGH);
250
digitalWrite(10,LOW);
251
delay(500+val);
//если уровень заряда аккума ниже 50% едем назад 650мс , если ниже 15% - 1000мс
252
253
254
napravlenie=random(0,6);
//случайно выбираем направление поворота
255
if
( napravlenie>3)
//если больше 3 то...
256
{
257
digitalWrite(13,HIGH);
//поворачиваем влево
258
digitalWrite(12,LOW);
259
digitalWrite(11,HIGH);
260
digitalWrite(10,LOW);
261
delay(500+val);
//если уровень заряда аккума ниже 50% едем назад 650мс , если ниже 15% - 1000мс
262
}
263
else
//если меньше 3 то...
264
{
265
digitalWrite(13,LOW);
//поворачиваем вправо
266
digitalWrite(12,HIGH);
267
digitalWrite(11,LOW);
268
digitalWrite(10,HIGH);
269
delay(500+val);
//если уровень заряда аккума ниже 50% едем назад 650мс , если ниже 15% - 1000мс
270
}
271
272
273
}
274
275
276
277
278
279
280
281
282
283
if
(state==HIGH&&(pos>=95&&pos<=150))
//если сработал TSOP и угол сервы от 150 до 95град. то...
284
{
285
286
povorot=random(0,100);
//случайно выбираем время завершения поворота
287
digitalWrite(13,HIGH);
//поворачиваем влево
288
digitalWrite(12,LOW);
289
digitalWrite(11,HIGH);
290
digitalWrite(10,LOW);
291
delay(povorot);
//время поворота
292
}
293
294
if
(state==HIGH&&(pos>=85&&pos<=95))
//если сработал TSOP и угол сервы от 95 до 85град. то...
295
296
{
297
298
299
digitalWrite(13,LOW);
//сдаем назад
300
digitalWrite(12,HIGH);
301
digitalWrite(11,HIGH);
302
digitalWrite(10,LOW);
303
delay(1000+val);
//если уровень заряда аккума ниже 50% едем назад 650мс , если ниже 15% - 1000мс
304
305
306
307
308
digitalWrite(13,LOW);
//поворачиваем вправо
309
digitalWrite(12,HIGH);
310
digitalWrite(11,LOW);
311
digitalWrite(10,HIGH);
312
delay(500+val);
//если уровень заряда аккума ниже 50% едем назад 650мс , если ниже 15% - 1000мс
313
314
315
}
316
317
if
(state==HIGH&&(pos>=30&&pos<=85))
//если сработал TSOP и угол сервы от 85 до 30град. то...
318
319
{
320
321
povorot=random(0,100);
//случайно выбираем время завершения поворота
322
digitalWrite(13,LOW);
//поворачиваем вправо
323
digitalWrite(12,HIGH);
324
digitalWrite(11,LOW);
325
digitalWrite(10,HIGH);
326
delay(povorot);
//время завершения поворота
327
}
328
}
329
}
330
}
331
void
blink()
//функция внешнего прерывания
332
//обработка сигнала с головного TSOРа
333
334
335
{
336
state = !state;
//меняем значение переменной на противоположное
337
digitalWrite(1,HIGH);
//включаем сигнальный светодиод
338
}
Клево! а для чего нужны прерывания?
>а для чего нужны прерывания?
Уточните вопрос: вас интересует зачем вообще нужны прерывания, или зачем они используются в данном скетче?
>Вот программа робота.
Спасибо за прекрасно откоментированный код.
Для себя "подсмотрел" идею увеличивать время включения движков когда "просаживается" аккамулятор.
зачем они используются в данном скетче?
именно в этом
>а для чего нужны прерывания?<
Действительно , можно и без прерывания , просто опрашивать цифровой пин.
Но , спрерыванием он как то интереснее себя ведет.
Серва несколько задерживается в том положении , в которм обнаружила препятствие .
>Для себя "подсмотрел" идею увеличивать время включения движков когда "просаживается" аккамулятор.<
Это довольно таки условно.
Аккум просаживается нелинейно.
Сейчас работаю над модуляцией частоты ИК т.к. датчик , иногда , срабатывает на энергосберегающие лампы и яркое солнце.
видео бы еще для полного счастья =)
Ссылка на видео стоит в первом сообщении.
> зачем они используются в данном скетче?
Так в комментариях же написанно:"//обработка сигнала с головного TSOРа". TSOP, как я понимаю это датчик препятствия. Вот для того что-бы ловить его "срабатывание" и использовано прерывание.
Почему прерывание, а не просто опрос пина? Читаем документацию arduino.ru/Reference/AttachInterrupt, раздел ""Использование перерываний", там расписано в чем преимущества "через прерывание", по сравнению в простым чтением пина.
> Это довольно таки условно. Аккум просаживается нелинейно.
Ну это уже детали. Подобрать "приемлемые параметры", увеличить частоту дискретизации и т.п. всегда можно. Главное "идея", "подход". А идея увеличивать время реакции при просаживании, лично для меня, была нова. Честно говоря вообще не приходило в голову "что-то с этим делать", просто принимал как неизбежность.
>>Так в комментариях же написанно:"//обработка сигнала с головного TSOРа". TSOP, как я понимаю это датчик препятствия. Вот для того что-бы ловить его "срабатывание" и использовано прерывание.<<<
На самом деле можно и без прерывания.
Прерывание лишь изменяет состояние переменной , а она опрашивается в строго определенные моменты программы.
На первый взгляд , действительно , не видно разницы (в данном роботе) в поведении машины , но потестив ее пару дней
становится ясно что с прерыванием она ведет себя ... умнее , что ли.
Если кому интересно , схему и программу выложу позже.
Схемку можно глянуть, пажалуйста
>> Схемку можно глянуть, пажалуйста<<
Позже.
Скорее всего я полностью изменю прграмму.
Приблизительную схему можно составить по коментам в программе.
Народ , я в тупике.
Дело вот в чем.
Вот это програма управления , тем же , роботом с ИК пульта (одна она прекрасно работает).
001
unsigned
long
val=0;
002
unsigned
long
val2=0;
003
unsigned
long
val3=0;
004
unsigned
long
val4=0;
005
unsigned
long
val5=0;
006
unsigned
long
val6=0;
007
unsigned
long
val7=0;
008
unsigned
long
val8=0;
009
010
011
#include <Servo.h>
012
Servo myservo;
013
014
void
setup()
015
016
{
017
pinMode(19,INPUT);
018
019
pinMode(9,OUTPUT);
020
pinMode(10,OUTPUT);
021
pinMode(11,OUTPUT);
022
pinMode(12,OUTPUT);
023
pinMode(13,OUTPUT);
024
025
pinMode(6,OUTPUT);
026
pinMode(7,OUTPUT);
027
pinMode(8,OUTPUT);
028
myservo.attach(5);
029
}
030
void
loop()
031
032
{
033
034
//**************************АККУМУЛЯТОР********************//
035
if
(analogRead(19)<615)
036
{
037
digitalWrite(6,HIGH);
038
digitalWrite(7,LOW);
039
digitalWrite(8,LOW);
040
041
if
(analogRead(19)<512)
042
{
043
digitalWrite(6,LOW);
044
digitalWrite(7,HIGH);
045
digitalWrite(8,LOW);
046
}
047
048
}
049
050
if
(analogRead(19)>615)
051
{
052
digitalWrite(6,LOW);
053
digitalWrite(7,LOW);
054
digitalWrite(8,HIGH);
055
}
056
//**********************МИНИМАЛЬНЫЙ ЗАРЯД*****************//
057
if
(analogRead(19)<=485)
058
{
059
digitalWrite(6,LOW);
060
digitalWrite(7,HIGH);
061
digitalWrite(8,LOW);
062
digitalWrite(13,LOW);
//вперд
063
digitalWrite(12,LOW);
064
digitalWrite(11,LOW);
065
digitalWrite(10,LOW);
066
delay(500);
067
digitalWrite(6,LOW);
068
digitalWrite(7,LOW);
069
digitalWrite(8,LOW);
070
delay(500);
071
myservo.write(90);
072
}
073
//******************************************************//
074
else
075
{
076
myservo.write(90);
077
078
if
(pulseIn(2,LOW)<1)
079
{
080
digitalWrite(12,LOW);
081
digitalWrite(11,LOW);
082
digitalWrite(10,LOW);
083
digitalWrite(13,LOW);
084
085
}
086
087
088
089
090
val=pulseIn(2,LOW);
091
val=(val/1000);
092
093
094
095
if
(val==2)
096
{
097
val2=pulseIn(2,LOW);
098
val3=pulseIn(2,LOW);
099
val4=pulseIn(2,LOW);
100
val5=pulseIn(2,LOW);
101
val6=pulseIn(2,LOW);
102
val7=pulseIn(2,LOW);
103
val8=pulseIn(2,LOW);
104
105
106
107
if
((val2/1000)==0&&(val3/1000)==0&&(val4/1000)==1&&(val5/1000)==0&&
108
(val6/1000)==1&&(val7/1000)==1&&(val8/1000)==1)
109
{
110
111
112
digitalWrite(13,HIGH);
//вперд
113
digitalWrite(12,LOW);
114
digitalWrite(11,LOW);
115
digitalWrite(10,HIGH);
116
117
118
119
120
121
122
}
123
124
125
126
127
128
129
130
if
((val2/1000)==0&&(val3/1000)==0&&(val4/1000)==1&&
131
(val5/1000)==0&&(val6/1000)==1&&(val7/1000)==1&&(val8/1000)==0)
132
{
133
134
135
digitalWrite(13,LOW);
//вправо
136
digitalWrite(12,HIGH);
137
digitalWrite(11,LOW);
138
digitalWrite(10,HIGH);
139
140
}
141
142
143
144
145
146
if
((val2/1000)==1&&(val3/1000)==1&&(val4/1000)==0&&
147
(val5/1000)==0&&(val6/1000)==1&&(val7/1000)==1&&(val8/1000)==0)
148
{
149
150
151
152
digitalWrite(13,HIGH);
//лево
153
digitalWrite(12,LOW);
154
digitalWrite(11,HIGH);
155
digitalWrite(10,LOW);
156
157
158
}
159
160
161
162
if
((val2/1000)==1&&(val3/1000)==0&&(val4/1000)==1&&
163
(val5/1000)==0&&(val6/1000)==1&&(val7/1000)==1&&(val8/1000)==1)
164
{
165
166
167
168
digitalWrite(13,LOW);
//назад
169
digitalWrite(12,HIGH);
170
digitalWrite(11,HIGH);
171
digitalWrite(10,LOW);
172
173
}
174
}
175
176
177
178
179
180
181
}
182
183
}
184
185
186
187
Но , я не могу совместить ее с вышеописаной (автономной ) программой.
188
Чтобы с кнопки пульта программа переключалась между автономной и ручной.
189
Что я только не делал и два TSOPA через два прерывания , и последовательный опрос и т.д.
190
Программы вместе не работают вообще.
191
192
У кого какие мысли ?
193
194
195
196
197
198
>У кого какие мысли ?
Мысли:
1.Не работает
2. Названия переменных я , конечно же , меняю.
3.Не совсем понял. Пульт и TSOP работают на одной частоте .
Датчик препятствий распознает пульт как препятствие.
У меня стоят два TSOPа (по одному на каждое прерывание).
4.При разных вариантах "неработает" по разному.
Но чаще всего пульт вообще не работает , а автономная программа постоянно фиксирует препятствие и бесконечно совершает
маневр.
5.Попробую
6.Только в пределах микросекунд , а я счатываю милисекунды.
Ложных срабатываний пульта нет .Несрабатываний ( в прграмме ручного управления )тоже не было.
7.Думал об этом.Наверное попробую.
8.Памяти хватает . ATmega 328 на борту.
Максимум что я , пока , придумал это переключать режимы не командой с пульта а кнопкой на цифровом пине.
Мне кажется что конструкция "считывания импульсов в переменные" (если она крутится в автономной программе)
сильно забивает цикл и мешает работе сервы.
Вот один из примеров.
Вот так работает (вкл/выкл фар)
прерывание (само собой ) не работает.
01
unsigned
long
val=0;
02
unsigned
long
val2=0;
03
unsigned
long
val3=0;
04
unsigned
long
val4=0;
05
unsigned
long
val5=0;
06
unsigned
long
val6=0;
07
unsigned
long
val7=0;
08
unsigned
long
val8=0;
09
volatile
int
state = LOW;
10
11
#include <Servo.h>
12
Servo myservo;
13
14
void
setup()
15
16
{
17
pinMode(4,INPUT);
18
pinMode(1,OUTPUT);
19
pinMode(13,OUTPUT);
20
pinMode(11,OUTPUT);
21
pinMode(12,OUTPUT);
22
pinMode(10,OUTPUT);
23
pinMode(9,OUTPUT);
24
pinMode(6,OUTPUT);
25
pinMode(7,OUTPUT);
26
pinMode(8,OUTPUT);
27
pinMode(2,INPUT);
28
pinMode(19,INPUT);
29
pinMode(17,INPUT);
30
pinMode(18,OUTPUT);
31
attachInterrupt(0, blink, CHANGE);
32
}
33
void
loop()
34
35
{
36
37
38
if
(state==HIGH)
39
{
40
digitalWrite(1,HIGH);
41
}
42
else
43
{
44
digitalWrite(1,LOW);
45
}
46
47
48
if
(pulseIn(4,LOW)<1)
49
{
50
digitalWrite(12,LOW);
51
digitalWrite(11,LOW);
52
digitalWrite(10,LOW);
53
digitalWrite(13,LOW);
54
55
}
56
57
val=pulseIn(4,LOW);
58
val=(val/1000);
59
60
if
(val==2)
61
{
62
val2=pulseIn(4,LOW);
63
val3=pulseIn(4,LOW);
64
val4=pulseIn(4,LOW);
65
val5=pulseIn(4,LOW);
66
val6=pulseIn(4,LOW);
67
val7=pulseIn(4,LOW);
68
val8=pulseIn(4,LOW);
69
70
71
72
if
((val2/1000)==0&&(val3/1000)==0&&(val4/1000)==1&&(val5/1000)==0&&
73
(val6/1000)==1&&(val7/1000)==1&&(val8/1000)==1)
74
{
75
digitalWrite(18,!digitalRead(18));
76
delay(500);
77
}
78
}
79
}
80
81
82
void
blink()
83
{
84
state = !state;
85
86
}
А вот так не работает (включил частоту на ИК светодиоде).
На пкльт не реагирует , на датчик реагирует с большим опозданием.
01
unsigned
long
val=0;
02
unsigned
long
val2=0;
03
unsigned
long
val3=0;
04
unsigned
long
val4=0;
05
unsigned
long
val5=0;
06
unsigned
long
val6=0;
07
unsigned
long
val7=0;
08
unsigned
long
val8=0;
09
volatile
int
state = LOW;
10
11
#include <Servo.h>
12
Servo myservo;
13
14
void
setup()
15
16
{
17
pinMode(4,INPUT);
18
pinMode(1,OUTPUT);
19
pinMode(13,OUTPUT);
20
pinMode(11,OUTPUT);
21
pinMode(12,OUTPUT);
22
pinMode(10,OUTPUT);
23
pinMode(9,OUTPUT);
24
pinMode(6,OUTPUT);
25
pinMode(7,OUTPUT);
26
pinMode(8,OUTPUT);
27
pinMode(2,INPUT);
28
pinMode(19,INPUT);
29
pinMode(17,INPUT);
30
pinMode(18,OUTPUT);
31
attachInterrupt(0, blink, CHANGE);
32
}
33
void
loop()
34
35
{
36
tone(9,36000);
37
38
39
if
(state==HIGH)
40
{
41
digitalWrite(1,HIGH);
42
}
43
else
44
{
45
digitalWrite(1,LOW);
46
}
47
48
49
if
(pulseIn(4,LOW)<1)
50
{
51
digitalWrite(12,LOW);
52
digitalWrite(11,LOW);
53
digitalWrite(10,LOW);
54
digitalWrite(13,LOW);
55
56
}
57
58
val=pulseIn(4,LOW);
59
val=(val/1000);
60
61
if
(val==2)
62
{
63
val2=pulseIn(4,LOW);
64
val3=pulseIn(4,LOW);
65
val4=pulseIn(4,LOW);
66
val5=pulseIn(4,LOW);
67
val6=pulseIn(4,LOW);
68
val7=pulseIn(4,LOW);
69
val8=pulseIn(4,LOW);
70
71
if
((val2/1000)==0&&(val3/1000)==0&&(val4/1000)==1&&(val5/1000)==0&&
72
(val6/1000)==1&&(val7/1000)==1&&(val8/1000)==1)
73
{
74
digitalWrite(18,!digitalRead(18));
75
delay(500);
76
77
}
78
}
79
}
80
81
82
void
blink()
83
{
84
state = !state;
85
86
}
Может , и правда , забивает ? Завтра проверю.
Попробуйте сделать так (выключив tone, естественно при нем работать не будет)
01
if
(state==HIGH)
02
{
03
digitalWrite(1,HIGH);
04
delay(500);
05
state=LOW;
06
}
07
08
else
09
{
10
digitalWrite(1,LOW);
11
}
....
1
void
blink(){
2
state=HIGH;
3
}
Что-бы он включал на заметное время фары при любом импульсе на IR приемнике. Тогда, если при включенном TSOP и, не трогая пульт, фары будут гореть или мограть, вы будете знать что IR-приемник ловит ваш TSOP.
>>IR-приемник ловит ваш TSOP.<<
TSOP это и есть IR приемник.
Так и есть частота светодиодов создает устойчивую помеху .
При включиеных ИК светодиодах робот на пульт не реагирует.
Но .
1.Даже если на TSOPах нет отраженного (или еще какого либо) сигнала - то же самое , на пульт не реагирует.
2.У меня два TSOPa один -датчик препятствий (впереди) , второй я делал специально для пульта , он смотрит вверх .
Эти TSOPы подклчены к разным ногам МК (прерываниям) и опрашиваются раздельно.
>второй я делал специально для пульта , он смотрит вверх
Боюсь что этого "мало", все это излучение хорошо отражается-переотражается от стен/потолка. Попробуйте сделать такой финт ушами:
1. Выключаете несколько раз в секунду излучатель головного TSOP-a.
2. В этот момент делаете включаете "опрос пульта" и выключаете "опрос головного", если "там тихо" , опять включаете головной.
Вообщем работаете с ними "попеременно". Возможно, в итоге, вообще одним TSOP-пом обойдется, играясь только включением-выключением излучателя и по разному интерпретирую его срабатывания. Естественно опрашивать пульт прийдется, все-таки через прерывания. pulseIn тут уже не подойдет никак. На нем программа будет "останавливаться и ждать".
Ну и посмотрите все-таки еще раз в сторону IRRemote. Там именно через прерывания и сделано. Объявлен массив rawbuf в него, при обработке прерывания, закидывают временные интервалы между пойманными тиками, а потом уже анализируются и пытаются декодировать в код клавиши (если известен протокол пульта).
Плюс есть еще есть нюанс, что с пульта первый импульс, как правило, идет более длинный чем остальные. Стартовый. Что-бы определить "начало передачи" и не "зависать" если вы услышали команду "с середины".
Ну и еще подводным камнем может быть как пульт шлет "удержание кнопки". Просто повторяет ее, повторяет сменив один бит, шлет специальный код "повторение" и т.п. В IRRemote есть семпл IRrecvDump им можно посмотреть-сдампить что-же именно шлет ваш пульт.
>>1. Выключаете несколько раз в секунду излучатель головного TSOP-a.
2. В этот момент делаете включаете "опрос пульта" и выключаете "опрос головного", если "там тихо" , опять включаете головной.<<
Вы читаете мои мысли.
Я придумал вот что.
Сделать генератор частоты на внешней микросхеме (что бы он совершенно не зависил от МК).
Сделать импульсную модуляцию этого генератора.
У меня длинна пакета импульсов с пульта составляет 9мс.
Так вот сделать модуляцию - 10мс горит , 10мс не горит .
Вот в эти самые "не горит" ловить пакет с пульта.
Теоретически все гладко , посмотрим что будет на практике.
Дело ваше. Но IMHO, это гиморней. Если не считать того что "нужно еще одну железку вкорячить", то вылезет еще куча вопросов: а как синхронизировать эту железку с МК? и т.п. Помоему "программно" все-таки намного проще будет и гибче будет. Можно подбирать соотношение времени опросов пульта/головного. Можно делать что-то типа "выключили головной на 2 мкс." если на "пульте" тишина, включили обратно головной, если "что-то есть на пульте", то "послушаем дополнительное время, что-бы наверняка". Такой гибкости "в железе" вы вряд ли добъетесь.
>Так вот сделать модуляцию - 10мс горит , 10мс не горит
Зачем? Вы сможете давить пульт с такой частотой? IMHO "прислушиваться к пульту" несколько раз в секунду будет вполне достаточно. А остальное время отдать на "голову", что-бы "не разбить свое лицо о камни" :)
К тому же "длинна пакета импульсов с пульта составляет 9мс" и "10мс не горит". А если начало пакета не совпадет по времени с периодом "10 мс не горит", что будет? Пульт-то вы нажимать будете "когда в голову взбредет", а не "в строгом соотвествии".
Поэтому, возможно, прийдется (если пульт будет "сбивать с толку" головной TSOP), добавлять логику типа "если головной задетектил что-то", выключить его, убедится что "это не пульт", и только тогда решать что "это препятствие".
Получается такая логика (и возможно на одном TSOP-е):
В этом случае даже не прийдется решать "как делить между ними время".
Не очень хороший вариант.
Дело в том что солнце и энергосберегающие лампы дают постоянную засветку на несущей частоте TSOPа (36-38КГц).
В таком случае программа будет постоянно входить в состояние опроса пульта.
Функция pulseIn отказывается работать вместе сфункцией tone.
Определять сигнал свой/чужой лучше всего по длинне , заранее сгенерированого , импульса.
Допустим .
1.пришел сигнал - меряем длинну импульса .
2.Если длинна равна 3мс (собственная ИК модуляция) - препятствие.
3.Если 2мс (начальный импульс в пачке пульта) - пульт.
4. Если больше/меньше - фоновая засветка.
>Дело в том что солнце и энергосберегающие лампы дают постоянную засветку на несущей частоте TSOPа
Вполне возможно. Только любопытно как же тогда пульты бытовой техники так спокойно работают. Сберегайки-то счас на каждом шагу.
Да и я какое-то время назад, монстрячил IR-приемник для управления компом - люстра из 6-сти сберегаек по 25ват никак не мешала. Ну да ладно, примем на веру. Раз у вас "засвечивает", значит так и есть.
>Функция pulseIn отказывается работать вместе сфункцией tone.
Скорее всего потому что используют одно и тоже прерывание.
Ну даже если бы "работала", то лучше было-бы отказатся от нее. Она фактически "останавливает программу и ждет", лучше избегать этого.
>лучше всего по длинне , заранее сгенерированого , импульса
Лучше всего то что "заработает" :) Описанная вами логика, выглядит здраво. Я бы попробовал.
Ну разве что разницу между стартовым импульсом и "собственная ИК модуляция" увеличил, для более четкого "различия" (если это не приводит к ухудшению обнаружения препятсвия).
leshak , я тут , как оказалось , легко и просто решил проблему с энергосберегающими лампами.
Проанализировал что с них идет , так вот : частота от 34 КГц до 40КГц , беспорядочные импульсы от 1до 100 мс
(в среднем около 7-20мс).
Излучение от них слабое , но TSOPу хватает. Поставил кондер 0.1мкф между сигнальной ногой и плюсом
(когда сигнала нет , на выходе TSOPа лог1 , когда сигнал появляется - лог0).
Осталась проблема с лонцем , но ее отложим .
В ближайшие пол года солнца не предвидится.
И вообще , что то думаю я в сторону полностью "железного" датчика с хорошей (многоимпульсной ) модуляцией ,
чтоб все проблемы засветки , ложных срабатываний и т.д. решались в нем а на МК выходил чистый логический уровень.
Видел я подобные проекты ИК бамперов . Можно и на отдельном МК датчик соорудить.
Вобщем посмотрим. Если и буду делать то только в следующем роботе.
>>Да и я какое-то время назад, монстрячил IR-приемник для управления компом - люстра из 6-сти сберегаек по 25ват никак не мешала. Ну да ладно, примем на веру. Раз у вас "засвечивает", значит так и есть. <<
Моя автономная программа просто выдает частоту 36КГц , TSOP реагирует на эту частоту
(хот на импульсы , хоть на постоянный сигнал).
А в пультах идет импульсная кодировка.
И импульсы от лампы не могут , чудесным образом , сложиться в код кнопки .
Потому лампы пультам и не мешают.
Спасибо за разъяснение.
Но у меня от ламп вообще не ловилось никаких импульсов. Пока пульт не нажмешь - на TSOP-пе тишина. Правда покопался в памяти, вспомнил что подключал его тоже с кондером. Не особо понимая зачем. Просто "так было в даташите". Видимо это спасло меня "от ламп".
А вот что пришло в голову: а может для головного, взять TSOP с другой частотой? Есть же, вроде и с несущей на 50Кгц.
Кстати, раскажите а от чего вы шасси (колеса, гусеницы) брали?
Гусеницы от Tamiya похоже
>> Кстати, раскажите а от чего вы шасси (колеса, гусеницы) брали?<<
Шасси полностью самодельное , выточил из текстолита , фурнитура и некоторые детали из детского (металического) конструктора.
Гусеницы , звезды , катки - Tamiya.
Моторы - переделаные сервы.
Выкусил ограничитель на ведущей шестерне , снял всю электронику.
Так что теперь это просто мотор-редукторы.
Позже выложу отдельные фото деталей платформы.
Браво! А не скажешь, что за двигатели там стоят? Мотор-редуктора, если я понял?
>>Браво! А не скажешь, что за двигатели там стоят? Мотор-редуктора, если я понял? <<
Я же писал , это переделаные (под постоянное вращение) сервоприводы Tower pro sg5010.
Попробовал совместить программу пульта и автономную , но и здесь грабли.
Программа состоит из двух больших подпрограмм .
Переключение между ними происходит посредством нажатия кнопки с фиксированым положением.
Программа нормально переходит из ручной в автономную , но при переходе из автономной в ручную - ручная не работает
(не отвечает на команды пульта) хотя переход произошел (это показывает сигнальный светодиод).
001
#include <Servo.h>
002
Servo myservo;
003
volatile
int
state = LOW;
004
int
val=0;
005
int
val2=0;
006
int
val3=0;
007
int
val4=0;
008
int
val5=0;
009
int
val6=0;
010
int
val7=0;
011
int
val8=0;
012
013
int
pos=0;
014
int
val11=0;
015
int
val22=0;
016
int
val33=0;
017
int
val44=0;
018
019
020
void
setup ()
021
022
{
023
pinMode(4,INPUT);
024
pinMode(3,INPUT);
025
pinMode(7,OUTPUT);
026
027
pinMode(1,OUTPUT);
028
pinMode(13,OUTPUT);
029
pinMode(11,OUTPUT);
030
pinMode(12,OUTPUT);
031
pinMode(10,OUTPUT);
032
pinMode(9,OUTPUT);
033
pinMode(6,OUTPUT);
034
pinMode(7,OUTPUT);
035
pinMode(8,OUTPUT);
036
pinMode(2,INPUT);
037
pinMode(19,INPUT);
038
pinMode(17,INPUT);
039
pinMode(18,OUTPUT);
040
041
042
randomSeed(analogRead(0));
043
myservo.attach(5);
044
}
045
void
loop ()
046
047
{
048
049
050
if
(digitalRead(4)==HIGH)
051
052
{
053
digitalWrite(7,HIGH);
054
055
if
(pulseIn(2,LOW)==0)
056
{
057
digitalWrite(12,LOW);
058
digitalWrite(11,LOW);
059
digitalWrite(10,LOW);
060
digitalWrite(13,LOW);
061
digitalWrite(18,LOW);
062
}
063
064
065
066
067
068
069
070
071
val=pulseIn(2,LOW);
072
val=(val/1000);
073
if
(val==2)
074
{
075
val2=pulseIn(2,LOW);
076
val3=pulseIn(2,LOW);
077
val4=pulseIn(2,LOW);
078
val5=pulseIn(2,LOW);
079
val6=pulseIn(2,LOW);
080
val7=pulseIn(2,LOW);
081
val8=pulseIn(2,LOW);
082
083
084
085
086
087
if
((val2/1000)==0&&(val3/1000)==0&&(val4/1000)==0&&(val5/1000)==0&&
088
(val6/1000)==0&&(val7/1000)==0&&(val8/1000)==0)
089
{
090
091
092
digitalWrite(18,HIGH);
093
094
095
}
096
097
098
if
((val2/1000)==1&&(val3/1000)==0&&(val4/1000)==0&&(val5/1000)==0&&
099
(val6/1000)==0&&(val7/1000)==0&&(val8/1000)==0)
100
{
101
102
103
digitalWrite(1,!digitalRead(1));
104
delay(500);
105
106
107
}
108
109
110
111
112
113
114
if
((val2/1000)==0&&(val3/1000)==0&&(val4/1000)==1&&(val5/1000)==0&&
115
(val6/1000)==1&&(val7/1000)==1&&(val8/1000)==1)
116
{
117
118
119
digitalWrite(13,HIGH);
//вперд
120
digitalWrite(12,LOW);
121
digitalWrite(11,LOW);
122
digitalWrite(10,HIGH);
123
124
125
126
127
128
129
}
130
131
132
133
134
135
136
137
if
((val2/1000)==0&&(val3/1000)==0&&(val4/1000)==1&&
138
(val5/1000)==0&&(val6/1000)==1&&(val7/1000)==1&&(val8/1000)==0)
139
{
140
141
digitalWrite(13,HIGH);
//лево
142
digitalWrite(12,LOW);
143
digitalWrite(11,HIGH);
144
digitalWrite(10,LOW);
145
146
}
147
148
149
150
151
152
if
((val2/1000)==1&&(val3/1000)==1&&(val4/1000)==0&&
153
(val5/1000)==0&&(val6/1000)==1&&(val7/1000)==1&&(val8/1000)==0)
154
{
155
156
157
digitalWrite(13,LOW);
//вправо
158
digitalWrite(12,HIGH);
159
digitalWrite(11,LOW);
160
digitalWrite(10,HIGH);
161
162
163
164
165
}
166
167
168
169
if
((val2/1000)==1&&(val3/1000)==0&&(val4/1000)==1&&
170
(val5/1000)==0&&(val6/1000)==1&&(val7/1000)==1&&(val8/1000)==1)
171
{
172
173
174
175
digitalWrite(13,LOW);
//назад
176
digitalWrite(12,HIGH);
177
digitalWrite(11,HIGH);
178
digitalWrite(10,LOW);
179
180
}
181
}
182
183
184
185
186
187
188
}
189
else
190
191
{
192
digitalWrite(7,LOW);
193
194
tone(9,36000);
195
196
197
198
if
(analogRead(17)<11)
//если на фоторезисторе меньше 9 то...
199
{
200
digitalWrite(18,HIGH);
//включаем фары
201
202
}
203
else
//если на фоторезисторе больше 9 то...
204
{
205
digitalWrite(18,LOW);
//выключаем фары
206
207
}
208
209
210
211
//***********************ДВИЖЕНИЕ************************//
212
213
digitalWrite(13,HIGH);
//вперед
214
digitalWrite(12,LOW);
215
digitalWrite(11,LOW);
216
digitalWrite(10,HIGH);
217
218
219
220
221
val33=random(12,17);
222
for
(pos = 30; pos < 150; pos +=3)
// с права на лево
223
{
224
myservo.write(pos);
225
delay(val33);
226
227
228
229
230
if
(digitalRead(3)==HIGH)
231
{
232
233
234
235
digitalWrite(13,LOW);
//назад
236
digitalWrite(12,HIGH);
237
digitalWrite(11,HIGH);
238
digitalWrite(10,LOW);
239
delay(500+val44);
240
241
242
243
digitalWrite(13,HIGH);
//влево
244
digitalWrite(12,LOW);
245
digitalWrite(11,HIGH);
246
digitalWrite(10,LOW);
247
delay(1000+val44);
248
249
250
251
}
252
253
254
255
256
257
if
(digitalRead(2)==LOW&&(pos>=30&&pos<=85))
258
{
259
260
val22=random(0,100);
261
digitalWrite(13,LOW);
//вправо
262
digitalWrite(12,HIGH);
263
digitalWrite(11,LOW);
264
digitalWrite(10,HIGH);
265
delay(val22);
266
267
}
268
269
if
(digitalRead(2)==LOW&&(pos>=88&&pos<=95))
270
271
{
272
273
274
digitalWrite(13,LOW);
//назад
275
digitalWrite(12,HIGH);
276
digitalWrite(11,HIGH);
277
digitalWrite(10,LOW);
278
delay(1000+val44);
279
280
281
digitalWrite(13,HIGH);
//влево
282
digitalWrite(12,LOW);
283
digitalWrite(11,HIGH);
284
digitalWrite(10,LOW);
285
delay(1000+val44);
286
287
288
}
289
290
if
(digitalRead(2)==LOW&&(pos>=95&&pos<=150))
291
292
{
293
val22=random(0,100);
294
digitalWrite(13,HIGH);
//влево
295
digitalWrite(12,LOW);
296
digitalWrite(11,HIGH);
297
digitalWrite(10,LOW);
298
delay(val22);
299
}
300
301
302
303
}
304
305
306
307
308
//2************************************************************//
309
310
311
312
313
val33=random(12,17);
314
for
(pos = 150; pos >30; pos -=3)
// с лева на право
315
{
316
myservo.write(pos);
317
delay(val33);
318
319
320
321
if
(digitalRead(3)==HIGH)
322
{
323
324
325
digitalWrite(13,LOW);
//назад
326
digitalWrite(12,HIGH);
327
digitalWrite(11,HIGH);
328
digitalWrite(10,LOW);
329
delay(500+val44);
330
331
332
333
digitalWrite(13,HIGH);
//влево
334
digitalWrite(12,LOW);
335
digitalWrite(11,HIGH);
336
digitalWrite(10,LOW);
337
delay(1000+val44);
338
339
340
}
341
342
343
344
345
346
347
348
349
350
351
if
(digitalRead(2)==LOW&&(pos>=95&&pos<=150))
352
{
353
354
val22=random(0,100);
355
digitalWrite(13,HIGH);
//влево
356
digitalWrite(12,LOW);
357
digitalWrite(11,HIGH);
358
digitalWrite(10,LOW);
359
delay(val22);
360
}
361
362
if
(digitalRead(2)==LOW&&(pos>=85&&pos<=95))
363
364
{
365
366
367
digitalWrite(13,LOW);
//назад
368
digitalWrite(12,HIGH);
369
digitalWrite(11,HIGH);
370
digitalWrite(10,LOW);
371
delay(1000+val44);
372
373
374
375
376
digitalWrite(13,LOW);
//вправо
377
digitalWrite(12,HIGH);
378
digitalWrite(11,LOW);
379
digitalWrite(10,HIGH);
380
delay(1000+val44);
381
382
383
}
384
385
if
(digitalRead(2)==LOW&&(pos>=30&&pos<=85))
386
387
{
388
389
val22=random(0,100);
390
digitalWrite(13,LOW);
//вправо
391
digitalWrite(12,HIGH);
392
digitalWrite(11,LOW);
393
digitalWrite(10,HIGH);
394
delay(val22);
395
}
396
}
397
}
398
}
Честно горя скетч такого объема трудно "прокрутить в голове". Попробуйте сделать "рефакторинг кода", глядишь и сами увидите "где что-то не так".
Разделите "принятие решения" и "выполнение решение". Сделайте для команда константы
1
#define cmdRigh=1
2
#define cmdLeft=2
3
#define cmdStop=3
Объявите две функции getAutoCommand (в которой будет автономная логика) и getManualCommand (в которой будет логика из пульта). Вызываете ту функцию "какой режим сейчас включен", примерно так
01
if
(manualMode) cmd=getManualCommand()
else
cmd=getAutoCommand()
02
03
switch
(cmd) {
04
case
CMD_RIGHT:
05
//... включаем пины для поворота влево
06
break
;
07
case
CMD_LFFT
08
//... включаем пины для поворота вправо
09
....
10
break
;
11
// ....
12
}<br>
Все эти серии из digitalWrite тоже можно "причесать", посмотрите ветку arduino.ru/forum/apparatnye-voprosy/binarnye-chasy, как там человек хранит в коде "какие леды нужно включить, какие выключить". Немного расточительно на каждый пин, по целому байту отводить, но все равно "намного читабельный".
Можно через прямую запись в порт сделать, тогда код еще читабельней будет.
Сейчас же скет изобилует кучей "магических цифр", дублированием кода. Код "не читается". Ну хотя-бы эти все "влево", "вправо" в отдельные функции повыносить. val22, val33 какие-то более осмысленные имена дать и т.п.
Вот эти
1
(val2/1000)==1&&(val3/1000)==0&&(val4/1000)==1&&
2
170
3
(val5/1000)==0&&(val6/1000)==1&&(val7/1000)==1&&(val8/1000)==1
тоже можно упрятать в какие-то константы, и оформить в виде функции которая возвращает "код клавиши".
Да и сами val2,val3, val4 не нужны. Можно объявить массив byte vals[7], тогда и вычивать их можно будет не кучей pulseIn, а
циклом
for(i=0;i<7;i++)vals[i]=pulseIn(2,LOW).
И "сравнивать" потом тоже будет удобней (сделать массив в котором "ожидаемые значение", пробежались по двум массивам, сравнили каждый элемент, а не выписывать "длинющие условие if-a").
>>>Объявите две функции getAutoCommand (в которой будет автономная логика) и getManualCommand (в которой будет логика из пульта). Вызываете ту функцию "какой режим сейчас включен", примерно так<<<
Думал об этом - попробую.
А то я тут уже в такие дебри полез ...
"При переходе на ручное управление опрашивать ячейку ипрома и если там 1 то пишем туда 0 , включаем релюшку
(сброс питания с МК).
А при входе в автономную программу пишем в ячейку 1."
Спаял попробовал -работает , но в готовое устройство я такое , конечно же , не поставлю.
>>val22, val33 какие-то более осмысленные имена дать и т.п.<<
Это все в порядке эксперимента , лоск буду наводить когда функционал будет нормально работать.
>(сброс питания с МК)
Да жесткач. Но за умение добиватся цели любыми средствами - уважение :)
>Это все в порядке эксперимента
Это понятно. Все мы знаем откуда это возникает. Более того, на начальных этапах именно так и нужно. Криво-косо, абы живо. Пока "идея не протухла".
>лоск буду наводить когда функционал будет нормально работать
Подходы к программированию типа XP, говорят что так нельзя. Когда "код большой", вы уже не сможете его нормально отрефакторить (тем более с ArduinoIDE которое практически не имеет инструментов для "работы с кодом"). Велик страх "что-то поломать" (и довольно обоснованный), да и "работает - не трогай". Но развивать такой кодом все "трудней и трудней" (вот даже сейчас, ошибка скорее всего где-то в логика, а "увидеть" ее не получается). Поэтому обычно рекомендую идти "маленькими шагами".
Этап первый: сделал какую-то фичу. как угодно, лишь-бы "быстрее". Этап второй: поведение кода не меняется, но стараешься сделать его красивым, читабельным и удобным для поддержки. Потом следующая фича: опять два этапа....
И они "не разрывны", хотя конечно, это все, в довольно большой степени "религиозные" подходы к написанию кода. Дело вкуса. Но лично мне такая парадигма очень помогает (плюс Unit Tesiting, но в ардуине на него "ресурсов не хватит").
Кажется нашел проблему .
Щас еще поковыряю - посмотрим.
Дело в том что при запуске автономной программы включается выдача частоты (ИК светодиоды).
При переходе в ручную программу частота остается т.к. не была отключена функцией noTone.
А , как я уже писал выше , pulseIn напрочь отказывается работать когда работает частота (то же самое и с сервами).
Даже вот такой , простенький , таймер , вместе с pulseIn работает крайне некорректно (да и pulseIn в это время тоже)
01
long
previousMillis = 0;
02
void
setup()
03
04
{
05
pinMode(13,OUTPUT);
06
}
07
08
09
void
loop()
10
11
{
12
if
(millis() -previousMillis >1000)
13
{
14
previousMillis = millis();
15
digitalWrite(13, !digitalRead(13));
16
}
17
18
}
Видать pulseIn "сжирает" все системные таймеры и если хоть один таймер занят чем то другим то отказывается работать.
На досуге надо заняться изысканием замены pulseIn , пусть менее элеганттным зато более функциональным.
Но как ни крути таймеры придется использовать.
Все !
Это последняя версия этого робота - Tankbot v7 (седьмая версия платы !).
Я так и не смог сделать переключение между режимами с ИК пульта .
Сделал переключение на кнопке.
Сделал два нижних датчика (впереди).
Один датчик работал плохо , теперь если и упадет , то только при движении назад.
Так же добавил управление головной сервой с пульта.
Поставил подстроечный резистор на ИК свотодиоды , теперь можно регулировать дальность от 5см до 40см.
В конце видео фотик сдох , так что других фото/видео материалов , в ближайшее время ,не будет.
Видео
video.mail.ru/mail/heruvim219/Tank-Bot/21.html