chipKIT® Development Platform

Inspired by Arduino™

Crossplatform timer api for ChipKIT and Arduino

Created Wed, 23 Aug 2017 21:33:48 +0000 by benderamp


benderamp

Wed, 23 Aug 2017 21:33:48 +0000

Hello, this is my another very simple lib to access timer interrupts API on ChipKIT/PIC32MX and Arduino/AVR without dealing with platform-specific headers and registers. https://github.com/sadr0b0t/arduino-timer-api

to install

git clone https://github.com/1i7/arduino-timer-api.git
cp -r ./arduino-timer-api/timer-api ~/Arduino/libraries

restart IDE, examples would appear in File/Examples/timer-api menu

Basic example:

#include"timer-api.h"

void setup() {
    Serial.begin(9600);

    // freq 5Hz == 5 ops per second <=>
    // timer period = 200ms
    timer_init_ISR_5Hz(TIMER_DEFAULT);

    // freq 50Hz == 50 ops per second <=>
    // timer period = 20мс
    //timer_init_ISR_50Hz(TIMER_DEFAULT);
    
    pinMode(13, OUTPUT);
}

void loop() {
    Serial.println("Hello from loop!");
    delay(5000);

    // any code here: blocking or non-blocking
}

void timer_handle_interrupts(int timer) {
    static long prev_time = micros();

    long _time = micros();
    long _period = _time - prev_time;
    prev_time = _time;
    
    static int count = 5;

    // print message every 5th interrupt call
    // (with interrupt freq 5Hz - print once per second)
    if(count == 0) {
        Serial.print("goodbye from timer: ");
        Serial.println(_period, DEC);
        
        digitalWrite(13, !digitalRead(13));
        
        count = 5;
    }
    count--;
}

Procedure timer_handle_interrupts would be called with chosen frequency no matter what the main loop contains and doing, so this is a kind of specific multitasking in the same sketch.

Most common frequencies are available with corresponding calls in a cross-platform way:

void timer_init_ISR_100KHz(int timer);
void timer_init_ISR_50KHz(int timer);
void timer_init_ISR_20KHz(int timer);
void timer_init_ISR_10KHz(int timer);
void timer_init_ISR_5KHz(int timer);
void timer_init_ISR_2KHz(int timer);
void timer_init_ISR_1KHz(int timer);
void timer_init_ISR_100Hz(int timer);
void timer_init_ISR_50Hz(int timer);
void timer_init_ISR_20Hz(int timer);
void timer_init_ISR_10Hz(int timer);
void timer_init_ISR_5Hz(int timer);

You can also provide your own frequency setting by setting custom timer, prescaler and timer compare adjuster value

#include"timer-api.h"

void setup() {
    Serial.begin(9600);

    // http://www.robotshop.com/letsmakerobots/arduino-101-timers-and-interrupts
    // 1. CPU frequency 16Mhz for Arduino
    // 2. maximum timer counter value (256 for 8bit, 65536 for 16bit timer)
    // 3. Divide CPU frequency through the choosen prescaler (16000000 / 256 = 62500)
    // 4. Divide result through the desired frequency (62500 / 2Hz = 31250)
    // 5. Verify the result against the maximum timer counter value (31250 < 65536 success) if fail, choose bigger prescaler.
    
    // Arduino 16МГц
    // Настроим и запустим таймер с периодом 20 миллисекунд (50 срабатываний в секунду == 50Гц):
    // prescaler=1:8, adjustment=40000:
    // 16000000/8/50=40000 (50Hz - срабатывает 50 раз в секунду, т.е. каждые 20мс)
    // Обработчик прерывания от таймера - функция timer_handle_interrupts 
    // (с заданными настройками будет вызываться каждые 20мс).
    //timer_init_ISR(TIMER_DEFAULT, TIMER_PRESCALER_1_8, 40000-1);
    
    // ChipKIT PIC32MX 80МГц
    // Настроим и запустим таймер с периодом 20 миллисекунд (50 срабатываний в секунду == 50Гц):
    // prescaler=1:64, adjustment=25000:
    // 80000000/64/25000=50 (срабатывает 50 раз в секунду, т.е. каждые 20мс)
    // Обработчик прерывания от таймера - функция timer_handle_interrupts 
    // (с заданными настройками будет вызываться каждые 20мс).
    timer_init_ISR(TIMER_DEFAULT, TIMER_PRESCALER_1_64, 25000-1);
    
    pinMode(13, OUTPUT);
}

void loop() {
    Serial.println("Hello from loop!");
    delay(5000);

    // any code here: blocking or non-blicking
}


/**
 * Процедура, вызываемая прерыванием по событию таймера с заданным периодом.
 */
void timer_handle_interrupts(int timer) {
    static long prev_time = micros();

    long _time = micros();
    long _period = _time - prev_time;
    prev_time = _time;

    static int count = 50;

    // печатаем статус каждые 50 вызовов прерывания,
    // на частоте 50Гц - 1 раз в секунду
    if(count == 0) {
        Serial.print("goodbye from timer: ");
        Serial.println(_period, DEC);
        
        digitalWrite(13, !digitalRead(13));
        
        count = 50;
    }
    count--;
}

But note, that this might result in losing cross-platformity.