def PullData(): print("pull data") spi = SPI(1, 0) spi.msh = 100000 spi.bpw = 8 spi.writebytes([0x30]) sleep(0.1) moistureVals = spi.readbytes(3) moisture = str(moistureVals[0]) + str(moistureVals[1]) + str(moistureVals[2]) spi.writebytes([0x31]) sleep(0.1) moistureVals1 = spi.readbytes(3) moisture1 = str(moistureVals1[0]) + str(moistureVals1[1]) + str(moistureVals1[2]) spi.writebytes([0x35]) sleep(0.1) lightVals = spi.readbytes(3) light = str(lightVals[0]) + str(lightVals[1]) + str(lightVals[2]) Data = [] Data.append(moisture) Data.append(moisture1) Data.append(light) spi.close() return Data
class PT100(Sensor): def __init__(self): self.val = None self.tempList = [] self.spi = SPI(0, 0) self.spi.msh = 1000000 GPIO.setup(CS_PIN, GPIO.OUT) GPIO.output(CS_PIN, GPIO.HIGH) self.inter = Interpolate(x, y) def spi_read(self): GPIO.output(CS_PIN, GPIO.LOW) self.spi.xfer([REG_CONF, CNF_ONESHOT]) GPIO.output(CS_PIN, GPIO.HIGH) time.sleep(0.1) GPIO.output(CS_PIN, GPIO.LOW) self.spi.xfer([REG_LSB]) lsb = self.spi.readbytes(1) GPIO.output(CS_PIN, GPIO.HIGH) GPIO.output(CS_PIN, GPIO.LOW) self.spi.xfer([REG_MSB]) msb = self.spi.readbytes(1) GPIO.output(CS_PIN, GPIO.HIGH) err = (False, True)[lsb[0] & 1] adc = (msb[0] << 8 | lsb[0]) >> 1 return (err, adc) def update(self): value = 0 err = False for i in range(10): err, adc = self.spi_read() if err: break value = value + adc if err: #self.val=None return value = value / 10. res = (value / 2**15 * 400) self.tempList.append(self.inter(res)) if len(self.tempList) > 5: del self.tempList[0] tSum = 0 for t in self.tempList: tSum = tSum + t self.val = tSum / len(self.tempList)
def getMoist_ch1(): #print("Reading Moisture CH 1") spi = SPI(1, 0) spi.msh = 100000 spi.bpw = 8 spi.writebytes([0x31]) sleep(0.01) moistureVals = spi.readbytes(3) moisture = str(moistureVals[0]) + str(moistureVals[1]) + str(moistureVals[2]) spi.close() return moisture
def getLight(): #print("Reading Light Data") spi = SPI(1, 0) spi.msh = 100000 spi.bpw = 8 spi.writebytes([0x35]) sleep(0.01) lightVals = spi.readbytes(3) light = str(lightVals[0]) + str(lightVals[1]) + str(lightVals[2]) spi.close() return light
def Watering(): print("watering") spi = SPI(1, 0) spi.msh = 100000 spi.bpw = 8 list = [] i=0 while i<50: spi.writebytes([0x31]) sleep(0.1) list.append(spi.readbytes(3)) print(list.pop()) ++i sleep(0.5) spi.close()
def startWatering(): print("Started watering...") session['watering_command_status'] = "ON" # send the signal to arduino to start watering spi = SPI(1, 0) spi.msh = 100000 spi.bpw = 8 # send the appropriate signal spi.writebytes([0x36]) # '6' print(spi.readbytes(1)) spi.close() return flask.redirect("/")
def stopWatering(): print("Stopping watering") session['watering_command_status'] = "OFF" # send the signal to arduino to stop watering spi = SPI(1, 0) spi.msh = 100000 spi.bpw = 8 # send the appropriate signal spi.writebytes([0x37]) # '7' print(spi.readbytes(1)) spi.close() return flask.redirect("/")
class ltc1858: def __init__(self, spi_bus = 0, spi_client = 0, spi_freq = 1000000, spi_mode = 0b00, RD = "P9_12"): #define pins self.logger = logging.getLogger('LTC1858') self.logger.setLevel(logging.WARNING) self.spi_bus = spi_bus self.spi_client = spi_client self.spi_freq = spi_freq #1Mhz is plenty self.spi_mode = spi_mode """We actually send 16 bits but the SPI protocol is a bit screwy It's just easier currently to send two 8 bit words as protocol is broken""" self.spi_bits_per_word = 8 self.spi_cshigh = False #Need the RD set to low to get data - Could do something #more fancy with this later self.RD = RD self.data_in = BitArray(14) self.vrange = {"+-5V" : 0b00, "+5V" : 0b10, "+-10V" : 0b01, "+10V" : 0b11} #Create a chan dict as not standard binary self.chans = {0 : 0b000, 1 : 0b100, 2 : 0b001, 3 : 0b101, 4 : 0b010, 5 : 0b110, 6 : 0b011, 7 : 0b111} self.adc_reg = {"Monitor" : False, "Range" : "+5V", "V" : 0, "Command" : 0} #Bitstring is terribly slow so for a register #read we use a preconstructed bitstring rather #Than create every time self.chip_reg = [] for i in xrange(8): self.chip_reg.append(self.adc_reg.copy()) self.single_ended = 0b1 self.setup_chip() self.setup_spi() def setup_spi(self): #This is for BB Black self.spi = SPI(self.spi_bus, self.spi_client) self.spi.msh = self.spi_freq self.spi.mode = self.spi_mode self.bpw = self.spi_bits_per_word self.spi.cshigh = self.spi_cshigh def setup_chip(self): #Just need to setup RD and make sure it is low GPIO.setup(self.RD, GPIO.OUT) GPIO.output(self.RD, False) def set_reg(self,adc,monitor,adc_range): self.chip_reg[adc]["Monitor"] = monitor self.chip_reg[adc]["Range"] = adc_range self.chip_reg[adc]["Command"] = self.construct_word(adc,adc_range) def construct_word(self, chan_no, vrange): t_word = BitArray(8) t_word[0] = self.single_ended t_word[1:4] = self.chans[chan_no] t_word[4:6] = self.vrange[vrange] #Ignore nap and sleep return t_word def single_read(self, chan_no, v_range): #Need to set command and then read back so #two words - Just send the same word twice #self.send_data(self.construct_word(chan_no, v_range)) data_out = self.send_data(self.construct_word(chan_no, v_range)) data_conv = self.convert_to_v(data_out, v_range) return data_conv def register_read(self): #This does one pass at reading all dac inputs for i in xrange(8): if self.chip_reg[i]["Monitor"] is True: data_out = self.send_data(self.chip_reg[i]["Command"]) vv = self.convert_to_v(data_out, self.chip_reg[i]["Range"]) self.chip_reg[i]["V"] = vv def send_data(self,data): self.spi.writebytes([data.uint,0x00]) #Send data then zeros as per DS #at 1MHz we don't care if it's duplex read a,b = self.spi.readbytes(2) self.data_in[0:8] = a self.data_in[8:] = (b >> 2) return self.data_in def convert_to_v(self,num, v_range): if v_range == "+5V": return 5.0*num.uint/2**14 elif v_range == "+10V": return 10.0*num.uint/2**14 elif v_range == "+-5V": return num.int*5.0/2**13 elif v_range == "+-10V": return num.int*10.0/2**13 else: return -69
class RFM69(BaseRadio): DATA = [] DATALEN = 0 SENDERID = 0 TARGETID = 0 PAYLOADLEN = 0 ACK_REQUESTED = False ACK_RECEIVED = False RSSI = 0 _mode = 0 _interruptPin = DIO0_PIN _csPin = NSS_PIN _address = 0 _promiscuousMode = False _powerLevel = 31 _isRFM69HW = True def __init__(self, isRFM69HW=True, interruptPin=DIO0_PIN, csPin=NSS_PIN): self._isRFM69HW = isRFM69HW self._interruptPin = interruptPin self._csPin = csPin self.SPI = SPI(SPI_BUS, SPI_CS) self.SPI.bpw = 8 self.SPI.mode = 0 self.SPI.msh = SPI_CLK_SPEED self.SPI.lsbfirst = False GPIO.setup(self._interruptPin, GPIO.IN) self.lastIrqLevel = GPIO.input(self._interruptPin) GPIO.setup(self._csPin, GPIO.OUT) GPIO.output(self._csPin, GPIO.HIGH) self.start_time = datetime.datetime.now() # Convention I want to stick to is a single underscore to indicate "private" methods. # I'm grouping all the private stuff up at the beginning. def _millis(self): delta = datetime.datetime.now() - self.start_time return delta.total_seconds() * 1000 def _readReg(self, addr): self._select() self.SPI.writebytes([addr & 0x7F]) result = self.SPI.readbytes(1)[0] self._unselect() return result def _writeReg(self, addr, value): self._select() self.SPI.writebytes([addr | 0x80, value]) self._unselect() # Select the transceiver def _select(self): GPIO.output(self._csPin, GPIO.LOW) # Unselect the transceiver chip def _unselect(self): GPIO.output(self._csPin, GPIO.HIGH) def _setMode(self, newMode): if newMode == RF69_MODE_TX: self._writeReg(REG_OPMODE, (self._readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_TRANSMITTER) if self._isRFM69HW: self.setHighPowerRegs(True) elif newMode == RF69_MODE_RX: self._writeReg(REG_OPMODE, (self._readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER) if self._isRFM69HW: self.setHighPowerRegs(False) elif newMode == RF69_MODE_SYNTH: self._writeReg(REG_OPMODE, (self._readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_SYNTHESIZER) elif newMode == RF69_MODE_STANDBY: self._writeReg(REG_OPMODE, (self._readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_STANDBY) elif newMode == RF69_MODE_SLEEP: self._writeReg(REG_OPMODE, (self._readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_SLEEP) # we are using packet mode, so this check is not really needed # but waiting for mode ready is necessary when going from sleep because the FIFO may not # be immediately available from previous mode while (self._mode == RF69_MODE_SLEEP and (self._readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00): # Wait for ModeReady pass self._mode = newMode def _canSend(self): #if signal stronger than -100dBm is detected assume channel activity if (self._mode == RF69_MODE_RX and self.PAYLOADLEN == 0 and self.readRSSI() < CSMA_LIMIT): self._setMode(RF69_MODE_STANDBY) return True return False def _sendFrame(self, toAddress, buffer, bufferSize, requestACK=False, sendACK=False): self._setMode(RF69_MODE_STANDBY) #turn off receiver to prevent reception while filling fifo while ((self._readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00): pass # Wait for ModeReady self._writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00) # DIO0 is "Packet Sent" if bufferSize > RF69_MAX_DATA_LEN: bufferSize = RF69_MAX_DATA_LEN #write to FIFO self._select() self.SPI.writebytes([REG_FIFO | 0x80, bufferSize + 3, toAddress, self._address]) #control byte if (sendACK): self.SPI.writebytes([0x80]) elif (requestACK): self.SPI.writebytes([0x40]) else: self.SPI.writebytes([0x00]) bufferBytes = [] for i in range(0, bufferSize): self.SPI.writebytes([ord(buffer[i])]) self._unselect() # no need to wait for transmit mode to be ready since its handled by the radio self._setMode(RF69_MODE_TX) txStart = self._millis() # wait for DIO0 to turn HIGH signalling transmission finish while (GPIO.input(self._interruptPin) == 0 and self._millis()-txStart < RF69_TX_LIMIT_MS): pass self._setMode(RF69_MODE_STANDBY) def _interruptHandler(self): if (self._mode == RF69_MODE_RX and (self._readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PAYLOADREADY)): self._setMode(RF69_MODE_STANDBY) self._select() self.SPI.writebytes([REG_FIFO & 0x7f]) self.PAYLOADLEN = self.SPI.readbytes(1)[0] self.PAYLOADLEN = 66 if self.PAYLOADLEN > 66 else self.PAYLOADLEN self.TARGETID = self.SPI.readbytes(1)[0] # match this node's address, or broadcast address or anything in promiscuous mode # address situation could receive packets that are malformed and don't fit this libraries extra fields if(not(self._promiscuousMode or self.TARGETID==self._address or self.TARGETID==RF69_BROADCAST_ADDR) or self.PAYLOADLEN < 3): self.PAYLOADLEN = 0 self._unselect() self._receiveBegin() return self.DATALEN = self.PAYLOADLEN - 3 self.SENDERID = self.SPI.readbytes(1)[0] CTLbyte = self.SPI.readbytes(1)[0] self.ACK_RECEIVED = CTLbyte & 0x80 #extract ACK-requested flag self.ACK_REQUESTED = CTLbyte & 0x40 #extract ACK-received flag self.DATA = self.SPI.readbytes(self.DATALEN) self._unselect() self._setMode(RF69_MODE_RX) self.RSSI = self.readRSSI() def _noInterrupts(self): pass def _interrupts(self): pass def _receiveBegin(self): 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 initialize(self, freqBand, nodeId, networkID): self._address = nodeId config = [ [ REG_OPMODE, RF_OPMODE_SEQUENCER_ON | RF_OPMODE_LISTEN_OFF | RF_OPMODE_STANDBY ], [ REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONTYPE_FSK | RF_DATAMODUL_MODULATIONSHAPING_00 ], #no shaping [ REG_BITRATEMSB, RF_BITRATEMSB_55555], #default:4.8 KBPS [ REG_BITRATELSB, RF_BITRATELSB_55555], [ REG_FDEVMSB, RF_FDEVMSB_50000], #default:5khz, (FDEV + BitRate/2 <= 500Khz) [ REG_FDEVLSB, RF_FDEVLSB_50000], [ REG_FRFMSB, RF_FRFMSB_315 if freqBand == RF69_315MHZ else (RF_FRFMSB_433 if freqBand == RF69_433MHZ else (RF_FRFMSB_868 if freqBand == RF69_868MHZ else RF_FRFMSB_915)) ], [ REG_FRFMID, RF_FRFMID_315 if freqBand == RF69_315MHZ else (RF_FRFMID_433 if freqBand == RF69_433MHZ else (RF_FRFMID_868 if freqBand == RF69_868MHZ else RF_FRFMID_915)) ], [ REG_FRFLSB, RF_FRFLSB_315 if freqBand == RF69_315MHZ else (RF_FRFLSB_433 if freqBand == RF69_433MHZ else (RF_FRFLSB_868 if freqBand == RF69_868MHZ else RF_FRFLSB_915)) ], # 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) #[ REG_PALEVEL, RF_PALEVEL_PA0_ON | RF_PALEVEL_PA1_OFF | RF_PALEVEL_PA2_OFF | RF_PALEVEL_OUTPUTPOWER_11111], #[ REG_OCP, RF_OCP_ON | RF_OCP_TRIM_95 ], #over current protection (default is 95mA) # RXBW defaults are [ REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_24 | RF_RXBW_EXP_5] (RxBw: 10.4khz) [ REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_16 | RF_RXBW_EXP_2 ], #(BitRate < 2 * RxBw) # for BR-19200: #* 0x19 */ [ REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_24 | RF_RXBW_EXP_3 ], [ REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01 ], #DIO0 is the only IRQ we're using [ REG_RSSITHRESH, 220 ], #must be set to dBm = (-Sensitivity / 2) - default is 0xE4=228 so -114dBm #[ REG_PREAMBLELSB, RF_PREAMBLESIZE_LSB_VALUE ] # default 3 preamble bytes 0xAAAAAA [ REG_SYNCCONFIG, RF_SYNC_ON | RF_SYNC_FIFOFILL_AUTO | RF_SYNC_SIZE_2 | RF_SYNC_TOL_0 ], [ REG_SYNCVALUE1, 0x2D ], #attempt to make this compatible with sync1 byte of RFM12B lib [ REG_SYNCVALUE2, networkID ], #NETWORK ID [ REG_PACKETCONFIG1, RF_PACKET1_FORMAT_VARIABLE | RF_PACKET1_DCFREE_OFF | RF_PACKET1_CRC_ON | RF_PACKET1_CRCAUTOCLEAR_ON | RF_PACKET1_ADRSFILTERING_OFF ], [ REG_PAYLOADLENGTH, 66 ], #in variable length mode: the max frame size, not used in TX #[ REG_NODEADRS, nodeID ], #turned off because we're not using address filtering [ REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFONOTEMPTY | RF_FIFOTHRESH_VALUE ], #TX on FIFO not empty [ REG_PACKETCONFIG2, RF_PACKET2_RXRESTARTDELAY_2BITS | RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AES_OFF ], #RXRESTARTDELAY must match transmitter PA ramp-down time (bitrate dependent) # 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) #[ REG_TESTDAGC, RF_DAGC_CONTINUOUS ], # run DAGC continuously in RX mode [ REG_TESTDAGC, RF_DAGC_IMPROVED_LOWBETA0 ], # run DAGC continuously in RX mode, recommended default for AfcLowBetaOn=0 [255, 0] ] while self._readReg(REG_SYNCVALUE1) != 0xaa: self._writeReg(REG_SYNCVALUE1, 0xaa) while self._readReg(REG_SYNCVALUE1) != 0x55: self._writeReg(REG_SYNCVALUE1, 0x55) for chunk in config: self._writeReg(chunk[0], chunk[1]) self.setEncryptionKey(None) self.setHighPower(self._isRFM69HW) self._setMode(RF69_MODE_STANDBY) # wait for mode ready while (self._readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00: pass self._interrupts() 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._writeReg(REG_SYNCVALUE2, networkID) # set output power: 0=min, 31=max # this results in a "weaker" transmitted signal, and directly results in a lower RSSI at the receiver def setPowerLevel(self, powerLevel): self._powerLevel = powerLevel self._writeReg(REG_PALEVEL, (_readReg(REG_PALEVEL) & 0xE0) | (self._powerLevel if self._powerLevel < 31 else 31)) def send(self, toAddress, buffer, bufferSize, requestACK): self._writeReg(REG_PACKETCONFIG2, (self._readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART) # avoid RX deadlocks now = self._millis() while (not self._canSend() and self._millis()-now < RF69_CSMA_LIMIT_MS): self.receiveDone() self._sendFrame(toAddress, buffer, bufferSize, 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, buffer, bufferSize, retries=2, retryWaitTime=40): for i in range(0, retries): self.send(toAddress, buffer, bufferSize, True) sentTime = self._millis() while self._millis()-sentTime<retryWaitTime: if self.ACKReceived(toAddress): return True return False # Should be polled immediately after sending a packet with ACK request def ACKReceived(self, fromNodeID): if self.receiveDone(): return (self.SENDERID == fromNodeID or fromNodeID == RF69_BROADCAST_ADDR) and self.ACK_RECEIVED return False #check whether an ACK was requested in the last received packet (non-broadcasted packet) def ACKRequested(self): return self.ACK_REQUESTED and (self.TARGETID != RF69_BROADCAST_ADDR) # Should be called immediately after reception in case sender wants ACK def sendACK(self, buffer="", bufferSize=0): sender = self.SENDERID _RSSI = self.RSSI #save payload received RSSI value self._writeReg(REG_PACKETCONFIG2, (self._readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART) # avoid RX deadlocks now = self._millis() while (not self._canSend() and self._millis()-now < RF69_CSMA_LIMIT_MS): self.receiveDone() self._sendFrame(sender, buffer, bufferSize, False, True) self.RSSI = _RSSI #restore payload RSSI def receiveDone(self): self._noInterrupts() #re-enabled in _unselect() via _setMode() or via _receiveBegin() if GPIO.input(self._interruptPin): self._interruptHandler() if (self._mode == RF69_MODE_RX and self.PAYLOADLEN > 0): self._setMode(RF69_MODE_STANDBY) #enables interrupts return True elif (self._mode == RF69_MODE_RX): #already in RX no payload yet self._interrupts() #explicitly re-enable interrupts return False self._receiveBegin() return False # To enable encryption: radio.encrypt("ABCDEFGHIJKLMNOP") # To disable encryption: radio.encrypt(null) # KEY HAS TO BE 16 bytes !!! def setEncryptionKey(self, key): if key is not None: if len(key) != 16: raise Exception("Key must be exactly 16 bytes!") self._setMode(RF69_MODE_STANDBY) if (key is not None): keyBytes = [] self._select() self.SPI.writebytes([REG_AESKEY1 | 0x80]) for i in range(0,16): keyBytes.append(ord(key[i])) self.SPI.writebytes(keyBytes) self._unselect() self._writeReg(REG_PACKETCONFIG2, (self._readReg(REG_PACKETCONFIG2) & 0xFE) | (0 if key is None else 1)) # The following methods are not required by BaseRadio. # They depend too heavily on the specific radio hardware and would not get any benefit from being part of the # BaseRadio class. def getRSSI(self, forceTrigger=False): rssi = 0 if (forceTrigger): # RSSI trigger not needed if DAGC is in continuous mode self._writeReg(REG_RSSICONFIG, RF_RSSI_START) while ((self._readReg(REG_RSSICONFIG) & RF_RSSI_DONE) == 0x00): pass # Wait for RSSI_Ready rssi = -self._readReg(REG_RSSIVALUE) rssi >>= 1 return rssi # ON = disable filtering to capture all frames on network # OFF = enable node+broadcast filtering to capture only frames sent to this/broadcast address def setPromiscuous(self, onOff): self._promiscuousMode = onOff def setHighPower(self, onOff): self._isRFM69HW = onOff self._writeReg(REG_OCP, RF_OCP_OFF if self._isRFM69HW else RF_OCP_ON) if (self._isRFM69HW): # enable P1 & P2 amplifier stages self._writeReg(REG_PALEVEL, (self._readReg(REG_PALEVEL) & 0x1F) | RF_PALEVEL_PA1_ON | RF_PALEVEL_PA2_ON) else: # enable P0 only self._writeReg(REG_PALEVEL, RF_PALEVEL_PA0_ON | RF_PALEVEL_PA1_OFF | RF_PALEVEL_PA2_OFF | self.powerLevel) def setHighPowerRegs(self, onOff): self._writeReg(REG_TESTPA1, 0x5D if onOff else 0x55) self._writeReg(REG_TESTPA2, 0x7C if onOff else 0x70) def readAllRegs(self): print "Register, Address, Value" print "REG_FIFO, 0x00, {}".format(hex(self._readReg(REG_FIFO))) print "REG_OPMODE, 0x01, {}".format(hex(self._readReg(REG_OPMODE))) print "REG_DATAMODUL, 0x02, {}".format(hex(self._readReg(REG_DATAMODUL))) print "REG_BITRATEMSB, 0x03, {}".format(hex(self._readReg(REG_BITRATEMSB))) print "REG_BITRATELSB, 0x04, {}".format(hex(self._readReg(REG_BITRATELSB))) print "REG_FDEVMSB, 0x05, {}".format(hex(self._readReg(REG_FDEVMSB))) print "REG_FDEVLSB, 0x06, {}".format(hex(self._readReg(REG_FDEVLSB))) print "REG_FRFMSB, 0x07, {}".format(hex(self._readReg(REG_FRFMSB))) print "REG_FRFMID, 0x08, {}".format(hex(self._readReg(REG_FRFMID))) print "REG_FRFLSB, 0x09, {}".format(hex(self._readReg(REG_FRFLSB))) print "REG_OSC1, 0x0A, {}".format(hex(self._readReg(REG_OSC1))) print "REG_AFCCTRL, 0x0B, {}".format(hex(self._readReg(REG_AFCCTRL))) print "REG_LOWBAT, 0x0C, {}".format(hex(self._readReg(REG_LOWBAT))) print "REG_LISTEN1, 0x0D, {}".format(hex(self._readReg(REG_LISTEN1))) print "REG_LISTEN2, 0x0E, {}".format(hex(self._readReg(REG_LISTEN2))) print "REG_LISTEN3, 0x0F, {}".format(hex(self._readReg(REG_LISTEN3))) print "REG_VERSION, 0x10, {}".format(hex(self._readReg(REG_VERSION))) print "REG_PALEVEL, 0x11, {}".format(hex(self._readReg(REG_PALEVEL))) print "REG_PARAMP, 0x12, {}".format(hex(self._readReg(REG_PARAMP))) print "REG_OCP, 0x13, {}".format(hex(self._readReg(REG_OCP))) print "REG_AGCREF, 0x14, {}".format(hex(self._readReg(REG_AGCREF))) print "REG_AGCTHRESH1, 0x15, {}".format(hex(self._readReg(REG_AGCTHRESH1))) print "REG_AGCTHRESH2, 0x16, {}".format(hex(self._readReg(REG_AGCTHRESH2))) print "REG_AGCTHRESH3, 0x17, {}".format(hex(self._readReg(REG_AGCTHRESH3))) print "REG_LNA, 0x18, {}".format(hex(self._readReg(REG_LNA))) print "REG_RXBW, 0x19, {}".format(hex(self._readReg(REG_RXBW))) print "REG_AFCBW, 0x1A, {}".format(hex(self._readReg(REG_AFCBW))) print "REG_OOKPEAK, 0x1B, {}".format(hex(self._readReg(REG_OOKPEAK))) print "REG_OOKAVG, 0x1C, {}".format(hex(self._readReg(REG_OOKAVG))) print "REG_OOKFIX, 0x1D, {}".format(hex(self._readReg(REG_OOKFIX))) print "REG_AFCFEI, 0x1E, {}".format(hex(self._readReg(REG_AFCFEI))) print "REG_AFCMSB, 0x1F, {}".format(hex(self._readReg(REG_AFCMSB))) print "REG_AFCLSB, 0x20, {}".format(hex(self._readReg(REG_AFCLSB))) print "REG_FEIMSB, 0x21, {}".format(hex(self._readReg(REG_FEIMSB))) print "REG_FEILSB, 0x22, {}".format(hex(self._readReg(REG_FEILSB))) print "REG_RSSICONFIG, 0x23, {}".format(hex(self._readReg(REG_RSSICONFIG))) print "REG_RSSIVALUE, 0x24, {}".format(hex(self._readReg(REG_RSSIVALUE))) print "REG_DIOMAPPING1, 0x25, {}".format(hex(self._readReg(REG_DIOMAPPING1))) print "REG_DIOMAPPING2, 0x26, {}".format(hex(self._readReg(REG_DIOMAPPING2))) print "REG_IRQFLAGS1, 0x27, {}".format(hex(self._readReg(REG_IRQFLAGS1))) print "REG_IRQFLAGS2, 0x28, {}".format(hex(self._readReg(REG_IRQFLAGS2))) print "REG_RSSITHRESH, 0x29, {}".format(hex(self._readReg(REG_RSSITHRESH))) print "REG_RXTIMEOUT1, 0x2A, {}".format(hex(self._readReg(REG_RXTIMEOUT1))) print "REG_RXTIMEOUT2, 0x2B, {}".format(hex(self._readReg(REG_RXTIMEOUT2))) print "REG_PREAMBLEMSB, 0x2C, {}".format(hex(self._readReg(REG_PREAMBLEMSB))) print "REG_PREAMBLELSB, 0x2D, {}".format(hex(self._readReg(REG_PREAMBLELSB))) print "REG_SYNCCONFIG, 0x2E, {}".format(hex(self._readReg(REG_SYNCCONFIG))) print "REG_SYNCVALUE1, 0x2F, {}".format(hex(self._readReg(REG_SYNCVALUE1))) print "REG_SYNCVALUE2, 0x30, {}".format(hex(self._readReg(REG_SYNCVALUE2))) print "REG_SYNCVALUE3, 0x31, {}".format(hex(self._readReg(REG_SYNCVALUE3))) print "REG_SYNCVALUE4, 0x32, {}".format(hex(self._readReg(REG_SYNCVALUE4))) print "REG_SYNCVALUE5, 0x33, {}".format(hex(self._readReg(REG_SYNCVALUE5))) print "REG_SYNCVALUE6, 0x34, {}".format(hex(self._readReg(REG_SYNCVALUE6))) print "REG_SYNCVALUE7, 0x35, {}".format(hex(self._readReg(REG_SYNCVALUE7))) print "REG_SYNCVALUE8, 0x36, {}".format(hex(self._readReg(REG_SYNCVALUE8))) print "REG_PACKETCONFIG1, 0x37, {}".format(hex(self._readReg(REG_PACKETCONFIG1))) print "REG_PAYLOADLENGTH, 0x38, {}".format(hex(self._readReg(REG_PAYLOADLENGTH))) print "REG_NODEADRS, 0x39, {}".format(hex(self._readReg(REG_NODEADRS))) print "REG_BROADCASTADRS, 0x3A, {}".format(hex(self._readReg(REG_BROADCASTADRS))) print "REG_AUTOMODES, 0x3B, {}".format(hex(self._readReg(REG_AUTOMODES))) print "REG_FIFOTHRESH, 0x3C, {}".format(hex(self._readReg(REG_FIFOTHRESH))) print "REG_PACKETCONFIG2, 0x3D, {}".format(hex(self._readReg(REG_PACKETCONFIG2))) print "REG_AESKEY1, 0x3E, {}".format(hex(self._readReg(REG_AESKEY1))) print "REG_AESKEY2, 0x3F, {}".format(hex(self._readReg(REG_AESKEY2))) print "REG_AESKEY3, 0x40, {}".format(hex(self._readReg(REG_AESKEY3))) print "REG_AESKEY4, 0x41, {}".format(hex(self._readReg(REG_AESKEY4))) print "REG_AESKEY5, 0x42, {}".format(hex(self._readReg(REG_AESKEY5))) print "REG_AESKEY6, 0x43, {}".format(hex(self._readReg(REG_AESKEY6))) print "REG_AESKEY7, 0x44, {}".format(hex(self._readReg(REG_AESKEY7))) print "REG_AESKEY8, 0x45, {}".format(hex(self._readReg(REG_AESKEY8))) print "REG_AESKEY9, 0x46, {}".format(hex(self._readReg(REG_AESKEY9))) print "REG_AESKEY10, 0x47, {}".format(hex(self._readReg(REG_AESKEY10))) print "REG_AESKEY11, 0x48, {}".format(hex(self._readReg(REG_AESKEY11))) print "REG_AESKEY12, 0x49, {}".format(hex(self._readReg(REG_AESKEY12))) print "REG_AESKEY13, 0x4A, {}".format(hex(self._readReg(REG_AESKEY13))) print "REG_AESKEY14, 0x4B, {}".format(hex(self._readReg(REG_AESKEY14))) print "REG_AESKEY15, 0x4C, {}".format(hex(self._readReg(REG_AESKEY15))) print "REG_AESKEY16, 0x4D, {}".format(hex(self._readReg(REG_AESKEY16))) print "REG_TEMP1, 0x4E, {}".format(hex(self._readReg(REG_TEMP1))) print "REG_TEMP2, 0x4F, {}".format(hex(self._readReg(REG_TEMP2))) if self._isRFM69HW: print "REG_TESTPA1, 0x5A, {}".format(hex(self._readReg(REG_TESTPA1))) print "REG_TESTPA2, 0x5C, {}".format(hex(self._readReg(REG_TESTPA2))) print "REG_TESTDAGC, 0x6F, {}".format(hex(self._readReg(REG_TESTDAGC))) # returns centigrade def readTemperature(self, calFactor): self._setMode(RF69_MODE_STANDBY) self._writeReg(REG_TEMP1, RF_TEMP1_MEAS_START) while ((self._readReg(REG_TEMP1) & RF_TEMP1_MEAS_RUNNING)): pass #'complement'corrects the slope, rising temp = rising val # COURSE_TEMP_COEF puts reading in the ballpark, user can add additional correction return ~self._readReg(REG_TEMP2) + COURSE_TEMP_COEF + calFactor def rcCalibration(self): _writeReg(REG_OSC1, RF_OSC1_RCCAL_START) while ((_readReg(REG_OSC1) & RF_OSC1_RCCAL_DONE) == 0x00): pass
GPIO.output("P9_12", GPIO.HIGH) # initialize bt module k = 0 while k < 100: #print("Sending init message") bt.xfer2([ 0x00, 0xFE, 0x2A, 0x01, 0x00, 0xFE, 0x26, 0x02, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFA ]) i = 0 while i < 30: if GPIO.input("P9_15") != 1: value = bt.readbytes(12) if value[1] == 0xFE and value[6] == 0 and value[7] == 6: #print("Init Success") #print(value) i = 50 k = 100 time.sleep(0.001) i = i + 1 k = k + 1 k = 0 while k < 100: #print("Setting Scan Time") bt.xfer2( [0x00, 0xFE, 0x07, 0x01, 0x30, 0xFE, 0x03, 0x02, 0xFE, 0xFF, 0xC8]) i = 0 while i < 35:
spi = SPI(0, 0) spi.msh=1000000 GPIO.setup(CS_PIN,GPIO.OUT) GPIO.output(CS_PIN,GPIO.HIGH) inter=Interpolate(x,y) while True: GPIO.output(CS_PIN,GPIO.LOW) spi.xfer([REG_CONF,CNF_ONESHOT]) GPIO.output(CS_PIN,GPIO.HIGH) time.sleep(0.1) GPIO.output(CS_PIN,GPIO.LOW) spi.xfer([0x02]) lsb=spi.readbytes(1) GPIO.output(CS_PIN,GPIO.HIGH) GPIO.output(CS_PIN,GPIO.LOW) spi.xfer([0x01]) msb=spi.readbytes(1) GPIO.output(CS_PIN,GPIO.HIGH) GPIO.output(CS_PIN,GPIO.LOW) spi.xfer([0x07]) flt=spi.readbytes(1) GPIO.output(CS_PIN,GPIO.HIGH) adc=(msb[0]<<8|lsb[0])>>1 res=(adc/2**15*400) time.sleep(0.1)
def send_cmd(cmd,data): ser_cmd = (cmd << 10) | (data & ((1<<10)-1)) w0 = ser_cmd >> 8 w1 = ser_cmd & ((1<<8)-1) return [w0, w1] # write to RDAC spi.xfer(list(struct.unpack('BB', struct.pack('>H', 1 << 10 | 0)))) # read RDAC spi.xfer(list(struct.unpack('BB', struct.pack('>H', 0b10 << 10 | 0)))) # read Control register spi.xfer(list(struct.unpack('BB', struct.pack('>H', 0b111 << 10 | 0)))) spi.readbytes(2) for i in range(1024): spi.xfer(list(struct.unpack('BB', struct.pack('>H', 1 << 10 | i)))) time.sleep(.2) spi.writebytes([0x0,0x0]) spi.writebytes([0x18,0x02]) spi.writebytes([0x05,0x00]) spi.writebytes([0x08,0x0]) spi.writebytes([0x0,0x0]) spi.writebytes([0x0,0x0]) spi.writebytes([0x0,0x0]) spi.xfer([0x0,0x0])
spi.msh = 500000 #Frequency spi.bpw = 8 #bits per word spi.cshigh = True #true means you select the chip, depends on the chip, here low means active, normally Low for IMU spi.threewire = False #if it is true, you just read, otherwise you also send commands spi.lsbfirst = False #Least significant bit first (left) #spi.mode=3 spi.open(0, 0) #open #GPIO.setup("P8_11",GPIO.OUT) #GPIO.output("P8_11",GPIO.HIGH) try: while True: res = spi.xfer2([0xFFFF, 0xFFFF]) #deliver two bytes #spi.cshigh=False res1 = spi.readbytes(10) angle = (res1[0] << 8) | res1[1] #merge leftbyte and rightbyte angle1 = angle & 0x3FFF #move the first two bits angle2 = float(angle1) / 16363 * 360 #print("res is", str(res)) print("res1 is", str(res1)) print("angle is", str(angle)) print("angle2 is", str(angle2)) time.sleep(.25) #spi.cshigh=True except KeyboardInterrupt: spi.close()
from Adafruit_BBIO.SPI import SPI spi = SPI(1,0) spi.mode=2 spi.msh=200000 spi.open(1,0) print spi.readbytes(4) #print spi.xfer2([32, 11, 110, 22, 220]) spi.close()
class BStabBb: def __init__(self, coarsePin="P9_15", finePin="P9_16", readPin="P9_14", clockRate=100000): self.CS_FB_COARSE_PIN = coarsePin self.CS_FB_FINE_PIN = finePin self.CS_ADC_PIN = readPin self.FB_CLK_RATE = clockRate GPIO.setup(self.CS_FB_COARSE_PIN, GPIO.OUT) GPIO.setup(self.CS_FB_FINE_PIN, GPIO.OUT) GPIO.setup(self.CS_ADC_PIN, GPIO.OUT) self.spi00 = SPI(0,0) self.spi00.msh = self.FB_CLK_RATE self.fname = "dacValues.pyon" self.maxDACvalue = (1<<16)-1 # Ca43 self.kHz_per_mG = -2.45 # measured self.mG_per_mA = 146 / 56.64 # (sensor+DiffAmp) equivalent : 6.06ohm # Verr: voltage of error signal self.mA_per_mVerr = 1 / 6.06 self.mG_per_mVerr = self.mG_per_mA * self.mA_per_mVerr self.kHz_per_mVerr = self.kHz_per_mG * self.mG_per_mVerr # maximum DAC output: 2.048V self.mVDAC_per_DACvalue = 2.048e3 / self.maxDACvalue # estimates for the slope qubit_freq'(DACvalue) # fine DAC gain 1 # coarse DAC gain 200 self.kHz_per_fDACvalue_est = self.kHz_per_mG * self.mG_per_mVerr * self.mVDAC_per_DACvalue self.kHz_per_cDACvalue_est = self.kHz_per_mG * self.mG_per_mVerr * 200 * self.mVDAC_per_DACvalue def get_max_dac_value(self): return self.maxDACvalue def adjust_b_field(self, freq_diff, corrFactor=1): [cDAC, fDAC] = self.calcNewDACvaluesFromFreqDiff(freq_diff, corrFactor) self.setStabiliserDACs(cDAC, fDAC) def setStabiliserDACs(self, cDacValue, fDacValue, verbose=False): """Update feedback DAC values""" self.set_DAC_values(CDAC=cDacValue,FDAC=fDacValue) dacValues = {'cDAC':cDacValue,'fDAC':fDacValue} pyon.store_file(self.fname, dacValues) #self.set_dataset("BField_stabiliser.cDAC", float(cDacValue), persist=True, broadcast=True) #self.set_dataset("BField_stabiliser.fDAC", float(fDacValue), persist=True, broadcast=True) #if verbose: # print("Update DACs {} {} --- Done.".format(int(cDacValue),int(fDacValue))) return dacValues def checkStabiliserOutput(self, volt_margin=3, verbose=False): """Read feedback shunt voltage via ssh connection""" shunt_ok = False shunt_voltage = self.read_voltage() if shunt_voltage > (10-volt_margin): shunt_ok_msg = "Too high!" elif shunt_voltage < volt_margin: shunt_ok_msg = "Too low!" else: shunt_ok = True shunt_ok_msg = "Fine." if verbose: print("Read ADC --- Shunt input voltage: {} --- {}".format(shunt_voltage, shunt_ok_msg)) # to do: raise Error when railing return shunt_ok def getSlopes(self): """Return conversion factors [cDAC_per_mG,fDAC_per_mG] """ """Use for scanning the magnetic field""" # fine DAC gain 1 # coarse DAC gain 200 mG_per_fDACvalue = self.mG_per_mVerr * self.mVDAC_per_DACvalue mG_per_cDACvalue = self.mG_per_mVerr * 200 * self.mVDAC_per_DACvalue return {'cDAC_per_mG': 1.0/mG_per_cDACvalue, 'fDAC_per_mG': 1.0/mG_per_fDACvalue} def calcNewDACvaluesFromFreqDiff(self, freq_diff, corrFactor=1): """Calculate new DAC values, based on the stretch qubit frequency difference to the setpoint""" # least significant bits in mV output fDAClsb = self.mVDAC_per_DACvalue # VERR = 200*cDAC + fDAC - 202*DIFF_SIG cDAClsb = 200 * fDAClsb VERR_diff = freq_diff / self.kHz_per_mVerr / 1e3 VERR_corr = VERR_diff * corrFactor if abs(VERR_corr) > 10*cDAClsb: change_cDAC = - int(round(VERR_corr / cDAClsb)) change_fDAC = 0 else: change_cDAC = 0 change_fDAC = - int(round(VERR_corr / fDAClsb)) try: oldDacValues = pyon.load_file(self.fname) #old_cDAC = self.get_dataset("BField_stabiliser.cDAC") #old_fDAC = self.get_dataset("BField_stabiliser.fDAC") except FileNotFoundError: print('Error: could not find file. Using default values') oldDacValues = {'cDAC':54710,'fDAC':33354} old_cDAC = oldDacValues['cDAC'] old_fDAC = oldDacValues['fDAC'] new_cDAC = old_cDAC + change_cDAC new_fDAC = old_fDAC + change_fDAC # when fDAC out of range, change coarse DAC if (new_fDAC > self.maxDACvalue or new_fDAC < 0): new_cDAC += (new_fDAC-30000)/200 new_fDAC = 30000 return [new_cDAC, new_fDAC] def set_DAC_values(self,CDAC=-1,FDAC=-1): ''' this is the external function to be called for setting the coarse and fine dac ''' if CDAC is not -1: self._set_coarse_dac(CDAC) if FDAC is not -1: self._set_fine_dac(FDAC) def read_voltage(self,verbose=0): ''' this is the external function to be called for reading out the ADC voltage ''' # for AD7477: # 2 bytes bytes = self._read_value(self.CS_ADC_PIN, 2) # most significant bit first num = bytes[0] * 256 + bytes[1] # 4 leading zeros, 2 trailing zeros num = num >> 2 # 5V reference, 10 bits AV = 5.0 * num / 1024 # G=0.33 for voltage divider between shunt and ADC # convert to feedback shunt input voltage FB_SHNT_IN_V = 3 * AV if verbose: print("byte response: %X %X"% (bytes[0], bytes[1])) print("num respose: %d" % (num)) print("ADC input voltage: %.2f" % (AV)) print("Feedback shunt input voltage: %.2f" % (FB_SHNT_IN_V)) return AV def test_set_pin(self,logicHigh=1,pin="P8_14"): ''' this is a test function to set a pin on the beaglebone to high or low ''' GPIO.setup(pin, GPIO.OUT) if logicHigh: GPIO.output(pin, GPIO.HIGH) else: GPIO.output(pin, GPIO.LOW) def _set_coarse_dac(self,value): self._set_dac_value(self.CS_FB_COARSE_PIN, value) def _set_fine_dac(self,value): self._set_dac_value(self.CS_FB_FINE_PIN, value) def _set_dac_value(self, cs_pin, value): GPIO.output(cs_pin, GPIO.LOW) value = self._check_dac_value(value) # check if value is in range MSByte = value >> 8 LSByte = value - (MSByte << 8) # write self.spi00.writebytes([MSByte,LSByte]) GPIO.output(cs_pin, GPIO.HIGH) def _check_dac_value(self,value): value = int(value) if value > 65535: value = 65535 if value < 0: value = 0 return value def _read_value(self,cs_pin, length): ''' internal read value of analogue voltage ''' GPIO.output(cs_pin, GPIO.LOW) bytes = self.spi00.readbytes(length) GPIO.output(cs_pin, GPIO.HIGH) return bytes def ping(self): return True
class RFM69(BaseRadio): DATA = [] DATALEN = 0 SENDERID = 0 TARGETID = 0 PAYLOADLEN = 0 ACK_REQUESTED = False ACK_RECEIVED = False RSSI = 0 _mode = 0 _interruptPin = DIO0_PIN _csPin = NSS_PIN _address = 0 _promiscuousMode = False _powerLevel = 31 _isRFM69HW = True def __init__(self, isRFM69HW=True, interruptPin=DIO0_PIN, csPin=NSS_PIN): self._isRFM69HW = isRFM69HW self._interruptPin = interruptPin self._csPin = csPin self.SPI = SPI(SPI_BUS, SPI_CS) self.SPI.bpw = 8 self.SPI.mode = 0 self.SPI.msh = SPI_CLK_SPEED self.SPI.lsbfirst = False GPIO.setup(self._interruptPin, GPIO.IN) self.lastIrqLevel = GPIO.input(self._interruptPin) GPIO.setup(self._csPin, GPIO.OUT) GPIO.output(self._csPin, GPIO.HIGH) self.start_time = datetime.datetime.now() # Convention I want to stick to is a single underscore to indicate "private" methods. # I'm grouping all the private stuff up at the beginning. def _millis(self): delta = datetime.datetime.now() - self.start_time return delta.total_seconds() * 1000 def _readReg(self, addr): self._select() self.SPI.writebytes([addr & 0x7F]) result = self.SPI.readbytes(1)[0] # print "readReg {} = {}". format(hex(addr), hex(result)) self._unselect() return result def _writeReg(self, addr, value): # print "writeReg, Address {}:{}". format(hex(addr), hex(value)) self._select() self.SPI.writebytes([addr | 0x80, value]) self._unselect() # Select the transceiver def _select(self): GPIO.output(self._csPin, GPIO.LOW) # Unselect the transceiver chip def _unselect(self): GPIO.output(self._csPin, GPIO.HIGH) def _setMode(self, newMode): if newMode == RF69_MODE_TX: self._writeReg(REG_OPMODE, (self._readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_TRANSMITTER) if self._isRFM69HW: self.setHighPowerRegs(True) elif newMode == RF69_MODE_RX: self._writeReg(REG_OPMODE, (self._readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER) if self._isRFM69HW: self.setHighPowerRegs(False) elif newMode == RF69_MODE_SYNTH: self._writeReg(REG_OPMODE, (self._readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_SYNTHESIZER) elif newMode == RF69_MODE_STANDBY: self._writeReg(REG_OPMODE, (self._readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_STANDBY) elif newMode == RF69_MODE_SLEEP: self._writeReg(REG_OPMODE, (self._readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_SLEEP) # we are using packet mode, so this check is not really needed # but waiting for mode ready is necessary when going from sleep because the FIFO may not # be immediately available from previous mode while (self._mode == RF69_MODE_SLEEP and (self._readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00): # Wait for ModeReady pass self._mode = newMode def _canSend(self): #if signal stronger than -100dBm is detected assume channel activity if (self._mode == RF69_MODE_RX and self.PAYLOADLEN == 0 and self.getRSSI() < CSMA_LIMIT): self._setMode(RF69_MODE_STANDBY) return True return False def _sendFrame(self, toAddress, buffer, bufferSize, requestACK=False, sendACK=False): self._setMode(RF69_MODE_STANDBY) #turn off receiver to prevent reception while filling fifo while ((self._readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00): pass # Wait for ModeReady self._writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00) # DIO0 is "Packet Sent" if bufferSize > RF69_MAX_DATA_LEN: bufferSize = RF69_MAX_DATA_LEN #write to FIFO self._select() self.SPI.writebytes([REG_FIFO | 0x80, bufferSize + 3, toAddress, self._address]) #control byte if (sendACK): self.SPI.writebytes([0x80]) elif (requestACK): self.SPI.writebytes([0x40]) else: self.SPI.writebytes([0x00]) bufferBytes = [] for i in range(0, bufferSize): self.SPI.writebytes([ord(buffer[i])]) self._unselect() # no need to wait for transmit mode to be ready since its handled by the radio self._setMode(RF69_MODE_TX) txStart = self._millis() # wait for DIO0 to turn HIGH signalling transmission finish while (GPIO.input(self._interruptPin) == 0 and self._millis()-txStart < RF69_TX_LIMIT_MS): pass self._setMode(RF69_MODE_STANDBY) def _interruptHandler(self): if (self._mode == RF69_MODE_RX and (self._readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PAYLOADREADY)): self._setMode(RF69_MODE_STANDBY) self._select() self.SPI.writebytes([REG_FIFO & 0x7f]) self.PAYLOADLEN = self.SPI.readbytes(1)[0] self.PAYLOADLEN = 66 if self.PAYLOADLEN > 66 else self.PAYLOADLEN self.TARGETID = self.SPI.readbytes(1)[0] # match this node's address, or broadcast address or anything in promiscuous mode # address situation could receive packets that are malformed and don't fit this libraries extra fields if(not(self._promiscuousMode or self.TARGETID==self._address or self.TARGETID==RF69_BROADCAST_ADDR) or self.PAYLOADLEN < 3): self.PAYLOADLEN = 0 self._unselect() self._receiveBegin() return self.DATALEN = self.PAYLOADLEN - 3 self.SENDERID = self.SPI.readbytes(1)[0] CTLbyte = self.SPI.readbytes(1)[0] self.ACK_RECEIVED = CTLbyte & 0x80 #extract ACK-requested flag self.ACK_REQUESTED = CTLbyte & 0x40 #extract ACK-received flag self.DATA = self.SPI.readbytes(self.DATALEN) self._unselect() self._setMode(RF69_MODE_RX) self.RSSI = self.getRSSI() def _noInterrupts(self): pass def _interrupts(self): pass def _receiveBegin(self): 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 initialize(self, freqBand, nodeId, networkID): self._address = nodeId config = [ [ REG_OPMODE, RF_OPMODE_SEQUENCER_ON | RF_OPMODE_LISTEN_OFF | RF_OPMODE_STANDBY ], [ REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONTYPE_FSK | RF_DATAMODUL_MODULATIONSHAPING_00 ], #no shaping [ REG_BITRATEMSB, RF_BITRATEMSB_55555], #default:4.8 KBPS [ REG_BITRATELSB, RF_BITRATELSB_55555], [ REG_FDEVMSB, RF_FDEVMSB_50000], #default:5khz, (FDEV + BitRate/2 <= 500Khz) [ REG_FDEVLSB, RF_FDEVLSB_50000], [ REG_FRFMSB, RF_FRFMSB_315 if freqBand == RF69_315MHZ else (RF_FRFMSB_433 if freqBand == RF69_433MHZ else (RF_FRFMSB_868 if freqBand == RF69_868MHZ else RF_FRFMSB_915)) ], [ REG_FRFMID, RF_FRFMID_315 if freqBand == RF69_315MHZ else (RF_FRFMID_433 if freqBand == RF69_433MHZ else (RF_FRFMID_868 if freqBand == RF69_868MHZ else RF_FRFMID_915)) ], [ REG_FRFLSB, RF_FRFLSB_315 if freqBand == RF69_315MHZ else (RF_FRFLSB_433 if freqBand == RF69_433MHZ else (RF_FRFLSB_868 if freqBand == RF69_868MHZ else RF_FRFLSB_915)) ], # 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) #[ REG_PALEVEL, RF_PALEVEL_PA0_ON | RF_PALEVEL_PA1_OFF | RF_PALEVEL_PA2_OFF | RF_PALEVEL_OUTPUTPOWER_11111], #[ REG_OCP, RF_OCP_ON | RF_OCP_TRIM_95 ], #over current protection (default is 95mA) # RXBW defaults are [ REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_24 | RF_RXBW_EXP_5] (RxBw: 10.4khz) [ REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_16 | RF_RXBW_EXP_2 ], #(BitRate < 2 * RxBw) # for BR-19200: #* 0x19 */ [ REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_24 | RF_RXBW_EXP_3 ], [ REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01 ], #DIO0 is the only IRQ we're using [ REG_RSSITHRESH, 220 ], #must be set to dBm = (-Sensitivity / 2) - default is 0xE4=228 so -114dBm #[ REG_PREAMBLELSB, RF_PREAMBLESIZE_LSB_VALUE ] # default 3 preamble bytes 0xAAAAAA [ REG_SYNCCONFIG, RF_SYNC_ON | RF_SYNC_FIFOFILL_AUTO | RF_SYNC_SIZE_2 | RF_SYNC_TOL_0 ], [ REG_SYNCVALUE1, 0x2D ], #attempt to make this compatible with sync1 byte of RFM12B lib [ REG_SYNCVALUE2, networkID ], #NETWORK ID [ REG_PACKETCONFIG1, RF_PACKET1_FORMAT_VARIABLE | RF_PACKET1_DCFREE_OFF | RF_PACKET1_CRC_ON | RF_PACKET1_CRCAUTOCLEAR_ON | RF_PACKET1_ADRSFILTERING_OFF ], [ REG_PAYLOADLENGTH, 66 ], #in variable length mode: the max frame size, not used in TX #[ REG_NODEADRS, nodeID ], #turned off because we're not using address filtering [ REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFONOTEMPTY | RF_FIFOTHRESH_VALUE ], #TX on FIFO not empty [ REG_PACKETCONFIG2, RF_PACKET2_RXRESTARTDELAY_2BITS | RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AES_OFF ], #RXRESTARTDELAY must match transmitter PA ramp-down time (bitrate dependent) # 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) #[ REG_TESTDAGC, RF_DAGC_CONTINUOUS ], # run DAGC continuously in RX mode [ REG_TESTDAGC, RF_DAGC_IMPROVED_LOWBETA0 ], # run DAGC continuously in RX mode, recommended default for AfcLowBetaOn=0 [255, 0] ] print "writing REG_SYNCVALUE1" while self._readReg(REG_SYNCVALUE1) != 0xaa: self._writeReg(REG_SYNCVALUE1, 0xaa) while self._readReg(REG_SYNCVALUE1) != 0x55: self._writeReg(REG_SYNCVALUE1, 0x55) print "done writing REG_SYNCVALUE1" for chunk in config: self._writeReg(chunk[0], chunk[1]) self.setEncryptionKey(None) self.setHighPower(self._isRFM69HW) self._setMode(RF69_MODE_STANDBY) # wait for mode ready while (self._readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00: pass self._interrupts() 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._writeReg(REG_SYNCVALUE2, networkID) # set output power: 0=min, 31=max # this results in a "weaker" transmitted signal, and directly results in a lower RSSI at the receiver def setPowerLevel(self, powerLevel): self._powerLevel = powerLevel self._writeReg(REG_PALEVEL, (_readReg(REG_PALEVEL) & 0xE0) | (self._powerLevel if self._powerLevel < 31 else 31)) def send(self, toAddress, buffer, bufferSize, requestACK): self._writeReg(REG_PACKETCONFIG2, (self._readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART) # avoid RX deadlocks now = self._millis() while (not self._canSend() and self._millis()-now < RF69_CSMA_LIMIT_MS): self.receiveDone() self._sendFrame(toAddress, buffer, bufferSize, 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, buffer, bufferSize, retries=2, retryWaitTime=40): for i in range(0, retries): self.send(toAddress, buffer, bufferSize, True) sentTime = self._millis() while self._millis()-sentTime<retryWaitTime: if self.ACKReceived(toAddress): return True return False # Should be polled immediately after sending a packet with ACK request def ACKReceived(self, fromNodeID): if self.receiveDone(): return (self.SENDERID == fromNodeID or fromNodeID == RF69_BROADCAST_ADDR) and self.ACK_RECEIVED return False #check whether an ACK was requested in the last received packet (non-broadcasted packet) def ACKRequested(self): return self.ACK_REQUESTED and (self.TARGETID != RF69_BROADCAST_ADDR) # Should be called immediately after reception in case sender wants ACK def sendACK(self, buffer="", bufferSize=0): sender = self.SENDERID _RSSI = self.RSSI #save payload received RSSI value self._writeReg(REG_PACKETCONFIG2, (self._readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART) # avoid RX deadlocks now = self._millis() while (not self._canSend() and self._millis()-now < RF69_CSMA_LIMIT_MS): self.receiveDone() self._sendFrame(sender, buffer, bufferSize, False, True) self.RSSI = _RSSI #restore payload RSSI def receiveDone(self): self._noInterrupts() #re-enabled in _unselect() via _setMode() or via _receiveBegin() if GPIO.input(self._interruptPin): self._interruptHandler() if (self._mode == RF69_MODE_RX and self.PAYLOADLEN > 0): self._setMode(RF69_MODE_STANDBY) #enables interrupts return True elif (self._mode == RF69_MODE_RX): #already in RX no payload yet self._interrupts() #explicitly re-enable interrupts return False self._receiveBegin() return False # To enable encryption: radio.encrypt("ABCDEFGHIJKLMNOP") # To disable encryption: radio.encrypt(null) # KEY HAS TO BE 16 bytes !!! def setEncryptionKey(self, key): if key is not None: if len(key) != 16: raise Exception("Key must be exactly 16 bytes!") self._setMode(RF69_MODE_STANDBY) if (key is not None): keyBytes = [] self._select() self.SPI.writebytes([REG_AESKEY1 | 0x80]) for i in range(0,16): keyBytes.append(ord(key[i])) self.SPI.writebytes(keyBytes) self._unselect() self._writeReg(REG_PACKETCONFIG2, (self._readReg(REG_PACKETCONFIG2) & 0xFE) | (0 if key is None else 1)) # The following methods are not required by BaseRadio. # They depend too heavily on the specific radio hardware and would not get any benefit from being part of the # BaseRadio class. def getRSSI(self, forceTrigger=False): rssi = 0 if (forceTrigger): # RSSI trigger not needed if DAGC is in continuous mode self._writeReg(REG_RSSICONFIG, RF_RSSI_START) while ((self._readReg(REG_RSSICONFIG) & RF_RSSI_DONE) == 0x00): pass # Wait for RSSI_Ready rssi = -self._readReg(REG_RSSIVALUE) rssi >>= 1 return rssi # ON = disable filtering to capture all frames on network # OFF = enable node+broadcast filtering to capture only frames sent to this/broadcast address def setPromiscuous(self, onOff): self._promiscuousMode = onOff def setHighPower(self, onOff): self._isRFM69HW = onOff self._writeReg(REG_OCP, RF_OCP_OFF if self._isRFM69HW else RF_OCP_ON) if (self._isRFM69HW): # enable P1 & P2 amplifier stages self._writeReg(REG_PALEVEL, (self._readReg(REG_PALEVEL) & 0x1F) | RF_PALEVEL_PA1_ON | RF_PALEVEL_PA2_ON) else: # enable P0 only self._writeReg(REG_PALEVEL, RF_PALEVEL_PA0_ON | RF_PALEVEL_PA1_OFF | RF_PALEVEL_PA2_OFF | self.powerLevel) def setHighPowerRegs(self, onOff): self._writeReg(REG_TESTPA1, 0x5D if onOff else 0x55) self._writeReg(REG_TESTPA2, 0x7C if onOff else 0x70) def readAllRegs(self): print "Register, Address, Value" print "REG_FIFO, 0x00, {}".format(hex(self._readReg(REG_FIFO))) print "REG_OPMODE, 0x01, {}".format(hex(self._readReg(REG_OPMODE))) print "REG_DATAMODUL, 0x02, {}".format(hex(self._readReg(REG_DATAMODUL))) print "REG_BITRATEMSB, 0x03, {}".format(hex(self._readReg(REG_BITRATEMSB))) print "REG_BITRATELSB, 0x04, {}".format(hex(self._readReg(REG_BITRATELSB))) print "REG_FDEVMSB, 0x05, {}".format(hex(self._readReg(REG_FDEVMSB))) print "REG_FDEVLSB, 0x06, {}".format(hex(self._readReg(REG_FDEVLSB))) print "REG_FRFMSB, 0x07, {}".format(hex(self._readReg(REG_FRFMSB))) print "REG_FRFMID, 0x08, {}".format(hex(self._readReg(REG_FRFMID))) print "REG_FRFLSB, 0x09, {}".format(hex(self._readReg(REG_FRFLSB))) print "REG_OSC1, 0x0A, {}".format(hex(self._readReg(REG_OSC1))) print "REG_AFCCTRL, 0x0B, {}".format(hex(self._readReg(REG_AFCCTRL))) print "REG_LOWBAT, 0x0C, {}".format(hex(self._readReg(REG_LOWBAT))) print "REG_LISTEN1, 0x0D, {}".format(hex(self._readReg(REG_LISTEN1))) print "REG_LISTEN2, 0x0E, {}".format(hex(self._readReg(REG_LISTEN2))) print "REG_LISTEN3, 0x0F, {}".format(hex(self._readReg(REG_LISTEN3))) print "REG_VERSION, 0x10, {}".format(hex(self._readReg(REG_VERSION))) print "REG_PALEVEL, 0x11, {}".format(hex(self._readReg(REG_PALEVEL))) print "REG_PARAMP, 0x12, {}".format(hex(self._readReg(REG_PARAMP))) print "REG_OCP, 0x13, {}".format(hex(self._readReg(REG_OCP))) print "REG_AGCREF, 0x14, {}".format(hex(self._readReg(REG_AGCREF))) print "REG_AGCTHRESH1, 0x15, {}".format(hex(self._readReg(REG_AGCTHRESH1))) print "REG_AGCTHRESH2, 0x16, {}".format(hex(self._readReg(REG_AGCTHRESH2))) print "REG_AGCTHRESH3, 0x17, {}".format(hex(self._readReg(REG_AGCTHRESH3))) print "REG_LNA, 0x18, {}".format(hex(self._readReg(REG_LNA))) print "REG_RXBW, 0x19, {}".format(hex(self._readReg(REG_RXBW))) print "REG_AFCBW, 0x1A, {}".format(hex(self._readReg(REG_AFCBW))) print "REG_OOKPEAK, 0x1B, {}".format(hex(self._readReg(REG_OOKPEAK))) print "REG_OOKAVG, 0x1C, {}".format(hex(self._readReg(REG_OOKAVG))) print "REG_OOKFIX, 0x1D, {}".format(hex(self._readReg(REG_OOKFIX))) print "REG_AFCFEI, 0x1E, {}".format(hex(self._readReg(REG_AFCFEI))) print "REG_AFCMSB, 0x1F, {}".format(hex(self._readReg(REG_AFCMSB))) print "REG_AFCLSB, 0x20, {}".format(hex(self._readReg(REG_AFCLSB))) print "REG_FEIMSB, 0x21, {}".format(hex(self._readReg(REG_FEIMSB))) print "REG_FEILSB, 0x22, {}".format(hex(self._readReg(REG_FEILSB))) print "REG_RSSICONFIG, 0x23, {}".format(hex(self._readReg(REG_RSSICONFIG))) print "REG_RSSIVALUE, 0x24, {}".format(hex(self._readReg(REG_RSSIVALUE))) print "REG_DIOMAPPING1, 0x25, {}".format(hex(self._readReg(REG_DIOMAPPING1))) print "REG_DIOMAPPING2, 0x26, {}".format(hex(self._readReg(REG_DIOMAPPING2))) print "REG_IRQFLAGS1, 0x27, {}".format(hex(self._readReg(REG_IRQFLAGS1))) print "REG_IRQFLAGS2, 0x28, {}".format(hex(self._readReg(REG_IRQFLAGS2))) print "REG_RSSITHRESH, 0x29, {}".format(hex(self._readReg(REG_RSSITHRESH))) print "REG_RXTIMEOUT1, 0x2A, {}".format(hex(self._readReg(REG_RXTIMEOUT1))) print "REG_RXTIMEOUT2, 0x2B, {}".format(hex(self._readReg(REG_RXTIMEOUT2))) print "REG_PREAMBLEMSB, 0x2C, {}".format(hex(self._readReg(REG_PREAMBLEMSB))) print "REG_PREAMBLELSB, 0x2D, {}".format(hex(self._readReg(REG_PREAMBLELSB))) print "REG_SYNCCONFIG, 0x2E, {}".format(hex(self._readReg(REG_SYNCCONFIG))) print "REG_SYNCVALUE1, 0x2F, {}".format(hex(self._readReg(REG_SYNCVALUE1))) print "REG_SYNCVALUE2, 0x30, {}".format(hex(self._readReg(REG_SYNCVALUE2))) print "REG_SYNCVALUE3, 0x31, {}".format(hex(self._readReg(REG_SYNCVALUE3))) print "REG_SYNCVALUE4, 0x32, {}".format(hex(self._readReg(REG_SYNCVALUE4))) print "REG_SYNCVALUE5, 0x33, {}".format(hex(self._readReg(REG_SYNCVALUE5))) print "REG_SYNCVALUE6, 0x34, {}".format(hex(self._readReg(REG_SYNCVALUE6))) print "REG_SYNCVALUE7, 0x35, {}".format(hex(self._readReg(REG_SYNCVALUE7))) print "REG_SYNCVALUE8, 0x36, {}".format(hex(self._readReg(REG_SYNCVALUE8))) print "REG_PACKETCONFIG1, 0x37, {}".format(hex(self._readReg(REG_PACKETCONFIG1))) print "REG_PAYLOADLENGTH, 0x38, {}".format(hex(self._readReg(REG_PAYLOADLENGTH))) print "REG_NODEADRS, 0x39, {}".format(hex(self._readReg(REG_NODEADRS))) print "REG_BROADCASTADRS, 0x3A, {}".format(hex(self._readReg(REG_BROADCASTADRS))) print "REG_AUTOMODES, 0x3B, {}".format(hex(self._readReg(REG_AUTOMODES))) print "REG_FIFOTHRESH, 0x3C, {}".format(hex(self._readReg(REG_FIFOTHRESH))) print "REG_PACKETCONFIG2, 0x3D, {}".format(hex(self._readReg(REG_PACKETCONFIG2))) print "REG_AESKEY1, 0x3E, {}".format(hex(self._readReg(REG_AESKEY1))) print "REG_AESKEY2, 0x3F, {}".format(hex(self._readReg(REG_AESKEY2))) print "REG_AESKEY3, 0x40, {}".format(hex(self._readReg(REG_AESKEY3))) print "REG_AESKEY4, 0x41, {}".format(hex(self._readReg(REG_AESKEY4))) print "REG_AESKEY5, 0x42, {}".format(hex(self._readReg(REG_AESKEY5))) print "REG_AESKEY6, 0x43, {}".format(hex(self._readReg(REG_AESKEY6))) print "REG_AESKEY7, 0x44, {}".format(hex(self._readReg(REG_AESKEY7))) print "REG_AESKEY8, 0x45, {}".format(hex(self._readReg(REG_AESKEY8))) print "REG_AESKEY9, 0x46, {}".format(hex(self._readReg(REG_AESKEY9))) print "REG_AESKEY10, 0x47, {}".format(hex(self._readReg(REG_AESKEY10))) print "REG_AESKEY11, 0x48, {}".format(hex(self._readReg(REG_AESKEY11))) print "REG_AESKEY12, 0x49, {}".format(hex(self._readReg(REG_AESKEY12))) print "REG_AESKEY13, 0x4A, {}".format(hex(self._readReg(REG_AESKEY13))) print "REG_AESKEY14, 0x4B, {}".format(hex(self._readReg(REG_AESKEY14))) print "REG_AESKEY15, 0x4C, {}".format(hex(self._readReg(REG_AESKEY15))) print "REG_AESKEY16, 0x4D, {}".format(hex(self._readReg(REG_AESKEY16))) print "REG_TEMP1, 0x4E, {}".format(hex(self._readReg(REG_TEMP1))) print "REG_TEMP2, 0x4F, {}".format(hex(self._readReg(REG_TEMP2))) if self._isRFM69HW: print "REG_TESTPA1, 0x5A, {}".format(hex(self._readReg(REG_TESTPA1))) print "REG_TESTPA2, 0x5C, {}".format(hex(self._readReg(REG_TESTPA2))) print "REG_TESTDAGC, 0x6F, {}".format(hex(self._readReg(REG_TESTDAGC))) # returns centigrade def readTemperature(self, calFactor): self._setMode(RF69_MODE_STANDBY) self._writeReg(REG_TEMP1, RF_TEMP1_MEAS_START) while ((self._readReg(REG_TEMP1) & RF_TEMP1_MEAS_RUNNING)): pass #'complement'corrects the slope, rising temp = rising val # COURSE_TEMP_COEF puts reading in the ballpark, user can add additional correction return ~self._readReg(REG_TEMP2) + COURSE_TEMP_COEF + calFactor def rcCalibration(self): _writeReg(REG_OSC1, RF_OSC1_RCCAL_START) while ((_readReg(REG_OSC1) & RF_OSC1_RCCAL_DONE) == 0x00): pass
from Adafruit_BBIO.SPI import SPI import Adafruit_BBIO.GPIO as GPIO import time spi = SPI(0, 0) #4 busses, this is bus 0 spi.msh = 10000 #Frequency spi.bpw = 8 #bits per word spi.cshigh = False #true means you select the chip, depends on the chip, here low means active, normally Low for IMU spi.threewire = False #if it is true, you just read, otherwise you also send commands spi.lsbfirst = False #Least significant bit first (left) spi.open(0, 0) #open #GPIO.setup("P8_11",GPIO.OUT) #GPIO.output("P8_11",GPIO.HIGH) try: while True: res = spi.xfer2([0xFFFF, 0xFFFF]) #deliver two bytes res1 = spi.readbytes(2) #Read 2 bytes angle = (res1[0] << 8) | res1[1] #merge leftbyte and rightbyte angle1 = angle & 0x3FFF #move the first two bits angle2 = float(angle1) / 16363 * 360 print("data is") print(angle2) time.sleep(.25) except KeyboardInterrupt: spi.close()
class RFM69HCW(): def __init__(self, LED_STATE=default_LED_STATE, Fxosc=default_Fxosc, Fstep=default_Fstep, callsign=None, node_id=default_node_id, network_id=default_network_id, carrier_freq=default_carrier_freq, carrier_dev=default_carrier_dev, carrier_bitrate=default_bitrate): self._mode = OPMODE_SLEEP self.LED_STATE = LED_STATE self.Fxosc = Fxosc self.Fstep = Fstep self.callsign = callsign self.RFM_SPI = SPI(0, 0) self.RFM_SPI.msh = 5000000 self.carrier_freq = carrier_freq self.carrier_dev = carrier_dev self.bitrate = carrier_bitrate self.node_id = node_id self.network_id = network_id if self.callsign is None: raise NoCallSign("FCC Callsign not defined") self.ord_callsign = map(ord, list(self.callsign)) self._io_setup() GPIO.output(BLUE_LEDPIN, GPIO.LOW) self.reset_radio() return def _io_setup(self): GPIO.setup(BLUE_LEDPIN, GPIO.OUT) GPIO.setup(MODULE_EN, GPIO.OUT) GPIO.setup(MODULE_RST, GPIO.OUT) GPIO.setup(G0_PIN, GPIO.IN) GPIO.setup(G1_PIN, GPIO.OUT) GPIO.setup(G2_PIN, GPIO.OUT) # GPIO.add_event_detect(G0_PIN, GPIO.FALLING, callback=g0int) GPIO.add_event_detect(G0_PIN, GPIO.RISING, callback=g0int) def _check_register(self, addr, value): vals = self.RFM_SPI.xfer2([addr, 0x0]) if vals[1] != value: str = "addr: " + hex(addr) + "(" + inv_sx1231_reg[ addr] + ")" + " should be: " + hex(value) + " got: " + hex( vals[1]) raise CheckError(str) print "Reg{", hex(addr), "}(", inv_sx1231_reg[addr], ")\t\t=", hex( vals[1]) def write_register(self, reg, val, checkit=False): addr = reg reg = reg | 0x80 # print "reg is: ", bin(reg) # print "val is: " , bin(val) # RFM_SPI.writebytes([reg, val]) self.RFM_SPI.xfer2([reg, val]) if checkit == True: self._check_register(addr, val) return def read_register(self, reg): regval = self.RFM_SPI.xfer2([reg, 0x0]) return regval[1] def reset_radio(self): #self.blue_blink(2) GPIO.output(MODULE_EN, GPIO.HIGH) GPIO.output(MODULE_RST, GPIO.LOW) time.sleep(0.5) GPIO.output(MODULE_RST, GPIO.HIGH) time.sleep(0.5) GPIO.output(MODULE_RST, GPIO.LOW) time.sleep(0.5) def blue_invert(self): if (self.LED_STATE) == True: self.blue_off() else: self.blue_on() def blue_off(self): self.LED_STATE = False GPIO.output(BLUE_LEDPIN, GPIO.HIGH) return def blue_on(self): self.LED_STATE = True GPIO.output(BLUE_LEDPIN, GPIO.LOW) return def blue_blink(self, n=3): for num in range(0, n * 2): self.blue_invert() time.sleep(0.25) return def report_setup(self): print 'LED_STATE is:\t', self.LED_STATE print 'Fxosc is: \t', self.Fxosc print 'Fstep is: \t', self.Fstep print 'Callsign is: \t', self.callsign return # Facts: # Fxosc = 32Mhz # Fstep = 32e6/2^9 = 61.03515625 # Frf = int(carrier_hz/Fstep) def write_carrier_freq(self, carrier_hz=436500000): frf = int(carrier_hz / self.Fstep) # vals = RFM_SPI.xfer2([RegFrfMsb, 0x0, 0x0, 0x0]) # print "Pre: vals=\t", hex(vals[0]), "\t", hex(vals[1]), "\t", hex(vals[2]), "\t", hex(vals[3]) frfmsb = (frf >> 16) & 0xff frfmid = (frf >> 8) & 0xff frflsb = frf & 0xff wbuf = [(sx1231_reg["RegFrfMsb"] | 0x80), int(frfmsb), int(frfmid), int(frflsb)] self.RFM_SPI.writebytes(wbuf) vals = self.RFM_SPI.xfer2([sx1231_reg["RegFrfMsb"], 0x0, 0x0, 0x0]) # print "Post: vals=\t", hex(vals[0]), "\t", hex(vals[1]), "\t", hex(vals[2]), "\t", hex(vals[3]) return def set_freq_deviation(self, freq_dev_hz=20000): freqdev = int(freq_dev_hz / self.Fstep) wbuf = [(sx1231_reg["RegFdevMsb"] | 0x80), (int(freqdev >> 8) & 0x3f), int(freqdev & 0xff)] self.RFM_SPI.writebytes(wbuf) # print "fdev_msb:\t", # check_register(sx1231_reg["RegFdevMsb"], (int(freqdev>>8) & 0x3f)) # print "\nfdev_lsb:\t", # check_register(sx1231_reg["RegFdevLsb"], (int(freqdev & 0xff))) # print "\n" return def set_bitrate(self, bitrate_hz=1200): rate = int(self.Fxosc / bitrate_hz) wbuf = [(sx1231_reg["RegBitrateMsb"] | 0x80), (int(rate >> 8) & 0xff), int(rate & 0xff)] self.RFM_SPI.writebytes(wbuf) def set_sync_value(fourbytelist): wbuf = [(sx1231_reg["RegSyncValue1"] | 0x80)] + fourbytelist self.RFM_SPI.writebytes(wbuf) def set_preamble(twobytelist): wbuf = [(sx1231_reg["RegPreambleMsb"] | 0x80)] + twobytelist self.RFM_SPI.writebytes(wbuf) """ Experiment with automodes """ def config_packet(self, pa, node_id=0x33, network_id=0x77): # Begin with sequencer on, listen off, and in standby self.write_register(sx1231_reg["RegOpMode"], OPMODE_SEQUENCER_ON | OPMODE_LISTEN_OFF, True) self.set_mode(OPMODE_STANDBY) # Automodes - Finish Emptying fifo while in STBY self.write_register( sx1231_reg["RegAutoModes"], AUTOMODE_ENTER_CRC_OK | AUTOMODE_EXIT_FIFO_NOT_EMPTY | AUTOMODE_INTERM_STDBY, True) # Packet Mode, FSK, No Shaping self.write_register( sx1231_reg["RegDataModul"], DATAMODUL_Packet | DATAMODUL_FSK | DATAMODUL_NoShaping) self.write_carrier_freq(self.carrier_freq) self.set_freq_deviation(self.carrier_dev) self.set_bitrate(self.bitrate) # PA Output Power self.write_register(sx1231_reg["RegPaLevel"], PAOutputCfg( PA0, 0x1F)) # keep at PA0 until end of initialize # DIO Mappings g0_flag = False g1_flag = False g2_flag = False g3_flag = False g4_flag = False g5_flag = False # (DccFreq|RxBwMant|RxBwExp) Table 13 self.write_register(sx1231_reg["RegRxBw"], (010 << 5 | 0x10 << 3 | 100 << 0)) # 20.8kHz? # DIO_0 initialize to PAYLOAD ready in RX self.write_register( sx1231_reg["RegDioMapping1"], ((self.read_register(sx1231_reg["RegDioMapping1"]) & (~(0b11 << DIO_0_POS))) | DIO0_PAYLOADREADY << DIO_0_POS), True) # DIO_1 is RX TIMEOUT self.write_register( sx1231_reg["RegDioMapping1"], ((self.read_register(sx1231_reg["RegDioMapping1"]) & (~(0b11 << DIO_1_POS))) | DIO1_RX_TIMEOUT << DIO_1_POS), True) # DIO_4 is Clkout self.write_register(sx1231_reg["RegDioMapping2"], (DIO4_RXRDY << DIO_4_POS | DIO_CLK_DIV32), True) # Clear IRQFLAG and reset FIFO self.write_register(sx1231_reg["RegIrqFlags2"], IRQFLAGS2_FIFOOVERRUN) # RSSI Thresh self.write_register(sx1231_reg["RegRssiThresh"], 0xdc, True) # -220/2 = -110dBm? # Preamble length (0xaa..N) self.write_register(sx1231_reg["RegPreambleLsb"], 0xf, True) # Sync Config self.write_register( sx1231_reg["RegSyncConfig"], SYNCCFG_SYNC_ON | SYNCCFG_FILL_FIFO_INTR | SYNCCFG_SIZE_2, True) # Sync Word self.write_register(sx1231_reg["RegSyncValue1"], node_id, True) self.write_register(sx1231_reg["RegSyncValue2"], network_id, True) # Packet config 1 self.write_register( sx1231_reg["RegPacketConfig1"], PACKET1_FORMAT_FIXED | PACKET1_DCFREE_NONE | PACKET1_CRC_ON | PACKET1_CRCAUTOCLEAR_ON | PACKET1_ADDRESS_FILTERING_BOTH, True) # Payload Length self.write_register(sx1231_reg["RegPayloadLength"], default_Payload_bytes, True) # Node address: self.write_register(sx1231_reg["RegNodeAdrs"], self.node_id, True) self.write_register(sx1231_reg["RegBroadcastAdrs"], self.node_id + 1, True) # Fifothresh? Only for TX self.write_register(sx1231_reg["RegFifoThresh"], FIFOTHRESH_NOT_EMPTY | FIFOTHRESH_THRESHOLD_15, True) # Packet config 2 self.write_register(sx1231_reg["RegPacketConfig2"], PACKET2_AUTORX_RESTART_ON, True) # Magic numbers self.write_register( sx1231_reg["RegPaRamp"], 0b0011, True ) # 500uS close to 1/2400 bps ... see PacketConfig2 InterPacketRxDelay Must match the tx PA Ramp-down time # self.write_register(sx1231_reg["RegAfcCtrl"],0x40 | (0b1<<5) , True ) # AfcLowBetaOn - Manual misprint....bits 7-6 read as 0b01 not 0b00 self.write_register( sx1231_reg["RegAfcCtrl"], (0b1 << 5), True ) # AfcLowBetaOn - Manual misprint....bits 7-6 read as 0b01 not 0b00 self.write_register(sx1231_reg["RegTestDagc"], 0x20, True) # page 74 for AfcLowBetaOn=1 self.write_register(sx1231_reg["RegPaLevel"], pa) return def set_mode(self, mode): if (mode == self._mode): return if (mode == OPMODE_SLEEP): self.write_register( sx1231_reg["RegDioMapping1"], ((self.read_register(sx1231_reg["RegDioMapping1"]) & (~(0b11 << DIO_0_POS))) | DIO0_PAYLOADREADY << DIO_0_POS)) self.write_register( sx1231_reg["RegOpMode"], (self.read_register(sx1231_reg["RegOpMode"]) & 0xe3) | OPMODE_SLEEP) self._mode = OPMODE_SLEEP elif (mode == OPMODE_STANDBY): self.write_register( sx1231_reg["RegDioMapping1"], ((self.read_register(sx1231_reg["RegDioMapping1"]) & (~(0b11 << DIO_0_POS))) | DIO0_PAYLOADREADY << DIO_0_POS)) self.write_register( sx1231_reg["RegOpMode"], (self.read_register(sx1231_reg["RegOpMode"]) & 0xe3) | OPMODE_STANDBY) self._mode = OPMODE_STANDBY elif (mode == OPMODE_FS_SYNTH): self.write_register( sx1231_reg["RegOpMode"], (self.read_register(sx1231_reg["RegOpMode"]) & 0xe3) | OPMODE_FS_SYNTH) self._mode = OPMODE_FS_SYNTH elif (mode == OPMODE_TX): self.write_register( sx1231_reg["RegDioMapping1"], ((self.read_register(sx1231_reg["RegDioMapping1"]) & (~(0b11 << DIO_0_POS))) | DIO0_PACKETSENT << DIO_0_POS)) self.write_register( sx1231_reg["RegOpMode"], (self.read_register(sx1231_reg["RegOpMode"]) & 0xe3) | OPMODE_TX) self._mode = OPMODE_TX elif (mode == OPMODE_RX): self.write_register( sx1231_reg["RegDioMapping1"], ((self.read_register(sx1231_reg["RegDioMapping1"]) & (~(0b11 << DIO_0_POS))) | DIO0_PAYLOADREADY << DIO_0_POS)) self.write_register( sx1231_reg["RegOpMode"], (self.read_register(sx1231_reg["RegOpMode"]) & 0xe3) | OPMODE_RX) self._mode = OPMODE_RX else: raise ValueError('Unrecognized Mode') while ((self.read_register(sx1231_reg["RegIrqFlags1"]) & IRQFLAGS1_MODEREADY) == 0x00): pass return def RSSI(self): # write trigger self.write_register(sx1231_reg["RegRssiConfig"], 0b1) while ((self.read_register(sx1231_reg["RegRssiConfig"]) & RSSI_DONE) == 0x0): pass rssival = -self.read_register(sx1231_reg["RegRssiValue"]) rssival = rssival / 2 return rssival # call when g0flag goes true def read_fifo(self): global g0_flag self.standby() fifolist = self.RFM_SPI.readbytes(default_Payload_bytes + 1) #debugging # value = True # while value: # print "* "; # value = self.read_register(sx1231_reg["RegIrqFlags2"]) & IRQFLAGS2_PAYLOADREADY # garbage=self.RFM_SPI.readbytes(default_Payload_bytes+1) value = self.read_register( sx1231_reg["RegIrqFlags2"]) & IRQFLAGS2_PAYLOADREADY if value == 0: g0_flag = False return fifolist def standby(self): self.set_mode(OPMODE_STANDBY) return def receive(self): self.set_mode(OPMODE_RX) g0_flag = False return def send(self, bytelist): self.set_mode(OPMODE_STANDBY) if len(bytelist) > MAX_PACKET_LEN: raise ValueError('Max Packet Len Exceeded') #bytelist = [self.node_id+1]+[self.node_id] + bytelist # bytelist = [self.node_id] + [self.node_id+1] + bytelist # bytelist = [self.node_id] + bytelist bytelist = [self.node_id] + bytelist print "\tbytelist: ", bytelist wbuf = [(sx1231_reg["RegFifo"] | 0x80)] + bytelist self.RFM_SPI.writebytes(wbuf) start_time = time.time() self.set_mode(OPMODE_TX) # Read pin or register... # value = GPIO.input(G0_PIN) value = self.read_register( sx1231_reg["RegIrqFlags2"]) & IRQFLAGS2_PACKETSENT #print "Start send:\t", start_time while value == 0: # value = GPIO.input(G0_PIN) value = self.read_register( sx1231_reg["RegIrqFlags2"]) & IRQFLAGS2_PACKETSENT elapsed_time = time.time() - start_time if (elapsed_time > 10): break #print "Stop send:\t", elapsed_time self.set_mode(OPMODE_STANDBY) return def stop(self): return
import time from Adafruit_BBIO.SPI import SPI spi_in = SPI(0,0) spi_out = SPI(0,1) while True: try: spi_out.writebytes([0x50]) print spi_in.readbytes(2) time.sleep(0.02) except KeyboardInterrupt: break
#!/usr/bin/env python # -*- coding: utf-8 -*- import time from Adafruit_BBIO.SPI import SPI spi_in = SPI(0, 0) spi_out = SPI(0, 1) while True: try: print spi_in.readbytes(1) time.sleep(0.03) except KeyboardInterrupt: Break