Перевел код на радиоуправление RNF24, поглючивает. Помогите разобраться..
- Войдите на сайт для отправки комментариев
Чт, 29/10/2020 - 12:37
Написал нужный мне код для управление фотокамерой по ик лучу. Работает прекрасно - доволен. Понадобилось перевести все это дело на дистанционку, для того, чтобы при повороте камеры не терялась связь с пультом. Реализовал затею на двух ардуинках с встроенными NRF24 на борту. Китайцы как всегда балуют.) Разложил скетч на две составляющие, работает, но почему-то при нажатии на любую из кнопок срабатывают все команды одновременно. Подозреваю, что где-то, чего-то накосячил - однозначно, начинающий..
Код который в последствии был безжалостно покромсан.) Кстати, замечания по оптимизации и улучшению оного приму с благодарностью.
#include <IRremote.h> IRsend irsend; static const unsigned long SONY_VIDEO = 0x12B8F; static const unsigned long SONY_MENU = 0x1CB8F; static const unsigned long SONY_MENU_UP = 0x5CB8F; static const unsigned long SONY_MENU_DOWN = 0xDCB8F; static const unsigned long SONY_MENU_RIGHT = 0xFCB8F; static const unsigned long SONY_MENU_LEFT = 0x7CB8F; static const unsigned long SONY_MENU_OK = 0x9cb8f; static const unsigned long SONY_MENU_Play = 0x3cb8f; static const unsigned long SONY_MENU_Fn = 0x4cb8f; static const unsigned long SONY_MENU_Bin = 0xbcb8f; static const unsigned long SONY_MENU_Play2 = 0xe2b8f; static const unsigned long SONY_MENU_Flag = 0x04b8f; static const unsigned long SONY_MENU_Hist = 0xd8b8f; static const unsigned long SONY_ZOOM_PLUS = 0x52B8F; static const unsigned long SONY_ZOOM_LESS = 0xD2B8F; boolean butt_flag = 0; boolean butt; boolean butt1_flag = 0; boolean butt1; boolean butt2_flag = 0; boolean butt2; boolean butt3_flag = 0; boolean butt3; boolean butt4_flag = 0; boolean butt4; boolean butt5_flag = 0; boolean butt5; boolean butt6_flag = 0; boolean butt6; boolean butt7_flag = 0; boolean butt7; boolean butt8_flag = 0; boolean butt8; boolean butt9_flag = 0; boolean butt9; boolean butt10_flag = 0; boolean butt10; unsigned long last_press; void sendToSony(unsigned long hexCode) { for (int i=0; i<3; i++) { irsend.sendSony(hexCode, 20); delay(40); } } void setup(){ pinMode(7, INPUT_PULLUP); pinMode(9, INPUT_PULLUP); pinMode(10, INPUT_PULLUP); pinMode(11, INPUT_PULLUP); pinMode(12, INPUT_PULLUP); pinMode(13, INPUT_PULLUP); pinMode(14, INPUT_PULLUP); pinMode(15, INPUT_PULLUP); pinMode(16, INPUT_PULLUP); pinMode(17, INPUT_PULLUP); pinMode(18, INPUT_PULLUP); pinMode(19, INPUT_PULLUP); } void loop(){ butt = !digitalRead(9); if (butt == HIGH && butt_flag == LOW && millis() - last_press > 50) { butt_flag = HIGH; sendToSony(SONY_VIDEO); last_press = millis(); } if (butt == LOW && butt_flag == HIGH) { butt_flag = LOW; } butt1 = !digitalRead(10); if (butt1 == HIGH && butt1_flag == LOW && millis() - last_press > 50) { butt1_flag = HIGH; sendToSony(SONY_MENU); last_press = millis(); } if (butt1 == LOW && butt1_flag == HIGH) { butt1_flag = LOW; } butt2 = !digitalRead(11); if (butt2 == HIGH && butt2_flag == LOW && millis() - last_press > 50) { butt2_flag = HIGH; sendToSony(SONY_MENU_UP); last_press = millis(); } if (butt2 == LOW && butt2_flag == HIGH) { butt2_flag = LOW; } butt3 = !digitalRead(12); if (butt3 == HIGH && butt3_flag == LOW && millis() - last_press > 50) { butt3_flag = HIGH; sendToSony(SONY_MENU_DOWN); last_press = millis(); } if (butt3 == LOW && butt3_flag == HIGH) { butt3_flag = LOW; } butt4 = !digitalRead(13); if (butt4 == HIGH && butt4_flag == LOW && millis() - last_press > 50) { butt4_flag = HIGH; sendToSony(SONY_MENU_RIGHT); last_press = millis(); } if (butt4 == LOW && butt4_flag == HIGH) { butt4_flag = LOW; } butt5 = !digitalRead(14); if (butt5 == HIGH && butt5_flag == LOW && millis() - last_press > 50) { butt5_flag = HIGH; sendToSony(SONY_MENU_LEFT); last_press = millis(); } if (butt5 == LOW && butt5_flag == HIGH) { butt5_flag = LOW; } butt6 = !digitalRead(15); if (butt6 == HIGH && butt6_flag == LOW && millis() - last_press > 50) { butt6_flag = HIGH; sendToSony(SONY_MENU_OK); last_press = millis(); } if (butt6 == LOW && butt6_flag == HIGH) { butt6_flag = LOW; } butt7 = !digitalRead(16); if (butt7 == HIGH && butt7_flag == LOW && millis() - last_press > 50) { butt7_flag = HIGH; sendToSony(SONY_MENU_Play); last_press = millis(); } if (butt7 == LOW && butt7_flag == HIGH) { butt7_flag = LOW; } butt8 = !digitalRead(17); if (butt8 == HIGH && butt8_flag == LOW && millis() - last_press > 50) { butt8_flag = HIGH; sendToSony(SONY_MENU_Fn); last_press = millis(); } if (butt8 == LOW && butt8_flag == HIGH) { butt8_flag = LOW; } butt9 = !digitalRead(7); if (butt9 == HIGH && butt9_flag == LOW && millis() - last_press > 50) { butt9_flag = HIGH; sendToSony(SONY_MENU_Bin); last_press = millis(); } if (butt9 == LOW && butt9_flag == HIGH) { butt9_flag = LOW; } butt10 = !digitalRead(19); if (butt10 == HIGH && butt10_flag == LOW && millis() - last_press > 50) { butt10_flag = HIGH; sendToSony(SONY_MENU_Play2); last_press = millis(); } if (butt10 == LOW && butt10_flag == HIGH) { butt10_flag = LOW; } }
Код Приемника
#include <SPI.h> #include "nRF24L01.h" #include "RF24.h" #include <IRremote.h> IRsend irsend; RF24 radio(10, 9); byte address[][6] = {"0xE8E8F0F0E1LL"}; byte recieved_data[7]; static const unsigned long SONY_VIDEO = 0x12B8F; static const unsigned long SONY_MENU = 0x1CB8F; static const unsigned long SONY_MENU_UP = 0x5CB8F; static const unsigned long SONY_MENU_DOWN = 0xDCB8F; static const unsigned long SONY_MENU_RIGHT = 0xFCB8F; static const unsigned long SONY_MENU_LEFT = 0x7CB8F; static const unsigned long SONY_MENU_OK = 0x9cb8f; void sendToSony(unsigned long hexCode) { for (int i=0; i<3; i++) { irsend.sendSony(hexCode, 20); } } void setup() { Serial.begin(9600); radio.begin(); radio.setAutoAck(1); radio.setRetries(0, 15); radio.enableAckPayload(); radio.setPayloadSize(32); radio.openReadingPipe(1, address[0]); radio.setChannel(0x60); radio.setPALevel (RF24_PA_MAX); radio.setDataRate (RF24_250KBPS); radio.powerUp(); radio.startListening(); } void loop() { byte pipeNo; while ( radio.available(&pipeNo)) { radio.read( &recieved_data, sizeof(recieved_data)); recieved_data[0], sendToSony(SONY_VIDEO); recieved_data[1], sendToSony(SONY_MENU); recieved_data[2], sendToSony(SONY_MENU_UP); recieved_data[3], sendToSony(SONY_MENU_DOWN); recieved_data[4], sendToSony(SONY_MENU_RIGHT); recieved_data[5], sendToSony(SONY_MENU_LEFT); recieved_data[6], sendToSony(SONY_MENU_OK); } }
Код Передатчика
#include <SPI.h> #include "nRF24L01.h" #include "RF24.h" RF24 radio(10, 9); byte address[][6] = {"0xE8E8F0F0E1LL"}; byte transmit_data[7]; byte latest_data[7]; boolean flag; void setup() { pinMode(3, INPUT_PULLUP); pinMode(4, INPUT_PULLUP); pinMode(5, INPUT_PULLUP); pinMode(6, INPUT_PULLUP); pinMode(7, INPUT_PULLUP); pinMode(8, INPUT_PULLUP); pinMode(11, INPUT_PULLUP); radio.begin(); radio.setAutoAck(1); radio.setRetries(0, 15); radio.enableAckPayload(); radio.setPayloadSize(32); radio.openWritingPipe(address[0]); radio.setChannel(0x60); radio.setPALevel (RF24_PA_MAX); radio.setDataRate (RF24_250KBPS); radio.powerUp(); radio.stopListening(); } void loop() { transmit_data[0] = !digitalRead(3); transmit_data[1] = !digitalRead(4); transmit_data[2] = !digitalRead(5); transmit_data[3] = !digitalRead(6); transmit_data[4] = !digitalRead(7); transmit_data[5] = !digitalRead(8); transmit_data[6] = !digitalRead(11); for (int i = 0; i < 3; i++) { // в цикле от 0 до числа каналов if (transmit_data[i] != latest_data[i]) { // если есть изменения в transmit_data flag = 1; // поднять флаг отправки по радио latest_data[i] = transmit_data[i]; // запомнить последнее изменение } } if (flag == 1) { radio.powerUp(); // включить передатчик radio.write(&transmit_data, sizeof(transmit_data)); // отправить по радио flag = 0; //опустить флаг radio.powerDown(); // выключить передатчик } }
П.С. Не судите строго, учусь..
почему-то при нажатии на любую из кнопок срабатывают все команды одновременно.
Действительно, с чего бы это?
А что написано в приёмнике в строках №№ 50-56? Можете объяснить?
Ну.. тут я разложил команды на прием, назначив каждой свой отдельный канал в массиве - recieved_data[0], recieved_data[1] и т.д. По идее каналы не должны пересекаться - как я понимаю у каждого для этого выделен свой, или я не правильно мыслю?
Ну.. тут я разложил команды на прием, назначив каждой свой отдельный канал в массиве - recieved_data[0], recieved_data[1] и т.д. По идее каналы не должны пересекаться - как я понимаю у каждого для этого выделен свой, или я не правильно мыслю?
почти, а зачищать данные в массиве после исполнения команды?
Ну.. тут я разложил команды на прием, назначив каждой свой отдельный канал в массиве - recieved_data[0], recieved_data[1] и т.д. По идее каналы не должны пересекаться - как я понимаю у каждого для этого выделен свой, или я не правильно мыслю?
Простите, но я этого не понимаю.
Вы можете внятно и конкретно сказать, что делается в каждой из этих строк (лучше и две предыдущие захватите)
Прямо так. В первой строке делается .... и так далее.
Ну.. тут я разложил команды на прием, назначив каждой свой отдельный канал в массиве - recieved_data[0], recieved_data[1] и т.д. По идее каналы не должны пересекаться - как я понимаю у каждого для этого выделен свой, или я не правильно мыслю?
почти, а зачищать данные в массиве после исполнения команды?
К моему стыду мне об этом ничего не известно. ( Конечно догадывался о подобном, даже пытался фигурными скобками оградить каждый элемент массива от остальных, но увы, не помогло.(
Ну.. тут я разложил команды на прием, назначив каждой свой отдельный канал в массиве - recieved_data[0], recieved_data[1] и т.д. По идее каналы не должны пересекаться - как я понимаю у каждого для этого выделен свой, или я не правильно мыслю?
Простите, но я этого не понимаю.
Вы можете внятно и конкретно сказать, что делается в каждой из этих строк (лучше и две предыдущие захватите)
Прямо так. В первой строке делается .... и так далее.
и т.д.
recieved_data[1], sendToSony(SONY_MENU); //прием первого канала массива с последующим выполнением команды
ладно, не мучайтесь, похоже эти строчки для вас как китайская грамота...
Просто поверьте - тут написана чушь.
Обратите внимание, что в исходном коде каждая команда , например sendToSony(SONY_MENU); - исполнялась по условию нажатия кнопки. А в вашем коде никаких условий нет, поэтому при получении любых данных от передатчика все команды выполняются "сами".
Вам не нужно пересылать целый массив, присвойте каждой команде номер пересылайте по радио одно число - номер команды. А в приемнике проверяйте, что за число пришло, и далее просто цепояка операторов if (command == 1) - выполняем первую команду, if (command == 2) - вторую и так далее
и т.д.
Вас кто-то беспардонно обманул.
и т.д.
Ну, вот хотя Вы ни хрена в этом коде не понимаете, даже Вы сказали, что прочитав что-то (неважно, что) из радиотрубы, Вы тут же по очереди выполняете все команды.
Ну, а раз Вы, исполняете все команды всякий раз, когда хоть что-то пришло, то непонятно, почему Вас удивляет что
при нажатии на любую из кнопок срабатывают все команды одновременно.
А Вы чего ожидали? Что написано, то и исполняется.
А потому что врать не надо....
Написал нужный мне код для управление фотокамерой по ик лучу. Работает прекрасно - доволен.
Последний коммент зачту за комплимент. Значит чему-то все-таки научился.))
Подключил светодиоды, чтоб проверить код на работоспособность. Все команды отрабатываются корректно. На каждое нажатие горит соответствующий светодиод. Код передатчика тот же.
П.С. Изучаю параллельно с разбирательствами работу массивов и прочее..
Вам не нужно пересылать целый массив, присвойте каждой команде номер пересылайте по радио одно число - номер команды. А в приемнике проверяйте, что за число пришло, и далее просто цепояка операторов if (command == 1) - выполняем первую команду, if (command == 2) - вторую и так далее
Прислушался, реализовал. Спасибо!
Что получилось..
Приемник
Передатчик