Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

Ultra Light MQTT client
Goto page 1, 2  Next
 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> Share your working BASCOM-AVR code here
View previous topic :: View next topic  
Author Message
bzijlstra

Bascom Ambassador



Joined: 30 Dec 2004
Posts: 1179
Location: Tilburg - Netherlands

netherlands.gif
PostPosted: Tue May 31, 2016 6:27 pm    Post subject: Ultra Light MQTT client Reply with quote

This is a Ultra Light MQTT client. An Arduino Mega 2560 with a W5100 ethernet shield acting as a Ultra Light MQTT client.

If you want to read more about this MQTT protocol check

http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html



On the left our Arduino Mega 2560 with W5100 ethernet shield. Doing a connect / publish / disconnect. This can be all kind of information published to a MQTT broker server. On PC, Mobiel, you can subscribe to these messages and get an update everytime new information is published.

The flow of the network traffic in WireShark. You will find each item back in the Bascom-code below



Code:
'Bascom Ultra Light MQTT client

'Hardware: Arduino Mega 2560 with W5100 Ethernet shield

'Ben Zijlstra - 2016

$regfile = "m2560def.dat"                                   ' specify the used micro
$crystal = 16000000                                         ' used crystal frequency
$baud = 56700                                               ' use baud rate
$hwstack = 200
$swstack = 220
$framesize = 250

Config Portb.4 = Output
Wiz5100_cs Alias Portb.4
Wiz5100_cs = 1
Waitms 500

Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0
Spiinit


Config Tcpip = Noint , Mac = 12.128.12.33.46.74 , Ip = 192.168.0.221 , Submask = 255.255.255.0 , Gateway = 192.168.0.1 , _
Localport = 1000 , Tx = $55 , Rx = $55 , Chip = W5100 , Spi = 1 , Cs = Portb.4

Dim Idx As Byte
Dim Bclient As Byte
Dim Result As Word
Dim X As Byte
Dim S As Word
Dim I As Byte
Dim Tempw As Word
Dim Helpw As Word

Const Cdebug = 1                                            'for debug purpose

Const Connect = "{016}{025}{000}{004}MQTT{004}{002}{000}{030}{000}{013}Bascom-Client"
Const Publish = "{048}{034}{000}{007}mcselecBascom-MQTT-client online"
Const Pingreq = "{192}{000}"                                '&HC0 &H00 - keep alive
Const Disconnect = "{224}{000}"                             '&HE0 &H00

Print "Programm start"

Idx = 0
Bclient = Getsocket(idx , Sock_stream , 7000 , 0)

Result = Socketconnect(idx , <ip-address of your MQTT-broker> , 1883)          'the IP-address of the MQTT broker and the port
Do
     Tempw = Socketstat(idx , 0)                            'get status
     If Tempw = Sock_established Then
          #if Cdebug
               Print "Socket established with MQTT broker"
          #endif
          Exit Do
     End If
Loop

#if Cdebug
     Print "Connect"
#endif
Result = Tcpwrite(idx , Connect)                            'connect to the broker

Do
     Tempw = Socketstat(idx , Sel_recv)                       'get received bytes
     If Tempw > 0 Then                                      'if there is something received
          Helpw = Tcpread(idx , S , Tempw)                  'read
          If S = &H220 Then
               #if Cdebug
                    Print "Connect ACK"
               #endif
               Exit Do
          End If
     End If
Loop

#if Cdebug
     Print "Publish"
#endif
Result = Tcpwrite(idx , Publish)                            'publish the message

Wait 4

'For X = 1 To 10
'     Result = Tcpwrite(idx , Pingreq)                       'ping - keep alive
'     Wait 10
'Next X
'Wait 4

#if Cdebug
     Print "Disconnect"
#endif
Result = Tcpwrite(idx , Disconnect)                         'disconnect

Wait 4
Socketdisconnect Idx                                        'disconnect socket

End


If you remove the remarks at the PINGREQ line, you will see PINGREQuest at work. This is a keep-alive message to the MQTT-broker server.

And here a picture of a Android smartphone with a MQTT client and some messages that are published.



To do some tests you could install an Open Source MQTT v3.1/v3.1.1 Broker server like Mosquitto.

Have fun
Ben Zijlstra


Last edited by bzijlstra on Sat Jun 04, 2016 2:51 pm; edited 1 time in total
Back to top
View user's profile Visit poster's website
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 6198
Location: Holland

blank.gif
PostPosted: Tue May 31, 2016 7:29 pm    Post subject: Reply with quote

wonderful Ben !
It is great you pointed this MQTT out to me. This is the way to go for IoT. The protocol is versatile and complete. It is also proven and ere to stay.
I did read the protocol but i find it simpler to read your bascom code.
Thanks for your work on this.

_________________
Mark
Back to top
View user's profile Visit poster's website
bzijlstra

Bascom Ambassador



Joined: 30 Dec 2004
Posts: 1179
Location: Tilburg - Netherlands

netherlands.gif
PostPosted: Sat Jun 04, 2016 2:46 pm    Post subject: MQTT - connect / subscribe / publish / ping Reply with quote

Next step

Same program but added a subscribe and a keep-alive with pingrequest

If you check the connect string you will find a keep alive value. The client has to pingrequest the MQTT broker before the end of the keep alive time.
In this example the keep alive time in the connect string is 70 seconds, but the keep alives are every 60 seconds.

If you don't send a keep alive in time, the MQTT broker will disconnect the client.

Every time something is received or send, the keep alive timer can be set to 0.

Subscribe is to the topic mcselec

The first message Bascom-MQTT-client online is send by the client (our Arduino Mega 2560 with Ethernet shield)
and the second message has been typed on a SmartPhone with a MQTT client. Publishing Hello Bascom World! to the topic mcselec.



It still is a light client, there is a lot more to configure in the MQTT client.


Updated code!!


Code:
'Light Bascom MQTT client

'connect / publish / subscribe / pingreq / (disconnect)

'publish and subscribe to Topic mcselec

'Hardware: Arduino Mega 2560 with W5100 Ethernet shield

'Ben Zijlstra - 2016

$regfile = "m2560def.dat"                                   ' specify the used micro
$crystal = 16000000                                         ' used crystal frequency
$baud = 56700                                               ' use baud rate
$hwstack = 200
$swstack = 220
$framesize = 250

Config Portb.4 = Output
Wiz5100_cs Alias Portb.4
Wiz5100_cs = 1
Waitms 500

Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0
Spiinit


Config Tcpip = Noint , Mac = 12.128.12.33.46.74 , Ip = 192.168.0.221 , Submask = 255.255.255.0 , Gateway = 192.168.0.1 , _
Localport = 1000 , Tx = $55 , Rx = $55 , Chip = W5100 , Spi = 1 , Cs = Portb.4

Dim Idx As Byte
Dim Bclient As Byte
Dim Result As Word
Dim X As Byte
Dim S As Long
Dim I As Byte
Dim Tempw As Word
Dim Helpw As Word
Dim Status As Long
Dim Teller As Word
Dim Z(200) As Byte
Dim B As Byte
Dim Y As Byte
Dim Messagelen As Byte
Dim Message2 As String * 200

Dim Minteller As Word


Teller = 0

Const Cdebug = 0
Const C2dbug = 1                                            'for debug purpose

'Connect is   {016}(&H10) MQTT Control Packet type
'             {025}       Length message
'             {000}       Length protocol name MSB
'             {004}       Length protocol name LSB
'             MQTT        Protocol name
'             {004}       Protocol level
'             {002}       Connect flags (002 = Clean Session)
'             {000}       Keep alive MSB
'             {070}       Keep alive LSB (70 seconds)
'             {000}
'             {013}       Length client-ID
'             Bascom-client (Client-ID)


Const Connect = "{016}{025}{000}{004}MQTT{004}{002}{000}{070}{000}{013}Bascom-Client"

'Publish is   {048}(&H30) MQTT Control Packet type
'             {034}       Length message
'             {000}
'             {007}       Length topic
'             mcselec     Topic
'             Bascom-MQTT-client online (message)

Const Publish = "{048}{034}{000}{007}mcselecBascom-MQTT-client online"

'Subscribe is {130}(&H82) MQTT Control Packet type
'             {012}       Length message
'             {000}
'             {002}
'             {000}
'             {007}       Length of topic
'             mcselec     Subscribe to topic mcselec
'             {000}

Const Confirm = "{048}{030}{000}{007}mcselecReceived MQTT-message"

Const Subscribe = "{130}{012}{000}{002}{000}{007}mcselec{000}"

Const Pingreq = "{192}{000}"                                '&HC0 &H00 - ping request - keep alive

Const Disconnect = "{224}{000}"                             '&HE0 &H00

Print "Programm start"
Print

Idx = 0
Bclient = Getsocket(idx , Sock_stream , 7000 , 0)           'Open socket TCP (sock_stream), local port 7000
Result = Socketconnect(idx , xxx.xxx.xxx.xxx , 1883)          'the IP-address of the MQTT broker and the port
Do
     Tempw = Socketstat(idx , 0)                            'get status
     If Tempw = Sock_established Then
          #if C2dbug
               Print "Socket established with MQTT broker"
          #endif
          Exit Do
     End If
Loop


#if Cdebug
     Print "Connect"
#endif
Result = Tcpwrite(idx , Connect)                            'connect to the broker

Do
     Tempw = Socketstat(idx , Sel_recv)                     'get received bytes
     If Tempw > 0 Then                                      'if there is something received
          Helpw = Tcpread(idx , S , Tempw)                  'read
          Status = S And &H0000FFFF                         'two bytes
          If Status = &H00000220 Then
               #if C2dbug
                    Print "Connect ACK"
               #endif
               Exit Do
          End If
     End If
Loop

#if C2dbug
     Print "Subscribe"
#endif
Result = Tcpwrite(idx , Subscribe)                          'subscribe to topic

Do
     Tempw = Socketstat(idx , Sel_recv)                     'get received bytes
     If Tempw > 0 Then                                      'if there is something received
          Helpw = Tcpread(idx , S , Tempw)                  'read
          Status = S And &H00FFFFFF                         'three bytes
          If Status = &H00000390 Then
               #if C2dbug
                    Print "Subscribe ACK"
               #endif
               Teller = 0                                   'reset the keep alive
               Exit Do
          End If
     End If
Loop
Wait 4

#if C2dbug
     Print "Publish"
#endif
Result = Tcpwrite(idx , Publish)                            'publish the message
Teller = 0                                                  'reset the keep alive

'is something published in the subscribed topic?
Do
     Tempw = Socketstat(idx , Sel_recv)                     'get received bytes

     If Tempw = 2 Then                                      '2 bytes, a reaction of a pingrequest
          Helpw = Tcpread(idx , B , 2)                      'read and ignore them
     End If


     If Tempw > 2 Then                                      'if there is something received
          #if Cdebug
               Print "something arrives"
               Print "Tempw = " ; Tempw
          #endif
          For B = 1 To Tempw
               Helpw = Tcpread(idx , Z(b) , 1)
          Next B
          #if Cdebug
               'Print Hex(z(1))                              '&H30 type of MQTT packet
               Print "Total length message including Topic  " ; Z(2)
               'Print Hex(z(3))
               Print "Length of Topic                       " ; Z(4)
          #endif
          Messagelen = Z(2) - Z(4)
          #if Cdebug
               Print "Message length " ; Messagelen
          #endif
          Z(4) = Z(4) + 4
          Print
          Print "Topic:   ";
          For Y = 5 To Z(4)
               Print Chr(z(y));
          Next Y
          Print

          Message2 = ""
          Z(4) = Z(4) + 1
          Print "Message: ";
          For Y = Z(4) To Messagelen + 9
               Print Chr(z(y));
               Message2 = Message2 + Chr(z(y))
          Next Y
          Teller = 0                                        'reset the keep alive counter
          Print
          Print

          'don't confirm the Bascom-MQTT-client online message
          'and don't confirm the confirm message Wink

          If Message2 <> "Bascom-MQTT-client online" Then
               If Message2 <> "Received MQTT-message" Then
                    #if C2dbug
                         Print "Confirm"
                    #endif
                    Result = Tcpwrite(idx , Confirm)        'publish the message
                    Teller = 0
               End If
          End If
     End If

     If Teller > 60 Then                                    'keep alive is 70 seconds (see connect header), 10 less than keep alive
          #if C2dbug
               Print "Pingreq"
          #endif
          Result = Tcpwrite(idx , Pingreq)                  'pingrequest - keep alive
          Teller = 0                                        'start interrupt counter all over again
     End If

     Minteller = Minteller + 1
     If Minteller = 15000 Then
          Teller = Teller + 1
          Minteller = 0
     End If

Loop

'you will never reach these lines at the moment


#if Cdebug
     Print "Disconnect"
#endif
Result = Tcpwrite(idx , Disconnect)                         'disconnect


Wait 4
Socketdisconnect Idx                                        'disconnect socket

End
 




Have fun
Ben Zijlstra
Back to top
View user's profile Visit poster's website
bzijlstra

Bascom Ambassador



Joined: 30 Dec 2004
Posts: 1179
Location: Tilburg - Netherlands

netherlands.gif
PostPosted: Mon Jun 20, 2016 1:45 pm    Post subject: Bascom Light MQTT client as TFT-display Reply with quote



Made a light Bascom MQTT client as a display. Using a Raspberry as a MQTT broker in my own network.

Two universal routines, Publish(topic,message) and Subscribe(topic).

If you want you can test the MQTT functionality with MQTT.fx - a JAVA MQTT client

Arduino Mega with W5100 ethernetshield and a HX8357C display is used. The TFT-routines are from HKipnik.

The only call to a display is

Code:
Call display_message(msg2)


Display of text is only handled in that routine so you could use your own display, LCD 16x2, I2C display etc.

Arrays are used to fill Publish and Subscribe, so these routines can be used in other clients.

A keep alive time is 70 seconds. Before the end of the keep alive time a PINGREQuest is send. A PINGRESponse clears the keep alive and ping timers.

Code:
'Light Bascom MQTT client - TFT with HX8357c

'HX8357C routines from HKipnik

'connect / subscribe / publish / pingreq / (disconnect)

'publish and subscribe to Topic home/lcd

'Hardware: Arduino Mega 2560 with W5100 Ethernet shield

'Connecting to a Raspberry Mosquitto MQTT Broker - 192.168.0.98

'Ben Zijlstra - 2016

$regfile = "m2560def.dat"                                   ' specify the used micro
$crystal = 16000000                                         ' used crystal frequency
$baud = 56700                                               ' use baud rate
$hwstack = 200
$swstack = 220
$framesize = 250

Config Portb.4 = Output
Wiz5100_cs Alias Portb.4
Wiz5100_cs = 1
Waitms 500

Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0
Spiinit

Config Tcpip = Noint , Mac = 12.128.12.33.46.74 , Ip = 192.168.0.221 , Submask = 255.255.255.0 , Gateway = 192.168.0.1 , _
Localport = 1000 , Tx = $55 , Rx = $55 , Chip = W5100 , Spi = 1 , Cs = Portb.4

Dim Idx As Byte
Dim Bclient As Byte
Dim Result As Word
Dim S As Long
Dim Tempw As Word
Dim Helpw As Word
Dim Status As Long
Dim Z(255) As Byte
Dim B As Byte
Dim Y As Byte
Dim Messagelen As Byte
Dim Msg2 As String * 200
Dim Emptyline As String * 40
Dim Dsp_txt(11) As String * 40

Dim Line_counter As Byte

'keep alive
Dim Keepalive_counter As Long
Dim Pingresponse_counter As Long
Dim Pub_ar(255) As Byte
Dim Sub_ar(100) As Byte
Dim Msg As String * 150
Dim Topic As String * 100

Keepalive_counter = 0
Pingresponse_counter = 0

Line_counter = 1
Emptyline = Space(40)

Dim Lcd_textt As String * 200

Const Cdebug = 1                                            'for debug purpose
Const C2dbug = 1

Const Keepalive = 60
Const Keepalive_ticks = Keepalive * 15000                   'keep alive * second
Const Keepalive_ticks_pingresponse = Keepalive_ticks + 30000
Const Client_id = "Bascom-Client"

'Connect is   {016}(&H10) MQTT Control Packet type
'             {025}       Length message
'             {000}       Length protocol name MSB
'             {004}       Length protocol name LSB
'             MQTT        Protocol name
'             {004}       Protocol level
'             {002}       Connect flags (002 = Clean Session)
'             {000}       Keep alive MSB
'             {070}       Keep alive LSB (70 seconds)
'             {000}
'             {013}       Length client-ID
'             Bascom-client (Client-ID)
Const Connect = "{016}{025}{000}{004}MQTT{004}{002}{000}{070}{000}{013}Bascom-Client"
Const Confirm = "{048}{031}{000}{008}home/lcdReceived MQTT-message"
Const Pingreq = "{192}{000}"                                '&HC0 &H00 - ping request - keep alive
Const Disconnect = "{224}{000}"                             '&HE0 &H00

Declare Sub Display_message(byval Msg2 As String)
Declare Sub Publish(byval Topic As String , Byval Msg As String)
Declare Sub Subscribe(byval Topic As String)

'*******************************************************************************
'Display Mode
'*******************************************************************************
Const Lcd_mode = 4                                          '1=Portrait 2=Portrait 180° 3=landscape 4=landscape 180°
Const Lcd_driver = 2                                        '1=HX8357B  2=HX8357C
Const Sd_card = 0
'*******************************************************************************
$include "TFTDriver\HX8357_declarations.inc"
'*******************************************************************************
'Init the Display
'*******************************************************************************
Call Lcd_init()
Call Lcd_clear(black)
'*******************************************************************************
' Display landscape
'*******************************************************************************
Call Lcd_clear(black)
Call Lcd_text( "BASCOM-AVR MQTT-example" , 5 , 1 , 2 , Dodgerblue , Black , 1)
Call Lcd_line(5 , 23 , 475 , 23 , 1 , Yellow)
Call Lcd_text( "home/lcd" , 5 , 30 , 2 , Floralwhite , Black , 1)
Call Lcd_text( " " , 460 , 1 , 2 , Black , Red , 1)

Print "Programm start"
Print
Idx = 0
Bclient = Getsocket(idx , Sock_stream , 7000 , 0)           'Open socket TCP (sock_stream), local port 7000
Result = Socketconnect(idx , 192.168.0.98 , 1883)           'the IP-address of the MQTT broker and the port
Call Lcd_text( " " , 460 , 1 , 2 , Black , Red , 1)
Do
     Tempw = Socketstat(idx , 0)                            'get status
     If Tempw = Sock_established Then
          #if C2dbug
               Print "Socket established with MQTT broker"
          #endif
          Call Lcd_text( "Socket established with MQTT broker    " , 5 , 300 , 2 , Floralwhite , Black , 1)
          Exit Do
     End If
Loop

#if Cdebug
     Print "Connect"
#endif
Call Lcd_text( "Connect" , 5 , 300 , 2 , Floralwhite , Black , 1)
Result = Tcpwrite(idx , Connect)                            'connect to the broker
Do
     Tempw = Socketstat(idx , Sel_recv)                     'get received bytes
     If Tempw > 0 Then                                      'if there is something received
          Helpw = Tcpread(idx , S , Tempw)                  'read
          Status = S And &H0000FFFF                         'two bytes
          If Status = &H00000220 Then
               #if C2dbug
                    Print "Connect ACK"
               #endif
               Call Lcd_text( "Connect ACK                            " , 5 , 300 , 2 , Floralwhite , Black , 1)
               Exit Do
          End If
     End If
Loop


Call Lcd_text( "Subscribe to home/lcd                  " , 5 , 300 , 2 , Floralwhite , Black , 1)

Call Subscribe( "home/lcd")

Call Lcd_text( " " , 460 , 1 , 2 , Black , Green , 1)

Wait 4

#if C2dbug
     Print "Publish"
#endif

Call Publish( "home/lcd" , "TFT-screen online")

Call Lcd_text( "                                       " , 5 , 300 , 2 , Floralwhite , Black , 1)
                                                      'reset the keep alive
'is something published in the subscribed topic?
Do
     Tempw = Socketstat(idx , Sel_recv)                     'get received bytes
     If Tempw = 2 Then                                      '2 bytes, a reaction of a pingrequest
          Helpw = Tcpread(idx , S , 2)
          Status = S And &H0000FFFF                         'two bytes
          If Status = &H000000D0 Then
               #if Cdebug
                    Print "Pingresponse received"
               #endif

               Call Lcd_text( " " , 460 , 1 , 2 , Black , Green , 1)
               Pingresponse_counter = 0                     'start pingresponse time again
          End If
     End If

     If Tempw > 2 Then                                      'if there is something received
          #if Cdebug
               Print "something arrives"
               Print "Tempw = " ; Tempw
          #endif
          For B = 1 To Tempw
               Helpw = Tcpread(idx , Z(b) , 1)
          Next B
          #if Cdebug
               'Print Hex(z(1))                              '&H30 type of MQTT packet
               Print "Total length message including Topic  " ; Z(2)
               'Print Hex(z(3))
               Print "Length of Topic                       " ; Z(4)
          #endif
          Messagelen = Z(2) - Z(4)
          Decr Messagelen
          Decr Messagelen
          #if Cdebug
               Print "Message length " ; Messagelen
          #endif
          Z(4) = Z(4) + 4
          Print
          Print "Topic:   ";
          For Y = 5 To Z(4)
               Print Chr(z(y));
          Next Y
          Print
          Msg2 = ""
          Z(4) = Z(4) + 1
          Print "Message: ";
          For Y = Z(4) To Messagelen + 12
               Print Chr(z(y));
               Msg2 = Msg2 + Chr(z(y))
          Next Y

          Print
          Print

          'don't confirm the Bascom-MQTT-client online message
          'and don't confirm the confirm message Wink
          If Msg2 <> "Bascom-MQTT-client online" Then
               If Msg2 <> "Received MQTT-message" Then
                    Call Display_message(msg2)
                    #if C2dbug
                         Print "Confirm"
                    #endif
                    Result = Tcpwrite(idx , Confirm)        'publish the message
                    Keepalive_counter = 0
                    Pingresponse_counter = 0
               End If
          End If
     End If

     'keep alive pingrequest
     If Keepalive_counter > Keepalive_ticks Then            'keep alive is 70 seconds (see connect header)
          #if C2dbug
               Print "Pingreq"
          #endif
          Call Lcd_text( " " , 460 , 1 , 2 , Black , Red , 1)
          Result = Tcpwrite(idx , Pingreq)                  'pingrequest
          Keepalive_counter = 0
     End If

     If Pingresponse_counter > Keepalive_ticks_pingresponse Then
          Print "No pingresponses! - Reboot"
          Goto 0                                            'reboot
     End If

     'Keep alive counter
     Incr Keepalive_counter
     'pingresponse counter
     Incr Pingresponse_counter
Loop
'you will never reach these lines at the moment

#if Cdebug
     Print "Disconnect"
#endif
Result = Tcpwrite(idx , Disconnect)                         'disconnect

Wait 4
Socketdisconnect Idx                                        'disconnect socket
End


Sub Publish(byval Topic , Byval Msg)
     Local Topic_len As Byte
     Local Message_len As Byte
     Local Temp As Byte
     Local Temp2 As Byte
     Local Temps As String * 1
     Local Temp3 As Byte

     Topic_len = Len(topic)
     Message_len = Len(msg)
     Temp = Topic_len + Message_len
     Temp3 = Temp + 4                                       'length for tcpwrite
     Incr Temp
     Incr Temp

'Const Publish = "{048}{028}{000}{008}home/lcdTFT-screen online"

     Pub_ar(1) = "{048}"
     Pub_ar(2) = Temp
     Pub_ar(3) = "{000}"
     Pub_ar(4) = Topic_len

     'topic
     For Temp = 1 To Topic_len
          Temp2 = Temp + 4
          Temps = Mid(topic , Temp , 1)
          Pub_ar(temp2) = Asc(temps)
     Next Temp

     'message
     For Temp = 1 To Message_len
          Incr Temp2
          Temps = Mid(msg , Temp , 1)
          Pub_ar(temp2) = Asc(temps)
     Next Temp
     #if C2dbug
          Print "Publish"
     #endif
     Result = Tcpwrite(idx , Pub_ar(1) , Temp3)             'publish the message
     Keepalive_counter = 0 : Pingresponse_counter = 0       'reset the keep alive
End Sub


Sub Subscribe(byval Topic)
     Local Topic_len As Byte
     Local Temp As Byte
     Local Temp2 As Byte
     Local Temps As String * 1
     Local Temp3 As Byte
     Topic_len = Len(topic)

     Temp3 = Topic_len + 7
     Temp = Temp3 - 2

     'Const Subscribe = "{130}{013}{000}{002}{000}{008}home/lcd{000}"

     Sub_ar(1) = "{130}"
     Sub_ar(2) = Temp
     Sub_ar(3) = "{000}"
     Sub_ar(4) = "{002}"
     Sub_ar(5) = "{000}"
     Sub_ar(6) = Topic_len

     'topic
     For Temp = 1 To Topic_len
         Temp2 = Temp + 6
         Temps = Mid(topic , Temp , 1)
         Sub_ar(temp2) = Asc(temps)
     Next Temp

     Print "Temp2 = " ; Temp2

     Incr Temp2

     Sub_ar(temp2) = "{000}"
     #if C2dbug
          Print "Subscribe"
     #endif
     Result = Tcpwrite(idx , Sub_ar(1) , Temp3)             'subscribe to topic
     Do
          Tempw = Socketstat(idx , Sel_recv)                'get received bytes
          If Tempw > 0 Then                                 'if there is something received
               Helpw = Tcpread(idx , S , Tempw)             'read
               Status = S And &H00FFFFFF                    'three bytes
               If Status = &H00000390 Then
                    #if C2dbug
                         Print "Subscribe ACK"
                    #endif
                    Keepalive_counter = 0
                    Pingresponse_counter = 0                'reset the keep alive
                    Exit Do
               End If
          End If
     Loop
End Sub


Sub Display_message(byval Msg2 As String)
     Local Verticalpos As Word
     Local Dsp_help As Byte
     Verticalpos = 60
     Lcd_textt = Left(msg2 , 39)
     Emptyline = Space(40)
     Mid(emptyline , 1) = Lcd_textt

     Dsp_txt(line_counter) = Emptyline

     Line_counter = Line_counter + 1
     If Line_counter = 11 Then
          For Dsp_help = 1 To 10
               Dsp_txt(dsp_help) = Dsp_txt(dsp_help + 1)
          Next Dsp_help
          Line_counter = 10
     End If

     'display all lines
     For Dsp_help = 1 To 10
          Call Lcd_text(dsp_txt(dsp_help) , 5 , Verticalpos , 2 , Floralwhite , Black , 1)       '10 lines x 39 characters
          Verticalpos = Verticalpos + 24
     Next Dsp_help

End Sub


$include "TFTDriver\HX8357_functions.inc"
$include "Font\Digital20x32.font"                           '7 segments
$include "Font\font12x16.font"
$include "Font\font25x32.font"
$include "Font\Arial11x14.font"
 


Have fun
Ben Zijlstra
Back to top
View user's profile Visit poster's website
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 6198
Location: Holland

blank.gif
PostPosted: Mon Jun 20, 2016 10:51 pm    Post subject: Reply with quote

excellent Ben. I got the thin client going.
Thank you for your research and sharing. This saves me a lot of work.

_________________
Mark
Back to top
View user's profile Visit poster's website
bzijlstra

Bascom Ambassador



Joined: 30 Dec 2004
Posts: 1179
Location: Tilburg - Netherlands

netherlands.gif
PostPosted: Wed Jun 22, 2016 5:26 pm    Post subject: Some remarks... Reply with quote

Got some remarks about the Bascom program

In the program I am using
Code:
'topic
     For Temp = 1 To Topic_len
         Temp2 = Temp + 6
         Temps = Mid(topic , Temp , 1)
         Sub_ar(temp2) = Asc(temps)
     Next Temp
 


In this case, I want a single byte of a string, instead of using a MID it is easier to use an ASC(string,index)

Code:
'topic
     For Temp = 1 To Topic_len
         Temp2 = Temp + 6
         Temp4 = Asc(topic , Temp)
         Sub_ar(temp2) = Temp4
     Next Temp
 


===

If you go over the MQTT documentation you will find things like Retain and Last Will and Testament

Quote:
A retained message is a normal MQTT message with the retained flag set to true. The broker will store the last retained message and the corresponding QoS for that topic. Each client that subscribes to a topic pattern, which matches the topic of the retained message, will receive the message immediately after subscribing. For each topic only one retained message will be stored by the broker.


Quote:
The Last Will and Testament (LWT) feature is used in MQTT to notify other clients about an ungracefully disconnected client. Each client can specify its last will message (a normal MQTT message with topic, retained flag, QoS and payload) when connecting to a broker. The broker will store the message until it detects that the client has disconnected ungracefully. If the client disconnect abruptly, the broker sends the message to all subscribed clients on the topic, which was specified in the last will message. The stored LWT message will be discarded if a client disconnects gracefully by sending a DISCONNECT message.


*From HiveMQ MQTT Essentials

If you would like to check, the const for these commands are

Connect with Last Will and Testament

Code:
Const Connect_lwt = "{016}{045}{000}{004}MQTT{004}{038}{000}{070}{000}{013}Bascom-Client{000}{008}home/lcd{000}{007}Offline{000}"
 


===

Creating a retain message

Code:
Const Retain = "{049}{022}{000}{008}home/lcdBascom Rules"


===

Deleting a retain message

Code:
Const Delete_retain = "{049}{010}{000}{008}home/lcd"


===

These examples are Ultra Light MQTT clients

In the specs of MQTT something about topic and message length

Quote:
The length of the actual topic string is at most 65535 bytes. This is a limit imposed by the mqtt spec, you can't change it. It is also worth noting that the topic is encoded with utf-8, so you may have less than 65535 characters available.

The payload of the message is limited to 268,435,456 bytes. Again, this is defined by the spec.

If you are routinely approaching either of these limits you should be thinking about whether what you are doing is sensible.


On the Internet you can find installation instructions how to turn your Raspberry Pi into a Mosquitto Broker.

Have fun
Ben Zijlstra


Last edited by bzijlstra on Tue Jul 05, 2016 2:09 am; edited 2 times in total
Back to top
View user's profile Visit poster's website
bzijlstra

Bascom Ambassador



Joined: 30 Dec 2004
Posts: 1179
Location: Tilburg - Netherlands

netherlands.gif
PostPosted: Tue Jul 05, 2016 1:27 am    Post subject: Some MQTT-routines Reply with quote

Made some MQTT-routines

Code:
Declare Sub Mqtt_connect()
Declare Sub Mqtt_connect_lastwill(byval Topic As String , Byval Lwt_msg As String)
Declare Sub Mqtt_disconnect()
Declare Sub Mqtt_publish(byval Topic As String , Byval Msg As String)
Declare Sub Mqtt_publish_retain(byval Topic As String , Byval Retain_msg As String)
Declare Sub Mqtt_publish_delete_retain(byval Topic As String)
Declare Sub Mqtt_subscribe(byval Topic As String)
Declare Sub Mqtt_unsubscribe(byval Topic As String)


MQTT-Connect command with keep alive time and client-id

The MQTT connection itself is always between one client and the broker, no client is connected to another client directly. The connection is initiated through a client sending a CONNECT message to the broker.

Code:
Call Mqtt_connect()


Code:

Sub Mqtt_connect
     Local Client_id_len As Byte
     Client_id_len = Len(client_id)
     Local Temp As Byte
     Local Keepalivew As Word
     Keepalivew = Keepalive
     Local Ar_counter As Byte

     Temp = 12 + Client_id_len                              '12 fixed connect bytes + len client_id

     Pubsub_ar(1) = "{016}"                                 'MQTT connect
     Pubsub_ar(2) = Temp                                    'Length message
     Pubsub_ar(3) = "{000}"                                 'Length protocol name MSB
     Pubsub_ar(4) = "{004}"                                 'Length protocol name LSB
     Pubsub_ar(5) = Asc( "M")                               'protocol name MQTT
     Pubsub_ar(6) = Asc( "Q")
     Pubsub_ar(7) = Asc( "T")
     Pubsub_ar(8) = Asc( "T")
     Pubsub_ar(9) = "{004}"                                 'protocol-level
     Pubsub_ar(10) = "{002}"                                'connect flags Clean Session
     Pubsub_ar(11) = High(keepalivew)                       'keep alive MSB
     Pubsub_ar(12) = Low(keepalivew)                        'keep alive LSB
     Pubsub_ar(13) = "{000}"
     Pubsub_ar(14) = Client_id_len                          'client_id_length
     Ar_counter = 15
     For Temp = 1 To Client_id_len
          Pubsub_ar(ar_counter) = Asc(client_id , Temp)
          Incr Ar_counter
     Next Temp

     Result = Tcpwrite(idx , Pubsub_ar(1) , Ar_counter)     'connect to the broker
     Do
          Tempw = Socketstat(idx , Sel_recv)                'get received bytes
          If Tempw > 0 Then                                 'if there is something received
               Helpw = Tcpread(idx , S , Tempw)             'read
               Status = S And &H0000FFFF                    'two bytes
               If Status = &H00000220 Then
                    #if C2dbug
                         Print "Connect ACK"
                    #endif
                    Exit Do
               End If
          End If
     Loop
End Sub



MQTT-Connect command with Last Will and Testament (LWT), keep alive time and client-id

The Last Will and Testament (LWT) feature is used in MQTT to notify other clients about an ungracefully disconnected client. Each client can specify its last will message (a normal MQTT message with topic, retained flag, QoS and payload) when connecting to a broker. The broker will store the message until it detects that the client has disconnected ungracefully. If the client disconnect abruptly, the broker sends the message to all subscribed clients on the topic, which was specified in the last will message. The stored LWT message will be discarded if a client disconnects gracefully by sending a DISCONNECT message.



Example of a Last Will and Testament message. If you disconnect the power of the MQTT-client, the MQTT-broker will not receive PINGREQuest, and after 1.5 times the keep alive time, the broker will disconnect the client and send the Last Will and Testament message to the clients that have subscribed to the topics of this client.

Code:
Call Mqtt_connect_lastwill( "home/lcd/log" , "TFT-screen Offline")       'send a empty lwt-message to delete lwt message


Code:
Sub Mqtt_connect_lastwill(byval Topic , Byval Lwt_msg)
     Local Client_id_len As Byte
     Client_id_len = Len(client_id)
     Local Temp As Byte
     Local Keepalivew As Word
     Keepalivew = Keepalive
     Local Ar_counter As Byte
     Local Topic_len As Word
     Topic_len = Len(topic)

     Local Lwt_msg_len As Word
     Lwt_msg_len = Len(lwt_msg)

     Temp = 17 + Client_id_len                              '17 fixed connect bytes + len client_id
     Temp = Temp + Topic_len                                '+ topic
     Temp = Temp + Lwt_msg_len                              '+ lwt_msg

     Pubsub_ar(1) = "{016}"                                 'MQTT connect
     Pubsub_ar(2) = Temp                                    'Length message
     Pubsub_ar(3) = "{000}"                                 'Length protocol name MSB
     Pubsub_ar(4) = "{004}"                                 'Length protocol name LSB
     Pubsub_ar(5) = Asc( "M")                               'protocol name MQTT
     Pubsub_ar(6) = Asc( "Q")
     Pubsub_ar(7) = Asc( "T")
     Pubsub_ar(8) = Asc( "T")
     Pubsub_ar(9) = "{004}"                                 'protocol-level
     Pubsub_ar(10) = "{038}"                                'connect flags Clean Session
     Pubsub_ar(11) = High(keepalivew)                       'keep alive MSB
     Pubsub_ar(12) = Low(keepalivew)                        'keep alive LSB
     Pubsub_ar(13) = "{000}"
     Pubsub_ar(14) = Client_id_len                          'client_id_length
     Ar_counter = 15
     For Temp = 1 To Client_id_len
          Pubsub_ar(ar_counter) = Asc(client_id , Temp)
          Incr Ar_counter
     Next Temp
     Pubsub_ar(ar_counter) = High(topic_len)
     Incr Ar_counter
     Pubsub_ar(ar_counter) = Low(topic_len)
     Incr Ar_counter
     For Temp = 1 To Topic_len
          Pubsub_ar(ar_counter) = Asc(topic , Temp)
          Incr Ar_counter
     Next Temp
     Pubsub_ar(ar_counter) = High(lwt_msg_len)
     Incr Ar_counter
     Pubsub_ar(ar_counter) = Low(lwt_msg_len)
     Incr Ar_counter
     For Temp = 1 To Lwt_msg_len
          Pubsub_ar(ar_counter) = Asc(lwt_msg , Temp)
          Incr Ar_counter
     Next Temp
     Pubsub_ar(ar_counter) = "{000}"

     Result = Tcpwrite(idx , Pubsub_ar(1) , Ar_counter)     'connect to the broker
     Do
          Tempw = Socketstat(idx , Sel_recv)                'get received bytes
          If Tempw > 0 Then                                 'if there is something received
               Helpw = Tcpread(idx , S , Tempw)             'read
               Status = S And &H0000FFFF                    'two bytes
               If Status = &H00000220 Then
                    #if C2dbug
                         Print "Connect ACK"
                    #endif
                    Exit Do
               End If
          End If
     Loop

End Sub



MQTT-Disconnect command

Code:
Call Mqtt_disconnect()                                 'disconnect socket


Code:
Sub Mqtt_disconnect()
     #if Cdebug
          Print "Disconnect"
     #endif
     Result = Tcpwrite(idx , Disconnect)                    'disconnect
     Wait 4
     Socketdisconnect Idx
End Sub



MQTT-Publish

Code:
Call Mqtt_publish( "home/lcd/log" , "TFT-screen Online")


After a MQTT client is connected to a broker, it can publish messages. MQTT has a topic-based filtering of the messages on the broker, so each message must contain a topic, which will be used by the broker to forward the message to interested clients. Each message typically has a payload which contains the actual data to transmit in byte format.



Code:
Sub Mqtt_publish(byval Topic , Byval Msg)
     Local Topic_len As Byte
     Local Message_len As Byte
     Local Temp As Byte
     Local Temp2 As Byte
     Local Temp3 As Byte
     Local Temp4 As Byte

     Topic_len = Len(topic)
     Message_len = Len(msg)
     Temp = Topic_len + Message_len

     If Temp > 249 Then
          Temp = 249
     End If

     Temp3 = Temp + 4                                       'length for tcpwrite
     Incr Temp
     Incr Temp

     Startmsgcounter = 3

     'calculate remaining length bytes
     If Temp > 127 Then
          Pubsub_ar(2) = Temp - 128
          Pubsub_ar(3) = "{001}"
          Incr Startmsgcounter
     Else
          Pubsub_ar(2) = Temp
     End If

     Pubsub_ar(1) = "{048}"
     Pubsub_ar(startmsgcounter) = "{000}"
     Incr Startmsgcounter
     Pubsub_ar(startmsgcounter) = Topic_len

     'topic
     For Temp = 1 To Topic_len
          Temp2 = Temp + Startmsgcounter
          Pubsub_ar(temp2) = Asc(topic , Temp)
     Next Temp

     'message
     For Temp = 1 To Message_len
          Incr Temp2
          Pubsub_ar(temp2) = Asc(msg , Temp)
     Next Temp
     #if C2dbug
          Print "Publish"
     #endif
     Result = Tcpwrite(idx , Pubsub_ar(1) , Temp3)          'publish the message
End Sub



MQTT-Publish with retain

A retained message is a normal MQTT message with the retained flag set to true. The broker will store the last retained message and the corresponding QoS for that topic Each client that subscribes to a topic pattern, which matches the topic of the retained message, will receive the message immediately after subscribing. For each topic only one retained message will be stored by the broker.



Everytime a new client does a subscribe to a certain topic, the client can have it receive a retained message. The retained message is stored on the broker. This can be the last good know temperature etc.

Code:
Call Mqtt_publish_retain( "home/lcd" , "Bascom rules")


Code:
Sub Mqtt_publish_retain(byval Topic , Byval Retain_msg)
     Local Topic_len As Byte
     Topic_len = Len(topic)

     Local Retain_msg_len As Byte
     Retain_msg_len = Len(retain_msg)

     Local Startmsgcounter As Byte
     Local Temp As Byte
     Local Temp2 As Byte
     Local Temp3 As Byte

     Temp = Topic_len
     Temp = Temp + Retain_msg_len
     Temp = Temp + 2
     Temp3 = Temp + 2                                       'length total packet

     Startmsgcounter = 3
     'calculate remaining length bytes
     If Temp > 127 Then
          Pubsub_ar(2) = Temp - 128
          Pubsub_ar(3) = "{001}"
          Incr Startmsgcounter
     Else
          Pubsub_ar(2) = Temp
     End If

     Pubsub_ar(1) = "{049}"                                 'MQTT packet
     Pubsub_ar(startmsgcounter) = "{000}"

     Incr Startmsgcounter
     Pubsub_ar(startmsgcounter) = Topic_len

     'topic
     For Temp = 1 To Topic_len
          Temp2 = Temp + Startmsgcounter
          Pubsub_ar(temp2) = Asc(topic , Temp)
     Next Temp

     'retain message
     For Temp = 1 To Retain_msg_len
          Incr Temp2
          Pubsub_ar(temp2) = Asc(retain_msg , Temp)
     Next Temp

     Incr Temp2
     Incr Temp3

     #if C2dbug
          Print "Publish retain message"
     #endif
     Pubsub_ar(temp2) = "{000}"
     Result = Tcpwrite(idx , Pubsub_ar(1) , Temp3)          'publish the message

End Sub



Delete retain message

Code:
Mqtt_publish_delete_retain( "home/lcd")


Code:
Sub Mqtt_publish_delete_retain(byval Topic)
     Local Topic_len As Byte
     Topic_len = Len(topic)

     Local Startmsgcounter As Byte
     Local Temp As Byte
     Local Temp2 As Byte
     Local Temp3 As Byte

     Temp = Topic_len
     Temp = Temp + 2
     Temp3 = Temp + 2                                       'length total packet

     Startmsgcounter = 3
     'calculate remaining length bytes
     If Temp > 127 Then
          Pubsub_ar(2) = Temp - 128
          Pubsub_ar(3) = "{001}"
          Incr Startmsgcounter
     Else
          Pubsub_ar(2) = Temp
     End If
     Pubsub_ar(1) = "{049}"                                 'MQTT packet
     Pubsub_ar(startmsgcounter) = "{000}"
     Incr Startmsgcounter
     Pubsub_ar(startmsgcounter) = Topic_len
     'topic
     For Temp = 1 To Topic_len
          Temp2 = Temp + Startmsgcounter
          Pubsub_ar(temp2) = Asc(topic , Temp)
     Next Temp

     Incr Temp2
     Incr Temp3
     #if C2dbug
          Print "Publish delete retain message"
     #endif
     Pubsub_ar(temp2) = "{000}"
     Result = Tcpwrite(idx , Pubsub_ar(1) , Temp3)          'publish the message
End Sub



MQTT-Subscribe

A client needs to send a SUBSCRIBE message to the MQTT broker in order to receive relevant messages

Code:
Call Mqtt_subscribe( "home/lcd/log")


Code:
Sub Mqtt_subscribe(byval Topic)
     Local Topic_len As Byte
     Local Temp As Byte
     Local Temp2 As Byte
     Local Temp3 As Byte
     Local Temp4 As Byte
     Topic_len = Len(topic)

     Temp3 = Topic_len + 7
     Temp = Temp3 - 2

     'Const Subscribe = "{130}{013}{000}{002}{000}{008}home/lcd{000}"

     Startmsgcounter = 3

     If Temp > 127 Then
          Pubsub_ar(2) = Temp - 128
          Pubsub_ar(3) = "{001}"
          Incr Startmsgcounter
     Else
          Pubsub_ar(2) = Temp
     End If

     Pubsub_ar(1) = "{130}"
     Pubsub_ar(startmsgcounter) = "{000}"
     Incr Startmsgcounter
     Pubsub_ar(startmsgcounter) = "{005}"
     Incr Startmsgcounter
     Pubsub_ar(startmsgcounter) = "{000}"
     Incr Startmsgcounter
     Pubsub_ar(startmsgcounter) = Topic_len

     'topic
     For Temp = 1 To Topic_len
          Temp2 = Temp + Startmsgcounter
          Pubsub_ar(temp2) = Asc(topic , Temp)
     Next Temp

     Incr Temp2

     Pubsub_ar(temp2) = "{000}"                             'finishing byte of the subscribe string

     #if C2dbug
          Print "Subscribe"
     #endif
     Result = Tcpwrite(idx , Pubsub_ar(1) , Temp3)          'subscribe to topic
     Do
          Tempw = Socketstat(idx , Sel_recv)                'get received bytes
          If Tempw > 0 Then                                 'if there is something received
               Helpw = Tcpread(idx , S , Tempw)             'read
               Status = S And &H00FFFFFF                    'three bytes
               If Status = &H00000390 Then
                    #if C2dbug
                         Print "Subscribe ACK"
                    #endif
                    Keepalive_counter = 0
                    Pingresponse_counter = 0                'reset the keep alive
                    Exit Do
               End If
          End If
     Loop
End Sub



MQTT-Unsubscribe

The counterpart of the SUBSCRIBE message is the UNSUBSCRIBE message which deletes existing subscriptions of a client on the broker.

Code:
Call Mqtt_unsubscribe( "home/lcd/log")


Code:
Sub Mqtt_unsubscribe(byval Topic)
     Local Topic_len As Byte
     Topic_len = Len(topic)

     Local Temp As Byte
     Local Temp2 As Byte
     Temp2 = Topic_len + 6

     Pubsub_ar(1) = "{162}"
     Pubsub_ar(2) = Temp2                                   'mits onder de 128 karakters....
     Pubsub_ar(3) = "{000}"
     Pubsub_ar(4) = "{005}"
     Pubsub_ar(5) = "{000}"
     Pubsub_ar(6) = Topic_len

     Startmsgcounter = 6
     For Temp = 1 To Topic_len
          Incr Startmsgcounter
          Pubsub_ar(startmsgcounter) = Asc(topic , Temp)
     Next Temp

     Result = Tcpwrite(idx , Pubsub_ar(1) , Temp2)
     Do
          Tempw = Socketstat(idx , Sel_recv)                'get received bytes
          If Tempw > 0 Then                                 'if there is something received
               Helpw = Tcpread(idx , S , Tempw)             'read
               Print Helpw
               Print S
               Print Hex(s)


               Status = S And &H00FFFFFF                    'three bytes
               If Status = &HB0020005 Then
                    #if C2dbug
                         Print "unsubscribe ACK"
                    #endif
                    Keepalive_counter = 0
                    Pingresponse_counter = 0                'reset the keep alive
                    Exit Do
               End If
          End If
     Loop
End Sub


Will put the main MQTT program online later on. Here some pictures of the TFT-screen home/lcd







It is all experimental. QoS 0. Max length topic/message 255 bytes. But client can handle megabytes of MQTT-info.

Have fun
Ben Zijlstra
Back to top
View user's profile Visit poster's website
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 6198
Location: Holland

blank.gif
PostPosted: Tue Jul 05, 2016 9:12 am    Post subject: Reply with quote

thank you for this update Ben. MQTT is really a great standard for handling automation messages.
your code works well on my mqtt broker too.

_________________
Mark
Back to top
View user's profile Visit poster's website
bzijlstra

Bascom Ambassador



Joined: 30 Dec 2004
Posts: 1179
Location: Tilburg - Netherlands

netherlands.gif
PostPosted: Wed Jul 06, 2016 12:16 am    Post subject: MQTT Led on/off example Reply with quote

A small example of MQTT - Putting the D13 testled on the Arduino Mega on and off with MQTT

You have to put the two include files in the attached ZIP file in a MQTT directory below your working directory.
(Or in the source remove the mqtt\ before the include...)

Code:
'Light Bascom MQTT client - Led on/off example

'connect / subscribe / publish / pingreq / (disconnect)

'publish to   home/hobbycorner/arduino1/log

'subscribe to home/hobbycorner/arduino1/ledD13

'Hardware: Arduino Mega 2560 with W5100 Ethernet shield

'Connecting to a Raspberry Mosquitto MQTT Broker - 192.168.0.98

'Ben Zijlstra - 2016

'Monkey proof. Accepts huge amount of bytes but stores only 511 bytes

'mqtt_client_ID = Bascom<MAC-address>


$regfile = "m2560def.dat"                                   ' specify the used micro
$crystal = 16000000                                         ' used crystal frequency
$baud = 115200                                              ' use baud rate
$hwstack = 300
$swstack = 300
$framesize = 300

Config Portb.4 = Output
Wiz5100_cs Alias Portb.4
Wiz5100_cs = 1
Waitms 500

Config Portb.7 = Output
Ledd13 Alias Portb.7

Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0
Spiinit

Config Tcpip = Noint , Mac = 12.128.12.33.46.84 , Ip = 192.168.0.222 , Submask = 255.255.255.0 , Gateway = 192.168.0.1 , _
Localport = 7000 , Tx = $55 , Rx = $55 , Chip = W5100 , Spi = 1 , Cs = Portb.4

Config Submode = New

'debug-options
Const Cdebug = 1                                            'for debug purpose
Const C2dbug = 1                                            'if you are using debug, the main loop will take more time

$include "mqtt\mqtt_functions.inc"
$include "Mqtt\Mqtt_declares.inc"

'declares for add-on routine
Dim Templed As Byte

'constants                                                  'and perhaps you get problems with your keep-alives
Const Mqtt_keepalive = 60
Const Mqtt_keepalive_ticks = Mqtt_keepalive * 14000         'depends on the length of the main loop - keep alive * second
Const Mqtt_ka_ticks_pr = Mqtt_keepalive_ticks + 30000

Mqtt_client_id = "Bascom1212812334684"                      'same as MAC address


#if C2dbug
     Print "Programm start"
     Print
#endif

Mqtt_idx = 0

Do
     Mqtt_bclient = Getsocket(mqtt_idx , Sock_stream , 0 , 0)       'Open socket TCP (sock_stream), local port 7000
     Mqtt_result = Socketconnect(mqtt_idx , 192.168.0.98 , 1883)       'the IP-address of the MQTT broker and the port

     Mqtt_tempw = Socketstat(mqtt_idx , 0)                  'get status
     If Mqtt_tempw = Sock_established Then
          #if C2dbug
               Print "Socket established with MQTT broker"
          #endif
          Exit Do
     End If
Loop

#if Cdebug
     Print "Connect"
#endif

'Call Mqtt_connect()
'Wait 2
Call Mqtt_connect_lastwill( "home/hobbycorner/arduino1/log" , "arduino1 Offline")       'send a empty lwt-message to delete lwt message
Wait 2
Call Mqtt_subscribe( "home/hobbycorner/arduino1/ledD13")
Wait 2
Wait 2
'Call Mqtt_publish_retain( "home/lcd" , "Bascom rules")
'wait 2
'Call Mqtt_publish_delete_retain( "home/lcd")
'Wait 2
'Call Mqtt_subscribe( "home/lcd/log")
'Wait 2
'Call Mqtt_publish( "home/lcd/log" , "status")
'Wait 2
'Call Mqtt_unsubscribe( "home/lcd/log")
'Wait 2
'Call Mqtt_unsubscribe( "home/lcd")

#if Cdebug
     Print
     Print "Check your Arduino Mega D13"
     Print "testled for location - blinking"
#endif
For Templed = 1 To 20                                       'to check the D13 test led on the Arduino Mega.
     Toggle Ledd13
     Waitms 500
Next Templed

Print
Print "You can now publish LED_ON or LED_OFF"
Print "to home/hobbycorner/arduino1/ledD13"
Print
Print "Publish LED-status to "
Print "home/hobbycorner/arduino1/log"
Print

Wait 4
Call Mqtt_publish( "home/hobbycorner/arduino1/log" , "led D13 OFF after blinktest")


'is something published in the subscribed topic?
Do
     Mqtt_tempw = Socketstat(mqtt_idx , Sel_recv)           'get received bytes
     If Mqtt_tempw = 2 Then                                 '2 bytes, a reaction of a pingrequest
          Mqtt_helpw = Tcpread(mqtt_idx , Mqtt_s , 2)
          Mqtt_status = Mqtt_s And &H0000FFFF               'two bytes
          If Mqtt_status = &H000000D0 Then
               #if Cdebug
                    Print "Pingresponse received"
               #endif
               Mqtt_pingresponse_counter = 0                'start pingresponse time again
          End If
     End If

     If Mqtt_tempw > 2 Then                                 'if there is something received
          #if Cdebug
               Print "something arrives"
               Print
               'Print "Tempw = " ; Tempw
          #endif

          'here we read all bytes but we only store 511 bytes in array mqtt_ar()

          For Mqtt_b = 1 To Mqtt_tempw
               Mqtt_bb = Mqtt_b
               If Mqtt_bb > 511 Then Mqtt_bb = 511
               Mqtt_helpw = Tcpread(mqtt_idx , Mqtt_ar(mqtt_bb) , 1)
          Next Mqtt_b

          'you can expect here in mqtt_ar(1) a 48 or 49

          If Mqtt_ar(1) = 48 Or Mqtt_ar(1) = 49 Then

          'length of topic/message combination will be in mqtt_ar(2)

          'here we check how many bytes are used for Remaining Length..

          'if topic/message < 128 bytes, the length of topic is in mqtt_ar(4)

          'if topic/message larger you get extra remaining length bytes, up to 4 bytes

               Mqtt_startmsgcounter = 4                     'length of topic in mqtt_ar(4)

               If Mqtt_ar(2) > 127 Then                     'MSB-bit, so a second byte is used for the length
                    Incr Mqtt_startmsgcounter
               End If

               If Mqtt_ar(3) > 127 Then                     'MSB-bit, so a third byte is used for the length
                    Incr Mqtt_startmsgcounter
               End If

               If Mqtt_ar(4) > 127 Then                     'MSB-bit, so a fourth byte is used for the length
                    Incr Mqtt_startmsgcounter
               End If

               Mqtt_pakketlength = Mqtt_bb - 4

               #if Cdebug
                    Print "Total length message including Topic  " ; Mqtt_pakketlength
                    Print "Length of Topic                       " ; Mqtt_ar(mqtt_startmsgcounter)
               #endif

               Mqtt_pakkethlp = Mqtt_startmsgcounter + 1
               Mqtt_pakkethlp2 = Mqtt_startmsgcounter + Mqtt_ar(mqtt_startmsgcounter)

               Mqtt_topic = ""
               For Mqtt_pakkethelp = Mqtt_pakkethlp To Mqtt_pakkethlp2
                    Mqtt_topic = Mqtt_topic + Chr(mqtt_ar(mqtt_pakkethelp))
               Next Mqtt_pakkethelp
               Print
               Print "Topic:   " ; Mqtt_topic

               Mqtt_msg2 = ""
               For Mqtt_pakkethlp = Mqtt_pakkethelp To Mqtt_pakketlength + 4
                    Mqtt_msg2 = Mqtt_msg2 + Chr(mqtt_ar(mqtt_pakkethlp))
               Next Mqtt_pakkethlp
               Print
               Print "Message: " ; Mqtt_msg2
               Print

               'here you put the routine that will act on incoming (topic/)message

              'in this case a cool MQTT D13-Led on/off

              '****************************************************************

               If Mqtt_msg2 = "LED_ON" Then
                    Set Ledd13
               End If

               If Mqtt_msg2 = "LED_OFF" Then
                    Reset Ledd13
               End If

               '****************************************************************

          End If
     End If

     'keep alive pingrequest
     If Mqtt_keepalive_counter > Mqtt_keepalive_ticks Then  'keep alive is 70 seconds (see connect header)
          '#if C2dbug
          Print "Pingreq"
          '#endif
          Mqtt_result = Tcpwrite(mqtt_idx , Mqtt_pingreq)   'pingrequest
          Mqtt_keepalive_counter = 0
     End If

     If Mqtt_pingresponse_counter > Mqtt_ka_ticks_pr Then   'keepalive ticks pingresponse
          Print "No pingresponses! - Reboot"
          Goto 0                                            'reboot
     End If

     'Keep alive counter
     Incr Mqtt_keepalive_counter
     'pingresponse counter
     Incr Mqtt_pingresponse_counter
Loop
'you will never reach these lines at the moment

Call Mqtt_disconnect()
                                'disconnect socket
End
 


With a publish to home/hobbycorner/arduino1/ledD13 of the message LED_ON or LED_OFF put a led on or off.

This client is subscribed to home/hobbycorner/arduino1/ledD13 and checks what messages are send.


You can see I have waited a few minutes, so you can see the PINGREQuests at work.


To help you locate the D13 testled on the Arduino Mega, this is put in the home/hobbycorner/arduino1/log


Because we have also a subscribe to home/hobbycorner/arduino1/ledD13 on the Arduino MQTT Dashboard, we can see what has been sent to the Bascom-MQTT client.



At the connect we made a Last Will and Testament message when the client goes offline without a mqtt_disconnect.

I am happy
Ben Zijlstra

BTW, this is a small trick to get the complete MQTT message read, but only store the first 511 bytes in an array... The Wiznet W5100 ethernetcontroller readbuffer pointer will stay at the right location, reading 10 bytes or reading 10.000 bytes

Code:
'here we read all bytes but we only store 511 bytes in array mqtt_ar()

          For Mqtt_b = 1 To Mqtt_tempw
               Mqtt_bb = Mqtt_b
               If Mqtt_bb > 511 Then Mqtt_bb = 511
               Mqtt_helpw = Tcpread(mqtt_idx , Mqtt_ar(mqtt_bb) , 1)
          Next Mqtt_b


Last edited by bzijlstra on Sat Jul 16, 2016 11:46 pm; edited 4 times in total
Back to top
View user's profile Visit poster's website
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 6198
Location: Holland

blank.gif
PostPosted: Wed Jul 06, 2016 8:06 pm    Post subject: Reply with quote

thanks Ben for this sample ,code , info and screens. I did not used the last will yet but it is useful indeed.
_________________
Mark
Back to top
View user's profile Visit poster's website
Evert :-)

Bascom Expert



Joined: 18 Feb 2005
Posts: 2165

netherlands.gif
PostPosted: Thu Jul 07, 2016 11:28 am    Post subject: Reply with quote

Nice example Ben, thanks for the hard work again.
_________________
www.evertdekker.com Bascom code vault
Back to top
View user's profile Visit poster's website
bzijlstra

Bascom Ambassador



Joined: 30 Dec 2004
Posts: 1179
Location: Tilburg - Netherlands

netherlands.gif
PostPosted: Thu Jul 07, 2016 1:33 pm    Post subject: Thanks!! Reply with quote

Evert. Thanks for the compliments.

Have fun
Ben Zijlstra
Back to top
View user's profile Visit poster's website
bzijlstra

Bascom Ambassador



Joined: 30 Dec 2004
Posts: 1179
Location: Tilburg - Netherlands

netherlands.gif
PostPosted: Tue Aug 02, 2016 6:04 pm    Post subject: MQTT-SMS Reply with quote

Here the code to send a SMS-message from your MQTT network

Used a M590 GPRS module connected through a level converter to COM2 of an Arduino Mega

The Arduino Mega is acting as a MQTT-client waiting for a message in home/gateway/sms/outgoing

And leaving a succesfull or non-successfull message in home/gateway/sms/log


The M590 module from Chinese Electronics (CE)


The Arduino Mega, a power supply, levelconverter for serial and the M590 module
Later on I will make a case for it. Why the power supply? In the datasheet of the M590, the module can have peaks of 2 Amps. That will be to much for the Arduino Mega with an USB power supply.

A nice case:





Code:

'Light Bascom MQTT client - MQTT-SMS gateway

'connect / subscribe / publish / pingreq / (disconnect)

'subscribe to home/gateway/sms/outgoing

'publish to   home/gateway/sms/log

'Hardware: Arduino Mega 2560 with W5100 Ethernet shield

'M590 GPRS module

'Connecting to a Raspberry Mosquitto MQTT Broker - 192.168.0.98

'Ben Zijlstra - 2016

'Monkey proof.

'mqtt_client_ID = Bascom<MAC-address>

'Publish a message to topic: home/gateway/sms/outgoing and it will be send

'format message: [<number phone>]message

'succesfull or not succesfull as a message in the topic: home/gateway/sms/log


$regfile = "m2560def.dat"                                   ' specify the used micro
$crystal = 16000000                                         ' used crystal frequency
$baud = 115200                                              ' use baud rate
$hwstack = 300
$swstack = 300
$framesize = 300

Config Portb.4 = Output
Wiz5100_cs Alias Portb.4
Wiz5100_cs = 1
Waitms 500

'serial connection to the nodemcu
Config Com1 = 115200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
'serial connection to a debug PC
Config Com2 = 115200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
'create a buffered serial connection to the M590 module
Config Serialin1 = Buffered , Size = 254

'Open both com-ports
Open "com1:" For Binary As #1
Open "com2:" For Binary As #2

Config Portb.7 = Output
Ledd13 Alias Portb.7

Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0
Spiinit

Config Tcpip = Noint , Mac = 222.237.186.254.254.237 , Ip = 192.168.0.223 , Submask = 255.255.255.0 , Gateway = 192.168.0.1 , _
Localport = 7000 , Tx = $55 , Rx = $55 , Chip = W5100 , Spi = 1 , Cs = Portb.4

Config Submode = New

'debug-options
Const Cdebug = 1                                            'for debug purpose
Const C2dbug = 1                                            'if you are using debug, the main loop will take more time

$include "mqtt\mqtt_functions.inc"                          'see previous items in this forum
$include "Mqtt\Mqtt_declares.inc"                           'see previous items in this forum

'declares for add-on routine
Dim Templed As Byte
Dim Buffer As String * 80
Dim A As Byte
Dim C As Byte
Dim Count As Byte
Dim Sms(2) As String * 100
Dim Status As String * 7
Dim Error_counter As Byte
Dim Timeout As Word

Enable Interrupts

'constants                                                  'and perhaps you get problems with your keep-alives
Const Mqtt_keepalive = 60
Const Mqtt_keepalive_ticks = Mqtt_keepalive * 14000         'depends on the length of the main loop - keep alive * second
Const Mqtt_ka_ticks_pr = Mqtt_keepalive_ticks + 30000

Mqtt_client_id = "Bascomdeedbafefeed"                       'same as MAC address

Sub Wait_for_ok_error()
     Buffer = ""
     Timeout = 0
     Do
          Incr Timeout
          A = Inkey(#2)
          If A > 0 Then
               Print #1 , Chr(a);
               Buffer = Buffer + Chr(a)
               C = Instr(buffer , "OK" )
               If C > 0 Then
                    Print #1 , ""
                    Status = "OK"
                    Exit Do
               End If
               C = Instr(buffer , "ERROR" )
               If C > 0 Then
                    Print #1 , ""
                    Status = "ERROR"
                    Exit Do
               End If
          End If
     Loop Until Timeout = 25000
     If Timeout = 25000 Then
          Status = "ERROR"
          Wait 4
     End If
     If Status = "ERROR" Then
          Print #1 , "Error count " ; Error_counter
          Goto Process
     End If
End Sub


#if C2dbug
     Print "Programm start"
     Print
#endif

Mqtt_idx = 0

Do
     Mqtt_bclient = Getsocket(mqtt_idx , Sock_stream , 0 , 0)       'Open socket TCP (sock_stream)
     Mqtt_result = Socketconnect(mqtt_idx , 192.168.0.98 , 1883)       'the IP-address of the MQTT broker and the port 1883

     Mqtt_tempw = Socketstat(mqtt_idx , 0)                  'get status
     If Mqtt_tempw = Sock_established Then
          #if C2dbug
               Print "Socket established with MQTT broker"
          #endif
          Exit Do
     End If
Loop

#if Cdebug
     Print "Connect"
#endif


Call Mqtt_connect()
Wait 2
Call Mqtt_subscribe( "home/gateway/sms/outgoing")
Wait 4
Call Mqtt_publish( "home/gateway/sms/log" , "Device MQTT-SMS Online")


'is something published in the subscribed topic?
Do
     Mqtt_tempw = Socketstat(mqtt_idx , Sel_recv)           'get received bytes
     If Mqtt_tempw = 2 Then                                 '2 bytes, a reaction of a pingrequest
          Mqtt_helpw = Tcpread(mqtt_idx , Mqtt_s , 2)
          Mqtt_status = Mqtt_s And &H0000FFFF               'two bytes
          If Mqtt_status = &H000000D0 Then
               #if Cdebug
                    Print "Pingresponse received"
               #endif
               Mqtt_pingresponse_counter = 0                'start pingresponse time again
          End If
     End If

     If Mqtt_tempw > 2 Then                                 'if there is something received
          #if Cdebug
               Print "something arrives"
               Print
               'Print "Tempw = " ; Tempw
          #endif

          'here we read all bytes but we only store 511 bytes in array mqtt_ar()

          For Mqtt_b = 1 To Mqtt_tempw
               Mqtt_bb = Mqtt_b
               If Mqtt_bb > 511 Then Mqtt_bb = 511
               Mqtt_helpw = Tcpread(mqtt_idx , Mqtt_ar(mqtt_bb) , 1)
          Next Mqtt_b

          'you can expect here in mqtt_ar(1) a 48 or 49

          If Mqtt_ar(1) = 48 Or Mqtt_ar(1) = 49 Then

          'length of topic/message combination will be in mqtt_ar(2)

          'here we check how many bytes are used for Remaining Length..

          'if topic/message < 128 bytes, the length of topic is in mqtt_ar(4)

          'if topic/message larger you get extra remaining length bytes, up to 4 bytes

               Mqtt_startmsgcounter = 4                     'length of topic in mqtt_ar(4)

               If Mqtt_ar(2) > 127 Then                     'MSB-bit, so a second byte is used for the length
                    Incr Mqtt_startmsgcounter
               End If

               If Mqtt_ar(3) > 127 Then                     'MSB-bit, so a third byte is used for the length
                    Incr Mqtt_startmsgcounter
               End If

               If Mqtt_ar(4) > 127 Then                     'MSB-bit, so a fourth byte is used for the length
                    Incr Mqtt_startmsgcounter
               End If

               Mqtt_pakketlength = Mqtt_bb - 4

               #if Cdebug
                    Print "Total length message including Topic  " ; Mqtt_pakketlength
                    Print "Length of Topic                       " ; Mqtt_ar(mqtt_startmsgcounter)
               #endif

               Mqtt_pakkethlp = Mqtt_startmsgcounter + 1
               Mqtt_pakkethlp2 = Mqtt_startmsgcounter + Mqtt_ar(mqtt_startmsgcounter)

               Mqtt_topic = ""
               For Mqtt_pakkethelp = Mqtt_pakkethlp To Mqtt_pakkethlp2
                    Mqtt_topic = Mqtt_topic + Chr(mqtt_ar(mqtt_pakkethelp))
               Next Mqtt_pakkethelp
               'Print
               'Print "Topic:   " ; Mqtt_topic

               Mqtt_msg2 = ""
               For Mqtt_pakkethlp = Mqtt_pakkethelp To Mqtt_pakketlength + 4
                    Mqtt_msg2 = Mqtt_msg2 + Chr(mqtt_ar(mqtt_pakkethlp))
               Next Mqtt_pakkethlp
               'Print
               'Print "Message: " ; Mqtt_msg2
               'Print

               'here you put the routine that will act on incoming (topic/)message


              '****************************************************************

               'format: [<mobile number>]message to be send

               Error_counter = 0
               Timeout = 0

               Count = Split(mqtt_msg2 , Sms(1) , "]")

               Sms(1) = Mid(sms(1) , 2)
               Sms(1) = "{034}" + Sms(1)
               Sms(1) = Sms(1) + "{034}{013}{010}"

               Print #1 , "Phonenumber TO " ; Sms(1)
               Print #1 , "Message        " ; Sms(2)

               Set Ledd13                                   'active led

               Process:
                    Incr Error_counter
                    If Error_counter = 10 Then
                         Buffer = "Error sending SMS to " + Sms(1)
                         Call Mqtt_publish( "home/gateway/sms/log" , Buffer)
                         Goto Quit_process
                    End If
                    Timeout = 0

                    Print #2 , "ATZ{013}{010}"              'reset GSM-module
                    Print #1 , "ATZ{013}{010}"

                    Call Wait_for_ok_error
                    Wait 1

                    Print #2 , "ATE0{013}{010}"             'echo off
                    Print #1 , "ATE0{013}{010}"

                    Call Wait_for_ok_error
                    Wait 1

                    Print #2 , "AT+CREG=0{013}{010}"        'disconnect from network
                    Print #1 , "AT+CREG=0{013}{010}"

                    Call Wait_for_ok_error
                    Wait 1

                    Print #2 , "AT+CREG=1{013}{010}"        'connect to network
                    Print #1 , "AT+CREG=1{013}{010}"

                    Call Wait_for_ok_error
                    Wait 1

                    Print #2 , "AT+CREG?{013}{010}"         'check network connection
                    Print #1 , "AT+CREG?{013}{010}"

                    Buffer = ""
                    Do
                         Incr Timeout
                         A = Inkey(#2)
                         If A > 0 Then
                              Print #1 , Chr(a);
                              Buffer = Buffer + Chr(a)
                              C = Instr(buffer , "+CREG: 1,1" )       'connected to the network
                              If C > 0 Then
                                   Print #1 , ""
                                   Status = "OK"
                                   Exit Do
                              End If
                         End If
                    Loop Until Timeout = 25000
                    If Timeout = 25000 Then Goto Process
                    Wait 1

                    Print #2 , "AT+CMGF=1{013}{010}"        'text mode
                    Print #1 , "AT+CMGF=1{013}{010}"

                    Call Wait_for_ok_error
                    Wait 1

                    Print #2 , "AT+CSCS={034}GSM{034}{013}{010}"       'default alphabet
                    Print #1 , "AT+CSCS={034}GSM{034}{013}{010}"

                    Call Wait_for_ok_error
                    Wait 1

                    Print #2 , "AT+CMGS=" ; Sms(1)          'SMS message
                    Wait 1                                  'first phone number with quotes
                    Print #1 , "ÄT+CMGS=" ; Sms(1)

                    Wait 1

                    Print #2 , Sms(2)                       'SMS message
                    Print #1 , Sms(2)

                    Wait 1

                    Print #2 , ""
                    Print #1 , ""

                    Wait 1

                    Print #2 , ""
                    Print #1 , ""

                    Wait 1

                    Print #2 , "mqtt-sms"                   'footer
                    Print #1 , "mqtt-sms"

                    Wait 1

                    Print #2 , "{026}"                      'end of SMS message
                    Print #1 , "<Ctrl-Z>"

                    Call Wait_for_ok_error
                    Wait 1

                    Buffer = "SMS sent to " + Sms(1)        'put an entry in the log
                    Call Mqtt_publish( "home/gateway/sms/log" , Buffer)

               Quit_process:

               Reset Ledd13                                 'non active led

               '****************************************************************

          End If
     End If

     'keep alive pingrequest
     If Mqtt_keepalive_counter > Mqtt_keepalive_ticks Then  'keep alive is 70 seconds (see connect header)
          '#if C2dbug
          Print "Pingreq"
          '#endif
          Mqtt_result = Tcpwrite(mqtt_idx , Mqtt_pingreq)   'pingrequest
          Mqtt_keepalive_counter = 0
     End If

     If Mqtt_pingresponse_counter > Mqtt_ka_ticks_pr Then   'keepalive ticks pingresponse
          Print "No pingresponses! - Reboot"
          Goto 0                                            'reboot
     End If

     'Keep alive counter
     Incr Mqtt_keepalive_counter
     'pingresponse counter
     Incr Mqtt_pingresponse_counter
Loop
'you will never reach these lines at the moment

Call Mqtt_disconnect()
                                'disconnect socket
End
 






Device on line, message in outgoing and SMS sent.


Last edited by bzijlstra on Sun Jan 08, 2017 3:05 pm; edited 1 time in total
Back to top
View user's profile Visit poster's website
Evert :-)

Bascom Expert



Joined: 18 Feb 2005
Posts: 2165

netherlands.gif
PostPosted: Thu Aug 04, 2016 10:23 pm    Post subject: Reply with quote

Hi Ben,

Thanks for the update.

If you have Mqtt running on you own raspberry then you also must have a look at Node Red
Very interesting to do (a lot) more with the Iot and Mqtt.
You can install and run Node Red on the same raspberry and connect everything with everything with some simple wires.
Have a look at this video for example https://www.youtube.com/watch?v=f5o4tIz2Zzc

Hope that you are now just as enthusiast as me.

_________________
www.evertdekker.com Bascom code vault
Back to top
View user's profile Visit poster's website
bzijlstra

Bascom Ambassador



Joined: 30 Dec 2004
Posts: 1179
Location: Tilburg - Netherlands

netherlands.gif
PostPosted: Fri Aug 05, 2016 12:30 am    Post subject: Node Red Reply with quote

Thanks for the tip. The YouTube video looks very promising...

Have fun
Ben Zijlstra
Back to top
View user's profile Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> Share your working BASCOM-AVR code here All times are GMT + 1 Hour
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum