I'm scratching my head at what on the face of it is a simple problem. And looking for some advice. I'm writing a simple Wifi_manager class for a project I'm on which simply monitors my Wifi connection and if it drops, tries to re-connect.
To solve this problem, when the user uses creates a Wifi_manager object and asks it to 'connect' it will attach a 'callback' to a timer object. Every time the timer pops the callback will check the Wifi connection using the isconnected() method. If it's not connected it will try and reconnect.
1) Is there a better way of doing this? i.e. should I be using timers?
2) I've got most of the methods all working. But when the Wifi connection does drop my callback fails and I get an error:
Code: Select all
sdio_transfer timeout STA=0x00400004
Code: Select all
cyw43_kso_set(1): failed
sdio_transfer_cmd53: timeout wr=1 len=64 dma=1 buf_idx=0 STA=00400040 SDMMC=00000000:00000000 DMA=00000000:00000000:0000ffff RCC=2050017f
[CYW43] do_ioctl(2, 263, 19): timeout
This could be an actual bug - but wanted to check here first before reporting it.
The code is just alfa at the moment so please excuse the mess!
https://github.com/SamsungResearchUK-Io ... connect.py
To reproduce the problem you need to copy the wifi_connect.py to your pyboard 'd'.
Then do:
Code: Select all
>>> import wifi_connect
>>> from wifi_connect import Wifi_manager
>>>
>>> mw = Wifi_manager() # Create my wifi manager object
WiFi Manager bringing up wlan interface.
>>>
>>> mw.status() # Get staus of the wifi manager
(True, {'Retries': 3, 'Started': 614099554, 'SSID name': None, 'Current IP address': '192.168.123.105', 'Active monitor': False, 'Connected': True, 'Password': None})
>>>
>>> mw.retries() # Check how many retries it will attempt when initially connecting.
3
>>> mw.retries(8) # Set retries to 8 - wifi is really poor in this area.
(True, 'Retry set to 8 retries')
>>> mw.connect('srbackup', '**********') # Connect to my wifi network 'srbackup' and provide password.
Code: Select all
>>>
>>> Connection up
Connection up
Connection up
Connection up
Connection up
Connection up
But if it runs a line of code at line number 163 for me:
Code: Select all
def __check_connection(self, timer): # we will receive the timer object when being called
"""
The private method __check_connection is called by a timer as a callback.
It's used to check the IP connection and try and reconnect in the event of the connection being pulled down.
:return:
"""
# print(timer.counter()) # show current timer's counter value
if self.active: # Check first that we are required to try and reconnect
if not self._wifi.isconnected():
self.connected = False
print("Warning: WiFi connection lost. Trying to reconnect")
[b] self._wifi.connect(self.ssid, self._password)[/b] # Line 163 problem
else:
#print("Connected on IP: {}".format(self.current_ip_address))
print("Connection up")
self.connected = True
else:
# OK - it looks like we should not be monitoring this connection. Could be a race condition. Make sure we stop monitoring!
self._timer.deinit()
print('Wifi Manager has stopped monitoring the connection')
Basically my object is calling up the low level connect method which is in the object attribute self._wifi.connect()
The other thing to note is the timer callback. I'm using this timer function within my object and it gets the hidden 'self' parameter as well as the timer object like this:
Code: Select all
if not self.active:
print("WiFi Manager is now monitoring the connection")
self.active = True # Let the WiFi manager store state on managing the WiFi network to true.
self._timer = pyb.Timer(1, freq=0.1) # create a timer object using timer 1 - trigger at 0.1Hz
self._timer.callback(self.__check_connection) # set the callback to our timer function
Code: Select all
self._timer.callback(self.__check_connection)
Code: Select all
def __check_connection(self, timer): # we will receive the timer object when being called
Code: Select all
self._wifi.connect(self.ssid, self._password)
Kind regards, Nicholas.