diff --git a/adafruit_esp32spi/PWMOut.py b/adafruit_esp32spi/PWMOut.py new file mode 100755 index 0000000..fbdbc05 --- /dev/null +++ b/adafruit_esp32spi/PWMOut.py @@ -0,0 +1,108 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019 Brent Rubell for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`PWMOut` +============================== +PWMOut CircuitPython API for ESP32SPI. + +* Author(s): Brent Rubell +""" + +class PWMOut(): + """ + Implementation of CircuitPython PWMOut for ESP32SPI. + + :param int esp_pin: Valid ESP32 GPIO Pin, predefined in ESP32_GPIO_PINS. + :param ESP_SPIcontrol esp: The ESP object we are using. + :param int duty_cycle: The fraction of each pulse which is high, 16-bit. + :param int frequency: The target frequency in Hertz (32-bit). + :param bool variable_frequency: True if the frequency will change over time. + """ + ESP32_PWM_PINS = set([0, 1, 2, 4, 5, + 12, 13, 14, 15, + 16, 17, 18, 19, + 21, 22, 23, 25, + 26, 27, 32, 33]) + def __init__(self, esp, pwm_pin, *, frequency=500, duty_cycle=0, variable_frequency=False): + if pwm_pin in self.ESP32_PWM_PINS: + self._pwm_pin = pwm_pin + else: + raise AttributeError("Pin %d is not a valid ESP32 GPIO Pin."%pwm_pin) + self._esp = esp + self._duty_cycle = duty_cycle + self._freq = frequency + self._var_freq = variable_frequency + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, exc_traceback): + self.deinit() + + def deinit(self): + """De-initalize the PWMOut object.""" + self._duty_cycle = 0 + self._freq = 0 + self._pwm_pin = None + + def _is_deinited(self): + """Checks if PWMOut object has been previously de-initalized""" + if self._pwm_pin is None: + raise ValueError("PWMOut Object has been deinitialized and can no longer " + "be used. Create a new PWMOut object.") + + @property + def duty_cycle(self): + """Returns the PWMOut object's duty cycle as a + ratio from 0.0 to 1.0.""" + self._is_deinited() + return self._duty_cycle + + @duty_cycle.setter + def duty_cycle(self, duty_cycle): + """Sets the PWMOut duty cycle. + :param float duty_cycle: Between 0.0 (low) and 1.0 (high). + :param int duty_cycle: Between 0 (low) and 1 (high). + """ + self._is_deinited() + if not isinstance(duty_cycle, (int, float)): + raise TypeError("Invalid duty_cycle, should be int or float.") + duty_cycle /= 65535.0 + if not 0.0 <= duty_cycle <= 1.0: + raise ValueError("Invalid duty_cycle, should be between 0.0 and 1.0") + self._esp.set_analog_write(self._pwm_pin, duty_cycle) + + @property + def frequency(self): + """Returns the PWMOut object's frequency value.""" + self._is_deinited() + return self._freq + + @frequency.setter + def frequency(self, freq): + """Sets the PWMOut object's frequency value. + :param int freq: 32-bit value that dictates the PWM frequency in Hertz. + NOTE: Only writeable when constructed with variable_Frequency=True. + """ + self._is_deinited() + self._freq = freq + raise NotImplementedError("PWMOut Frequency not implemented in ESP32SPI") diff --git a/adafruit_esp32spi/adafruit_esp32spi.py b/adafruit_esp32spi/adafruit_esp32spi.py index e5f109a..a72bbb9 100644 --- a/adafruit_esp32spi/adafruit_esp32spi.py +++ b/adafruit_esp32spi/adafruit_esp32spi.py @@ -560,11 +560,14 @@ def socket_write(self, socket_num, buffer): if self._debug: print("Writing:", buffer) self._socknum_ll[0][0] = socket_num - resp = self._send_command_get_response(_SEND_DATA_TCP_CMD, - (self._socknum_ll[0], buffer), - sent_param_len_16=True) + sent = 0 + for chunk in range((len(buffer) // 64)+1): + resp = self._send_command_get_response(_SEND_DATA_TCP_CMD, + (self._socknum_ll[0], + memoryview(buffer)[(chunk*64):((chunk+1)*64)]), + sent_param_len_16=True) + sent += resp[0][0] - sent = resp[0][0] if sent != len(buffer): raise RuntimeError("Failed to send %d bytes (sent %d)" % (len(buffer), sent)) diff --git a/adafruit_esp32spi/adafruit_esp32spi_requests.py b/adafruit_esp32spi/adafruit_esp32spi_requests.py index ec17481..3857061 100755 --- a/adafruit_esp32spi/adafruit_esp32spi_requests.py +++ b/adafruit_esp32spi/adafruit_esp32spi_requests.py @@ -129,7 +129,7 @@ def iter_content(self, chunk_size=1, decode_unicode=False): return # pylint: disable=too-many-branches, too-many-statements, unused-argument, too-many-arguments, too-many-locals -def request(method, url, data=None, json=None, headers=None, stream=False): +def request(method, url, data=None, json=None, headers=None, stream=False, timeout=1): """Perform an HTTP request to the given url which we will parse to determine whether to use SSL ('https://') or not. We can also send some provided 'data' or a json dictionary which we will stringify. 'headers' is optional HTTP headers @@ -163,7 +163,7 @@ def request(method, url, data=None, json=None, headers=None, stream=False): sock = socket.socket(addr_info[0], addr_info[1], addr_info[2]) resp = Response(sock) # our response - sock.settimeout(1) # 1 second timeout + sock.settimeout(timeout) # socket read timeout try: if proto == "https:": diff --git a/adafruit_esp32spi/adafruit_esp32spi_socket.py b/adafruit_esp32spi/adafruit_esp32spi_socket.py index bcace39..ccf5b4f 100644 --- a/adafruit_esp32spi/adafruit_esp32spi_socket.py +++ b/adafruit_esp32spi/adafruit_esp32spi_socket.py @@ -87,11 +87,15 @@ def write(self, data): # pylint: disable=no-self-use def readline(self): """Attempt to return as many bytes as we can up to but not including '\r\n'""" #print("Socket readline") + stamp = time.monotonic() while b'\r\n' not in self._buffer: # there's no line already in there, read some more avail = min(_the_interface.socket_available(self._socknum), MAX_PACKET) if avail: self._buffer += _the_interface.socket_read(self._socknum, avail) + elif self._timeout > 0 and time.monotonic() - stamp > self._timeout: + self.close() # Make sure to close socket so that we don't exhaust sockets. + raise RuntimeError("Didn't receive full response, failing out") firstline, self._buffer = self._buffer.split(b'\r\n', 1) gc.collect() return firstline diff --git a/adafruit_esp32spi/adafruit_esp32spi_wifimanager.py b/adafruit_esp32spi/adafruit_esp32spi_wifimanager.py index 9906847..28b08b0 100755 --- a/adafruit_esp32spi/adafruit_esp32spi_wifimanager.py +++ b/adafruit_esp32spi/adafruit_esp32spi_wifimanager.py @@ -31,6 +31,8 @@ # pylint: disable=no-name-in-module +from time import sleep +from micropython import const from adafruit_esp32spi import adafruit_esp32spi import adafruit_esp32spi.adafruit_esp32spi_requests as requests @@ -38,52 +40,112 @@ class ESPSPI_WiFiManager: """ A class to help manage the Wifi connection """ - def __init__(self, esp, secrets, status_pixel=None, attempts=2): + NORMAL = const(1) + ENTERPRISE = const(2) + +# pylint: disable=too-many-arguments + def __init__(self, esp, secrets, status_pixel=None, attempts=2, connection_type=NORMAL): """ :param ESP_SPIcontrol esp: The ESP object we are using :param dict secrets: The WiFi and Adafruit IO secrets dict (See examples) - :param status_pixel: (Optional) The pixel device - A NeoPixel or DotStar (default=None) - :type status_pixel: NeoPixel or DotStar + :param status_pixel: (Optional) The pixel device - A NeoPixel, DotStar, + or RGB LED (default=None) + :type status_pixel: NeoPixel, DotStar, or RGB LED :param int attempts: (Optional) Failed attempts before resetting the ESP32 (default=2) + :param const connection_type: (Optional) Type of WiFi connection: NORMAL or ENTERPRISE """ # Read the settings - self._esp = esp + self.esp = esp self.debug = False self.ssid = secrets['ssid'] self.password = secrets['password'] self.attempts = attempts - requests.set_interface(self._esp) + self._connection_type = connection_type + requests.set_interface(self.esp) self.statuspix = status_pixel self.pixel_status(0) + # Check for WPA2 Enterprise keys in the secrets dictionary and load them if they exist + if secrets.get('ent_ssid'): + self.ent_ssid = secrets['ent_ssid'] + else: + self.ent_ssid = secrets['ssid'] + if secrets.get('ent_ident'): + self.ent_ident = secrets['ent_ident'] + else: + self.ent_ident = '' + if secrets.get('ent_user'): + self.ent_user = secrets['ent_user'] + if secrets.get('ent_password'): + self.ent_password = secrets['ent_password'] +# pylint: enable=too-many-arguments + def reset(self): """ Perform a hard reset on the ESP32 """ if self.debug: print("Resetting ESP32") - self._esp.reset() + self.esp.reset() def connect(self): """ Attempt to connect to WiFi using the current settings """ if self.debug: - if self._esp.status == adafruit_esp32spi.WL_IDLE_STATUS: + if self.esp.status == adafruit_esp32spi.WL_IDLE_STATUS: print("ESP32 found and in idle mode") - print("Firmware vers.", self._esp.firmware_version) - print("MAC addr:", [hex(i) for i in self._esp.MAC_address]) - for access_pt in self._esp.scan_networks(): + print("Firmware vers.", self.esp.firmware_version) + print("MAC addr:", [hex(i) for i in self.esp.MAC_address]) + for access_pt in self.esp.scan_networks(): print("\t%s\t\tRSSI: %d" % (str(access_pt['ssid'], 'utf-8'), access_pt['rssi'])) + if self._connection_type == ESPSPI_WiFiManager.NORMAL: + self.connect_normal() + elif self._connection_type == ESPSPI_WiFiManager.ENTERPRISE: + self.connect_enterprise() + else: + raise TypeError("Invalid WiFi connection type specified") + + def connect_normal(self): + """ + Attempt a regular style WiFi connection + """ failure_count = 0 - while not self._esp.is_connected: + while not self.esp.is_connected: try: if self.debug: print("Connecting to AP...") self.pixel_status((100, 0, 0)) - self._esp.connect_AP(bytes(self.ssid, 'utf-8'), bytes(self.password, 'utf-8')) + self.esp.connect_AP(bytes(self.ssid, 'utf-8'), bytes(self.password, 'utf-8')) + failure_count = 0 + self.pixel_status((0, 100, 0)) + except (ValueError, RuntimeError) as error: + print("Failed to connect, retrying\n", error) + failure_count += 1 + if failure_count >= self.attempts: + failure_count = 0 + self.reset() + continue + + def connect_enterprise(self): + """ + Attempt an enterprise style WiFi connection + """ + failure_count = 0 + self.esp.wifi_set_network(bytes(self.ent_ssid, 'utf-8')) + self.esp.wifi_set_entidentity(bytes(self.ent_ident, 'utf-8')) + self.esp.wifi_set_entusername(bytes(self.ent_user, 'utf-8')) + self.esp.wifi_set_entpassword(bytes(self.ent_password, 'utf-8')) + self.esp.wifi_set_entenable() + while not self.esp.is_connected: + try: + if self.debug: + print("Waiting for the ESP32 to connect to the WPA2 Enterprise AP...") + self.pixel_status((100, 0, 0)) + sleep(1) failure_count = 0 self.pixel_status((0, 100, 0)) + sleep(1) except (ValueError, RuntimeError) as error: print("Failed to connect, retrying\n", error) failure_count += 1 @@ -104,7 +166,7 @@ def get(self, url, **kw): :return: The response from the request :rtype: Response """ - if not self._esp.is_connected: + if not self.esp.is_connected: self.connect() self.pixel_status((0, 0, 100)) return_val = requests.get(url, **kw) @@ -123,7 +185,7 @@ def post(self, url, **kw): :return: The response from the request :rtype: Response """ - if not self._esp.is_connected: + if not self.esp.is_connected: self.connect() self.pixel_status((0, 0, 100)) return_val = requests.post(url, **kw) @@ -141,7 +203,7 @@ def put(self, url, **kw): :return: The response from the request :rtype: Response """ - if not self._esp.is_connected: + if not self.esp.is_connected: self.connect() self.pixel_status((0, 0, 100)) return_val = requests.put(url, **kw) @@ -160,7 +222,7 @@ def patch(self, url, **kw): :return: The response from the request :rtype: Response """ - if not self._esp.is_connected: + if not self.esp.is_connected: self.connect() self.pixel_status((0, 0, 100)) return_val = requests.patch(url, **kw) @@ -179,7 +241,7 @@ def delete(self, url, **kw): :return: The response from the request :rtype: Response """ - if not self._esp.is_connected: + if not self.esp.is_connected: self.connect() self.pixel_status((0, 0, 100)) return_val = requests.delete(url, **kw) @@ -195,10 +257,10 @@ def ping(self, host, ttl=250): :return: The response time in milliseconds :rtype: int """ - if not self._esp.is_connected: + if not self.esp.is_connected: self.connect() self.pixel_status((0, 0, 100)) - response_time = self._esp.ping(host, ttl=ttl) + response_time = self.esp.ping(host, ttl=ttl) self.pixel_status(0) return response_time @@ -206,26 +268,29 @@ def ip_address(self): """ Returns a formatted local IP address, update status pixel. """ - if not self._esp.is_connected: + if not self.esp.is_connected: self.connect() self.pixel_status((0, 0, 100)) self.pixel_status(0) - return self._esp.pretty_ip(self._esp.ip_address) + return self.esp.pretty_ip(self.esp.ip_address) def pixel_status(self, value): """ - Change Status NeoPixel if it was defined + Change Status Pixel if it was defined :param value: The value to set the Board's status LED to :type value: int or 3-value tuple """ if self.statuspix: - self.statuspix.fill(value) + if hasattr(self.statuspix, 'color'): + self.statuspix.color = value + else: + self.statuspix.fill(value) def signal_strength(self): """ Returns receiving signal strength indicator in dBm """ - if not self._esp.is_connected: + if not self.esp.is_connected: self.connect() - return self._esp.rssi() + return self.esp.rssi() diff --git a/adafruit_esp32spi/digitalio.py b/adafruit_esp32spi/digitalio.py new file mode 100755 index 0000000..49f5c35 --- /dev/null +++ b/adafruit_esp32spi/digitalio.py @@ -0,0 +1,209 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019 Brent Rubell for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`digitalio` +============================== +DigitalIO for ESP32 over SPI. + +* Author(s): Brent Rubell, based on Adafruit_Blinka digitalio implementation +and bcm283x Pin implementation. +https://github.com/adafruit/Adafruit_Blinka/blob/master/src/adafruit_blinka/microcontroller/bcm283x/pin.py +https://github.com/adafruit/Adafruit_Blinka/blob/master/src/digitalio.py +""" +from micropython import const + +class Pin: + """ + Implementation of CircuitPython API Pin Handling + for ESP32SPI. + + :param int esp_pin: Valid ESP32 GPIO Pin, predefined in ESP32_GPIO_PINS. + :param ESP_SPIcontrol esp: The ESP object we are using. + + NOTE: This class does not currently implement reading digital pins + or the use of internal pull-up resistors. + """ + #pylint: disable=invalid-name + IN = const(0x00) + OUT = const(0x01) + LOW = const(0x00) + HIGH = const(0x01) + _value = LOW + _mode = IN + pin_id = None + + ESP32_GPIO_PINS = set([0, 1, 2, 4, 5, + 12, 13, 14, 15, + 16, 17, 18, 19, + 21, 22, 23, 25, + 26, 27, 32, 33]) + + def __init__(self, esp_pin, esp): + if esp_pin in self.ESP32_GPIO_PINS: + self.pin_id = esp_pin + else: + raise AttributeError("Pin %d is not a valid ESP32 GPIO Pin."%esp_pin) + self._esp = esp + + def init(self, mode=IN): + """Initalizes a pre-defined pin. + :param mode: Pin mode (IN, OUT, LOW, HIGH). Defaults to IN. + """ + if mode is not None: + if mode == self.IN: + self._mode = self.IN + self._esp.set_pin_mode(self.pin_id, 0) + elif mode == self.OUT: + self._mode = self.OUT + self._esp.set_pin_mode(self.pin_id, 1) + else: + raise RuntimeError("Invalid mode defined") + + def value(self, val=None): + """Sets ESP32 Pin GPIO output mode. + :param val: Pin output level (LOW, HIGH) + """ + if val is not None: + if val == self.LOW: + self._value = val + self._esp.set_digital_write(self.pin_id, 0) + elif val == self.HIGH: + self._value = val + self._esp.set_digital_write(self.pin_id, 1) + else: + raise RuntimeError("Invalid value for pin") + else: + raise NotImplementedError("digitalRead not currently implemented in esp32spi") + + def __repr__(self): + return str(self.pin_id) + +# pylint: disable = too-few-public-methods +class DriveMode(): + """DriveMode Enum.""" + PUSH_PULL = None + OPEN_DRAIN = None +DriveMode.PUSH_PULL = DriveMode() +DriveMode.OPEN_DRAIN = DriveMode() + + +class Direction(): + """DriveMode Enum.""" + INPUT = None + OUTPUT = None +Direction.INPUT = Direction() +Direction.OUTPUT = Direction() + + +class DigitalInOut(): + """Implementation of DigitalIO module for ESP32SPI. + + :param ESP_SPIcontrol esp: The ESP object we are using. + :param int pin: Valid ESP32 GPIO Pin, predefined in ESP32_GPIO_PINS. + """ + _pin = None + #pylint: disable = attribute-defined-outside-init + def __init__(self, esp, pin): + self._esp = esp + self._pin = Pin(pin, self._esp) + self.direction = Direction.INPUT + + def __enter__(self): + return self + + def __exit__(self, exception_type, exception_value, traceback): + self.deinit() + + def deinit(self): + """De-initializes the pin object.""" + self._pin = None + + def switch_to_output(self, value=False, drive_mode=DriveMode.PUSH_PULL): + """Set the drive mode and value and then switch to writing out digital values. + :param bool value: Default mode to set upon switching. + :param DriveMode drive_mode: Drive mode for the output. + """ + self._direction = Direction.OUTPUT + self._drive_mode = drive_mode + self.value = value + + def switch_to_input(self, pull=None): + """Sets the pull and then switch to read in digital values. + :param Pull pull: Pull configuration for the input. + """ + raise NotImplementedError("Digital reads are not currently supported in ESP32SPI.") + + @property + def direction(self): + """Returns the pin's direction.""" + return self.__direction + + @direction.setter + def direction(self, pin_dir): + """Sets the direction of the pin. + :param Direction dir: Pin direction (Direction.OUTPUT or Direction.INPUT) + """ + self.__direction = pin_dir + if pin_dir is Direction.OUTPUT: + self._pin.init(mode=Pin.OUT) + self.value = False + self.drive_mode = DriveMode.PUSH_PULL + elif pin_dir is Direction.INPUT: + self._pin.init(mode=Pin.IN) + else: + raise AttributeError("Not a Direction") + + @property + def value(self): + """Returns the digital logic level value of the pin.""" + return self._pin.value() is 1 + + @value.setter + def value(self, val): + """Sets the digital logic level of the pin. + :param type value: Pin logic level. + :param int value: Pin logic level. 1 is logic high, 0 is logic low. + :param bool value: Pin logic level. True is logic high, False is logic low. + """ + if self.direction is Direction.OUTPUT: + self._pin.value(1 if val else 0) + else: + raise AttributeError("Not an output") + + @property + def drive_mode(self): + """Returns pin drive mode.""" + if self.direction is Direction.OUTPUT: + return self._drive_mode + raise AttributeError("Not an output") + + @drive_mode.setter + def drive_mode(self, mode): + """Sets the pin drive mode. + :param DriveMode mode: Defines the drive mode when outputting digital values. + Either PUSH_PULL or OPEN_DRAIN + """ + self.__drive_mode = mode + if mode is DriveMode.OPEN_DRAIN: + raise NotImplementedError('Drive mode %s not implemented in ESP32SPI.'%mode) + elif mode is DriveMode.PUSH_PULL: + self._pin.init(mode=Pin.OUT) diff --git a/examples/esp32spi_aio_post.py b/examples/esp32spi_aio_post.py index bdf395c..dfbf194 100644 --- a/examples/esp32spi_aio_post.py +++ b/examples/esp32spi_aio_post.py @@ -30,7 +30,14 @@ """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) +# 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) counter = 0 diff --git a/examples/esp32spi_wpa2ent_aio_post.py b/examples/esp32spi_wpa2ent_aio_post.py new file mode 100644 index 0000000..2123c05 --- /dev/null +++ b/examples/esp32spi_wpa2ent_aio_post.py @@ -0,0 +1,59 @@ +import time +import board +import busio +from digitalio import DigitalInOut +import neopixel +from adafruit_esp32spi import adafruit_esp32spi +from adafruit_esp32spi.adafruit_esp32spi_wifimanager import ESPSPI_WiFiManager + +print("ESP32 SPI WPA2 Enterprise webclient test") + +# 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 + +# ESP32 setup +# If your board does define the three pins listed below, +# you can set the correct pins in the second block +try: + esp32_cs = DigitalInOut(board.ESP_CS) + esp32_ready = DigitalInOut(board.ESP_BUSY) + esp32_reset = DigitalInOut(board.ESP_RESET) +except AttributeError: + 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) +wifi = ESPSPI_WiFiManager(esp, secrets, status_light, connection_type=ESPSPI_WiFiManager.ENTERPRISE) + +counter = 0 + +while True: + try: + print("Posting data...", end='') + data = counter + feed = 'test' + payload = {'value':data} + response = wifi.post( + "https://io.adafruit.com/api/v2/"+secrets['aio_username']+"/feeds/"+feed+"/data", + json=payload, + headers={"X-AIO-KEY":secrets['aio_key']}) + print(response.json()) + response.close() + counter = counter + 1 + print("OK") + except (ValueError, RuntimeError) as e: + print("Failed to get data, retrying\n", e) + wifi.reset() + continue + response = None + time.sleep(15) diff --git a/examples/esp32spi_wpa2ent_simpletest.py b/examples/esp32spi_wpa2ent_simpletest.py index d8d2a14..2eb06b6 100644 --- a/examples/esp32spi_wpa2ent_simpletest.py +++ b/examples/esp32spi_wpa2ent_simpletest.py @@ -25,16 +25,17 @@ def normalize(v): print("ESP32 SPI WPA2 Enterprise test") -# For running on the PyPortal, use this block -esp32_cs = DigitalInOut(board.ESP_CS) -esp32_ready = DigitalInOut(board.ESP_BUSY) -esp32_reset = DigitalInOut(board.ESP_RESET) - -# For a board that doesn't have the ESP pin definitions, use this block and -# set the pins as needed. -#esp32_cs = DigitalInOut(board.D8) -#esp32_ready = DigitalInOut(board.D5) -#esp32_reset = DigitalInOut(board.D7) +# ESP32 setup +# If your board does define the three pins listed below, +# you can set the correct pins in the second block +try: + esp32_cs = DigitalInOut(board.ESP_CS) + esp32_ready = DigitalInOut(board.ESP_BUSY) + esp32_reset = DigitalInOut(board.ESP_RESET) +except AttributeError: + 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)