This post aims to describe the sequence of events that occur when a user sends these data items: 0x1234 , 1.5 , Forum from MCU to MPU using Router Bridge.
Readers are welcome to provide comments and suggestions for improving both the technical content and the presentation of this post.
A: MCU ------------> MPU
1. At the MCU side, the user executes the following code to send the tag and the data items:
Bridge.call("get_data", 0x1234, 1.57, "Forum"); //get_data is called tag
2. Data Send Mechanism by MCU
(1) MCU and MPU uses UART port communication link called Router Bridge for data exchange.
(2) The four arguments of Bridge.call("get_data", 0x1234, 1.57, "Forum") are taken care of by the MsgPack.h Library to prepare the following 24-byte Message Frame.
1-byte : Message Marker
9-byte : for string get_data (1-byte String Marke1 + 8 byte for 8 characters)
3-byte : for integer 0x1234 (1-byte Int Marker + 2-byte for 2-byte data)
5-byte : for float 1.57 (1-byte float Marker + 4-byte for IEEE-754 fromatted 32-bit)
6-byte : for string Forum (1-byte String Marker + 5-byte for 5-charcaters)
0x94 : Message Marker
0xA8 : String Marker (0xA0)+Number of characters in string (0x08): get_data
0x67 0x65 0x74 0x5F 0x64 0x61 0x74 0x61 : ASCII code for: g e t _ d a t a
0xCD : Integer Marker (0xCD)
0x12 0x34 : High byte and Low byte of 0x1234
0xCA : Float Marker
0x3F 0xC8 0xF5 0xC3 : 32-bit IEEE-754 formatted data for 1.57
0xA5 : String Marker (0xA0)+Number of characters (0x05) in string: Forum
0x46 0x6F 0x72 0x75 0x6D : ASCII codes for charcaters of F o r u m
(3) The resultatnt 24-byte wide Transmission Frame is: ( (spaces and linefeeds are shown for clarity)
0x94
0xA8 0x67 0x65 0x74 0x5F 0x64 0x61 0x74 0x61
0xCD 0x12 0x34
0xCA 0x3F 0xC8 0xF5 0xC3
0xA5 0x46 0x6F 0x72 0x75 0x6D
(4) The above 24 bytes data are sent by the MCU one-after-another as 10-bit (1-StartBit, 8-dataBit, 1-StopBit) asynchronous frame at Bd = 115200. The total arrival time is about:
(10 x 24) x1/115200 = 2.08 ms.
3. Data Receiption Decoding and Storage by MPU
(1) MPU executes following Python code to receive, decode, and store the 24-byte data received from MCU.
Bridge.provide("get_data", getDataCallback)
(2) Once the matching tag get_data has een detected, the Bridge.provide() mechanism parses the remaining byte stream as they arrive to extract the data items as int, float, and string and save them in the corresponding variables y , z , msg of the getDataCallback() function. After that the control is transferred to the getDataCallback() function to print the variables and to send ack/status to MCU if there is any.
def getDataCallback(y, z, msg): //Python automatically applies data types
print("\n--- Data Received Successfully ---")
print(f"y (int) : {hex(y)} (Decimal: {y})") #shows: y (int) : 0x1234 (Decimal: 4660)
print(f"z (float) : {z:.2f}") #shows: z (float) : 1.57
print(f"msg (string): {msg}") #shows: msg (string): Forum
4. Application
C++ Sketch
#include "Arduino_RouterBridge.h"
void setup() {
// Initialize communication layer
Bridge.begin();
}
void loop() {
// Fire the notification asynchronously every 5 seconds
Bridge.call("get_data", 0x1234, 1.57, "Forum");
Monitor.println("Sending Data to MPU");
delay(5000);
}
Python Script
import time
from arduino.app_utils import App, Bridge
def getDataCallback(y, z, msg):
print("==Printing received data at 5-sec interval==")
print(f"y (int) : {hex(y)} ({y})")
print(f"z (float) : {z:.2f}")
print(f"msg (string): {msg}")
# Register the callback function under the "get_data" key
Bridge.provide("get_data", getDataCallback)
def loop():
print("==Sleeping for 2-sec...!==")
time.sleep(2)
App.run(user_loop=loop)
B: MPU ----------> MCU
Bridge.call() waits to receive data/message/response from MPU. The returned value is collected by the MCU using the result() method of an object of type RpcCall (a helper class). Here, we will see how this event happens. However, MPU can also initiate Bridge.call() and Bridge.notify() functions to send data to the MCU.
Hints:
At MCU side:
unsigned long prMillis = millis();
bool status = false; //will turn to true when message comes from MPU
String value = ""; //value will be loaded with message that comes from MPU
do
{
RpcCall rpc = Bridge.call("get_data", 0x1234, 1.57, "Forum");
status = rpc.result(value);
}
while((staus != true) && (millis() - prMillis < 3)); //timeout: 3 ms
if(status == false)
{
Monitor.println("Communication error!");
while(true); //wait for ever
}
else
{
Monitor.println(value); //shows: Communication is ok!
}
At MPU side:
def getDataCallback(y, z, msg):
print("==Printing received data at 5-sec interval==")
print(f"y (int) : {hex(y)} ({y})")
print(f"z (float) : {z:.2f}")
print(f"msg (string): {msg}")
return "Communication is ok!"