Page 2 of 3
Re: ntptime kills the wifi station, hard reset required to fix
Posted: Tue Apr 20, 2021 12:36 pm
by pythoncoder
davef wrote: ↑Fri Apr 16, 2021 10:17 pm
...
Is that -3155673600 indicative of the problem? Actually after trying this a few more times it seems if I don't wait more than one (?) second between tries then I get the error...
If you look at ntptime.py you'll find
this line. A return value of -3155673600 means that the
time() function has failed,
msg was not updated, so the final subtraction returns
-NTP_DELTA.
I think the
settime() function is buggy as it doesn't cater for this case. You might rewrite it as follows:
Code: Select all
def settime():
t = time()
if t < 0:
return False
import machine
import utime
tm = utime.gmtime(t)
machine.RTC().datetime((tm[0], tm[1], tm[2], tm[6] + 1, tm[3], tm[4], tm[5], 0))
return True
You could then detect failure in your code and take remedial action (wait a few seconds and try again?).
I have raised
this issue against ntptime as this is surely a bug.
Re: ntptime kills the wifi station, hard reset required to fix
Posted: Tue Apr 20, 2021 7:55 pm
by davef
Hi Peter,
Thanks heaps for identifying what hopefully is the cause of ntptime freezing in my system.
You might rewrite it as follows:
I would really like to be able to rewrite, add, change source code and re-build. Latest effort here
viewtopic.php?f=2&t=9886.
I am planning to set-up a new 64-bit machine for my Micropython work, but first I will buy a bunch of NodeMCU's as suggested in the thread.
Appreciate your efforts towards sorting out my issues.
Re: ntptime kills the wifi station, hard reset required to fix
Posted: Fri Apr 23, 2021 7:09 pm
by davef
Have not seen any failures at settime() with your code modification ... on an ESP8266.
The random error I still get on the modified ESP8266 and the stock ESP32 firmware is:
Does not the 110 indicate an error thrown by the ESP operating system?
Re: ntptime kills the wifi station, hard reset required to fix
Posted: Mon May 03, 2021 10:13 am
by kevinkk525
The error still persists on the pyboard-D with micropython 1.15... Any way to solve this? The first ntptime.time() works succesfully, afterwards no connection works anymore and it needs a hard reset.
Re: ntptime kills the wifi station, hard reset required to fix
Posted: Mon May 03, 2021 10:34 am
by davef
I can still get up to 5 fails on ntptime.time()
Here is what I do:
Code: Select all
def getntptime():
now = 0
# ntptime.host = 'nz.pool.ntp.org'
count = 0
while (count < 5):
count += 1
try:
now = ntptime.time()
except OSError as error:
try:
with open('errors.txt', 'a') as outfile:
outfile.write('ntptime.time() failed with now = ' + str(now) + '\n')
except OSError:
pass
print('.', end = '')
utime.sleep(1)
if (now > 660000000):
count = 0
break
if (count == 5):
count = 0
try:
with open('errors.txt', 'a') as outfile:
outfile.write('ntptime.time() failed 5 times' + '\n')
except OSError:
print('oops')
machine.reset()
print(' got epoch time')
utime.sleep(1)
Those 5 fails will be now = 0
The 660000000 is just a "recent time". Probably you could say "as long as now != 0" you have a valid epoch time.
Re: ntptime kills the wifi station, hard reset required to fix
Posted: Mon May 03, 2021 10:35 am
by kevinkk525
I don't have an epoch problem on the pyboard-D. The first sync works and after that I can't connect anywhere anymore. No socket will work, all connection attempts time out.
Re: ntptime kills the wifi station, hard reset required to fix
Posted: Mon May 03, 2021 10:48 am
by davef
We need to hear from kwiley!
Re: ntptime kills the wifi station, hard reset required to fix
Posted: Fri May 20, 2022 3:17 pm
by greentree
Has anyone made progress on this issue?
I've encountered similar flakiness with ntptime.py (borrowed as above from the ESP8266 port) using MicroPython v1.18 on a PYBD-SF2W.
However, a hard reboot to reset the wifi seems at this point unnecessary.
I've set
Code: Select all
s.settimeout(10)
#s.settimeout(1)
in ntptime.py. Using test code
Code: Select all
from network import WLAN, STA_IF, AP_IF
from time import sleep_ms
import ntptime
ap = WLAN(AP_IF) # create access-point interface
ap.active(False) # deactivate the interface
sleep_interval = 500
stats = [0,0,0,0]
success = [0,0]
wlan = WLAN(STA_IF)
sleep_ms(sleep_interval)
wlan.active(True)
sleep_ms(sleep_interval)
wlan.connect(ssid, passwd)
sleep_ms(sleep_interval)
for i in range(100):
try:
status_before = wlan.status()
t=ntptime.time()
status_after = wlan.status()
print(i,status_before,status_after,t)
success[1] += 1
except Exception as ex:
status_after = wlan.status()
print(i,status_before,status_after,'ntptime error:',ex)
success[0] += 1
finally:
stats[status_after] += 1
sleep_ms(sleep_interval)
wlan.disconnect()
wlan.deinit()
print('\n\nSuccess results:')
print(success)
print('Status results:')
print(stats)
gives results like
Code: Select all
0 1 1 ntptime error: [Errno 113] EHOSTUNREACH
1 1 1 ntptime error: [Errno 113] EHOSTUNREACH
2 1 1 ntptime error: [Errno 113] EHOSTUNREACH
3 1 1 ntptime error: [Errno 113] EHOSTUNREACH
4 1 1 ntptime error: [Errno 113] EHOSTUNREACH
5 2 2 ntptime error: [Errno 113] EHOSTUNREACH
6 3 3 ntptime error: [Errno 110] ETIMEDOUT
7 3 3 706373344
8 3 3 706373345
9 3 3 706373345
10 3 3 706373346
11 3 3 706373347
12 3 3 706373347
13 3 3 706373348
14 3 3 ntptime error: [Errno 110] ETIMEDOUT
15 3 3 706373359
16 3 3 706373360
and
Code: Select all
Success results:
[21, 79]
Status results:
[0, 5, 1, 94]
The EHOSTUNREACH errors almost always occur at the start, with wlan.status<3, so this error could be easily circumvented.
ETIMEDOUT errors do not seem predictable from wlan.status.
Does anyone have insight into the root cause of these errors? If not, error handling like the above may be adequate for my application at least.
Re: ntptime kills the wifi station, hard reset required to fix
Posted: Fri May 20, 2022 7:30 pm
by davef
Without reading through the whole thread the following has been working for me for the last year:
Code: Select all
try:
import usocket as socket
except:
import socket
try:
import ustruct as struct
except:
import struct
import utime
import machine
# (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
NTP_DELTA = 3155673600
# The NTP host can be configured at runtime by doing: ntptime.host = 'myhost.org'
host = "pool.ntp.org"
def time():
NTP_QUERY = bytearray(48)
NTP_QUERY[0] = 0x1B
addr = socket.getaddrinfo(host, 123)[0][-1]
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
counter = 0
# try 5 times to get the time
while True:
counter +=1
try:
s.settimeout(10) # was 1 second
res = s.sendto(NTP_QUERY, addr)
msg = s.recv(48)
counter = 0
s.close()
break
except Exception:
try:
with open('errors.txt', 'a') as outfile:
outfile.write('getting the time failed' + '\n')
except OSError:
pass
utime.sleep(50)
if counter == 5:
counter = 0
machine.reset()
val = struct.unpack("!I", msg[40:44])[0]
return val - NTP_DELTA
# There's currently no timezone support in MicroPython, and the RTC is set in UTC time.
def settime():
t = time()
if t < 0:
return False
import machine
import utime
tm = utime.gmtime(t)
machine.RTC().datetime((tm[0], tm[1], tm[2], tm[6] + 1, tm[3], tm[4], tm[5], 0))
line 32 set to 10 seconds
line 45 for a situation where it doesn't matter if it takes a few minutes to get the time.
line 57 and 58 a modification by Peter Hinch
Re: ntptime kills the wifi station, hard reset required to fix
Posted: Sat May 21, 2022 2:37 pm
by greentree
@davef, thanks for sharing that code. I'll add Peter Hinch's fix to settime.
In my application, NTP is only correcting the DS3231 RTC, which is pretty accurate for long periods, but battery life is limiting. So having time resets work only some of the time is less problematic than long delays during NTP queries. But it's helpful to see your strategy.
Have you tried setting the timeout to longer (e.g. 50 s) instead of having an interval between attempts?