Receiving/sending SMS

Some of our PLCs are equipped with LTE modem capable of sending SMS. In this tutorial we will learn how to configure such PLC and how to use function block for sending SMS.

Axon Mx65

For receiving/sending SMS via an LTE modem, it is not necessary to configure the modem as described in LTE configuration. Instead, you need to configure Alarm channel. Double click on the PLC in the Left panel. Select a Messaging subpanel, right click on the blank list of channels and select Add alarm channel from the context menu:


A new alarm channel will appear. By default it is filled with preconfiguration for sending emails. Click on the Type (now prefilled with “Smtp”) and change it to Gsm:


Move over to the channel's properties and change the Port Number to LTE:


If the SIM card is protected with a PIN code, enter it, otherwise leave empty:


Most modems (UniPi's as well) need initialization commands. Click to three-dot icon next to AT Commands Definition. A window will pop up:


In the drop down menu select the correct modem. For UniPi Axon product line it is UniPi Axon LTE:


Don't forget to apply this selection by clicking on Apply and closing this dialog:


The channel is configured and now the changes need to be commited. Click on the OK in the red bar:

To use the modem in program, look for “SendSMS Triggered” function block and place it into a program:


The function block expects 4 inputs and we will create a auxiliary variables for better debugging. Starting with the variable for input channel. Create a string variable and set its initial value to the name of the created alarm channel. By default it will be alrchannel:


The same we will do for the rest of the variables:

  • recipient: string variable containing a phone number in international format such as 00420777666555)
  • message: string variable containing the actual SMS message
  • trigger: bool variable which will execute the sending of the message on rising edge

The result should look similar:


Now deploy the solution and start the debugging mode. On each change of the variable trigger from False to True, the message will be send:

If the SMS has been send correctly, the Result output will be 0. Otherwise an error code will be issued and you can consult help (F1) for the given function block to determine the cause of the error.

The receiveSMS function block in the base is not intended for use in FBD, as it would query messages in each program cycle. However, it can be used in FBD with appropriate modifications

This function block has no input variables, but contains 5 outputs:

  • channel: variable of type string, contains the designation of the alarm channel on which the SMS was received (in case of multiple modems)
  • sender: variable of type string, contains telephone number in international format (e.g. +420777666555)
  • message: variable of type string, contains the text of the SMS message itself
  • receivetime: variable of type DT, contains the time when the message was received

The last output is an unlabeled output, which is of type integer and contains a numeric status with the result of the operation. More is described below in the text (for the output result).


Since the block is intended only for use in the ST, it is necessary to create your own function block written in the ST for its use. This is only possible in Full Mode solution. The procedure for switching to full mode can be found here in the introductory article.

To receive an SMS, create a function block by right-clicking on the project (e.g. in executable projects).


A dialog box will appear, select/paste here:

  • Name: ReceiveSMS_fbd
  • Type: FunctionBlock
  • Language: st
  • Namespace: v0_0

and confirm by clicking OK.


A window with the code structure example of the function block will open. Delete all the contents of the block and replace them with the following code:

ReceiveSMS_fbd.st
NAMESPACE v0_0 
FUNCTION_BLOCK ReceiveSMS_fbd

	VAR
		trigger : R_TRIG;
		readPulse : bool := 0;
	END_VAR
	VAR_INPUT
		readSMS : bool := 0;
	END_VAR
	VAR_OUTPUT
		result : int := 31;
		
		sms_channel : string := "";
		sender : string := "";
		message : string := "";
		receive_time : dt := dt#0001-01-01-00:00:00;
	END_VAR

	trigger(CLK:=readSMS,Q=>readPulse);
	
	IF readPulse THEN
		result := MESSAGING.RECEIVESMS(
			CHANNEL => sms_channel,
			SENDER => sender,
			MESSAGE => message,
			RECEIVETIME => receive_time
		);
	END_IF;

END_FUNCTION_BLOCK
END_NAMESPACE

The result should look like this:


You can now close the function block window, then save and compile the solution.

Then open main.program.fbd and right-click on an empty space and select from the context menu: Add library box → Add library box.


A dialog window for searching for functions and function blocks opens. In the Name field, enter a name of the block: ReceiveSMS_fbd, highlight it and click OK.


This inserts the block into the program space:


Now you need to create several test variables. First, create an input variable trigger of type bool and enter False as its initial value. Connect the variable to the readSMS input of the block:


Next, create the output variables channel, sender, and message, all of the type string. Lastly, create a variable receivetime of type DT. Since all variables are output, it is not necessary to set their initial values. Finally, connect them to the block.

The result should look something like this:


Upload the solution and start debugging. Each time the value of the variable trigger is changed from False to True, one message is read from the SIM card memory.

The result output will be 0 if the message was read correctly and 31 if no message is available. Other values indicate an error, see the help (F1 key) for the receivesms function block.