Официальный сайт компании Arduino по адресу arduino.cc
nRF24L01 криво работает обратная связь с массивом
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Пнд, 21/01/2019 - 20:57
Тестирую обратную связь в nRF24L01, но в ответ на отправленые данные приходят предидущие отправленные данные, не могу понять в чем дело (
Заренее благодарен всем, кто подскажет в чем дело!
Приемник:
#include <SPI.h> #include "nRF24L01.h" #include "RF24.h" #define CH_NUM 0x60 #define SIG_POWER RF24_PA_MAX #define SIG_SPEED RF24_1MBPS RF24 radio(9,10); byte addresses[][6] = {"1Node","2Node"}; int data[2]; void setup(){ Serial.begin(9600); radio.begin(); radio.setAutoAck(1); radio.enableAckPayload(); radio.setRetries(0,15); radio.setPayloadSize(4); radio.setChannel(CH_NUM); radio.setPALevel(SIG_POWER); radio.setDataRate(SIG_SPEED); radio.openWritingPipe(addresses[1]); radio.openReadingPipe(1,addresses[0]); radio.startListening(); radio.powerUp(); } void loop(){ byte pipeNo, gotByte; while (radio.available(&pipeNo)){ radio.read(&data, sizeof(data)); Serial.print(data[0]); Serial.print(" ");Serial.println(data[1]);Serial.println("\n"); radio.writeAckPayload(pipeNo,&data, sizeof(data) ); } }
Передатчик:
#include <SPI.h> #include "nRF24L01.h" #include "RF24.h" #define CH_NUM 0x60 #define SIG_POWER RF24_PA_MAX #define SIG_SPEED RF24_1MBPS RF24 radio(9,10); byte addresses[][6] = {"1Node","2Node"}; int data[2]; int data_in[2]; void setup(){ Serial.begin(9600); radio.begin(); randomSeed(analogRead(A0)); radio.setAutoAck(1); radio.enableAckPayload(); radio.setRetries(0,15); radio.setPayloadSize(4); radio.setChannel(CH_NUM); radio.setPALevel(SIG_POWER); radio.setDataRate(SIG_SPEED); radio.openWritingPipe(addresses[1]); radio.openReadingPipe(1,addresses[0]); radio.stopListening(); radio.powerUp(); } void loop(){ data[0] = random(-100, 100); data[1] = data[0]*2; Serial.print(data[0]); Serial.print(" ");Serial.println(data[1]); //печатаем то, что хотим отправить if(radio.write(&data,sizeof(data))){ Serial.println("KK"); // печатаем кк, если отправка успешна while(radio.available()){ radio.read(&data_in, sizeof(data_in)); Serial.print(data_in[0]); Serial.print(" ");Serial.println(data_in[1]); // получаем обратно то, что отправили, но приходит не то, что отправили, а то что отправили в прошлый раз } } else{ Serial.println("NN"); } Serial.println("\n"); delay(3000); }
Ну, так и написано. Вы не успели отправить, тут же читаете. Прочитаете предыдущие. АВы чего ожидали?
Попробуйте отправить, подождать ответа, принять и только потом отправлять новое.
Вставил задержку, не помогло, сначала так 10 секунд и ждет ответа, а уже потом принимает прошлые отправления...
Я просто хотел, что бы данные проверялись, а если не совпадают, то отправляем заново.
radio.write(&data,sizeof(data)) - выдает true если успешно отправило или оно еще и сверяет данные?
Могу ли я быть уверен, что если radio.write(&data,sizeof(data)) выдала true, то на другой стороне у меня правильныые данные, или это просто информация о том что данные были приняты ?
И все равно интересно, почему оно так странно себя ведет...
Я просто хотел, что бы данные проверялись, а если не совпадают, то отправляем заново.
radio.write(&data,sizeof(data)) - выдает true если успешно отправило или оно еще и сверяет данные?
Могу ли я быть уверен, что если radio.write(&data,sizeof(data)) выдала true, то на другой стороне у меня правильныые данные, или это просто информация о том что данные были приняты ?
И все равно интересно, почему оно так странно себя ведет...
Получилось разобраться?
У меня аналогичная проблема. Все это из-за того что writeAckPayload не успевает в заданный интервал времени отправить ответ т.к. перед ним есть функция обработки данных. Поэтому в ответ уходят данные из FIFO буфера.
"Не успевает"? А по-моему он и не должен. Почитайте описание протокола , ack_payload всегда плсылает данные, подготовленные в предыдущем цикле. Чтобы получить актуальный ответ - просто пошлите запрос дважды с небольшим промежутком
Или тупо отключить функцию ack и отправлять ответы вручную.
Не совсем верно. В описании написано одно, а практика показывает что он отправляет каждый раз то что получил.
Но вот что я вчера заметил, если не обрабатывать ответ а сразу его пересылать обратно, передатчик получает именно то что передал, а если на приемнике производить обработку ответа и потом только его отправлять, приемник передает правильные данные, но передатчик получает то что было передано в прошлый раз. Отсюда можно сделать вывод что это не проблема приемника и его ответов, а проблема передатчика который по истечении таймаута ожидания ответа, читает из FIFO то что было прислано прошлый раз.
Вывод: на передатчике перед получением ответа необходимо очищать буфер принятых данных, но пока я не разобрался как, ибо функция эта сделана локальной. и применить ее не получается. (Возможно это сымитирует ситуацию потери пакета ACK, но это я не уверен. не вникал в принцип его получения. и передатчик сам повторно запросит повторение отправки ACK пакета при включенной setAutoAck(1) .)
Не совсем понял как это реализовать? Если отключить enableAckPayload() передатчик не будет обрабатывать АСК пакеты от приемника т.к. их не запрашивал. В данном случае ответить передатчику не представляется возможным. Если только не менять в корне код программы для реализации полудуплекса. Что для меня является не приемлимым.
Или я в корне не правильно понял идею, подскажи пожалуйста, что имел в виду?
передатчик не будет обрабатывать АСК пакеты от приемника т.к. их не запрашивал
Передатчик делает то, на что ты его запрограммировал, гений. Напишешь код обработки - будет обрабатывать.
Верно. но в рамках имеющегося инструментария.
Если функционально отключить запрос ответа, и реализовать его же только по другому чем это отличается от изначального функционала?