I am new in mbedOS.
It seems to me that DigitalOut.read method is wrongly documented (or wrongly implemented). I did not check deeply (e.g. assembly) since I am new in mbed tools.
Documentation for DigitalOut class reads:
“Return the output setting, represented as 0 or 1 (int)”
which can be misleading, since the code really reads the physical value on the pin
(return gpio_read(&gpio);)
Note that the documentation for DigitalIn.read reads differently
“Read the input, represented as 0 or 1 (int)”.
Additionally, note that documentation for DigitalInOut.read (digitalinout.html) reports two non-matching descriptions:
“Read the value of a digital pin when set as an input()
.”
“Return the output setting, represented as 0 or 1 (int)”
Note that I started working with your hello-world example from
mbed-os-example-blinky
Your initial main code is
int main()
{
// Initialise the digital pin LED1 as an output
DigitalOut led1(LED1);
while (true) {
led = !led;
thread_sleep_for(BLINKING_RATE_MS);
}
}
I tried to slightly modify in order to drive three leds and retrieve debug information.
I report here two ways. The first one is not working, i.e. it never toggles led3.
I suspect it is because the first led2.read() call is unable to detect a risen hw value (LED_OFF=1) on the pin.
First way:
int main()
{
// Initialise the digital pin LED1 as an output
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
Serial pc(USBTX, USBRX); //tx, rx
led1 = LED_OFF;
led2 = LED_OFF;
led3 = LED_OFF;
pc.printf("Hello world!\n\r");
pc.printf("Off leds!\n\r");
thread_sleep_for(BLINKING_RATE_MS*3u);
while (true) {
bool t3 = false;
if ((led1 = !led1).read() == LED_OFF)
if ((led2 = !led2).read() == LED_OFF){
led3 = !led3;
t3 = true;
}
pc.printf("Led1 set to hw%d v=%d\n\r",led1.read(),(led1.read() == LED_ON));
pc.printf("Led2 set to hw%d v=%d\n\r",led2.read(),(led2.read() == LED_ON));
pc.printf("Led3 set to hw%d v=%d\n\r",led3.read(),(led3.read() == LED_ON));
if (t3)
pc.printf("Led3 toggled\n\r");
pc.printf("\n\r");
thread_sleep_for(BLINKING_RATE_MS);
}
}
Second way:
int main()
{
// Initialise the digital pin LED1 as an output
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
Serial pc(USBTX, USBRX); //tx, rx
led1 = LED_OFF;
led2 = LED_OFF;
led3 = LED_OFF;
pc.printf("Hello world!\n\r");
pc.printf("Off leds!\n\r");
thread_sleep_for(BLINKING_RATE_MS*3u);
while (true) {
bool led1lv = (led1.read() == LED_ON);
bool led2lv = (led2.read() == LED_ON);
bool led3lv = (led3.read() == LED_ON);
led1 = !led1;
if (!(led1lv = !led1lv)){
led2 = !led2;
if (!(led2lv = !led2lv)){
led3 = !led3;
led3lv = !led3lv;
}
}
pc.printf("Led1 set to %d\n\r",led1lv);
pc.printf("Led2 set to %d\n\r",led2lv);
pc.printf("Led3 set to %d\n\r",led3lv);
pc.printf("\n\r");
thread_sleep_for(BLINKING_RATE_MS);
}
}
The cyclic serial output retrived with TeraTerm from first way is
Hello world!
Off leds!
Led1 set to hw0 v=1
Led2 set to hw1 v=0
Led3 set to hw1 v=0
Led1 set to hw1 v=0
Led2 set to hw0 v=1
Led3 set to hw1 v=0
Led1 set to hw0 v=1
Led2 set to hw0 v=1
Led3 set to hw1 v=0
Led1 set to hw1 v=0
Led2 set to hw1 v=0
Led3 set to hw1 v=0
Led1 set to hw0 v=1
Led2 set to hw1 v=0
Led3 set to hw1 v=0
whereas in second case I obtained as in the following (and all led combinations are issued on the board):
Hello world!
Off leds!
Led1 set to 1
Led2 set to 0
Led3 set to 0
Led1 set to 0
Led2 set to 1
Led3 set to 0
Led1 set to 1
Led2 set to 1
Led3 set to 0
Led1 set to 0
Led2 set to 0
Led3 set to 1
Led1 set to 1
Led2 set to 0
Led3 set to 1
Led1 set to 0
Led2 set to 1
Led3 set to 1
Led1 set to 1
Led2 set to 1
Led3 set to 1
Led1 set to 0
Led2 set to 0
Led3 set to 0
Led1 set to 1
Led2 set to 0
Led3 set to 0
Please, confirm about gpio_read reading the physical pin. If yes, I suggest to modify the documentation, with a ‘warning’ for the usage of the read method. Fix also documentation for DigitalInOut class, with the aim of consistency.