Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 03:45 27 Nov 2024 Privacy Policy
Jump to

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: Australia
Posts: 311
Posted: 12:03am 20 Nov 2023
Copy link to clipboard 
Print this post

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 States
Posts: 292
Posted: 06:12pm 20 Nov 2023
Copy link to clipboard 
Print this post

Thank You.
 
Dinosaur

Guru

Joined: 12/08/2011
Location: Australia
Posts: 311
Posted: 10:30pm 20 Nov 2023
Copy link to clipboard 
Print this post

Hi All

Correction:
  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
Should be
  Case 1
    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
Otherwise Case 1 would hog the time.
Regards
Hervey Bay Qld.
 
Dinosaur

Guru

Joined: 12/08/2011
Location: Australia
Posts: 311
Posted: 11:00pm 21 Nov 2023
Copy link to clipboard 
Print this post

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-----------------------------------------------------------------
'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
Why does my Tab spacing get stuffed up here ?
Edited 2023-11-22 09:02 by Dinosaur
Regards
Hervey Bay Qld.
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3150
Posted: 12:58am 22 Nov 2023
Copy link to clipboard 
Print this post

  Dinosaur said  Why does my Tab spacing get stuffed up here ?


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: Australia
Posts: 311
Posted: 04:01am 22 Nov 2023
Copy link to clipboard 
Print this post

Hi All

  Quote  How would this web site know how many spaces you want a TAB to represent?

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: Australia
Posts: 311
Posted: 08:25am 23 Nov 2023
Copy link to clipboard 
Print this post

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: Australia
Posts: 311
Posted: 02:51am 09 Dec 2023
Copy link to clipboard 
Print this post

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));
Which prints the first 8 Char's of the string and reports the string as 8 Char long ?
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 Kingdom
Posts: 3802
Posted: 08:56am 09 Dec 2023
Copy link to clipboard 
Print this post

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: Australia
Posts: 311
Posted: 09:48am 09 Dec 2023
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 3802
Posted: 10:57am 09 Dec 2023
Copy link to clipboard 
Print this post

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: Australia
Posts: 311
Posted: 07:53pm 13 Dec 2023
Copy link to clipboard 
Print this post

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
   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"
So then I have to repower.
Edited 2023-12-14 06:24 by Dinosaur
Regards
Hervey Bay Qld.
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024