Skip to content

Error Handling

luni64 edited this page Jul 18, 2020 · 3 revisions

Things can and will go wrong in programming. E.g. assume that you try to acquire three channels of an FTM1 module which only provides two channels

OneShotTimer t1(FTM1), t2(FTM1), t3(FTM1)

void setup()
{
    t1.begin(callback1);
    t2.begin(callback2);
    t3.begin(callback3);
}
...

This will lead to a runtime error when you try to initialize t3 in the last line. TeensyTimerTool won't crash on it but t3 will never work of course.

Manually Check for Errors

So, it is a good idea to check if the acquisition of a timer didn't produce an error. Here an example showing how this can be done. In case of an error a panic function will be called which simply prints out the error and enters an endless, fast blink loop to signal a problem.

OneShotTimer t1(FTM1), t2(FTM1), t3(FTM1)

void setup()
{
    ...
    errorCode err;
    err = t1.begin(callback1);
    if (err != errorCode::OK)
    {
        panic(err);
    }

    err = t2.begin(callback2);
    if (err != errorCode::OK)
    {
        panic(err);
    }
    ...
}


void panic(errorCode err)  // print out error code, stop everything and do a fast blink
{
    Serial.printf("Error %d\n", err);
    while(1)
    {
        digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
        delay(50);
    }
}
...

All defined error codes can be found in the file 'ErrorHandling/error_codes.h'

Using an Error Handling Callback

Although the example above works perfectly, it is quite tedious to always check things for possible errors. To make error handling more convenient you can attach an error handler function to the library. You first need to initialize it by calling attachErrFunc as shown in the example below. Now, TeensyTimerTool automatically calls the attached error function whenever something goes wrong.

OneShotTimer t1(FTM1), t2(FTM1), t3(FTM1)

void setup()
{
    TeensyTimerTool::attachErrFunc(panic);

    while(!Serial);
    pinMode(LED_BUILTIN, OUTPUT);

    t1.begin(callback1);
    t2.begin(callback2);
    t3.begin(callback3);
}


void panic(errorCode err)  // print out error code, stop everything and do a fast blink
{
    Serial.printf("Error %d\n", err);
    while(1)
    {
        digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
        delay(50);
    }
}
...

Using the Built in Error Handler

TeensyTimerTool provides a standard error handler which prints out the error number and the corresponding error message. The constructor of the error handler expects a Stream reference (e.g. Serial or Serial1...) on which the messages are printed.

  • In case of a warning the information is printed and the error handler returns control to the calling code.

  • In case of an error the error handler prints the message and enters a endless 50ms blink loop on LED_BUILTIN.

WARNING: The constructor of the error handler sets the pin mode of LED_BUILTIN to OUTPUT and blinks on that pin in case of an error. Do not use the standard error handler if you have something connected on pin LED_BUILTIN.

Here a quick example showing how to use the built in standard error handler for printing on Serial.

OneShotTimer t1(FTM1), t2(FTM1), t3(FTM1)

void setup()
{
    TeensyTimerTool::attachErrFunc(ErrorHandler(Serial));

    while(!Serial);
    pinMode(LED_BUILTIN, OUTPUT);

    t1.beginOneShot(callback1);
    t2.beginOneShot(callback2);
    t3.beginOneShot(callback3);
}
...

Output:

Error: 104: Timer module has no free channel