6 years, 7 months ago.

Periodically Make println

Hi There! I'm trying to send data with 40 frames per second over UART, making this via Interrupt is not possible, since it has to take place at that point of the code. The Problem is: it is sending data without delay, saying in each while loop. Why?

main.cpp

/* Includes */
#include "mbed.h"
#include <Timing.h>

Serial pc(USBTX, USBRX);

/* Simple main function */
int main() {
  pc.baud(115200);
 
  volatile uint32_t lastsend = micros();
  uint32_t a = 0;
    while(1) {

     a++; //incrementing a in every loop, then sending value of a 40 times per second

      if(lastsend - micros() > 25000)
      {
        lastsend = micros();

        pc.printf("%f",a);
        pc.printf("\r\n");
      }
  }
}

Timing.cpp

#include "mbed.h"
#include "Timing.h"

volatile uint32_t _millis;
volatile uint32_t _micros;

void startTiming(void)
{
        SysTick_Config (SystemCoreClock / 1000);
        _millis = 0;//reset _millis
}

uint32_t micros(void)
{

        _micros = _millis*1000 + 1000 - SysTick->VAL/72;

        // = _millis*1000+(SystemCoreClock/1000-SysTick->VAL)/72;
        return _micros;

}

uint32_t millis(void)
{
        return _millis;
}

void delay_ms(uint32_t nTime)
{
        uint32_t curTime = _millis;
        while((nTime-(_millis-curTime)) > 0);
}

void delay_us(uint32_t nTime)
{
        uint32_t curTime = _micros;
        while((nTime-(_micros-curTime)) > 0);
}

extern "C" void SysTick_Handler(void) {
    _millis++;
}

Any suggestions?

1 Answer

6 years, 7 months ago.

Hello Trembel,

A simple option could be to use wait:

#include "mbed.h"

Serial  pc(USBTX, USBRX);

int main()
{
    uint32_t  a = 0;

    pc.baud(115200);

    while (1)
    {
        a++;    //incrementing a in every loop, then sending value of a 40 times per second
        for (int i = 0; i < 40; i++)
        {
            wait_us(25000);
            pc.printf("%ld\r\n", a);
        }
    }
}

Disadvantage of wait is that it's blocking the while loop. That can be avoided by using a Timer. Below is a solution very similar to what you have tested.

#include "mbed.h"

Serial          pc(USBTX, USBRX);
Timer           timer;
uint32_t        a = 0;
int             i = 0;

int main()
{
    pc.baud(115200);
    timer.start();

    while (1)
    {
        if (timer.read_us() > 25000)
        {
            timer.reset();
            pc.printf("%ld\r\n", a);
            if (i++ == 39)
            {
                i = 0;
                a++;
            }
        }
    }
}

But more accurate results can be achieved by using a Ticker. For example as below:

#include "mbed.h"

Serial          pc(USBTX, USBRX);
Ticker          ticker;
uint32_t        a = 0;
volatile bool   tick = false;
volatile int    i = 0;

void onTick()
{
    tick = true;
    i++;
}

int main()
{
    pc.baud(115200);
    ticker.attach_us(onTick, 25000);

    while (1)
    {
        if (tick)
        {
            tick = false;
            pc.printf("%ld\r\n", a);
            if (i == 39)
            {
                i = 0;
                a++;
            }
        }
    }
}

Accepted Answer