Communicating by serial while maintaining a high fixed looping function frequency

11 Oct 2013

Hi,

I'm working on a project where I would like to send a string x times per second, while still maintaining a stable main loop.

Currently I am running the main loop at 1000Hz, and sending a string at 1Hz by using interrupts:

#define SLOWFREQ 1
#define FASTFREQ 1000
Ticker SlowTick, FastTick;
MODSERIAL pc(USBTX, USBRX, 512); //512B buffer
int SlowTicker, FastTicker;

void SlowTickFunction(){
    SlowTicker=1;
}

void FastTickFunction(){
    FastTicker=1;
}

int main() {
    SlowTick.attach_us(&SlowTickFunction, 1000000/SLOWFREQ);
    FastTick.attach_us(&FastTickFunction, 1000000/FASTFREQ);
    pc.baud(115200);
    
    while(1) {
        if(FastTicker==1){ //running at FASTFREQ Hz
            FastTicker=0
            //doing some tasks
        }
        if(SlowTicker==1){ //running at SLOWFREQ Hz
            SlowTicker=0
            pc.printf("V1: %f, V2: %f, V3: %f, V4: %d V5: %f, \r\n", Var1, Var2, Var3, Var4, Var5); //printing some variables
        }
    }
}

Is this how you would send data to the computer if you just wanted to view it in the terminal? Any tips or clues to do this better\smarter?

Say I later want to compress the data output by only sending the necessary few bits for each variable to a self written application on my computer that interprets it and presents the data to me, would I still use this technique? I've seen people mention that one should only use putc because it's less resource-demanding, but I'm having trouble seeing how this would be implemented.

Lastly, a question regarding the modserial-library. Have I understood it correctly when I am assuming that "fully buffered input/output" means that when I use modserials printf-function it will immediately send it to a buffer, which in turn will send the data when the micro controller has available resources? Because when I use the standard serial library and I send a long string, I notice a "break", which I assume is the micro controller sending the data and "pauses" everything else until the data has been sent, which speed is set by the baud rate. I can't seem to notice this break when using the modserial-library. This would of course be devastating for a project like mine that demands a stable high frequency looping function.

10 Oct 2013

Quote:

Say I later want to compress the data output by only sending the necessary few bits for each variable to a self written application on my computer that interprets it and presents the data to me, would I still use this technique? I've seen people mention that one should only use putc because it's less resource-demanding, but I'm having trouble seeing how this would be implemented.

It depends on your requirements. You can for example send the raw binary data also over serial port. A downside is that errors in the serial connection/program are harder to compensate for. If you send it as characters you can reserve some characters to tell your receiver that a new message is coming for example. If you send it as binary you cannot do that, since each byte can have any value.

Quote:

Lastly, a question regarding the modserial-library. Have I understood it correctly when I am assuming that "fully buffered input/output" means that when I use modserials printf-function it will immediately send it to a buffer, which in turn will send the data when the micro controller has available resources? Because when I use the standard serial library and I send a long string, I notice a "break", which I assume is the micro controller sending the data and "pauses" everything else until the data has been sent, which speed is set by the baud rate. I can't seem to notice this break when using the modserial-library. This would of course be devastating for a project like mine that demands a stable high frequency looping function.

Correct. The default library will keep waiting until all data is put into the serial output buffer. On the LPC1768 this buffer is 16-characters deep. So for short messages they can all be placed into this buffer directly, for longer messages it will wait until there is space again in this buffer, until all characters are sent.

MODSERIAL puts it in its own software buffer. It will also first fill the 16-character hardware buffer, but if it still has characters remaining your program will resume (which is almost directly), and once there is space again in the output buffer it will interrupt your program to place new data there, and afterwards directly continue with your program again.

11 Oct 2013

Alright, thank you very much for your explanation. I was a bit confused about all this but obviously I wasn't that far off. If you or anyone else have any tips or anything regarding the code or how to better send the string, please tell me :)

11 Oct 2013

Tomas,

Variables used for semaphores need to be declared 'volatile' to avoid the possibility of undesired optimization side-effects.

Like this -

volatile int SlowTicker, FastTicker;

If your FastTicker code is small enough (like reading the ADC), you can put into the FastTickFunction() (instead of the main() loop), to avoid most 'jitter' in the action's timing.

16 Oct 2013

I think I understand. I did some research, and if I understood it correctly this is necessary because if the variables are not declared 'volatile', there may be situations where the new value of the variable will not be read?

Thank you!