Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New send variant: listenMode #41

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 136 additions & 2 deletions RFM69.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ def sendFrame(self, toAddress, buff, requestACK, sendACK):
#wait for modeReady
while (self.readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00:
pass
# DIO0 is "Packet Sent"
self.writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00)

if (len(buff) > RF69_MAX_DATA_LEN):
buff = buff[0:RF69_MAX_DATA_LEN]
Expand All @@ -263,8 +265,12 @@ def sendFrame(self, toAddress, buff, requestACK, sendACK):

self.DATASENT = False
self.setMode(RF69_MODE_TX)
while (self.readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PACKETSENT) == 0x00:
pass
slept = 0
while not self.DATASENT:
time.sleep(self.sendSleepTime)
slept += self.sendSleepTime
if slept > 1.0:
break
self.setMode(RF69_MODE_RX)

def interruptHandler(self, pin):
Expand Down Expand Up @@ -391,3 +397,131 @@ def shutdown(self):
self.setHighPower(False)
self.sleep()
GPIO.cleanup()

#
# Sends data in a special manner (cf. https://lowpowerlab.com/forum/low-power-techniques/low-power-radio-wakeup/)
# Parameters:
# toAddress: nodeId of the recipient
# buff: data buffer to send
# burstDurationSec: duration of burst transmission in seconds
# (should match the setting on the receiver side)
def sendBurst(self, toAddress, buff, burstDurationSec = 1.0):

self.setMode(RF69_MODE_STANDBY)
self.writeReg(REG_PACKETCONFIG1, RF_PACKET1_FORMAT_VARIABLE | RF_PACKET1_DCFREE_WHITENING | RF_PACKET1_CRC_ON | RF_PACKET1_CRCAUTOCLEAR_ON )
self.writeReg(REG_PACKETCONFIG2, RF_PACKET2_RXRESTARTDELAY_NONE | RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AES_OFF)
self.writeReg(REG_SYNCVALUE1, 0x5A)
self.writeReg(REG_SYNCVALUE2, 0x5A)
self.writeReg(REG_FRFMSB, self.readReg(REG_FRFMSB) + 1)
self.writeReg(REG_FRFLSB, self.readReg(REG_FRFLSB))

#listenModeApplyHighSpeedSettings
self.writeReg(REG_BITRATEMSB, RF_BITRATEMSB_200000)
self.writeReg(REG_BITRATELSB, RF_BITRATELSB_200000)
self.writeReg(REG_FDEVMSB, RF_FDEVMSB_100000)
self.writeReg(REG_FDEVLSB, RF_FDEVLSB_100000)
self.writeReg(REG_RXBW, RF_RXBW_DCCFREQ_000 | RF_RXBW_MANT_20 | RF_RXBW_EXP_0 )

Duration = 1
StartDuration = Duration
StartTime = time.time()

while(Duration > 0):

# DIO0 is "Packet Sent"
self.writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00)

if (len(buff) > RF69_MAX_DATA_LEN):
buff = buff[0:RF69_MAX_DATA_LEN]

ack = 0x40

if isinstance(buff, basestring):
self.spi.xfer2([REG_FIFO | 0x80, len(buff) + 3, toAddress, self.address, ack] + [int(ord(i)) for i in list(buff)])
else:
self.spi.xfer2([REG_FIFO | 0x80, len(buff) + 3, toAddress, self.address, ack] + buff)

self.DATASENT = False
self.setMode(RF69_MODE_TX)
slept = 0
while not self.DATASENT:
time.sleep(self.sendSleepTime)
slept += self.sendSleepTime
if slept > burstDurationSec:
break

Duration = StartDuration - (time.time() - StartTime)

self.setMode(RF69_MODE_STANDBY)
self.setFreqeuncy(self.freqBand)
self.resetToNormalMode()

def resetToNormalMode(self):

frfMSB = {RF69_315MHZ: RF_FRFMSB_315, RF69_433MHZ: RF_FRFMSB_433,
RF69_868MHZ: RF_FRFMSB_868, RF69_915MHZ: RF_FRFMSB_915}
frfMID = {RF69_315MHZ: RF_FRFMID_315, RF69_433MHZ: RF_FRFMID_433,
RF69_868MHZ: RF_FRFMID_868, RF69_915MHZ: RF_FRFMID_915}
frfLSB = {RF69_315MHZ: RF_FRFLSB_315, RF69_433MHZ: RF_FRFLSB_433,
RF69_868MHZ: RF_FRFLSB_868, RF69_915MHZ: RF_FRFLSB_915}

self.CONFIG = {
0x01: [REG_OPMODE, RF_OPMODE_SEQUENCER_ON | RF_OPMODE_LISTEN_OFF | RF_OPMODE_STANDBY],
#no shaping
0x02: [REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONTYPE_FSK | RF_DATAMODUL_MODULATIONSHAPING_00],
#default:4.8 KBPS
0x03: [REG_BITRATEMSB, RF_BITRATEMSB_55555],
0x04: [REG_BITRATELSB, RF_BITRATELSB_55555],
#default:5khz, (FDEV + BitRate/2 <= 500Khz)
0x05: [REG_FDEVMSB, RF_FDEVMSB_50000],
0x06: [REG_FDEVLSB, RF_FDEVLSB_50000],

0x07: [REG_FRFMSB, frfMSB[self.freqBand]],
0x08: [REG_FRFMID, frfMID[self.freqBand]],
0x09: [REG_FRFLSB, frfLSB[self.freqBand]],

# looks like PA1 and PA2 are not implemented on RFM69W, hence the max output power is 13dBm
# +17dBm and +20dBm are possible on RFM69HW
# +13dBm formula: Pout=-18+OutputPower (with PA0 or PA1**)
# +17dBm formula: Pout=-14+OutputPower (with PA1 and PA2)**
# +20dBm formula: Pout=-11+OutputPower (with PA1 and PA2)** and high power PA settings (section 3.3.7 in datasheet)
#0x11: [REG_PALEVEL, RF_PALEVEL_PA0_ON | RF_PALEVEL_PA1_OFF | RF_PALEVEL_PA2_OFF | RF_PALEVEL_OUTPUTPOWER_11111],
#over current protection (default is 95mA)
#0x13: [REG_OCP, RF_OCP_ON | RF_OCP_TRIM_95],

# RXBW defaults are { REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_24 | RF_RXBW_EXP_5} (RxBw: 10.4khz)
#//(BitRate < 2 * RxBw)
0x19: [REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_16 | RF_RXBW_EXP_2],
#for BR-19200: //* 0x19 */ { REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_24 | RF_RXBW_EXP_3 },
#DIO0 is the only IRQ we're using
0x25: [REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01],
#must be set to dBm = (-Sensitivity / 2) - default is 0xE4=228 so -114dBm
0x29: [REG_RSSITHRESH, 220],
#/* 0x2d */ { REG_PREAMBLELSB, RF_PREAMBLESIZE_LSB_VALUE } // default 3 preamble bytes 0xAAAAAA
0x2e: [REG_SYNCCONFIG, RF_SYNC_ON | RF_SYNC_FIFOFILL_AUTO | RF_SYNC_SIZE_2 | RF_SYNC_TOL_0],
#attempt to make this compatible with sync1 byte of RFM12B lib
0x2f: [REG_SYNCVALUE1, 0x2D],
#NETWORK ID
0x30: [REG_SYNCVALUE2, self.networkID],
0x37: [REG_PACKETCONFIG1, RF_PACKET1_FORMAT_VARIABLE | RF_PACKET1_DCFREE_OFF |
RF_PACKET1_CRC_ON | RF_PACKET1_CRCAUTOCLEAR_ON | RF_PACKET1_ADRSFILTERING_OFF],
#in variable length mode: the max frame size, not used in TX
0x38: [REG_PAYLOADLENGTH, 66],
#* 0x39 */ { REG_NODEADRS, nodeID }, //turned off because we're not using address filtering
#TX on FIFO not empty
0x3C: [REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFONOTEMPTY | RF_FIFOTHRESH_VALUE],
#RXRESTARTDELAY must match transmitter PA ramp-down time (bitrate dependent)
0x3d: [REG_PACKETCONFIG2, RF_PACKET2_RXRESTARTDELAY_2BITS | RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AES_OFF],
#for BR-19200: //* 0x3d */ { REG_PACKETCONFIG2, RF_PACKET2_RXRESTARTDELAY_NONE | RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AES_OFF }, //RXRESTARTDELAY must match transmitter PA ramp-down time (bitrate dependent)
#* 0x6F */ { REG_TESTDAGC, RF_DAGC_CONTINUOUS }, // run DAGC continuously in RX mode
# run DAGC continuously in RX mode, recommended default for AfcLowBetaOn=0
0x6F: [REG_TESTDAGC, RF_DAGC_IMPROVED_LOWBETA0],
0x00: [255, 0]
}

#write config
for value in self.CONFIG.values():
self.writeReg(value[0], value[1])

self.writeReg(REG_LNA, (self.readReg(REG_LNA) & ~0x3) | RF_LNA_GAINSELECT_AUTO)
self.setHighPower(self.isRFM69HW)
Binary file added wiring.fzz
Binary file not shown.