Some radiomodem FSK mode transmissions in the ISM 868 band can be received with Arduino + Dragino Lora shield (Semtech SX1278 chip).
SX1278 library: https://github.com/open-electronics/LoRa/releases
SX1278 datasheet: http://www.semtech.com/apps/filedown/down.php?file=sx1276_77_78_79.pdf
ReqIrqFlags1: bit 0 SyncAddressMatch detected (sync value 0x01)
SX1278 datasheet:
"Packet mode (recommended): user only provides/retrieves payload bytes to/from the FIFO. The packet is automatically
built with preamble, Sync word, and optional CRC and DC-free encoding schemes The reverse operation is performed
in reception. The uC processing overhead is hence significantly reduced compared to Continuous mode. Depending on
the optional features activated (CRC, etc) the maximum payload length is limited to 255, 2047 bytes or unlimited"
First byte of the packet seems to be length of the packet....
#include <SX1278.h>
#define SERIAL_SPEED 9600
#define FREQ 869.525
#define BPS 9600
#define STATE_STANDBY 1
#define STATE_FSRX 4
#define STATE_RX 5
#define S_DELAY 10
#define L_DELAY 100
#define RX_BUFFER_LEN 255
#define SX_BEGIN "SX.begin"
#define SX_BITRATE "SX.readBPS "
#define SX_FREQ "SX.readFreq "
#define SX_IRQ1_TXT "RegIrqFlags1_value "
#define SX_IRQ2_TXT "RegIrqFlags2_value "
#define RSSI_THRESHOLD 180 // -rssi/2
#define CH_FILTER_BW B00001100 // 25 kHz
#define SYNC_VALUE 0x01
#define PRINT_IRQ_CHG 0
#define RegRssiConfig 0x0e
#define RegRxBw 0x12
#define RegPacketConfig1 0x30
#define RegFifo 0x00
#define RegOpMode 0x01
#define RegPaRamp 0x0a
#define RegRssiThresh 0x10
#define RegOokPeak 0x14
#define RegPreambleDetect 0x1f
#define RegSyncConfig 0x27
#define RegSyncValue1 0x28
#define RegSyncValue2 0x29
#define RegSyncValue3 0x2a
#define RegPacketConfig2 0x31
#define RegPayloadLength 0x32
#define RegIrqFlags1 0x3e
#define RegIrqFlags2 0x3f
#define RegDioMapping1 0x40
byte b;
byte RegIrqFlags1_value;
byte RegIrqFlags2_value;
byte rxBuffer[RX_BUFFER_LEN];
void setup() {
Serial.begin(SERIAL_SPEED);
if (SX.begin()) {
Serial.println(F(SX_BEGIN));
delay(S_DELAY);
SX.startModeFSKOOK();
b = SX.SPIread(RegOpMode);
bitClear(b, 6);
bitClear(b, 5);
SX.SPIwrite(RegOpMode, b);
// Channel filter bandwidth control
SX.SPIwrite(RegRxBw, CH_FILTER_BW);
SX.setFreq(FREQ);
Serial.print(F(SX_FREQ));
Serial.println(SX.readFreq(), DEC);
SX.setBPS(BPS);
Serial.print(F(SX_BITRATE));
Serial.println(SX.readBPS(), DEC);
// Bits 7-6: AutoRestartRxMode, 01 ïƒ On, without waiting for the PLL to re-lock
// Bit 4: Enables the Sync word generation and detection: 0 => Off, 1 => On
// Bit 5: Sets the polarity of the Preamble. 0 ïƒ 0xAA, 1 ïƒ 0x55
// Bits 2-0: Size of the Sync word (SyncSize + 1)
b = SX.SPIread(RegSyncConfig);
bitClear(b, 7);
bitSet(b, 6);
bitSet(b, 4);
bitClear(b, 5);
bitClear(b, 2);
bitSet(b, 1);
bitClear(b, 0);
SX.SPIwrite(RegSyncConfig, b);
SX.SPIwrite(RegSyncValue1, SYNC_VALUE);
SX.SPIwrite(RegSyncValue2, SYNC_VALUE);
SX.SPIwrite(RegSyncValue3, SYNC_VALUE);
// Bits 6-5: Defines DC-free encoding/decoding performed: 00->none, 01->manchester, 10->whitening
// Bit 7: packet format, 0 = fixed length, 1 = variable length
// Bit 4: crc calc/check, 0 = off, 1 = on
// Bits 2-1: Defines address based filtering in Rx: 00 ïƒ None (Off)
// Bit 3: Defines the behavior of the packet handler when CRC check fails:
// 0 => Clear FIFO and restart new packet reception. No PayloadReady interrupt issued.
// 1 => Do not clear FIFO. PayloadReady interrupt issued.
// Bit 0: Selects the CRC and whitening algorithms:
// 0 ïƒ CCITT CRC implementation with standard whitening
// 1 ïƒ IBM CRC implementation with alternate whitening
b = SX.SPIread(RegPacketConfig1);
bitClear(b, 6);
bitSet(b, 5);
bitSet(b, 7);
bitClear(b, 4);
bitClear(b, 3);
bitClear(b, 2);
bitClear(b, 1);
bitClear(b, 0);
SX.SPIwrite(RegPacketConfig1, b);
// Bits 6-5: FSK data shaping:
// 00 -> no shaping, 01 -> Gaussian filter BT = 1.0
// 10 -> Gaussian filter BT = 0.5, 11 -> Gaussian filter BT = 0.3
// Bits 3-0: Rise/Fall time of ramp up/down in FSK:
// 1001 ïƒ 40 us
b = SX.SPIread(RegPaRamp);
bitClear(b, 6);
bitClear(b, 5);
bitSet(b, 3);
bitClear(b, 2);
bitClear(b, 1);
bitSet(b, 0);
SX.SPIwrite(RegPaRamp, b);
SX.SPIwrite(RegPayloadLength, RX_BUFFER_LEN);
// Data processing mode: 0 => Continuous mode, 1 => Packet mode
b = SX.SPIread(RegPacketConfig2);
bitSet(b, 6);
SX.SPIwrite(RegPacketConfig2, b);
// RSSI smoothing.
// Defines the number of samples taken to average the RSSI result. 010 -> 8 samples
b = SX.SPIread(RegRssiConfig);
bitClear(b, 2);
bitSet(b, 1);
bitClear(b, 0);
SX.SPIwrite(RegRssiConfig, b);
SX.SPIwrite(RegRssiThresh, RSSI_THRESHOLD);
// Bit 5: enables the Bit Synchronizer:
// 0 -> bit sync disabled (not possible in packet mode), 1 -> bit sync enabled
b = SX.SPIread(RegOokPeak);
bitSet(b, 5);
SX.SPIwrite(RegOokPeak, b);
// Set DIO mapping
b = SX.SPIread(RegDioMapping1);
bitClear(b, 5);
bitClear(b, 4);
bitClear(b, 3);
bitClear(b, 2);
SX.SPIwrite(RegDioMapping1, b);
// RegPreambleDetect (0x1f). Enables Preamble detector when set to 1.
// The AGC settings supersede this bit during the startup / AGC phase.
// Bit 7: 0 -> turned off, 1 -> turned on
// Bits 6-5: Number of Preamble bytes to detect to trigger an interrupt.
// 00 ïƒ 1 byte, 10 ïƒ 3 bytes, 01 ïƒ 2 bytes
b = SX.SPIread(RegPreambleDetect);
bitClear(b, 7);
bitClear(b, 6);
bitSet(b, 5);
SX.SPIwrite(RegPreambleDetect, b);
clearFifoAndFlags();
SX.setState(STATE_FSRX);
delay(L_DELAY);
SX.setState(STATE_RX);
#if (PRINT_IRQ_CHG == 1)
RegIrqFlags1_value = SX.SPIread(RegIrqFlags1);
RegIrqFlags2_value = SX.SPIread(RegIrqFlags2);
Serial.print(F(SX_IRQ1_TXT));
Serial.println(RegIrqFlags1_value, BIN);
Serial.print(F(SX_IRQ2_TXT));
Serial.println(RegIrqFlags2_value, BIN);
#endif
}
}
void loop() {
byte r2 = SX.SPIread(RegIrqFlags2);
#if (PRINT_IRQ_CHG == 1)
byte r1 = SX.SPIread(RegIrqFlags1);
if (r1 != RegIrqFlags1_value) {
RegIrqFlags1_value = r1;
Serial.print(F(SX_IRQ1_TXT));
Serial.println(RegIrqFlags1_value, BIN);
}
if (r2 != RegIrqFlags2_value) {
RegIrqFlags2_value = r2;
Serial.print(F(SX_IRQ2_TXT));
Serial.println(RegIrqFlags2_value, BIN);
}
#endif
if (bitRead(r2, 2) == 1) {
b = SX.SPIread(RegPayloadLength);
if (b > 0) {
b = SX.dataReceived(rxBuffer, b);
if (b > 0) {
for (int i = 0; i < b; i++) {
Serial.print(rxBuffer[i]);
Serial.print(";");
}
Serial.println();
}
}
}
}
void clearFifoAndFlags() {
// Flag(s) and FIFO are cleared when this bit is set
b = SX.SPIread(RegIrqFlags2);
bitSet(b, 4);
SX.SPIwrite(RegIrqFlags2, b);
delay(S_DELAY);
}
Kommentit
Tämän blogin kommentit tarkistetaan ennen julkaisua.