Приветствую! Вот есть задачка сделать передачу данных между двумя ATmega328p. Принимаю данные по UART и по SPI заливаю их в SX1276. Ну и на принимающей стороне тот же цикл только наоборот. Все на словах конечно волшебно, но очень уж я устал ковырять этот SX с его кучей регистров. Если у кого был опыт общения с данной железкой, прошу отписаться. На текущий момент данные по UART принимаю, но никак не догоняю как их закинуть по SPI в радиомодуль.
Так вопрос то обо что? О работе с радиомодулем? При чем тут UART, он простой как огурец. Может есть библиотки готовые от этого SX? С них и начать бы.
это правда. Я тоже ковырял два вечера, потом настигла другая задача. Пока лоры в стороне лежат в не распакованном пакетике. в ютубе есть канал "электроника в объективе". Там Руслан и код выкладывал и на дальность тестировал. На какой частоте планируешь работать?
а чего их ковырять то? есть же готовые библиотеки вот это не пробовали? https://github.com/sandeepmistry/arduino-LoRa
На 868 МГц собираюсь. Проект подразумевает сделать из ATmega328p что-то вроде преобразователя из одного протокола в другой. Данные получаю по UART, преобразую как надо и дальше по LoRa кидаю их на приемную сторону. Про библиотеки знаю, пробовал. Но при попытке использовать UART и библиотеки для LoRa происходит магия. UART отваливается, данные не принимаются. Поэтому было принято решение LoRa ковырять по регистрам.
простите, если вы не в состоянии готовую библиотеку с UART подружить - кудаж вы в регистры-то полезли...
Приехали LoRa на 1276 от NiceRF. С библиотекой, что выше - https://github.com/sandeepmistry/arduino-LoRa на Ардуино Нано-Уно прекрасно работают через SPI и туда-сюда данные гоняют. Примеры там прям внутри вполне достаточные. А вот попробовал на один SPI натравить и LoRa и nRF24L01+, соответственно SCK(13), MISO(12), MOSI(11), SS LoRa(10), NRESET LoRa(9) и те же SCK(13), MISO(12), MOSI(11) для nRF24L01+ и CE(7), CS (8) и получаю какой то трэш. nRF24L01+ работает вроде нормально. А вот LoRa начинает какую то ерунду принимать, видимо с nRF-ки. Методом научного тыка установил, что ерунда лезет прямо после RF24.openReadingPipe Покурил обе библиотеки. То ли в arduino-LoRa SS не дергают, то ли они не созданы друг для друга и стоит nRF-ку на Software driven SPI перетащить. Ни у кого идей нет?
ну если не можешь совладать с библиотеками, значит рано взялся за библиотеки. Пиши код ручками. На шине SPI прекрасно разруливается хоть сто устройств, лишь бы пин SE был.
К сожалению нет. Ну тогда может рано за микропроцессоры браться и начинать с ламп и перфокарт? Я прекрасно понимаю, что там разруливается ровно столько устройств, сколько в шину влезет. Вопрос был в другом, что при параллельном подключении библиотека LoRa начинает получать паразитные данные. Код ниже. Дано: 1. Приемник. 2. Передатчик nRF который шлет micros() 3. Передатчик LoRa который шлет "LoRa" + автоинкремент число Передатчик (2) и (3) исправно работают по сценарию описанному ниже и мониторятся на COM порте в putty параллельно с приемником. Приемник, подключение: LoRa -> Arduino GND -> GND VCC -> 3.3V SCK -> 13 MISO -> 12 MOSI -> 11 NSS(SS) -> 10 DIO0 -> 8 NRESET -> 9 nRF24L01 -> Arduino GND -> GND VCC -> 3.3V SCK -> 13 MISO -> 12 MOSI -> 11 CE -> 6 CSN -> 7 Код приемника: в котором мы будем играться с #define RADIO_ENABLED true(1) или false(0) #define LORA_ENABLED true(1) или false(0) Код (C++): #include <nRF24L01.h> #include <RF24.h> #include <SPI.h> #include <LoRa.h> #define LORA_SS_PIN 10 #define LORA_RESET_PIN 9 #define LORA_DID0_PIN 8 #define RADIO_ENABLED true #define LORA_ENABLED true #define NRF_CE_PIN 6 #define NRF_CSN_PIN 7 RF24 radio(NRF_CE_PIN, NRF_CSN_PIN); // (CE, CSN) void setup() { Serial.begin(9600); Serial.println(F("Setup arduino")); Serial.print(F("RADIO_ENABLED: ")); Serial.println(RADIO_ENABLED); Serial.print(F("LORA_ENABLED: ")); Serial.println(LORA_ENABLED); initLoRa(); initRadio(); Serial.println(F("Setup done...")); } void initRadio() { if (!RADIO_ENABLED) return; Serial.println(F("Setup radio chanel")); radio.begin(); radio.failureDetected = 0; radio.setChannel(5); radio.setDataRate (RF24_1MBPS); radio.setPALevel (RF24_PA_HIGH); radio.openReadingPipe (1, 0x1234567890LL); radio.printDetails(); radio.startListening(); Serial.println(F("Setup radio DONE...")); } void initLoRa() { if (!LORA_ENABLED) return; Serial.println(F("Init LoRa Receiver")); LoRa.setPins(LORA_SS_PIN, LORA_RESET_PIN, LORA_RESET_PIN); if (!LoRa.begin(866E6)) { Serial.println(F("Starting LoRa failed!")); while (1); } else { Serial.println(F("LoRa Receiver done...")); } } void loop() { readRadioChanel(); readLoraChanel(); } void readRadioChanel() { if (!RADIO_ENABLED) return; if ( radio.available()) { unsigned long got_time; while (radio.available()) { // While there is data ready radio.read( &got_time, sizeof(unsigned long) ); // Get the payload Serial.print(F("Getting: ")); Serial.println(got_time); } } else { // Serial.println(F("Radio not available")); } } void readLoraChanel() { if (!LORA_ENABLED) return; int packetSize = LoRa.parsePacket(); if (packetSize) { Serial.print(F("Received packet '")); while (LoRa.available()) { Serial.print((char)LoRa.read()); } Serial.print(F("' with RSSI(уровень сигнала) ")); Serial.print(LoRa.packetRssi()); Serial.print(F(" - ")); Serial.println(getRssiValue(LoRa.packetRssi())); } else { // Serial.println(F("No new LoRa packets")); } } String getRssiValue(int level) { String result = "No signal"; if(level > -70) { result = "Execelent"; } else if(level > -85) { result = "Good"; } else if(level > -100) { result = "Poor"; } return result; } Итак. Тест 1. Слушаем только nRF24L01 Код (C++): #define RADIO_ENABLED true #define LORA_ENABLED false На Serial имеем: Тест 2. Слушаем только LoRa Код (C++): #define RADIO_ENABLED false #define LORA_ENABLED true На Serial имеем: Тест 3. Слушаем только nRF24L01 + LoRa Код (C++): #define RADIO_ENABLED true #define LORA_ENABLED true На Serial имеем: Та же самая хрень идет из LoRa если ее воткнуть сразу перед nRF24L01 Тест 4. Меняем местами init-ы было: Код (C++): initRadio(); initLoRa(); стало: Код (C++): initLoRa(); initRadio(); На Serial имеем:
P.S. Покурил библиотеки. А именно: https://github.com/sandeepmistry/arduino-LoRa/blob/master/src/LoRa.h - для LoRa http://tmrh20.github.io/RF24/RF24_8cpp_source.html - для nRF24L01 В первом случае все вроде корректно. ВСЯ работа с SPI идет через метод: Код (C++): uint8_t LoRaClass::singleTransfer(uint8_t address, uint8_t value) { uint8_t response; digitalWrite(_ss, LOW); _spi->beginTransaction(_spiSettings); _spi->transfer(address); response = _spi->transfer(value); _spi->endTransaction(); digitalWrite(_ss, HIGH); return response; } В RF24 все методы работы с SPI обернуты в csn(LOW); csn(HIGH); который тоже не выглядит подозрительно: Код (C++): void RF24::csn(bool mode) 16 { 17 18 #if defined (RF24_TINY) 19 if (ce_pin != csn_pin) { 20 digitalWrite(csn_pin,mode); 21 } 22 else { 23 if (mode == HIGH) { 24 PORTB |= (1<<PINB2); // SCK->CSN HIGH 25 delayMicroseconds(100); // allow csn to settle. 26 } 27 else { 28 PORTB &= ~(1<<PINB2); // SCK->CSN LOW 29 delayMicroseconds(11); // allow csn to settle 30 } 31 } 32 // Return, CSN toggle complete 33 return; 34 35 #elif defined(ARDUINO) && !defined (RF24_SPI_TRANSACTIONS) 36 // Minimum ideal SPI bus speed is 2x data rate 37 // If we assume 2Mbs data rate and 16Mhz clock, a 38 // divider of 4 is the minimum we want. 39 // CLK:BUS 8Mhz:2Mhz, 16Mhz:4Mhz, or 20Mhz:5Mhz 40 41 #if !defined (SOFTSPI) 42 _SPI.setBitOrder(MSBFIRST); 43 _SPI.setDataMode(SPI_MODE0); 44 _SPI.setClockDivider(SPI_CLOCK_DIV2); 45 #endif 46 #elif defined (RF24_RPi) 47 if(!mode) 48 _SPI.chipSelect(csn_pin); 49 #endif 50 51 #if !defined (RF24_LINUX) 52 digitalWrite(csn_pin,mode); 53 delayMicroseconds(csDelay); 54 #endif 55 56 } Вся разница в частоте SPISettings для обоих библиотек
ерунда. nRF24 работает до 10 Мгц, у Лоры тоже существенных ограничений нет. Поэтому выставляешь бит SPI2X и работаешь на половине от тактовой. Как она получает данные? Там callback функции организованы или прерывания? Трансиверы перед переключением обязательно выключать.
Оно само SPI_CLOCK_DIV2 для nRF24L01 и 2278 при каждом обращении выставляет. Прерывания. На каждый байт переводим CS в LOW, выставляем прерывание, читаем байт и обратно в HIGH. То есть вроде как оно никогда не остается открытым, чтобы там еще что-то могло оказаться. Под выключением имеется ввиду CS в HIGH? Оно в обоих библиотеках только на чтение запись переводится в LOW и сразу обратно. Или что-то другое?
Задампил регистры LoRa в 2х режимах, когда включена только LoRa и когда включена nRF24L01 + LoRa. У меня разрыв шаблона. - При дампинге мусор не идет. - Некоторые регистры в LoRa отличаются даже на инициализации. - Передатчик шлет '*** LoRa 8**' а приемник показывает что-то вроде '** LoRa 8***;' при чем в обоих случаях Что-то подсказывает, что раз out сильно увеличился, то еще где то Serial врет. Еще как то эту штуку дебажить можно?