Teensy 3.0 timers

Status
Not open for further replies.

lauris

New member
Hi,

I'm trying to run/port arduino sketch on Teensy 3.0. The sketch is located here

https://neseweb.de/wp-content/plugins/download-monitor/download.php?id=1

Here's the failing code snippet:

Code:
void TimerInit() {
    cli();
    TCCR0A = 0;// set entire TCCR0A register to 0
    TCCR0B = 0;// same for TCCR0B
    TCNT0  = 0;//initialize counter value to 0
    OCR0A  = 99;//= (16*10^6) / (2500*64) - 1 (must be <256)
    TCCR0A |= (1 << WGM01);// turn on CTC mode
    TCCR0B |= (1 << CS11) | (1 << CS10);
    TIMSK0 |= (1 << OCIE0A);// enable timer compare interrupt
    sei();
}

Here are the errors:

Code:
Receive_433.ino: In function 'void TimerInit()':
Receive_433:75: error: 'TCCR0A' was not declared in this scope
Receive_433:76: error: 'TCCR0B' was not declared in this scope
Receive_433:77: error: 'TCNT0' was not declared in this scope
Receive_433:78: error: 'OCR0A' was not declared in this scope
Receive_433:79: error: 'WGM01' was not declared in this scope
Receive_433:80: error: 'CS11' was not declared in this scope
Receive_433:80: error: 'CS10' was not declared in this scope
Receive_433:81: error: 'TIMSK0' was not declared in this scope
Receive_433:81: error: 'OCIE0A' was not declared in this scope
Receive_433.ino: At global scope:
Receive_433:86: error: expected constructor, destructor, or type conversion before '(' token


Do I need to import something ? I'm seeing TCCR0A register used in core_pins.h file, but importing it didn't help...

Thanks,
Lauris
 
That Arduino program's code is for an AVR microrprocessor. At a glance, it is using a timer to create a periodic interrupt. In that interrupt service routine (ISR), there is a lot of code to "bit-bang" serial input from a low cost on-off-keying (OOK) 433MHz receiver, and capture data transmitted by a different device.
The ISR is "sampling" the receiver's bit stream for 1's and 0's, and probably detecting a data frame preamble that's longer than any bit. These OOK radios are hard to work with due to noise that causes the data bit to be wild after transmission ceases. During the transmission, the usual way to deal with OOK is in hardware, make an op-amp with an integrator to keep the average voltage on the bit stream. Then 1's and 0's are discernable. When data stops, the noise causes the integrator to output no-data bits (mostly). The ISR in the code must do something similar, in code.

So on the Teensy 3 is a 32 bit ARM processor rather than an Atmel AVR as the code was written for.
I think you're going to have to toss out the AVR timer init and ISR and replace it with a different sampling strategy.
Seems like an interrupt based scheme is not needed.
I couldn't see the sampling interval in the code's comments, and the code doesn't say what AVR is used, nor the CPU freq., nor the intended sample frequency.
But with a bit of study, the main logic should be portable.
Maybe someone here knows better how to emulate the AVR's timer/ISR.
 
Teensy 3 has IntervalTimer, which is the easiest way to make this code work.

First, replace the init code using IntervalTimer. It's very easy, since all you do is give it the function to run and the interval in microseconds. There's no need to fiddle with hardware registers like normal Arduino.

Code:
// Initializes the timer. The configured interval determines
// the scan interval of the wireless data port.

IntervalTimer myTimer;

void TimerInit() {
    myTimer.begin(TIMER0_COMPA_vect, 400);  // run every 400 us
}

Then just change the interrupt to an ordinary function.

Code:
// The interrupt reads one bit of data
void TIMER0_COMPA_vect(void) {
// ISR( TIMER0_COMPA_vect )  // <-- old version
 
Lauris
As you can see, Paul has provided much easier to use library functions. The author of the AVR code had to grunge around at the register level.
 
Minor but time-waster:
Windows 7.. Teensy.exe, error window saying board mismatch (.hex vs. board plugged in), comes up behind the active windows and thus is overlooked, and there is no error display in the Teensy.exe window itself.
 
Thanks stevech and Paul, I'll give it a try.
An option for you is to not use the timer and interrupt.
Perhaps use

delayMicroseconds(400); // 400 or whatever

in a loop.

Note that the Teensy's millisecond timer will interrupt 1000 times a second but it's execution time is quite small, perhaps unimportant unless you are trying for 10 micros seconds' accuracy.
 
Status
Not open for further replies.
Back
Top