Does MySensors require Arduino Timer 2?
-
I've been working on a low cost AC Energy Sensor. It consists of a 1:1 isolation transformer, a current transformer (CT), an Arduino Nano, some resistors and capacitors and a 90-to-260VAC to 5VDC power supply.
In order to make ~70 energy samples per cycle I use Timer 2 to initiate when to sample. One energy sample (one voltage, one current) takes about 0.2mSec. I have been succesful in doing this.
But when I integrate MySensors, my output stops just after the MySensors banner. I suspect that MySensors also uses Timer 2
I treat MySensors as a black box. For me, fiddling with libraries and what not is a deep, dark rabbit hole. I will be concentrating on "isolating" my use of Timer 2 by restoring the registers when I'm done taking samples.
Another alternative is to hang an ESP-1S off the serial port and let it pass the data to Home Assistant via my MQTT broker (or directly using ESPHome). Thus avoiding the use of MySensors. The cost of the nRf24 is almost the same as an ESP-1S
The ESP8266 has only one ADC limited to 1V and I need two. I could use two ESP-01S which cost less than a Nano?
So much for musing, what about IRQ's in MySensors?
OSD
-
I have success!
(oops, that's suppose to be Timer1)
I only sample for 1/60 of a second. What I did was to back up all the timer registered I used and then resorted them after I was done sampling. (As opposed to initializing the registers in setup and then starting the timer when needed.)
Now I have a Nano sampling the data and sending it to a MySensors Gateway on an RPi3B+ which then sends it to an MQTT broker runing on an old laptop. Also running on the laptop is Home Assistant running inside of VirtualBox.
If MySensors does use Timer1, it appears that restoring the registers allows it to be shared.
//------------------------------------------------------ISR ISR(TIMER1_OVF_vect){ // interrupt service routine for overflow TCNT1 = TimerPreloadValue; // must be first line! starts the timer counting again digitalWrite(TRIGGER_START_SAMPLE_PIN,HIGH); samplesVolts[--sample]=analogRead(VOLTS_IN_PIN); // decrement before capturing samplesCurrent[sample]=analogRead(CURRENT_IN_PIN); digitalWrite(TRIGGER_START_SAMPLE_PIN,LOW); if (!sample){ // count down to zero digitalWrite(TRIGGER_START_SAMPLE_PERIOD_PIN,LOW); // indicate that sampling is complete samplingEnd = micros(); TCCR1B &= 248; // turns off timer } } //------------------------------------------------------sampleOneCycle void sampleOneCycle(){ // back up timer registers uint8_t TCNT1_b = TCNT1; uint8_t TCCR1B_b = TCCR1B; uint8_t TCCR1A_b = TCCR1A; uint8_t TIMSK1_b = TIMSK1; // configure timer which starts the sampling noInterrupts(); // disable all interrupts TCCR1A = 0; TCCR1B = 0; TCNT1 = TimerPreloadValue; // preload timer //TCCR1B |= (1 << CS10)|(1 << CS12); // 1024 prescaler TCCR1B &= 248; // turns off timer? TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt ISR // demark sampling sample = NUMBER_OF_SAMPLES; // count down to zero digitalWrite(TRIGGER_START_SAMPLE_PERIOD_PIN,HIGH); samplingStart = micros(); TCNT1 = 65535; // first trigger right away! TCCR1B |= 1; // turns on timer interrupts(); // enable all interrupts // wait for sampling to be complete while(digitalRead(TRIGGER_START_SAMPLE_PERIOD_PIN)){}; samplingEnd = micros(); // restore timer registers TCNT1 = TCNT1_b; TCCR1B = TCCR1B_b; TCCR1A = TCCR1A_b; TIMSK1 = TIMSK1_b; }