sandeepmistry / arduino-LoRa

An Arduino library for sending and receiving data using LoRa radios.
MIT License
1.64k stars 627 forks source link

ESP32 with multiple LoRa SX1278 as SPI slave #278

Closed IoTThinks closed 4 years ago

IoTThinks commented 5 years ago

Hi, Thanks a lot for your awesome LoRa library. I would like to explore how to use esp32 as master and 2 sx1278 as slave.

image

The pin mapping as bellow.

// LoRa 1 pins
#define LORA_SS          23
#define LORA_SCK         18
#define LORA_MOSI         5
#define LORA_MISO        36
#define LORA_DIO012      39
#define LORA_RST         13

// LoRa 2 pins
#define LORA2_SS         32
#define LORA2_SCK        18 // Shared
#define LORA2_MOSI        5 // Shared
#define LORA2_MISO       36 // Shared
#define LORA2_DIO012     34
#define LORA2_RST        15

In Lora 1, I put as bellow

  SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_SS);
  LoRa.setPins(LORA_SS, LORA_RST, LORA_DIO012);

  while (!LoRa.begin(433E6)) {
    Serial.println("[LoRa] Starting LoRa failed!");
    delay(1000);
  }

In LoRa 2, I put as bellow.

  LoRaClass LoRa2;
  SPI.begin(LORA2_SCK, LORA2_MISO, LORA2_MOSI, LORA2_SS);
  LoRa2.setPins(LORA2_SS, LORA2_RST, LORA2_DIO012);

  while (!LoRa2.begin(433E6)) {
    Serial.println("[LoRa2] Starting LoRa failed!");
    delay(1000);
  }

I know I should control the SS (Slave select) but don't know how to integrate it with your library. Thanks a lot for any advice.

slavino commented 5 years ago

Maybe offtopic but would this help you any further? https://github.com/espressif/arduino-esp32/blob/master/libraries/SPI/examples/SPI_Multiple_Buses/SPI_Multiple_Buses.ino

IoTThinks commented 5 years ago

Maybe offtopic but would this help you any further? https://github.com/espressif/arduino-esp32/blob/master/libraries/SPI/examples/SPI_Multiple_Buses/SPI_Multiple_Buses.ino

Thanks. I read this url already. This one is 2 SPI masters (HSPI and vSPI).

My case is 1 SPI master and 2 LoRa SPI slave. BTW, I'm still playing around with SS for each slave.

IoTThinks commented 5 years ago

I set something like this. I remove SS pin in SPI.begin. Seems to work but one LoRa by another LoRa. Not so concurrently.

LoRa 1

  SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI);
  LoRa.setPins(LORA_SS, LORA_RST, LORA_DIO012);

  while (!LoRa.begin(433E6)) {
    Serial.println("[LoRa] Starting LoRa failed!");
    delay(1000);
  }

LoRa 2:

  SPI.begin(LORA2_SCK, LORA2_MISO, LORA2_MOSI);
  LoRa2.setPins(LORA2_SS, LORA2_RST, LORA2_DIO012);

  while (!LoRa2.begin(470E6)) {
    Serial.println("[LoRa2] Starting LoRa failed!");
    delay(1000);
  }

Then I active and detactive the two LoRa chips between receiving.

void setActiveLoRa() {
  pinMode(LORA2_SS, OUTPUT);
  pinMode(LORA_SS, OUTPUT);
  digitalWrite(LORA2_SS, HIGH);
  digitalWrite(LORA_SS, LOW);  
}

void setActiveLoRa2() {
  pinMode(LORA_SS, OUTPUT);
  pinMode(LORA2_SS, OUTPUT);  
  digitalWrite(LORA_SS, HIGH);
  digitalWrite(LORA2_SS, LOW);
}

Not so concurrently.

    // LoRa 1
    setActiveLoRa(); 
    String loraMessage = receiveLoRaMessage();
    if(loraMessage != "") 
      Serial.println("[LoRa] " + loraMessage);
    delay(50);

    // LoRa 2
    setActiveLoRa2();
    String lora2Message = receiveLoRa2Message();
    if(lora2Message != "") 
      Serial.println("[LoRa2] " + lora2Message); 
    delay(50);
morganrallen commented 5 years ago

What is the results of that code you say won't run concurrently? Keep in mind, the LoRa receive functions are blocking, so without some kind of threading you wouldn't be able to achieve concurrency anyhow.

IoTThinks commented 5 years ago

Thanks a lot. So there is any way I can let chip LoRa 1 to receive (in blocking mode) and let chip LoRa 2 to start hearing for new packet? So the goal is 2 LoRa chips can take turn receiving / sending faster?

Will threading in Arduino-ESP32 be helpful?

keithr0 commented 5 years ago

Since the ESP32 has two processors, you could separate your transmit and receive functions that way. there are several tutorials on the web on how to run two processes that way. This one is pretty basic but gives an introduction to the concepts https://www.youtube.com/watch?v=k_D_Qu0cgu8

IoTThinks commented 5 years ago

Ok, let me try.

morganrallen commented 5 years ago

You might need to even go as far as using multi-core communication. Since ESP32 Arduino is still based on FreeRTOS you can create tasks as if you were using ESP IDF. So you might use an onReceive interrupt to start a task that reads from the serial port. Here is a snippet that show some of the basic function but some more reading will be needed to understand how FreeRTOS manages tasks. FreeRTOS Reference

void l1read(void * pvParameters) {
  int packetSize = pvParameters;

  for (int i = 0; i < packetSize; i++) {
    Serial.print((char)LoRa.read());
  }

  // cleanup task before exiting
  vTaskDelete(NULL);
}

void on_lora1_receive_callback(int packetSize) {
  xTaskCreate(lora1_read, "l1read", 1024, packetSize, tskIDLE_PRIORITY, NULL);
}

If you have onReceive callbacks set for each module something like this might work. The ESP32 and FreeRTOS will handle the tasks in the background and carry on.

IoTThinks commented 4 years ago

I'm using tasks to mitigate the issue. To close.