master
Cuddly Cheetah 5 years ago
parent 2d25fbf8a2
commit 8063db6278

@ -1,6 +1,6 @@
#!/usr/bin/env python2
from RFM69registers import *
from RFM69_POCSAGregisters import *
import spidev
import RPi.GPIO as GPIO
import time
@ -8,12 +8,12 @@ import time
def chunks(l, n):
n = max(1, n)
return (l[i:i+n] for i in xrange(0, len(l), n))
class RFM69(object):
def __init__(self, freqBand, nodeID, networkID, isRFM69HW = False, intPin = 18, rstPin = 29, spiBus = 0, spiDevice = 0):
class RFM69_POCSAG(object):
def __init__(self, freqBand, pocsagBaudRate = 1200, isRFM69HW = False, intPin = 18, rstPin = 29, spiBus = 0, spiDevice = 0):
self.freqBand = freqBand
self.address = nodeID
self.networkID = networkID
self.pocsagBaudRate = pocsagBaudRate
self.isRFM69HW = isRFM69HW
self.intPin = intPin
self.rstPin = rstPin
@ -21,14 +21,8 @@ class RFM69(object):
self.spiDevice = spiDevice
self.intLock = False
self.mode = ""
self.promiscuousMode = False
self.DATASENT = False
self.DATALEN = 0
self.SENDERID = 0
self.TARGETID = 0
self.PAYLOADLEN = 0
self.ACK_REQUESTED = 0
self.ACK_RECEIVED = 0
self.RSSI = 0
self.DATA = []
self.sendSleepTime = 0.05
@ -44,16 +38,17 @@ class RFM69(object):
frfLSB = {RF69_315MHZ: RF_FRFLSB_315, RF69_433MHZ: RF_FRFLSB_433,
RF69_868MHZ: RF_FRFLSB_868, RF69_915MHZ: RF_FRFLSB_915}
brMSB = { 512: 0xF4, 1200: RF_BITRATEMSB_1200, 2400: RF_BITRATEMSB_2400 }
brLSB = { 512: 0xF4, 1200: RF_BITRATELSB_1200, 2400: RF_BITRATELSB_2400 }
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_1200],
0x04: [REG_BITRATELSB, RF_BITRATELSB_1200],
#default:5khz, (FDEV + BitRate/2 <= 500Khz)
0x05: [REG_FDEVMSB, RF_FDEVMSB_50000],
0x06: [REG_FDEVLSB, RF_FDEVLSB_50000],
0x03: [REG_BITRATEMSB, brMSB[self.pocsagBaudRate]],
0x04: [REG_BITRATELSB, brLSB[self.pocsagBaudRate]],
0x05: [REG_FDEVMSB, 0x00], # 4.5KHz for POCSAG
0x06: [REG_FDEVLSB, 0x4a],
0x07: [REG_FRFMSB, frfMSB[freqBand]],
0x08: [REG_FRFMID, frfMID[freqBand]],
@ -79,9 +74,9 @@ class RFM69(object):
#/* 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],
0x2f: [REG_SYNCVALUE1, 0x00],
#NETWORK ID
0x30: [REG_SYNCVALUE2, networkID],
0x30: [REG_SYNCVALUE2, 0x00],
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
@ -98,6 +93,11 @@ class RFM69(object):
0x00: [255, 0]
}
#rfmModule.writeReg(REG_OPMODE, RF_OPMODE_SEQUENCER_ON | RF_OPMODE_LISTEN_OFF | RF_OPMODE_TRANSMITTER)
#rfmModule.writeReg(REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONSHAPING_00)
#self.writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00)
#self.writeReg(REG_DIOMAPPING2, RF_DIOMAPPING2_CLKOUT_OFF)
#initialize SPI
self.spi = spidev.SpiDev()
self.spi.open(self.spiBus, self.spiDevice)
@ -107,7 +107,7 @@ class RFM69(object):
GPIO.output(self.rstPin, GPIO.HIGH);
time.sleep(0.5)
GPIO.output(self.rstPin, GPIO.LOW);
time.sleep(0.5)
time.sleep(0.1)
#verify chip is syncing?
while self.readReg(REG_SYNCVALUE1) != 0xAA:
@ -120,7 +120,12 @@ class RFM69(object):
for value in self.CONFIG.values():
self.writeReg(value[0], value[1])
self.encrypt(0)
#pocsag specific
self.writeReg(REG_PACKETCONFIG1, RF_PACKET1_FORMAT_FIXED | RF_PACKET1_DCFREE_OFF | RF_PACKET1_CRC_OFF | RF_PACKET1_CRCAUTOCLEAR_ON | RF_PACKET1_ADRSFILTERING_OFF)
self.writeReg(REG_PAYLOADLENGTH, 0x00)
self.writeReg(REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFONOTEMPTY | RF_FIFOTHRESH_VALUE)
self.writeReg(REG_PREAMBLELSB, 0x00)
self.writeReg(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN)
self.setHighPower(self.isRFM69HW)
# Wait for ModeReady
while (self.readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00:
@ -133,7 +138,6 @@ class RFM69(object):
self.writeReg(REG_FRFMSB, FRF >> 16)
self.writeReg(REG_FRFMID, FRF >> 8)
self.writeReg(REG_FRFLSB, FRF)
def setMode(self, newMode):
if newMode == self.mode:
return
@ -161,72 +165,20 @@ class RFM69(object):
pass
self.mode = newMode;
def sleep(self):
self.setMode(RF69_MODE_SLEEP)
def setAddress(self, addr):
self.address = addr
self.writeReg(REG_NODEADRS, self.address)
def setNetwork(self, networkID):
self.networkID = networkID
self.writeReg(REG_SYNCVALUE2, networkID)
def setBaudRate(self, baudRate):
brMSB = { 512: 0xF4, 1200: RF_BITRATEMSB_1200, 2400: RF_BITRATEMSB_2400 }
brLSB = { 512: 0xF4, 1200: RF_BITRATELSB_1200, 2400: RF_BITRATELSB_2400 }
self.pocsagBaudRate = baudRate
self.writeReg(REG_BITRATEMSB, brMSB[self.pocsagBaudRate])
self.writeReg(REG_BITRATELSB, brLSB[self.pocsagBaudRate])
def setPowerLevel(self, powerLevel):
if powerLevel > 31:
powerLevel = 31
self.powerLevel = powerLevel
self.writeReg(REG_PALEVEL, (self.readReg(REG_PALEVEL) & 0xE0) | self.powerLevel)
def canSend(self):
if self.mode == RF69_MODE_STANDBY:
self.receiveBegin()
return True
#if signal stronger than -100dBm is detected assume channel activity
elif self.mode == RF69_MODE_RX and self.PAYLOADLEN == 0 and self.readRSSI() < CSMA_LIMIT:
self.setMode(RF69_MODE_STANDBY)
return True
return False
def send(self, toAddress, buff = "", requestACK = False):
self.writeReg(REG_PACKETCONFIG2, (self.readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART)
now = time.time()
while (not self.canSend()) and time.time() - now < RF69_CSMA_LIMIT_S:
self.receiveDone()
self.sendFrame(toAddress, buff, requestACK, False)
# to increase the chance of getting a packet across, call this function instead of send
# and it handles all the ACK requesting/retrying for you :)
# The only twist is that you have to manually listen to ACK requests on the other side and send back the ACKs
# The reason for the semi-automaton is that the lib is ingterrupt driven and
# requires user action to read the received data and decide what to do with it
# replies usually take only 5-8ms at 50kbps@915Mhz
def sendWithRetry(self, toAddress, buff = "", retries = 3, retryWaitTime = 10):
for i in range(0, retries):
self.send(toAddress, buff, True)
sentTime = time.time()
while (time.time() - sentTime) * 1000 < retryWaitTime:
if self.ACKReceived(toAddress):
return True
return False
def ACKReceived(self, fromNodeID):
if self.receiveDone():
return (self.SENDERID == fromNodeID or fromNodeID == RF69_BROADCAST_ADDR) and self.ACK_RECEIVED
return False
def ACKRequested(self):
return self.ACK_REQUESTED and self.TARGETID != RF69_BROADCAST_ADDR
def sendACK(self, toAddress = 0, buff = ""):
toAddress = toAddress if toAddress > 0 else self.SENDERID
while not self.canSend():
self.receiveDone()
self.sendFrame(toAddress, buff, False, True)
def sendBuffer(self, buff):
#turn off receiver to prevent reception while filling fifo
self.setMode(RF69_MODE_STANDBY)
#wait for modeReady
while (self.readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00:
@ -235,10 +187,7 @@ class RFM69(object):
self.writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00)
transmitChunks = chunks(buff, 30)
"""if (len(firstBuff) > RF69_MAX_DATA_LEN):
leftOverBuff = firstBuff[RF69_MAX_DATA_LEN:]
firstBuff = firstBuff[0:RF69_MAX_DATA_LEN]
leftOverChunks = chunks(leftOverBuff, 30)"""
self.spi.xfer2([REG_FIFO | 0x80] + transmitChunks.next())
self.DATASENT = False
self.setMode(RF69_MODE_TX)
@ -260,107 +209,13 @@ class RFM69(object):
if slept > 1.0:
break
self.setMode(RF69_MODE_RX)
def sendFrame(self, toAddress, buff, requestACK, sendACK):
#turn off receiver to prevent reception while filling fifo
self.setMode(RF69_MODE_STANDBY)
#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)
len = 0
buflen = 0
if (len(buff) > RF69_MAX_DATA_LEN):
buff = buff[0:RF69_MAX_DATA_LEN]
ack = 0
if sendACK:
ack = 0x80
elif requestACK:
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 > 1.0:
break
self.setMode(RF69_MODE_RX)
def interruptHandler(self, pin):
self.intLock = True
self.DATASENT = True
self.intLock = False
def receiveBegin(self):
while self.intLock:
time.sleep(.1)
self.DATALEN = 0
self.SENDERID = 0
self.TARGETID = 0
self.PAYLOADLEN = 0
self.ACK_REQUESTED = 0
self.ACK_RECEIVED = 0
self.RSSI = 0
if (self.readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PAYLOADREADY):
# avoid RX deadlocks
self.writeReg(REG_PACKETCONFIG2, (self.readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART)
#set DIO0 to "PAYLOADREADY" in receive mode
self.writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01)
self.setMode(RF69_MODE_RX)
def receiveDone(self):
if (self.mode == RF69_MODE_RX or self.mode == RF69_MODE_STANDBY) and self.PAYLOADLEN > 0:
self.setMode(RF69_MODE_STANDBY)
return True
if self.readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_TIMEOUT:
# https://github.com/russss/rfm69-python/blob/master/rfm69/rfm69.py#L112
# Russss figured out that if you leave alone long enough it times out
# tell it to stop being silly and listen for more packets
self.writeReg(REG_PACKETCONFIG2, (self.readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART)
elif self.mode == RF69_MODE_RX:
# already in RX no payload yet
return False
self.receiveBegin()
return False
def readRSSI(self, forceTrigger = False):
rssi = 0
if forceTrigger:
self.writeReg(REG_RSSICONFIG, RF_RSSI_START)
while self.readReg(REG_RSSICONFIG) & RF_RSSI_DONE == 0x00:
pass
rssi = self.readReg(REG_RSSIVALUE) * -1
rssi = rssi >> 1
return rssi
def encrypt(self, key):
self.setMode(RF69_MODE_STANDBY)
if key != 0 and len(key) == 16:
self.spi.xfer([REG_AESKEY1 | 0x80] + [int(ord(i)) for i in list(key)])
self.writeReg(REG_PACKETCONFIG2,(self.readReg(REG_PACKETCONFIG2) & 0xFE) | RF_PACKET2_AES_ON)
else:
self.writeReg(REG_PACKETCONFIG2,(self.readReg(REG_PACKETCONFIG2) & 0xFE) | RF_PACKET2_AES_OFF)
def readReg(self, addr):
return self.spi.xfer([addr & 0x7F, 0])[1]
def writeReg(self, addr, value):
self.spi.xfer([addr | 0x80, value])
def promiscuous(self, onOff):
self.promiscuousMode = onOff
def setHighPower(self, onOff):
if onOff:
self.writeReg(REG_OCP, RF_OCP_OFF)
@ -370,7 +225,6 @@ class RFM69(object):
self.writeReg(REG_OCP, RF_OCP_ON)
#enable P0 only
self.writeReg(REG_PALEVEL, RF_PALEVEL_PA0_ON | RF_PALEVEL_PA1_OFF | RF_PALEVEL_PA2_OFF | powerLevel)
def setHighPowerRegs(self, onOff):
if onOff:
self.writeReg(REG_TESTPA1, 0x5D)
@ -378,13 +232,11 @@ class RFM69(object):
else:
self.writeReg(REG_TESTPA1, 0x55)
self.writeReg(REG_TESTPA2, 0x70)
def readAllRegs(self):
results = []
for address in range(1, 0x50):
results.append([str(hex(address)), str(bin(self.readReg(address)))])
return results
def readTemperature(self, calFactor):
self.setMode(RF69_MODE_STANDBY)
self.writeReg(REG_TEMP1, RF_TEMP1_MEAS_START)
@ -393,13 +245,10 @@ class RFM69(object):
# COURSE_TEMP_COEF puts reading in the ballpark, user can add additional correction
#'complement'corrects the slope, rising temp = rising val
return (int(~self.readReg(REG_TEMP2)) * -1) + COURSE_TEMP_COEF + calFactor
def rcCalibration(self):
self.writeReg(REG_OSC1, RF_OSC1_RCCAL_START)
while self.readReg(REG_OSC1) & RF_OSC1_RCCAL_DONE == 0x00:
pass
def shutdown(self):
self.setHighPower(False)
self.sleep()

@ -1,18 +1,16 @@
#!/usr/bin/env python2
import RFM69
from RFM69registers import *
import RFM69_POCSAG
from RFM69_POCSAGregisters import *
import datetime
import time
from ConfigParser import SafeConfigParser
rfmModule = RFM69.RFM69(RF69_433MHZ, 1, 1, True)
rfmModule.shutdown()
config = SafeConfigParser()
rfmModule = RFM69_POCSAG.RFM69_POCSAG(RF69_433MHZ, pocsagBaudRate=1200, True)
#rfmModule.shutdown()
print "class initialized"
print "reading all registers"
results = rfmModule.readAllRegs()
for result in results:
print result
print "Performing rcCalibration"
rfmModule.writeReg(REG_FDEVMSB, 0x00)
@ -20,46 +18,13 @@ rfmModule.writeReg(REG_FDEVLSB, 0x4a)
freqHz = 434790000
freqHz /= 61.03515625 # divide down by FSTEP to get FRF
freqHz = int(freqHz) + 35
rfmModule.writeReg(REG_FRFMSB, freqHz >> 16)
rfmModule.writeReg(REG_FRFMID, freqHz >> 8)
rfmModule.writeReg(REG_FRFLSB, freqHz)
rfmModule.writeReg(REG_OPMODE, RF_OPMODE_SEQUENCER_ON | RF_OPMODE_LISTEN_OFF | RF_OPMODE_TRANSMITTER)
rfmModule.writeReg(REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONSHAPING_00)
#rfmModule.writeReg(REG_BITRATEMSB, 0xF4)
#rfmModule.writeReg(REG_BITRATELSB, 0xF4)
rfmModule.writeReg(REG_BITRATEMSB, RF_BITRATEMSB_1200)
rfmModule.writeReg(REG_BITRATELSB, RF_BITRATELSB_1200)
#rfmModule.writeReg(REG_BITRATEMSB, 0xFF)
#rfmModule.writeReg(REG_BITRATELSB, 0xFF)
rfmModule.writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00)
rfmModule.writeReg(REG_DIOMAPPING2, RF_DIOMAPPING2_CLKOUT_OFF)
freqHz = int(freqHz) + 35 # offset per chip (you may have to calibrate)
rfmModule.setFreqeuncy(freqHz)
rfmModule.writeReg(REG_PACKETCONFIG1, RF_PACKET1_FORMAT_FIXED | RF_PACKET1_DCFREE_OFF | RF_PACKET1_CRC_OFF | RF_PACKET1_CRCAUTOCLEAR_ON | RF_PACKET1_ADRSFILTERING_OFF)
rfmModule.writeReg(REG_PAYLOADLENGTH, 0x00)
rfmModule.writeReg(REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFONOTEMPTY | RF_FIFOTHRESH_VALUE)
rfmModule.writeReg(REG_PREAMBLELSB, 0x00)
rfmModule.writeReg(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN)
rfmModule.rcCalibration()
print "setting high power"
rfmModule.setHighPower(True)
print "Checking temperature"
print rfmModule.readTemperature(0)
# print "setting encryption"
# rfmModule.encrypt("1234567891011121")
print "sending blah to 2"
rfmModule.setMode(RF69_MODE_SYNTH)
#wait for modeReady
time.sleep(10)
while (rfmModule.readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00:
pass
import uuid
def my_random_string(string_length=10):
"""Returns a random string of length string_length."""
random = str(uuid.uuid4())+str(uuid.uuid4())+str(uuid.uuid4())+str(uuid.uuid4())+str(uuid.uuid4())+str(uuid.uuid4())+str(uuid.uuid4())+str(uuid.uuid4()) # Convert UUID format to a Python string.
@ -67,23 +32,16 @@ def my_random_string(string_length=10):
random = random.replace("-","") # Remove the UUID '-'.
return random[0:string_length] # Return the random string.
from pocsag import encodeTXBatch
msgs = []
#msgs.append([True, "133709", "1234567890U[]-"])
"""
msgs.append([False, "133722", 'Zeile 1\nZeile 2\nZeile 3\nZeile 4'])
msgs.append([False, "133742", '1234567890^12w3e4rt5zu<yxcvf1qwerdftgzhj123we4rwt5dezghqwertwe6456e5n6er6n45w6n456n45'])
msgs.append([True, "133782", "1234567890U-()"])
"""
for i in range(1):
msgs.append([False, "133702", my_random_string(80)])
msgs.append([False, "133702", my_random_string(80)])
data = encodeTXBatch(msgs)
rfmModule.sendBuffer(data)
rfmModule.shutdown()
time.sleep(2000)
#rfmModule.shutdown()
Loading…
Cancel
Save