Pico W Micro Python MQTT of data to a RP4B

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 MQTT of data to a RP4B

Post by beetle » Mon Aug 22, 2022 5:55 pm

Rissy,

Try to only use the on-message callback function to examine the message topic and to pass the data to another function appropriate to the message. Good practice is to make functions do one thing only and do it well rather then load them up with too much baggage.

But thats an aside, does the following illustrate a way of using your pesky global variables.
In a file called module1.py put in the following code:

Code: Select all

# Set up a global varialbe and initialise it with a value
gVar = 0.0 

# define a fuction that will set the global variable
def set_me_var():
    global gVar
    gVar = 22.23
in another file called module_main.py put in the following code:

Code: Select all

import module1

module1.set_me_var()   # run the fuction in module1
print(module1.gVar)    # print the global var in module1

Then run module_main.py and I hope all is clear.

If your global vars are shared between many modules then create a file just for them e.g. my_naughty_globals.py and import this module into the other modules that may need to reference them. Thus a global var of 'rissy_pesky_one' set up in this shared module will be referenced in these modules by - 'my_naughty_globals.rissy_pesky_one' .
I must emphasise the naming of this file as 'my_naughty_globals' is mandatory :D

And a edit to remind that global variables and only global to the module in which they are defined. They are not global outside of the module thus you have to directly access them with the module.var way of accessing them, and you have to import the module as well.

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

Re: Pico W Micro Python MQTT of data to a RP4B

Post by Rissy » Mon Aug 22, 2022 6:43 pm

beetle wrote:
Mon Aug 22, 2022 5:55 pm
Rissy,

Try to only use the on-message callback function to examine the message topic and to pass the data to another function appropriate to the message.
This is all i wanted to do in all fairness. I just couldn't move my GV made from the message payload outside of that function. It was trapped!? So that's why i had no choice but to load it up with writing my GV to a file instead. That's still literally all its doing though.
beetle wrote:
Mon Aug 22, 2022 5:55 pm
But thats an aside, does the following illustrate a way of using your pesky global variables.
In a file called module1.py put in the following code:

Code: Select all

# Set up a global varialbe and initialise it with a value
gVar = 0.0 

# define a fuction that will set the global variable
def set_me_var():
    global gVar
    gVar = 22.23
in another file called module_main.py put in the following code:

Code: Select all

import module1

module1.set_me_var()   # run the fuction in module1
print(module1.gVar)    # print the global var in module1

Then run module_main.py and I hope all is clear.
So what you're saying is that the one thing i did wrong is not declare the GV at the beginning of my script outside of the function and assign it an arbitrary value of zero and then reiterate its existence as a global variable AGAIN from within the function too?

OMG.

Why didn't you only bring in the global variable from module 1 using:

Code: Select all

from module1 import gVar gVar_from_module1
? or somthing to that effect? Instead of the whole module1.py?

Is that not a more accepted, more minimalist approach to passing global variables between scripts (you're calling them modules)?

Also, you said "module1.set_me_var() # run the fuction in module1". Does this run the function script where the GV is produced in module1.py? Why would you need to do this if that script is already running in parallel to the module_main.py script?
beetle wrote:
Mon Aug 22, 2022 5:55 pm
If your global vars are shared between many modules then create a file just for them e.g. my_naughty_globals.py and import this module into the other modules that may need to reference them. Thus a global var of 'rissy_pesky_one' set up in this shared module will be referenced in these modules by - 'my_naughty_globals.rissy_pesky_one' .
I must emphasise the naming of this file as 'my_naughty_globals' is mandatory :D
Thy shall be done. :lol:
beetle wrote:
Mon Aug 22, 2022 5:55 pm
And a edit to remind that global variables and only global to the module in which they are defined. They are not global outside of the module thus you have to directly access them with the module.var way of accessing them, and you have to import the module as well.
I don't get what you said here?


My second RP4B and my second Pico W arrived today. I'm going to be also buying some other play things, like a small LCD screen, resistors, LEDs, potentiometer so that i can have a play with more real worldy type items. Once i've got my RP4B initialised and setup similar to my first one, I'll set up MQTT on there too, and bring in the same values from the first RP4B and have a go at manipulating my scripts more now that you've shown me where i went wrong. (thank you, finally).

Ultimately, I want to put my Pico W in the loft instead of my RP4B, so i'll be spending time inversing each of their current functionality by using these second ones here to do the testing with and leave my current monitoring system running the whole time until i'm happy to do the switcheroony dealy bopper.

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

Re: Pico W Micro Python MQTT of data to a RP4B

Post by beetle » Mon Aug 22, 2022 7:45 pm

Rissy wrote:
Mon Aug 22, 2022 6:43 pm
beetle wrote:
Mon Aug 22, 2022 5:55 pm
Rissy,

Try to only use the on-message callback function to examine the message topic and to pass the data to another function appropriate to the message.
This is all i wanted to do in all fairness. I just couldn't move my GV made from the message payload outside of that function. It was trapped!? So that's why i had no choice but to load it up with writing my GV to a file instead. That's still literally all its doing though.
beetle wrote:
Mon Aug 22, 2022 5:55 pm
But thats an aside, does the following illustrate a way of using your pesky global variables.
In a file called module1.py put in the following code:

Code: Select all

# Set up a global varialbe and initialise it with a value
gVar = 0.0 

# define a fuction that will set the global variable
def set_me_var():
    global gVar
    gVar = 22.23
in another file called module_main.py put in the following code:

Code: Select all

import module1

module1.set_me_var()   # run the fuction in module1
print(module1.gVar)    # print the global var in module1

Then run module_main.py and I hope all is clear.
So what you're saying is that the one thing i did wrong is not declare the GV at the beginning of my script outside of the function and assign it an arbitrary value of zero and then reiterate its existence as a global variable AGAIN from within the function too?

Certainly you should declare your global outside of the function if you want to reference it from another module (file or whatever). When a variable is created you need to assign it a value or you get an error. And yes if you want to use the global variable in a function you need to declare it global or another local to the function variable of the same name will be created in the function. I suggest you play with these simple modules I presented to see what happens if you dont create the global as I suggest.

OMG.

Why didn't you only bring in the global variable from module 1 using:

Code: Select all

from module1 import gVar gVar_from_module1
? or somthing to that effect? Instead of the whole module1.py?
Is that not a more accepted, more minimalist approach to passing global variables between scripts (you're calling them modules)?

I think you are suggesting: from module1 import set_me_var, gVar, Well give it a go and report back what happens :D ps a hint that that separate a naughty_globals_variable.py file could be handy :shock:


Also, you said "module1.set_me_var() # run the fuction in module1". Does this run the function script where the GV is produced in module1.py? Why would you need to do this if that script is already running in parallel to the module_main.py script?
Yes it runs the function created in module1 and this will update the global var created in module1
beetle wrote:
Mon Aug 22, 2022 5:55 pm
If your global vars are shared between many modules then create a file just for them e.g. my_naughty_globals.py and import this module into the other modules that may need to reference them. Thus a global var of 'rissy_pesky_one' set up in this shared module will be referenced in these modules by - 'my_naughty_globals.rissy_pesky_one' .
I must emphasise the naming of this file as 'my_naughty_globals' is mandatory :D
Thy shall be done. :lol:
beetle wrote:
Mon Aug 22, 2022 5:55 pm
And a edit to remind that global variables and only global to the module in which they are defined. They are not global outside of the module thus you have to directly access them with the module.var way of accessing them, and you have to import the module as well.
I don't get what you said here?
Well I should have said 'global variable are and not and etc. But I think you will benefit from a little googling on 'python global variable' theres a lot of good stuff out there and its well worth understanding how python namespaces work.

My second RP4B and my second Pico W arrived today. I'm going to be also buying some other play things, like a small LCD screen, resistors, LEDs, potentiometer so that i can have a play with more real worldy type items. Once i've got my RP4B initialised and setup similar to my first one, I'll set up MQTT on there too, and bring in the same values from the first RP4B and have a go at manipulating my scripts more now that you've shown me where i went wrong. (thank you, finally).
May I humbly suggest you only take the essence of what you are attempting to do but base it on the rpi4 mqtt code I presented. Its a cut down version of a program I use, but its fully working and will respond to any mqtt messages that match the subscritions found in the program
Ultimately, I want to put my Pico W in the loft instead of my RP4B, so i'll be spending time inversing each of their current functionality by using these second ones here to do the testing with and leave my current monitoring system running the whole time until i'm happy to do the switcheroony dealy bopper.
You got a new rpi4, I hav'nt see one available for a long time... I'm off to see if I can fine one :o

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

Re: Pico W Micro Python MQTT of data to a RP4B

Post by beetle » Mon Aug 22, 2022 9:21 pm

Rissy, I can't find any rpi4's :(

maybe you like these examples better 8-)

module_globals.py:

Code: Select all

gVar = 0
module1.py:

Code: Select all

import module_globals

# define a fuction that will set the global variable
def set_me_var():
    module_globals.gVar = 22.63
    print("module1 says I've set gVar to 22.63")
module_main.py:

Code: Select all

import module_globals
from  module1 import set_me_var

print('module_main says the value of gVar is: ', module_globals.gVar)
set_me_var() 
print('module_main now says gVar is: ', module_globals.gVar)
Result:
module_main says the value of gVar is: 0
module1 says I've set gVar to 22.63
module_main now says gVar is: 22.63

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

Re: Pico W Micro Python MQTT of data to a RP4B

Post by beetle » Tue Aug 23, 2022 5:56 am

Rissy,
The examples on the global var's was to show how they could be used, mainly because you kept on remarking about their use in your programs. But I would be very remiss if I did not point out there is usually a better way so I finish up with this small example of the same sort of thing but not a global in sight. 8-)

module1.py:

Code: Select all

# define a fuction that will return a value
def set_me_var():
    # so stuff to read sensors and set a varible to a value
    temperature = 20.8
    return  temperature 
module_main.py

Code: Select all

from  module1 import set_me_var

whats_me_temp = set_me_var()
print(whats_me_temp)

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

Re: Pico W Micro Python MQTT of data to a RP4B

Post by Rissy » Tue Aug 23, 2022 6:38 am

beetle wrote:
Mon Aug 22, 2022 9:21 pm
Rissy, I can't find any rpi4's :(

maybe you like these examples better 8-)

module_globals.py:

Code: Select all

gVar = 0
module1.py:

Code: Select all

import module_globals

# define a fuction that will set the global variable
def set_me_var():
    module_globals.gVar = 22.63
    print("module1 says I've set gVar to 22.63")
module_main.py:

Code: Select all

import module_globals
from  module1 import set_me_var

print('module_main says the value of gVar is: ', module_globals.gVar)
set_me_var() 
print('module_main now says gVar is: ', module_globals.gVar)
Result:
module_main says the value of gVar is: 0
module1 says I've set gVar to 22.63
module_main now says gVar is: 22.63
Ah i see. I'm with you on this one. I understand now. No wonder i never got this. This is quite convoluted and verbose to do what i wanted to do. Reading through the guides I certainly never got this gist at all. I'm one of these people who can only learn so much by trying to read content as my brain seems to interpret things in a weird way sometimes. So I find it necessary to branch out to other sources to help me where I can't interpret the written word (YouTube, forums etc) and even asking for a real world example for me to follow and then I get a handle on where i've gone wrong.
Once i have a working proven method of something which i've written myself after being shown how, even if i forget in the future, i'll be able to remind myself easier by reading my own words. You'll notice from my previously submitted coding examples that I heavily comment, especially on more new or complicated pieces of coding. That's me employing memory self preservation techniques right there.

I appreciate you trying to force me to learn in ways which perhaps you've have to do yourself, but if you knew me, you'd understand that I'm asking on a forum because i've exhausted other routes before then, and even if people can give me a nudge in the right direction, that's sometmes enough. I'll soon say if i need a real world example to help me.

We only live one life, and for days of that short life last week I chased after trying different things to get me over a hurdle, and spent numerous hours trying to find the information i needed to get me to understand, and completely failed. Hence why i came to a forum to ask for help. You've helped me no doubt, but after that initial nudge with the if statements, I was very much chasing the carrot without a chance of grabbing it (much to your amusement of course). You only conceded once i had my own working solution to get around one particular topic of understanding i was clearly having diffculty with.

Thank you for finally coming through for me, and showing me (spelling out for me) what i needed (need) to do, to fix my code to neaten it up. I do appreciate it, finally. Just as well i'm an extremely patient person. Although if i hadn't found my own work around, i'd probably have lost that patnience and tried a different forum to ask someone else for some help. You were the only person to swoop in with your cape on and help me, so i can't fault you for that and I certainly recognise that, it's very much appreciated. Perhaps next time though (providing you still have patience for me), you'll help me out a bit more direclty...? ;)

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

Re: Pico W Micro Python MQTT of data to a RP4B

Post by Rissy » Tue Aug 23, 2022 6:45 am

beetle wrote:
Tue Aug 23, 2022 5:56 am
Rissy,
The examples on the global var's was to show how they could be used, mainly because you kept on remarking about their use in your programs. But I would be very remiss if I did not point out there is usually a better way so I finish up with this small example of the same sort of thing but not a global in sight. 8-)

module1.py:

Code: Select all

# define a fuction that will return a value
def set_me_var():
    # so stuff to read sensors and set a varible to a value
    temperature = 20.8
    return  temperature 
module_main.py

Code: Select all

from  module1 import set_me_var

whats_me_temp = set_me_var()
print(whats_me_temp)
I've had to buy the beginners kits twice.

https://thepihut.com/collections/raspbe ... tarter-kit

This is how i've bought by Pi's. They're only 2GB of course, but that seems to be enough for what I am using them for at this stage of my learning and capability. I was only pointed towards RP's from a colleague when we started discussing my loft monitoring requirements. As I said, i'm brand new to this whole thing as of about 4-5 weeks ago.

I don't think i've made bad progress in that time, but it's come a a cost. Everything else has gone by the way-side due to my steep learning curve and the hourse been necessary to pull something out of the bag. This time obviously cut down emmensely with people having already written drivers etc which i'd have had to spend months or years trying to do myself. Time I just don't have.

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

Re: Pico W Micro Python MQTT of data to a RP4B

Post by Rissy » Tue Aug 23, 2022 8:07 am

beetle,

I'd like to just run past you what i've put, just so can absolutely be certain i have the idea (against my own working programs to change them)

To remind you:

MQTT_PW_Vars.py is my MQTT subscribing code
Global_Variables.py is your suggested inclusion of a GV code
PicoW_Vars.py is my logging code

==============

In MQTT_PW_Vars.py I put (only showing pertinent code, not whole thing):

import Global_Variables

OS_Temp = '0'
OS_Hum = '0'
Pico_Temp = '0'


def on_message(client, userdata, message):
#topics = message.topic.split('/') # topics is now a list containing the topic segments
#topics = message.topic.split() # topics is now a list containing the topic segments
topics = message.topic
#print(topic[1])
payload = message.payload.decode("utf-8") #is this the right thing to do? Try just using the message.topic without decoding first
#print(payload)
if topics == topic1:
global OS_Temp
print(f"Received: {(message.payload.decode('utf-8'))} from Topic: {message.topic}")
Global_Variables.GVAR = message.payload
OS_Temp = str(Global_Variables.GVAR)
#PWTfile = open(PicoTempFile, 'w')
#PWTfile.write(OS_Temp)
#PWTfile.close()
msg1set=True
(return msg1set)
if topics == topic2:
global OS_Hum
print(f"Received: {(message.payload.decode('utf-8'))} from Topic: {message.topic}")
Global_Variables.GVAR = message.payload
OS_Hum = str(Global_Variables.GVAR)
#PWHfile = open(PicoHumFile, 'w')
#PWHfile.write(OS_Hum)
#PWHfile.close()
msg2set=True
return(msg2set)
if topics == topic3:
global Pico_Temp
print(f"Received: {(message.payload.decode('utf-8'))} from Topic: {message.topic}")
Global_Variables.GVAR = message.payload
Pico_Temp = str(Global_Variables.GVAR)
#PicoFile = open(CPUFile, 'w')
#PicoFile.write(Pico_Temp)
#PicoFile.write("\n")
#PicoFile.close()
msg3set=True
return(msg3set)

=======================

In Global_Variables.py I put:

#!/usr/bin/env python
#!/bin/bash
#Global_Variables.py

GVAR = 0

======================

In PicoW_Vars.py I put (only showing pertinent code, not whole thing):

import Global_Variables
from MQTT_PW_Vars import on_message


#collect readings from Pico W
#Picoread1 = open(PicoTempFile, 'r')
#string1 = Picoread1.read()
#Picoread1.close()
#float1 = float(string1)
#temperature = float1
on_message()
temperature = OS_Temp


#Picoread2 = open(PicoHumFile, 'r')
#string2 = Picoread2.read()
#Picoread2.close()
#float2 = float(string2)
#humidity = float2
on_message()
humidity = OS_Hum


#Picoread3 = open(PicoFile, 'r')
#string3 = Picoread3.read()
#Picoread3.close()
#float3 = float(string3)
#picotemp = float3
on_message()
picotemp = Pico_Temp


=========================

Is that it? Do i have it? (Please just be straight with me now, I'm having a hard enough time trying to get this into my thick skull)

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

Re: Pico W Micro Python MQTT of data to a RP4B

Post by Rissy » Tue Aug 23, 2022 9:45 am

Also
May I humbly suggest you only take the essence of what you are attempting to do but base it on the rpi4 mqtt code I presented. Its a cut down version of a program I use, but its fully working and will respond to any mqtt messages that match the subscritions found in the program
I've yet to have a proper look at your suggested code i'll admit. I've taken a copy of them both and i'll take a look through and see if i understand them. Be prepared for me to ask more silly questions if i don't though! :lol:

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

Re: Pico W Micro Python MQTT of data to a RP4B

Post by beetle » Tue Aug 23, 2022 10:49 am

Is that it? Do i have it? (Please just be straight with me now, I'm having a hard enough time trying to get this into my thick skull)
To be straight, then no I don't think so, but I find it very hard to make sense of your sudo code, it quite boggles my eyes :shock:

I believe your situation is that you have a working program that gives you the results you need, but you know there must be a better way to code it up. So you are going to now take your time with your new rpi4 and rpi pico to re-program your project, but theres now time to get this done to a better standard whilst your initial effort chugs away. An to this end I really do think it worth stepping back from your initial code and taking the time to rethink its structure. Don't get too stuck in your initial thoughts on how your program is coded and try not to get a bit blinkered with your use of global variables. These only so much one can tart up an old lady, perhaps is now time to try you luck with a sweet young bimbo :D (metaphorically speaking of course ;) )

I would suggest you copy the examples of the code I provided into python scripts named as I suggest, and then run them and take an hour to play around with them a bit. I would suggest especially take note of the last example of not needing to use global variables in most cases. I'm not sure you took that on-board as you copy my post but don't reference it in your reply. Give yourself a bit of time.

Post Reply