Раскодировать текст при передаче через nrf24l01
- Войдите на сайт для отправки комментариев
Добрый день.
Когда-то не очень давно дали мне хороший код, помогающий модулям nrf работать в двух режимах. Я успешно его применял, не заморачиваясь насчет букв (передавал температуру цифрами). Потом только буквы. Попытался передавать смешанные сообщения... и нашел проблему. Проблема следующая: это код стационарного (постоянно подключенного к компу) устройства, которое я хочу научить интерпретировать сообщения вида: "tok 20 14" (запрос понятен. требуется температура. температура 20,14 градусов цельсия) наряду с обычными сообщениями, содержащими только текст.
if(radio.available())
{
char data[128] = "";
radio.read(data, 128);
Serial.println("receiving");
for (int i=1;i<128;i++)
{
if (data[i] != 0)
{
Serial.print(data[i]);
}
}
}
чтобы нормально декодировался текст, data[] делаем массивом символов, но при этом цифры интерпретируются как код символов. Чтобы нормально декодировать цифры, делаем data[] массивом байт, при этом текст тоже декодируется как набор байт.
Ничего похожего на процедуры конвертации в известном мне смысле я не нашел. Могу переложить операцию на ПК, но все же хочется добиться этого в ардуино, ибо в планах такое же, но автономное устройство.
Спасибо.
Во-первых, совершенно не ясно зачем и как вы пытаетесь читать 128 байт, так как максимальный размер передаваемого пакета составляет 32 байта, а то что свыше просто обрезается.
Во-вторых, прочтите что написали и сформулируйте вопрос, потому как совершенно не понятно чего хотите.
Во-первых, совершенно не ясно зачем и как вы пытаетесь читать 128 байт, так как максимальный размер передаваемого пакета составляет 32 байта, а то что свыше просто обрезается.
32 байта - это что? Длина буфера или определение протокола?
Если длина буфера, то это не является ограничением для длины принимаемого пакета - читайте сколь угодно длинные последовательности. Главное успевайте делать это вовремя.
Попробую)
128 возникло в ходе экспериментов, про ограничения пакета не знал.
Хочу передать и принять пакет, содержащий и текст и числа, чтобы текст в Serial monitor был текстом, а числа - числами (и с ними можно было бы провести арифметические операции)
Сокращая вопрос: точная длина текстового сообщения неизвестна, точное количество цифр тоже неизвестно. Можно ли как-то создать и передать "массив массивов", например такой (приведу два разных варианта):
arr[0]: Unknown command
arr[1]:
arr[2]:
*Получили сообщение о том, что команду система не поняла*
arr[0]: Readings correct
arr[1]: 25
arr[2]: 55
*Получили сообщение с текущей температурой*
Все неудобство в том, что radio.write и radio.read пользовательскую структуру не примут
Вы бы указали, какими библиотеками пользуетесь.
Судя по именам используемых функций, radio - это, например, не объект класса Nrf24l.
Виноват,
Код использовал отсюда
Все неудобство в том, что radio.write и radio.read пользовательскую структуру не примут
Почему? А преобразование типов на что?
Да и судя по декларациям
функции едят что угодно.
Все неудобство в том, что radio.write и radio.read пользовательскую структуру не примут
Неправда - замечательно примет.
Это из одного из моих скетчей. Работает превосходно.
sensor - в данном случае как раз является структурой.
Во-первых, совершенно не ясно зачем и как вы пытаетесь читать 128 байт, так как максимальный размер передаваемого пакета составляет 32 байта, а то что свыше просто обрезается.
32 байта - это что? Длина буфера или определение протокола?
Если длина буфера, то это не является ограничением для длины принимаемого пакета - читайте сколь угодно длинные последовательности. Главное успевайте делать это вовремя.
bool RF24::read( void* buf, uint8_t len ) { // Fetch the payload read_payload( buf, len ); // was this the last of the data available? return read_register(FIFO_STATUS) & _BV(RX_EMPTY); }uint8_t RF24::read_payload(void* buf, uint8_t len) { uint8_t status; uint8_t* current = reinterpret_cast<uint8_t*>(buf); uint8_t data_len = min(len,payload_size); uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len; //printf("[Reading %u bytes %u blanks]",data_len,blank_len); csn(LOW); status = SPI.transfer( R_RX_PAYLOAD ); while ( data_len-- ) *current++ = SPI.transfer(0xff); while ( blank_len-- ) SPI.transfer(0xff); csn(HIGH); return status; }так что прочитать более 32 байт не получится. Поэтому просто пишите функии, которые будут
передавать/принимать ваш массив по 32 байта.
Ustas, дайте пожалуйста ссылку на код, вроде что-то знакомое, а найти не могу.
Ustas, дайте пожалуйста ссылку на код, вроде что-то знакомое, а найти не могу.
http://habrahabr.ru/post/171613/ - тут выкладывал куски кода
Спасибо, как выяснилось искал не там)
За код спасибо, почти разобрался.
Остался последний вопрос: я задал такую структуру
typedef struct{ char comment[32]; int value1; int value2; int value3; }message;Она идентична и у приемника и у передатчика.
Для теста задал:
responce.comment = "I'm online and waiting"; responce.value1 = 25; responce.value2 = 19; radio.write(&responce, sizeof(responce));Система ругается:
Система требует строку определенного размера, к тому же считает ее константой, у меня же строки будут разные по длине. А заменить тип на String не выриант, поскольку по неясным причинам на него плохо реагирует serial.println (искажение кодировки, да и затратная по памяти эта штука)
Что предпринять?
Для теста задал:
responce.comment = "I'm online and waiting"; responce.value1 = 25; responce.value2 = 19; radio.write(&responce, sizeof(responce));Система ругается:
Попробуйте первую строчку переписать так:
я вот так делаю:
Обе функции суть одно и то же, только в memcpy размер передаваемого пакета указывается явно, а strcpy, предназначенная для обработки строк, копирует любое количество байтов, пока не стретится нулевой (0x00 - стандартный признак конца строки в си).
Спасибо, работает.
Правда, нашел еще один косяк:
Передаю, меняю числа
Принимаю и читаю по-всякому.
if(radio.available()) { message sensor; radio.read(&sensor, sizeof(sensor)); Serial.println(sensor.comment); Serial.println(int(sensor.value1)); Serial.println(sensor.value2); }В мониторе стабильные
-4061
-8720
Чувствую я, что где-то накосячил, но где? (Если передавать не структурой, а по очереди, то все нормально)
Перечитайте сообщения #1 и #8 и посчитайте количество байт вашей структуры.
typedef struct{ char comment[26]; int value1; int value2; int value3; }message;Блин) Спасибо.
Привык я к защите от дурака высокоуровневых языков ООП...
И снова я со своими глупостями.
А нет ли более изящного способа передать "смесь". Например, имеем
и со стороны приемника
Помогите вставить нужные преобразования вместо многоточий. Либо поменять что-то еще. Вариант со структурой тоже катит, но мне так или иначе требуется преобразование. Основное условие: в порту нужна строка вида "temp25" одним махом, ее будем парсить более высокоразвитой программой
Ну тогда уж не
а
Ибо зачем нужна информация о длине пакета уже после его передачи? Мертвому припарка...
Не, библиотеку, реализовывающую функцию radio, не я писал, там именно такой порядок параметров. Дальше он может и в обратном порядке передавать, это мы не знаем (да нам и не важно)
Из библиотеки:
Скорее всего step962 что-то не так понял.
Да, принял приведенные строчки за псевдокод и предположил, что речь идет о формировании пакета для передачи... А это было обращение к конкретной библиотечной функции.