0

I have an Arduino board with a sensor, an OLED screen and an XBee module. I've setup the timer interrupts in timer1 to sample the sensor every one second. I've done the following:

  • tried to update the OLED screen with the reading and it works.
  • tried sending the reading from inside loop over XBee and it works.
  • tried doing both of the above and the Arduino seems to shut down after a bit.
  • tried sending the reading from inside the timer interrupt handler and it doesn't work.

Are there limitations on what interrupt handlers can do that I'm not aware of? (Other than using time delays)

Source code

#include <XBee.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

XBee xbee = XBee();
ZBRxResponse response = ZBRxResponse();
ZBTxRequest sensorml_level_0_zbTx = ZBTxRequest(addr64, sensorml_payload_level_0,sizeof(sensorml_payload_level_0));
ZBTxRequest keepalive_level_0_zbTx = ZBTxRequest(addr64, keepalive_payload_level_0,sizeof(keepalive_payload_level_0));

union u_tag {
   uint8_t b[4];
   float fval;
} 
u;

void setup() {
   display.begin(SSD1306_SWITCHCAPVCC);
   Serial.begin(9600);
   xbee.setSerial(Serial);
   noInterrupts();
   TCCR1A = 0;
   TCCR1B = 0;
   TCNT1  = 0;
   OCR1A = 62500;
   TCCR1B |= (1 << WGM12);
   TCCR1B |= (1 << CS12);
   TCCR1B |= (1 << CS10);
   TIMSK1 |= (1 << OCIE1A);
   interrupts();
}

ISR(TIMER1_COMPA_vect){
   reading =  analogRead(SENSORPIN);
   reading = (1023 / reading)  - 1;
   reading = SERIESRESISTOR / reading;
   reading = -0.15784 * reading + 305.17;
   sendObservation(reading,00);
}

void sendObservation(float value, int id){
   char idBuffer[] = "00";
   sprintf(idBuffer,"%02d",id);
   uint8_t frame[] = {'0','1','|','0','0','#','0','0','0','0'};
   frame[3] = idBuffer[0];
   frame[4] = idBuffer[1];
   u.fval = value;
   for (int i=6;i<10;i++){
      frame[i]=u.b[i-6];
   }
   ZBTxRequest request = ZBTxRequest(addr64, frame, sizeof(frame));
   xbee.send(request);
}

I skipped most variable declarations to keep the code short.

  • Just so you know, cross posting is not allowed. – The Guy with The Hat Nov 7 '14 at 14:02
  • Should I remove it then? Why is it not? – Moises Jimenez Nov 7 '14 at 14:07
  • meta.stackexchange.com/a/64069/238586. The Stack Overflow one should be closed soon, so don't remove this one. – The Guy with The Hat Nov 7 '14 at 14:12
  • You say the arduino shuts down after a bit; How long is that? does anything get through before it stops responding? also, what is happening in loop during all this? – BrettAM Nov 7 '14 at 18:31
  • @BrettM I can't say for sure how long it takes. I will be able to on monday though. So I'll keep you posted. – Moises Jimenez Nov 8 '14 at 20:45
1

I suspect send() is blocking.

XBee::send() calls _serial->flush() (see code). Serial.write() buffers data to be written, sets transmitting = true, clears TXC0 and enables the USART data register empty (DRE) interrupt. Bytes will be sent out when the DRE interrupt triggers. However, since you are currently in interrupt context, this will not happen until your ISR returns. flush() spins until TXC0 is set, but since the DRE interrupt never triggers, it spins infinitely. I am basing this on this code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.