sandeepmistry / arduino-LoRa

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

LoRa and another SPI device #206

Open ts7622 opened 5 years ago

ts7622 commented 5 years ago

Hi,

i use an RX5808 5.8GHz video receiver to read the RSSI for the corresponding channel i set with SPI. Thats working great. The retrieving data is send via RA-01 (SX1278) to the server. The Problem is that i cant set the RX5808 channel after LoRa.begin() is called.

At the beginning of my setup() i set the slave select pins to OUTPUT and HIGH. Both devices getting initialized. Then the slave select for the RX5808 is LOW and the LoRa SS is HIGH right before changing the video channel. But its just not working. If LoRa.begin() is removed i can set the RX5808 channel without problems.

What is LoRa.begin() doing that communication with another SPI device fails? And what is a possible solution?

main.ino

#include <LoRa.h>

const int VRX_SPI_SELECT                = 3;
const int VRX_SPI_DATA                  = 10;
const int VRX_SPI_CLOCK                 = 12;
const int VRX_RSSI                      = 7;

const int LORA_SELECT                   = 9;
const int LORA_RESET                    = 8;
const int LORA_DATA                     = 2;

#include "lora.h";
#include "vrx.h";

using namespace lora;
using namespace vrx;

void setup() {
  Serial.begin(9600);

  pinMode(VRX_SPI_SELECT,OUTPUT);
  digitalWrite(VRX_SPI_SELECT,HIGH);
  pinMode(LORA_SELECT,OUTPUT);
  digitalWrite(LORA_SELECT,HIGH);

  vrx::init();
  lora::init();
}

void loop() {
  lora::receive();
  AutoTune();
  delay(1);
}

int highValue=0;
int highChannel=0;

void AutoTune()
{
  String txt="";
  int val=0;
  Serial.println("AutoTune");

  int count = 0;
  for(count=0;count<40;count++)
  {
    vrx::setChannel(count);
    delay(50);
    val = analogRead(A7);    // read the input pin
    if(val > highValue)
    {
      highValue=val;
      highChannel=count;
    }
    txt += String(val) + " ";
    if(count == 7 || count == 15 || count == 23 || count == 31 || count == 39) {
      txt += "\n";
    }
  }
  count=highChannel;
    vrx::setChannel(count);
  Serial.println(txt);
  Serial.println("------");
}

lora.h

namespace lora {

  void send(String cmd, String val);
  void receive();

  void init() {
    LoRa.setPins(LORA_SELECT, LORA_RESET, LORA_DATA);
    if (!LoRa.begin(433E6)) {             // initialize ratio at 915 MHz
      Serial.println("LoRa init failed. Check your connections.");
      while (true);                       // if failed, do nothing
    }
    Serial.println("LoRa init succeeded.");
  }

  void send(String cmd, String val) {
    String msg = String(did) + "1000;" + cmd + ";" + val;
    Serial.println("lora tx: " + msg);
    LoRa.beginPacket();
    LoRa.write(0xFF);
    LoRa.write(0xBB);
    LoRa.write(0);
    LoRa.write(msg.length());
    LoRa.print(msg);
    LoRa.endPacket();
  }

  void receive() {
    if(String(LoRa.parsePacket()).toInt() != 0) {
      int recipient = LoRa.read();          // recipient address
      byte sender = LoRa.read();            // sender address
      byte incomingMsgId = LoRa.read();     // incoming msg ID
      byte incomingLength = LoRa.read();    // incoming msg length

      String incoming = "";

      while (LoRa.available()) {
        incoming += (char)LoRa.read();
      }
      if (incomingLength == incoming.length()) {
        Serial.println("lora rx: " + incoming);
      }
    }
  }
}

vrx.h (original: https://github.com/simonchambers/fs-5.8g-vrx/blob/master/Firmware/fs_skyrf_58g-main.c)

namespace vrx {
  // channel Table
  uint16_t channelTable[] = {
  0x2a05 ,0x299b ,0x2991 ,0x2987 ,0x291d ,0x2913 ,0x2909 ,0x289f ,
  0x2903 ,0x290c ,0x2916 ,0x291f ,0x2989 ,0x2992 ,0x299c ,0x2a05 ,
  0x2895 ,0x288b ,0x2881 ,0x2817 ,0x2a0f ,0x2a19 ,0x2a83 ,0x2a8d ,
  0x2906 ,0x2910 ,0x291a ,0x2984 ,0x298e ,0x2998 ,0x2a02 ,0x2a0c ,
  0x281d ,0x2890 ,0x2902 ,0x2915 ,0x2987 ,0x299a ,0x2a0c ,0x2a1f
  };

  void SERIAL_SENDBIT1()
  {
    digitalWrite(VRX_SPI_CLOCK, LOW);
    delayMicroseconds(300);
    digitalWrite(VRX_SPI_DATA, HIGH);
    delayMicroseconds(300);
    digitalWrite(VRX_SPI_CLOCK, HIGH);
    delayMicroseconds(300);
    digitalWrite(VRX_SPI_CLOCK, LOW);
    delayMicroseconds(300);
  }

  void SERIAL_SENDBIT0()
  {
    digitalWrite(VRX_SPI_CLOCK, LOW);
    delayMicroseconds(300);
    digitalWrite(VRX_SPI_DATA, LOW);
    delayMicroseconds(300);
    digitalWrite(VRX_SPI_CLOCK, HIGH);
    delayMicroseconds(300);

    digitalWrite(VRX_SPI_CLOCK, LOW);
    delayMicroseconds(300);
  }

  void SERIAL_ENABLE_LOW()
  {
    delayMicroseconds(100);
    digitalWrite(VRX_SPI_SELECT,LOW);
    delayMicroseconds(100);
  }

  void SERIAL_ENABLE_HIGH()
  {
    delayMicroseconds(100);
    digitalWrite(VRX_SPI_SELECT,HIGH);
    delayMicroseconds(100);
  }

  void init() {
    pinMode (VRX_SPI_SELECT, OUTPUT);
    pinMode (VRX_SPI_DATA, OUTPUT);
    pinMode (VRX_SPI_CLOCK, OUTPUT);
    digitalWrite(VRX_SPI_SELECT, HIGH);
  }

  void setChannel(uint8_t channel)
  {
    uint8_t i;
    uint16_t channelData;

    // channelData = pgm_read_word(&channelTable[channel]);
    channelData = channelTable[channel];

    // bit bash out 25 bits of data
    // Order: A0-3, !R/W, D0-D19
    // A0=0, A1=0, A2=0, A3=1, RW=0, D0-19=0
    SERIAL_ENABLE_HIGH();
    delay(2);
    SERIAL_ENABLE_LOW();

    SERIAL_SENDBIT0();
    SERIAL_SENDBIT0();
    SERIAL_SENDBIT0();
    SERIAL_SENDBIT1();

    SERIAL_SENDBIT0();

    // remaining zeros
    for (i=20;i>0;i--)
      SERIAL_SENDBIT0();

    // Clock the data in
    SERIAL_ENABLE_HIGH();
    delay(2);
    SERIAL_ENABLE_LOW();

    // Second is the channel data from the lookup table
    // 20 bytes of register data are sent, but the MSB 4 bits are zeros
    // register address = 0x1, write, data0-15=channelData data15-19=0x0
    SERIAL_ENABLE_HIGH();
    SERIAL_ENABLE_LOW();

    // Register 0x1
    SERIAL_SENDBIT1();
    SERIAL_SENDBIT0();
    SERIAL_SENDBIT0();
    SERIAL_SENDBIT0();

    // Write to register
    SERIAL_SENDBIT1();

    // D0-D15
    //   note: loop runs backwards as more efficent on AVR
    for (i=16;i>0;i--)
    {
      // Is bit high or low?
      if (channelData & 0x1)
      {
        SERIAL_SENDBIT1();
      }
      else
      {
        SERIAL_SENDBIT0();
      }

      // Shift bits along to check the next one
      channelData >>= 1;
    }

    // Remaining D16-D19
    for (i=4;i>0;i--)
      SERIAL_SENDBIT0();

    // Finished clocking data in
    SERIAL_ENABLE_HIGH();
    delay(2);

    digitalWrite(VRX_SPI_SELECT,LOW);
    digitalWrite(VRX_SPI_CLOCK, LOW);
    digitalWrite(VRX_SPI_DATA, LOW);
  }
}
ts7622 commented 5 years ago

At the moment i use two Arduinos communicating over UART to avoid this problem. it would be great if the author has an solution to this.