Pico W Micro Python for SHT30 Temp/Humidity HELP!

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
beetle
Posts: 51
Joined: Sat Oct 16, 2021 11:35 am

Re: Pico W Micro Python for SHT30 Temp/Humidity HELP!

Post by beetle » Wed Nov 16, 2022 12:14 pm

Rissy a final mention on the errorlog file, I would always include some form of date/time stamp in the log.
See the following snippet as one way to include this. (many other ways to get and format a date time string of course). You dont need all of those file.wite statements on single lines as you can concatenate, but for getting the initial code to work in a very readable way I like to do it this way.

Code: Select all

import time

def appendfile(message, error):
    now = time.localtime()
    with open('errorlog.txt', 'a') as f:
        f.write(str(now[:5]))
        f.write(',')
        f.write(message)
        f.write(',')
        f.write(error)
        f.write('\n')

Rissy
Posts: 116
Joined: Sun Aug 14, 2022 8:15 am

Re: Pico W Micro Python for SHT30 Temp/Humidity HELP!

Post by Rissy » Wed Nov 16, 2022 2:03 pm

Thanks for your input. I think that's what i was looking for from someone. Basically just tell me where I'm wrong and present an alternative solution that WILL work.

I'll try out your solution tonight now! Thanks! (I wish everyone was as forthcoming with help and advice when I ask for a direct specific piece of help. For some people, it seems to be a sport of sorts to keep those who are still learning, stuck down low in the learning curve unnecessarily!?)

As for time stamping. That was actually my next manoeuvre actually. I was looking at this very subject a couple of weeks ago, but trying to get a proper time source into the Pico W via the internet, corrected to your required time-region seems to be a bit of headache. You're suggesting just importing time, but my understanding right now is that it is MUCH more complicated than this!?

beetle
Posts: 51
Joined: Sat Oct 16, 2021 11:35 am

Re: Pico W Micro Python for SHT30 Temp/Humidity HELP!

Post by beetle » Wed Nov 16, 2022 3:44 pm

Rissy wrote:
Wed Nov 16, 2022 2:03 pm
Thanks for your input. I think that's what i was looking for from someone. Basically just tell me where I'm wrong and present an alternative solution that WILL work.

I'll try out your solution tonight now! Thanks! (I wish everyone was as forthcoming with help and advice when I ask for a direct specific piece of help. For some people, it seems to be a sport of sorts to keep those who are still learning, stuck down low in the learning curve unnecessarily!?)

As for time stamping. That was actually my next manoeuvre actually. I was looking at this very subject a couple of weeks ago, but trying to get a proper time source into the Pico W via the internet, corrected to your required time-region seems to be a bit of headache. You're suggesting just importing time, but my understanding right now is that it is MUCH more complicated than this!?
Rissy, I'm happy to read that I may have helped you, but I do not concur with your remarks that some people are using you as 'sport' to keep you stuck down. On their behalf I find this attitude a bit offensive. Some advice may prove more beneficial than others but I'm sure any responder is simply trying to assist. It maybe they simply miss-judge your level of competence and ability to understand their response.

A final note if that I was thinking that your errorlog file was on a rpi and not a rpi-pico though mostly this sort of code will work on both. Just to be on the safe side I just ran the example on a rpi-pico and it all worked. I was using Thonny to run the code and I did note that, for whatever reason, the errorlog.txt file did not immediately show in the files list side panel. However a few more runs of the code did provoke it to be displayed and the results as as shown below:
(2022, 11, 16, 14, 52),SHT Error:,Bus error
(2022, 11, 16, 14, 55),SHT Error:,Bus error
(2022, 11, 16, 15, 17),SHT Error:,Bus error

As you can see the date/time format is YYYY,MM,DD,hh,mm. However, the date and time on the rpi-pico was correct because I was connect to it over Thonny via a usb connection. When the picoW is on its own then you can get the date and time via the wifi connection. You will need to look at ntptime. Alas this in in GMT and there are a few hoops to get BST which, judging from your remarks, you have come across. There are also other ways to extract and format the date time so I'm sure you can get it MUCH more complicate if you wish ;)

But, I would not be writing the errorlog file to the rpi-pico. You are sending mqtt messages from the rpi-pico to and rpi so the best way IMHO is to send the error message as an mqtt message to the rpi and deal with logging any error messages to a file on the rpi itself (with the benefit of more easily getting the correct time). On the rpi you could also keep the last time that an mqtt message was received (e.g. a temperature reading from the pico) and have a periodic routine to check and create an alert if the the last message received time is greater than the expected time interval. The alert could be anything you wish, but an email, sms other something like that could be done and all of this sort of coding is probably better done on the rpi.

Have fun

Rissy
Posts: 116
Joined: Sun Aug 14, 2022 8:15 am

Re: Pico W Micro Python for SHT30 Temp/Humidity HELP!

Post by Rissy » Wed Nov 16, 2022 4:43 pm

beetle wrote:
Wed Nov 16, 2022 3:44 pm
Rissy, I'm happy to read that I may have helped you, but I do not concur with your remarks that some people are using you as 'sport' to keep you stuck down. On their behalf I find this attitude a bit offensive. Some advice may prove more beneficial than others but I'm sure any responder is simply trying to assist. It maybe they simply miss-judge your level of competence and ability to understand their response.
I don't mean to offend anyone of course.

However, my remarks come not only with my experience of some peoples responses to my requests for help (I'm not specifically referring to this forum of course), but also the shear statistics of what I observe in the fact that, as an example; a forum request is clearly read by, lets say 100 individuals, but maybe only 2 may reply, and possibly only 1 of those will actually help rather than just pick fault with what i'm doing or the way i'm doing it, and offer no helpful alternative. You are obviously helping. Which i sincerely appreciate. I appreciate anyone who's helped me, and i'm very vocal with that in my responses.

I tired so much of a negative experience with at least one other forum that I actually even said "That's it. I'm through with this forum.". I've never returned to that forum since. Has it held me back, yes. Has it stopped me from getting better and evolving my fun home project?
Certainly not. It's perhaps just taken me a bit longer than it would have done with some helpful support. But as you say, i'm having fun along the way, even if i feel like i'm on my own most of the time doing it. :)

beetle
Posts: 51
Joined: Sat Oct 16, 2021 11:35 am

Re: Pico W Micro Python for SHT30 Temp/Humidity HELP!

Post by beetle » Wed Nov 16, 2022 4:49 pm

Rissy, another snippet of code for you in case you are still wanting to get the correct time on the rpi-picoW. There is an alternative to ntptime and thats to use worldtime. If you want to go down that route then I suggest you copy the code to your picoW and run it. Then examine the code relating to the world get_world_time() function. Also look at http://worldtimeapi.org for a fuller explanation

However, its probably best to tuck this away for a rainy day, and make use of the main rpi for you logging and time requirements. But there you go, its a good way to get the correct time on the picoW where its required to do so.

Code: Select all

import ujson as json
import urequests as requests
import network
import time
import ubinascii
import machine
rtc = machine.RTC()

#********************************
ssid = 'YOUR_SSID'
password = 'YOUR_PASSWORD'
#********************************

def wlan_connect():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.config(pm = 0xa11140)
    wlan.connect(ssid, password)

    # Wait for connect or fail
    max_wait = 10
    while max_wait > 0:
        if wlan.status() < 0 or wlan.status() >= 3:
            break
        max_wait -= 1
        print('waiting for connection...')
        time.sleep(1)

    #Handle connection error
    if wlan.status() != 3:
        raise RuntimeError('network connection failed - status: ',wlan.status())
        #note:
        #define CYW43_LINK_DOWN         (0)
        #define CYW43_LINK_JOIN         (1)
        #define CYW43_LINK_NOIP         (2)
        #define CYW43_LINK_UP           (3)
        #define CYW43_LINK_FAIL         (-1)
        #define CYW43_LINK_NONET        (-2)
        #define CYW43_LINK_BADAUTH      (-3)
    else:
        print('connected')
        status = wlan.ifconfig()
        print( 'ip = ' + status[0] )
        mac = ubinascii.hexlify(network.WLAN().config('mac'),':').decode()
        print('MAC: ', mac)
        print('channel: ', wlan.config('channel'))
        print('SSID: ', wlan.config('essid'))
        print('txpower: ', wlan.config('txpower'))
        print()
        return True

def get_world_time():
    global rtc
    received = None
    URL = "http://worldtimeapi.org/api/timezone/Europe/London"
    #URL = "http://worldtimeapi.org/api/ip"
    while True:
        try:
            received = requests.get(URL)
            break
        except ValueError as e:
            print('error: ',e)
            time.sleep(1)

    time_dic = json.loads(received.content)
    
    for key,data in time_dic.items():
       print(key,':',data)
        
    current_time = time_dic['datetime']
    the_date,the_time = current_time.split('T')
    year, month, mday = [int(x) for x in the_date.split('-')]
    the_time = the_time.split('.')[0]
    hours, minutes, seconds = [int(x) for x in the_time.split(':')]
    year_day = time_dic['day_of_year']
    week_day = time_dic['day_of_week']
    is_dst = time_dic['dst']
    now = (year, month, mday, week_day, hours, minutes, seconds, 0)
    print(now)
    #rtc.datetime((year, month, mday, week_day, hours, minutes, seconds, 0))
    rtc.datetime(now)
    received.close()

if wlan_connect():
    get_world_time()

print(rtc.datetime())
time.sleep(10)
print(rtc.datetime())
print(time.localtime())                     
    



Rissy
Posts: 116
Joined: Sun Aug 14, 2022 8:15 am

Re: Pico W Micro Python for SHT30 Temp/Humidity HELP!

Post by Rissy » Wed Nov 16, 2022 6:11 pm

Thank you. I'll check it out.....once i'm successfully writing an error message to a simple text file.

This still isn't working.

This is what I have now, based on your input:

Code: Select all

def appendfile(message, error):
    print(message,",",error)
    with open('errorlog.txt', 'a') as file:
        file.write(message)
        file.write(',')
        file.write(error)
        file.write('\n')
        file.close()

def sht_error(ex):
    print("something went wrong reading the SHT-30!")
    print('Error:', ex)
    message = 'SHT Error:'
    appendfile(message, ex) #message, error
the result of this on-screen:

Code: Select all

something went wrong reading the SHT-30!
Error: Bus error
SHT Error: , Bus error
Traceback (most recent call last):
  File "<stdin>", line 74, in <module>
  File "<stdin>", line 57, in readsensor
  File "<stdin>", line 44, in sht_error
  File "<stdin>", line 36, in appendfile
TypeError: object with buffer protocol required
The result in errorlog.txt:

Code: Select all

SHT Error:,
What's this error all about now?

Rissy
Posts: 116
Joined: Sun Aug 14, 2022 8:15 am

Re: Pico W Micro Python for SHT30 Temp/Humidity HELP!

Post by Rissy » Wed Nov 16, 2022 6:32 pm

Scratch that. I got it!

For whatever reason, it doesn't like it unless I put each segment of the overall error log content on individual lines.

So i now have this, and it finally works!

Code: Select all

def sht_error(ex):
    print("something went wrong reading the SHT-30!")
    print('Error:', ex)
    message = 'SHT Error: '
    appendfile(message, ex) #message, error
    
def appendfile(message, error):
   with open('errorlog.txt', 'a') as file:
       file.write(message)
       errorstring=str(error)
       file.write(errorstring)
       file.write('\n')
       file.close()
Result to the screen:

Code: Select all

something went wrong reading the SHT-30!
Error: Bus error
resetting SHT30
Result to the errorlog.txt file:

Code: Select all

SHT Error: Bus error
Phew! Weeks that's not been working for! Unbelievable!

beetle
Posts: 51
Joined: Sat Oct 16, 2021 11:35 am

Re: Pico W Micro Python for SHT30 Temp/Humidity HELP!

Post by beetle » Wed Nov 16, 2022 8:07 pm

It works, but not so fast, lets tidy things up.

I believe the 'error' you pass to your funtion is a string so you dont need
errorstring=str(error)
file.write(errorstring)

all you need is
file.write(error)

But in case I'm wrong you can find out the type of any variable with the type() function.

check it out with

Code: Select all

def appendfile(message, error):
    print(type(error))
    with open('errorlog.txt', 'a') as f:
        f.write(message)
        f.write(error)
        f.write('\n')
and it should print <class 'str'> to the console.

And, as you are using a contex manager (the with statement) you dont need to close the file with
file.close()
as the contex manager will do this for you. If you want more info on contex managers then read the following:
https://realpython.com/python-with-stat ... with-files

Rissy
Posts: 116
Joined: Sun Aug 14, 2022 8:15 am

Re: Pico W Micro Python for SHT30 Temp/Humidity HELP!

Post by Rissy » Wed Nov 16, 2022 8:41 pm

beetle wrote:
Wed Nov 16, 2022 8:07 pm
It works, but not so fast, lets tidy things up.

I believe the 'error' you pass to your funtion is a string so you dont need
errorstring=str(error)
file.write(errorstring)

all you need is
file.write(error)

But in case I'm wrong you can find out the type of any variable with the type() function.

check it out with

Code: Select all

def appendfile(message, error):
    print(type(error))
    with open('errorlog.txt', 'a') as f:
        f.write(message)
        f.write(error)
        f.write('\n')
and it should print <class 'str'> to the console.
As you'll see from my 6:32pm post and the given code I used, this didn't work. I didn't assess the class i'll admit, but none the less, without first converting the error to a string, it wont print to file. I agree with you that it should, but it doesn't!?
beetle wrote:
Wed Nov 16, 2022 8:07 pm
And, as you are using a contex manager (the with statement) you dont need to close the file with
file.close()
as the contex manager will do this for you. If you want more info on contex managers then read the following:
https://realpython.com/python-with-stat ... with-files
Ah yes, of course. I'm aware of this. I obviously was in a hurry in editing yet another iteration until I got one that succeeded. :lol:

Rissy
Posts: 116
Joined: Sun Aug 14, 2022 8:15 am

Re: Pico W Micro Python for SHT30 Temp/Humidity HELP!

Post by Rissy » Fri Nov 18, 2022 12:50 pm

beetle wrote:
Wed Nov 16, 2022 4:49 pm
Rissy, another snippet of code for you in case you are still wanting to get the correct time on the rpi-picoW. There is an alternative to ntptime and thats to use worldtime. If you want to go down that route then I suggest you copy the code to your picoW and run it. Then examine the code relating to the world get_world_time() function. Also look at http://worldtimeapi.org for a fuller explanation

However, its probably best to tuck this away for a rainy day, and make use of the main rpi for you logging and time requirements. But there you go, its a good way to get the correct time on the picoW where its required to do so.

Code: Select all

import ujson as json
import urequests as requests
import network
import time
import ubinascii
import machine
rtc = machine.RTC()

#********************************
ssid = 'YOUR_SSID'
password = 'YOUR_PASSWORD'
#********************************

def wlan_connect():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.config(pm = 0xa11140)
    wlan.connect(ssid, password)

    # Wait for connect or fail
    max_wait = 10
    while max_wait > 0:
        if wlan.status() < 0 or wlan.status() >= 3:
            break
        max_wait -= 1
        print('waiting for connection...')
        time.sleep(1)

    #Handle connection error
    if wlan.status() != 3:
        raise RuntimeError('network connection failed - status: ',wlan.status())
        #note:
        #define CYW43_LINK_DOWN         (0)
        #define CYW43_LINK_JOIN         (1)
        #define CYW43_LINK_NOIP         (2)
        #define CYW43_LINK_UP           (3)
        #define CYW43_LINK_FAIL         (-1)
        #define CYW43_LINK_NONET        (-2)
        #define CYW43_LINK_BADAUTH      (-3)
    else:
        print('connected')
        status = wlan.ifconfig()
        print( 'ip = ' + status[0] )
        mac = ubinascii.hexlify(network.WLAN().config('mac'),':').decode()
        print('MAC: ', mac)
        print('channel: ', wlan.config('channel'))
        print('SSID: ', wlan.config('essid'))
        print('txpower: ', wlan.config('txpower'))
        print()
        return True

def get_world_time():
    global rtc
    received = None
    URL = "http://worldtimeapi.org/api/timezone/Europe/London"
    #URL = "http://worldtimeapi.org/api/ip"
    while True:
        try:
            received = requests.get(URL)
            break
        except ValueError as e:
            print('error: ',e)
            time.sleep(1)

    time_dic = json.loads(received.content)
    
    for key,data in time_dic.items():
       print(key,':',data)
        
    current_time = time_dic['datetime']
    the_date,the_time = current_time.split('T')
    year, month, mday = [int(x) for x in the_date.split('-')]
    the_time = the_time.split('.')[0]
    hours, minutes, seconds = [int(x) for x in the_time.split(':')]
    year_day = time_dic['day_of_year']
    week_day = time_dic['day_of_week']
    is_dst = time_dic['dst']
    now = (year, month, mday, week_day, hours, minutes, seconds, 0)
    print(now)
    #rtc.datetime((year, month, mday, week_day, hours, minutes, seconds, 0))
    rtc.datetime(now)
    received.close()

if wlan_connect():
    get_world_time()

print(rtc.datetime())
time.sleep(10)
print(rtc.datetime())
print(time.localtime())                     
    


I'm gonna look at this next, now that i've got my errorlog.txt file working.

Post Reply