From 32d88ff7fb891e8730ac3db001548eb4b6deba19 Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Tue, 30 Nov 2021 09:58:25 -0500 Subject: [PATCH] Add Feather ESP32-S2 examples. --- .pylintrc | 2 +- Adafruit_Feather_ESP32-S2/Analog_In/code.py | 19 +++ .../BME280_LC709203_Adafruit_IO/code.py | 131 ++++++++++++++++++ .../BME280_LC709203_Simple_Data/code.py | 33 +++++ .../Capacitive_Touch_One_Pin/code.py | 15 ++ .../Capacitive_Touch_Two_Pins/code.py | 18 +++ .../Digital_Input/code.py | 17 +++ Adafruit_Feather_ESP32-S2/Storage/boot.py | 14 ++ Adafruit_Feather_ESP32-S2/Storage/code.py | 37 +++++ .../code.py | 29 ++++ 10 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 Adafruit_Feather_ESP32-S2/Analog_In/code.py create mode 100644 Adafruit_Feather_ESP32-S2/BME280_LC709203_Adafruit_IO/code.py create mode 100644 Adafruit_Feather_ESP32-S2/BME280_LC709203_Simple_Data/code.py create mode 100644 Adafruit_Feather_ESP32-S2/Capacitive_Touch_One_Pin/code.py create mode 100644 Adafruit_Feather_ESP32-S2/Capacitive_Touch_Two_Pins/code.py create mode 100644 Adafruit_Feather_ESP32-S2/Digital_Input/code.py create mode 100644 Adafruit_Feather_ESP32-S2/Storage/boot.py create mode 100644 Adafruit_Feather_ESP32-S2/Storage/code.py create mode 100644 CircuitPython_Templates/Analog_Pin_Values_Nonstandard_AREF/code.py diff --git a/.pylintrc b/.pylintrc index 7791f53d2..6bef3df83 100644 --- a/.pylintrc +++ b/.pylintrc @@ -52,7 +52,7 @@ confidence= # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" # disable=import-error,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call -disable=too-many-instance-attributes,len-as-condition,too-few-public-methods,anomalous-backslash-in-string,no-else-return,simplifiable-if-statement,too-many-arguments,duplicate-code,no-name-in-module,no-member,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,missing-docstring,invalid-name,bad-whitespace,consider-using-enumerate,unexpected-keyword-arg,consider-using-f-string +disable=too-many-instance-attributes,len-as-condition,too-few-public-methods,anomalous-backslash-in-string,no-else-return,simplifiable-if-statement,too-many-arguments,duplicate-code,no-name-in-module,no-member,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,missing-docstring,invalid-name,bad-whitespace,consider-using-enumerate,unexpected-keyword-arg,consider-using-f-string,unspecified-encoding # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option diff --git a/Adafruit_Feather_ESP32-S2/Analog_In/code.py b/Adafruit_Feather_ESP32-S2/Analog_In/code.py new file mode 100644 index 000000000..799c88df6 --- /dev/null +++ b/Adafruit_Feather_ESP32-S2/Analog_In/code.py @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries +# SPDX-License-Identifier: Unlicense +""" +CircuitPython analog voltage value example +""" +import time +import board +import analogio + +analog_pin = analogio.AnalogIn(board.A0) + + +def get_voltage(pin): + return (pin.value * 2.6) / 51375 + + +while True: + print(get_voltage(analog_pin)) + time.sleep(0.1) diff --git a/Adafruit_Feather_ESP32-S2/BME280_LC709203_Adafruit_IO/code.py b/Adafruit_Feather_ESP32-S2/BME280_LC709203_Adafruit_IO/code.py new file mode 100644 index 000000000..c003f90f8 --- /dev/null +++ b/Adafruit_Feather_ESP32-S2/BME280_LC709203_Adafruit_IO/code.py @@ -0,0 +1,131 @@ +# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries +# SPDX-License-Identifier: Unlicense +""" +CircuitPython Adafruit IO Example for BME280 and LC709203 Sensors +""" +import time +import ssl +import alarm +import board +import digitalio +import wifi +import socketpool +import adafruit_requests +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError +from adafruit_lc709203f import LC709203F, PackSize +from adafruit_bme280 import basic as adafruit_bme280 +try: + from secrets import secrets +except ImportError: + print("WiFi and Adafruit IO credentials are kept in secrets.py, please add them there!") + raise + +# Duration of sleep in seconds. Default is 600 seconds (10 minutes). +# Feather will sleep for this duration between sensor readings / sending data to AdafruitIO +sleep_duration = 600 + +# Update to match the mAh of your battery for more accurate readings. +# Can be MAH100, MAH200, MAH400, MAH500, MAH1000, MAH2000, MAH3000. +# Choose the closest match. Include "PackSize." before it, as shown. +battery_pack_size = PackSize.MAH400 + +# Setup the little red LED +led = digitalio.DigitalInOut(board.LED) +led.switch_to_output() + +# Pull the I2C power pin low +i2c_power = digitalio.DigitalInOut(board.I2C_POWER_INVERTED) +i2c_power.switch_to_output() +i2c_power.value = False + +# Set up the BME280 and LC709203 sensors +bme280 = adafruit_bme280.Adafruit_BME280_I2C(board.I2C()) +battery_monitor = LC709203F(board.I2C()) +battery_monitor.pack_size = battery_pack_size + +# Collect the sensor data values and format the data +temperature = "{:.2f}".format(bme280.temperature) +temperature_f = "{:.2f}".format((bme280.temperature * (9 / 5) + 32)) # Convert C to F +humidity = "{:.2f}".format(bme280.relative_humidity) +pressure = "{:.2f}".format(bme280.pressure) +battery_voltage = "{:.2f}".format(battery_monitor.cell_voltage) +battery_percent = "{:.1f}".format(battery_monitor.cell_percent) + + +def go_to_sleep(sleep_period): + # Create a an alarm that will trigger sleep_period number of seconds from now. + time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + sleep_period) + # Exit and deep sleep until the alarm wakes us. + alarm.exit_and_deep_sleep_until_alarms(time_alarm) + + +# Fetch the feed of the provided name. If the feed does not exist, create it. +def setup_feed(feed_name): + try: + # Get the feed of provided feed_name from Adafruit IO + return io.get_feed(feed_name) + except AdafruitIO_RequestError: + # If no feed of that name exists, create it + return io.create_new_feed(feed_name) + + +# Send the data. Requires a feed name and a value to send. +def send_io_data(feed, value): + return io.send_data(feed["key"], value) + + +# Wi-Fi connections can have issues! This ensures the code will continue to run. +try: + # Connect to Wi-Fi + wifi.radio.connect(secrets["ssid"], secrets["password"]) + print("Connected to {}!".format(secrets["ssid"])) + print("IP:", wifi.radio.ipv4_address) + + pool = socketpool.SocketPool(wifi.radio) + requests = adafruit_requests.Session(pool, ssl.create_default_context()) + +# Wi-Fi connectivity fails with error messages, not specific errors, so this except is broad. +except Exception as e: # pylint: disable=broad-except + print(e) + go_to_sleep(60) + +# Set your Adafruit IO Username and Key in secrets.py +# (visit io.adafruit.com if you need to create an account, +# or if you need your Adafruit IO key.) +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) + +# Turn on the LED to indicate data is being sent. +led.value = True +# Print data values to the serial console. Not necessary for Adafruit IO. +print("Current BME280 temperature: {0} C".format(temperature)) +print("Current BME280 temperature: {0} F".format(temperature_f)) +print("Current BME280 humidity: {0} %".format(humidity)) +print("Current BME280 pressure: {0} hPa".format(pressure)) +print("Current battery voltage: {0} V".format(battery_voltage)) +print("Current battery percent: {0} %".format(battery_percent)) + +# Adafruit IO sending can run into issues if the network fails! +# This ensures the code will continue to run. +try: + print("Sending data to AdafruitIO...") + # Send data to Adafruit IO + send_io_data(setup_feed("bme280-temperature"), temperature) + send_io_data(setup_feed("bme280-temperature-f"), temperature_f) + send_io_data(setup_feed("bme280-humidity"), humidity) + send_io_data(setup_feed("bme280-pressure"), pressure) + send_io_data(setup_feed("battery-voltage"), battery_voltage) + send_io_data(setup_feed("battery-percent"), battery_percent) + print("Data sent!") + # Turn off the LED to indicate data sending is complete. + led.value = False + +# Adafruit IO can fail with multiple errors depending on the situation, so this except is broad. +except Exception as e: # pylint: disable=broad-except + print(e) + go_to_sleep(60) + +go_to_sleep(sleep_duration) diff --git a/Adafruit_Feather_ESP32-S2/BME280_LC709203_Simple_Data/code.py b/Adafruit_Feather_ESP32-S2/BME280_LC709203_Simple_Data/code.py new file mode 100644 index 000000000..5e390b577 --- /dev/null +++ b/Adafruit_Feather_ESP32-S2/BME280_LC709203_Simple_Data/code.py @@ -0,0 +1,33 @@ +# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries +# SPDX-License-Identifier: Unlicense +""" +CircuitPython Simple Example for BME280 and LC709203 Sensors +""" +import time +import board +import digitalio +from adafruit_bme280 import basic as adafruit_bme280 +from adafruit_lc709203f import LC709203F, PackSize + +# Pull the I2C power pin low +i2c_power = digitalio.DigitalInOut(board.I2C_POWER_INVERTED) +i2c_power.switch_to_output() +i2c_power.value = False + +# Create sensor objects, using the board's default I2C bus. +i2c = board.I2C() +bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c) +battery_monitor = LC709203F(board.I2C()) +battery_monitor.pack_size = PackSize.MAH400 + +# change this to match your location's pressure (hPa) at sea level +bme280.sea_level_pressure = 1013.25 + +while True: + print("\nTemperature: {:.1f} C".format(bme280.temperature)) + print("Humidity: {:.1f} %".format(bme280.relative_humidity)) + print("Pressure: {:.1f} hPa".format(bme280.pressure)) + print("Altitude: {:.2f} meters".format(bme280.altitude)) + print("Battery Percent: {:.2f} %".format(battery_monitor.cell_percent)) + print("Battery Voltage: {:.2f} V".format(battery_monitor.cell_voltage)) + time.sleep(2) diff --git a/Adafruit_Feather_ESP32-S2/Capacitive_Touch_One_Pin/code.py b/Adafruit_Feather_ESP32-S2/Capacitive_Touch_One_Pin/code.py new file mode 100644 index 000000000..f14b240ff --- /dev/null +++ b/Adafruit_Feather_ESP32-S2/Capacitive_Touch_One_Pin/code.py @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries +# SPDX-License-Identifier: Unlicense +""" +CircuitPython Capacitive Touch Pin Example - Print to the serial console when one pin is touched. +""" +import time +import board +import touchio + +touch = touchio.TouchIn(board.A4) + +while True: + if touch.value: + print("Pin touched!") + time.sleep(0.1) diff --git a/Adafruit_Feather_ESP32-S2/Capacitive_Touch_Two_Pins/code.py b/Adafruit_Feather_ESP32-S2/Capacitive_Touch_Two_Pins/code.py new file mode 100644 index 000000000..436c7f5eb --- /dev/null +++ b/Adafruit_Feather_ESP32-S2/Capacitive_Touch_Two_Pins/code.py @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries +# SPDX-License-Identifier: Unlicense +""" +CircuitPython Capacitive Two Touch Pin Example - Print to the serial console when a pin is touched. +""" +import time +import board +import touchio + +touch_one = touchio.TouchIn(board.A4) +touch_two = touchio.TouchIn(board.A5) + +while True: + if touch_one.value: + print("Pin one touched!") + if touch_two.value: + print("Pin two touched!") + time.sleep(0.1) diff --git a/Adafruit_Feather_ESP32-S2/Digital_Input/code.py b/Adafruit_Feather_ESP32-S2/Digital_Input/code.py new file mode 100644 index 000000000..ac437225c --- /dev/null +++ b/Adafruit_Feather_ESP32-S2/Digital_Input/code.py @@ -0,0 +1,17 @@ +""" +CircuitPython Digital Input Example - Blinking an LED using a button switch. +""" +import board +import digitalio + +led = digitalio.DigitalInOut(board.LED) +led.direction = digitalio.Direction.OUTPUT + +button = digitalio.DigitalInOut(board.D5) +button.switch_to_input(pull=digitalio.Pull.UP) + +while True: + if not button.value: + led.value = True + else: + led.value = False diff --git a/Adafruit_Feather_ESP32-S2/Storage/boot.py b/Adafruit_Feather_ESP32-S2/Storage/boot.py new file mode 100644 index 000000000..b656d20a3 --- /dev/null +++ b/Adafruit_Feather_ESP32-S2/Storage/boot.py @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries +# SPDX-License-Identifier: Unlicense +""" +CircuitPython Essentials Storage CP Filesystem boot.py file +""" +import board +import digitalio +import storage + +pin = digitalio.DigitalInOut(board.A0) +pin.switch_to_input(pull=digitalio.Pull.UP) + +# If the pin is connected to ground, the filesystem is writable by CircuitPython +storage.remount("/", readonly=pin.value) diff --git a/Adafruit_Feather_ESP32-S2/Storage/code.py b/Adafruit_Feather_ESP32-S2/Storage/code.py new file mode 100644 index 000000000..26186e932 --- /dev/null +++ b/Adafruit_Feather_ESP32-S2/Storage/code.py @@ -0,0 +1,37 @@ +# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries +# SPDX-License-Identifier: Unlicense +""" +CircuitPython Essentials Storage CP Filesystem code.py file +""" +import time +import board +import digitalio +import microcontroller + +led = digitalio.DigitalInOut(board.LED) +led.switch_to_output() + +try: + with open("/temperature.txt", "a") as temp_log: + while True: + # The microcontroller temperature in Celsius. Include the + # math to do the C to F conversion here, if desired. + temperature = microcontroller.cpu.temperature + + # Write the temperature to the temperature.txt file every 10 seconds. + temp_log.write('{0:.2f}\n'.format(temperature)) + temp_log.flush() + + # Blink the LED on every write... + led.value = True + time.sleep(1) # ...for one second. + led.value = False # Then turn it off... + time.sleep(9) # ...for the other 9 seconds. + +except OSError as e: # When the filesystem is NOT writable by CircuitPython... + delay = 0.5 # ...blink the LED every half second. + if e.args[0] == 28: # If the file system is full... + delay = 0.15 # ...blink the LED every 0.15 seconds! + while True: + led.value = not led.value + time.sleep(delay) diff --git a/CircuitPython_Templates/Analog_Pin_Values_Nonstandard_AREF/code.py b/CircuitPython_Templates/Analog_Pin_Values_Nonstandard_AREF/code.py new file mode 100644 index 000000000..b4a7cd8c8 --- /dev/null +++ b/CircuitPython_Templates/Analog_Pin_Values_Nonstandard_AREF/code.py @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries +# SPDX-License-Identifier: Unlicense +""" +CircuitPython analog voltage value example + +REMOVE THIS TEXT AND ALL THE FOLLOWING, AND THE PYLINT DISABLE COMMENT, BEFORE SUBMITTING TO LEARN: +Update VOLTAGE to the max voltage returned by the board you're using. +Update VALUE to the max analog pin value returned by the board you're using. + +For example: +If you are using Feather ESP32-S2, update VOLTAGE to 2.6 and VALUE to 51375. + +Remove the #pylint: disable=undefined-variable before submitting to Learn. It is unnecessary +once the VOLTAGE and VALUE are updated to valid numbers. +""" +import time +import board +import analogio + +analog_pin = analogio.AnalogIn(board.A0) + + +def get_voltage(pin): + return (pin.value * VOLTAGE) / VALUE # pylint: disable=undefined-variable + + +while True: + print(get_voltage(analog_pin)) + time.sleep(0.1)