8 years, 9 months ago.

the program stops responding after 154 loops (run in NUCLEO STM32F411RET6)

My source :

  1. include "mbed.h"
  2. include "Clock.h" Programme testé sur la carte NUCLEO STM32F411RET6 -------- Hyperterminal configuration 9600 bauds, 8-bit data, no parity --------

Serial pc(SERIAL_TX, SERIAL_RX);

DigitalOut myled(LED1); DigitalOut stateLed(LED1);

int i = 1;

void init_serial_port() { Serial port configuration : 115200 baud, 8-bit data, no parity, stop bit pc.baud(115200); Serial port configuration (valeurs par defaut) : 9600 baud, 8-bit data, no parity, stop bit pc.baud(9600); pc.format(8, SerialBase::None, 1); pc.printf("Run little program !!\n"); }

Clock rtc; Create Clock instance (set to 00:00:00 January 1, 1970)

Create some alarm times time_t alarm1 = Clock::asTime(2015, 3, 24, 11, 36, 15); year, month, day of month, hour, minute, second time_t alarm2 = Clock::asTime(2015, 3, 24, 11, 37, 30); year, month, day of month, hour, minute, second

Create flags to support performing time consuming tasks in main() (in case you have such tasks) bool minute_tick_flag = false;

/**

  • @brief Clock tick event handler (called once a second)
  • @note Make sure that it takes less than 1 second to execute
  • this function. Otherwise the rtc will fall behind!
  • One technique is to set some flags here and
  • then test them in the while loop of main().
  • See minute_tick_flag.
  • @param
  • @retval
  • / void onRtcTick(void) { pc.printf("==================================================\r\n"); pc.printf("Nombres de boucles effectuer %d\n", i++); stateLed = !stateLed; time_t time = time(NULL); you can call C time function if you like time_t time = rtc.time(); or rtc equivalent pc.printf("Time as seconds since January 1, 1970 = %d\r\n", time); pc.printf("Time as a basic string = %s\r\n", ctime(&time));

You can use also custom format. char buffer[32]; strftime(buffer, 32, "%I:%M %p", localtime(&time)); pc.printf("Time as a custom formatted string = %s\r\n", buffer); Or design your own: pc.printf("Date: %.4d-%.2d-%.2d\r\n", rtc.year(), rtc.mon(), rtc.mday()); pc.printf("Time: %.2d:%.2d:%.2d\r\n", rtc.hour(), rtc.min(), rtc.sec());

But if it takes too much time (more than 1s) to execute this Interrupt Service Routine then the RTC will fall behind! That's why we shall keep this routine as short as possible. For time consuming tasks we better set flags here and after testing them in the main() perform the task there. For an example have a look at the minute_tick_flag.

Execute periodical tasks if(rtc.sec() % 10 == 0) { pc.printf("\r\n Called each 10 seconds\r\n\r\n"); }

if(rtc.sec() == 0) { pc.printf("\r\n Called each minute.\r\n\r\n");

if(rtc.min() % 5 == 0) pc.printf("\r\n Called each 5 minutes\r\n");

if(rtc.min() == 0) pc.printf("\r\n Called each hour\r\n");

if(rtc.hour() == 0) pc.printf("\r\n Called at midnight\r\n");

minute_tick_flag = true; set the flag here (to be tested and reset in main()) }

Trigger alarms if(rtc.time() == alarm1) { pc.printf("\r\n Alarm1 triggered!\r\n\r\n"); }

if(rtc.time() == alarm2) { pc.printf("\r\n Alarm2 triggered!\r\n\r\n"); } }

int main() { init_serial_port();

pc.printf("Hello World !\n");

rtc.attach(onRtcTick); attach a handler function to the rtc tick event

Set time. For instance 2015, March, 24th, 11 hours, 35 minutes, 45 seconds rtc.set(2015, 3, 24, 11, 35, 45); year, month (1 stands for Jan etc.), day of month, hour, minute, second

while(1) { if(minute_tick_flag == true) { minute_tick_flag = false; clear the flag for next use Perform time consuming tasks at defined times! pc.printf("Performing some time consuming tasks in the main() ...\r\n\r\n"); ... } } }

Question relating to:

Demo for the Clock library (real time clock driven by a Ticker). clock, real time clock, RTC, Ticker

Hi Olivier,

I’m glad that you are interested in my ‘Clock’ library and I’m ready to help you to make the modified ‘Hello_Clock’ example run on NUCLEO-F411RE. Unfortunately the attached source code is very difficult to read. I’m not even able to compile it for my NUCLEO-F103RB because the comments are not separated properly. Could you please either attach your source formatted as code (see the mbed ‘Editing Hints’ for more details how to do it) or send an e-mail to hudakz@inbox.com with your code attached as text file?

Thanks,

Zoltan

posted by Zoltan Hudak 26 Jul 2015

1 Answer

8 years, 9 months ago.

Hi Olivier,

I’ve successfully formatted and compiled the code but I’m not able to reproduce the reported error on my NUCLEO-F103RB. The application is running well without any errors for more than a half an hour now. I have used the Clock library also for my home automation room thermostats and those are running already several months with no problems. Have you tried to run it on NUCLEO-F411RE more times? Did the error occur always in loop #154? What I can suggest is to keep the interrupt service routine as short as possible. For example like below:

Modified Hello_Clock

#include "mbed.h"
#include "Clock.h"

//Programme testé sur la carte NUCLEO STM32F411RET6 --------  Hyperterminal configuration  9600 bauds, 8-bit data, no parity --------
Serial      pc(SERIAL_TX, SERIAL_RX);

//DigitalOut  myLed(LED1);
DigitalOut  stateLed(LED1);

int         i = 1;

/**
 * @brief
 * @note
 * @param
 * @retval
 */
void init_serial_port(void) {

    //Serial port configuration : 115200 baud, 8-bit data, no parity, stop bit

    pc.baud(115200);

    //Serial port configuration (valeurs par defaut) : 9600 baud, 8-bit data, no parity, stop bit
    pc.baud(9600);
    pc.format(8, SerialBase::None, 1);
    pc.printf("Run little program !!\n");
}

Clock           rtc;    //Create Clock instance (set to 00:00:00 January 1, 1970)

//Create some alarm times
time_t          alarm1 = Clock::asTime(2015, 3, 24, 11, 36, 15);    //year, month, day of month, hour, minute, second
time_t          alarm2 = Clock::asTime(2015, 3, 24, 11, 37, 30);    //year, month, day of month, hour, minute, second

// Create flags to support performing time consuming tasks in main() (in case you have such tasks)
volatile bool   second_tick_flag = false;
volatile bool   minute_tick_flag = false;

/**
 * @brief   Clock tick event handler (called once a second)
 * @note    Make sure that it takes less than 1 second to execute
 *          this function. Otherwise the rtc will fall behind!
 *          One technique is to set some flags here and
 *          then test them in the while loop of main().
 *          See minute_tick_flag.
 * @param
 * @retval
 */
void onRtcTick(void) {
    second_tick_flag = true;
}

/**
 * @brief
 * @note
 * @param
 * @retval
 */
int main(void) {
    init_serial_port();

    pc.printf("Hello World !\n");

    rtc.attach(onRtcTick);  //attach a handler function to the rtc tick event

    //Set time. For instance 2015, March, 24th, 11 hours, 35 minutes, 45 seconds
    rtc.set(2015, 3, 24, 11, 35, 45);       //year, month (1 stands for Jan etc.), day of month, hour, minute, second
    while(1) {
        if(second_tick_flag == true) {
            second_tick_flag = false;       //clear the flag for next use
            pc.printf("==================================================\r\n");
            pc.printf("Nombres de boucles effectuer %d\r\n", i++);
            stateLed = !stateLed;

            //time_t  time = time(NULL);      //you can call C time function if you like
            time_t  time = rtc.time();      //or rtc equivalent

            pc.printf("Time as seconds since January 1, 1970 = %d\r\n", time);
            pc.printf("Time as a basic string = %s\r\n", ctime(&time));

            //You can use also custom format.
            char    buffer[32];
            strftime(buffer, 32, "%I:%M %p", localtime(&time));
            pc.printf("Time as a custom formatted string = %s\r\n", buffer);

            //Or design your own:
            pc.printf("Date: %.4d-%.2d-%.2d\r\n", rtc.year(), rtc.mon(), rtc.mday());
            pc.printf("Time: %.2d:%.2d:%.2d\r\n", rtc.hour(), rtc.min(), rtc.sec());

            //But if it takes too much time (more than 1s) to execute this Interrupt Service Routine  then the RTC will fall behind!
            //That's why we shall keep this routine as short as possible.
            //For time consuming tasks we better set flags here and after testing them in the main()  perform the task there.
            //For an example have a look at the minute_tick_flag.
            //Execute periodical tasks
            if(rtc.sec() % 10 == 0) {
                pc.printf("\r\n Called each 10 seconds\r\n\r\n");
            }

            if(rtc.sec() == 0) {
                pc.printf("\r\n Called each minute.\r\n\r\n");

                if(rtc.min() % 5 == 0)
                    pc.printf("\r\n Called each 5 minutes\r\n");

                if(rtc.min() == 0)
                    pc.printf("\r\n Called each hour\r\n");

                if(rtc.hour() == 0)
                    pc.printf("\r\n Called at midnight\r\n");

                minute_tick_flag = true;    //set the flag here (to be tested and reset in main()) }

                //Trigger alarms
                if(rtc.time() == alarm1) {
                    pc.printf("\r\n Alarm1 triggered!\r\n\r\n");
                }

                if(rtc.time() == alarm2) {
                    pc.printf("\r\n Alarm2 triggered!\r\n\r\n");
                }
            }

            if(minute_tick_flag == true) {
                minute_tick_flag = false;   //clear the flag for next use

                //Perform time consuming tasks at defined times!
                pc.printf("Performing some time consuming tasks in the main() ...\r\n\r\n");

                //...
            }
        }
    }
}

Please let me know how it works.

Thanks,

Zoltan

Accepted Answer

thank you for your very quick response, I will test again in order to observe whether the crash still takes the same time ...

anyway your code on the Web Library (ENC28J60: https://developer.mbed.org/users/hudakz/code/WebSwitch_ENC28J60/) will allow me to come to the result corresponding to a project I short on MikroElektronika:http://www.libstock.com/projects/view/638/web-server-designed-for-pic18f4620-enc28j60-and-ds18s20-avec-graphique-des-temperatures. What I miss and the measurement of time with simultaneous temperature (in OneWire) and the current and voltage measurement for the French Electricity consumption with graphical display of a web ... and the ability to send emails (the MikroElektronika library not allow) or less to choose to go to the free library and visible code. I still have lots of work ahead ...

posted by FOURNET Olivier 26 Jul 2015