RX: RTL-SDR.COM V.3, GNU Radio, Python
TX: Arduino Uno & Dragino Lora Shield (Semtech SX1278) http://wiki.dragino.com/index.php?title=Lora_Shield
436 MHz 1200 bps 2-FSK
NRZ, CRC OFF, preamble polarity 0xAA, preamble length 24, no sync words
Arduino code (Open-Electronics sx1278 library is available in GitHub. https://github.com/open-electronics/LoRa/releases)
SX1278 datasheet: https://cdn-shop.adafruit.com/product-files/3179/sx1276_77_78_79.pdf
#include <SX1278.h>
#define SERIAL_SPEED 9600
#define FREQ 436
#define BPS 1200
#define STATE_STANDBY 1
#define STATE_FSTX 2
#define STATE_TX 3
#define S_DELAY 1
#define L_DELAY 10
#define ST_DELAY 550
#define TX_DELAY 1000
#define NUM_SYNC_BYTES 3
#define TX_BUFFER_LEN 34
#define SX_BEGIN "SX.begin"
#define SX_BITRATE "SX.readBPS "
#define SX_FREQ "SX.readFreq "
#define RegRxBw 0x12
#define RegOokPeak 0x14
#define RegPreambleMsb 0x25
#define RegPreambleLsb 0x26
#define RegSyncConfig 0x27
#define RegPacketConfig1 0x30
#define RegPacketConfig2 0x31
byte syncBytes[NUM_SYNC_BYTES] = {0x01, 0x01, 0x01};
byte txBuffer[TX_BUFFER_LEN] = {65,65,65,65,65,65,66,66,66,66,66,66,70,70,70,70,70,70,48,48,48,48,48,48,32,32,32,32,32,32,10,10,10,10};
void setup() {
Serial.begin(SERIAL_SPEED);
if (SX.begin()) {
Serial.println(F(SX_BEGIN));
delay(S_DELAY);
SX.startModeFSKOOK();
SX.setModulation(0); // FSK
// Channel filter bandwidth control. RxBwMant (bits 4-3): 01->20 & RxBwExp (bits 2-0): 4 = 25 kHz
byte b = SX.SPIread(RegRxBw);
bitClear(b, 4);
bitSet(b, 3);
bitSet(b, 2);
bitClear(b, 1);
bitClear(b, 0);
SX.SPIwrite(RegRxBw, b);
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);
bitClear(b, 4);
bitClear(b, 5);
bitClear(b, 2);
bitClear(b, 1);
bitClear(b, 0);
SX.SPIwrite(RegSyncConfig, b);
// 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 = 0;
SX.SPIwrite(RegPacketConfig1, b);
SX.SPIwrite(RegPreambleMsb, 0);
SX.SPIwrite(RegPreambleLsb, 24);
b = SX.SPIread(RegPacketConfig2);
bitSet(b, 6);
SX.SPIwrite(RegPacketConfig2, b);
// 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);
SX.setPower(2); // 10 mW
SX.setState(STATE_STANDBY);
// SX.setState(STATE_FSTX);
// delay(S_DELAY);
// SX.setState(STATE_TX);
delay(L_DELAY);
}
}
void loop() {
SX.dataToSend(txBuffer, TX_BUFFER_LEN);
delay(L_DELAY);
SX.setState(STATE_FSTX);
delay(S_DELAY);
SX.setState(STATE_TX);
delay(ST_DELAY);
SX.setState(STATE_STANDBY);
delay(TX_DELAY);
}
Full size image https://ibb.co/jEwfUd
32-bit IEEE float IQ file.
Skip head and head blocks are used to decrease durations of noise in the signal. IQ data is recorded with SDRSharp + RTL-SDR (Correct IQ to remove DC spike). Squelch block could be used to eliminate noise before and after FSK data burst. Center_freq value is -200 for adjusting more optimally to the center of the signal. Dev_lo = center_freq - dev. Dev_hi = center_freq + dev.
Samp_per_sym = samp_rate / 1200 / decimation. Omega = samp_per_sym*(1+0.0).
Frequency Xlating FIR filter taps = firdes.low_pass(1.0, samp_rate, (dev_hi - dev_lo), 200).
Python code converts binary file out.txt to text file out-d1.txt
f = open("out.txt", "rb")
d = f.readlines()
f.close()
d[0] = d[0].replace('\x00', '0')
d[0] = d[0].replace('\x01', '1')
f = open("out-d1.txt", "w")
f.write(d[0])
f.close()
print 'converted'
byte txBuffer[TX_BUFFER_LEN] = {65,65,65,65,65,65,66,66,66,66,66,66,70,70,70,70,70,70,48,48,48,48,48,48,32,32,32,32,32,32,10,10,10,10};
Kommentit
Tämän blogin kommentit tarkistetaan ennen julkaisua.