Skip to content

Commit 9fde055

Browse files
committed
Merge branch 'main' into 14-add-a-class-for-udp-client
2 parents 354e503 + 9c4100f commit 9fde055

File tree

10 files changed

+298
-92
lines changed

10 files changed

+298
-92
lines changed

README.md

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ In this repo it will be implemented an Arduino library wrapper for RPClite to be
55
Including Arduino_RouterBridge.h gives the user access to a Bridge object that can be used both as a RPC client and/or server to execute and serve RPCs to/from the CPU Host running a GOLANG router.
66

77
- The Bridge object is pre-defined on Serial1 and automatically initialized inside the main setup()
8-
- The Bridge.call method is blocking and works the same as in RPClite
8+
- The Bridge.call method is non-blocking and returns a RpcResult async object
9+
- RpcResult class implements a blocking .result method that waits for the RPC response and returns true if the RPC returned with no errors
910
- The Bridge can provide callbacks to incoming RPC requests both in a thread-unsafe and thread-safe fashion (provide & provide_safe)
1011
- Thread-safe methods execution is granted in the main loop thread where update_safe is called. By design users cannot access .update_safe() freely
1112
- Thread-unsafe methods are served in an update callback, whose execution is granted in a separate thread. Nonetheless users can access .update() freely with caution
@@ -24,29 +25,50 @@ String greet() {
2425
}
2526

2627
void setup() {
27-
Serial.begin(115200);
28-
while (!Serial);
29-
28+
29+
Bridge.begin();
30+
Monitor.begin();
31+
3032
pinMode(LED_BUILTIN, OUTPUT);
3133

3234
if (!Bridge.provide("set_led", set_led)) {
33-
Serial.println("Error providing method: set_led");
35+
Monitor.println("Error providing method: set_led");
3436
} else {
35-
Serial.println("Registered method: set_led");
37+
Monitor.println("Registered method: set_led");
3638
}
3739

3840
Bridge.provide_safe("greet", greet);
3941

4042
}
4143

4244
void loop() {
43-
float res;
44-
if (!Bridge.call("multiply", res, 1.0, 2.0)) {
45-
Serial.println("Error calling method: multiply");
46-
Serial.println(Bridge.get_error_code());
47-
Serial.println(Bridge.get_error_message());
45+
float sum;
46+
47+
// CALL EXAMPLES
48+
49+
// Standard chained call: Bridge.call("method", params...).result(res)
50+
if (!Bridge.call("add", 1.0, 2.0).result(sum)) {
51+
Monitor.println("Error calling method: add");
52+
};
53+
54+
// Async call
55+
RpcResult async_rpc = Bridge.call("add", 3.0, 4.5);
56+
if (!async_rpc.result(sum)) {
57+
Monitor.println("Error calling method: add");
58+
Monitor.print("Error code: ");
59+
Monitor.println(async_rpc.error.code);
60+
Monitor.print("Error message: ");
61+
Monitor.println(async_rpc.error.traceback);
62+
}
63+
64+
// Implicit boolean cast. Use with caution as in this case the call is indeed
65+
// executed expecting a fallback nil result (MsgPack::object::nil_t)
66+
if (!Bridge.call("send_greeting", "Hello Friend")) {
67+
Monitor.println("Error calling method: send_greeting");
4868
};
4969

70+
// Please use notify when no reult (None, null, void, nil etc.) is expected from the opposite side
71+
// the following is executed immediately
5072
Bridge.notify("signal", 200);
5173
}
5274
```

examples/simple_bridge/simple_bridge.ino

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,23 @@ void setup() {
4747

4848
void loop() {
4949
float res;
50-
if (!Bridge.call("multiply", res, 1.0, 2.0)) {
50+
if (!Bridge.call("multiply", 1.0, 2.0).result(res)) {
5151
Serial.println("Error calling method: multiply");
5252
Serial.println(Bridge.get_error_code());
5353
Serial.println(Bridge.get_error_message());
5454
};
5555

56+
// Call with deferred response check
57+
RpcResult outcome = Bridge.call("multiply", 5.0, 7.0);
58+
Serial.println("RPC called");
59+
delay(10);
60+
if (outcome.result(res)) {
61+
Serial.print("Result of the operation is: ");
62+
Serial.println(res);
63+
} else {
64+
Serial.println(Bridge.get_error_code());
65+
Serial.println(Bridge.get_error_message());
66+
}
67+
5668
Bridge.notify("signal", 200);
5769
}

examples/test/python/main.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import time
2+
from arduino.app_utils import *
3+
4+
5+
def no_args_no_result():
6+
print("0 args no result")
7+
return
8+
9+
def no_args_bool_result():
10+
print("0 args bool result")
11+
return True
12+
13+
def one_args_float_result(a):
14+
print("1 args float result")
15+
return a^2
16+
17+
def two_args_float_result(a, b):
18+
print("2 args float result")
19+
return a/b
20+
21+
def one_args_no_result(msg: str):
22+
print("1 args no result")
23+
print(f"Message received: {msg}")
24+
25+
def two_args_no_result(msg: str, x: int):
26+
print("2 args no result")
27+
print(f"Message received: {msg} {str(x)}")
28+
29+
30+
if __name__ == "__main__":
31+
32+
Bridge.provide("0_args_no_result", no_args_no_result)
33+
Bridge.provide("0_args_bool_result", no_args_bool_result)
34+
Bridge.provide("1_args_float_result", one_args_float_result)
35+
Bridge.provide("2_args_float_result", two_args_float_result)
36+
Bridge.provide("1_args_no_result", one_args_no_result)
37+
Bridge.provide("2_args_no_result", two_args_no_result)
38+
39+
App.run()

examples/test/test.ino

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
This file is part of the Arduino_RouterBridge library.
3+
4+
Copyright (c) 2025 Arduino SA
5+
6+
This Source Code Form is subject to the terms of the Mozilla Public
7+
License, v. 2.0. If a copy of the MPL was not distributed with this
8+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
10+
*/
11+
12+
13+
#include "Arduino_RouterBridge.h"
14+
15+
bool x;
16+
int i=0;
17+
18+
void setup() {
19+
Bridge.begin();
20+
Monitor.begin();
21+
}
22+
23+
void loop() {
24+
25+
// testing monitor
26+
Monitor.println("\r\n"+String(i));
27+
i++;
28+
29+
// working
30+
Bridge.call("0_args_no_result");
31+
32+
if (Bridge.call("0_args_no_result")){
33+
Monitor.println("0_args_no_result TRUE without result"); // returns true because there's no result
34+
}
35+
else{
36+
Monitor.println("0_args_no_result FALSE without result");
37+
}
38+
39+
if (Bridge.call("0_args_bool_result")){
40+
Monitor.println("0_args_bool_result TRUE without result");
41+
}
42+
else{
43+
Monitor.println("0_args_bool_result FALSE without result"); // returns false -> check the result
44+
}
45+
46+
x = false;
47+
if (Bridge.call("0_args_bool_result").result(x)){
48+
Monitor.println("0_args_bool_result TRUE with result: "+String(x)); // returns true - the perfect call
49+
}
50+
else{
51+
Monitor.println("0_args_bool_result FALSE witt result: "+String(x));
52+
}
53+
54+
int y = -1;
55+
if (Bridge.call("0_args_bool_result").result(y)){
56+
Monitor.println("0_args_bool_result TRUE with result: "+String(y)+" (wrong result type)");
57+
}
58+
else {
59+
Monitor.println("0_args_bool_result FALSE with result: "+String(y)+" (wrong result type)"); // returns false - wrong type
60+
}
61+
62+
float pow;
63+
RpcResult async_res = Bridge.call("1_args_float_result", 2.0, 3.0); // passing 2 args to a function expecting 1
64+
if (async_res.result(pow)) {
65+
Monitor.println("Result of assignment and then result: "+String(pow)); // returns true, so the right result
66+
} else {
67+
Monitor.println("Error code: "+String(async_res.error.code));
68+
Monitor.println("Error message: "+async_res.error.traceback);
69+
}
70+
71+
float div = 0;
72+
RpcResult async_res1 = Bridge.call("2_args_float_result", 2.0); // passing 1 arg when 2 are expected
73+
if (async_res1.result(div)) {
74+
Monitor.println("Result of assignment and then result: "+String(div)); // returns true, so the right result
75+
} else {
76+
Monitor.println("Error code: "+String(async_res1.error.code));
77+
Monitor.println("Error message: "+async_res1.error.traceback);
78+
}
79+
80+
div = 0;
81+
RpcResult async_res2 = Bridge.call("2_args_float_result", 2.0, "invalid"); // passing a wrong type arg
82+
if (async_res2.result(div)) {
83+
Monitor.println("Result of assignment and then result: "+String(div)); // returns true, so the right result
84+
} else {
85+
Monitor.println("Error code: "+String(async_res2.error.code));
86+
Monitor.println("Error message: "+async_res2.error.traceback);
87+
}
88+
89+
x = false;
90+
RpcResult async_res3 = Bridge.call("0_args_bool_result");
91+
if (async_res3.result(x)) {
92+
Monitor.println("Result of assignment and then result: "+String(x)); // returns true, so the right result
93+
} else {
94+
Monitor.println("Error expecting bool result: "+String(async_res3.error.code));
95+
}
96+
97+
// Avoid the following:
98+
// the call happens in the destructor falling back to the "no_result" case (a type mismatch here)
99+
RpcResult async_res4 = Bridge.call("0_args_bool_result");
100+
101+
delay(1000);
102+
}

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"url": "https://github.com/bcmi-labs/Arduino_RouterBridge",
1212
"maintainer": true
1313
},
14-
"version": "0.1.4",
14+
"version": "0.2.1",
1515
"license": "MPL2.0",
1616
"frameworks": "arduino",
1717
"platforms": "*",

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Arduino_RouterBridge
2-
version=0.1.4
2+
version=0.2.1
33
author=BCMI-labs
44
maintainer=BCMI-labs
55
sentence=A RPC bridge for Arduino UNO Q boards

0 commit comments

Comments
 (0)