Если с библиотекой всё нормально (в чём я не уверен), то тогда ищите источник помех. Конкретно с Si4463 пока не работал, только с другими модулями. Но разницы нет, т.к. все модули работают одинаково (по SPI).
-Из-за плохой связи могут быть ошибки при передачи пакетов по эфиру. Но во всех современных радиомодулях (включая Si4463) есть аппаратная проверка контрольной суммы. При этом вероятность приёма пакетов с ошибками (по эфиру) крайне низкая ... я бы сказал стремится к нулю)). Например при включенной CRC16, у меня ещё небыло случаев, чтобы радиомодуль принял пакет по эфиру с ошибками. В другой теме экспериментировали с модулями. Радиомодуль может принимать пакеты с ошибка по эфиру, если например отключить проверку CRC и уменьшить длину преамбулы до 1 байт и длину адреса до 2...3 байт. В этом случае (при выключенном передатчике) приёмник радиомодуля синхронизируется по шуму эфира и выдаёт случайный набор битов)).
-Из-за антенны могут быть наводки от работающего передатчика (на полную мощность). Уже обсуждали, когда делали радиоуправляемый самолётик тут - viewtopic.php?f=28&t=141596 Врубаем передатчик на полную мощность - идут ошибки при чтении приёмниго буфера (по SPI) RFM23BP. Потом поставили нормальную антенну и ошибки (помехи от передатчика) пропали)) Есть и другие варианты.
-Из-за помех от различных устройств могут быть ошибки. Например, когда делали радиоуправляемый кораблик, мы использовали nRF24L01. Там помехи были при работающем двигателе. Даже видео сняли)) Врубаем двигатель, зелёный светодиод на пульте мигает - идут ошибки при чтении приёмниго буфера (по SPI) nRF24L01. Помехи такие сильные, что аж сам модуль зависает )) Включается автоматическая перезагрузка модуля.)) https://www.youtube.com/watch?v=cQme_y4TORw Потом запаяли сам радиомодуль nRF24L01 в экран и добавили фильт по питанию и фильтр на двигатель - ошибки (помехи от двигателя) пропали))
-Из-за плохого питания могут быть ошибки. Подключали к импульсному блоку питания, получили ошибки. Даже точно выяснили причину: импульсные помехи от блока питания по проводу MISO, по которому в МК приходят данные из приёмного буфера радиомодуля. )) Поэтому на все модули ставят фильтры по питанию: конденсаторы - обязательно. Дополнительные дросселя - желательно. Отдельные стабилизаторы - желательно. И т.д. Короче, сделали нормальное питание - ошибки (мпульсные помехи от блока питания) пропали)) Гдето видео валяется))
-Ну и наверное самое главное: мы во всех схемах используем контрольные суммы. Считаем CRC в МК и добавляем к каждому пакету. При этом что бы не случилось (помехи по проводам, обрав проводов радиомодуля, отключение питания радиомодуля или падение питания ниже нормы... и т.д.) пакеты с ошибками у нас не проходят)) Т.е. ложных команд (в радиоуправляемых схемах) у нас нет.
Кратко вот. ))
P.S. А вообще... если ошибки идут часто, то источник помех обычно обнаруживается быстро)) Если есть приборы, то совсем хорошо)) Но обычно достаточно просто подключить радиомодуль напрямую к МК и погонять туда-сюда пустые пакеты, при разных условиях: -на разной скорости SPI (маловероятно, но на всякий случай). -на разной мощности передатчика (мин/макс). -от отдельного источника питания (от батарей). -при отключеном дополнительном оборудовании (всё лишнее отключить). -и т.д.
Зарегистрирован: Сб май 07, 2016 16:19:58 Сообщений: 13
Рейтинг сообщения:0
Попробую погонять устройство дома, на столе, посмотрю будут ли идти такие глюки или нет.. Сейчас передающее устройство стоит в мастерской на другом конце огорода. Радиоприемник запитан сейчас от платы stm32f103c8t6(китай), по питанию si4463 поставил электролит 100 мкф и керамику 0.1 мкф. Кстати модуль радио такой rf4463pro он с экраном идет, заказывал с китая. БП AC-DC 220 в 5 на 3 Вата на него повесил электролит 680 мкф. Антенна спиралька. Все это дело на макетной плате и запихано в корпус от маршрутизатора.
И еще возник такой вопрос по настройке модуля. В даташите есть схема включения, где используется одна антенна на прием и передачу. И направление настраивается выводами gpio2 и gpio3. Это переключение происходит автоматически или надо в коде самому менять? Просто по библиотеки от NiceRF там настраивается один раз и больше в коде нигде не меняется. Спойлер
Код:
// set antenna switch,in RF4463 is GPIO2 and GPIO3 // don't change setting of GPIO2,GPIO3,NIRQ,SDO buf[0] = RF4463_GPIO_NO_CHANGE; //gpio0 buf[1] = RF4463_GPIO_NO_CHANGE; //gpio1 buf[2] = RF4463_GPIO_RX_STATE; //gpio2 buf[3] = RF4463_GPIO_TX_STATE; //gpio3 buf[4] = RF4463_NIRQ_INTERRUPT_SIGNAL; buf[5] = RF4463_GPIO_SPI_DATA_OUT; setCommand(6,RF4463_CMD_GPIO_PIN_CFG,buf);
В библиотеке RadioHead при настройке модуля на прием или передачу настраиваются и выводы, но как я понял это gpio0 и gpio1 судя по коду. Так как там записывают два байта, а первые два байта в регистре GPIO_PIN_CFG 0x13 это gpio0 и gpio1. Спойлер
Код:
void RH_RF24::setModeRx() { if (_mode != RHModeRx) { // CAUTION: we cant clear the rx buffers here, else we set up a race condition // with the _rxBufValid test in available()
// Tell the receiver the max data length we will accept (a TX may have changed it) uint8_t l[] = { sizeof(_buf) }; set_properties(RH_RF24_PROPERTY_PKT_FIELD_2_LENGTH_7_0, l, sizeof(l));
// Set the antenna switch pins using the GPIO, assuming we have an RFM module with antenna switch uint8_t gpio_config[] = { RH_RF24_GPIO_HIGH, RH_RF24_GPIO_LOW }; command(RH_RF24_CMD_GPIO_PIN_CFG, gpio_config, sizeof(gpio_config));
void RH_RF24::setModeTx() { if (_mode != RHModeTx) { // Set the antenna switch pins using the GPIO, assuming we have an RFM module with antenna switch uint8_t config[] = { RH_RF24_GPIO_LOW, RH_RF24_GPIO_HIGH }; command(RH_RF24_CMD_GPIO_PIN_CFG, config, sizeof(config));
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
В первой библиотеке выводы GPIO настроены на автоматическое переключение антенного коммутатора при изменении режима работы прием/передача. Во второй эти выводы настроены на ручное переключение из программы пользователя. Мой Вам совет - не пользуйтесь библиотеками написанными непонятно кем, лучше напишите свои. У меня по этим чипам статья есть здесь, а то что в ней не затронуто (нарпример переключение коммутатора) описано в документации на чип.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Всем доброго времени суток. Просьба помочь новенькому До этого дальше ардуино с диодиками не ходил... Для реализации определенной задачи, начинаю разбираться с модулем сделанным в Китае (E30-170T20D). На нем стоит SI4463 ревизии 1B. Управляется он китайским аналогом STM8LG6. Прошивку пишу в IAR. Собственно SI4463 "не взлетает" Вроде поднял SPI между STM8L и SI4463 (если первой командой даю PART_INFO, то возвращаются байтики: 11 44 63 00 00 0F 00 03), но вот если подаю POWER_UP, то SI4463 перестаёт подавать признаки жизни, по SPI после READ_CMD_BUFF никогда не приходит CTS (0xFF), только 0. CTS на GPIO1 в виде 1 тоже теряется...
Мой код: Спойлер
Код:
#include <iostm8l151g6.h> #include <intrinsics.h> //Здесь описана функция __enable_interrupt ().
void si4463_nSEL_High(void) { __enable_interrupt(); // re-enable interrupts while (SPI1_SR_bit.BSY){} // wait not busy PB_ODR_bit.ODR4 = 1; // nSEL(SI4463) = NSS(STM8L) = High delay(5440); // 340 µs }
// Запись байта в регистр SPI и чтение (для тактирования) unsigned char si4463_spi_shift_byte(unsigned char tx) { while(!SPI1_SR_bit.TXE){} SPI1_DR = tx; while (!SPI1_SR_bit.RXNE){} return SPI1_DR; }
// Посылка данных по SPI (несколько байт) void si4463_send_config_line(unsigned char* buf, unsigned char size) { unsigned char i; si4463_nSEL_Low(); i=0; while (i < size) { si4463_spi_shift_byte(buf[i]); i++; } si4463_nSEL_High(); }
// Приём данных от трансивера (после команды) unsigned int si4463_cmd_response(char* buf, unsigned int size, unsigned short int maxReq) { unsigned int i; while(maxReq > 0) { si4463_nSEL_Low(); i = 0;
while (i < (size + 2)) { if(i == 0) { // Первым делом посылаем команду "read CTS and the command response". buf[0] = si4463_spi_shift_byte(0x44); } else if (i == 1) { delay(1600); // 100 µs if(si4463_spi_shift_byte(0xFF) != 0xFF) { // Если вернулся не 0xFF (не CTS), то повтор запроса maxReq--; break; } } else { // Принимаем ответ и складываем в буфер (помним, что первые два запроса были "накладными расходами") buf[i-2] = si4463_spi_shift_byte(0xFF); } i++; }
si4463_nSEL_High(); if (i > 1) { return 1; // Данные в буфере } } return 0; // Не дождались CTS }
// Переназначение USART порта на альтернативные выводы (у нас так распаяно) - USART1_TX on PA2 and USART1_RX on PA3 SYSCFG_RMPCR1_bit.USART1TR_REMAP = 1;
// Переназначение тактирования USART (по умолчанию это нога висит на GPIO SI4463, а оно нам надо?) - USART1_CK mapped on PA0 SYSCFG_RMPCR1_bit.USART1CK_REMAP = 1;
// SPI pin maps SYSCFG_RMPCR1_bit.SPI1_REMAP = 0; /* SPI1_MIS0 is mapped on PB7 SPI1_MOSI is mapped on PB6 SPI1_SCK is mapped on PB5 SPI1_NSS is mapped on PB4 */
К сожалению пайка такова, что подключить лог-анализатор не вышло Как выяснилось в коде и подключении проблем нет. В данном случае ситуация такова: если выполняя команду POWER_UP, вторым байтом идет не 1, а 0, то микруха начинает вести себя адекватно, выдавая CTS. Этот байт в документации интерпретируется 1 - Boot main application image, 0 - Stay on bootload. Собственно вопросы: что за bootload (пока не нашёл инфы), как исправить (т.к. после конфигурирования все равно не фунцикляет )???
Хмммм. У меня в документации на ревизию В написано, что опция FUNC=1 единственная для перевода чипа в режим PRO. Я всегда посылал следующую последовательность байтов для POWERUP: 0x02 0x01 0x00 0x01 0xC9 0xC3 0x80 где последние 4 байта - это частота кварца (01C9C380 = 30.000.000 гц = 30 мгц). Правда, китайские платы никогда не использовал.
Выяснилось, проблема в железе... И ещё в этом модуле кварц 26МГц стартует не с вывода XOUT SI4464, а с вывода управляющей STM8, также в команде POWER_UP необходимо включить XTAL_OPTIONS TCXO иначе не работает.
Написан код передатчика, загружен в один из модулей, нахожусь в полной уверенности что он что-то передаёт - радиостанция характерно шипит на этой частоте. Но вот с приёмником не справился Прерывание по приёму поступают хаотично и в FIFO валит мусор при этом в эфире чисто. Скрины WDS:
Пояснения к коду: процедура spi_send_buf по всем правилам отправляет из буфера обозначенное кол-во байт, si4463_get_response по всем правилам принимает от si4463 ответ, второй параметр сколько байт принять, третий - кол-во попыток в случае с задержкой CTS. На выводе PC0 висит nIRQ. Кусок кода: Спойлер
Это я понимаю. Но мы же пытаемся принять пакет с определенной преамбулой и синхрословом... Конкретно в моём случае, я загружаю следующий конфиг, как в приёмник, так и в передатчик: Спойлер
Код:
/* // Set properties: RF_PREAMBLE_TX_LENGTH_9 // Number of properties: 9 // Group ID: 0x10 // Start ID: 0x00 // Default values: 0x08, 0x14, 0x00, 0x0F, 0x21, 0x00, 0x00, 0x00, 0x00, // Descriptions: // PREAMBLE_TX_LENGTH - Configure length of TX Preamble. // PREAMBLE_CONFIG_STD_1 - Configuration of reception of a packet with a Standard Preamble pattern. // PREAMBLE_CONFIG_NSTD - Configuration of transmission/reception of a packet with a Non-Standard Preamble pattern. // PREAMBLE_CONFIG_STD_2 - Configuration of timeout periods during reception of a packet with Standard Preamble pattern. // PREAMBLE_CONFIG - General configuration bits for the Preamble field. // PREAMBLE_PATTERN_31_24 - Configuration of the bit values describing a Non-Standard Preamble pattern. // PREAMBLE_PATTERN_23_16 - Configuration of the bit values describing a Non-Standard Preamble pattern. // PREAMBLE_PATTERN_15_8 - Configuration of the bit values describing a Non-Standard Preamble pattern. // PREAMBLE_PATTERN_7_0 - Configuration of the bit values describing a Non-Standard Preamble pattern. */ #define RF_PREAMBLE_TX_LENGTH_9 0x11, 0x10, 0x09, 0x00, 0x08, 0x18, 0xF7, 0x0F, 0x30, 0x00, 0x33, 0x33, 0x33
/* // Set properties: RF_SYNC_CONFIG_5 // Number of properties: 5 // Group ID: 0x11 // Start ID: 0x00 // Default values: 0x01, 0x2D, 0xD4, 0x2D, 0xD4, // Descriptions: // SYNC_CONFIG - Sync Word configuration bits. // SYNC_BITS_31_24 - Sync word. // SYNC_BITS_23_16 - Sync word. // SYNC_BITS_15_8 - Sync word. // SYNC_BITS_7_0 - Sync word. */ #define RF_SYNC_CONFIG_5 0x11, 0x11, 0x05, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00
Кстати пакет который передается передатчиком (другим модулем), в нужном формате, я не принимаю
Хорошо-бы посмотреть коды Ваших функций spi_send_buf() и si4463_get_response(). Зря Вы делаете всю обработку в ISR. Это следует делать в main(). Перевод чипа в режим приёме происходит не мгновенно. Следует читать статус чипа до тех пор пока он не укажет состояние приёма. И только потом гасить флаги прерывания в чипе. Вот пример как это сделано у меня для чипа Si4362 - для Si4463 аналогично. Аргументы функций - это массивы байтов для соответствующих команд. Например, const uint8_t SI4362_start_rx[] = {0x08, 0x32, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08}; // START_RX где первый байт у меня - это длина массива.
Код:
do { SI4362_write(SI4362_rqst_device_state); // Send REQUEST_DEVICE_STATE command SI4362_read(SI4362_read_cmd_buff, 3); // Send READ_CMD_BUFF command } while (SPIbuf[1] != 0x08); // loop that waits for RX state SI4362_write(SI4362_clear_irq); // Send CLEAR_IRQ command
Ещё неясно зачем ограничивать число попыток чтения инфы из чипа в si4463_get_response()? Почему просто не дождаться CTS Вашей функцией waitCTS() и потом уже производить приём наверняка. Также, зачем вызываете waitCTS() после spi_send_buf() в некольких местах. Это не ошибка, но зачем?
К сожалению не могу отредактировать свой предыдущий пост Решил выложить всю информацию о модуле E30-170T20D, вдруг кому пригодится и поможет разобраться в моём косяке. Фото: Спойлер
Схема коммутации MCU & SI446:
Скрины настройки в WDS: Спойлер Без подчёркнутой галки SI4463 после POWER_UP не выдаёт CTS
В поле field видно, что полезны 24 байта.
При таком же загруженном конфиге в передатчик, на радиостанции на указанной частоте слышу характерный звук с паузой между пакетами, которую я использую при передаче - делаю вывод, что передаёт
В общем, первая строка, результат PART_INFO. Следующие строки: 2-а байта RX FIFO, и TX FIFO, 0xFF разделитель, 0x18 = 24 данные из RX FIFO. Данные приходят 2-3 раза в секунду... Откуда не знаю Передаю я 1-н пакет в ~3 сек, патерн 24 байта. Пакет, который передаётся моим передатчиком, не принимается
Ser60: К сожалению дополнительная проверка REQUEST_DEVICE_STATE не дала ясности, трансивер всегда отвечает байтами 8, 0. Т.е.: RX state, CURRENT_CHANNEL: 0. В команде START_RX параметры NEXT_STATE выставлял 8-ки, изменений нет.
По поводу ограничения попыток - предполагаю, что в некоторых случаях придётся ресетится... Привык я так писать
Попробуйте после приёма первого пакета отключить передатчик. Если по-прежнему будет приниматься тот-же пакет, то дело явно в приёмнике. После чтения пакета из Fifo попробуйте clear Fifo и послать в приёмник код сброса флагов прерывания до перехода к приёму нового пакета. Дайте знать что получится. Может это Вы и делаете уже, я сейчас подробно код не смотрел.
Это содержание RX_FIFO. Передатчик Si4012, приемник Si4463, 169.4MГц, ООК, 32kbps. Все настройки Si4463 из WDS. Преамбюл 4 байта 0xAA, синхрослово 2 байта 0x2D 0xD4 (0xB4 0x2B в настройки приемника), одно поле (18 байт) для данных. GPIO_1 = CTS, GPIO_3 = VALID_PREAMBLE, IRQ = VALID_SYNC Получаю преамбюл и синхрослово (GPIO_3 = VALID_PREAMBLE и IRQ = VALID_SYNC переходят из 0 в 1 и наоборот, но ничего больше этого.
Статьи Ser60 читал.
P.S. Извините за русский. Я болгар и русский учил где-то сорока лет назад...
Коля, неясно зачем Вам нужно IRQ = VALID_SYNC? Я всегда ставлю IRQ=0x27 и прерывание определяется битами в WDS конфирурации. В противном случае если читаете FIFO сразу после принятия синхрослова, то приём пакета в этот момент может быть не завершено, особенно если читаете из FIFO быстрее чем принимаются данные. Также рекомендую обнулять RX FIFO каждый раз перед принятием нового пакета (из Вашего сообщение неясно делается-ли это).
Можете привести фрагмент кода где ожидаете приём пакета и чтения его из FIFO в приёмнике и код передачи пакета в передатчике? А также осциллограммы на выводах SPI включая CTS. Ну и, наконец, конгигурацию регистров приёмника и передатчика.
Сейчас этот форум просматривают: тишина и гости: 42
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения