pimoroni / EnviroPlus-FeatherWing

CircuitPython library for the Enviro+ FeatherWing
https://shop.pimoroni.com/products/enviro-plus-featherwing
MIT License
10 stars 11 forks source link

Conflict between Enviro+ and Adafruit Airlift Featherwing - D11 #4

Closed wildestpixel closed 1 year ago

wildestpixel commented 4 years ago

On M4 feather Express, I get a REPL output of

code.py output:
Traceback (most recent call last):
File "code.py", line 34, in <module>
ValueError: D11 in use

My Circuitpython Code is :

# 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

from pimoroni_pms5003 import PMS5003

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

pms5003 = PMS5003()
### 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.D13)
esp32_ready = DigitalInOut(board.D11)
esp32_reset = DigitalInOut(board.D12)

# 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
print("Connecting to WiFi...")
wifi.connect()
print("Connected!")

# Initialize MQTT interface with the esp interface
MQTT.set_socket(socket, esp)

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

# 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
print("Connecting 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:
    reading = pms5003.read()
    pm2 = reading.data[1]
    # Explicitly pump the message loop.
    io.loop()
    # Send a new message every 10 seconds.
    if (time.monotonic() - last) >= 10:
#        value = randint(0, 100)
        print("Publishing {0} to DemoFeed.".format(pm2))
        io.publish("DemoFeed", pm2)
        last = time.monotonic()

Code to read the PMS 2.5 data alone is fine, as is my script uploading to AdafruitIO, but the complaint is about pin D11, which is ESPBUSY or esp32_ready on the airlift.

dedSyn4ps3 commented 4 years ago

I have been having the exact same issue. I have been looking into a lot of documentation in between my jobs and school, and I think I have found in the readme for this repo a vague solution. There is a small section mentioning the screen module and how to initialize a screen object to display the plotter graphs. What we have to do it initialize the screen with the 'spi' argument included when we create the screen object. The issue is because the airlift and the enviroplus both use the SPI bus, and we need to explicitly state that they need to be sharing the bus together. I'm gonna do some coding tomorrow when I have the time, and figure out how to go about setting the airlift as the master and enviro as slave spi, or vice versa. Maybe you'll beat me to it, but that's what we need to do!

wildestpixel commented 4 years ago

I've returned the Enviroplus feathewring to Pimoroni and interfaced the PMS5003 directly via an ESP8266 (making my airlift redundant) and got my readings up on ThinkSpeak and charted back into my website or downloadable as csv.

The connection at D11 / port pin 21 is pretty hard in the .mpy side of things - if airlift is using D11 and PMS5003 from Pimoroni is using D11 your only hack is to solder esp_busy to another pin and address that in Circuitpython.

The only thing I've missed from the Enviroplus featherwing is the gas sensor as I have mems and bme280 elsewhere.

The fact that unlike adafruits circuitpython libraries, this one seems to be a one touch and like it or lump it means that I've learned to be very careful of where I'm buying things from. Some vendors maintain their libraries with customers in mind, others post a solution that seems to work at launch and don't address user feedback.

dedSyn4ps3 commented 4 years ago

That's a bummer. I started noticing the more proprietary-ish nature of the code as I've been digging through it. I was hoping it would've been more straightforward to address through circuitpython like alot of other adafruit feathers are able to do. I like having the display locally and still be able to log/view my IO dashboard when I leave and was hoping to accomplish that with this. I also have an enviro plus for my pi zero w that I really like the color display with images on it. I started trying to do the same thing with it and incorporate it with AIO but haven't been able to yet. I've tried using a couple different means of threading to run the data sync in parallel but the screen never finishes initializing and it always hangs. Not sure if I can find a different solution for it or not but I'd like to think there's a way to do it. I would've thought enough people would want to use MQTT with these products enough to where they would have dedicated modules or walkthroughs but I haven't really seen anything "official".

guru commented 4 years ago

I think because it replicates the all-singin' all-dancing Enviro+, it uses pretty much all the pins. There is one potential pin spare, but even if a pin did move, there would be overlap with the ESP32 support pins on D13 through D10, and it also has the same problem the Ultimate GPS Fwing has: Can't use it with UART-occupying Feathers like the 8266 and nRF52 https://www.adafruit.com/product/3133

Architecture-wise, Phil has strong feelings about being as Pythonic as possible, which he will have passed to Nat when developing our first Featherwing, but hopefully feedback from people using Feather day to day will help bring him around to something more embedded friendly.

dedSyn4ps3 commented 4 years ago

Also I forgot to mention that I have gotten the enviroplus featherwing to work with sending live feeds to my io dashboard. I don't use the MQTT client, I use HTTP. It all works great with the M4 Express, the only thing I hadn't gotten to work at the same time is the plotter displays on-screen.

dglaude commented 4 years ago

I have not tested with my AirLift FeatherWing (that I need to locate, it is at home... but where?).

I suggest the following hardware setup: EnviroPlus + nRF52840 + Raspberry Pi (with BT) And on the software side use BroadcastNet library: https://github.com/adafruit/Adafruit_CircuitPython_BLE_BroadcastNet

For explanation on how to use that lib, you can folow this: https://learn.adafruit.com/bluetooth-le-broadcastnet-sensor-node-raspberry-pi-wifi-bridge

When time permit, I will investigate further and maybe document this and share the code.

dedSyn4ps3 commented 4 years ago

@dglaude I definitely looked into what you mentioned and have been tinkering around with a new nRF52840 Sense Feather that I just snagged the other day. Quite an impressive and chock full little piece of kit! Can't believe I hadn't noticed it until now!

@wildestpixel this post is for you though my dude. I know there has been some issues with the D11 pin conflict and mentions of returned enviro-feathers, but I love these little guys too much to give up! Haha...anyways, I made a pull request for the main Enviro+ Python repo and included a script based off an Adafruit example using one of their sensor boards, that I was able to get to work with my enviro-pi to send live sensor data to AIO while still running the cool little weather-and-light display.

It's late and I've had a long ass night at work but had to give my featherwing a little attention before bed, and so far I have managed to initialize the screen, display the REPL, connect to my wifi, pull my aio feed, AND send sensor data, all in the REPL running individual lines of my code. It's only a small step for sure, but I have not had any SPI conflicts as of yet as they are still sharing the bus and working fine. Tomorrow I will see about displaying more than just the REPL and see about drawing the readings on screen while updating the feed and see where that gets me. There may be hope left after all gents!

20200620_000522

dedSyn4ps3 commented 4 years ago

Another quick update because my ass just couldn't wait to check it out and see! 20200620_002834 1

dedSyn4ps3 commented 4 years ago

As the pics above kind of show, I have been able to confirm a constant feed update to my adafruit io dashboard now using my new code file. I was thinking about making a pull request to include it, but right now I have only got it working with the bme280 sensor on the board. I'm working today on getting the plotters to show on screen as well, and maybe try and add the page turner for OX/CO2 and other displays.

One small step at a time, but it's working now!

wildestpixel commented 4 years ago

It will work with anything other than PMS5003 as the conflict is board.D11, hence That pin vs esp32_ready. Getting bme280 data onto Adafruit IO isn’t the subject of this git issue or what it tries to resolve.

dedSyn4ps3 commented 4 years ago

The esp_reset is not necessarily needed, did you try assigning that to None and using that pin for the esp_ready and let the PMS5003 use the D11? I don't have one at the moment so I can't exactly try or else I would. I just didn't notice if you had tried that or not.

As for the git issue, it's titled as 'Conflict between Enviro+ and Adafruit Airlift Featherwing - D11' which was the exact issue I was having trying to sync up with aio using my featherwing. My issue involved D11, your issue involved D11. As far as I'm concerned, we both had valid issues in regards to what your title said....bud ;)

dglaude commented 3 years ago

For Wifi connectivity while using all the feature of Enviro+, I believe the ESP32S2 based Feather (like Feather S2 from unexpected maker) will make that easier as they have build-in Wifi and do not require an AirLift.

Gadgetoid commented 1 year ago

As far as I'm aware there's no action we can take here. Putting a line under this. Feel free to re-open if you feel it necessary.