Hello, I am trying to use access point for knowing what is the ip-address when it connects to a specific WIFI with an access point webserver. After that, It will disable the access point mode and enable the station mode's web server to control the led light.
Problem faced:
1) How get out from the while of the ap web server?
2) How to unbind the socket and reuse it on the station mode’s webserver.
Algorithm of the program
1) Connect WIFI throught WIFImanager and disconnecting from the WIFI (link for the WIFI:https://github.com/tayfunulu/WiFiManager/blob/master/wifimgr.py)
2) opening the AP web server
if user press turn off webserver
3) AP mode disable
4) Station mode enable, reconnecting back to WIFI
5) Station mode webserver for controlling led lights
Start your code here Code: <code> try: import usocket as socket except: import socket from time import sleep import network from machine import Pin led1 = Pin(26,Pin.OUT) led2 = Pin(25,Pin.OUT) led3 = Pin(33,Pin.OUT) led4 = Pin(32,Pin.OUT) led1.value(1) import WIFI from WIFI import wlan_sta,wlan_ap wifi = WIFI.get_connection() sleep(1) wifi_config = wlan_sta.ifconfig() wlan_sta.active(False) wlan_ap.active(False) import esp esp.osdebug(None) import gc gc.collect() ssid = 'MicroPython-AP' password = '' ap = network.WLAN(network.AP_IF) ap.active(True) ap.config(essid=ssid, password=password) while ap.active() == False: pass print('Connection successful') print(ap.ifconfig()) led1.value(0) def web_page(): html = """<html><head><meta name="viewport" content="width=device-width, initial-scale=1"></head> <body><h1>Hello, World!</h1><h2>%(wifi_config)s</h2> <a href=\"?turnoff=on\"><button>Turn Off Webserver</button></a> </body></html>"""%dict(wifi_config=wifi_config) return html s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('',80)) s.listen(5) i = 1 while i < 99 : led2.value(1) conn, addr = s.accept() print('Got a connection from %s' % str(addr)) request = conn.recv(1024) request = str(request) print('Content = %s' % str(request)) turnoff_on = request.find('/?turnoff=on') if turnoff_on == 6: i = i + 99 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() i = i + 1 sleep(1) led2.value(0) ap.active(False) wifi = WIFI.get_connection() led3.value(1) def web_control(): html = """<html><head> <meta name="viewport" content="width=device-width, initial-scale=1"></head> <body> <h1>ESP Web Server</h1> <h2>Relay 1</h2> <a href=\"?led1=on\"><button>ON</button></a> <a href=\"?led1=off\"><button>OFF</button></a> <h2>Relay 2</h2> <a href=\"?led2=on\"><button>ON</button></a> <a href=\"?led2=off\"><button>OFF</button></a> <h2>Relay 3</h2> <a href=\"?led3=on\"><button>ON</button></a> <a href=\"?led3=off\"><button>OFF</button></a> <h2>Relay 4</h2> <a href=\"?led4=on\"><button>ON</button></a> <a href=\"?led4=off\"><button>OFF</button></a> </body></html>""" return html addr = socket.getaddrinfo('0.0.0.0', port)[0][-1] server_socket = socket.socket() client,addr = server_socket.accept() client.close() s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('',80)) s.listen(5) while True: sleep(1) led3.value(0) conn, addr = s.accept() print('Got a connection from %s' % str(addr)) request = conn.recv(1024) request = str(request) print('Content = %s' % request) led1_on = request.find('/?led1=on') led1_off = request.find('/?led1=off') led2_on = request.find('/?led2=on') led2_off = request.find('/?led2=off') led3_on = request.find('/?led3=on') led3_off = request.find('/?led3=off') led4_on = request.find('/?led4=on') led4_off = request.find('/?led4=off') if led1_on == 6: print('LED ON') led1.value(1) if led1_off == 6: print('LED OFF') led1.value(0) if led2_on == 6: print('LED ON') led2.value(1) if led2_off == 6: print('LED OFF') led2.value(0) if led3_on == 6: print('LED ON') led3.value(1) if led3_off == 6: print('LED OFF') led3.value(0) if led4_on == 6: print('LED ON') led4.value(1) if led4_off == 6: print('LED OFF') led4.value(0) response = web_control() conn.send('HTTP/1.1 200 OK\n') conn.send('Content-Type: text/html\n') conn.send('Connection: close\n\n') conn.sendall(response) conn.close()
Thanks in advance.
Hi.
If I understood well, you want to implement wi-fi manager in your script.
I experimented with the library you’ve sent and I was able to make it work.
Import the wifimgr.py library to your board. Do you know how to do that?
Then, upload the following code as main.pyhttps://pastebin.com/QLSrfTNp
This is the web server that controls one output, but you can change it to control as many as you want.
After importing the library and uploading and running the code. You should connect to the WiFi Manager network.
The password by default is: tayfunulu
Then, go to the ESP32 local IP: 192.168.4.1 The following page should load. You can select the network you want to connect and the password.
Then, you should receive a success message:
After this, the ESP32 is connected to your local network. So, connect your computer or smartphone to your local network.
Then, in a browser open the ESP32 IP address, and you should see the web server.
At the same time, you can take a look at the micropython shell to see what’s going on in the background. Or to see if the ESP32 is crashing in some of the steps.
Once you’ve entered your network credentials the first time, the next times it will connect automatically if it finds that network.
I hope this helps.
Regards,
Sara
Hello
Tq for your reply, Sara.
I am sorry to say you misunderstood my question and I know the thing that you explained.
The problem is happening after the WifiManager.
After WifiManager, I want to create another ap webserver to show the IP address of my esp32 on the WIFI which it connected when it is in station mode to the user. Once the user knows IP address and he or she will press the Turn Off Webserver button on the webserver. This makes the program exit from the while loop. In the meantime, the esp32 is turning to station mode and station mode webserver is enable, the user able to connect the webserver by keying in the IP address with their phone.
Hi
try
put your code in threads
your server stays in listening mode and when a client connects its starts a new thread to handle that client
https://techtutorialsx.com/2017/10/02/esp32-micropython-creating-a-thread/
https://techtutorialsx.com/2017/12/30/esp32-arduino-using-the-pthreads-library/
https://www.youtube.com/watch?v=i8ffEbyU-7w
I hope it helps
Hi.
So, the only difference is that you want the ESP32 IP address to be shown in the access point mode?
Regards,
Sara
Hi DK,
Tq for replying me.
I will try that.
Hi Sara,
Yes, but the problem starts after the access point mode is disabled and station mode is enabled.
I don’t know how to bind the socket to be set in the station mode web server after unbinding the socket from the access point mode webserver.
Hi.
I think unbinding is done automatically by the library. Once you’ve selected your network and writing the network credentials, it automatically unbinds the socket.
After that, it sets the ESP32 to station mode and you can call the following (you’re already on station mode here)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('', 80)) s.listen(5)
See lines 43 to 45 in the code I shared with you: https://pastebin.com/QLSrfTNp
Regards,
Sara
Hi again.
Today I’ve spent my afternoon around this issue. And now I think I understand your problem. I didn’t know you were having an error about the socket. But after searching for a while I finally understand your issue.
You get an error because of an open socket after the code sets the ESP32/ESP8266 to station mode.
A workaround for this is to reset the ESP after being set to station mode, the first time. This will “forget” all open sockets set as an access point before.
I don’t know if this is the best solution for this problem. But it works.
Basically, put the binding socket inside a try and except clause as follows:
try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('', 80)) s.listen(5) except OSError as e: machine.reset()
You need to import the machine module at the beginning of your sketch: import machine
In case you get the error regarding an already open socket, we’ll reset the board. The next time, the ESP32 already has the credentials saved, so it doesn’t need to go through the access point, and you won’t have that error.
I’ve tested it and it worked for me.
I hope this helps.
And I’m sorry that I took so long understanding your issue.
Regards,
Sara