Помогите Роботу DVR-1

DVR
Offline
Зарегистрирован: 17.12.2012

 

Надеюсь что здесь мне смогут помочь.

  У меня давно заволялась робо платформа на двух моторах,кое что докупил и  решил собрать это чудо DVR-1.

Отличительной его особенностью является то, что элементом используемого питания является 3.7 Вольт Li-ion аккумулятор  с двумя преобразователями напряжения http://www.dvrobot.ru/shop/c7.tretiy_razdel_c.htm?os=20. Это позволяет моему роботу заряжаться от любого зарядного для телефона, и при этом в состоянии сам заряжать телефон. Также вся логика питания в том числе двигатели питаются тоже от 5 Вольт.

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

Мне всего то нужно три действия.

  1. Робот все время едет в перед.
  2. при срабатывании центрального ИК ,робот разворачивается на 180 градусов.
  3. при срабатывании правого или левого ИК соответственно разворачивается в право или в лево.

В будущем планирую еще прикупить солнечную батарею 5 Вольт 300 мА  http://www.dvrobot.ru/shop/i349.5_Volt_300_mA.htm. Это позволит ДВР полностью быть автономным, но все упирается в скетч.

Надеюсь знатоки откликнутся. Спасибо.

Ниже вставляю глючный код. Загрузив его DVR-1 начинает жить своей непонятной жизнью, тупит вообщем.

int IK1 = 6;
int IKP = 9;
int IKL = 10;
int KNOPKA4 = 8;
int KNOPKA5 = 13;

int IN1 = 2;
int IN2 = 3; 

int IN3 = 4; 
int IN4 = 5; 
int SVET = 11;  

 
void setup() 
{
  pinMode(IK1, INPUT);
  pinMode(IKP, INPUT);
  pinMode(IKL, INPUT);
  pinMode(KNOPKA4, INPUT);
 pinMode(KNOPKA5, INPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
 
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);

  pinMode (SVET, OUTPUT); 


}

void loop() 
{  
  if (digitalRead(IK1)== HIGH) 
  {
    digitalWrite(IN1,LOW); 
   digitalWrite(IN2,HIGH); 
   digitalWrite(IN3,HIGH); 
   digitalWrite(IN4,LOW);                              
    }
     else 
  {
                           
   digitalWrite(IN1,LOW); 
   digitalWrite(IN2,LOW); 
   digitalWrite(IN3,LOW); 
   digitalWrite(IN4,LOW); 
    digitalWrite(SVET,HIGH );
   delay(800);  
digitalWrite(IN1,HIGH); 
   digitalWrite(IN2,LOW); 
   digitalWrite(IN3,HIGH); 
   digitalWrite(IN4,LOW); 
 delay(500);    
  }
  
  
     if (digitalRead(IKP) == HIGH) 
  {
    digitalWrite(IN1,LOW); 
   digitalWrite(IN2,HIGH); 
   digitalWrite(IN3,HIGH); 
   digitalWrite(IN4,LOW); 
  }
     else 
  {
                           
   digitalWrite(IN1,HIGH); 
   digitalWrite(IN2,LOW); 
   digitalWrite(IN3,LOW); 
   digitalWrite(IN4,HIGH); 
   delay(800);  
digitalWrite(IN1,HIGH); 
   digitalWrite(IN2,LOW); 
   digitalWrite(IN3,HIGH); 
   digitalWrite(IN4,LOW); 
 delay(1000);    
  }
     
  if (digitalRead(IKL) == HIGH) 
  {
    digitalWrite(IN1,LOW); 
   digitalWrite(IN2,HIGH); 
   digitalWrite(IN3,HIGH); 
   digitalWrite(IN4,LOW); 
  }
     else 
  {
                           
   digitalWrite(IN1,HIGH); 
   digitalWrite(IN2,LOW); 
   digitalWrite(IN3,LOW); 
   digitalWrite(IN4,HIGH); 
   delay(800);  
digitalWrite(IN1,LOW); 
   digitalWrite(IN2,HIGH); 
   digitalWrite(IN3,LOW); 
   digitalWrite(IN4,HIGH); 
 delay(1000);    
  }
     
}

 

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

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

Как минимум, вам нужно выяснить что у вас тупит:

  • Неправильно реализована логика
  • Сам алгоритм придуман неправильно
  • Железо ведет себя не так как вы думаете (шумят датчики, слепят друг-друга, направильно подключены и т.п.)

Сами понимаете что с диагностикой "как-то тупит" - вам никто не поможет (не собирать же такого робота). Нужно выяснить "как именно тупит".

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

Сгрупируйте ваши digitalWrite, к примеру в leftWeel(shor mode) и rightWheel(byte mode)  который принимаю параметр mode означающий куда нужно крутить колесо (или остановить).  Точно так же можно вынести в функции опрос датчиков.

Вообщем примерно так:

#define FORWARD 1 // крутить вперед
#define BACKWARD -1 // крутить назад
#define OFF 0 // остановить


void leftWheel(short mode){
  switch(mode){
    case FORWARD:
             // тут пишите ваши digitalWrite для кручения левого колеса ВПЕРЕД
             //.....
             //.....
             Serial.println("LEFT FORWARD"); // сообщили в лог о включении колеса
             
             break;
    case  BACKWARD:
             // тут пишите ваши digitalWrite для кручения левого колеса НАЗАД
             //.....
             //.....
             Serial.println("LEFT BACKWARD"); // сообщили в лог о включении колеса      
            break;        

    case OFF:
             // тут пишите ваши digitalWrite для остановки левого колеса
             //.....
             //.....
             Serial.println("LEFT STOP"); // сообщили в лог о включении колеса      
            break;    
  }
}


void rightWheel(short mode){
  // ..все то же самое для правого колеса
}


bool raisedCentralSensor(){ // возвращает иситну если сработал центральный сенсор
   return digitalRead(IK1)== HIGH; // ну или на каком-там пине он у вас висит
}

bool raisedLeftSensor()(){ 
  // аналогично
}

bool raisedRightSensor()(){ 
  // аналогично
}

Тогда у вас "главный код" станет намного более читабельным и появится возможность добавить логгирование (для понимания "что происходит"). Вообщем разбиратся с ним и вам и другим будет намного легче, если оно будет выглядеть вот так:

void loop(){
  
  if(raisedCentralSensor()){
      // останавливаемся
      leftWheel(OFF);
      rightWhell(OFF);
      
      // мигаем светом или что вы там делатете
      
      // разворачиваемся
      leftWheel(FORWARD); // левое плечо вперед
      rightWhell(BACKWARD); // правое назад
      delay(800);
  } else if(raisedLeftSensor()){
    //.......
  }   else  { // едем прямо

      //   ....  Только пялит глаза – ошалел, обалдел. Он увидел, как траулер встал на винты, Обороты врубив на предел.
      leftWheel(FORWARD);
      rightWhell(FORWARD);
  }
 // ............
  
}

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

maksim
Offline
Зарегистрирован: 12.02.2012

Ну а это так, в довес к выше написанному:

#define IKF 6
#define IKR 9
#define IKL 10
#define KNOPKA4 8
#define KNOPKA5 13
#define IN1 2
#define IN2 3
#define IN3 4
#define IN4 5
#define SVET 11 

void setup() 
{
  // входы лучше подтянуть
  digitalWrite(IKF, 1);
  digitalWrite(IKR, 1);
  digitalWrite(IKL, 1);
  digitalWrite(KNOPKA4, 1);
  digitalWrite(KNOPKA5, 1);
  // настраеваем на выход
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode (SVET, OUTPUT);
  // поехали 
  Forward(); 
}

void loop() 
{
  if(!digitalRead(IKF)) // если сработал центральный датчик, то
  {
    digitalWrite(SVET, HIGH);    
    Stop(); // отстанавливаемся
    Backward(); // отъезжаем назад
    Right();  // разворачиваемся
    Right();
    Forward(); // едем вперед
    digitalWrite(SVET, LOW);
  }
  else if(!digitalRead(IKL)) // если сработал левый датчик, то
  {
    Stop(); // отстанавливаемся
    Right();  // поворачиваем направо
    Forward(); // едем вперед
  }
  else if(!digitalRead(IKR)) // если сработал правый датчик, то
  {
    Stop(); // отстанавливаемся
    Left();  // поворачиваем налево
    Forward(); // едем вперед
  }
}

void Forward()
{
  digitalWrite(IN1, LOW); 
  digitalWrite(IN2, HIGH); 
  digitalWrite(IN3, HIGH); 
  digitalWrite(IN4, LOW); 
}

void Backward()
{  
  digitalWrite(IN1, HIGH); 
  digitalWrite(IN2, LOW); 
  digitalWrite(IN3, LOW); 
  digitalWrite(IN4, HIGH); 
  delay(800);
}

void Left()
{
  digitalWrite(IN1, HIGH); 
  digitalWrite(IN2, LOW); 
  digitalWrite(IN3, HIGH); 
  digitalWrite(IN4, LOW); 
  delay(1000);
}

void Right()
{
  digitalWrite(IN1, LOW); 
  digitalWrite(IN2, HIGH); 
  digitalWrite(IN3, LOW); 
  digitalWrite(IN4, HIGH);
  delay(1000); 
}

void Stop()
{
  digitalWrite(IN1, LOW); 
  digitalWrite(IN2, LOW); 
  digitalWrite(IN3, LOW); 
  digitalWrite(IN4, LOW);
  delay(500);
}

Естественно задержки и правильное напрвление вращения двигателей вам нужно самому подкорректировать.

DVR
Offline
Зарегистрирован: 17.12.2012

Ребята спасибо вам большое!Вам не на форумах надо сидеть, а наработе деньги делать с такими та головами. Код работает,робот едет, НО ТОЛЬКО ДО ПЕРВОГО СРАБАТЫВАНИЯ ЛЮБОГО ИЗ ДАТЧИКОВ ПОТОМ ПРОСТО ТУПО В ПЕРЕД И УЖЕ НЕТ РЕАКЦИИ НА ДАТЧИКИ. Включишь выключиш питание, опять проделает команду от любого датчика и сново только пряма не обращая на сигналы датчика. 

#define IKF 6
#define IKR 5
#define IKL 3
#define IN1 8
#define IN2 9
#define IN3 10
#define IN4 11
#define SVET 13 

void setup() 
{
  // входы лучше подтянуть
  digitalWrite(IKF, 1);
  digitalWrite(IKR, 1);
  digitalWrite(IKL, 1);
  // настраеваем на выход
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);

  // поехали 
  Forward(); 
}

void loop() 
{
  if(!digitalRead(IKF)) // если сработал центральный датчик, то
  {
      
    Stop(); // отстанавливаемся
    Backward(); // отъезжаем назад
    Right();  // разворачиваемся
    Forward(); // едем вперед
    
  }
  else if(!digitalRead(IKL)) // если сработал левый датчик, то
  {
   
    Right();  // поворачиваем направо
    Forward(); // едем вперед
  }
  else if(!digitalRead(IKR)) // если сработал правый датчик, то
  {
   
    Left();  // поворачиваем налево
    Forward(); // едем вперед
  }
  
}

void Forward()
{
  
   digitalWrite(IN1, HIGH); 
  digitalWrite(IN2, LOW); 
  digitalWrite(IN3, HIGH); 
  digitalWrite(IN4, LOW); 
}

void Backward()
{  
 digitalWrite(IN1, LOW); 
  digitalWrite(IN2, HIGH); 
  digitalWrite(IN3, LOW); 
  digitalWrite(IN4, HIGH);  
  delay(800);
}

void Left()
{
  digitalWrite(IN1, HIGH); 
  digitalWrite(IN2, LOW); 
  digitalWrite(IN3, LOW); 
  digitalWrite(IN4, HIGH); 
  delay(1000);
}

void Right()
{
  digitalWrite(IN1, LOW); 
  digitalWrite(IN2, HIGH); 
  digitalWrite(IN3, HIGH); 
  digitalWrite(IN4, LOW);
  delay(1000); 
}

void Stop()
{
  digitalWrite(IN1, LOW); 
  digitalWrite(IN2, LOW); 
  digitalWrite(IN3, LOW); 
  digitalWrite(IN4, LOW);
  delay(1000);
}

 

DVR
Offline
Зарегистрирован: 17.12.2012

ЧТО ТАКОЕ ШУМЫ И ОТКУДА ОНИ БЕРУТЬСЯ и как с ними бороться???? разобрал робота провода все разъеденил, так как пало подозрение, что модуль повышения напряжения  шумит ( до этого момента и не знал что это возможно). Хоть и выяснил причину глюка , но так и не могу понять что зашумы и как их убить ! Спасибо.

DVR
Offline
Зарегистрирован: 17.12.2012

ЧТО ТАКОЕ ШУМЫ И ОТКУДА ОНИ БЕРУТЬСЯ и как с ними бороться???? разобрал робота провода все разъеденил, так как пало подозрение, что модуль повышения напряжения  шумит ( до этого момента и не знал что это возможно). Хоть и выяснил причину глюка , но так и не могу понять что зашумы и как их убить ! Спасибо.

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

Как с ними боротся - зависит от чего они происходят.  

Все время держите в уме то что очевидно для вас (так как перед глазами), не очевидно форуму.

Вот например, что у вас за датчики (ссылка)? Как их подключили?  Может стоит им питание давать по очереди? Только перед самим опросом?

Вы сказали "Хоть и выяснил причину глюка", но не сказали как. Уверены что правильно диагностировали?

Вот если бы вы написали, как я советовал, отдельную функцию для опроса датчика, то можно было-бы ее изменить и логировать что датчики выдают (а привести этот лог на форуме).

Модицифировать raisedCentralSensor() в такой вид:

bool prevCentral;
bool raisedCentralSensor(){ // возвращает иситну если сработал центральный сенсор
   bool newState=digitalRead(IK1)!= HIGH; // читаем состояние датчика
   
  if(newState!=prevCentral){ // датчик поменял состояние с прошлого опроса
     Serial.print(millis()); // вывели время
     Serial.print(": center="); // вывели какой датчик
     Serial.print(newState); // вывели его новое состояние
     
  }
  
  prevCentral=newState; // сохранили состояние на будущие
  
  return newState;

}

Аналогично можно натыкаить serial.print в функции Forward,Backward e.t.c  Тогда можно будет открыть Serial монитор и просто смотреть "что там происходит и с какими интервалами". Когда сработал датчик, когда мотор...

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

И да.. еще... вы не забыли что когда вызывается функция delay() в этот момент скетч останавливается и ничего не делает? Ни датчики не опрашивает, ни решений никаких не принимает.

maksim
Offline
Зарегистрирован: 12.02.2012

Если у вас в 33 строке Right(); хватает одного раза на разворот, то тогда и поворот направо будет разворотом.

DVR
Offline
Зарегистрирован: 17.12.2012

Спасибо все заработало !! Щас думаю чего еще навесить на него что бы он не просто от стены к стене ездил