Teensy 2.0 with Serial Communication, I2C and another interrupt pin? - Page 1
Forum section: electronics / general

author: meba
author_rank: Contributor
timestamp: January 17, 2021, 02:03:34 pm
content: Hi,I am currently trying to use a Teensy 2.0 with Serial Communication, I2C and at least one more interrupt pin. Unfortunately SCL, SDA and TX,RX are already occupying all the 4 interrupt pins of the Teensy 2.0. But I need one more to read the hall effect sensor of a fan. Using a different microcontroller isn't really an option, but I am sure there must be a solution for this problem, right?There seems to be another interrupt pin (INT6) on Pin24 / PE6, but it does not seem to be working. I am not getting an interrupt when I connect the input there.

author: ledtester
author_rank: Super Contributor
timestamp: January 17, 2021, 02:30:30 pm
content: Can you bit-bang your I2C? Then you can move SCL and SDA to other pins.Might be overkill, but here's a general purpose bitbanging I2C library:https://github.com/bitbank2/BitBang_I2CAnother possibly helpful resource:https://calcium3000.wordpress.com/2016/08/19/i2c-bit-banging-tutorial-part-i/

author: meba
author_rank: Contributor
timestamp: January 17, 2021, 02:38:29 pm
content: Thanks for the response! That sounds promising, I will have a look at it.

author: newbrain
author_rank: Super Contributor
timestamp: January 17, 2021, 02:41:49 pm
content: I would not bitbang the I2C, if at all possible.The ATmega 32u4 has got a Pin Change Interrupt that can be triggered by any of port B pins.If one is available, you are all set.If you are using the Arduino framework, I don't think it's supported by default but you can probably find examples or libraries.

author: meba
author_rank: Contributor
timestamp: January 17, 2021, 02:53:11 pm
content: I just found another solution. While INT6 is not working with attachInterrupt() you can access it diretly via the register as a fifth interrupt pin. I don't really understand how to work with registers yet, but it only requires very little code:setup:EICRB |= (1<<ISC60)|(1<<ISC61);EIMSK |= (1<<INT6);interrupt function:ISR(INT6_vect) {// interrupt code goes here}source:https://propaneandelectrons.com/blog/int6-on-arduino-leonardo-atmega32u4This way I don't have to mess with I2C or the serial communication. Just use the internal pin PE6 of the Teensy.

author: Nominal Animal
author_rank: Super Contributor
timestamp: January 17, 2021, 06:30:57 pm
content: In Arduino, ATmega32u4 INT6 is interrupt number 4; seecores/arduino/WInterrupts.c(noting that__AVR_ATmega32U4__is defined for Teensy 2.0), which uses (for interrupt 4)EICRB = (EICRB & ~((1<<ISC60) | (1<<ISC61))) | (mode << ISC60);EIMSK |= (1<<INT6);In other words, if you want to be Arduino-y,Code:void setup(void) {pinMode(PIN_E6, INPUT); // PIN_E6 == 24, as shown in the reverse side of the Teensy pinout cardattachInterrupt(EXTERNAL_INT_4, hallSensorInterrupt, RISING); // Or FALLING or CHANGE}void hallSensorInterrupt(void) {// Pin PE6 changed from LOW to HIGHstatic unsigned long last_us;unsigned long curr_us, elapsed_us;curr_us = micros();us = curr_us - last_us;last_us = curr_us;// us is the microseconds (1,000,000ths of a second)// between current and previous Hall sensor rising edges}Yet another option is to use theTeensyduino FreqCount Library, which on Teensy 2.0 uses pin 11 (PD6, the one with the LED). It counts the number of pulses (without blocking, i.e. it does not "stop" your Arduino sketch execution, it does the work in the background while your program runs other code). If you use GateInterval of 150 (150ms), you have a new measurement available about seven times per second. Divide the result by 9 to get RPMs.(Because 1RPM= 1/60Hz, and GateInterval is in milliseconds (thousandths of a second), for any integer GateInterval, the divisor (to convert to RPMs) is (60·GateInterval/1000 = 0.06·GateInterval). For accurate readings, you want both GateInterval and the divisor to be exact integers.)