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
Kommentit
Tämän blogin kommentit tarkistetaan ennen julkaisua.