Помогите подружить ИК приемник с моторами
- Войдите на сайт для отправки комментариев
Здравствуйте! У меня крайняя необходимость в помощи местных обывателей. Уже как вторую ночь не могу довести до ума скетч. Я его вернее сделал, но осталась одна маленькая деталь, я бы даже назвал это аномалией, которая не поддается никакому объяснению. Очень надеюсь на вашу помощь.
Скетч прилагаю...
#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);}
Все становится с точностью да наоборот, т.е. при нажатии кнопки вперед моторы вращаются нормально, а при нажатии кнопки назад едва шевелятся. Очень прошу помощи!
Начните без инфрареда. Проверьте просто подавая сигналы на входы ( вплоть до проводочками.)
ENA и ENB куда-то подключили?
И вроде в {digitalWrite(IN1,LOW),digitalWrite(IN2,HIGH),digitalWrite(IN3,HIGH),digitalWrite(IN4,LOW);} Я думал после всяких digitalWrite(IN1,LOW) должна стоять не запятая а вот такая фигУшка ;
Можно и запятые ставить вместо точки с запятой. Это здесь не так важно.
А вот использовать пины для хранения признаков как минимум странно. Я про motorPin_1 и 2.
И комментарии в setup, говорят о многом. Либо полное непонимание разницы между пином и переменной, либо не знаю, зачем такие комментарии писать.
motor_pin1 и motor_pin2 это должны были быть светодиоды. Но так как их нет я решил обойтись без них. Комментарии писал чисто для себя чтоб было больше понимания. Суть впринципе не в этом... скетч то рабочий! Если я привязываю светодиод L на motor_pin1 или motor_pin2 они загораются, значит то что я пишу в программе работает! Но вот почему только в одну сторону?
на ENB и ENA висят перемычки. ШИМ пока еще в планах (с этим бы разобраться)
Что я только не делал. У меня есть скетч где от простого нажатия одной кнопки на пульте моторы включаются в одну сторону, и при нажатии другой в другую (но не отключаются после отжатия). И на тойже самой конфигурации подключения работает такой скетч как надо.
Если к скетчу добавляю еще две кнопки вправо и влево:
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%).
ЧТО ЭТО ЗА ХРЕНЬ ТАКАЯ???
начнём с того, что код твой не читаемый.
ты бы его оформил нормально и воспользовался Ctrl + T тогда больше человеков на него бы обратили внимание.
а так глянут на эту кашу - и дальше пошли.
типа пример
void setup() { pinMode(13, OUTPUT); } void loop() { if(digitalRead(14)==HIGH); //если кнопка нажата ... { digitalWrite(13,HIGH); //включаем светодиод } else //если не нажата... { digitalWrite(13,LOW); //выключаем } }типа пример
void setup() { pinMode(13, OUTPUT); } void loop() { if(digitalRead(14)==HIGH); //если кнопка нажата ... { digitalWrite(13,HIGH); //включаем светодиод } else //если не нажата... { digitalWrite(13,LOW); //выключаем } }В смысле, это пример как НЕ надо форматировать текст?
ну сам Ctrl + T не нажал.
а так, если вас подобная запись устраивает как у топикстартера - я не против.
Меня не устраивает, потому смотрел по диагонали. Вы привели пример, который не отформатирован. Можно понять это так, что это правильный пример. Потому я добавил свой комментарий.
Вообщем решил проблему. Оказывается просто перемудрил с кодом:)
А он должен был быть таким:
#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(); //сбрасываем значения ИК приемника } }Вы меня извините я так сказать начинающий пользователь. Сильно ногами не пинайте. Нажимал в Arduino IDE ctrl+t у меня одна строка на пару пробелов пододвинулась, нажимаю еще раз, а она мне говорит нечего форматировать
Вы конечно можете использовать запятые, вместо точек с запятой, однако наступит момент, когда скетч вдруг перестанет работать по непонятной причине.
Для этого придуманы фигурные скобки.
Крутость не в использовании редких конструкций и сложных условий.
Круче - когда текст читается как любимая книга и скетч работает корректно, готовый к быстрой правке и пониманию не только автором, но и другими программистами.
как по мне, так лучше
#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) ? они не нужны.
если не записать: digitalRead(ledPin) == HIGH, то мотор после отпускания кнопки продолжает вращаться. Кстати маленько допилил код и добавил туда PWM. Скетч работает всем спасибо кто откликнулся.