Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : How to MQTT from Rpi Zero to Rpi Pico
Author | Message | ||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi all After completing this test I thought I would share with a Subject Title that would be found by others looking for help on this. '------------------------------------------------------------------------------- 'As a Dinosaur I need this reminder as to how to do it. '1: On Rpi-Zero (the Broker), with Debian Bookworm ' sudo apt-get install mosquitto mosquitto-clients ' Create Hotspot (Rpi-Hotspot) with following settings: ' Tick Connect Automatically,SSID = Rpi-Hotspot,Mode = Hotspot, Band = 2.4Ghz ' Security = WPA3 Personal,Enter Password,IPv4 = Shared to other computers ' Enter desired IP for Broker,Mask = 24,Gateway = same IP (it works) '2: On Rpi-Pico ' At Command line : OPTION WIFI SSID$,PASSWD$ will connect to Broker. ' OPTION WIFI Rpi-Hotspot,"*******" '3: Run the Rpi-Pico program below, ' A DO/LOOP continously calls TimeGet and TaskScan ' As StepNbr is 0 at boot, that is the first Case taken. ' Step -1 Connects & subscribes to topics ' Step 1 Publishes TxValue every Minute. ' Step 2 - 65535 can do what you like, but remember to reset to Step 1. ' Don't do any loops in these steps, just check and set the next StepNbr, as that ' means the others will get timely attention. '4: On Linux PC (a Client) , sudo apt-get install mosquitto-clients ' Connect to Rpi-Hotspot, Edit connection as per Rpi-Zero with new IP ' and route with Broker IP, then use the following but use your Broker IP: ' mosquitto_pub -h 192.168.0.101 -m "Test Message " -t YourTopic -d '5: When ever settings are changed, the Pico has to be reset. '------------------------------------------------------------------------------- OPTION EXPLICIT OPTION DEFAULT NONE Dim Integer CalTime,mSec,StepNbr,CommFlag,TxValue Dim Integer StartTime0,Delay0,StartTime1,Delay1 'variables for each Task DIM AS STRING IP$ SUB MM.STARTUP 'Initialise PicoMite RTC GETTIME 'DS3231 on I2C GP8,GP9 END SUB Sub MM.PROMPT 'declare Time as Prompt Print Time$ ">"; End Sub SUB Initialize Caltime = Timer 'use this as mSec at program start mSec = (Timer - CalTime) 'mSec = elapsed since started Print "Step 0 "; CalTime 'starting point at Boot iF StartTime0 = 0 THEN StartTime0 = mSec 'So that next delay is correct iF StartTime1 = 0 THEN StartTime1 = mSec 'So that next delay is correct End Sub Sub TimeGet() 'get latest mSec & check Task Flags mSec = (Timer - CalTime) 'mSec elapsed since program started If mSec - StartTime0 >= 1000 Then 'If delay elapsed, allow action on it. StartTime0 = mSec :Delay0 = 1 'reset flags EndIf If mSec - StartTime1 >= 60000 Then 'If delay elapsed, allow action on it. StartTime1 = mSec :Delay1 = 1 'reset flags EndIf 'Repeat here for StartTime2 to whatever End Sub Sub TaskScan 'Step through each Task Select case StepNbr Case -1 Print StepNbr WEB MQTT Connect "192.168.0.101", 1883,"Rpi-Hotspot","********",WebInt WEB MQTT subscribe "AmpHr" 'get what was sent WEB MQTT subscribe "Control" 'get Control Cmnd's from Rpi-Zero Print "Comm's Initiated" WEB MQTT PUBLISH "AmpHr",IP$, 0 ,1 'no reply but retain for Broker's use. Print mSec Print StartTime1 StepNbr = 1 Case 0 'At startup it comes here first If MM.INFO(WIFI STATUS) = 1 Then 'If we are connected IP$ = MM.INFO(IP ADDRESS) 'Get my IP address StepNbr = -1 'Go Initialize CommFlag = 1 'Flag to use later EndIf Case 1 If Delay1 = 1 Then ' 1 Sec time is up. StepNbr = 2 WEB MQTT PUBLISH "AmpHr",Str$(TxValue), 0 ,0 'no reply no retain StartTime1 = mSec :Delay1 = 0 ' reset for next 1 Min EndIf Case 2 StepNbr = 3 Case 3 'StepNbr = 5 'un-comment to quit after Step 3 End Select 'otherwise will run forever End Sub Sub WebInt Print "From Int. Routine" Print mm.topic$ Print mm.message$ If (mm.topic$ = "Control") AND (mm.Message$ = "Reset") then CPU-Restart EndIf StepNbr = 1 End Sub 'Program jumps here at start Do TimeGet 'get the latest time in mSec. TaskScan 'se which tasks need attention. If StepNbr = 5 Then exit do 'a way to exit program Loop WEB MQTT CLOSE ' Print "Run Time = ";mSec 'time program has run for. Print "Tot ziens" End Regards Hervey Bay Qld. |
||||
pwillard Senior Member Joined: 07/06/2022 Location: United StatesPosts: 292 |
Thank You. |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi All Correction: Case 1 Should beIf Delay1 = 1 Then ' 1 Sec time is up. StepNbr = 2 WEB MQTT PUBLISH "AmpHr",Str$(TxValue), 0 ,0 'no reply no retain StartTime1 = mSec :Delay1 = 0 ' reset for next 1 Min EndIf Case 1 Otherwise Case 1 would hog the time.If Delay1 = 1 Then ' 1 Sec time is up. WEB MQTT PUBLISH "AmpHr",Str$(TxValue), 0 ,0 'no reply no retain StartTime1 = mSec :Delay1 = 0 ' reset for next 1 Min EndIf StepNbr = 2 Regards Hervey Bay Qld. |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi All Now that I (think) I know how it all works, I have re-written to MQTT CLOSE after every transmission. It only takes 25mSec to open a connection, Publish a message and then Close the MQTT. Note that comments above code have been updated as well. In some way holding the port open when not in use may have contributed to MMCC scrolling problem. '---AmpHour.bas----------------------------------------------------------------- Why does my Tab spacing get stuffed up here ?'As a Dinosaur I need this reminder as to how to do it. 'On Debian Bookworm '1: On Rpi-Zero (the Broker), with Debian Bookworm ' sudo apt-get install mosquitto mosquitto-clients ' edit /etc/mosquitto/mosquitto.conf and add the following lines: ' allow_anonymous true ' listener 1883 ' Create Hotspot (Rpi-Hotspot) with following settings: ' Tick Connect Automatically,SSID = Rpi-Hotspot,Mode = Hotspot, Band = 2.4Ghz ' Security = WPA/WPA2/WPA3 Personal,Enter Password, ' IPv4 = Shared to other computers ' Enter desired IP for Broker,Mask = 24,Gateway = same IP (it works) ' '2: On Rpi-Pico ' At Command line : OPTION WIFI SSID$,PASSWD$ will connect to Broker. ' OPTION WIFI Rpi-Hotspot,"*******" '3: Run the Rpi-Pico program below, ' A DO/LOOP continously calls TimeGet and TaskScan ' As StepNbr is 0 at boot, that is the first Case taken. ' Step 0 Confirms (once) we can reach the Hotspot and then disconnects. ' Step 1 Publishes (once) Time to Rpi-Zero (Pico has TC). ' Step 2 Publishes (once) Pico's IP address (you can Ping from Zero) ' Step 3 Publishes (reteadly) an incrementing TxValue. ' Step 4 Start of your other code. '4: On Linux PC (a Client) , sudo apt-get install mosquitto-clients ' Connect to Rpi-Hotspot, Edit connection as per Rpi-Zero with new IP ' and route with Broker IP, then use the following but use your Broker IP: ' mosquitto_pub -h 192.168.0.101 -m "Test Message " -t YourTopic -d '5: When ever settings are changed, the Pico has to be reset. ' Purging mosquitto in Linux to re-install involves manually removing ' the /etc/mosquitto folder. ' ' Note: Haven't tested yet for how long the broker will hold onto message. ' Because Clients are sending every 30 sec's, I check every 20 sec'c. '------------------------------------------------------------------------------- OPTION EXPLICIT OPTION DEFAULT NONE DIM AS STRING IP$,Tyd$ Dim as Float TxValue Dim Integer CalTime,LoopTime,StartTime,BootTime,mSec,StepNbr,CommFlag Dim Integer StartTime0,Delay0 'variables for each Task Dim Integer StartTime1,Delay1 Dim Integer StartTime2,Delay2 Dim Integer StartTime3,Delay3 Dim Integer StartTime4,Delay4 SUB MM.STARTUP 'Initialise PicoMite RTC GETTIME 'DS3231 on I2C GP8,GP9 Print "Got Time" END SUB Sub MM.PROMPT 'declare Time as Prompt Print Time$ ">"; End Sub SUB Initialize mSec = (Timer - CalTime) 'mSec = elapsed since started StartTime0 = mSec 'So that next delay is correct StartTime1 = mSec 'So that next delay is correct StartTime2 = mSec 'So that next delay is correct StartTime3 = mSec 'So that next delay is correct StartTime4 = mSec 'So that next delay is correct TxValue = 50.0 End Sub Sub TimeGet() 'get latest mSec & check Task Flags mSec = (Timer - CalTime) 'mSec elapsed since program started If mSec - StartTime0 >= 5000 Then 'Boot Pause. StartTime0 = mSec :Delay0 = 1 'reset flags EndIf If mSec - StartTime1 >= 10000 Then 'allow Time Send. StartTime1 = mSec :Delay1 = 1 'reset flags EndIf If mSec - StartTime2 >= 10000 Then 'allow IP send. StartTime2 = mSec :Delay2 = 1 EndIf If mSec - StartTime3 >= 30000 Then 'allow A/H send. StartTime3 = mSec :Delay3 = 1 EndIf If mSec - StartTime4 >= 60000 Then 'allow ? StartTime4 = mSec :Delay4 = 1 EndIf End Sub Sub WifiConnect Print "Attempting Connection" WEB MQTT Connect "192.168.0.101", 1883,"Rpi-Hotspot","76216770",WebInt WEB MQTT subscribe "AmpHr" 'get what was sent StartTime = mSec Do If MM.INFO(WIFI STATUS) > 0 Then Exit Do mSec = (Timer - CalTime) If mSec - StartTime > 30000 Then Print "CPU-RESTART ;";MM.INFO(WIFI STATUS) CPU RESTART EndIf Loop CommFlag = 1 End Sub Sub TaskScan 'Step through each Task Select case StepNbr Case 0 'At startup it comes here first If Delay0 = 1 Then WifiConnect If CommFlag = 1 Then 'If we are connected WEB MQTT CLOSE Print "Step 0 Success,wait for 10 Sec's" StartTime0 = mSec :Delay0 = 0 'Cancel this step StartTime1 = mSec :Delay1 = 0 'refresh delay for next step. StepNbr = 1 'Go Initialize MQTT EndIf If mSec - BootTime > 30000 Then 'If it's taking to long CPU RESTART 'Reboot & try again EndIf EndIf Case 1 ' Time send; only once If Delay1 = 1 Then WifiConnect Tyd$ = Time$ WEB MQTT PUBLISH "AmpHr",Tyd$ , 0 ,1 WEB MQTT CLOSE Print "Step 1 Time sent, wait for 10 sec's;";Tyd$ StartTime1 = mSec :Delay1 = 0 StartTime2 = mSec :Delay2 = 0 'refresh delay for next step. StepNbr = 2 EndIf Case 2 'IP Addr send; only once If Delay2 = 1 Then WifiConnect IP$ = MM.INFO(IP ADDRESS) 'Get my IP address WEB MQTT PUBLISH "AmpHr",IP$,0,1 WEB MQTT CLOSE Print "IP Address sent, wait for 30 Sec's ;"IP$ StartTime2 = mSec :Delay2 = 0 StartTime3 = mSec :Delay3 = 0 'setup delay for next step. StepNbr = 3 EndIf Case 3 'Repeat send incrementing value. If Delay3 = 1 Then '30 Sec time is up. WifiConnect TxValue = TxValue + 0.1 WEB MQTT PUBLISH "AmpHr",Str$(TxValue) , 0 ,1 WEB MQTT CLOSE Print "A/H Updated ;";Str$(TxValue) StartTime3 = mSec :Delay3 = 0 StepNbr = 4 EndIf Case 4 StepNbr = 3 End Select End Sub Sub WebInt If (mm.topic$ = "Control") AND (mm.Message$ = "Reset") then CPU-Restart EndIf End Sub 'Program jumps here at start of Boot. CalTime = Timer StartTime = Timer - CalTime BootTime = StartTime StepNbr = 0 Print "Entering Wifi-Status Check" Initialize Print "Wait for 5 Sec's for Step 0" Do TimeGet 'get the latest time in mSec. TaskScan 'se which tasks need attention. If StepNbr = 5 Then exit do 'a way to exit program Loop WEB MQTT CLOSE ' Print "Tot ziens" End Edited 2023-11-22 09:02 by Dinosaur Regards Hervey Bay Qld. |
||||
lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3150 |
How would this web site know how many spaces you want a TAB to represent? I use only spaces for indentation--TABs are likely to get messed up if you move the text to anywhere other than where it started out. PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi All Good point. When I use Geany it converts for me, so will see if that is possible with MMEdit. Otherwise, just before I post, load it into Geany. Regards Hervey Bay Qld. |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi All Tidied up and final before I start adding dedicated logic for my purpose. Updated Nov 26 to fully working. AmpHour.zip Edited 2023-11-26 19:09 by Dinosaur Regards Hervey Bay Qld. |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi All Have an issue where MQTT on the Pico appears to transmit 16 characters, but am receiving only 8 on the Rpi-Zero. Can't work out if the problem is with MMBasic or FreeBasic on the Zero. On the Pico: If CommFlag = 1 Then 'If WiFiConnect succeeded TxStr = "C= " + Str$(TxValue) + ", mA = " + Str$(mAmps) On Error skip 1 WEB MQTT PUBLISH "AmpHr", TxStr , 0 ,1 If CommFlag = 1 Then If PFlag > 0 Then Print TxStr, Len(TxStr) On The Zero end I am using Mosquitto with a statement like: Open Pipe "mosquitto_sub --quiet -N --retained-only -t AmpHr -w 4" for input as #pf Input #pf, RxStr Close #pf Print RxStr + ";" + Str(Len(RxStr)); I have sent messages longer then 8, but as a single string between quotes. Perhaps the embedded semicolon ? EDIT: Either MQTT or Mosquitto at the other end doesn't like a comma in the string. Edited 2023-12-09 15:11 by Dinosaur Regards Hervey Bay Qld. |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3802 |
I expect the problem is: Input #pf, RxStr which in most BASICs will stop at the comma (in your example). You may be able to use such as LINE INPUT (if it has it). John Edited 2023-12-09 18:57 by JohnS |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi All Good find John. Not sure if Line Input will work with "Pipe" but will tests. Regards Hervey Bay Qld. |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3802 |
You may (probably will) have to send a CR and/or LF Or add another comma and then use input twice. John |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi All Just an update on this thread. After updating the Pico to WebmiteV5.08.00b4 the performance has become more reliable. It now survives the whole night sending messages every minute. Basically I have a Zero W with an MQTT Broker and Client. Transmissions published from the Pico are routed through the Broker to the Client on the Zero W. The idea is to allow the Zero W to be switched OFF during the night (save current) and then in the morning start it again. Every 3 min's the Pico goes looking for the Wifi with WEBSCAN Netscan%(). This causes a statement to be printed (out of my control) saying: Performing WiFi Scan If the Wifi is still off, then If LInStr(NetScan%(),"Rpi-Hotspot") Then fails and the Pico tries again in another 3 minutes.After running all night, I simply turn the Wifi OFF on the Zero W and wait a few minutes and turn it ON again. So, when the Wifi is ON, the Pico hangs(No heartbeat) with still only the Wifi Scan on the screen. After about 5 minutes (typing this post) I pressed Ctrl C with no result. So I turned the Wifi OFF again, thinking it may escape the loop. A few minutes later I got Not Found and the command prompt.This whole episode would have taken 15 minutes. Would it have got there without me pressing Ctrl C ? Worth noting that the Zero W never fails. So I think there is still an issue with the WEB part but I can't identify what or where. But at least now it can be chewed over by others.Hope there is enough detail. EDIT: When I simply pressed RUN to restart the program on the Pico, the following print statements are executed at the beginning of the program, but it appears to hang on the SETPIN statements. Print "Var Restored = ";BattCapacity So then I have to repower.Print "Got RTC = ";Time$ Print "Got Version = ";MM.Ver Print "On platform = ";MM.Device$ Print "CPU Speed = ";MM.Info(CPUSPEED) Print "Drive Capacity = ";MM.Info(DISK SIZE) Print "Drive SpaceLeft = ";MM.Info(Free Space) Print "Nbr of Variables= ";MM.Info(VARCNT) If BattCapacity = 0 Then BattCapacity = 12000 'Coulomb = 200A x 60 = 12,000 SetPin GP18,CIN 'we are counting Amp Hour pulses SetPin GP22,CIN 'no option means Risng edge PULLDOWN Print "Finished setting Pins" Edited 2023-12-14 06:24 by Dinosaur Regards Hervey Bay Qld. |
||||
Print this page |