Работа с IR и BT одновременно
- Войдите на сайт для отправки комментариев
Здрасти форумчанам. Маленький вопросик хочу задать вам.
Вот, сделал из стааренького малюсенького танка типа Tigr масштаб нескажу но в длинну не более 8см :) ( давно валяется без дела и откуда нескажу) но внутри пара моторчиков с редукторами IR управление видимо было. ВОт с кнопками и работой с IR я справился, дежиш - крутит, отпустил стоит :). Драйвер искал самый мелкий типа L9110S. Реши впишнуть впридачу НС-05 и место как раз оставалсоь так вот незадача с коддом...
Удержание работает в ir в блютусине мигате падла. Понмиаю что все в процедуре обработки нажатия кнопок пульта ir (брал с примера Осипова Д. по удержанию). Там прсото появился минус на входе ir - включили таймер, есть удеражние нажатия - выполняем код, нету - останавливаем счётчик. Можит как томожно переключаться между блютусом и пультом по switch\case? Но немогу догнать как.
Вот кусочек кода если кто пожелает глянуть.. Кнопки ir работают шикарно а bt -нет.
#include <IRremote.h> //Подключаем библиотеку для IR сенсора //=====IR_Sensor* #define recvPin 2 //Вход IR-приемника и кнопки пульта uint32_t val; IRrecv irrecv(recvPin); decode_results results; #define KEY2 0xFF18E7 //2 #define KEY8 0xFF4AB5 //8 #define KEY5 0xFF38C7 //5 #define KEY4 0xFF10EF //4 #define KEY6 0xFF5AA5 //6 //=====Blink led* #define bLink 13 //Индикатор и аварийный сброс //=====Wired connections* #define HG7881_A_IA 5 //D10 --> Motor B Input A --> MOTOR B + #define HG7881_A_IB 6 //D11 --> Motor B Input B --> MOTOR B - #define HG7881_B_IA 10 //D10 --> Motor B Input A --> MOTOR B + #define HG7881_B_IB 11 //D11 --> Motor B Input B --> MOTOR B - //=====Functional connections* #define MOTOR_A_PWM HG7881_A_IA //Motor B PWM Speed #define MOTOR_A_DIR HG7881_A_IB //Motor B Direction #define MOTOR_B_PWM HG7881_B_IA //Motor B PWM Speed #define MOTOR_B_DIR HG7881_B_IB //Motor B Direction //=====Actual values for "fast" and "slow" depend on the motor #define PWM_SLOW 110 //arbitrary slow speed PWM duty cycle #define PWM_FAST 200 //arbitrary fast speed PWM duty cycle //=====Delays* unsigned long eventTime=0; //eventTime, для паузы, вместо delay, будем использовать функцию millis. void setup(){ Serial.begin(9600); irrecv.enableIRIn(); pinMode( MOTOR_A_DIR, OUTPUT ); pinMode( MOTOR_A_PWM, OUTPUT ); pinMode( MOTOR_B_DIR, OUTPUT ); pinMode( MOTOR_B_PWM, OUTPUT ); digitalWrite( MOTOR_A_DIR, LOW ); digitalWrite( MOTOR_A_PWM, LOW ); digitalWrite( MOTOR_B_DIR, LOW ); digitalWrite( MOTOR_B_PWM, LOW ); //=========== Обработка управления танком по Ir } void tankIr(){ if (digitalRead(recvPin)==LOW) //Читаем данные с Ir. В момент приема данных на выходе появляется пульсирующий (-)отрицательный сигнал eventTime=millis(),digitalWrite(bLink,HIGH); //Если обнаружен отрицательный сигнал запускаем таймер,и включаем таймерПИН //(timer, HIGH); if(millis()-eventTime>100) digitalWrite(bLink,LOW), //Продолжительность работы таймера >100 миллисекунд. И ТаймерПИН выключаем //(timer, LOW) digitalWrite(MOTOR_A_DIR,LOW),digitalWrite(MOTOR_B_DIR,LOW),analogWrite(MOTOR_A_PWM,0),analogWrite(MOTOR_B_PWM,0); //ВЫключаем всё if (irrecv.decode(&results)) { val=results.value; //Сверяем значение из переменной val if (val==KEY2 && (digitalRead(bLink)==HIGH)) digitalWrite(MOTOR_A_DIR,HIGH),digitalWrite(MOTOR_B_DIR,HIGH); if (val==KEY8 && (digitalRead(bLink)==HIGH)) analogWrite(MOTOR_A_PWM,PWM_SLOW),analogWrite(MOTOR_B_PWM,PWM_SLOW); if (val==KEY4 && (digitalRead(bLink)==HIGH)) digitalWrite(MOTOR_A_DIR,HIGH),analogWrite(MOTOR_A_PWM,0); if (val==KEY6 && (digitalRead(bLink)==HIGH)) digitalWrite(MOTOR_B_DIR,HIGH),analogWrite(MOTOR_B_PWM,0); irrecv.resume(); //Receive the next value // Serial.println(val,HEX); } } //=========== Обработка управления танком по Bluetooth void tankBt(){ if (Serial.available()){ byte i=Serial.read(); if (i=='W') {digitalWrite(MOTOR_A_DIR,HIGH),digitalWrite(MOTOR_B_DIR,HIGH);} //Задаём движение вперёд if (i=='S') {analogWrite(MOTOR_A_PWM,PWM_SLOW),analogWrite(MOTOR_B_PWM,PWM_SLOW);} //Задаём движение назад if (i=='A') {digitalWrite(MOTOR_A_DIR,HIGH),analogWrite(MOTOR_A_PWM,0);} //Задаём движение влево if (i=='D') {digitalWrite(MOTOR_B_DIR,HIGH),analogWrite(MOTOR_B_PWM,0);} //Задаём движение вправо if (i=='T') {digitalWrite(bLink,LOW), //Стоп режим, при отпускании клавиш в программе в порт шлется "T" digitalWrite(MOTOR_A_DIR,LOW),digitalWrite(MOTOR_B_DIR,LOW),analogWrite(MOTOR_A_PWM,0),analogWrite(MOTOR_B_PWM,0);} } } void loop(){ tankIr(); tankBt(); }
Код...
Когда не работает IR, постоянно срабатывает 53,54 строки и все выключается. Сделайте с этим что нибудь. Например: включите "таймер" при приеме BT - продублируйте 52 строку перед 69.
Пробовал - невыходит. В случае запуска таймера на tankBt(); светики дружно подмигивают и гаснут. С ir-всё успешно удерживается при этом. Всю голову сломал уже. Я чую что нужно всегда слушать serial а ir на это время опускать. Однако пока bt-модуль физически подключен он всегда слушает сериал (по наблюдениям за
bLink-
пином)Пробовал - невыходит.
Код попытки в студию.
Начинаем отладку: закоментируйте вызов tankIR() из loop и убедитесь что БТ адекватно работает.
светики дружно подмигивают и гаснут
Конечно гаснут, у Вас выключение всего через 100 милисекунд. Вам надо как-то по другому? Вы держите кнопку пульта и код управления передается каждые (чуть больше чем) 100 милисекунд?
Тогда правим логику, например так:
0. вводим флаг сработки от БТ: eventBT
1. В tankBT: Есть сигнал от БТ-> выставляем eventBT=1 (признак что включились от БТ)
2. В tankIR в 52 добавляем сброс флага БТ при срабатывании приемника пульта: eventBT=0
3. В tankIR в условии 53 строки добавляем проверку на выключение ( eventBT=0)
Таким образом, если включились от БТ, выключаем БТ или любой кнопкой на пульте (авто через 100 милисек). Если включили от пульта - как обычно.
Или (просто но не красиво) можно при получении команды от БТ сделать(перед 69 строкой):
eventTime=millis()+10 000
и тогда автовыключение сработает аж через 10 секунд. Или при нажатии на кнопку пульта - как обычно. Или при передаче "Т" через БТ.
Пробовал - невыходит.
Код попытки в студию.
Начинаем отладку: закоментируйте вызов tankIR() из loop и убедитесь что БТ адекватно работает.
Я почему так и пописываю код вынося отдельно функции в loop чтобы проверить как они работают отдельно. При отключенном BT пультик работает шикарно. При отключенном IR блютусинка поет и управляется :) Тоест mxn опри IR что при BT необходимое условие это именно выполнение комманды (вращение, свечение и тп именно при удержании). Самое сложное было именно победить IR - там удержание или по 0хаааааа или по таймеру... По таймеру оказалось проще.
С BT вообще красота код простой и вего пару кБ занимает :)
Так что по одельности работают правильно и при удежании. Асовместно лиш IR сохраняет удержание, BT лиш дружно мигает...
светики дружно подмигивают и гаснут
Конечно гаснут, у Вас выключение всего через 100 милисекунд. Вам надо как-то по другому? Вы держите кнопку пульта и код управления передается каждые (чуть больше чем) 100 милисекунд?
Тогда правим логику, например так:
0. вводим флаг сработки от БТ: eventBT
А вот это я и пытался сделать и логику понимая - описать немог пока. Счас покурю ваши советы и опробую...
вот как решил (не работает как надо, стало чуть хуже даже:( Ввёл новые переменные (ключи состояния)
boolean ir = false;
boolean bt = false;
и вот циклы BT и IR
теперь при разъединении с BT упарвление к IR больше невозвращается и кнопки пультика неработаеют до перезагрузки... Наблюдение продожается....
Вернувшись к исходному коду обнаружил, что если находяс подключенным к BT нажимать кнопки IR то они выполняются как всегда прекрасн. И если при нажатых IR кнопках (удерживаемой любой точнее) посылать в сериал (по BT) то они прекрасно также удерживаются. Стоит отпустить IR то и управление по BT станоистя "мигающим" прерывистым. Чтобы немучить движки я подключил инвесно-светики :).
Я так понял что это обрабатывается if (digitalRead(recvPin)==LOW) //Читаем данные с Ir.
однако если я добавляю в код управления по BT стоку типа digitalWrite(recvPin,LOW); то это НИКАК и ничего неменяет... (это я решил найти самый прсотой способ, обойти флаги и прочее.. но видимо без них никак всё-же)
Вы меня конечно простите, но Вы пробовали два решения которые детально описаны в #5?
В своих попытках ввести флаги, Вы не то пытаетсь контролировать. Еще раз пройдитесь по исходникам, Вы понимаете логику каждой строчки? Всю логику совместной работы Вам портит лишь одна строка автовыключения по таймеру:
Я вижу Вы хотите разобраться, поэтому не пишу код.
Логика использования флага - описано по пунктам в #5.
Очень простое решение со временем действия команд с БТ - описано во второй части #5 ("просто но не красиво...."). Ничего не блокирует, просто послав команду с БТ, без других команд, Ваше устройство будет ей следовать 10 сек(можете поставить своё время. в приведенном примере 10 000=10 сек). Послав "Т" можете остановить. Нажав на пульте - пошлете новую команду. Просто и ничего не ломает!
Это вы меня извините, я боролся с отключением IR (нетеми способами конечное) а нужн овсёже флагами. Итак чт осейчас вышло уделите внимания чуток. В переменные флаг:
byte bt=0; //Флаг состояния Bt-управления
функция tankIr() выглядит так:
а функция tankBt() так:
при этом коды Ir обрабатываются и удерживаются, и комманды Bt так-же. Огромное спасибо за терпливое ожидание моих наблюдений :)
Простых путей неищем (по акваконтроллеру и тепличке помню). С меня фото и видео работы мелкого танка. Осталось дождаться драйвера на моторчики (счас курю форумы и они неочень оказались, управляются по "-" :(
Рад что у Вас получилось. Теперь небольшой совет, что бы не городить ненужные каскадные ИФ-ы (4,5 сторока tankIR), не поленитесь, разберитесь с ЭТИМ. Удачи!