5 years, 3 months ago.

UART Communication Nucleo F072

Hi, i want to send all 2 seconds a command over uart. The answer I want to convert in an analog voltage. At the moment I just want to send the command and show the answer on the pc.

Uart communication

#include "mbed.h"
#define size 512

Ticker write_ticker;

Serial pc(USBTX,USBRX,9600); // UART to PC
Serial easerial(A0, A1,115200);  //Uart to device

char rxBuff[size];//array to store
unsigned int bufferWritingIndex = 0;//Writing Pointer
unsigned int bufferReadingIndex = 0;//Reading Pointer

 
void RxInterrupt(void);
void readPc(void);
void write_EA(void);
 
int main(void) 
{
    // Set setting for UART
    easerial.format(8,Serial::None,1);
    pc.format(8,Serial::None,1);
    
    easerial.attach(&RxInterrupt, Serial::RxIrq);
    wait(1);  // 1000 millisecond
    write_ticker.attach(&write_EA,1); // Write all second
    //easerial.printf("moti \r");    // Send command
    while(1) 
    {
        readPc();          
    }
}
 
void RxInterrupt(void)
{
    if(easerial.readable())
    {
        rxBuff[bufferWritingIndex++]=easerial.getc();
        if(bufferWritingIndex>=size)
        bufferWritingIndex=0;    
    }
    
}
  
void readPc(void)
{
    char rxByte;
    while(bufferReadingIndex != bufferWritingIndex)
    {
        rxByte = rxBuff[bufferReadingIndex++];
        pc.putc(rxByte);                // Write answer of device to pc 
        if(bufferReadingIndex>=size)
         bufferWritingIndex=0;
    }
}

void write_EA() {
      easerial.printf("moti \r");    // Send command
}  

This answer i get at the pc, line 1,2,3 are right and the fourth line is wrong:

include the mbed library with this snippet

<\0><\0>moti <\r><\n>
+00000<\r><\n>
Ready.<\r><\n>
m????m????m????m????

Why I don’t get every two seconds a response of the device? Why are most symbols of the last line wrong?

1 Answer

5 years, 3 months ago.

Hi Ireno,

The printf() function shouldn't be put in ISR, please refer to Ticker documentation.

https://os.mbed.com/docs/mbed-os/v5.11/apis/ticker.html

Quote:

No blocking code in ISR: avoid any call to wait, infinite while loop or blocking calls in general.

No printf, malloc or new in ISR: avoid any call to bulky library functions. In particular, certain library functions (such as printf, malloc and new) are not re-entrant, and their behavior could be corrupted when called from an ISR.

While an event is attached to a Ticker, deep sleep is blocked to maintain accurate timing. If you don't need microsecond precision, consider using the LowPowerTicker class instead because that does not block deep sleep mode.

That would cause unexpected behavior.

Desmond, team Mbed

A simple fix:

volatile bool write_Now = false;

// in main()
....
    while(1) 
    {
        readPc(); 
        if (write_Now) {
          write_Now = false;
          easerial.printf("moti \r");
        }
    }
}

void write_EA() {
    write_Now  = true;
}  

This won't be exactly 1 second depending on the amount of serial data readPc() has to deal with but it should be fairly close.

posted by Andy A 28 Jan 2019