[EN] ESP8266/ESP32 WiFi

The ESP8266 and ESP32 boards are equipped with built-in WiFi connectivity. They can work in both self-application mode (Access Point) and client mode connected to an existing WiFi network or STA. Developers can set the device name (ESSID) or use the default name from the system as MicroPython-xxxx, where x represents the MAC Address of the device, the password is micropythoN (developers can assign new) and the IP Address (IP Address) is 192.168.4.1.

(Figure. Our ESP8266+Uno)

This article continues from the previous article that communicates the operation of the Arduino Uno Maker board via communication on the I2C bus and see the status of the ports D2, D3, D4, D5, D6, D7, D8 and D9 of Arduino Uno Maker board via ESP8266 or ESP32 web page.

Network basics

For the network module of ESP8266/ESP32 Network libraries must be imported. Commands to check the status of interfaces in AP and STA modes are written in Python as code3-1 and code3-2. The result is False when not ready to connect or not connected to a WiFi network and is true when ready to work with a WiFi network.

#code3-1
import network as nw
ifSTA = nw.WLAN(nw.STA_IF)
print(ifSTA.active())
#code3-2
import network as nw
ifAP = nw.WLAN(nw.AP_IF)
print(ifAP.active())

To read the interface settings, you can use the following commands: to read IP Address, subnetmask, gateway and DNA.

#code3-3
import network as nw
ifAP = nw.WLAN(nw.AP_IF)
if (ifAP.active() == True):
    print(ifAP.ifconfig())

An example of the output image from code3-3 is as follows.

(Figure. 2 Result of code3-3)

AP Mode

AP mode defines the ESP8266 as a web service device and the user connects to WiFi to this device to read information from a website which has IP Address 192.168.4.1 by the name of ESSID and the developer password can be customized.

The procedure for programming in AP mode is as follows.
1. Create an AP interface
2. Check the status of the Interface. If the status is False, rerun active() and define the ESSID name and password of ESP8266/ESP32.
3. Create a function to send HTML data when a client connects.
4. Read the settings and display them (If you don’t want to show the IP Address of the AP device, you can skip it.).
5. Open a socket and select port number 80 and start waiting for the connection.
6. Loop to wait for connection When a connection is established (the line after accept() is started), the developer can read the connection device number and the value obtained from the connection then send the data back to the browser of the connected device. After that, the connection must be closed.

The sample code3-4 is an example displaying Hi JarutEx text with pageview count values.

#code3-4
import socket
import network
import esp
#---(1)
ap = network.WLAN(network.AP_IF)
#---(2)
ssid = 'JarutEx-AP'
password = '123456789'
ap.active(True)
ap.config(essid=ssid, password=password)
counter = 0
while ap.active() == False:
  pass
print('Connection successful')
#---(3)
def web_page():
    global counter
    counter = counter + 1
    html = """<html><head><meta name="viewport"
      content="width=device-width, initial-scale=1"></head>
      <body><h1>Hi JarutEx. No."""
    html += str(counter)
    html += "</h1></body></html>"
    return html
#---(4)
print(ap.ifconfig())
#---(5)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
#---(6)
while True:
    conn, addr = s.accept()
    print('conn {} from {}'.format(conn, addr))
    request = conn.recv(1024)
    print('request = {}'.format(request))
    response = web_page()
    conn.send('Content-Type: text/html\n')
    conn.send('Connection: close\n\n')
    conn.send(response)
    conn.close()

STA Mode

If connected ESP8266/ESP32 to an existing WiFi network, the procedure is as follows.
1. Create an Interface variable running in STA_IF mode.
2. Check the availability status of the interface.
3. If you’re ready to work, skip it. But if not ready to work, order to start working.
4. Connect to the WiFi network, if it fails in the connection, loop until it succeeds.
5. Read the settings that the WiFi networking system assigns to the ESP8266/ESP32.
6. Do the desired job
7. Shut down when not in use

The code3-6 is an example of a network connection.

#code3-6
import network as nw
myESSID = "AP"
myPassword = "password"
ifSTA = nw.WLAN(nw.STA_IF)
if (ifSTA.active() == False):
    ifSTA.active(True)
    ifSTA.connect(myESSID, myPassword)
    while not ifSTA.isconnected():
        pass
    print("network configuration:\n{}".format(ifSTA.ifconfig()))
ifSTA.active(False)
(Figure. 5 Result of code3-5)

หมายเหตุ
1.

Note
1. Step 7 is very important. If the developed program stops working without closing the interface, the ESP8266 board will continue to attempt to connect to the WiFi network. A reset must be performed to restart the system.
2. A network connection that requires authentication from the web page before running will not work in this example. You must use the network sharing from the mobile phone to test the program.

Example program showing a list of all Access Points that the ESP8266 board sees as code3-7.

#code3-7
import network as nw
ifSTA = nw.WLAN(nw.STA_IF)
if (ifSTA.active() == False):
    ifSTA.active(True)
    listAPs = ifSTA.scan()
    for AP in listAPs:
        print("{}".format(AP[0]))
ifSTA.active(False)

Commanding Arduino Uno via web

Example program to operate Arduino Uno Maker to order LED  on/off and show the status of LED connected to ports D2, D3,D4, D5, D6, D7, D8 and D9 via web in AP mode, can write code as code3-8 and code for Arduino Uno Maker is according to code3-9.

#code3-8
import esp
import time
import socket
import network
from machine import Pin, I2C

sclPin = Pin(5)
sdaPin = Pin(4)
unoAddr = 7
unoBuffer = bytearray(2)
unoStatus = 0
i2c = I2C(sda = sdaPin, scl = sclPin, freq=100000)

ap = network.WLAN(network.AP_IF)
ssid = 'JarutEx-AP'
password = '123456789'
ap.active(True)
ap.config(essid=ssid, password=password)
while ap.active() == False:
  pass
print('Connection successful')

def doOn():
    global unoBuffer
    global unoAddr
    unoBuffer[0] = 1
    unoBuffer[1] = 0
    i2c.writeto(unoAddr, unoBuffer)
    
def doOff():
    global unoBuffer
    global unoAddr
    unoBuffer[0] = 0
    unoBuffer[1] = 0
    i2c.writeto(unoAddr, unoBuffer)
    
def doReadStatus():
    global unoStatus
    global unoAddr
    unoStatus = i2c.readfrom(unoAddr,1)
    
def web_page():
    doReadStatus()
    html = """<html><head><meta name="viewport"
      content="width=device-width, initial-scale=1"></head>
      <body><h1>Status = """
    html += str(unoStatus)
    html += "</h1>"
    html += """<p><a href="/?led=on"><button>ON</button></a></p>
  <p><a href="/?led=off"><button>OFF</button></a></p>"""
    html += "</body></html>"
    return html

print(ap.ifconfig())
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
while True:
    conn, addr = s.accept()
    print('conn {} from {}'.format(conn, addr))
    request = str(conn.recv(1024))
    print('request = {}'.format(request))
    ledOn = request.find("/?led=on")
    ledOff = request.find("/?led=off")
    if (ledOn==6):
        doOn()
    if (ledOff==6):
        doOff()
    response = web_page()
    conn.send('HTTP/1.1 200 OK\n')
    conn.send('Content-Type: text/html\n')
    conn.send('Connection: close\n\n')    
    conn.send(response)
    conn.close()
// code3-9 โค้ดของ Arduino Uno
#include <Wire.h>
int unoAddr = 7;
uint8_t ledStatus[8] = {1, 1, 1, 1, 1, 1, 1, 1};
void i2cReceive( int bytes ) {
  uint8_t dInput = Wire.read();
  uint8_t pattern = Wire.read();
  Serial.println(dInput);
  if (dInput == 0) {
    for (int ledPin = 2; ledPin <= 9; ledPin++) {
      digitalWrite(ledPin, 0);
      ledStatus[ledPin-2] = 0;
    }
  }
  else if (dInput == 1) {
    for (int ledPin = 2; ledPin <= 9; ledPin++) {
      digitalWrite(ledPin, 1);
      ledStatus[ledPin-1] = 1;
    }
  } else {
    return;
  }
}
void i2cRequest() {
  for (int ledPin = 2; ledPin <= 9; ledPin++) {
    pinMode(ledPin, INPUT_PULLUP);
  }
  uint8_t bitNo = 0;
  uint8_t unoBuffer = 0;
  for (int ledIdx = 0; ledIdx < 8; ledIdx++) {
    unoBuffer |= ledStatus[ledIdx] << bitNo;
    bitNo++;
  }
  Serial.println(unoBuffer, HEX);
  Wire.write(unoBuffer);
}
void setup() {
  Serial.begin(115200);
  Serial.println("UNO Started");
  for (int ledPin = 2; ledPin <= 9; ledPin++) {
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin, ledStatus[ledPin - 2]);
  }
  Wire.begin(unoAddr);
  Wire.onReceive(i2cReceive);
  Wire.onRequest(i2cRequest);
}
void loop() {
}

Conclusion

From this article, you can learn how to program the WiFi module of ESP8266/ESP32 to work in AP and STA mode. They can list Access Points and write programs to operate Arduino Uno Maker via the web. Finally, we hope that this article will serve as a guide to learning how to program a device controller in Python and useful for further application.

If you want to talk with us, feel free to leave comments below!!

Reference

https://docs.micropython.org/en/latest/esp8266/tutorial/network_basics.html

(C) 2020, By Jarut Busarathid and Danai Jedsadathitikul

Updated 2021-12-05