Hi everyone, I’m testing the Arduino_RouterBridge library on an Arduino UNO Q using Arduino App Lab v0.2.4 on MacOs and I’m running into unexpected behavior:
I’m trying to understand whether this is a misuse of the Bridge API or a bug in the current App Lab version.
No errors during upload or runtime, but nothing appears in the MCU Monitor.
Meanwhile if I put a Monitor.println() inside loop() and add a delay(), I do see output (without using Bridge) and App.run in th python file; so I don’t think the issue is with Monitor, but instead with Bridge.
You reference a print function, but it is actually named stampa:
With that fixed, I can reproduce the problem you reported. I found it can be fixed by swapping the order of the Monitor.begin and Bridge.begin calls in the sketch.
So change these lines in your sketch:
to this:
Bridge.begin();
Monitor.begin();
Then restart the App. Everything should work as expected after doing that.
Warning: Do not use Bridge.call() or Monitor.print() inside provide() functions. Initiating a new communication while responding to one causes system deadlocks.
here:
What you should do instead is simply set a flag variable in the stampa function
// Use the `volatile` qualifier to ensure the `loop` function will recognize that the variable has been set by the
// callback function:
// https://docs.arduino.cc/language-reference/en/variables/variable-scope-qualifiers/volatile/
volatile bool stampaCalled;
void stampa() {
stampaCalled = true;
}
then take action according to the value of that variable in the loop function of the sketch:
if (stampaCalled) {
stampaCalled = false;
Monitor.println("bridge test");
}
To accompany this change, it will also be a good idea to make the loop function non-blocking, which can be done using the millis-based technique demonstrated in "BlinkWithoutDelay" tutorial:
#include <Arduino_RouterBridge.h>
unsigned long timestamp;
// Use the `volatile` qualifier to ensure the `loop` function will recognize that the variable has been set by the
// callback function:
// https://docs.arduino.cc/language-reference/en/variables/variable-scope-qualifiers/volatile/
volatile bool stampaCalled;
void stampa() {
stampaCalled = true;
}
void setup() {
Bridge.begin();
Monitor.begin();
Bridge.provide("print", stampa);
}
void loop() {
if (stampaCalled) {
stampaCalled = false;
Monitor.println("bridge test");
}
if (millis() - timestamp > 1000) {
timestamp = millis();
Bridge.call("print_mcu");
}
}
Use of Bridge call functions with methods that have no response
Unfortunately this is not mentioned in the tutorial, but we can find it in the readme of the "Arduino_RouterBridge" library:
and in the arduino.app_utils module's source code:
So change this line in the sketch:
to this:
Bridge.notify("print_mcu");
And change this line in the Python script:
to this:
Bridge.notify("print")
A further note on the problem I mentioned in my previous reply:
The Monitor.begin function contains a call to Bridge.begin, so the library could be made more user friendly by adding a check in Bridge.begin for whether it has already been initialized. It looks like such a check has been added:
That was done after the time of the last release of the "Arduino_RouterBridge" library, so this is why we still find that calling Bridge.begin after Monitor.begin makes the sketch hang.
ok to sumup, I have to call Bridge.begin() before Monitor.begin(). Not use Monitor.print or bridge.call inside a bridge.provide function. I used delay() just to make the code simplier and writing faster just to expose my problem. what about Monitor not displaying in my second code which doesn’t use the python part?
Reading between the lines, I think it is best to also consider this as applying to the Python script. A similar solution of only setting a flag variable in the callback function can be applied there as well:
from arduino.app_utils import App, Bridge
stampa_mcu_called = False
def stampa_mcu():
global stampa_mcu_called
stampa_mcu_called = True
Bridge.provide("print_mcu", stampa_mcu)
def loop():
global stampa_mcu_called
if stampa_mcu_called:
stampa_mcu_called = False
Bridge.notify("print")
App.run(user_loop=loop)
Unfortunately I don't have access to an LSM6DSOX IMU, so I can't fully investigate, but I don't encounter the problem you report. When I run the sketch, without an LSM6DSOX IMU connected to my UNO Q, I get the expected output:
I’m using an arduino modulino movement but tried to use the LSM6DSOXSensor library so that I can set update frequency and the scale of measurement. when running the sketch in Arduino App Lab the Serial monitor doesn’t show anything, but instead works fine in ide 2.x. I really need it to work in app lab because i want to implment briks to it
I think I misinterpreted this. My interpretation was that by "Serial", you were referring to the Serial object (e.g., Serial.println("hello")). However, I believe you actually meant to write "Serial Monitor" instead of "Serial".
The finding I reported in my previous reply:
was from running the sketch on the board after uploading it via Arduino IDE.
I tried running the sketch as part of an Arduino App Lab App and sure enough I am able to reproduce the fault you reported.
I produced a minimal sketch that blinks the LEDs to indicate whether the program is running:
#include <Arduino_RouterBridge.h>
#include <LSM6DSOXSensor.h>
LSM6DSOXSensor imu(&Wire1, LSM6DSOX_I2C_ADD_L);
void setup() {
pinMode(LED3_R, OUTPUT);
digitalWrite(LED3_R, HIGH);
pinMode(LED3_G, OUTPUT);
digitalWrite(LED3_G, HIGH);
pinMode(LED3_B, OUTPUT);
digitalWrite(LED3_B, HIGH);
// Red LED blink indicates whether sketch started successfully.
for (byte counter = 0; counter < 20; counter++) {
digitalWrite(LED3_R, LOW);
delay(100);
digitalWrite(LED3_R, HIGH);
delay(100);
}
Monitor.begin();
// Green LED blink indicates whether sketch continues to run after `Monitor.begin` call.
for (byte counter = 0; counter < 20; counter++) {
digitalWrite(LED3_G, LOW);
delay(100);
digitalWrite(LED3_G, HIGH);
delay(100);
}
Wire1.begin();
imu.begin();
}
void loop() {
// Blue LED blink indicates whether sketch continues to run after `imu.begin` call.
digitalWrite(LED3_B, LOW);
delay(100);
digitalWrite(LED3_B, HIGH);
delay(100);
}
I found that the sketch hangs under the following conditions:
a call to Monitor.begin() is present
a call to imu.begin() is present
So this left the mystery of why there is a different behavior when we upload the sketch using Arduino IDE (or even Arduino CLI from the UNO Q's own Linux machine). I found the important difference is that I was using the default board configuration in Arduino IDE, but Arduino App Lab (or to be more precise, its helper tool Arduino App CLI) uses a different configuration, which is achieved in Arduino IDE by selecting the Tools > Flash mode > RAM "custom board option" from the menus:
If I use that Tools > Flash mode > RAM in Arduino IDE, then I also experience the fault when the sketch was uploaded using Arduino IDE.