Tank-bot

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Представляю вам своего робота .

Робот умеет обходить препятствия (ИК датчик радарного типа).

Не падать со стола /лестницы и т.д. (датчик поверхности).

Включать/выключать фары автоматически (фоторезистор).

Так же на борту есть индикатор заряда аккумов - три светодиода.

Когда уровень заряда выше 60% - горит зеленый , когда ниже - горит желтый , когда ниже 15% - горит

красный , когда ниже 5% - красный мигает , отключаются маршевые двигатели , головня серва устанавливается по центру.

В таком состоянии логика и светодиоды будут работать около 3часов.

Так же реализовано управление по  ИК  (пульт от телека) , правда программа ИК на отдельном МК  ,

но скоро я совмещу две программы .

 

 

 

 

 

 

 

 

 

 

Остальные фото здесь foto.mail.ru/mail/heruvim219/Tank-bot

Видео здесь video.mail.ru/mail/heruvim219/Tank-Bot

Если кому интересно , схему и программу выложу позже.

 участник конкурса "Arduino 2012"

leshak
Offline
Зарегистрирован: 29.09.2011

 >Если кому интересно

Да как вы могли предположить, что на таком сайте не найдется хотя-бы одного человека которому будет интерестно?

Конечно интерестно. 

А аккумы заряжаются где-то снаружи или могут "прямо на месте"?

А по поводу проекта: однозначно "браво"!

 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

 Аккумы заряжаются внешним зарядником (потому сверху и стоят).

Просто на плате уже особо места не было , что бы ставить , какой нибудь , lm317 для заряда.

А прогу выложу позже (откоментирую и выложу).

Кстати , подскажите какую нибудь простенькую прогу для рисования схем.

 

"Arduino 2012"

Zaliv
Offline
Зарегистрирован: 05.03.2011

Это очень очень круто! Даже немного завидно (по хорошему) прямоте рук.

Если выложишь код для ознакомления, будет просто здорово.

Я правильно понял, что ИК датчик закреплен на поворачивающейся платформе?

Alexander
Offline
Зарегистрирован: 25.04.2010

Класс! Вы не против если я помещу краткое резюме, одну из фоток и ссылку на эту ветку в раздел проекты?

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>Я правильно понял, что ИК датчик закреплен на поворачивающейся платформе?< 

Датчик вращается на серве.

И по положению сервы определяет с  какой стороны препятствие , если препятствие прямо перед ним - сдает назад и разворачивается.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>Вы не против если я помещу краткое резюме, одну из фоток и ссылку на эту ветку в раздел проекты? <

Нет , не против .

Только я , немного , не понял  где именно вы хотите ее поместить ?

Alexander
Offline
Зарегистрирован: 25.04.2010

Спасибо. Сюда http://arduino.ru/projects

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Почему то в сети мало проектов роботов на дуино. 

Изначально мой ездил с дуиной на борту , потом я развел плату (только с шестого раза сделал рабочюю плату) и дуину убрал. 

Выложу схему и прогу и на одного дуино бота станет больше.

 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Вот программа робота.

Довольно сыровата , но , по мере апгрейда робота , буду выкладывать новые версии.

В прграмме довольно много рандомных значений это дает небольшую непредсказуемость в движениях.

Дело в том что машина с "жесткой" программой движения часто , надолго , зависала 

в неудобных местах - узких проходах и т.д.

 

 

001#include <Servo.h> //библиотека для серво
002Servo myservo;//объект серво
003volatile 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  
014void 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}
034void 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    
177if(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 
189if(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 
210if(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 
294if(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 
317if(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}
331void blink()//функция внешнего прерывания
332//обработка сигнала с головного TSOРа
333 
334 
335{
336  state = !state;//меняем значение переменной на противоположное
337  digitalWrite(1,HIGH);//включаем сигнальный светодиод
338}

 

Nikita1
Offline
Зарегистрирован: 19.10.2011

Клево! а для чего нужны прерывания? 

leshak
Offline
Зарегистрирован: 29.09.2011

 >а для чего нужны прерывания?

Уточните вопрос: вас интересует зачем вообще нужны прерывания, или зачем они используются в данном скетче?

leshak
Offline
Зарегистрирован: 29.09.2011

 >Вот программа робота.

Спасибо за прекрасно откоментированный код. 

Для себя "подсмотрел" идею увеличивать время включения движков когда "просаживается" аккамулятор.

Nikita1
Offline
Зарегистрирован: 19.10.2011

leshak пишет:

 зачем они используются в данном скетче?

именно в этом

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>а для чего нужны прерывания?<

Действительно , можно и без прерывания , просто опрашивать цифровой пин.

Но , спрерыванием он как то интереснее себя ведет. 

Серва несколько задерживается в том положении , в которм обнаружила препятствие .

>Для себя "подсмотрел" идею увеличивать время включения движков когда "просаживается" аккамулятор.<
 

Это довольно таки условно.

Аккум просаживается нелинейно.

 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Сейчас работаю над модуляцией частоты ИК т.к. датчик , иногда , срабатывает на энергосберегающие лампы и яркое солнце. 

Fenrir
Offline
Зарегистрирован: 03.07.2011

видео бы еще для полного счастья =)

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Ссылка на видео стоит в первом сообщении. 

leshak
Offline
Зарегистрирован: 29.09.2011

 > зачем они используются в данном скетче?

Так в комментариях же написанно:"//обработка сигнала с головного TSOРа". TSOP, как я понимаю это датчик препятствия. Вот для того что-бы ловить его "срабатывание" и использовано прерывание.

Почему прерывание, а не просто опрос пина? Читаем документацию arduino.ru/Reference/AttachInterrupt, раздел ""Использование перерываний", там расписано в чем преимущества "через прерывание", по сравнению в простым чтением пина.

leshak
Offline
Зарегистрирован: 29.09.2011

> Это довольно таки условно. Аккум просаживается нелинейно.

Ну это уже детали. Подобрать "приемлемые параметры", увеличить частоту дискретизации и т.п. всегда можно. Главное "идея", "подход". А идея увеличивать время реакции при просаживании, лично для меня, была нова. Честно говоря вообще не приходило в голову "что-то с этим делать", просто принимал как неизбежность.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>Так в комментариях же написанно:"//обработка сигнала с головного TSOРа". TSOP, как я понимаю это датчик препятствия. Вот для того что-бы ловить его "срабатывание" и использовано прерывание.<<<

 

На самом деле можно и без прерывания.

Прерывание лишь изменяет состояние переменной , а она опрашивается в строго определенные моменты программы.

На первый взгляд , действительно , не видно разницы (в данном роботе)  в поведении машины , но потестив ее пару дней 

становится ясно что с прерыванием она ведет себя ... умнее , что ли.

Nikita1
Offline
Зарегистрирован: 19.10.2011

nestandart пишет:

Если кому интересно , схему и программу выложу позже.

Схемку можно глянуть, пажалуйста

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>> Схемку можно глянуть, пажалуйста<<

Позже.

Скорее всего я полностью изменю прграмму.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Приблизительную схему можно составить по коментам в программе. 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Народ , я в тупике.

Дело вот в чем.

Вот это програма управления , тем же , роботом с ИК пульта  (одна она прекрасно работает).

001unsigned long val=0;
002unsigned long val2=0;
003unsigned long val3=0;
004unsigned long val4=0;
005unsigned long val5=0;
006unsigned long val6=0;
007unsigned long val7=0;
008unsigned long val8=0;
009 
010 
011#include <Servo.h>
012Servo myservo;
013 
014void 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}
030void 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   
090val=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  

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

>У кого какие мысли ?

Мысли:

  1. Через прерывания все-таки "кошерней".
  2. В обоих скетчах переменная "val" используется с разным смыслом. возможно на этом "интерферирует".
  3. IK-пульт дает "засветку" на TSOP.
  4. " не работают вообще" это "вообще никакие команды не выполняются" или "выполняются хаотично"?
  5. Вместо команд на сервы сделать вывод в Serial и посмотреть какие оно решения принимает (вообщем сделать вывод debug информации).
  6. Не забываем что пульт выдает сигналы "не четко", длительность импульсов может немного плавать.
  7. Посмотрел бы на библиотеку IRRemote, возможно что-то оттуда "выдрать" кусок захвата-декодинга сигналов, а может и целиком заюзать ее заюзать (если место позволяет).
  8. Возможно "вместе" уже памяти не хватает. Попробовать добавить банальное мограние диодом. Узнать у нас цикл loop крутится вообще или где-то зависает.

 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

1.Не работает

2. Названия переменных я , конечно же , меняю.

3.Не совсем понял. Пульт и TSOP работают на одной частоте .

Датчик препятствий распознает пульт как препятствие.

У меня стоят два TSOPа (по одному на каждое прерывание).

4.При разных вариантах "неработает" по разному.

Но чаще всего пульт вообще не работает , а автономная программа постоянно фиксирует препятствие и бесконечно совершает 

маневр.

5.Попробую

6.Только в пределах микросекунд , а я счатываю милисекунды.

Ложных срабатываний пульта нет .Несрабатываний ( в прграмме ручного управления )тоже не было.

7.Думал об этом.Наверное попробую.

8.Памяти хватает . ATmega 328  на борту.

 

Максимум что я , пока , придумал  это переключать режимы не командой с пульта а кнопкой на цифровом пине.

Мне кажется что конструкция "считывания импульсов в переменные" (если она крутится в автономной программе)

сильно забивает цикл и мешает работе сервы.

 

Вот один из примеров.

Вот так работает (вкл/выкл фар)

прерывание (само собой ) не работает.

 

А вот так не работает (включил частоту на ИК светодиоде).

На пкльт не реагирует , на датчик реагирует с большим опозданием.

Может , и правда , забивает ? Завтра проверю.

leshak
Offline
Зарегистрирован: 29.09.2011

 Попробуйте сделать  так  (выключив tone, естественно при нем работать не будет)

01if(state==HIGH)
02{
03  digitalWrite(1,HIGH);
04  delay(500);
05  state=LOW;
06}
07 
08else
09{
10  digitalWrite(1,LOW);
11}

....

1void blink(){
2  state=HIGH;
3}

 Что-бы он включал на заметное время фары при любом импульсе на IR приемнике. Тогда, если при включенном TSOP и, не трогая пульт, фары будут гореть или мограть, вы будете знать что IR-приемник ловит ваш TSOP.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>IR-приемник ловит ваш TSOP.<<

TSOP это и есть IR приемник. 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Так и есть частота светодиодов создает устойчивую помеху .

При включиеных ИК светодиодах робот на пульт не реагирует.

Но .

1.Даже если на TSOPах нет отраженного (или еще какого либо) сигнала - то же самое , на пульт не реагирует.

2.У меня два TSOPa  один -датчик препятствий (впереди) , второй я делал специально для пульта , он смотрит вверх .

Эти TSOPы подклчены к разным ногам МК (прерываниям) и опрашиваются раздельно.

leshak
Offline
Зарегистрирован: 29.09.2011

>второй я делал специально для пульта , он смотрит вверх

Боюсь что этого "мало", все это излучение хорошо отражается-переотражается от стен/потолка. Попробуйте сделать такой финт ушами:

1. Выключаете несколько раз в секунду излучатель головного TSOP-a.

2. В этот момент делаете включаете "опрос пульта" и выключаете "опрос головного", если "там тихо" , опять включаете головной. 

Вообщем работаете с ними "попеременно". Возможно, в итоге, вообще одним TSOP-пом обойдется, играясь только включением-выключением излучателя и по разному интерпретирую его срабатывания. Естественно опрашивать пульт прийдется, все-таки через прерывания. pulseIn тут уже не подойдет никак. На нем программа будет "останавливаться и ждать".

Ну и посмотрите все-таки еще раз в сторону IRRemote. Там именно через прерывания и сделано. Объявлен  массив rawbuf в него, при обработке прерывания, закидывают временные интервалы между пойманными тиками, а потом уже анализируются и пытаются декодировать в код клавиши (если известен протокол пульта). 

 Плюс есть еще есть нюанс, что с пульта первый импульс, как правило, идет более длинный чем остальные. Стартовый. Что-бы определить "начало передачи" и не "зависать" если вы услышали команду "с середины".

Ну и еще подводным камнем может быть как пульт шлет "удержание кнопки". Просто повторяет ее, повторяет сменив один бит, шлет специальный код "повторение" и т.п. В IRRemote есть семпл IRrecvDump им можно посмотреть-сдампить что-же именно шлет ваш пульт.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>1. Выключаете несколько раз в секунду излучатель головного TSOP-a.

2. В этот момент делаете включаете "опрос пульта" и выключаете "опрос головного", если "там тихо" , опять включаете головной.<<

Вы читаете мои мысли.

Я придумал вот что.

Сделать генератор частоты на внешней микросхеме (что бы он совершенно не зависил от МК).

Сделать импульсную модуляцию этого генератора.

У меня длинна пакета импульсов с пульта составляет 9мс.

Так вот сделать модуляцию - 10мс горит , 10мс не горит .

Вот в эти самые "не горит" ловить пакет с пульта.

Теоретически все гладко , посмотрим что будет на практике.

leshak
Offline
Зарегистрирован: 29.09.2011

Дело ваше. Но IMHO, это гиморней. Если не считать того что "нужно еще одну железку вкорячить", то вылезет еще куча вопросов: а как синхронизировать эту железку с МК? и т.п. Помоему "программно" все-таки намного проще будет и гибче будет. Можно подбирать соотношение времени  опросов пульта/головного. Можно делать что-то типа "выключили головной на 2 мкс." если на "пульте" тишина, включили обратно головной, если "что-то есть на пульте", то "послушаем дополнительное время, что-бы наверняка". Такой гибкости "в железе" вы вряд ли добъетесь.

>Так вот сделать модуляцию - 10мс горит , 10мс не горит

Зачем? Вы сможете давить пульт с такой частотой? IMHO "прислушиваться к пульту" несколько раз в секунду будет вполне достаточно. А остальное время отдать на "голову", что-бы "не разбить свое лицо о камни" :)

leshak
Offline
Зарегистрирован: 29.09.2011

 К тому же "длинна пакета импульсов с пульта составляет 9мс" и "10мс не горит". А если начало пакета не совпадет по времени с периодом "10 мс не горит", что будет? Пульт-то вы нажимать будете "когда в голову взбредет", а не "в строгом соотвествии".

Поэтому, возможно, прийдется (если пульт будет "сбивать с толку" головной TSOP), добавлять логику типа "если головной задетектил что-то", выключить его, убедится что "это не пульт", и только тогда решать что "это препятствие".

Получается такая логика (и возможно на одном TSOP-е):

  1. "Головной что-то поймал".
  2. Выключаем излучатель
  3. Если сигнал "продолжает поступать", обрабатываем его как пульт, если "исчез" - обрабатываем его как препятсвие.
  4. Включаем излучатель.

В этом случае даже не прийдется решать "как делить между ними время".

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Не очень хороший вариант.

Дело в том что солнце и энергосберегающие лампы дают постоянную засветку на несущей частоте TSOPа (36-38КГц).

В таком случае программа будет постоянно входить в состояние опроса пульта.

Функция pulseIn  отказывается работать вместе сфункцией tone.

Определять сигнал свой/чужой лучше всего по длинне , заранее сгенерированого , импульса.

Допустим .

1.пришел сигнал - меряем длинну импульса .

2.Если длинна равна 3мс (собственная ИК модуляция) - препятствие.

3.Если 2мс (начальный импульс в пачке пульта) - пульт.

4. Если больше/меньше - фоновая засветка.

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

 >Дело в том что солнце и энергосберегающие лампы дают постоянную засветку на несущей частоте TSOPа

Вполне возможно. Только любопытно как же тогда пульты бытовой техники так спокойно работают. Сберегайки-то счас на каждом шагу.

Да и я какое-то время назад, монстрячил IR-приемник для управления компом - люстра из 6-сти сберегаек по 25ват никак не мешала. Ну да ладно, примем на веру. Раз у вас "засвечивает", значит так и есть.

>Функция pulseIn отказывается работать вместе сфункцией tone.

Скорее всего потому что используют одно и тоже прерывание.

Ну даже если бы "работала", то лучше было-бы отказатся от нее. Она фактически "останавливает программу и ждет", лучше избегать этого. 

>лучше всего по длинне , заранее сгенерированого , импульса

Лучше всего то что "заработает" :)  Описанная вами логика, выглядит здраво. Я бы попробовал.

Ну разве что разницу между стартовым импульсом и "собственная ИК модуляция" увеличил, для более четкого "различия" (если это не приводит к ухудшению обнаружения препятсвия).

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

leshak , я тут , как оказалось , легко и просто решил проблему с энергосберегающими лампами.

Проанализировал что с них идет , так вот : частота от 34 КГц до 40КГц , беспорядочные импульсы от 1до 100 мс 

(в среднем около 7-20мс).

Излучение от них слабое , но TSOPу хватает. Поставил кондер 0.1мкф между сигнальной ногой и плюсом

 (когда сигнала нет , на выходе TSOPа лог1 , когда сигнал появляется - лог0).

Осталась проблема с лонцем , но ее отложим .

В ближайшие пол года солнца не предвидится.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

И вообще , что то думаю я в сторону полностью "железного" датчика с хорошей (многоимпульсной ) модуляцией ,

чтоб все проблемы засветки , ложных срабатываний и т.д. решались в нем а на МК выходил чистый логический уровень.

Видел я подобные проекты ИК бамперов .  Можно и на отдельном МК датчик соорудить.

Вобщем посмотрим. Если и буду делать то только в следующем роботе. 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>Да и я какое-то время назад, монстрячил IR-приемник для управления компом - люстра из 6-сти сберегаек по 25ват никак не мешала. Ну да ладно, примем на веру. Раз у вас "засвечивает", значит так и есть. <<

 

Моя автономная программа просто выдает частоту 36КГц , TSOP реагирует на эту частоту

(хот на импульсы , хоть на постоянный сигнал).

А в пультах идет импульсная кодировка.

И  импульсы от лампы не могут , чудесным образом , сложиться в код кнопки .

Потому лампы пультам и не мешают.

leshak
Offline
Зарегистрирован: 29.09.2011

 Спасибо за разъяснение.

Но у меня от ламп вообще не ловилось никаких импульсов. Пока пульт не нажмешь - на TSOP-пе тишина. Правда покопался в памяти, вспомнил что подключал его тоже с кондером. Не особо понимая зачем. Просто "так было в даташите". Видимо это спасло меня "от ламп".

А вот что пришло в голову: а может для головного, взять TSOP с другой частотой? Есть же, вроде и с несущей на 50Кгц.

Кстати, раскажите а от чего вы шасси (колеса, гусеницы) брали?

Nikita1
Offline
Зарегистрирован: 19.10.2011

Гусеницы от Tamiya похоже 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>> Кстати, раскажите а от чего вы шасси (колеса, гусеницы) брали?<<

Шасси полностью самодельное , выточил из текстолита , фурнитура и некоторые детали из детского (металического) конструктора.

Гусеницы  , звезды , катки - Tamiya.

Моторы - переделаные сервы.

Выкусил ограничитель на ведущей шестерне , снял всю электронику.

Так что теперь это просто мотор-редукторы.

Позже выложу отдельные фото деталей платформы.

MAFia
Offline
Зарегистрирован: 26.10.2011

 Браво! А не скажешь, что за двигатели там стоят? Мотор-редуктора, если я понял?

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>Браво! А не скажешь, что за двигатели там стоят? Мотор-редуктора, если я понял? <<

Я же писал , это переделаные (под постоянное вращение) сервоприводы Tower pro sg5010.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Попробовал совместить программу пульта и автономную , но и здесь грабли.

Программа состоит из двух больших подпрограмм .

Переключение между ними происходит посредством нажатия кнопки с фиксированым положением.

Программа нормально переходит из ручной в автономную , но при переходе из автономной в ручную - ручная не работает 

(не отвечает на команды пульта) хотя переход произошел  (это показывает сигнальный светодиод).

 

001#include <Servo.h>
002Servo myservo;
003volatile int state = LOW;
004int 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  
020void 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}
045void 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    
071val=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    
257if(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 
269if(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 
290if(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 
362if(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 
385if(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}

 

leshak
Offline
Зарегистрирован: 29.09.2011

 Честно горя скетч такого объема трудно "прокрутить в голове". Попробуйте сделать "рефакторинг кода", глядишь и сами увидите "где что-то не так". 

Разделите "принятие решения" и "выполнение решение". Сделайте для команда константы 

1#define cmdRigh=1
2#define cmdLeft=2
3#define cmdStop=3

Объявите две функции getAutoCommand (в которой будет автономная логика) и getManualCommand (в которой будет логика из пульта). Вызываете ту функцию "какой режим сейчас включен", примерно так

01if(manualMode) cmd=getManualCommand() else cmd=getAutoCommand()
02 
03switch(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 какие-то более осмысленные имена дать и т.п.

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

 Вот эти

1(val2/1000)==1&&(val3/1000)==0&&(val4/1000)==1&&
2170
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").

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

 >>>Объявите две функции getAutoCommand (в которой будет автономная логика) и getManualCommand (в которой будет логика из пульта). Вызываете ту функцию "какой режим сейчас включен", примерно так<<<

Думал об этом - попробую.

А то я тут уже в такие дебри полез ...

"При переходе на ручное управление опрашивать ячейку ипрома и если там 1 то пишем туда 0 , включаем релюшку 

(сброс питания с МК).

А при входе в автономную программу пишем в ячейку 1."

Спаял попробовал -работает , но в готовое устройство я такое , конечно же , не поставлю.

 

>>val22, val33 какие-то более осмысленные имена дать и т.п.<<

Это все в порядке эксперимента , лоск буду наводить когда функционал будет нормально работать.

leshak
Offline
Зарегистрирован: 29.09.2011

 >(сброс питания с МК)

Да жесткач. Но за умение добиватся цели любыми средствами - уважение :)

>Это все в порядке эксперимента

Это понятно. Все мы знаем откуда это возникает. Более того, на начальных этапах именно так и нужно. Криво-косо, абы живо. Пока "идея не протухла".

>лоск буду наводить когда функционал будет нормально работать

Подходы к программированию типа XP, говорят что так нельзя. Когда "код большой", вы уже не сможете его нормально отрефакторить (тем более с ArduinoIDE которое практически не имеет инструментов для "работы с кодом"). Велик страх "что-то поломать" (и довольно обоснованный), да и "работает - не трогай". Но развивать такой кодом все "трудней и трудней" (вот даже сейчас, ошибка скорее всего где-то в логика, а "увидеть" ее не получается). Поэтому обычно рекомендую идти "маленькими шагами".

Этап первый: сделал какую-то фичу. как угодно, лишь-бы "быстрее". Этап второй: поведение кода не меняется, но стараешься сделать его красивым, читабельным и удобным для поддержки. Потом следующая фича: опять два этапа....

И они "не разрывны", хотя конечно, это все, в довольно большой степени "религиозные" подходы к написанию кода. Дело вкуса. Но лично мне такая парадигма очень помогает (плюс Unit Tesiting, но в ардуине на него "ресурсов не хватит").

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Кажется нашел проблему .

Щас еще поковыряю - посмотрим.

Дело в том что при запуске автономной программы включается выдача частоты (ИК светодиоды).

При переходе в ручную программу частота остается  т.к. не была отключена функцией noTone.

А , как я уже писал выше , pulseIn напрочь отказывается работать когда работает частота (то же самое и с сервами).

Даже вот такой , простенький , таймер , вместе с pulseIn работает крайне некорректно (да и pulseIn в это время тоже)

 

01long previousMillis = 0;
02 void setup()
03 
04{
05  pinMode(13,OUTPUT);
06}
07 
08 
09void loop()
10 
11{
12 if (millis() -previousMillis >1000)
13 
14   previousMillis = millis(); 
15   digitalWrite(13, !digitalRead(13));
16 }
17  
18}

 

Видать pulseIn "сжирает" все системные таймеры и если хоть один таймер занят чем то другим  то отказывается работать. 

 

На досуге надо заняться изысканием замены pulseIn , пусть менее элеганттным зато более функциональным.

Но как ни крути таймеры придется использовать.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Все !

Это последняя версия этого робота - Tankbot v7 (седьмая версия платы !).

Я так и не смог сделать переключение между режимами с ИК пульта .

Сделал переключение на кнопке.

Сделал два нижних датчика (впереди).

Один датчик работал плохо , теперь если и упадет , то только при движении назад. 

Так же добавил управление головной сервой с пульта.

Поставил подстроечный резистор на ИК свотодиоды , теперь можно регулировать дальность от 5см до 40см.

В конце видео фотик сдох , так что других фото/видео материалов , в ближайшее время ,не будет.

Видео

video.mail.ru/mail/heruvim219/Tank-Bot/21.html