0

Pyportal SPI problems
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Pyportal SPI problems

by seaser74 on Sun Jan 26, 2020 9:10 am

Hello,

I am working on this project: https://learn.adafruit.com/pyportal-mqtt-sensor-node-control-pad-home-assistant
When I copy the code from this project to my Pyportal(MicroPython 4.1.2) it runs fine for a while but then it crashes after a while. it can run for 5 minutes or maybee a couple of hours but it crashes every time with the following error:

Code: Select all | TOGGLE FULL SIZE
Traceback (most recent call last):
  File "code.py", line 225, in <module>
  File "adafruit_minimqtt.py", line 636, in loop
  File "adafruit_minimqtt.py", line 656, in _wait_for_msg
UnicodeError:


To narrow it down, I am trying to make this example MQTT program work:

Code: Select all | TOGGLE FULL SIZE
import board
import busio
from digitalio import DigitalInOut
import neopixel
from adafruit_esp32spi import adafruit_esp32spi
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
import time
 
from adafruit_minimqtt import MQTT
 
### WiFi ###
 
# Get wifi details and more from a secrets.py file
try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise
 
# If you are using a board with pre-defined ESP32 Pins:
esp32_cs = DigitalInOut(board.ESP_CS)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)
 
# If you have an externally connected ESP32:
# esp32_cs = DigitalInOut(board.D9)
# esp32_ready = DigitalInOut(board.D10)
# esp32_reset = DigitalInOut(board.D5)
 
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
"""Use below for Most Boards"""
status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards
"""Uncomment below for ItsyBitsy M4"""
# status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2)
# Uncomment below for an externally defined RGB LED
# import adafruit_rgbled
# from adafruit_esp32spi import PWMOut
# RED_LED = PWMOut.PWMOut(esp, 26)
# GREEN_LED = PWMOut.PWMOut(esp, 27)
# BLUE_LED = PWMOut.PWMOut(esp, 25)
# status_light = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED)
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)
 
### Topic Setup ###
 
# MQTT Topic
# Use this topic if you'd like to connect to a standard MQTT broker
mqtt_topic = 'test/topic'
mqtt_time = 'pyportal/time'
 
# Adafruit IO-style Topic
# Use this topic if you'd like to connect to io.adafruit.com
# mqtt_topic = 'aio_user/feeds/temperature'


motion = 0

 
### Code ###
 
# Define callback methods which are called when events occur
# pylint: disable=unused-argument, redefined-outer-name
def connect(client, userdata, flags, rc):
    # This function will be called when the client is connected
    # successfully to the broker.
    print('Connected to MQTT Broker!')
    print('Flags: {0}\n RC: {1}'.format(flags, rc))
 
def disconnect(client, userdata, rc):
    # This method is called when the client disconnects
    # from the broker.
    print('Disconnected from MQTT Broker!')
 
def subscribe(client, userdata, topic, granted_qos):
    # This method is called when the client subscribes to a new feed.
    print('Subscribed to {0} with QOS level {1}'.format(topic, granted_qos))
 
def unsubscribe(client, userdata, topic, pid):
    # This method is called when the client unsubscribes from a feed.
    print('Unsubscribed from {0} with PID {1}'.format(topic, pid))
 
def publish(client, userdata, topic, pid):
    # This method is called when the client publishes data to a feed.
    print('Published to {0} with PID {1}'.format(topic, pid))
   
def message(client, topic, message):
    """Method callled when a client's subscribed feed has a new
    value.
    :param str topic: The topic of the feed with a new value.
    :param str message: The new value
    """
    #print('New message on topic {0}: {1}'.format(topic, message))
    if topic == "pyportal/time":
        print(message)
    if topic == "test/topic":
        if message == "1":
            print('backlight aan')
            client.publish(mqtt_topic, 'nummer 1')
        if message == "0":
            print('backlight uit')
            client.publish(mqtt_topic, 'nummer 0')
   
 
# Connectting to WiFi
wifi.connect()
 
# Set up a MiniMQTT Client
client = MQTT(socket,
            broker = secrets['broker'],
            port = 1883,
            network_manager = wifi,
            log = True)
                   
# Connect callback handlers to client
client.on_connect = connect
client.on_disconnect = disconnect
client.on_subscribe = subscribe
client.on_unsubscribe = unsubscribe
client.on_publish = publish
client.on_message = message

 
print('Attempting to connect to %s'%client.broker)
client.connect()
 
print('Subscribing to %s'%mqtt_topic, mqtt_time)
client.subscribe(mqtt_topic)
client.subscribe(mqtt_time)
 
print('Publishing to %s'%mqtt_topic)
client.publish(mqtt_topic, 'Hello Broker!')
 
#print('Unsubscribing from %s'%mqtt_topic)
#client.unsubscribe(mqtt_topic)
 
# print('Disconnecting from %s'%client.broker)
# client.disconnect()

# Start a blocking message loop
# If you only want to listen to incoming messages,
# you'll want to loop_forever as it handles network reconnections
# No code below this line will execute.
while True:
    client.loop()

 


This also crashes with a somehow similar error:

Code: Select all | TOGGLE FULL SIZE
Traceback (most recent call last):
  File "code.py", line 146, in <module>
  File "adafruit_minimqtt.py", line 636, in loop
  File "adafruit_minimqtt.py", line 642, in _wait_for_msg
  File "adafruit_esp32spi/adafruit_esp32spi_socket.py", line 137, in recv
  File "adafruit_esp32spi/adafruit_esp32spi_socket.py", line 173, in available
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 676, in socket_available
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 326, in _send_command_get_response
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 315, in _wait_response_cmd
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 299, in _wait_response_cmd
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 278, in _wait_spi_char
RuntimeError: Timed out waiting for SPI char


As far as I can see there is nothing wrong with the code, to me it looks the problem is caused by the adafruit_esp32spi library or module. I have absolutly no idea how to fix this, so any hints or help would be greatly appreciated!

seaser74
 
Posts: 7
Joined: Sun Jan 19, 2020 4:52 pm

Re: Pyportal SPI problems

by adafruit_support_carter on Mon Jan 27, 2020 4:07 pm

When I copy the code from this project to my Pyportal(MicroPython 4.1.2)

Do you mean CircuitPython 4.1.2?

Let's make sure your basic wifi and internet connection works. Try running the example here:
https://learn.adafruit.com/adafruit-pyp ... et-connect
and make sure that works as expected.

adafruit_support_carter
 
Posts: 14475
Joined: Tue Nov 29, 2016 2:45 pm

Re: Pyportal SPI problems

by seaser74 on Tue Jan 28, 2020 10:39 am

Sorry your right, Iment CircuitPython 4.1.2.
Did as you suggested and basic internet and WIFI seems to work!

Although I did know that already, because my script works fine for a random amount of time, then it crashes..

seaser74
 
Posts: 7
Joined: Sun Jan 19, 2020 4:52 pm

Re: Pyportal SPI problems

by adafruit_support_carter on Tue Jan 28, 2020 1:30 pm

It seems like some sort of intermittent network issue. When it occurs, the responses are becoming something other than expected, and it throws the exceptions.

Can you correlate the issue to anything?

adafruit_support_carter
 
Posts: 14475
Joined: Tue Nov 29, 2016 2:45 pm

Re: Pyportal SPI problems

by seaser74 on Wed Jan 29, 2020 1:15 pm

No, unfortunally not.
I've tried this demo MQTT code witch connect to the adafruit MQTT server instead of my own mosquitto server:

Code: Select all | TOGGLE FULL SIZE
# Example of using the Adafruit IO CircuitPython MQTT client
# to subscribe to an Adafruit IO feed and publish random data
# to be received by the feed.
#
# Example by Tony DiCola for Adafruit Industries
# Modified by Brent Rubell for Adafruit Industries, 2019
import time
from random import randint


import board
import busio
from adafruit_esp32spi import adafruit_esp32spi
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from digitalio import DigitalInOut
import neopixel
from adafruit_io.adafruit_io import IO_MQTT
from adafruit_minimqtt import MQTT

### WiFi ###

# Get wifi details and more from a secrets.py file
try:
    from secrets import secrets
except ImportError:
    print("WiFi secrets are kept in secrets.py, please add them there!")
    raise

# If you are using a board with pre-defined ESP32 Pins:
esp32_cs = DigitalInOut(board.ESP_CS)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)

# If you have an externally connected ESP32:
# esp32_cs = DigitalInOut(board.D9)
# esp32_ready = DigitalInOut(board.D10)
# esp32_reset = DigitalInOut(board.D5)

spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
"""Use below for Most Boards"""
status_light = neopixel.NeoPixel(
    board.NEOPIXEL, 1, brightness=0.2
)  # Uncomment for Most Boards
"""Uncomment below for ItsyBitsy M4"""
# status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2)
# Uncomment below for an externally defined RGB LED
# import adafruit_rgbled
# from adafruit_esp32spi import PWMOut
# RED_LED = PWMOut.PWMOut(esp, 26)
# GREEN_LED = PWMOut.PWMOut(esp, 27)
# BLUE_LED = PWMOut.PWMOut(esp, 25)
# status_light = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED)
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)

# Define callback functions which will be called when certain events happen.
# pylint: disable=unused-argument
def connected(client):
    # Connected function will be called when the client is connected to Adafruit IO.
    # This is a good place to subscribe to feed changes.  The client parameter
    # passed to this function is the Adafruit IO MQTT client so you can make
    # calls against it easily.
    print("Connected to Adafruit IO!  Listening for DemoFeed changes...")
    # Subscribe to changes on a feed named DemoFeed.
    client.subscribe("DemoFeed")

def subscribe(client, userdata, topic, granted_qos):
    # This method is called when the client subscribes to a new feed.
    print('Subscribed to {0} with QOS level {1}'.format(topic, granted_qos))

def unsubscribe(client, userdata, topic, pid):
    # This method is called when the client unsubscribes from a feed.
    print('Unsubscribed from {0} with PID {1}'.format(topic, pid))

# pylint: disable=unused-argument
def disconnected(client):
    # Disconnected function will be called when the client disconnects.
    print("Disconnected from Adafruit IO!")

# pylint: disable=unused-argument
def message(client, feed_id, payload):
    # Message function will be called when a subscribed feed has a new value.
    # The feed_id parameter identifies the feed, and the payload parameter has
    # the new value.
    print("Feed {0} received new value: {1}".format(feed_id, payload))


# Connect to WiFi
wifi.connect()

# Initialize a new MQTT Client object
mqtt_client = MQTT(
    socket=socket,
    broker="io.adafruit.com",
    username=secrets["aio_user"],
    password=secrets["aio_key"],
    network_manager=wifi
)

# Initialize an Adafruit IO MQTT Client
io = IO_MQTT(mqtt_client)

# Connect the callback methods defined above to Adafruit IO
io.on_connect = connected
io.on_disconnect = disconnected
io.on_subscribe = subscribe
io.on_unsubscribe = unsubscribe
io.on_message = message

# Connect to Adafruit IO
io.connect()

# Below is an example of manually publishing a new  value to Adafruit IO.
last = 0
print("Publishing a new message every 10 seconds...")
while True:
    # Explicitly pump the message loop.
    io.loop()
    # Send a new message every 10 seconds.
    if (time.monotonic() - last) >= 5:
        value = randint(0, 100)
        print("Publishing {0} to DemoFeed.".format(value))
        io.publish("DemoFeed", value)
        last = time.monotonic()


# You can also call loop_blocking if you only want to receive values.
# NOTE: If uncommented, no code below this line will run.
o.loop_blocking()


But still it trows back the same error.


Code: Select all | TOGGLE FULL SIZE
Feed DemoFeed received new value: 46
Traceback (most recent call last):
  File "code.py", line 120, in <module>
  File "adafruit_io/adafruit_io.py", line 216, in loop
  File "adafruit_minimqtt.py", line 636, in loop
  File "adafruit_minimqtt.py", line 642, in _wait_for_msg
  File "adafruit_esp32spi/adafruit_esp32spi_socket.py", line 137, in recv
  File "adafruit_esp32spi/adafruit_esp32spi_socket.py", line 173, in available
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 676, in socket_available
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 326, in _send_command_get_response
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 315, in _wait_response_cmd
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 299, in _wait_response_cmd
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 278, in _wait_spi_char
RuntimeError: Timed out waiting for SPI char



I am starting to think the ESP32 from this Pyportal is broken..

seaser74
 
Posts: 7
Joined: Sun Jan 19, 2020 4:52 pm

Re: Pyportal SPI problems

by adafruit_support_carter on Wed Jan 29, 2020 2:38 pm

I'd think if there was a hardware issue, even the basic internet check would have issues.

You're using the latest CP firmware - 4.1.2, so that good. What about the libraries? When was the last time you refreshed those to latest bundle versions?

adafruit_support_carter
 
Posts: 14475
Joined: Tue Nov 29, 2016 2:45 pm

Re: Pyportal SPI problems

by seaser74 on Sun Feb 23, 2020 5:54 am

Sorry for the late reply, but problem is still at hand.

At the moment I am using the 20200215 library's. But also with this the code only runs for a few hours before it crashes..
The code seems to crash on the part that waits for incoming messages.
If I completly erase this part of the code, it runs fine.
Code: Select all | TOGGLE FULL SIZE
def message(client, topic, message):
    """Method callled when a client's subscribed feed has a new
    value.
    :param str topic: The topic of the feed with a new value.
    :param str message: The new value
    """
    print('New message on topic {0}: {1}'.format(topic, message))
    if topic == "pyportal/temp":
        temp_label.text = (message)
    if topic == "pyportal/solar":
        solar_label.text = (message)


But for me the most interesting thing about the pyportal is that it can display sensor values from homeassistant..

seaser74
 
Posts: 7
Joined: Sun Jan 19, 2020 4:52 pm

Re: Pyportal SPI problems

by adafruit_support_carter on Mon Feb 24, 2020 11:57 am

How are you powering the PyPortal? Wondering if there's a chance this is power related somehow?

adafruit_support_carter
 
Posts: 14475
Joined: Tue Nov 29, 2016 2:45 pm

Re: Pyportal SPI problems

by seaser74 on Tue Feb 25, 2020 5:02 am

At the moment it is connected to my mac. I also tried the iPad charger(2,1A), but same issue occured...
Strangest thing is that the code is running fine for the last 48hours! The exact same code crashed 2 times before after a few hours. I havent changed anything just hit the reset button on the back, and now it runs for 48hours...

seaser74
 
Posts: 7
Joined: Sun Jan 19, 2020 4:52 pm

Re: Pyportal SPI problems

by seaser74 on Tue Feb 25, 2020 7:00 am

I think I jingxt it.. pyportal crashed just after i wrote the previous post.

Code: Select all | TOGGLE FULL SIZE
Traceback (most recent call last):
  File "code.py", line 272, in <module>
  File "adafruit_minimqtt.py", line 636, in loop
  File "adafruit_minimqtt.py", line 642, in _wait_for_msg

seaser74
 
Posts: 7
Joined: Sun Jan 19, 2020 4:52 pm

Re: Pyportal SPI problems

by adafruit_support_carter on Tue Feb 25, 2020 11:29 am

Do you know how to add a try/except block to catch that exception? If so, trying doing that and use it as a way to just continue and retry to transfer.

adafruit_support_carter
 
Posts: 14475
Joined: Tue Nov 29, 2016 2:45 pm

Re: Pyportal SPI problems

by seaser74 on Tue Feb 25, 2020 2:05 pm

I know about the try/except block, but haven't used it before. I am a novice in python.

Do you think this works:

Code: Select all | TOGGLE FULL SIZE
def message(client, topic, message):
    try:
        print('New message on topic {0}: {1}'.format(topic, message))
        if topic == "pyportal/temp":
            temp_label.text = (message)
        if topic == "pyportal/solar":
            solar_label.text = (message)
    except:
        pass


Thanx so far!

seaser74
 
Posts: 7
Joined: Sun Jan 19, 2020 4:52 pm

Re: Pyportal SPI problems

by adafruit_support_carter on Tue Feb 25, 2020 8:58 pm

That's the basic idea. It's better to catch the specific exception though. And so you know that it happened, maybe add a print statement. Something like this:
Code: Select all | TOGGLE FULL SIZE
def message(client, topic, message):
    try:
        print('New message on topic {0}: {1}'.format(topic, message))
        if topic == "pyportal/temp":
            temp_label.text = (message)
        if topic == "pyportal/solar":
            solar_label.text = (message)
    except RuntimeError:
        print("Error. Retrying...")

adafruit_support_carter
 
Posts: 14475
Joined: Tue Nov 29, 2016 2:45 pm

Please be positive and constructive with your questions and comments.