Report
3 days, 15 hours ago.

Transmit and Receive int array from and to Nucleo f4303re.

Hi im trying to write a code that takes data from pc using QT and receiving side nucleo f4303re will then be able to write it back to the pc serial for error checking. What i have done just is doing some part of the job as sometimes it transmits and receives and sometimes not. My mbed code is;

include the mbed library with this snippet

#include "mbed.h"

DigitalOut myled(LED1);
Serial pc(USBTX, USBRX);

int main() {
  pc.baud(115200);
char buffer[200];
// while (true){
//   char c = pc.getc();
// if(c=='H'){
//   myled = 1;
// }
//  if (c=='B'){
//   myled = 0;
//   wait(0.1);
// }
// }


for(int i=0;i<200;i++){


char c = pc.getc();
buffer[i] = c;
pc.putc(buffer[i]);


}
}

and my qt code function is;

qt code

void arduinoTest::writeArd(long samples[], int size_sample)
{
    char *samples32 = new char [size_sample];
    char *readData = new char [size_sample];


    for (int i =0;i<size_sample;i++){
        samples32[i] = samples[i];

        arduino->write(&samples32[i]);



        arduino->read(readData,size_sample);
        qDebug() << (int)readData[i] << "," ;




    }

I would love to learn an answer for that problem as well. I am currently facing the same issue.

posted by Ayberk Sadic 17 Apr 2019
Comment on this question

1 Answer

2 days, 18 hours ago.

Your current mbed code sends data back the first 200 bytes as they arrive and then stops doing anything until reset.

Is that what you want?

Other than stopping after 200 bytes there isn't any obvious reason why this shouldn't work.

There is one corner case possibility, you'd have to be unlucky to run into it but it is possible: While the port is at the same rate in both directions the PC and mbed are using different clocks so they could each be sending data at very slightly different rates (uarts can normally cope with up to a 5% error). This means that in some situations bytes can arrive faster than you can send them out. If you have the occasional gap in your data then this isn't an issue since that gives the slower side a chance to catch up but it looks like you send everything in one big block, theoretically if you were unlucky with the clock errors 200 bytes without a pause is enough to cause you to get buffer overflows.

There are two possible solutions to this: 1) Your current mbed code runs 1 byte at a time: receive, transmit,receive, transmit. Instead break the link between the two and let the mbed buffer data, a serial receive interrupt puts new data into a buffer, the background loop reads the buffer and outputs it.

2) Have the PC application add a small pause every 50 or so bytes. You may need to time that manually, the PC hardware will be buffering the writes so finding out when exactly it's finished sending everything you've given it can be tricky.

thank you so much. Actually the problem was with qt side. when i changed it it became better but now occasinnaly like in 200 bytes occasionally 3 consecutive bytes are becoming wrong. So im gonna try to do it with buffer. and then try with occasional pauses. I need to transmit these bytes to an external DAC and then play a sound so small pauses may endanger the necessary speed for the application. thanks!

posted by Bora Çelebi 17 Apr 2019

When data is coming from a DAC you shouldn't need to manually add pauses, you will need to send bytes to the DAC at a fixed rate which will be below the maximum rate of the serial port and so there will naturally be pauses. The issue is only because you are trying to drive the serial port at 100% utilization in both directions at the same time, even that wouldn't normally be an issue but you are asking both directions to be at exactly the same rate rather than roughly the same rate.

posted by Andy A 17 Apr 2019

Thank you so much actually with a baudrate of 57600 on both sides it worked. But to output it to the DAC can i just get 2 bytes from the serialport to Nucleo and then send it to a DAC of 16bits? or should i fill an array in nucleo first and then send every element to the DAC ?

posted by Bora Çelebi 17 Apr 2019

I assume that you have a fixed sample rate that you want to output the data from the DAC, if this is audio you need to play if back at the correct rate.

That means you need to pass the data to the DAC at the correct rate.

The way I'd structure this would be to have a circular buffer on the Nucleo that is large enough to hold say 250 ms worth of audio.

The PC sends the first 175 ms of data in one go and then every 100 ms after that it sends data in 100 ms blocks, the nucleo uses the receive interrupt to add the data to the buffer.

Once the buffer on the Nucleo gets to half full you kick off a Ticker interrupt which triggers at the required sample rate and reads a value from the buffer and outputs it to the DAC.

That way the PC can do bulk transfers which is what it's better at and can get its timing wrong by up to 25 ms each way without causing any issues. The nucleo handles the accurate timing but doesn't have to hold all the data at the same time.

Ideally the buffer on the nucleo should be as large as memory allows but larger buffers normally imply more latency if you need to get timing accurate or start the playback quickly.

posted by Andy A 18 Apr 2019

To post an answer, please log in.