Friedland Libra+ 48249SL wireless doorbell (868 MHz ISM band)
Arduino Uno & Dragino Lora Module (Semtech SX1278) http://www.dragino.com/products/module/item/102-lora-shield.html
Open-Electronics sx1278 library is available in GitHub. https://github.com/open-electronics/LoRa/releases
Transmission audio clip: https://vocaroo.com/i/s0bCrSX39cxh
Receiver unit
Serial.println(b);
Serial.println(b);
Serial.println(b);
#include <SX1278.h>
#define CONT_MODE
#define BIT_SYNC
#define SERIAL_SPEED 9600
#define FREQ 868.25
#define BPS 1200
#define STATE_STANDBY 1
#define STATE_FSRX 4
#define STATE_RX 5
#define S_DELAY 10
#define L_DELAY 100
#define RX_BUFFER_LEN 16
#define SX_BEGIN "SX.begin"
#define SX_BITRATE "SX.readBPS "
#define SX_FREQ "SX.readFreq "
#define OOK_THRESHOLD 0x1c
#define RSSI_THRESHOLD 180 // -rssi/2
#define RSSI_VAL (RSSI_THRESHOLD / 2) * -1
#define CH_FILTER_BW B00001011 // 50 kHz
#define SYNC_VALUE 0x01
#define DATA_PIN 7
#define DCLK_PIN 6
#define RegRssiConfig 0x0e
#define RegRxBw 0x12
#define RegPacketConfig1 0x30
#define RegFifo 0x00
#define RegRssiThresh 0x10
#define RegOokPeak 0x14
#define RegOokFix 0x15
#define RegOokAvg 0x16
#define RegPaRamp 0x0a
#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
bool rx = false;
uint8_t b;
uint8_t RegIrqFlags1_value;
uint8_t RegIrqFlags2_value;
uint8_t rxBuffer[RX_BUFFER_LEN];
void setup() {
Serial.begin(SERIAL_SPEED);
#ifdef CONT_MODE
pinMode(DATA_PIN, INPUT);
pinMode(DCLK_PIN, INPUT);
#endif
if (SX.begin()) {
Serial.println(F(SX_BEGIN));
delay(S_DELAY);
SX.startModeFSKOOK();
SX.setModulation(1); // OOK
// 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-1: Size of the Sync word (SyncSize + 1)
b = SX.SPIread(RegSyncConfig);
bitClear(b, 7);
bitSet(b, 6);
bitClear(b, 4);
bitClear(b, 5);
bitClear(b, 2);
bitClear(b, 1);
bitSet(b, 0);
SX.SPIwrite(RegSyncConfig, b);
SX.SPIwrite(RegSyncValue1, SYNC_VALUE);
SX.SPIwrite(RegSyncValue2, SYNC_VALUE);
SX.SPIwrite(RegSyncValue3, SYNC_VALUE);
#ifdef CONT_MODE
// Set DIO mapping
b = SX.SPIread(RegDioMapping1);
bitClear(b, 5);
bitClear(b, 4);
bitClear(b, 3);
bitClear(b, 2);
SX.SPIwrite(RegDioMapping1, b);
#endif
// 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.
b = SX.SPIread(RegPacketConfig1);
bitClear(b, 6);
bitClear(b, 5);
bitClear(b, 7);
bitClear(b, 4);
bitSet(b, 3);
bitClear(b, 2);
bitClear(b, 1);
SX.SPIwrite(RegPacketConfig1, b);
SX.SPIwrite(RegPayloadLength, RX_BUFFER_LEN);
// Data processing mode: 0 => Continuous mode, 1 => Packet mode
b = SX.SPIread(RegPacketConfig2);
#ifdef CONT_MODE
bitClear(b, 6);
#else
bitSet(b, 6);
#endif
SX.SPIwrite(RegPacketConfig2, b);
// RSSI smoothing.
// Defines the number of samples taken to average the RSSI result.
// 000 -> 2 samples
b = SX.SPIread(RegRssiConfig);
bitClear(b, 2);
bitClear(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
// Bits 4-3: Selects the type of threshold in the OOK data slicer:
// (01 = peak mode, 00 = fixed mode)
// Bits 2-0: Size of each decrement of the RSSI threshold in the OOK demodulator
b = SX.SPIread(RegOokPeak);
#ifdef BIT_SYNC
bitSet(b, 5);
#else
bitClear(b, 5);
#endif
bitClear(b, 4);
bitSet(b, 3);
bitClear(b, 2);
bitClear(b, 1);
bitClear(b, 0);
SX.SPIwrite(RegOokPeak, b);
SX.SPIwrite(RegOokFix, OOK_THRESHOLD);
b = SX.SPIread(RegOokAvg);
bitClear(b, 7);
bitClear(b, 6);
bitClear(b, 5);
bitClear(b, 3);
bitClear(b, 2);
SX.SPIwrite(RegOokAvg, b);
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);
// 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);
// Flag(s) and FIFO are cleared when this bit is set
b = SX.SPIread(RegIrqFlags2);
bitSet(b, 4);
SX.SPIwrite(RegIrqFlags2, b);
SX.setState(STATE_FSRX);
delay(L_DELAY);
SX.setState(STATE_RX);
RegIrqFlags1_value = SX.SPIread(RegIrqFlags1);
RegIrqFlags2_value = SX.SPIread(RegIrqFlags2);
Serial.print("RegIrqFlags1_value ");
Serial.println(RegIrqFlags1_value, BIN);
Serial.print("RegIrqFlags2_value ");
Serial.println(RegIrqFlags2_value, BIN);
#ifdef CONT_MODE
digitalWrite(DCLK_PIN, LOW);
#endif
rx = true;
}
}
void loop() {
if (rx) {
#ifdef CONT_MODE
b = shiftInMsb();
Serial.println(b);
Serial.println(b);
#else
uint8_t r1 = SX.SPIread(RegIrqFlags1);
uint8_t r2 = SX.SPIread(RegIrqFlags2);
if (r1 != RegIrqFlags1_value) {
RegIrqFlags1_value = r1;
Serial.print("RegIrqFlags1_value ");
Serial.println(RegIrqFlags1_value, BIN);
}
if (r2 != RegIrqFlags2_value) {
RegIrqFlags2_value = r2;
Serial.print("RegIrqFlags2_value ");
Serial.println(RegIrqFlags2_value, BIN);
}
if (bitRead(r2, 2) == 1) {
b = SX.SPIread(RegPayloadLength);
if (b > 0) {
Serial.print("RegPayloadLength ");
Serial.println(b, DEC);
b = SX.dataReceived(rxBuffer, b);
if (b > 0) {
for (int i = 0; i < b; i++) { Serial.print(rxBuffer[i]); }
Serial.println();
}
}
}
#endif
}
}
uint8_t shiftInMsb() {
uint8_t value = 0;
uint8_t i;
for (i = 0; i < 8; ++i) {
//digitalWrite(DCLK_PIN, HIGH);
PORTD = PORTD | B01000000;
value |= digitalRead(DATA_PIN) << (7 - i);
//digitalWrite(DCLK_PIN, LOW);
PORTD = PORTD & B10111111;
}
return value;
}
Kommentit
Tämän blogin kommentit tarkistetaan ennen julkaisua.