SX1276 LoRa

Тема в разделе "Проводная и беспроводная связь", создана пользователем Kisa9000, 6 дек 2018.

  1. Kisa9000

    Kisa9000 Нуб

    Приветствую! Вот есть задачка сделать передачу данных между двумя ATmega328p.
    Принимаю данные по UART и по SPI заливаю их в SX1276. Ну и на принимающей стороне тот же цикл только наоборот.
    Все на словах конечно волшебно, но очень уж я устал ковырять этот SX с его кучей регистров.
    Если у кого был опыт общения с данной железкой, прошу отписаться.
    На текущий момент данные по UART принимаю, но никак не догоняю как их закинуть по SPI в радиомодуль.
     
  2. ostrov

    ostrov Гуру

    Так вопрос то обо что? О работе с радиомодулем? При чем тут UART, он простой как огурец. Может есть библиотки готовые от этого SX? С них и начать бы.
     
  3. parovoZZ

    parovoZZ Гуру

    это правда. Я тоже ковырял два вечера, потом настигла другая задача. Пока лоры в стороне лежат в не распакованном пакетике.
    в ютубе есть канал "электроника в объективе". Там Руслан и код выкладывал и на дальность тестировал.

    На какой частоте планируешь работать?
     
  4. ImrDuke

    ImrDuke Гик

    Там же еще есть про эти модули видео

     
    Пушной звер нравится это.
  5. b707

    b707 Гуру

    а чего их ковырять то? есть же готовые библиотеки
    вот это не пробовали?
    https://github.com/sandeepmistry/arduino-LoRa
     
  6. Kisa9000

    Kisa9000 Нуб

    На 868 МГц собираюсь.
    Проект подразумевает сделать из ATmega328p что-то вроде преобразователя из одного протокола в другой.
    Данные получаю по UART, преобразую как надо и дальше по LoRa кидаю их на приемную сторону.
    Про библиотеки знаю, пробовал. Но при попытке использовать UART и библиотеки для LoRa происходит магия. UART отваливается, данные не принимаются. Поэтому было принято решение LoRa ковырять по регистрам.
     
  7. parovoZZ

    parovoZZ Гуру

    Так ведь есть же RA-01 и RA-02 - там сразу UART на входе.
     
  8. b707

    b707 Гуру

    простите, если вы не в состоянии готовую библиотеку с UART подружить - кудаж вы в регистры-то полезли...
     
  9. Sanders

    Sanders Нерд

    Приехали 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 перетащить.

    Ни у кого идей нет?
     
  10. parovoZZ

    parovoZZ Гуру

    слезать с ардуино-шизы.
     
  11. Sanders

    Sanders Нерд

    спасибо за дельный совет. Пойду выбирать между электрочайником и вафельницей.
     
  12. проводка на соплях
     
  13. parovoZZ

    parovoZZ Гуру

    ну если не можешь совладать с библиотеками, значит рано взялся за библиотеки. Пиши код ручками. На шине SPI прекрасно разруливается хоть сто устройств, лишь бы пин SE был.
     
  14. Sanders

    Sanders Нерд

    К сожалению нет.

    Ну тогда может рано за микропроцессоры браться и начинать с ламп и перфокарт? :)
    Я прекрасно понимаю, что там разруливается ровно столько устройств, сколько в шину влезет. Вопрос был в другом, что при параллельном подключении библиотека 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 имеем:
     
    Последнее редактирование: 20 дек 2018
  15. Sanders

    Sanders Нерд

    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 для обоих библиотек
     
  16. parovoZZ

    parovoZZ Гуру

    ерунда. nRF24 работает до 10 Мгц, у Лоры тоже существенных ограничений нет. Поэтому выставляешь бит SPI2X и работаешь на половине от тактовой.

    Как она получает данные? Там callback функции организованы или прерывания?

    Трансиверы перед переключением обязательно выключать.
     
  17. Sanders

    Sanders Нерд

    Оно само SPI_CLOCK_DIV2 для nRF24L01 и 2278 при каждом обращении выставляет.

    Прерывания. На каждый байт переводим CS в LOW, выставляем прерывание, читаем байт и обратно в HIGH.
    То есть вроде как оно никогда не остается открытым, чтобы там еще что-то могло оказаться.

    Под выключением имеется ввиду CS в HIGH? Оно в обоих библиотеках только на чтение запись переводится в LOW и сразу обратно.
    Или что-то другое?
     
  18. parovoZZ

    parovoZZ Гуру

    Сперва регистрами в самом трансивере, затем chip select в high.
     
  19. Sanders

    Sanders Нерд

    Задампил регистры LoRa в 2х режимах, когда включена только LoRa и когда включена nRF24L01 + LoRa.
    У меня разрыв шаблона.
    - При дампинге мусор не идет.
    - Некоторые регистры в LoRa отличаются даже на инициализации.
    - Передатчик шлет '*** LoRa 8**' а приемник показывает что-то вроде '** LoRa 8***;' при чем в обоих случаях

    Что-то подсказывает, что раз out сильно увеличился, то еще где то Serial врет.
    Еще как то эту штуку дебажить можно?