PyBytes Firmware OTA update failed?
I logged into Pybytes to look at my LoPy4 Signals compared to the data shown in TTN. It's connected to a WIFI network but also pushing LoRa data in US915 databand. I noticed that the signals values were all screwed up. Previously last night, everything looked good. Looking at the data values, I discovered that Signals had somehow changed from big to little-endian so a value I believe to be 3(?) was now displayed as 285,212,672 (Hex 1100 0000) all 5 signals I had were affected by this.
I tried to go in and look at the code, but the unit said "Offline". Odd, because Signals was being updated on 5 minute intervals, as was TTN. I watched several 5 minute update intervals succeed.
On the Settings page, I noticed it showed a Firmware Update was available. I had 1.18.1r10 loaded and it reported that 1.18.2 was available. I attempted the update. It said "updating firnware" for about 3-4 minutes, then finally reported back it failed. TTN stopped receiving frames as did Signals after this. It's 50 miles away so I probably won't get to it until maybe late tonight or tomorrow.
I wasn't using any deep sleep routines, just time.sleep(300) at the end of my loop as I was still figuring out code issues.
I attached my code in case someone suggests that it could be the cause of FOTA failure..
# main.py -- put your code here! from network import LoRa import socket import ubinascii import struct import time import os import math import abpkeys import ustruct from machine import UART, I2C, Pin #from machine import I2C, Pin #added for si7021 rh sensor from si7021 import SI7021 #added for si7021 rh sensor uart = UART(1, 9600) # init with given baudrate uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters #initialize i2c to link to rh sensor i2c = I2C(0, pins=("P9","P10")) i2c.init(I2C.MASTER, baudrate=9600) sensor = SI7021(i2c=i2c) # Initialise LoRa in LORAWAN mode. # Please pick the region that matches where you are using the device: # Asia = LoRa.AS923 # Australia = LoRa.AU915 # Europe = LoRa.EU868 # United States = LoRa.US915 lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915) # create an ABP authentication params #my keys are stored in abpkeys.py then linked here so I have the same source running #on multiple devices dev_addr=abpkeys.dev_addr nwk_swkey=abpkeys.nwk_swkey app_swkey=abpkeys.app_swkey #dev_addr = struct.unpack(">l", ubinascii.unhexlify('xxxxxxxx')) #nwk_swkey = ubinascii.unhexlify('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') #app_swkey = ubinascii.unhexlify('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') for i in range(0, 71): lora.remove_channel(i) print('Removed default channels') time.sleep(1) # Set US ISM 915 channel plan for TTN US lora.add_channel(0, frequency=903900000, dr_min=0, dr_max=3) lora.add_channel(1, frequency=904100000, dr_min=0, dr_max=3) lora.add_channel(2, frequency=904300000, dr_min=0, dr_max=3) lora.add_channel(3, frequency=904500000, dr_min=0, dr_max=3) lora.add_channel(4, frequency=904700000, dr_min=0, dr_max=3) lora.add_channel(5, frequency=904900000, dr_min=0, dr_max=3) lora.add_channel(6, frequency=905100000, dr_min=0, dr_max=3) lora.add_channel(7, frequency=905300000, dr_min=0, dr_max=3) #channel 8: 903900000 hz min_dr 0 max_dr 3 #channel 9: 904100000 hz min_dr 0 max_dr 3 #channel 10: 904300000 hz min_dr 0 max_dr 3 #channel 11: 904500000 hz min_dr 0 max_dr 3 #channel 12: 904700000 hz min_dr 0 max_dr 3 #channel 13: 904900000 hz min_dr 0 max_dr 3 #channel 14: 905100000 hz min_dr 0 max_dr 3 #channel 15: 905300000 hz min_dr 0 max_dr 3 print('US channels set') time.sleep(1) print('restoring LoRa NVRAM') lora.nvram_restore() print('Joining LoRa via ABP') # join a network using ABP (Activation By Personalization) lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) # create a LoRa socket s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # set the LoRaWAN data rate s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3) #Let's check whether the si7021 is attached and enable further code if it responds print('check si7021 serial') si7021presence=True temperature=-255 print(i2c.scan()) temperature=int(sensor.temperature()) relativehumid=int(sensor.humidity()) dewpoint=int(sensor.dew_point()) print('Temp',temperature) print('RH%',relativehumid) print('Dewpoint',dewpoint) try: temperature=int(sensor.temperature()) print('temperature = ',temperature) except NameError as msg: print(msg) si7021presence=False if( temperature !=-255): print('temperature reported = ',temperature) print('si7021 presence = ',si7021presence) #The first 5 seconds of dust data always seems irregular, so let's delay and clear the buffer data = uart.readall() time.sleep(10) data= uart.readall() time.sleep(1)# then give it another second for the next good byte to come in. while (1): readytosend=False print('polling Dust Sensor') data = uart.readall()# get everythitng from the serial buffer if data is not None:#make sure it'st not an empty buffer bytestream=data.split(b'BM')[0:31]# HPMA sends 32 byte packets that start with \x42\x4D ('BM') if len(bytestream)==30:#check tthat we actually got 30 bytes (excluding the data we split out) if bytestream[0:2]==b'\x00\x1c':#HPMA packet is always 28 data bytes(excluding start header and checksum) checksum=143#since split command removed the \x42\x4D, add them back to get correct checksum validated=0 for i in range(0,28): checksum+=bytestream[i]#cycle thru the data values and add them up validated=int(bytestream)*256+int(bytestream)#read checksum bytes from packet and make them a 2-byte integer if checksum==validated:# both values should match, else we have a corrupt packet pm25=int(bytestream)*256+int(bytestream)#these two bytes represent the particulate detected that's 2.5um large pm10=int(bytestream)*256+int(bytestream)#these two bytes represent the particulate detected that's 10um large print('pm2.5 = ',pm25) print('pm10 = ',pm10) readytosend=True else: print('checksum failed') else: print('invalid packet length') else: print('incomplete packet') if(si7021presence==True): print(i2c.scan()) print('poll temp') temperature=int(sensor.temperature()) print('poll RH') relativehumid=int(sensor.humidity()) print('poll Dew') dewpoint=int(sensor.dew_point()) if readytosend==True: # make the socket blocking # (waits for the data to be sent and for the 2 receive windows to expire) s.setblocking(True) print("Sending data!") # send some data # s.send(bytes([0x01, 0x02, 0x03])) #if(si7021presence==True): tempstruct=((ustruct.pack('>H',temperature))) rhstruct=((ustruct.pack('>H',relativehumid))) dewstruct=((ustruct.pack('>H',dewpoint))) s.send(bytes([bytestream, bytestream, bytestream,bytestream,tempstruct,tempstruct,rhstruct,rhstruct,dewstruct,dewstruct]))#,relativehumid,dewpoint])) #else: # s.send(bytes([bytestream, bytestream, bytestream,bytestream])) pybytes.send_virtual_pin_value(False, 0, (bytestream<<8)+bytestream) time.sleep(1) pybytes.send_virtual_pin_value(False, 1, (bytestream<<8)+bytestream) time.sleep(1) pybytes.send_virtual_pin_value(False, 2, temperature) time.sleep(1) pybytes.send_virtual_pin_value(False, 3, relativehumid) time.sleep(1) pybytes.send_virtual_pin_value(False, 4, dewpoint) time.sleep(1) #pybytes.send_virtual_pin_value(False,2,100) #time.sleep(10) print('saving LoRa NVRAM') lora.nvram_save() # make the socket non-blocking # (because if there's no data received it will block forever...) s.setblocking(False) print("receiving data!") # get any data received (if any...) data = s.recv(64) print(data) print("Go to sleep 5 minutes!") time.sleep(300)```
Whilst not super convinient as its 50 miles from you. If you can reclaim it and flash https://forum.pycom.io/topic/4185/new-pybytes-firmware-1-18-1-r9-experimental-lte-support manually
Is should solve the issue with corrupted / weird data from Lora.
I was able to get it back online by unplugging and replugging power. The firmware update didn't take. I tried it a second time, and that took. But now have a bunch of corrupted signals data..