From 1092aa59d16006e3405b407df80c4fcaafa9eb8a Mon Sep 17 00:00:00 2001 From: Milan Ventil Toman Date: Fri, 29 May 2020 13:14:16 +0200 Subject: [PATCH] First commit for the ESP8266 wifi davis logger --- WiFi.mpy | Bin 0 -> 1610 bytes WiFi.py | 105 +++++++++++++ boot.py | 3 + cc1101_davis.mpy | Bin 0 -> 7979 bytes cc1101_davis.py | 390 +++++++++++++++++++++++++++++++++++++++++++++++ davis_decode.mpy | Bin 0 -> 3139 bytes davis_decode.py | 223 +++++++++++++++++++++++++++ inet.conf | 20 +++ main.py | 89 +++++++++++ 9 files changed, 830 insertions(+) create mode 100644 WiFi.mpy create mode 100644 WiFi.py create mode 100644 boot.py create mode 100644 cc1101_davis.mpy create mode 100644 cc1101_davis.py create mode 100644 davis_decode.mpy create mode 100644 davis_decode.py create mode 100644 inet.conf create mode 100644 main.py diff --git a/WiFi.mpy b/WiFi.mpy new file mode 100644 index 0000000000000000000000000000000000000000..cc403981ddc1d500fa06ac41c922c731282974e8 GIT binary patch literal 1610 zcmZWp+iu%N5MAoxi+mAD(XWo$(puju}Skldcn=!xwDn_ukWUbv+WHZxl z>a~;>bFsneNX*UBqkX&+^RP?0Qfr_@_*|P>yQvQ)M=_>F)u`2v)%F35=M6HBPhT_fHj~{d#tr|~_aQKI%_W|H_IZp8FIvkHE*9ZJ zktm;s3@G;n0@Xr)%#g;hqI9H| zvGiO;MfH3CyiE8UH(YF9wgWTFya2>kPjJ1Y+C+I!(*^MR3#U+0!m`x5rV&7Lz(T^6 znHqE&XoPnZbH#usHPwVoO^4>80!OOGPO{cgV7Ft;m-SQhUo;wpkH3K}O;;ceYZx=R zt_ig!)D=@dHJ-u0$GCg*)~Dfch~t-+R#sNhg(&FT!MPXcO>Y33xp6KKujx5vZpmt( zf(GKE#d`);h4iSM`k+@KCt5Y*s6Kd#kb{%@;M)p0)@U1bIWIqmfGQ1^{}Mm2-ef3% zMTfci&EYC97Yc7U@BRY<>=$GL^_Zf<2A?bzbH#Nyng~=7W~Zy825W8Dtf|LJ1D>en z;W{depPaovZ>0g681(xOW{*zXcU#+$(7n5>8>__#x4j?X_{b{HqlF*913SnLV@eHG zHq$?&Q#~SSH2h{1xjez63(i)V3FhJ@5Cub9auhz ztHDfs_oVP}|NjKKuSxJae>5RdP83WpnrVk%J3x>(Dt3@SLK_-1_-bgcp}WF?gAy8% zoywO|I#()R_+EnfT=9LdQc4!z_e3|q1$Z0Bl*EKoO~%XVE9YAmIJ&ROl}mT_0xrg@ zIK*(?>(pj$cQ=_WBi)ZgQ2(eJFJ?2@)H>Yi%11~C-44_`SQtEP)s7U1W}>c`rlK34 tT)HN8UDFL5#kmYdv3O{h>hUo=(C~EOK|)uFe>0ce%A}x}*(_su{R{jiyr2L8 literal 0 HcmV?d00001 diff --git a/WiFi.py b/WiFi.py new file mode 100644 index 0000000..2c6408c --- /dev/null +++ b/WiFi.py @@ -0,0 +1,105 @@ +import network +import utime +import machine + +_DEBUG = False + + +class NetSet(object): + + def __init__(self, wifi_type): + self.sta = network.WLAN(network.STA_IF) + self.ap = network.WLAN(network.AP_IF) + if wifi_type == 'infra': + if _DEBUG: + print("Disabling AP") + self.ap.active(False) + if _DEBUG: + print("Activating INFRA") + self.sta.active(True) + self.sta.isconnected() # False, it should be # Comments by Yoda + self._SSID = None + self._PASS = None + self._TIMEOUT = None + elif wifi_type == 'ap': + if _DEBUG: + print("Disabling INFRA") + self.ap.active(True) + if _DEBUG: + print("Activating AP") + self.sta.active(False) + self.sta.isconnected() # False, it should be # Comments by Yoda + self._SSID = None + self._PASS = None + self._TIMEOUT = None + + def connectInfraGo(self, _timeout): + if _DEBUG: + print("Connecting to infra") + self.sta.connect(self._SSID, self._PASS) + if _DEBUG: + print("Let's wait for the network to come up") + while not (self.sta.isconnected()): + if _timeout > 0: + print("Trying... {} more times".format(_timeout)) + utime.sleep_ms(1001) + _timeout -= 1 + else: + print("Out of retrys") + return False + network_config = self.sta.ifconfig() + return network_config + + def connectInfra(self, _SSID, _PASS, _TIMEOUT): + self._SSID = _SSID + self._PASS = _PASS + try: + net_conf_result = self.connectInfraGo(_TIMEOUT) + utime.sleep_ms(100) + if net_conf_result: + return { + 'ip': net_conf_result[0], + 'mask': net_conf_result[1], + 'gw': net_conf_result[2], + 'dns': net_conf_result[3] } + else: + return False + except Exception as e: + print("ERROR: Network configuration failed with: {}".format(e)) + return False + + def connectAp(self): + # TBI + pass + + def readNetworkConfig(self): + self.config_dict = {} + try: + with open('inet.conf', 'r') as conf_handler: + for item in conf_handler.readlines(): + option = item.split("=")[0].strip() + if len(item.split("=")) == 2 and '#' not in option: + value = item.split("=")[1].strip() + self.config_dict.update({option: value}) + else: + if _DEBUG: + if '#' in option: + print(b"COMMENT in config") + else: + print(b"WARNING: Fucked up option, make it better") + except Exception as e: + if _DEBUG: + print("WARNING: Errors in INFRA config, still going for AP") + return False + if _DEBUG: + print("CONFIG DICT: {}".format(self.config_dict)) + self._SSID = self.config_dict['_SSID'] + self._PASS = self.config_dict['_PASS'] + self._TIMEOUT = int(self.config_dict['_TIMEOUT']) + self._INFLUX_HOST = self.config_dict['_INFLUX_HOST'] + self._INFLUX_PORT = self.config_dict['_INFLUX_PORT'] + self._INFLUX_USER = self.config_dict['_INFLUX_USER'] + self._INFLUX_PASS = self.config_dict['_INFLUX_PASS'] + self._INF_DB_WEATHER = self.config_dict['_INF_DB_WEATHER'] + self._INF_DB_STATUS = self.config_dict['_INF_DB_STATUS'] + self._INF_DB_RAW = self.config_dict['_INF_DB_RAW'] diff --git a/boot.py b/boot.py new file mode 100644 index 0000000..fea6b0e --- /dev/null +++ b/boot.py @@ -0,0 +1,3 @@ +# This file is executed on every boot (including wake-boot from deepsleep) +import gc +gc.collect() diff --git a/cc1101_davis.mpy b/cc1101_davis.mpy new file mode 100644 index 0000000000000000000000000000000000000000..384f59a96e24619aeabb63b1b75a16107dfd542e GIT binary patch literal 7979 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 literal 0 HcmV?d00001 diff --git a/cc1101_davis.py b/cc1101_davis.py new file mode 100644 index 0000000..35a022d --- /dev/null +++ b/cc1101_davis.py @@ -0,0 +1,390 @@ +import utime +import gc +import machine + +ss = machine.Pin(15,machine.Pin.OUT) # Chip select / HCS +so = machine.Pin(12) # HMISO +si = machine.Pin(13) # HMOSI +sck = machine.Pin(14) # HSCLK +interrupt = machine.Pin(2) # Interrupt for packet available + +gc.collect() + +class CC1101(object): + def __init__(self): + self.debug = 1 + self.hspi = machine.SPI(1, baudrate=600000, polarity=0, phase=0) + self.PA_TABLE = [0xC0, 0xC0, 0xC0, 0xC0, + 0xC0, 0xC0, 0xC0, 0xC0] + + self.FREQ_2 = [0x21, 0x21, 0x21, 0x21, 0x21] + self.FREQ_1 = [0x62, 0x65, 0x67, 0x64, 0x66] + self.FREQ_0 = [0xE2, 0x40, 0x9D, 0x11, 0x6F] + + self.CRC_TABLE = [ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0] + self.BUFFER_SIZE = 16 + self.DAVIS_PACKET_LENGTH = 10 + self.rxBuffer = [] + self.rxBufferIndex = 0 + self.rxBufferLength = 0 + self.hopIndex = 0 + self.freqComp = [0, 0, 0, 0, 0] + + # CC1101 Transfer Types. + self.WRITE_BURST = 0x40 + self.READ_SINGLE = 0x80 + self.READ_BURST = 0xC0 + + # Davis Register Configuration Settings. + self.DAVIS_IOCFG2 = 0x2E # GDO2 Output Pin Configuration + self.DAVIS_IOCFG1 = 0x2E # GDO1 Output Pin Configuration + self.DAVIS_IOCFG0 = 0x01 # GDO0 Output Pin Configuration + self.DAVIS_FIFOTHR = 0x42 # RX FIFO and TX FIFO Thresholds + self.DAVIS_SYNC1 = 0xCB # Synchronization word, high byte + self.DAVIS_SYNC0 = 0x89 # Synchronization word, low byte + self.DAVIS_PKTLEN = 0x0A # Packet Length + self.DAVIS_PKTCTRL1 = 0xC4 # Packet Automation Control + self.DAVIS_PKTCTRL0 = 0x00 # Packet Automation Control + self.DAVIS_ADDR = 0x00 # Device Address + self.DAVIS_CHANNR = 0x00 # Channel Number + self.DAVIS_FSCTRL1 = 0x06 # Frequency Synthesizer Control + self.DAVIS_FSCTRL0 = 0xF0 # Frequency Synthesizer Control + self.DAVIS_FREQ2 = 0x23 # Frequency Control Word, High Byte + self.DAVIS_FREQ1 = 0x0D # Frequency Control Word, Middle Byte + self.DAVIS_FREQ0 = 0x97 # Frequency Control Word, Low Byte + self.DAVIS_MDMCFG4 = 0xC9 # Modem Configuration + self.DAVIS_MDMCFG3 = 0x83 # Modem Configuration + self.DAVIS_MDMCFG2 = 0x12 # Modem Configuration + self.DAVIS_MDMCFG1 = 0x21 # Modem Configuration + self.DAVIS_MDMCFG0 = 0xF9 # Modem Configuration + self.DAVIS_DEVIATN = 0x24 # Modem Deviation Setting + self.DAVIS_MCSM2 = 0x07 # Main Radio Control State Machine Configuration + self.DAVIS_MCSM1 = 0x00 # Main Radio Control State Machine Configuration + self.DAVIS_MCSM0 = 0x18 # Main Radio Control State Machine Configuration + self.DAVIS_FOCCFG = 0x16 # Frequency Offset Compensation Configuration + self.DAVIS_BSCFG = 0x6C # Bit Synchronization Configuration + self.DAVIS_AGCCTRL2 = 0x43 # AGC Control + self.DAVIS_AGCCTRL1 = 0x40 # AGC Control + self.DAVIS_AGCCTRL0 = 0x91 # AGC Control + self.DAVIS_WOREVT1 = 0x87 # High Byte Event0 Timeout + self.DAVIS_WOREVT0 = 0x6B # Low Byte Event0 Timeout + self.DAVIS_WORCTRL = 0xF8 # Wake On Radio Control + self.DAVIS_FREND1 = 0x56 # Front End RX Configuration + self.DAVIS_FREND0 = 0x10 # Front End TX Configuration + self.DAVIS_FSCAL3 = 0xEF # Frequency Synthesizer Calibration + self.DAVIS_FSCAL2 = 0x2B # Frequency Synthesizer Calibration + self.DAVIS_FSCAL1 = 0x2F # Frequency Synthesizer Calibration + self.DAVIS_FSCAL0 = 0x1F # Frequency Synthesizer Calibration + self.DAVIS_RCCTRL1 = 0x00 # RC Oscillator Configuration + self.DAVIS_RCCTRL0 = 0x00 # RC Oscillator Configuration + self.DAVIS_FSTEST = 0x59 # Frequency Synthesizer Calibration Control + self.DAVIS_PTEST = 0x7F # Production Test + self.DAVIS_AGCTEST = 0x3F # AGC Test + self.DAVIS_TEST2 = 0x81 # Various Test Settings + self.DAVIS_TEST1 = 0x35 # Various Test Settings + self.DAVIS_TEST0 = 0x09 # Various Test Settings + + self.CC1101_IOCFG2 = 0x00 # GDO2 Output Pin Configuration + self.CC1101_IOCFG1 = 0x01 # GDO1 Output Pin Configuration + self.CC1101_IOCFG0 = 0x02 # GDO0 Output Pin Configuration + self.CC1101_FIFOTHR = 0x03 # RX FIFO and TX FIFO Thresholds + self.CC1101_SYNC1 = 0x04 # Sync Word, High Byte + self.CC1101_SYNC0 = 0x05 # Sync Word, Low Byte + self.CC1101_PKTLEN = 0x06 # Packet Length + self.CC1101_PKTCTRL1 = 0x07 # Packet Automation Control + self.CC1101_PKTCTRL0 = 0x08 # Packet Automation Control + self.CC1101_ADDR = 0x09 # Device Address + self.CC1101_CHANNR = 0x0A # Channel Number + self.CC1101_FSCTRL1 = 0x0B # Frequency Synthesizer Control + self.CC1101_FSCTRL0 = 0x0C # Frequency Synthesizer Control + self.CC1101_FREQ2 = 0x0D # Frequency Control Word, High Byte + self.CC1101_FREQ1 = 0x0E # Frequency Control Word, Middle Byte + self.CC1101_FREQ0 = 0x0F # Frequency Control Word, Low Byte + self.CC1101_MDMCFG4 = 0x10 # Modem Configuration + self.CC1101_MDMCFG3 = 0x11 # Modem Configuration + self.CC1101_MDMCFG2 = 0x12 # Modem Configuration + self.CC1101_MDMCFG1 = 0x13 # Modem Configuration + self.CC1101_MDMCFG0 = 0x14 # Modem Configuration + self.CC1101_DEVIATN = 0x15 # Modem Deviation Setting + self.CC1101_MCSM2 = 0x16 # Main Radio Control State Machine Configuration + self.CC1101_MCSM1 = 0x17 # Main Radio Control State Machine Configuration + self.CC1101_MCSM0 = 0x18 # Main Radio Control State Machine Configuration + self.CC1101_FOCCFG = 0x19 # Frequency Offset Compensation Configuration + self.CC1101_BSCFG = 0x1A # Bit Synchronization Configuration + self.CC1101_AGCCTRL2 = 0x1B # AGC Control + self.CC1101_AGCCTRL1 = 0x1C # AGC Control + self.CC1101_AGCCTRL0 = 0x1D # AGC Control + self.CC1101_WOREVT1 = 0x1E # High Byte Event0 Timeout + self.CC1101_WOREVT0 = 0x1F # Low Byte Event0 Timeout + self.CC1101_WORCTRL = 0x20 # Wake On Radio Control + self.CC1101_FREND1 = 0x21 # Front End RX Configuration + self.CC1101_FREND0 = 0x22 # Front End TX Configuration + self.CC1101_FSCAL3 = 0x23 # Frequency Synthesizer Calibration + self.CC1101_FSCAL2 = 0x24 # Frequency Synthesizer Calibration + self.CC1101_FSCAL1 = 0x25 # Frequency Synthesizer Calibration + self.CC1101_FSCAL0 = 0x26 # Frequency Synthesizer Calibration + self.CC1101_RCCTRL1 = 0x27 # RC Oscillator Configuration + self.CC1101_RCCTRL0 = 0x28 # RC Oscillator Configuration + self.CC1101_FSTEST = 0x29 # Frequency Synthesizer Calibration Control + self.CC1101_PTEST = 0x2A # Production Test + self.CC1101_AGCTEST = 0x2B # AGC Test + self.CC1101_TEST2 = 0x2C # Various Test Settings + self.CC1101_TEST1 = 0x2D # Various Test Settings + self.CC1101_TEST0 = 0x2E # Various Test Settings + + # CC1101 Status Registers. + self.CC1101_PARTNUM = 0x30 # Chip ID + self.CC1101_VERSION = 0x31 # Chip ID + self.CC1101_FREQEST = 0x32 # Frequency Offset Estimate from Demodulator + self.CC1101_LQI = 0x33 # Demodulator Estimate for Link Quality + self.CC1101_RSSI = 0x34 # Received Signal Strength Indication + self.CC1101_MARCSTATE = 0x35 # Main Radio Control State Machine State + self.CC1101_WORTIME1 = 0x36 # High Byte of WOR Time + self.CC1101_WORTIME0 = 0x37 # Low Byte of WOR Time + self.CC1101_PKTSTATUS = 0x38 # Current GDOx Status and Packet Status + self.CC1101_VCO_VC_DAC = 0x39 # Current Setting from PLL Calibration Module + self.CC1101_TXBYTES = 0x3A # Underflow and Number of Bytes + self.CC1101_RXBYTES = 0x3B # Overflow and Number of Bytes + self.CC1101_RCCTRL1_STATUS = 0x3C # Last RC Oscillator Calibration Result + self.CC1101_RCCTRL0_STATUS = 0x3D # Last RC Oscillator Calibration Result + + # CC1101 PA Table, TX FIFO and RX FIFO. + self.CC1101_PATABLE = 0x3E # PA TABLE address + self.CC1101_TXFIFO = 0x3F # TX FIFO address + self.CC1101_RXFIFO = 0x3F # RX FIFO address + + # CC1101 Command Strobes. + self.CC1101_SRES = 0x30 # Reset CC1101 chip + self.CC1101_SFSTXON = 0x31 # Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL = 1). If in RX (with CCA): + # Go to a wait state where only the synthesizer is running (for quick RX / TX turnaround). + self.CC1101_SXOFF = 0x32 # Turn off crystal oscillator + self.CC1101_SCAL = 0x33 # Calibrate frequency synthesizer and turn it off. SCAL can be strobed from IDLE mode without + # setting manual calibration mode (MCSM0.FS_AUTOCAL = 0) + self.CC1101_SRX = 0x34 # Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL = 1 + self.CC1101_STX = 0x35 # In IDLE state: Enable TX. Perform calibration first if MCSM0.FS_AUTOCAL = 1. + # If in RX state and CCA is enabled: Only go to TX if channel is clear + self.CC1101_SIDLE = 0x36 # Exit RX / TX, turn off frequency synthesizer and exit Wake-On-Radio mode if applicable + self.CC1101_SWOR = 0x38 # Start automatic RX polling sequence (Wake-on-Radio) if WORCTRL.RC_PD = 0 + self.CC1101_SPWD = 0x39 # Enter power down mode when CSn goes high + self.CC1101_SFRX = 0x3A # Flush the RX FIFO buffer. Only issue SFRX in IDLE or RXFIFO_OVERFLOW states + self.CC1101_SFTX = 0x3B # Flush the TX FIFO buffer. Only issue SFTX in IDLE or TXFIFO_UNDERFLOW states + self.CC1101_SWORRST = 0x3C # Reset real time clock to Event1 value + self.CC1101_SNOP = 0x3D # No operation. May be used to get access to the chip status byte + + # CC1101 Transfer Types. + self.WRITE_BURST = 0x40 + self.READ_SINGLE = 0x80 + self.READ_BURST = 0xC0 + + # CC1101 Returned Status Bytes. + self.CC1101_STATE_IDLE = 0x01 + self.CC1101_STATE_ENDCAL = 0x0C + self.CC1101_STATE_RX = 0x0D + self.CC1101_STATE_RXFIFO_ERROR = 0x11 + self.CC1101_STATE_TX = 0x13 + self.CC1101_STATE_TX_END = 0x14 + self.CC1101_STATE_TXFIFO_ERROR = 0x16 + self.reset() + self.setRegisters() + for i in range(0, 5): + self.freqComp[i] = self.DAVIS_FSCTRL0 + + def readRegister(self, regAddr): + addr = regAddr | self.READ_SINGLE + ss.off() + read_addr = bytes([addr]) + self.hspi.write(read_addr) + val = self.hspi.read(1, 0x00) + ss.on() + return int(val[0]) + + def writeRegister(self, regAddr, value): + ss.off() + self.hspi.write(bytes([regAddr])) + self.hspi.write(bytes([value])) + ss.on() + + def writeBurst(self, regAddr, wr_buffer): + addr = regAddr | self.WRITE_BURST + ss.off() + self.hspi.write(bytes([addr])) + for contents in wr_buffer: + self.hspi.write(bytes([contents])) + ss.on() + + def readBurst(self, regAddr, size): + addr = regAddr | self.READ_BURST + ss.off() + self.hspi.write(bytes([addr])) + rd_buffer = [] + for i in range(0, size): + rd_result = self.hspi.read(1, 0x00) + rd_buffer.append(hex(rd_result[0])) + ss.on() + return rd_buffer + + def cmdStrobe(self, command): + ss.off() + self.hspi.write(bytes([command])) + ss.on() + + def readStatus(self, regAddr): + addr = regAddr | self.READ_BURST + ss.off() + self.hspi.write(bytes([addr])) + value = self.hspi.read(1, 0x00) + ss.on() + return int(value[0]) + + def reset(self): + ss.off() + utime.sleep_ms(1) + ss.on() + utime.sleep_ms(1) + ss.off() + while so.value(): + pass + self.hspi.write(bytes([self.CC1101_SRES])) + while so.value(): + pass + ss.on() + + def sidle(self): + self.cmdStrobe(self.CC1101_SIDLE) + while self.readStatus(self.CC1101_MARCSTATE) != 0x01: + utime.sleep_us(100) + self.cmdStrobe(self.CC1101_SFTX) + self.cmdStrobe(self.CC1101_SFRX) + utime.sleep_us(100) + + def setRegisters(self): + self.writeRegister(self.CC1101_IOCFG2, self.DAVIS_IOCFG2) + self.writeRegister(self.CC1101_IOCFG1, self.DAVIS_IOCFG1) + self.writeRegister(self.CC1101_IOCFG0, self.DAVIS_IOCFG0) + self.writeRegister(self.CC1101_FIFOTHR, self.DAVIS_FIFOTHR) + self.writeRegister(self.CC1101_SYNC1, self.DAVIS_SYNC1) + self.writeRegister(self.CC1101_SYNC0, self.DAVIS_SYNC0) + self.writeRegister(self.CC1101_PKTLEN, self.DAVIS_PKTLEN) + self.writeRegister(self.CC1101_PKTCTRL1, self.DAVIS_PKTCTRL1) + self.writeRegister(self.CC1101_PKTCTRL0, self.DAVIS_PKTCTRL0) + self.writeRegister(self.CC1101_ADDR, self.DAVIS_ADDR) + self.writeRegister(self.CC1101_CHANNR, self.DAVIS_CHANNR) + self.writeRegister(self.CC1101_FSCTRL1, self.DAVIS_FSCTRL1) + self.writeRegister(self.CC1101_FSCTRL0, self.DAVIS_FSCTRL0) + self.writeRegister(self.CC1101_FREQ2, self.DAVIS_FREQ2) + self.writeRegister(self.CC1101_FREQ1, self.DAVIS_FREQ1) + self.writeRegister(self.CC1101_FREQ0, self.DAVIS_FREQ0) + self.writeRegister(self.CC1101_MDMCFG4, self.DAVIS_MDMCFG4) + self.writeRegister(self.CC1101_MDMCFG3, self.DAVIS_MDMCFG3) + self.writeRegister(self.CC1101_MDMCFG2, self.DAVIS_MDMCFG2) + self.writeRegister(self.CC1101_MDMCFG1, self.DAVIS_MDMCFG1) + self.writeRegister(self.CC1101_MDMCFG0, self.DAVIS_MDMCFG0) + self.writeRegister(self.CC1101_DEVIATN, self.DAVIS_DEVIATN) + self.writeRegister(self.CC1101_MCSM2, self.DAVIS_MCSM2) + self.writeRegister(self.CC1101_MCSM1, self.DAVIS_MCSM1) + self.writeRegister(self.CC1101_MCSM0, self.DAVIS_MCSM0) + self.writeRegister(self.CC1101_FOCCFG, self.DAVIS_FOCCFG) + self.writeRegister(self.CC1101_BSCFG, self.DAVIS_BSCFG) + self.writeRegister(self.CC1101_AGCCTRL2, self.DAVIS_AGCCTRL2) + self.writeRegister(self.CC1101_AGCCTRL1, self.DAVIS_AGCCTRL1) + self.writeRegister(self.CC1101_AGCCTRL0, self.DAVIS_AGCCTRL0) + self.writeRegister(self.CC1101_WOREVT1, self.DAVIS_WOREVT1) + self.writeRegister(self.CC1101_WOREVT0, self.DAVIS_WOREVT0) + self.writeRegister(self.CC1101_WORCTRL, self.DAVIS_WORCTRL) + self.writeRegister(self.CC1101_FREND1, self.DAVIS_FREND1) + self.writeRegister(self.CC1101_FREND0, self.DAVIS_FREND0) + self.writeRegister(self.CC1101_FSCAL3, self.DAVIS_FSCAL3) + self.writeRegister(self.CC1101_FSCAL2, self.DAVIS_FSCAL2) + self.writeRegister(self.CC1101_FSCAL1, self.DAVIS_FSCAL1) + self.writeRegister(self.CC1101_FSCAL0, self.DAVIS_FSCAL0) + self.writeRegister(self.CC1101_RCCTRL1, self.DAVIS_RCCTRL1) + self.writeRegister(self.CC1101_RCCTRL0, self.DAVIS_RCCTRL0) + self.writeRegister(self.CC1101_FSTEST, self.DAVIS_FSTEST) + self.writeRegister(self.CC1101_PTEST, self.DAVIS_PTEST) + self.writeRegister(self.CC1101_AGCTEST, self.DAVIS_AGCTEST) + self.writeRegister(self.CC1101_TEST2, self.DAVIS_TEST2) + self.writeRegister(self.CC1101_TEST1, self.DAVIS_TEST1) + self.writeRegister(self.CC1101_TEST0, self.DAVIS_TEST0) + self.writeBurst(self.CC1101_PATABLE, self.PA_TABLE) + self.setFrequency(self.hopIndex) + + def flush(self): + self.sidle() + self.cmdStrobe(self.CC1101_SFRX) # Flush Rx FIFO + self.cmdStrobe(self.CC1101_SFTX) # Flush Tx FIFO + self.rxBuffer = [0x00] * self.BUFFER_SIZE + self.rxBufferLength = self.rxBufferIndex = 0 + + def rx(self): + self.cmdStrobe(self.CC1101_SRX) + while (self.readStatus(self.CC1101_MARCSTATE) & 0x1F) != self.CC1101_STATE_RX: + utime.sleep_us(900) + self.rxing = 1 + self.writeRegister(self.CC1101_IOCFG0, self.DAVIS_IOCFG0) + + def hop(self): + self.hopIndex += 1 # Increment the index + if (self.hopIndex > 4): # 5 EU frequencies + self.hopIndex = 0 + self.writeRegister(self.CC1101_FSCTRL0, self.freqComp[self.hopIndex]) + self.setFrequency(self.hopIndex) # Set the frequency. + + def setFrequency(self, index): + self.sidle() + self.writeRegister(self.CC1101_FREQ2, self.FREQ_2[index]) + self.writeRegister(self.CC1101_FREQ1, self.FREQ_1[index]) + self.writeRegister(self.CC1101_FREQ0, self.FREQ_0[index]) + self.flush() + + def calcCrc(self, _buffer, length): + crc = 0x0000 + buffer_index = 0 + for i in range(length, 0, -1): + crc = (crc << 8) ^ self.CRC_TABLE[(crc >> 8) ^ (_buffer[buffer_index])] + buffer_index += 1 + return crc + + def readRssi(self): + rssi = self.readRegister(self.CC1101_RXFIFO) + if rssi >= 128: + return (rssi - 256)/2 - 74 + elif rssi < 128: + return rssi/2 -74 + else: + return False + + def readLQI(self): + return self.readRegister(self.CC1101_RXFIFO) & 0x7F + diff --git a/davis_decode.mpy b/davis_decode.mpy new file mode 100644 index 0000000000000000000000000000000000000000..d297958fbeec74dd196ec055c7a744153cee8d95 GIT binary patch literal 3139 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 4 + lsb = data & 0b00001111 + result = {"MSB": msb, "LSB": lsb} + return result + + def davis_id(self, header): + self.davis_packet_id = 0 + self.battery_low = 0 + self.unit_id = 0 + bin_header = self.byte_split(header) + self.unit_id = bin_header['LSB'] & 0b0111 + self.battery_low = bin_header['LSB'] >> 3 + self.davis_packet_id = bin_header['MSB'] + result = {"davis_id": self.unit_id, + "packet_id": self.davis_packet_id, + "bat_low": self.battery_low} + return result + + def decode_wind(self, databytes): + # wind speed in mph, i suppose. Let's convert it + wind_speed = round(float(databytes['windspeed'] * 1.60934), 1) + wind_direction_factor = round(float(360)/float(255), 1) + wind_direction = databytes['winddir'] + wind_direction = float(wind_direction) * wind_direction_factor + result = {"speed": wind_speed, "direction": wind_direction} + return result + + def decode_temp(self, temp): + temp_f = (float(temp)) / float(160) # in Fahrenheit + temp_c = round((temp_f - 32) * float(5)/float(9), 1) + result = {"celsius": temp_c, "fahrenheit": temp_f} + return result + + def decode_humidity(self, hum): + pass + + def supercap_decode(self, byte2, byte3): + cap = (byte2 << 2) + (byte3 >> 6) + result = float(cap / 100.00) + return result + + def solarvolt_decode(self, byte2, byte3): + solar = (byte2 << 1) + (byte3 >> 7) + result = float(solar) + return result + + def rain_decode(self, rain): + result = float(rain & 0x7F) + return result + + def rainrate_decode(self, byte2, byte3): + # if byte3(b2 here) is 0xFF, or 255, there is no rain + #print("b2:{} b3:{} = result:{}".format(byte2, byte3, byte2 + (byte3 >> 4 << 8))) + if byte2 == 255: + rainstate = 0 + rainrate = 0 + elif byte2 == 254: + rainstate = 1 + rainrate = 0.2 + else: + rainstate = 2 + if byte3 > 4: + rainrate = 720 / ((byte3 >> 4 << 8) + byte2) + else: + rainrate = 0 + result = {"state": float(rainstate), "rate": float(rainrate)} + #print(result) + return result + + def DecodePacket(self, packet): + # By default and most of the time, write to weather + self.write_influx_db = self.weather_influx_db + # Set all to None + self.wind = False + self.measurement = False + self.name = False + self.value = False + self.tags = False + self.wind = self.decode_wind( + {"windspeed": packet[1], "winddir": packet[2]}) + if self.davis_packet_id == 2: + # SuperCap charge 0x2 + if _DEBUG: + print('SCAP:') + supercap = self.supercap_decode( + packet[3], packet[4] + ) + if _DEBUG: + print("{}".format(supercap)) + self.write_influx_db = self.stat_influx_db + self.measurement = 'iss' + self.name = 'voltage' + self.tags = {'type': 'capacitor'} + self.value = supercap + elif self.davis_packet_id == 3: + # No fucking idea 0x3 + # {'hop':1,'h':48,'b0':6,'b1':237,'b2':255,'b3':195,'b4':135,'b5':50,'b6':110,'b7':255,'b8':255,'b9':179,'rssi':45,'lqi':0,'nxt':64,'cnt':163} + self.measurement = None + self.name = None + self.tags = None + self.value = None + + elif self.davis_packet_id == 5: + # Rainrate 0x5 + rainrate_dict = self.rainrate_decode( + packet[3], + packet[4]) + if _DEBUG: + print("RAINRATE: {}".format(rainrate_dict)) + self.measurement = 'rain' + self.name = 'value' + self.tags = {'type': 'rainrate'} + self.value = rainrate_dict['rate'] + elif self.davis_packet_id == 6: + # Sun Irradiation 0x6 (NOT ON vantage Vue) + pass + elif self.davis_packet_id == 7: + # Super Cap voltage 0x7 + solarvolt = self.solarvolt_decode( + packet[3], packet[4] + ) + if _DEBUG: + print("SOLV {}".format(solarvolt)) + self.write_influx_db = self.stat_influx_db + self.measurement = 'iss' + self.name = 'voltage' + self.tags = {'type': 'solar'} + self.value = solarvolt + elif self.davis_packet_id == 8: + # Temperature 0x8 + raw_temp = (packet[3] << 8) + packet[4] + temp_dict = self.decode_temp(raw_temp) + temp = float(temp_dict['celsius']) + if _DEBUG: + print("TEMP: {}".format(temp)) + self.measurement = 'temphumi' + self.name = 'temperature' + self.tags = {'type': 'external'} + self.value = temp + elif self.davis_packet_id == 9: + # Wind gusts 0x9 + windgust = packet[3] * 1.60934 + if _DEBUG: + print("WINDGUST: {}".format(windgust)) + self.measurement = 'wind' + self.name = 'value' + self.tags = {'type': 'windgust'} + self.value = windgust + elif self.davis_packet_id == 10: + # Humidity 0xa + raw_humidity = (((packet[4] >> 4) & 0b0011) << 8) \ + + packet[3] + humidity = round(int(raw_humidity) / float(10), 1) + if _DEBUG: + print("HUMI: {}".format(humidity)) + self.measurement = 'temphumi' + self.name = 'humidity' + self.tags = {'type': 'external'} + self.value = humidity + elif self.davis_packet_id == 14: + # Rain bucket tips 0xe + raw_rain = (packet[3]) + (packet[4] >> 7 << 8) + rain = self.rain_decode(raw_rain) + if _DEBUG: + print("RAINCOUNT: {}".format(rain)) + self.measurement = 'rain' + self.name = 'value' + self.tags = {'type': 'rain_bucket_tips'} + self.value = rain + diff --git a/inet.conf b/inet.conf new file mode 100644 index 0000000..8db3f0d --- /dev/null +++ b/inet.conf @@ -0,0 +1,20 @@ +# No spaces around '=' +# Try to avoid spaced at end or beginning of passwords. Stripping it +# One config option per line, all options need to be set. + +_SSID=YourSSID +_PASS=YourWifiPass + +# Time to keep waiting for the network to come up. Delay is 1001ms +_TIMEOUT=15 +_INFLUX_HOST=IPofTheInfluxDB +_INFLUX_PORT=PortOfTheInfluxDB + +# currently not implemented +_INFLUX_USER=InfluxUser +_INFLUX_PASS=HisPasswd + +# Names of the databases +_INF_DB_WEATHER=weather +_INF_DB_STATUS=status +_INF_DB_RAW=raw diff --git a/main.py b/main.py new file mode 100644 index 0000000..3159e0b --- /dev/null +++ b/main.py @@ -0,0 +1,89 @@ +import cc1101_davis +import davis_decode +import utime +import WiFi +gc.collect() + +_DEBUG = True + +wifi_con = WiFi.NetSet('infra') +wifi_con.readNetworkConfig() +ips = wifi_con.connectInfra( + wifi_con._SSID, + wifi_con._PASS, + wifi_con._TIMEOUT) + +if _DEBUG: + print("IPCONF: {}".format(ips)) + +davis = cc1101_davis.CC1101() +davis.setRegisters() +davis.setFrequency(davis.hopIndex) +decoder = davis_decode.davisDecoder( + wifi_con._INF_DB_WEATHER, + wifi_con._INF_DB_STATUS, + wifi_con._INF_DB_RAW) + +# Main receive loop +while True: + data_length = davis.readRegister(davis.CC1101_RXBYTES) + data = "" + if data_length & 0x7f == 15: + data = davis.readBurst(davis.CC1101_RXFIFO, 10) + rssi = davis.readRssi() + lqi = davis.readLQI() + hop = davis.hopIndex + davis.flush() + davis.hop() + davis.rx() + data_int = [davis_decode.reverseBits(int(item)) for item in data] + header = decoder.davis_id(data_int[0]) + decoder.DecodePacket(data_int) + data_prn = "{:5} {:5} {:5} {:5} {:5} {:5} {:5} {:5} {:5} {:5}".format( + data_int[0], + data_int[1], + data_int[2], + data_int[3], + data_int[4], + data_int[5], + data_int[6], + data_int[7], + data_int[8], + data_int[8],) + print("{_data:60} HOP: {_hop:<5} RSSI: {_rssi:<5} LQI: {_lqi:<5}".format( + _rssi=rssi, + _hop=hop, + _data=data_prn, + _lqi=lqi)) + if _DEBUG: + print("Header: {} Wind: {}".format(header, decoder.wind)) + print("{}: {}/{} ({})".format( + decoder.measurement, + decoder.name, + decoder.value, + decoder.tags)) + sent_ok = False + data_sent = None + try: + (sent_ok, data_sent) = davis_decode.send_to_influx( + wifi_con._INFLUX_HOST, + wifi_con._INFLUX_PORT, + decoder.write_influx_db, + wifi_con._INFLUX_USER, + wifi_con._INFLUX_PASS, + decoder.unit_id, + decoder.wind, + decoder.measurement, + decoder.name, + decoder.value, + decoder.tags) + except Exception as e: + print("ERROR: Data send 'urequest': {}".format(e)) + if _DEBUG: + if sent_ok: + print("DATA SEND: {}".format(data_sent.status_code)) + else: + print("DATA SEND FAIL: {}".format(data_sent)) + else: + utime.sleep_ms(100) + gc.collect()