I get the errors below in my console after a sending notes every hour for a few hours. Has anyone seen this before? This may be because I’m checking the signal strength at the same time I’m trying to send (doh!)
cardDetails = card.Transaction({“req”: “card.wireless”})
cardSignal = cardDetails[“net”][“bars”]
Using transaction timeout of 30 seconds.
{“req”:“card.wireless”,“crc”:“000e:3ce09784”}
Resetting Notecard I2C communications.
Sequence number mismatch. Expected 000e, received 000E.
CRC error on response from Notecard.
Sequence number mismatch. Expected 000e, received 000E.
CRC error on response from Notecard.
Sequence number mismatch. Expected 000e, received 000E.
CRC error on response from Notecard.
Sequence number mismatch. Expected 000e, received 000E.
CRC error on response from Notecard.
Sequence number mismatch. Expected 000e, received 000E.
CRC error on response from Notecard.
Prior to this commit, the hex strings for the CRC and sequence number from the Notecard were compared against hex strings computed by the host. If the casing of the hex digits differs between host and Notecard, there can be false CRC errors.
Apologies for the inconvenience. If you pull the latest note-python code from the main branch, the problem should resolve.
We will be releasing a new note-python version with this fix soon.
Thank you for the response, I moved to the new library, I am now seeing errors like the following when sending notes to the hub, I will try to investigate more this week:
Using transaction timeout of 30 seconds. [Errno 5] Input/output error Resetting Notecard I2C communications. Failed to acquire I2C lock
I have two IF statements in the main while loop, one calling the AHT every few minutes, the other publishing the sensor data every few hours. When the sensor publishes via this code I sometimes get the “Failed to acquire I2C lock” error. Is there an easy way to check if the i2c port is locked before. Do you think this is because I’m checking the hub for new notes right after the send?:
try:
req = {"req": "note.add"}
req["file"] = "data.qo"
req["sync"] = True
req["body"] = {json body...}
rsp = card.Transaction(req)
#Sync with Hub to collect any notes
req = {"req": "note.get"}
req["file"] = "my-inbound.qi"
req["delete"] = True
rsp = card.Transaction(req)
if "body" in rsp:
rspBody = rsp["body"]
...
except Exception as error:
print('Cannot Connet to HUB', error)
message = "Cannot Connect to HUB!"
Is there an easy way to check if the i2c port is locked before.
I’m not seeing anything in the CircuitPython API docs that’ll give you that information directly. We are using the try_lock method in note-python. We try to acquire the lock 5 times, pausing for 100 ms between tries. If we still can’t get the lock after that, then we raise the exception you’re seeing (“Failed to acquire I2C lock.”).
Do you think this is because I’m checking the hub for new notes right after the send?
That should not matter.
When the sensor publishes via this code I sometimes get the “Failed to acquire I2C lock” error.
Just to confirm, this only happens sometimes? Not always?
I don’t have the exact same hardware as you, but I’ll try to reproduce the problem on my end.
I’m using the following script to communicate with both the Notecard and the BME280 board over the same I2C bus, and I’m not running into that locking error you’re seeing. I’m also using a Blues Swan as opposed to an RPi Pico.
import notecard
import board
import adafruit_bme280.advanced as adafruit_bme280
import time
port = board.I2C()
card = notecard.OpenI2C(port, 0, 0, debug=True)
bme280 = adafruit_bme280.Adafruit_BME280_I2C(port)
# Change this to match the location's pressure (hPa) at sea level
bme280.sea_level_pressure = 1013.25
bme280.mode = adafruit_bme280.MODE_NORMAL
bme280.standby_period = adafruit_bme280.STANDBY_TC_500
bme280.iir_filter = adafruit_bme280.IIR_FILTER_X16
bme280.overscan_pressure = adafruit_bme280.OVERSCAN_X16
bme280.overscan_humidity = adafruit_bme280.OVERSCAN_X1
bme280.overscan_temperature = adafruit_bme280.OVERSCAN_X2
# The sensor will need a moment to gather initial readings
time.sleep(1)
req = {"req": "hub.set"}
req["product"] = "com.blues.hroche:blah"
req["mode"] = "continuous"
card.Transaction(req)
while True:
print("\nTemperature: %0.1f C" % bme280.temperature)
print("Humidity: %0.1f %%" % bme280.relative_humidity)
print("Pressure: %0.1f hPa" % bme280.pressure)
print("Altitude = %0.2f meters" % bme280.altitude)
req = {"req": "note.add"}
req["sync"] = True
req["file"] = "debug.qo"
req["body"] = {"temp": bme280.temperature, "humidity": bme280.relative_humidity}
card.Transaction(req)
time.sleep(10)
If possible, please share the full source code of your project. That’ll help me spot any differences and possibly reproduce the error on my end.
Thank you so much for your help with this Hayden, really appreciate it! My code below for rasberry pi pico. I recently noticed that I can reproduce the issue 100% of the time if I set my report_INTERVAL_SEC variable to 60 minutes which defines when to publish messages to the notehub, if it’s less than that(5 or 10 minutes) everything works fine…very strange! Appreciate any guidance you can provide.
import time
import board
import digitalio
import notecard
import busio
import adafruit_ahtx0
from analogio import AnalogIn
import microcontroller
import watchdog
import time
# Watchdog settings
wdt = microcontroller.watchdog
wdt.timeout= 8 # Set a timeout of the watchdog , max 8 seconds
#Note Card Settings
productUID = "xxxxx"
port = busio.I2C(board.GP1, board.GP0)
card = notecard.OpenI2C(port, 0, 0, debug=True)
#Temp/Humidity Sensor Settings
sensor = adafruit_ahtx0.AHTx0(port)
#LED Light Settings
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
# Pin to detect USB Power
powerPin = digitalio.DigitalInOut(board.GP24)
# Starting Variables
# Sync outbound notes to Notehub a max of every 1 minutes if notes are waiting to go out.
outbound_SYNC_MINS = 1
# Sync inbound notes to Notehub a minimum of every 12 hours
inbound_SYNC_MINS = (12*60)
# Read temp sensor every 60 seconds.
sensor_READ_INTERVAL_SEC = (60)
# Publish outbound notes every 1 hour
report_INTERVAL_SEC = (1*60*60)
# Default Temp
temperature = 20
humidity = 30
power = True
voltage = 0
last_REPORT_SEND_TIME = 0
last_SENSOR_READ_TIME = 0 # use 0 in production 0
# intialize notecard
req = {"req": "hub.set"}
req["product"] = productUID
req["mode"] = "periodic"
req["outbound"] = outbound_SYNC_MINS
req["inbound"] = inbound_SYNC_MINS
rsp = card.Transaction(req)
#Setup pin to read voltage
analog_in = AnalogIn(board.A3)
def get_voltage(pin):
return (pin.value * 3.3) / 65536
def readSensors():
wdt.feed()
global temperature
global humidity
global power
global voltage
global last_SENSOR_READ_TIME
global message
last_SENSOR_READ_TIME = time.time()
try:
# record last time sensors were read
print("read started...")
temperature = sensor.temperature
humidity = sensor.relative_humidity
power = powerPin.value
voltage = get_voltage(analog_in)
except Exception as error:
print('Cannot Read read AHT20', error)
message = "Cannot read AHT20"
# function to send data to the notehub
def publishSystemData(reason, action):
wdt.feed()
global message
global last_REPORT_SEND_TIME
try:
print("publish started")
#add in other data to send
req = {"req": "note.add"}
req["file"] = "data.qo"
req["sync"] = True
req["body"] = {"temperature": temperature,
"humidity": humidity, "power": power, }
rsp = card.Transaction(req)
if(rsp):
last_REPORT_SEND_TIME = time.time() # update last time data sync was done
getDataFromHub()
message = "GREEN"
except Exception as error:
print('Cannot Connect to HUB', error)
last_REPORT_SEND_TIME = last_REPORT_SEND_TIME+(60*10) # retry in 10 minutes
message = "Cannot Connect to HUB!"
# function to get data from the notehub
def getDataFromHub():
wdt.feed()
#fetch and new notes on routine sync
try:
req = {"req": "note.get"}
req["file"] = "my-inbound.qi"
req["delete"] = True
rsp = card.Transaction(req)
if "body" in rsp:
.....
else:
print("no new notes from hub")
message = "GREEN"
except:
print('Cannot Get Notes from HUB')
message = "Cannot Get Notes from HUB!"
while True: # main loop
wdt.mode = watchdog.WatchDogMode.RESET
wdt.feed()
# read sensors if last sensor read time greater than read interval
if (time.time()-last_SENSOR_READ_TIME >= sensor_READ_INTERVAL_SEC):
print("reading sensors..."+str(time.time()))
led.value = True
time.sleep(0.5)
led.value = False
readSensors()
time.sleep(4)
wdt.feed()
# Send Data to notehub if last report time greater than report interval
if (time.time()-last_REPORT_SEND_TIME > report_INTERVAL_SEC or last_REPORT_SEND_TIME == 0):
print("publishing data..."+str(time.time()))
publishSystemData("normal publish, lastsend: "+str(last_REPORT_SEND_TIME), "")
I’m wondering if this has something to do with the watchdog timer. Looking back to this error message you sent earlier:
Using transaction timeout of 30 seconds. [Errno 5] Input/output error Resetting Notecard I2C communications. Failed to acquire I2C lock
It seems like the watchdog might be expiring in the middle of this transaction. When I’ve seen something like “[Errno 5] Input/output error” in the past, it indicates that the connection to the MCU was lost, which could be indicative of the MCU resetting itself.
Can you try commenting out all the watchdog code and see if the problem goes away? Or setting the watchdog timeout to a larger value, perhaps a minute?
Thank you for the help Hayden. The issue seems to go away it I add a few seconds of offset between these two variables.
# Read temp sensor every 60 seconds.
sensor_READ_INTERVAL_SEC = (60)
# Publish outbound notes every 1 hour
report_INTERVAL_SEC = (1*60*60)
It seems the sleep variable does not actually delay the running of the if statements when inside the first if statement so they must have been firing at the exact same times. I’d assume everything fires top down but looks like everything is going at the same time(I think). Anyway working now, thanks again!