Raspberry Pi to Delphi messaging with MQTT

Bookmarks: 

Tuesday, February 28, 2017

As promised in the blog about building a chat application with MQTT, here is a follow-up article on using the TMS MQTT client, this time to setup messaging between a Raspberry Pi and a Windows PC. The TMS MQTT client fully supports Lazarus and thus also targetting Linux and its variant Raspbian, so we can use the TMS MQTT Client from Raspberry Pi. For this short demo, we setup Lazarus on Raspberry Pi and installed the TMS MQTT client component in the IDE as well as our free Raspberry Pi hardware lib.

We'll use the component TMSLCLAdaADC12b to be able to use the 12bit ADC connected via i2c to the Raspberry Pi. The goal of the setup is to read-out noise meter values via the ADC and send the measurements via messaging to the channel 'tms/raspi'. A Windows Delphi application will then listen through this same MQTT client to the messages on channel 'tms/raspi' and will display the values in our TMS Instrumentation Workshop component TvrScope. Best of all, with the help of these components, this is not much more than a 15 minute project where most of the time will be spent to properly connect the ADC breakout board via a breadboard to the Raspberry Pi i2c port.



For the code, we use the same setup in the Windows Delphi application as on the Raspberry Pi Lazarus application to connect our client to the Mosquitto test broker:

begin
  TMSMQTTClient1.BrokerHostName := 'test.mosquitto.org';
  TMSMQTTClient1.Connect;
end;

On the Raspberry Pi Lazarus app, we add a timer that will get the ADC value every 200msec and send the value as a message to 'tms/raspi'. For reason of simplicity, we'll send the value as a text message via MQTT. The code to do this is added to the timer OnTimer() event handler:

var
  i: integer;
begin
  // get value from the 4 channel ADC channel 0 to which the analog noise meter output is connected
  i := TMSLCLAdaADC12B1.ReadChannel(0);
  // send the value as text over MQTT
  TMSMQTTClient1.Publish('tms/raspi', inttostr(i)); 
end;

To get the i2c communication working on the Raspberry Pi, we open the i2c connection to the ADC in the form's OnCreate event:

procedure TForm1.FormCreate(Sender: TObject);
begin
  // make sure to start the Raspberry Pi app with sufficient permissions to be able to open access to i2c
  if not TMSLCLAdaADC12B1.Open then
  begin  
    ShowMessage('error opening i2c');
    Exit;
  end;
end;
and we close the port again from the form's OnClose event:

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  TMSLCLAdaADC12B1.Close;
end;

For the Delphi Windows client, here we'll add an event handler for TMSMQTTClient.OnPublishReceived() that is triggered when a message is received. From this event, we store the received value in a variable containing the last received value LastVal. Here the (positive) value of the ADC is mapped onto the 0 to 100 range:

procedure TForm1.TMSMQTTClient1PublishReceived(ASender: TObject;
  APacketID: Word; ATopic: string; APayload: TArray<System.Byte>);
var
  s:string;
begin
  s := TEncoding.UTF8.GetString(APayload);
  LastVal := Round(100 * strtoint(s) / 1024);
end;

To visualize the data, the TMS Instrumentation Workshop TVrScope component is used where we added one channel and automatic display (VrScope.Active = true). This means that at a configured frequency (VrScope.Frequency), this scope component requests the channel value and displays it in the scope. This is done via the TvrScope.OnNeedData() event that is triggered every time the scope advances and needs a new value. Here, the last received value LastVal is returned:
procedure TForm1.VrScope1NeedData(Sender: TObject; Channel: Integer;
  var Value: Integer);
begin
  Value := LastVal;
end;

As a result, here you can see some quickly captured data in our test setup:


In summary, this small demo shows how really quick & easy you can get started using m2m messaging using MQTT with the TMS MQTT Client and this on a wide range of devices, from desktop PC to mobile device, to Linux machine and to Raspberry Pi SBC. We wish you much fun with your projects and we love to hear from all the exciting stuff you create with these building blocks!

Bruno Fierens


Bookmarks: 

This blog post has not received any comments yet. Add a comment.



Cross platform messaging made easy with TMS MQTT

Bookmarks: 

Tuesday, February 14, 2017

Last week we released a new product, TMS MQTT. MQTT is a standard lightweight machine 2 machine messaging protocol. This enables the instant exchange of binary or text messages between code running on various operating systems. To fully take advantage of this, we developed our TMS MQTT client to work in VCL Windows applications, FMX Windows, macOS, iOS and Android applications and also on Linux desktop or Linux variants such as Raspbian on Raspberry Pi via FPC/Lazarus.

On this 22th birthday of Delphi, I wanted to show you how our TMS MQTT component allows you to develop a messaging application in a real RAD way. I'll do this by implementing a chat application that allows you to chat between clients running on desktops or mobile devices. This effectively takes less than 40 lines of code using the TMS MQTT component of which 15 lines already go to inserting the chat text left and right in items of an FMX listbox and another +/- 10 lines detecting the origin of the chat text that is received to decide whether to show it left or right in the listbox. So, I'd say only about 15 lines of code effectively concern using the MQTT client to do the messaging.

For this demo, we use the Mosquitto MQTT test broker and connect to it with 2 lines of code:
begin
  TMSMQTTClient1.BrokerHostName := 'test.mosquitto.org';
  TMSMQTTClient1.Connect();
end;

Upon connecting, we subscribe to the topic 'tms/chat' that is the topic that will be used to exchange chat text between multiple clients. This takes 2 lines of code from the TMQTTClient.OnConnectedStatusChanged() event:
procedure TForm1.TMSMQTTClient1ConnectedStatusChanged(ASender: TObject;
  const AConnected: Boolean; AStatus: TTMSMQTTConnectionStatus);
begin
  if AConnected then
    TMSMQTTClient1.Subscribe('tms/chat');
end;
To send a message, text entered in a memo control is published on this topic with one line of code:
  TMSMQTTClient1.Publish('tms/chat', TMSMQTTClient1.ClientID+'!'+ memo1.Lines.Text);
Here we add the unique ID of the app sending the chat text and the chat text itself.
Finally, incoming chat text on the subscribed topic is received via the TMQTTClient.OnPublishReceived() event. The unique client ID is retrieved to decide whether to put the chat text left or right of the message listbox and this is done via the code:
procedure TForm1.TMSMQTTClient1PublishReceived(ASender: TObject;
  APacketID: Word; ATopic: string; APayload: TArray);
var
  msg,orig: string;
  vp: integer;
  alright: boolean;
begin
  msg := TEncoding.UTF8.GetString(APayload);

  vp := pos('!', msg);

  if vp > 0 then
  begin
    orig := copy(msg,1,vp-1);
    alright := orig <> TMSMQTTClient1.ClientID;

    msg := copy(msg, vp + 1, Length(msg));
    AddMessage(msg, alright);
  end;
end;

And then comes the method to allows us to insert either left or right aligned text as items in an FMX listbox:
procedure TForm1.AddMessage(AMessage: string; AlignRight: boolean);
var
  li: Tlistboxitem;
begin
  li := Tlistboxitem.Create(self);
  li.StyledSettings := li.StyledSettings - [TStyledSetting.ssOther];
  li.Text := AMessage;
  li.Height := 22;
    li.VertTextAlign := TTextAlign.taTrailing;

  if AlignRight then
    li.TextAlign := TTextAlign.taTrailing
  else
    li.TextAlign := TTextAlign.taLeading;

  listbox1.AddObject(li);
end;

Compile and run this application on your operating system of choice. In my case, I did setup a small chat between the client compiled for Windows and the client deployed on an iPhone:

You can download the full source code of this FireMonkey application here.

I invite you to explore the numerous exciting capabilities of machine 2 machine messaging. Note that there are JS libs that facilitate to do MQTT messaging via websockets from a webbrowser. The demo included in the TMS MQTT download is based on messaging between a desktop or mobile client app and a web page application. With the TMS MQTT client, you can also use machine 2 machine messaging from your Raspberry Pi and send this way various sensor data captured by the Raspberry Pi to desktop or mobile apps. In a follow-up blog, we'll explain and offer such sample project.

I look forward to hear about how you will use MQTT machine 2 machine messaging in your apps or IoT projects!



Bruno Fierens


Bookmarks: 

This blog post has received 8 comments. Add a comment.




Previous  |  Next  |  Index