adafruit / Adafruit_CircuitPython_ESP32SPI

ESP32 as wifi with SPI interface
MIT License
103 stars 75 forks source link

Arduino RP2040 Connect. wifi chip integration missing Dhcp(True/False) #140

Closed manpowre closed 1 year ago

manpowre commented 3 years ago

CircuitPython version

Adafruit Circuitpython 7.0 latest and master (yeah I compiled master branch)

Code/REPL

import time
import board
import busio
from digitalio import DigitalInOut
import adafruit_requests as requests
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from adafruit_esp32spi import adafruit_esp32spi
import neopixel
from rainbowio import colorwheel
import gc
from secrets import secrets

UDP_IN_ADDR="192.168.2.147"
UDP_IN_PORT = 5500

UDP_TIMEOUT = 20

esp32_cs = DigitalInOut(board.CS1)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)

spi = busio.SPI(board.SCK1, board.MOSI1, board.MISO1)

esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
socket.set_interface(esp)

s_in = socket.socket(type=socket.SOCK_DGRAM)
s_in.settimeout(UDP_TIMEOUT)

if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
    print("ESP32 found and in idle mode")
print("Firmware vers.", esp.firmware_version)
print("MAC addr:", [hex(i) for i in esp.MAC_address])
print("Connecting to AP...")
while not esp.is_connected:
    try:
        esp.connect_AP(secrets["ssid"], secrets["password"])
    except RuntimeError as e:
        print("could not connect to AP, retrying: ", e)
        continue
print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi)

time.sleep(1)
IP_ADDR = esp.pretty_ip(esp.ip_address)
print("ip:", esp.ip_address)
print("My IP address is", esp.pretty_ip(esp.ip_address))
print("udp in addr: ", UDP_IN_ADDR, UDP_IN_PORT)

Behavior

The interface is missing the ifconfig to set a static IP adress: esp.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER)

this is critical for people wanting to use this device with circtuitpython to atleast be able to set a static IP, otherwise the DHCP will renew the IP adress from time to time.

I tested OpenMV micropython and their ifconfig works like a charm so its not the wifi chip, its the circtuitpython interface thats missing this.

Description

No response

Additional information

No response

ladyada commented 3 years ago

this library doesnt support dhcp static ip config - it looks like the esp32's nina firmware supports it? but you'd have to add the capability to the library or just tell your router to only use one IP address for the MAC.

manpowre commented 3 years ago

I tried openMV micropython and they implemented ifconfig() and that works. so its not the esp32 missing functionality, its the circuitpython library. (openMV doesnt support nepixel with pwm, so I cant use that). Sure setting router is fine, but this could easily be added to set the IP, subnetmask and gateway + dns.

ladyada commented 3 years ago

correct, you'd have to add the capability to the driver - we have not implemented it.

manpowre commented 3 years ago

I did some digging, the Nina interface has its commands and parameters here: https://github.com/arduino/nina-fw/blob/master/main/CommandHandler.cpp

I implemented into adafruit_esp32spi.py:

_SET_IP_CONFIG = const(0x14)
_SET_DNS_CONFIG = const(0x15)
_SET_HOSTNAME = const(0x16)

def set_ip_config(self, ip, gw, mask="255.255.255.0"):
        """Tells the ESP32 to set ip, gateway and network mask"""
        resp = self._send_command_get_response(_SET_IP_CONFIG, [self.unpretty_ip(ip), self.unpretty_ip(gw), self.unpretty_ip(mask)])
        return resp
        if resp[0][0] != 1:
            raise RuntimeError("Failed to set ip config with esp32")

    def set_dns_config(self, dns1, dns2="8.8.8.8"):
        """Tells the ESP32 to set DNS, with dns2 default to google dns=8.8.8.8"""
        resp = self._send_command_get_response(_SET_DNS_CONFIG, [self.unpretty_ip(dns1), self.unpretty_ip(dns2)])
        if resp[0][0] != 1:
            raise RuntimeError("Failed to set dns with esp32")

    def set_hostname(self, hostname):
        """Tells the ESP32 to set hostname"""
        resp = self._send_command_get_response(_SET_HOSTNAME, [hostname])
        return resp
        if resp[0][0] != 1:
            raise RuntimeError("Failed to set hostname with esp32")

the set_hostname works great, but the set_ip_config doesnt work. The ESP32 returns 0x00, which means failed.

Not submitting until I figured out why the set_ip_config function wont set the ip correctly.

ladyada commented 3 years ago

nice work! looks like you've got the right direction

manpowre commented 3 years ago

well the set_ip_config aint setting the ip. not sure whats going on here. getting fishy network interface for sure after I set the ip, gw and mask, and the controller is reporting 0x00, so that means fail to set it, but yea, a bit in the right direction. if we just can set the ip, then I can agree to drop the udp part hehe, even though udp to local IP works.. its just that we have to be able to set the IP atleast.

manpowre commented 3 years ago

got it working: ` _SET_IP_CONFIG = const(0x14) _SET_DNS_CONFIG = const(0x15) _SET_HOSTNAME = const(0x16)

def set_ip_config(self, ip, gw, mask="255.255.255.0"):
    """Tells the ESP32 to set ip, gateway and network mask b"\xFF" """
    resp = self._send_command_get_response(_SET_IP_CONFIG,
                                           params= [b"\x00",self.unpretty_ip(ip),self.unpretty_ip(gw), self.unpretty_ip(mask)],
                                           sent_param_len_16=False)
    return resp
    if resp[0][0] != 1:
        raise RuntimeError("Failed to set ip config with esp32")

def set_dns_config(self, dns1, dns2="8.8.8.8"):
    """Tells the ESP32 to set DNS, with dns2 default to google dns=8.8.8.8"""
    resp = self._send_command_get_response(_SET_DNS_CONFIG, [b"\x00", self.unpretty_ip(dns1), self.unpretty_ip(dns2)])
    if resp[0][0] != 1:
        raise RuntimeError("Failed to set dns with esp32")

`

I can now set ip to 192.168.2.2, gw 192.168.1.1, mask 255.255.255.0 and it recieves UDP packages at 192.168.2.2 !!

yayy

ladyada commented 3 years ago

yes!!! please submit a PR :)

anecdata commented 1 year ago

ip config, dns config, and hostname were implemented in this library last year, and there should be support already in the Arduino and Adafruit form of the NINA firmware. I think we can close this issue. https://github.com/adafruit/Adafruit_CircuitPython_ESP32SPI/pull/159