http://www.semtech.com/images/datasheet/sx1276_77_78_79.pdf
http://wiki.dragino.com/index.php?title=Lora_Shield

Arduino koodi versio 0.2. Testattu jonkin verran. Ei vielä implementoitu kaikkia ominaisuuksia, esim. continuous mode vastaanotto puuttuu vielä. Continuous modessa raakadatan käsittely ja analysointi (de-serialisointi) tullaan tekemään Windows ohjelmassa.

/*
   SX127x FskScanner by OH1GIU
   Version 0.2
   http://www.semtech.com/images/datasheet/sx1276_77_78_79.pdf
   http://wiki.dragino.com/index.php?title=Lora_Shield
*/
#include <SPI.h>
#include "fskscanner.h"

SPISettings spi_Settings(spi_max_speed, MSBFIRST, SPI_MODE0);
char serialData[serial_data_len];
byte rxFifo[fifo_buffer_size];
byte bytesRead;
byte rxLen = 255;

// 1200,2400,4800,9600,19200,38400,57600,12500,25000,50000
byte bps_hi[10] = {0x68, 0x34, 0x1A, 0x0D, 0x06, 0x03, 0x02, 0x0A, 0x05, 0x80};
byte bps_lo[10] = {0x2B, 0x15, 0x0B, 0x05, 0x83, 0x41, 0x2C, 0x00, 0x00, 0x00};

void setup() {
  Serial.begin(serial_speed);
}

void loop() {
  if (Serial.available() > 0) {
    bytesRead = Serial.readBytesUntil(serial_end_char, serialData, serial_data_read);
    if (bytesRead > 0) {
      serialData[bytesRead] = 0;
      procCmd();
      memset(serialData, 0, sizeof(serialData));
    }
  }
}

/*
   usage example:
   o<cr>
   s<cr>
   p1<cr>
   b4<cr>
   m0<cr>
   n423.875<cr>
   x<cr>
   f<cr>

   o = set module on
   f = set module off
   r = get RSSI value
   t = get RSSI threshold value
   g = get frequency
   n = set frequency, e.g. n433.92
   e = get mode, 0 = FSK, 1 = OOK
   h = get bps
   a = checks if data received, returns number of bytes received
   p(x) = set operative mode: p1 = packet, p0 = continuous. Continuous mode receive yet not implemented. In continuous mode data is received via the D6/D9 pin (DIO2). Serializing/deserializing data must be done in software.
   m(x) = set rx mode: m0 = FSK, m1 = OOK
   b(x) = set bps, b0=1200, b1=2400, b2=4800, b3=9600, b4=19200, b5=38400, b6=57600, b7=12500, b8=25000, b9=50000
   x = receive data
   v = get version (full revision number.metal mask)
   s = start FSK
   w = set state: w0 = Sleep mode, w1 = Stdby mode, w2 = FS mode TX (FSTx), w3 = Transmitter mode (Tx), w4 = FS mode RX (FSRx), w5 = Receiver mode (Rx)
*/
void procCmd() {
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("procCmd: "));
  Serial.print(serialData);
#endif

  float f = 0;
  byte b = 0;
  unsigned int i = 0;

  switch (serialData[0]) {
    case 'o':
      if (setON() == true) {
        Serial.println(F("ACK setON"));
      }
      else {
        Serial.println(F("NAK setON"));
      }
      break;
    case 'f':
      setOFF();
      Serial.println(F("ACK setOFF"));
      break;
    case 'r':
      f = readRSSIvalue();
      Serial.println(f, DEC);
      break;
    case 't':
      f = readRSSIthresh();
      Serial.println(f, DEC);
      break;
    case 'g':
      f = getFreq();
      Serial.println(f, DEC);
      break;
    case 'n':
      setFreq(serialData, strlen(serialData));
      Serial.println(F("ACK setFreq"));
      break;
    case 'e': // 0 = FSK, 1 = OOK
      b = getMode();
      Serial.println(b, DEC);
      break;
    case 'h':
      i = getBps();
      Serial.println(i, DEC);
      break;
    case 'a':
      b = isDataAvail();
      Serial.println(b, DEC);
      break;
    case 'p': // '1'=packet mode  '0'=continuous mode, e.g. p1
      setPackOnOff(serialData[1]);
      Serial.println(F("ACK setPackOnOff"));
      Serial.println(serialData[1]);
      break;
    case 'm': // '0'=FSK  '1'=OOK, e.g. m1
      setMode(serialData[1]);
      Serial.println(F("ACK setMode"));
      Serial.println(serialData[1]);
      break;
    case 'b':
      setBps(serialData[1]);
      Serial.println(F("ACK setBps"));
      break;
    case 'w':
      b = serialData[1] - '0';
      setOpMode(b);
      Serial.println(F("ACK setOpMode"));
      break;
    case 'x': {
        //memset(rxFifo, 0, sizeof(rxFifo));
        b = rxData(rxLen);
        if (b > 0) {
          for (int i = 0; i < b; i++) {
            Serial.print(rxFifo[i]);
          }
        }
        else {
          Serial.println();
        }
        break;
      }
    case 'v': {
        char ver[5];
        readVer(ver, sizeof(ver));
        Serial.println(ver);
        break;
      }
    case 's':
      startFSK();
      Serial.println(F("ACK startFSK"));
      break;
    default:
      Serial.println(F("NAK unknown cmd"));
      Serial.println(serialData);
      break;
  }
}

bool setON() {
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("setON"));
#endif

  pinMode(sx1278_reset_pin, OUTPUT);
  digitalWrite(sx1278_reset_pin, LOW);

  pinMode(SS, OUTPUT);
  digitalWrite(SS, HIGH);
  SPI.begin();
  if (readSPI(register_ver) == 0) {
    SPI.end();
    return false;
  }
  reset();
  setOpMode(opmode_stdby);
  writeSPI(register_ocp, sx1278_curr_trim);
  return true;
}

void setOFF() {
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("setOFF"));
#endif

  SPI.end();
  pinMode(SS, OUTPUT);
  digitalWrite(SS, LOW);
}

byte readSPI(byte addr)
{
  byte regVal = 0;
  SPI.beginTransaction(spi_Settings);
  digitalWrite(SS, LOW);
  delay(spi_low_trf_delay);
  bitClear(addr, sx127x_rw_setclr_bit);
  SPI.transfer(addr);
  delayMicroseconds(spi_delay);
  regVal = SPI.transfer(spi_slave_num);
  digitalWrite(SS, HIGH);
  SPI.endTransaction();

#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("readSPI"));
  Serial.print(F("\tRegister "));
  Serial.print(addr, HEX);
  Serial.print(F("\tValue "));
  Serial.print(regVal, HEX);
  Serial.println();
#endif

  return regVal;
}

void writeSPI(byte addr, byte value) {
  SPI.beginTransaction(spi_Settings);
  digitalWrite(SS, LOW);
  delay(spi_low_trf_delay);
  bitSet(addr, sx127x_rw_setclr_bit);
  SPI.transfer(addr);
  delayMicroseconds(spi_delay);
  SPI.transfer(value);
  digitalWrite(SS, HIGH);
  SPI.endTransaction();

#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("writeSPI"));
  Serial.print(F("\tRegister "));
  bitClear(addr, sx127x_rw_setclr_bit);
  Serial.print(addr, HEX);
  Serial.print(F("\tData "));
  Serial.print(value, BIN);
  Serial.println();
#endif
}

void startFSK()
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("startFSK"));
#endif

  setOpMode(opmode_sleep);
  byte regVal = readSPI(register_opmode);
  bitClear(regVal, sx127x_rw_setclr_bit);
  writeSPI(register_opmode, regVal);
}

/* Get IRQ flag bit from IRQ registers */
byte getIrqFlag(byte irq, byte irq_flag)
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("getIrqFlag IRQ "));
  Serial.print(irq, DEC);
  Serial.print("\tIRQ flag ");
  Serial.print(irq_flag, DEC);
#endif

  byte reg;
  if (irq == 1) {
    reg = register_irq_flags1;
  }
  else {
    reg = register_irq_flags2;
  }
  byte b = bitRead(readSPI(reg), irq_flag);
  return b;
}

byte isDataAvail()
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("isDataAvail"));
#endif

  byte b = 0;
  if (getIrqFlag(2, 2) == 1) {
    b = readSPI(register_payload_len);
  }
  return b;
}

byte rxData(byte rx_len)
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("rxData"));
#endif

  int i = 0;
  for (i = 0; i < rx_len; i++) {
    rxFifo[i] = readSPI(register_fifo);
    Serial.print(rxFifo[i]);
    if (bitRead(readSPI(register_irq_flags2), 6)) {
      break;
    }
  }
  return (byte) i;
}

/*
   Band 1 (HF)  862 (*779)-1020 (*960) MHz  SX1276/77/79
   Band 2 (LF)  410-525 (*480) MHz          SX1276/77/78/79
   Band 3 (LF)  137-175 (*160)MHz           SX1276/77/78/79
*/
void setFreq(char *bfreq, int flen)
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("setFreq"));
  Serial.println(bfreq);
#endif

  char c[flen];
  int n = 0;
  for (int i = 1; i < flen; i++) {
    c[n] = bfreq[i];
    n++;
  }
  c[n] = 0;
  float f = atof(c);

#if (debug_mode > 0)
  Serial.println(c);
  Serial.println(f, DEC);
#endif

  union freq
  {
    unsigned long lfreq;
    unsigned char cfreq[4];
  } uf;

  uf.lfreq = (f * 1000000) / 61.035;
  writeSPI(register_frfmsb, uf.cfreq[2]);
  writeSPI(register_frfmid, uf.cfreq[1]);
  writeSPI(register_frflsb, uf.cfreq[0]);
}

float getFreq()
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("getFreq"));
#endif

  byte fLsb = readSPI(register_frflsb);
  byte fMid = readSPI(register_frfmid);
  byte fMsb = readSPI(register_frfmsb);
  unsigned long l = fMsb;
  l = (l << 8) + fMid;
  l = (l << 8) + fLsb;
  float f = (l * 61.035) / 1000000;
  return f;
}

void setPackOnOff(char st)
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("setPackOnOff "));
  Serial.print(st);
#endif

  byte regVal = readSPI(register_packetconfig2);
  if (st == '1') {
    bitSet(regVal, 6);
  }
  else {
    bitClear(regVal, 6);
  }
  writeSPI(register_packetconfig2, regVal);

#if (debug_mode > 0)
  Serial.println();
  Serial.print("\t register_packetconfig2 ");
  Serial.print(regVal, BIN);
#endif
}

/* Preamble len. Preamble type: 0 = 0xAA, 1 = 0x55 */
void setPreambleMode(unsigned int preamble_len, byte preamble_type)
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("setPreambleMode"));
#endif

  writeSPI(register_preamble_msb, highByte(preamble_len));
  writeSPI(register_preamble_lsb, lowByte(preamble_len));
  byte regVal = readSPI(register_sync_config);
  if (preamble_type == 0) {
    bitClear(regVal, 5);
  }
  else {
    bitSet(regVal, 5);
  }
  writeSPI(register_sync_config, regVal);

#if (debug_mode > 0)
  Serial.println();
  Serial.print("\t register_sync_config ");
  Serial.print(regVal, BIN);
#endif

  regVal = readSPI(register_preamble_detect);
  if (preamble_len == 0) {
    bitClear(regVal, 7);
  }
  else {
    bitSet(regVal, 7);
  }
  writeSPI(register_preamble_detect , regVal);

#if (debug_mode > 0)
  Serial.print("\t register_preamble_detect ");
  Serial.print(regVal, BIN);
#endif
}

/* Packet fmt. fixed or variable (0/1), default 0. CRC on/off (0/1), default on. */
void setPacketFormat(byte fix_or_var, byte crc, byte payload_len)
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("setPacketFormat"));
#endif

  byte regVal = readSPI(register_packetconfig1);
  bitWrite(regVal, 7, fix_or_var);
  bitWrite(regVal, 4, crc);
  writeSPI(register_packetconfig1, regVal);
  writeSPI(register_payload_len, payload_len);

#if (debug_mode > 0)
  Serial.print("\t register_packetconfig1 ");
  Serial.print(regVal, BIN);
#endif
}

/* Sync conf. state: on/off (default on). Sync bytes: default 0x01, 0x01, 0x01 */
void setSyncConf(byte st, byte sync_val[], byte len_sync_val)
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("setSyncConf"));
#endif

  byte regVal = readSPI(register_sync_config);
  regVal = setBits(regVal, len_sync_val, 0, 3);
  bitWrite(regVal, 4, st);
  writeSPI(register_sync_config, regVal);
  if ((len_sync_val > 0) && (len_sync_val < 9)) {
    for (int r = 0; r < len_sync_val; r++) {
      writeSPI(register_sync_value1 + r, sync_val[r]);
    }
  }
}

void setOpMode(byte opm)
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("setOpMode"));
#endif

  byte regVal = readSPI(register_opmode);

  /* default opmode_sleep */
  regVal = regVal & B11111000;
 
  switch (opm) {
    case opmode_stdby:
      bitSet(regVal, 0);
      break;
    case opmode_fstx:
      bitSet(regVal, 1);
      break;
    case opmode_tx:
      bitSet(regVal, 0);
      bitSet(regVal, 1);
      break;
    case opmode_fsrx:
      bitSet(regVal, 2);
      break;
    case opmode_rx:
      bitSet(regVal, 0);
      bitSet(regVal, 2);
      break;
  }
  writeSPI(register_opmode, regVal);

#if (debug_mode > 0)
  Serial.print("\t register_opmode ");
  Serial.print(regVal, BIN);
#endif
}

void readVer(char* buf, unsigned int bufSize)
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("readVer"));
#endif

  byte regVal = readSPI(register_ver);
  byte metalMask = regVal & B00001111;
  byte revNumber = regVal >> 4;
  snprintf(buf, bufSize, "%1u.%1u", revNumber, metalMask);
}

float readRSSIvalue() {
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("readRSSIvalue"));
#endif

  byte regVal = 0;
  regVal = readSPI(register_rssi_value);
  float rssi = regVal;
  rssi = (rssi / 2) * -1;
  return rssi;
}

float readRSSIthresh() {
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("readRSSIthresh"));
#endif

  byte regVal = 0;
  regVal = readSPI(register_rssi_thresh);
  float rssi = regVal;
  rssi = (rssi / 2) * -1;
  return rssi;
}

/* '0'=FSK  '1'=OOK */
void setMode(char mode)
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("setMode"));
#endif

  byte b = 0;
  if (mode == '1') b = 1;
  byte regVal = readSPI(register_opmode);
  bitWrite(regVal, 5, b);
  bitClear(regVal, 6);
  writeSPI(register_opmode, regVal);

#if (debug_mode > 0)
  Serial.print("\t register_opmode ");
  Serial.print(regVal, BIN);
#endif
}

// FSK bit 5 = 0
// OOK bit 5 = 1
byte getMode()
{
  byte regVal = readSPI(register_opmode);
  return bitRead(regVal, 5);
}

//void setBps(char *buf, int blen)
void setBps(char c)
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("setBps "));
#endif

  /*char c[blen];
    int n = 0;
    for (int i = 1; i < blen; i++) {
    c[n] = buf[i];
    n++;
    }
    c[n] = 0;
    n = atoi(c);
    unsigned long lr = br / n;
    unsigned int r = lr;
    byte lo = lowByte(r);
    byte hi = highByte(r);*/

  int i = c - '0';
  if (i > 9) {
    i = 9;
  }
  byte lo = bps_lo[i];
  byte hi = bps_hi[i];

#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("setBps highbyte: "));
  Serial.print(hi, HEX);
  Serial.print(F("\tlowbyte: "));
  Serial.print(lo, HEX);
#endif

  writeSPI(register_brmsb, hi);
  writeSPI(register_brlsb, lo);
}

unsigned int getBps()
{
  byte brLsb = readSPI(register_brlsb);
  byte brMsb = readSPI(register_brmsb);
  unsigned int bps = word(brMsb, brLsb);
  unsigned long l = br / bps;
  bps = l;
  return bps;
}

void reset() {
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("reset"));
#endif

  digitalWrite(sx1278_reset_pin, HIGH);
  delay(sx1278_reset_high_delay);
  digitalWrite(sx1278_reset_pin, LOW);
  delay(sx1278_reset_low_delay);
}

byte setBits(byte b, byte value, byte bpos, byte blen)
{
#if (debug_mode > 0)
  Serial.println();
  Serial.println(F("setBits"));
#endif

  byte res = b;
  for (int i = 0 ; i < blen; i++) bitWrite(res, i + bpos, bitRead(value, i));
  return res;
}

 

fskscanner.h

#define debug_mode                0

#define serial_speed              38400
#define serial_data_len           24
#define serial_data_read          23  
#define serial_end_char           13
#define fifo_buffer_size          255

#define spi_max_speed             4000000 // 250 ns
#define spi_slave_num             0
#define spi_delay                 100
#define spi_slave_num             0
#define spi_low_trf_delay         1
#define sx127x_rw_setclr_bit      7

#define sx1278_reset_pin          5
#define sx1278_reset_high_delay   1
#define sx1278_reset_low_delay    20
#define sx1278_curr_trim          0x2F // 120 mA

#define register_fifo             0x00
#define register_opmode           0x01
#define register_brmsb            0x02
#define register_brlsb            0x03
#define register_fdevmsb          0x04
#define register_fdevlsb          0x05
#define register_frfmsb           0x06
#define register_frfmid           0x07
#define register_frflsb           0x08
#define register_ocp              0x0B
#define register_rssi_thresh      0x10
#define register_rssi_value       0x11
#define register_preamble_detect  0x1f
#define register_preamble_msb     0x25
#define register_preamble_lsb     0x26
#define register_sync_config      0x27
#define register_sync_value1      0x28
#define register_packetconfig1    0x30
#define register_packetconfig2    0x31
#define register_payload_len      0x32
#define register_fifothresh       0x35
#define register_irq_flags1       0x3e
#define register_irq_flags2       0x3f
#define register_ver              0x42

#define opmode_sleep              0x00 // Sleep mode
#define opmode_stdby              0x01 // Stdby mode
#define opmode_fstx               0x02 // FS mode TX (FSTx)
#define opmode_tx                 0x03 // Transmitter mode (Tx)
#define opmode_fsrx               0x04 // FS mode RX (FSRx)
#define opmode_rx                 0x05 // Receiver mode (Rx)

#define br                        32000000