Онкель, та дурдом какой то. Заголовок FF FF, адрес/команда 7F 7F, данные FF FF FF, КС FF. Это макс. Но, данные не могут быть FF, КС не может быть FF - вместо них 0. Получается 0 == FF. А раз так, то 0 мы тоже не можем использовать в данных/КС. Ведь 0 это у нас FF!))) Иначе, чему верить!
Это я к тому что не бывает чудес. Или нужно жертвовать длиной пакета (заголовок, диапазон данных/кс), либо быть готовым к тому что отдельные пакеты могут быть отбракованы. Т.е., определённую кобинацию данных можно НИКОГДА не принять!
Во-первых, 0 == FF не получается никак.
Во-вторых, уже изобретена масса способов, как обойти проблему трактовки отдельных байтов:
1. В протоколе MIDI все команды имеют старший бит 1, а данные - 0.
2. В кодировке UUE каждые 3 байта преобразуются в 4, чтобы избежать как совпадения со служебными символами, так и исключить символы сто старшим битом 1.
3. При кодировании целых чисел переменной длины в каждом байте используется 7 битов, а 8-й служит индикатором окончанияф числа.
Можно произвольным способом сочетать и модифицировать эти способы.
Да, это понятно. Но Онкель то не указывает что у него данные 7-битные! И если в той же КС вместо FF писать 0, чему верить? КС ведь тоже может иметь действительно 0-е значение? Как то неаккуратненько.
а как не заниматца, тут битрикс обновлял и стойкая мысль, что жрать осталось только бизонье дерьмо, но зато его много )))
Настоящий мужик в еде должен быть непривередлив. Хоть говна, лишь бы полный рот. :-)
так это из анекдоту...
я к тому, что написали коду немерянно, только сайт завалился после их автоматического обновления PHP и Percona...и сидел полдня вытаскивал всё ручками...по старинке...из командной строки...
Да, это понятно. Но Онкель то не указывает что у него данные 7-битные!
Совершенно неважна разрядность тех данных, что нужно передать. Хоть 21! Их всегда можно преобразовать в последовательность 7-разрядных. Или 6-разрядных, как в UUE.
Цитата:
И если в той же КС вместо FF писать 0, чему верить? КС ведь тоже может иметь действительно 0-е значение? Как то неаккуратненько.
Это все совершенно непринципиально. Можно в маркер писать 0, а в КС - FF. Можно в маркер писать А5, а к КС - 5А. Можно допустить совпадение КС с маркером, а можно саму КС сделать 7-разрядной - это все несущественные детали реализации.
SoftSerial, судя по исходнику, заблокирует исполнение и будет дёргать ногами, пока байты не закончатся. Так что по выходу из write() будет точно выплюнуто всё.
Набросала скетч, Мастер отправляет данные и переходит в режим приема, Слейв в свою очередь наоборот, принимает данные и переходит в режим передачи. если не ставить паузы, получаю ошибки.
Совершенно неважна разрядность тех данных, что нужно передать. Хоть 21! Их всегда можно преобразовать в последовательность 7-разрядных. Или 6-разрядных, как в UUE.
Это все совершенно непринципиально. Можно в маркер писать 0, а в КС - FF. Можно в маркер писать А5, а к КС - 5А. Можно допустить совпадение КС с маркером, а можно саму КС сделать 7-разрядной - это все несущественные детали реализации.
Мы ведь о физике говорим, о том что будет на выходе, а вы о чём? Понятно что всё что хош можно перевести во всё что хош, была бы фантазия.
if (sSerial.availableForWrite()==3) {
sSerial.write((char *) & ports, sizeof(ports));
}
Так?
Не работает
1. нет, не так.
2. В софт сериале метод write() блокирующий, поэтому вывод не буферизован и не нуждается в проверке.
3. в хард сериале метод write() НЕблокирующий, поэтому перед отправкой новой порции данных можно проверить наличие места в буфере. Только не на равенство чему-бы-то-ни-было.
4. метод write(const uint8_t *, size_t) возвращает число переданных байт. Таким образом можно следить за отсутствием пропажи байт, без проверки наличия свободного места.
5. Если речь про "типовые" Ардуино на 328-ом контроллере, то пропуск данных при передаче вообще невозможен даже без любых проверок. Метод write(uint8_t) возвращает 1, только после передачи байта или размещения его в буфер.
Irinka, на форуме уже неоднократно обсуждалось : если идёт отправка и/или приём то не стоит использовать serial.print или любой другой задержки. Если отправка с delay работает,значит банально приемник не успевает обрабатывать данные. В качестве решения - сохранять в буфер, потом обрабатывать или как говорили выше - оптимизировать алгоритм.
Я помочь в вопросе врятли смогу, так как сам вопрос не понял. Однако - как вы читаете свой код? В нем же полностью отсутсвует форматирование. Я пару минут только фигурные скобки разбирал (где открывается, где закрывается).
Последний код по логике работы вроде бы (не форматированный код я плохо читаю) не отличается от того что не работал. Так что вполне возможно где то операторные скобки не там стояли или ещё где опечатка была.
Последний код по логике работы вроде бы (не форматированный код я плохо читаю) не отличается от того что не работал. Так что вполне возможно где то операторные скобки не там стояли или ещё где опечатка была.
Отличается лишь тем, что начальное значение боулена false. Скобки здесь не причем. При выносе условия в отдельную функцию так же не работает. Фигня какая-то.
#include "Packet.h"
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(9, 10);
byte address="Test";
unsigned long TimeOtpr;
bool FlagTx=true; // Объявление флага TX - заметь -> ИСТИНОЙ
void setup() {
Serial.begin(9600);
radio.begin();
radio.setAutoAck(0);
//radio.setRetries(0, 15);
radio.enableAckPayload();
radio.setPayloadSize(32);
radio.openWritingPipe(address);
radio.setChannel(0x60);
radio.setPALevel (RF24_PA_MAX);
radio.setDataRate (RF24_250KBPS);
radio.powerUp();
}
void loop() {
if(FlagTx){ // Если флаг разрешает отправку, то выполняем отправку "чего-то"
radio.stopListening();
delay(20);
AllThePorts ports;
ports.text = B11100111;
ports.adr = B11111101;
ports.setCRC();
radio.write((char *) & ports, sizeof(ports));
Serial.println("Sent: ");
TimeOtpr = millis();
FlagTx = false; // Этим мы говорим, что уже отправили "что-то", надо бы "перекурить"...
}//if (FlagTx){
if(!FlagTx && millis()-TimeOtpr >= 1000) { // Если отправка запрещена, и мы уже "перекурили" 1 сек, то пора бы и поработать...
FlagTx=true; // Разрешаем отправку
}
}
И если все так же работает, значит это все была не мистика, а невнимательность и куча еще чего (отсутствие комментариев, форматирования - что в совокупности мешало проследить логику и отследить где-же "косяк").
Нашел статью по этим модулям, никакие флаги там не используются. Пропробуй вот этот скетч в "передатчик":
#include <SPI.h> // Подключаем библиотеку для работы с шиной SPI
#include <nRF24L01.h> // Подключаем файл настроек из библиотеки RF24
#include <RF24.h> // Подключаем библиотеку для работы с nRF24L01+
RF24 radio(9, 10); // Создаём объект radio для работы с библиотекой RF24, указывая номера выводов nRF24L01+ (CE, CSN)
int data[2]; // Создаём массив для отправки данных
void setup(){
radio.begin(); // Инициируем работу nRF24L01+
radio.setChannel(5); // Указываем канал передачи данных (от 0 до 127), 5 - значит передача данных осуществляется на частоте 2,405 ГГц (на одном канале может быть только 1 приёмник и до 6 передатчиков)
radio.setDataRate (RF24_1MBPS); // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS - 1Мбит/сек
radio.setPALevel (RF24_PA_HIGH); // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openWritingPipe (0x1234567890LL); // Открываем трубу с идентификатором 0x1234567890 для передачи данных (на одном канале может быть открыто до 6 разных труб, которые должны отличаться только последним байтом идентификатора)
radio.stopListening (); // Вsключаем приемник
}
void loop(){
data[0] = 5; // считываем показания Trema слайдера с вывода A1 и записываем их в 0 элемент массива data
data[1] = 7; // считываем показания Trema потенциометра с вывода A2 и записываем их в 1 элемент массива data
radio.write(&data, sizeof(data)); // отправляем данные из массива data указывая сколько байт массива мы хотим отправить. Отправить данные можно с проверкой их доставки: if( radio.write(&data, sizeof(data)) ){данные приняты приёмником;}else{данные не приняты приёмником;}
}
А этот в приемник:
#include <SPI.h> // Подключаем библиотеку для работы с шиной SPI
#include <nRF24L01.h> // Подключаем файл настроек из библиотеки RF24
#include <RF24.h> // Подключаем библиотеку для работы с nRF24L01+
RF24 radio(9, 10); // Создаём объект radio для работы с библиотекой RF24, указывая номера выводов nRF24L01+ (CE, CSN)
int data[2]; // Создаём массив для приёма данных
void setup(){
delay(1000);
Serial.begin(9600);
radio.begin(); // Инициируем работу nRF24L01+
radio.setChannel(5); // Указываем канал приёма данных (от 0 до 127), 5 - значит приём данных осуществляется на частоте 2,405 ГГц (на одном канале может быть только 1 приёмник и до 6 передатчиков)
radio.setDataRate (RF24_1MBPS); // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS - 1Мбит/сек
radio.setPALevel (RF24_PA_HIGH); // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openReadingPipe (1, 0x1234567890LL); // Открываем 1 трубу с идентификатором 0x1234567890 для приема данных (на ожном канале может быть открыто до 6 разных труб, которые должны отличаться только последним байтом идентификатора)
radio.startListening (); // Включаем приемник, начинаем прослушивать открытую трубу
}
void loop(){
if(radio.available()){ // Если в буфере имеются принятые данные
radio.read(&data, sizeof(data)); // Читаем данные в массив data и указываем сколько байт читать
Serial.print("One data: "); // Выводим data[0]
Serial.println(data[0]);
Serial.print("Two data: "); // Выводим data[1]
Serial.println(data[1]);
Serial.println("Data send complite. Pause 2 cek");
delay(2000);
}
}
write() - правильно. А то похоже было, что через println() собрались отправлять.
С битовыми полями (#13) - наглядней.
write() - правильно. А то похоже было, что через println() собрались отправлять.
С битовыми полями (#13) - наглядней.
Как-то так?
Похоже на то, что надо.
Можно ещё и так:
Онкель, та дурдом какой то. Заголовок FF FF, адрес/команда 7F 7F, данные FF FF FF, КС FF. Это макс. Но, данные не могут быть FF, КС не может быть FF - вместо них 0. Получается 0 == FF. А раз так, то 0 мы тоже не можем использовать в данных/КС. Ведь 0 это у нас FF!))) Иначе, чему верить!
Это я к тому что не бывает чудес. Или нужно жертвовать длиной пакета (заголовок, диапазон данных/кс), либо быть готовым к тому что отдельные пакеты могут быть отбракованы. Т.е., определённую кобинацию данных можно НИКОГДА не принять!
Во-первых, 0 == FF не получается никак.
Во-вторых, уже изобретена масса способов, как обойти проблему трактовки отдельных байтов:
1. В протоколе MIDI все команды имеют старший бит 1, а данные - 0.
2. В кодировке UUE каждые 3 байта преобразуются в 4, чтобы избежать как совпадения со служебными символами, так и исключить символы сто старшим битом 1.
3. При кодировании целых чисел переменной длины в каждом байте используется 7 битов, а 8-й служит индикатором окончанияф числа.
Можно произвольным способом сочетать и модифицировать эти способы.
Да, это понятно. Но Онкель то не указывает что у него данные 7-битные! И если в той же КС вместо FF писать 0, чему верить? КС ведь тоже может иметь действительно 0-е значение? Как то неаккуратненько.
Как можно занимаца всей вотэтой хней, когда душа рвеца на бескрайние, розовопесочные берега острова Самуи?
Как можно занимаца всей вотэтой хней, когда душа рвеца на бескрайние, розовопесочные берега острова Самуи?
а как не заниматца, тут битрикс обновлял и стойкая мысль, что жрать осталось только бизонье дерьмо, но зато его много )))
PS я правда Самуи не знаю, знаю есть Самоа и Новая Гвинея, это оно?
Нет. Самуи - в Сиамском заливе. Придет starbit - опишет в красках.
а как не заниматца, тут битрикс обновлял и стойкая мысль, что жрать осталось только бизонье дерьмо, но зато его много )))
Настоящий мужик в еде должен быть непривередлив. Хоть говна, лишь бы полный рот. :-)
а как не заниматца, тут битрикс обновлял и стойкая мысль, что жрать осталось только бизонье дерьмо, но зато его много )))
Настоящий мужик в еде должен быть непривередлив. Хоть говна, лишь бы полный рот. :-)
так это из анекдоту...
я к тому, что написали коду немерянно, только сайт завалился после их автоматического обновления PHP и Percona...и сидел полдня вытаскивал всё ручками...по старинке...из командной строки...
Да, это понятно. Но Онкель то не указывает что у него данные 7-битные!
Совершенно неважна разрядность тех данных, что нужно передать. Хоть 21! Их всегда можно преобразовать в последовательность 7-разрядных. Или 6-разрядных, как в UUE.
И если в той же КС вместо FF писать 0, чему верить? КС ведь тоже может иметь действительно 0-е значение? Как то неаккуратненько.
Это все совершенно непринципиально. Можно в маркер писать 0, а в КС - FF. Можно в маркер писать А5, а к КС - 5А. Можно допустить совпадение КС с маркером, а можно саму КС сделать 7-разрядной - это все несущественные детали реализации.
Похоже на то, что надо.
Можно ещё и так:
Спасибо.
Всем большое Спасибо.
После отправки данных приходится делать паузу, иначе бывают ошибки при передаче.
Можно как-то отследить момент когда данные полностью отправятся?
https://www.arduino.cc/reference/en/language/functions/communication/serial/availableforwrite/
????????? !!!
После отправки данных приходится делать паузу, иначе бывают ошибки при передаче.
Можно как-то отследить момент когда данные полностью отправятся?
Ошибок передачи быть не может, а вот ошибки приёма легко. Соответственно необходимо чтоб приемник в обратку прислал подтверждение принято/нет.
После отправки данных приходится делать паузу, иначе бывают ошибки при передаче.
Можно как-то отследить момент когда данные полностью отправятся?
Т.е. данные отправятся полностью, можно не делать паузу и проверку на отправку?
SoftSerial, судя по исходнику, заблокирует исполнение и будет дёргать ногами, пока байты не закончатся. Так что по выходу из write() будет точно выплюнуто всё.
Набросала скетч, Мастер отправляет данные и переходит в режим приема, Слейв в свою очередь наоборот, принимает данные и переходит в режим передачи. если не ставить паузы, получаю ошибки.
Совершенно неважна разрядность тех данных, что нужно передать. Хоть 21! Их всегда можно преобразовать в последовательность 7-разрядных. Или 6-разрядных, как в UUE.
Это все совершенно непринципиально. Можно в маркер писать 0, а в КС - FF. Можно в маркер писать А5, а к КС - 5А. Можно допустить совпадение КС с маркером, а можно саму КС сделать 7-разрядной - это все несущественные детали реализации.
Мы ведь о физике говорим, о том что будет на выходе, а вы о чём? Понятно что всё что хош можно перевести во всё что хош, была бы фантазия.
https://www.arduino.cc/reference/en/language/functions/communication/serial/availableforwrite/
????????? !!!
Не работает
https://www.arduino.cc/reference/en/language/functions/communication/serial/availableforwrite/
????????? !!!
Не работает
1. нет, не так.
2. В софт сериале метод write() блокирующий, поэтому вывод не буферизован и не нуждается в проверке.
3. в хард сериале метод write() НЕблокирующий, поэтому перед отправкой новой порции данных можно проверить наличие места в буфере. Только не на равенство чему-бы-то-ни-было.
4. метод write(const uint8_t *, size_t) возвращает число переданных байт. Таким образом можно следить за отсутствием пропажи байт, без проверки наличия свободного места.
5. Если речь про "типовые" Ардуино на 328-ом контроллере, то пропуск данных при передаче вообще невозможен даже без любых проверок. Метод write(uint8_t) возвращает 1, только после передачи байта или размещения его в буфер.
почему тогда, в коде выше, без паузы не работает корректно, ведь и прием и передача выполняются полностью
я не читал "кода выше", я написал, как работает сериал в Ардуино.
Вникать не стану, но, вероятно, у тебя где-то логика алгоритма нарушена. Тебе выше написали, что нужно всегда получать подтверждение приема.
Если проблему устраняет делей, то это всегда проблема в алгоритме. Проблема НЕ в передаче - я тебе это объяснил. Ищи дальше.
Irinka, на форуме уже неоднократно обсуждалось : если идёт отправка и/или приём то не стоит использовать serial.print или любой другой задержки. Если отправка с delay работает,значит банально приемник не успевает обрабатывать данные. В качестве решения - сохранять в буфер, потом обрабатывать или как говорили выше - оптимизировать алгоритм.
Помогите разобраться.
На базе примера ЕвгенийП хочу организовать работу с модулем nRF24L01
Packet.h
Передатчик:
Приёмник:
Не работает условие
//if (radio.available(&pipeNo) >= (int) sizeof(AllThePorts)) {
Serial.println((int)sizeof(AllThePorts));
Выдаёт 3 байта, т.е. всё что я отправляю
Serial.print((int)radio.available(&pipeNo));
Выдаёт 1
И ещё вопрос, что-то я совсем ничего не поняла...
Раскоментировав строки в порт печатается "Sent: " раз в 1 секунду, но данные не отправляются.
Или так:
Работает. Что не так то?
Я помочь в вопросе врятли смогу, так как сам вопрос не понял. Однако - как вы читаете свой код? В нем же полностью отсутсвует форматирование. Я пару минут только фигурные скобки разбирал (где открывается, где закрывается).
Объяснять я мастерица...
Вопрос по #125 посту:
Почему (int)sizeof(AllThePorts) показывает 3 байта, которые я и отправляю, а (int)radio.available(&pipeNo) показывает 1 байт. В чём дело?
#127 пост:
Вот к примеру:
41 строка кода
FlagTx=
true
; или
FlagTx=
false
;
Если в коде присутствует эта строка, данные не отправляются, но сообщение Sent выводится.Я не понима.ю что тут не так, ведь всё же элементарно
https://youtu.be/4pV8iIYvY4s
Путём проб и ошибок обнаружила, что если изначально bool FlagTx будет равен false то всё работает.
Почему так?
Последний код по логике работы вроде бы (не форматированный код я плохо читаю) не отличается от того что не работал. Так что вполне возможно где то операторные скобки не там стояли или ещё где опечатка была.
Последний код по логике работы вроде бы (не форматированный код я плохо читаю) не отличается от того что не работал. Так что вполне возможно где то операторные скобки не там стояли или ещё где опечатка была.
Отличается лишь тем, что начальное значение боулена false. Скобки здесь не причем. При выносе условия в отдельную функцию так же не работает. Фигня какая-то.
PS код отформатировала
А теперь попробуй вот такое:
И если все так же работает, значит это все была не мистика, а невнимательность и куча еще чего (отсутствие комментариев, форматирования - что в совокупности мешало проследить логику и отследить где-же "косяк").
Ну Вы же ничего не изменили в моём скетче, я написала, что работает только при изначальном значении false
https://youtu.be/jor4JwgUqLA
На видео Ваш код, и изменение на false
Мистика)
Я не могу ничего на это ответить.
Не успела ответить. Паузы я куда только не ставила, не в них дело.
И вот так как-то извращаться тоже пробовала (?):
и результат тот же - не отправляется?
Да, пробовала.
Результат тот же, и вместо bool пробовала byte и int, срабатывается если изначально число 0,а не 1
Можешь провести эксперимент (интереса ради)?
Нашел статью по этим модулям, никакие флаги там не используются. Пропробуй вот этот скетч в "передатчик":
А этот в приемник:
И что получится расскажи.
Вусмысле никакие флаги не используются? Где не используются?
В моём скетче я сама добавляю флаг, так как это мне необходимо.
Ваши скетчи не работают, ничего не приходит, нету даже radio.powerUp();
Я с данным оборудованием никогда не работал, примеры взял из статьи (ссылка выше) для эксперимента.
Может кто напишет, кто работал с ними - почему так на «левую» переменную оборудование реагирует.
Я так и не разобраалсь, не получается.
Красавчик помоги...(С) XD
Я заметила, что если ставлю паузу 100 мкс,то по факту она больше
Потому что в коде ещё delay на 20 имеется?
Задержка примерно 1,5 сек получается
Может быть в библиотеки проблема с таймерами?
С паузой я разобралась. Теперь стабильно раз в секунду данные отправляются-принимаются.
Как я поняла модуль "засыпает", и 5 строчкой я его "бужу".
НО:
Без паузы попрежнему не работает
и если изначально значение флага false, то работает
Вот неужели кроме меня тема никому не интересна? XDDD