Помогите подружить ИК приемник с моторами

tesak47
Offline
Зарегистрирован: 22.01.2015

Здравствуйте! У меня крайняя необходимость в помощи местных обывателей. Уже как вторую ночь не могу довести до ума скетч. Я его вернее сделал, но осталась одна маленькая деталь, я бы даже назвал это аномалией, которая не поддается никакому объяснению. Очень надеюсь на вашу помощь.

Скетч прилагаю...

#include <IRremote.h> //подключаем библиотеку для ИК приемника
int RECV_PIN = 2; //назначаем вход ИК приемника на 2 пин 
IRrecv irrecv(RECV_PIN); //переменная ИК приемника
decode_results results; //переменная считанных данных с ИК приемника
int IN1 = 9; //назначаем пин первого мотора
int IN2 = 10; //назначаем пин первого мотора
int IN3 = 11; //назначаем пин второго мотора
int IN4 = 12; //назначаем пин второго мотора
int motorPin_1 = 14; //пин первого мотора назначаем на 14 пин
int motorPin_2 = 16; //пин второго мотора назначаем на 16 пин
int ledPin = 13; //переменную для визуального контроля активности ИК приемника назначаем на 13 пин
unsigned long eventTime=0; //переменная для паузы

void setup() 
{              
  Serial.begin(9600); //включаем com-port
  irrecv.enableIRIn(); //включаем ИК приемник
  pinMode(IN1, OUTPUT); //обозначаем переменную как выход
  pinMode(IN2, OUTPUT); //обозначаем переменную как выход
  pinMode(IN3, OUTPUT); //обозначаем переменную как выход
  pinMode(IN4, OUTPUT); //обозначаем переменную как выход
  pinMode(motorPin_1, OUTPUT); //обозначаем переменную как выход
  pinMode(motorPin_2, OUTPUT); //обозначаем переменную как выход
  pinMode(ledPin, OUTPUT); //обозначаем переменную как выход
}

void loop() 
{
  if (digitalRead(RECV_PIN) == LOW) //если на ИК приемнике обнаружен отрицательный сигнал...   
  eventTime=millis(),digitalWrite(ledPin, HIGH);  //включить светодиод активности ИК приемника на 100 милисекунд
  if(millis()-eventTime>100) digitalWrite(ledPin, LOW),digitalWrite(motorPin_1, LOW),digitalWrite(motorPin_2, LOW);//если с момента отжатия кнопки на пульте прошло 100мск отключаем светодиод и пины
  if (irrecv.decode(&results)) //если на ИК датчик поступили данные...
  { 
    if(digitalRead(ledPin) == HIGH && (results.value == 0xFF609F))digitalWrite(motorPin_1, HIGH); //от кнопки "вперед", включить пин "motorPin_1"
    if(digitalRead(ledPin) == HIGH && (results.value == 0xFF6897))digitalWrite(motorPin_2, HIGH); //от кнопки "назад", включить пин "motorPin_2"
    Serial.println(results.value, HEX); //выводим в com-port данные с ик приемника
    irrecv.resume(); //сбрасываем значения ИК приемника
  } 
    if(digitalRead(motorPin_1)==1){digitalWrite(IN1,LOW),digitalWrite(IN2,HIGH),digitalWrite(IN3,HIGH),digitalWrite(IN4,LOW);}      
    if(digitalRead(motorPin_1)==0){digitalWrite(IN1,HIGH),digitalWrite(IN2,HIGH),digitalWrite(IN3,HIGH),digitalWrite(IN4,HIGH);}
    if(digitalRead(motorPin_2)==1){digitalWrite(IN1,HIGH),digitalWrite(IN2,LOW),digitalWrite(IN3,LOW),digitalWrite(IN4,HIGH);}
    if(digitalRead(motorPin_2)==0){digitalWrite(IN1,HIGH),digitalWrite(IN2,HIGH),digitalWrite(IN3,HIGH),digitalWrite(IN4,HIGH);}
}



Задумка простая: при помощи ИК пульта управлять моторчиками (вперед и назад), подключенные через L298N, да так, чтобы при нажатии кнопки двигатели вращались, а при отжатии вращение останавливалось. Так вот... почему то при нажатии кнопки назад (моторы ведут себя нормально), а при нажатии кнопки вперед (моторы едва шевелятся). Если я меняю местами первые две строки на вторые:

 

if(digitalRead(motorPin_1)==1){digitalWrite(IN1,LOW),digitalWrite(IN2,HIGH),digitalWrite(IN3,HIGH),digitalWrite(IN4,LOW);}      
if(digitalRead(motorPin_1)==0){digitalWrite(IN1,HIGH),digitalWrite(IN2,HIGH),digitalWrite(IN3,HIGH),digitalWrite(IN4,HIGH);}
if(digitalRead(motorPin_2)==1){digitalWrite(IN1,HIGH),digitalWrite(IN2,LOW),digitalWrite(IN3,LOW),digitalWrite(IN4,HIGH);}
if(digitalRead(motorPin_2)==0){digitalWrite(IN1,HIGH),digitalWrite(IN2,HIGH),digitalWrite(IN3,HIGH),digitalWrite(IN4,HIGH);}

Все становится с точностью да наоборот, т.е. при нажатии кнопки вперед моторы вращаются нормально, а при нажатии кнопки назад едва шевелятся. Очень прошу помощи!

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Начните без инфрареда.  Проверьте просто подавая сигналы на входы ( вплоть до проводочками.)

ENA  и   ENB  куда-то подключили?

И вроде  в {digitalWrite(IN1,LOW),digitalWrite(IN2,HIGH),digitalWrite(IN3,HIGH),digitalWrite(IN4,LOW);} Я думал после  всяких  digitalWrite(IN1,LOW) должна стоять не запятая а вот такая фигУшка   ;

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Можно и запятые ставить вместо точки с запятой. Это здесь не так важно.
А вот использовать пины для хранения признаков как минимум странно. Я про motorPin_1 и 2.
И комментарии в setup, говорят о многом. Либо полное непонимание разницы между пином и переменной, либо не знаю, зачем такие комментарии писать.

tesak47
Offline
Зарегистрирован: 22.01.2015

motor_pin1 и motor_pin2 это должны были быть светодиоды. Но так как их нет я решил обойтись без них. Комментарии писал чисто для себя чтоб было больше понимания. Суть впринципе не в этом... скетч то рабочий! Если я привязываю светодиод L на motor_pin1 или motor_pin2 они загораются, значит то что я пишу в программе работает! Но вот почему только в одну сторону?

tesak47
Offline
Зарегистрирован: 22.01.2015

на ENB и ENA висят перемычки. ШИМ пока еще в планах (с этим бы разобраться)

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

tesak47
Offline
Зарегистрирован: 22.01.2015

Если к скетчу добавляю еще две кнопки вправо и влево:


void loop() 
{
  if (digitalRead(RECV_PIN) == LOW) //если на ИК приемнике обнаружен отрицательный сигнал...   
  eventTime=millis(),digitalWrite(ledPin, HIGH);  //включить светодиод активности ИК приемника на 100 милисекунд
  if(millis()-eventTime>100) digitalWrite(ledPin, LOW),digitalWrite(motorLed_1, LOW),digitalWrite(motorLed_2, LOW),digitalWrite(motorLed_3, LOW),digitalWrite(motorLed_4, LOW);//если с момента отжатия кнопки на пульте прошло 100мск отключаем все светодиоды
  if (irrecv.decode(&results)) //если на ИК приемник поступили данные...
  { 
    if(digitalRead(ledPin) == HIGH && (results.value == 0xFF609F))digitalWrite(motorLed_1, HIGH); //от кнопки "вперед", включить светодиод "motorLed_1"
    if(digitalRead(ledPin) == HIGH && (results.value == 0xFF6897))digitalWrite(motorLed_2, HIGH); //от кнопки "назад", включить светодиод "motorLed_2"
    if(digitalRead(ledPin) == HIGH && (results.value == 0xFFD827))digitalWrite(motorLed_3, HIGH); //от кнопки "вправо", включить светодиод "motorLed_3"
    if(digitalRead(ledPin) == HIGH && (results.value == 0xFFDA25))digitalWrite(motorLed_4, HIGH); //от кнопки "влево", включить светодиод "motorLed_4"
    Serial.println(results.value, HEX); //выводим в com-port данные с ик приемника
    irrecv.resume(); //сбрасываем значения ИК приемника
  } 
    if(digitalRead(motorLed_2)==1){digitalWrite(IN1,HIGH),digitalWrite(IN2,LOW),digitalWrite(IN3,HIGH),digitalWrite(IN4,LOW);} //если горит светодиод мотора №2... крутим его
    if(digitalRead(motorLed_2)==0){digitalWrite(IN1,LOW),digitalWrite(IN2,LOW),digitalWrite(IN3,LOW),digitalWrite(IN4,LOW);} //если не горит... останавливаем
    if(digitalRead(motorLed_1)==1){digitalWrite(IN1,LOW),digitalWrite(IN2,HIGH),digitalWrite(IN3,LOW),digitalWrite(IN4,HIGH);} //если горит светодиод мотора №1... крутим его
    if(digitalRead(motorLed_1)==0){digitalWrite(IN1,LOW),digitalWrite(IN2,LOW),digitalWrite(IN3,LOW),digitalWrite(IN4,LOW);} //если не горит... останавливаем
    if(digitalRead(motorLed_3)==1){digitalWrite(IN1,LOW),digitalWrite(IN2,HIGH),digitalWrite(IN3,HIGH),digitalWrite(IN4,LOW);} //если горит светодиод мотора №3... крутим его
    if(digitalRead(motorLed_3)==0){digitalWrite(IN1,HIGH),digitalWrite(IN2,HIGH),digitalWrite(IN3,HIGH),digitalWrite(IN4,HIGH);} //если не горит... останавливаем
    if(digitalRead(motorLed_4)==1){digitalWrite(IN1,HIGH),digitalWrite(IN2,LOW),digitalWrite(IN3,LOW),digitalWrite(IN4,HIGH);} //если горит светодиод мотора №4... крутим его
    if(digitalRead(motorLed_4)==0){digitalWrite(IN1,HIGH),digitalWrite(IN2,HIGH),digitalWrite(IN3,HIGH),digitalWrite(IN4,HIGH);} //если не горит... останавливаем
    }

То моторы крутятся, но также с разной скоростью: 

быстрее всех крутится по комманде влево (примерно 50% от максимально возможной скорости), потом вправо (25%), вверх (15%), вниз (процентов 10%).

ЧТО ЭТО ЗА ХРЕНЬ ТАКАЯ???

vvadim
Offline
Зарегистрирован: 23.05.2012

начнём с того, что код твой не читаемый.

ты бы его оформил нормально и воспользовался Ctrl + T тогда больше человеков на него бы обратили внимание.

а так глянут на эту кашу - и дальше пошли.

vvadim
Offline
Зарегистрирован: 23.05.2012

типа пример 

void setup() 
 { 
 pinMode(13, OUTPUT); 
 } 

 void loop() 
 { 
 if(digitalRead(14)==HIGH);        //если кнопка нажата ... 
 { 
 digitalWrite(13,HIGH);            //включаем светодиод 
 } 
 else                              //если не нажата... 
 { 
digitalWrite(13,LOW);              //выключаем 
 } 
 } 

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

vvadim пишет:

типа пример 

void setup() 
 { 
 pinMode(13, OUTPUT); 
 } 

 void loop() 
 { 
 if(digitalRead(14)==HIGH);        //если кнопка нажата ... 
 { 
 digitalWrite(13,HIGH);            //включаем светодиод 
 } 
 else                              //если не нажата... 
 { 
digitalWrite(13,LOW);              //выключаем 
 } 
 } 

 

В смысле, это пример как НЕ надо форматировать текст?

 

vvadim
Offline
Зарегистрирован: 23.05.2012

ну сам Ctrl + T не нажал.

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

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

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

tesak47
Offline
Зарегистрирован: 22.01.2015

Вообщем решил проблему. Оказывается просто перемудрил с кодом:)

А он должен был быть таким:

#include <IRremote.h> //подключаем библиотеку для ИК приемника
int RECV_PIN = 2; //назначаем вход ИК приемника на 2 пин 
IRrecv irrecv(RECV_PIN); //переменная ИК приемника
decode_results results; //переменная считанных данных с ИК приемника
int IN1 = 3; //назначаем пин мотора №1
int IN2 = 4; //назначаем пин мотора №1
int IN3 = 5; //назначаем пин мотора №2
int IN4 = 6; //назначаем пин мотора №2
int ledPin = 13; //переменная для визуального контроля активности ИК приемника, назначаем на 13 пин
unsigned long eventTime=0; //переменная для паузы

void setup() 
{
  irrecv.enableIRIn(); //включаем ИК приемник
  pinMode(IN1, OUTPUT); //обозначаем переменную пина мотора №1 как выход
  pinMode(IN2, OUTPUT); //обозначаем переменную пина мотора №1 как выход
  pinMode(IN3, OUTPUT); //обозначаем переменную пина мотора №2 как выход
  pinMode(IN4, OUTPUT); //обозначаем переменную пина мотора №2 как выход
  pinMode(ledPin, OUTPUT); //обозначаем переменную как выход
}
void loop() 
{
  if (digitalRead(RECV_PIN) == LOW) //если на ИК приемнике обнаружен отрицательный сигнал...   
  eventTime=millis(),digitalWrite(ledPin, HIGH);  //...включить светодиод активности ИК приемника на 100 милисекунд
  if(millis()-eventTime>100) digitalWrite(ledPin, LOW),digitalWrite(IN1, LOW),digitalWrite(IN2, LOW),digitalWrite(IN3, LOW),digitalWrite(IN4, LOW);//если с момента отжатия кнопки на пульте прошло 100мск, отключаем все пины
  if (irrecv.decode(&results)) //если на ИК приемник поступили данные...
  {
    if (results.value == 0xFF609F && (digitalRead(ledPin) == HIGH) )digitalWrite(IN1, HIGH),digitalWrite(IN4, HIGH); //...с кнопки вперед и горит индикатор активности ИК приемника, вращаем мотор вперед
    if (results.value == 0xFF6897 && (digitalRead(ledPin) == HIGH) )digitalWrite(IN2, HIGH),digitalWrite(IN3, HIGH); //...с кнопки назад и горит индикатор активности ИК приемника, вращаем мотор назад
    if (results.value == 0xFFD827 && (digitalRead(ledPin) == HIGH) )digitalWrite(IN1, HIGH),digitalWrite(IN3, HIGH); //...с кнопки вправо и горит индикатор активности ИК приемника, вращаем мотор вправо
    if (results.value == 0xFFDA25 && (digitalRead(ledPin) == HIGH) )digitalWrite(IN4, HIGH),digitalWrite(IN2, HIGH); //...с кнопки влево и горит индикатор активности ИК приемника, вращаем мотор влево
    irrecv.resume(); //сбрасываем значения ИК приемника
  } 
 }

 

tesak47
Offline
Зарегистрирован: 22.01.2015

Вы меня извините я так сказать начинающий пользователь. Сильно ногами не пинайте. Нажимал в Arduino IDE ctrl+t у меня одна строка на пару пробелов пододвинулась, нажимаю еще раз, а она мне говорит нечего форматировать

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

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

vvadim
Offline
Зарегистрирован: 23.05.2012

как по мне, так лучше

#include <IRremote.h>      //подключаем библиотеку для ИК приемника
int RECV_PIN = 2;          //назначаем вход ИК приемника на 2 пин 
IRrecv irrecv(RECV_PIN);   //переменная ИК приемника
decode_results results;    //переменная считанных данных с ИК приемника
int IN1 = 3;               //назначаем пин мотора №1
int IN2 = 4;               //назначаем пин мотора №1
int IN3 = 5;               //назначаем пин мотора №2
int IN4 = 6;               //назначаем пин мотора №2
int ledPin = 13;           //переменная для визуального контроля активности ИК приемника, назначаем на 13 пин
unsigned long eventTime=0; //переменная для паузы

void setup() 
{
  irrecv.enableIRIn();      //включаем ИК приемник
  pinMode(IN1, OUTPUT);     //обозначаем переменную пина мотора №1 как выход
  pinMode(IN2, OUTPUT);     //обозначаем переменную пина мотора №1 как выход
  pinMode(IN3, OUTPUT);     //обозначаем переменную пина мотора №2 как выход
  pinMode(IN4, OUTPUT);     //обозначаем переменную пина мотора №2 как выход
  pinMode(ledPin, OUTPUT);  //обозначаем переменную как выход
}
void loop() 
{
  if (digitalRead(RECV_PIN) == LOW)     //если на ИК приемнике обнаружен отрицательный сигнал...   
  {
    eventTime=millis();
    digitalWrite(ledPin, HIGH);         //...включить светодиод активности ИК приемника на 100 милисекунд
  }    
  if(millis()-eventTime>100)            //если с момента отжатия кнопки на пульте прошло 100мск, отключаем все пины
  {
    digitalWrite(ledPin, LOW);
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);      
  }
  if (irrecv.decode(&results))             //если на ИК приемник поступили данные...
  {
    if (results.value == 0xFF609F && (digitalRead(ledPin) == HIGH) )   //...с кнопки вперед и горит индикатор активности ИК приемника, вращаем мотор вперед
    {
      digitalWrite(IN1, HIGH);
      digitalWrite(IN4, HIGH); 
    }
    if (results.value == 0xFF6897 && (digitalRead(ledPin) == HIGH) )   //...с кнопки назад и горит индикатор активности ИК приемника, вращаем мотор назад
    {
      digitalWrite(IN2, HIGH);
      digitalWrite(IN3, HIGH);
    } 
    if (results.value == 0xFFD827 && (digitalRead(ledPin) == HIGH) )    //...с кнопки вправо и горит индикатор активности ИК приемника, вращаем мотор вправо
    {
      digitalWrite(IN1, HIGH);
      digitalWrite(IN3, HIGH); 
    }

    if (results.value == 0xFFDA25 && (digitalRead(ledPin) == HIGH) )     //...с кнопки влево и горит индикатор активности ИК приемника, вращаем мотор влево
    {
      digitalWrite(IN4, HIGH);
      digitalWrite(IN2, HIGH);
    } 
    irrecv.resume();                       //сбрасываем значения ИК приемника
  } 
}

 а вот зачем в этих строках

if (results.value == 0xFFD827 && (digitalRead(ledPin) == HIGH) )

записывать (digitalRead(ledPin) == HIGH) ?  они не нужны.

tesak47
Offline
Зарегистрирован: 22.01.2015

если не записать: digitalRead(ledPin) == HIGH, то мотор после отпускания кнопки продолжает вращаться. Кстати маленько допилил код и добавил туда PWM. Скетч работает всем спасибо кто откликнулся.