043 - MicroPython TechNotes: ESP12E WiFi | External WiFi module

Introduction

In this article, I will demonstrate on how you can use an external WiFi module with ESP32 using MicroPython. Though ESP32 possesses a builtin Wifi device, sometimes an external module is necessary if you want to lessen the workload of the microcontroller. This is also applicable to microcontroller that does not have a builtin WiFi such as Raspberry Pi Pico and STM32.

We will use an ESP12E Wifi module or more commonly known as ESP8266 NodeMCU.

ESP12E can function in the following modes: 1. STA – or station mode, it needs to connect to a WiFi router. The WiFi router will provide IP address and handle all WiFi messages. If the module is used as a web server, a web client should be connected to the same WiFi router. This mode should be selected if you want to connect to the Internet. 2. SAP – or Software Access Point mode. In this mode, the ESP12E WiFi module provides IP addresses to all connected station devices. It also handles all WiFi transactions / message exchanges. This mode should be selected if you don’t want to use a WiFi router. 3. Both STA and SAP – or hybrid station mode and Access Point. It is complicated to use.

To use as WiFi STAtion: 1. Send AT+CWMODE=1 This will set the ESP12E WiFi module as station. 2. Send AT+CWJAP=”wifi_ssid”,”wifi_pass” This will configure the ESP12E WiFi module to connect to a WiFi router with the provided SSID and passwod. 3. Send AT+CIPMUX=1 This will configure the ESP12E WiFi module to allow multiple connections, maximum of 4. A value of 0 allows a single connection. 4. Send AT+CIPSERVER=1,80 This will configure the ESP12E WiFi module to create a web server on port 80. A value of 0 terminate the web server. 5. Send AT+CIFSR
This will return the IP address of the station device. This is the IP address we are going to use in connecting to the web server.

To use as Wifi Access Point: 1. Send AT+CWMODE=2 This will set the ESP12E WiFi module as Access Point device. 2. Send AT+CWSAP=”ESP12E”,”12345678″,5,3 This will configure the ESP12E WiFi module as Access Point with ESP12E as SSID and a password of 12345678. “5” is the number of channel to service. and 3 is the Security Type. 0 = OPEN 2 = WPA_PSK 3 = WPA2_PSK 4 = WPA_WPA2_PSK 3. Send AT+CIPMUX=1 This will configure the ESP12E WiFi module to allow multiple connections, maximum of 4. A value of 0 allows a single connection. 4. Send AT+CIPSERVER=1,80 This will configure the ESP12E WiFi module to create a web server on port 80. A value of 0 terminate the web server. 5. Send AT+CIFSR
This will return the IP address of the Access Point device. This is the IP address we are going to use in connecting to the web server.

To response to a client request: 1. Send AT+CIPSEND=id,html_length 2. Wait for a reply with “>” before sending the whole html page. 3. Send AT+CIPCLOSE=1 to close TCP connection.

Pinout

It has 4 pins namely:

  1. GND – for the ground pin.
  2. VCC – for the supply voltage.
  3. TX – for the UART serial transmit pin.
  4. RX – for the UART serial receive pin.

Bill Of Materials

In order to follow this lesson, you will need:

  1. ESP32 development board.
  2. Gorillacell ESP32 shield.
  3. 4-pin female-female dupont wires.
  4. ESP12E Wifi Module

Hardware Instruction

  1. First, attach the ESP32 development board on top of Gorillacell ESP32 shield and make sure that both USB port are on the same side.
  2. Next, attach the dupont wires to the WiFi module by following a color coding such as black for the ground, red for the VCC, yellow for the TX, and white for the RX pin.
  3. Next, attach the other end of the dupont wires to the ESP32 shield by matching the colors of the wires to the colors of the pin headers such that black is to black, red is to red, yellow and the following colors to the yellow pin headers. For this lesson, I choose GPIO 25 for the TX pin and GPIO 26 for the RX pin.
  4. Next, power the ESP32 shield by connecting an external 5V power supply though the type-C USB port. Make sure that the power switch is set to ON state.
  5. Lastly, connect the ESP32 development board to the computer by attaching a micro USB cable.

Software Instruction

  1. Copy the example source code from the SOURCE CODE section and paste it to Thonny IDE.
  2. Please feel free to modify it and adapt it according to your needs.

Video Demonstration

Call To Action

If you have any concern regarding this video, please write your question in the comment box. You might also liked to support my journey on Youtube by subscribing on my channel, TechToTinker. Click this to Subscribe. Thank you and have a good days ahead. See you, – George Bantique | tech.to.tinker@gmail.com

Source Code

1. Example # 1, demonstrates how to use ESP12E as WiFi Web Server using MicroPython:

  1# More details can be found in TechToTinker.blogspot.com 
  2# George Bantique | tech.to.tinker@gmail.com
  3
  4from machine import Pin
  5from machine import UART
  6from time import sleep_ms
  7
  8class GORILLACELL_WIFI:
  9    def __init__(self, port=2, baud=115200, tx=26, rx=25):
 10        self._wifi = UART(port, baudrate=baud, tx=tx, rx=rx)
 11        
 12    def sta_init(self, ssid, pwd):
 13        self.write('AT+CWMODE=1')
 14        while(1):
 15            response = str(self.decode())
 16            if response != "...":
 17                print(response)
 18            if "OK" in response:
 19                break
 20
 21        self.write('AT+CWJAP="{}","{}"'.format(ssid,pwd))
 22        is_to_check_OK = 0
 23        while(1):
 24            response = str(self.decode())
 25            if response != "...":
 26                print(response)
 27            if "WIFI GOT IP" in response:
 28                is_to_check_OK = 1
 29            if is_to_check_OK:
 30                if "OK" in response:
 31                    break
 32
 33    def ap_init(self, ssid, pwd):
 34        self.write('AT+CWMODE=2')
 35        while(1):
 36            response = str(self.decode())
 37            if response != "...":
 38                print(response)
 39            if "OK" in response:
 40                break
 41
 42        self.write('AT+CWSAP="{}","{}",5,3'.format(ssid,pwd))
 43        while(1):
 44            response = str(self.decode())
 45            if response != "...":
 46                print(response)
 47            if "OK" in response:
 48                break
 49            
 50    def server(self, cwmode):
 51        self.cipmux(mode=1)
 52        while(1):
 53            response = str(self.decode())
 54            if response != "...":
 55                print(response)
 56            if "OK" in response:
 57                break
 58
 59        self.cipserver(mode=1,port=80)
 60        while(1):
 61            response = str(self.decode())
 62            if response != "...":
 63                print(response)
 64            if "OK" in response:
 65                break
 66
 67        self.cifsr()
 68        while(1):
 69            response = str(self.decode())
 70            if response != "...":
 71                print(response)
 72            if cwmode == 1:
 73                if "STAIP" in response:
 74                    break
 75            elif cwmode == 2:
 76                if "APIP" in response:
 77                    break
 78                
 79    def display(self,ids,html):
 80        self.write('AT+CIPSEND={},{}'.format(ids,len(html))) 
 81        while(1):
 82            response = str(self.decode())
 83            if response != "...":
 84                print(response)
 85            if ">" in response:
 86                break
 87            if "ERROR" in response:
 88                self.write('AT+CIPSEND={},{}'.format(ids,len(html))) 
 89
 90        self.write(html)
 91        while(1):
 92            response = str(self.decode())
 93            if response != "...":
 94                print(response)
 95            if "OK" in response:
 96                break
 97
 98        self.write('AT+CIPCLOSE=1')
 99        while(1):
100            response = str(self.decode())
101            if response != "...":
102                print(response)
103            if "OK" in response:
104                break
105            
106    def parsed(self):
107        '''
108        PSEUDO CODE:
109            * Get each payload line by line, we are only
110            * interested in a line with IPD
111            * If +IPD is found, parse the important parts of the string
112            *    ipd is the +IPD string
113            *    ids is the ID of the connected client
114            *    req is the remaining part which will be further dissected
115            *    cnt is the number of receive characters
116            *    get is the remaining part which will be further dissected again
117            *    page is the requested html page by the client
118        '''
119        request = self.decode_line()
120        ids = ""
121        page = ""
122        if request != "...":
123            print(request)
124        if "+IPD," in request:
125            ipd,ids,req = request.split(",")
126            print(ipd, ids, req)
127            cnt,get = req.split(":")
128            print(cnt, get)
129            page = get[4:-10]
130            print(page)
131        return ids, page
132        
133    def write(self, tx_data):
134        self._wifi.write('{}rn'.format(tx_data))
135        
136    def read(self):
137        timeout = 1000
138        test_ret = "..."
139        while self._wifi.any()==0:
140            if timeout == 0:
141                return bytes(test_ret, 'utf-8')
142            else:
143                timeout -= 1
144        reply = self._wifi.read()
145        return reply
146
147    def readline(self):
148        timeout = 1000
149        test_ret = "..."
150        while self._wifi.any()==0:
151            if timeout == 0:
152                return bytes(test_ret, 'utf-8')
153            else:
154                timeout -= 1
155        reply = self._wifi.readline()
156        return reply
157    
158    def decode(self):
159        reply = self.read()
160        return reply.decode()
161    
162    def decode_line(self):
163        reply = self.readline()
164        return reply.decode()
165    
166    def prints(self):
167        print(self.decode())
168        
169    def echo(self, mode='None'):
170        if mode==0:
171            self.write('ATE0')
172        else: #mode==1
173            self.write('ATE1')
174            
175    def cwmode(self, mode='None'):
176        if   mode==1: # Station mode
177            self.write('AT+CWMODE=1')
178        elif mode==2: # AP mode
179            self.write('AT+CWMODE=2')
180        elif mode==3: # STA and AP mode
181            self.write('AT+CWMODE=3')
182        else:
183            self.write('AT+CWMODE?')
184        
185    def cifsr(self):
186        self.write('AT+CIFSR')
187        
188    def cipmux(self,mode='None'):
189        if mode==1:
190            self.write('AT+CIPMUX=1')
191        else:
192            self.write('AT+CIPMUX?')
193      
194    def cipserver(self,mode='None',port='None'):
195        sleep_ms(50)
196        self.write('AT+CIPSERVER={},{}'.format(mode,port))
197    
198led = Pin(2, Pin.OUT)
199wifi = GORILLACELL_WIFI()
200wifi.sta_init(ssid="Tenda_6F1750", pwd="geoven021110")
201#wifi.ap_init(ssid="ESP12E",pwd="12345678")
202wifi.server(1) # Set 1 for STA and 2 for AP
203
204def index_page():
205    global led
206    if led.value()==1:
207        led_state = 'ON'
208        print('led is ON')
209    elif led.value()==0:
210        led_state = 'OFF'
211        print('led is OFF')
212
213    html_page = """    
214     <html>  
215       <head>    
216         <meta content="width=device-width, initial-scale=1" name="viewport"></meta>    
217       </head>  
218       <body>    
219         <center><h2>ESP32 Web Server in MicroPython </h2></center>    
220         <center>  
221           <form>    
222             <button name="LED" type="submit" value="1"> LED ON </button>    
223             <button name="LED" type="submit" value="0"> LED OFF </button>    
224            </form>    
225         </center>    
226         <center>  
227           <p>LED is now <strong>""" + led_state + """</strong>.</p>  
228         </center>    
229       </body>  
230     </html>"""   
231    return html_page
232
233def favicon_page():
234    html_page = """  
235     HTTP/1.1 200 OK  
236     Content-Type: 'image/png'  
237       
238     <html>  
239       <head>  
240         <link rel='icon' type='image/png' href='/favicon.png'/>  
241       </head>  
242       <body>  
243       </body>  
244     </html>  
245     """  
246    return html_page
247
248
249while True:
250    client, page = wifi.parsed()
251    if page == "/ ":
252        wifi.display(client,index_page())
253
254    elif page == "/?LED=1 ":
255        led.value(1)
256        print('LED is ON')
257        wifi.display(client,index_page())
258        
259    elif page == "/?LED=0 ":
260        led.value(0)
261        print('LED is OFF')
262        html = index_page()
263        wifi.display(client,index_page())
264        
265    elif page == "/favicon.ico ":
266        #wifi.display(client,favicon_page())
267        pass
268            
269    sleep_ms(500)

References And Credits

  1. Purchased your Gorillacell ESP32 development kit: https://gorillacell.kr/

  2. ESP12E AT Commands: https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf http://room-15.github.io/blog/2015/03/26/esp8266-at-command-reference/ https://www.electronicshub.org/esp8266-at-commands/



Posts in this series



No comments yet!

GitHub-flavored Markdown & a sane subset of HTML is supported.