Go Down

Topic: Problems with code (using xbee library and interrupts) (Read 147 times) previous topic - next topic

Quimera

Hello everyone! :D

I have some problems with my code. I'm using xbee modules (Xbee S2C) to get wireless comunication between a computer program and my arduino. I'm using v1 and v0 as variables to on and off a valve connected to the Arduino and then get data from flow sensor. After upload the project, arduino responds great to the command 'v1' (valve opened) and then 'v0' (valve closed), but after that, arduino doesn't respond anymore to the commands  :o , they only work the first time when I upload the sketch or reboot the arduino. I think it could be a problem with interrupts, but I'm not sure. Thanks in advance for your help  :smiley-wink: , I'm using an Arduino UNO. Here's the code:

Code: [Select]


#include <SoftwareSerial.h>
#include <XBee.h>

#define ssRX 10 /* Rx pin for software serial */
#define ssTX 11 /* Tx pin for software serial */

SoftwareSerial xbee_ss(ssRX, ssTX); //RX,TX

volatile int numPulsos;
int pinSensor = 2;    //Flow sensor connected to pin 2
int cuenta = 0;
float factorConversion = 7.5; //
float volumen = 0, caudal_L_m = 0;
const int valvula =  13;
long dt = 0;
long t0 = 0;

uint8_t   bytes[sizeof(float)];
XBee xbee = XBee();

uint8_t payload_1[] = {0, 0};
uint8_t payload_2[] = {0, 0};
char comando[] = {' ',' '};

//Xbee coordinator address
XBeeAddress64 addr64 = XBeeAddress64(0x00000000, 0x00000000);

//Create objects to transmit payload
ZBTxRequest zbTx_1 = ZBTxRequest(addr64, payload_1, sizeof(payload_1));
ZBTxRequest zbTx_2 = ZBTxRequest(addr64, payload_2, sizeof(payload_2));

//Create object to get payload
ZBRxResponse rx = ZBRxResponse();

//Get status of payload
ZBTxStatusResponse txStatus = ZBTxStatusResponse();

//---Function during interrupt---------------
void ContarPulsos () {
  numPulsos++;
}

//---Get pulses frequency--------
int ObtenerFrecuencia() {
  int frecuencia;
  numPulsos = 0;
  interrupts();
  delay(1000);
  noInterrupts();
  frecuencia = numPulsos;
  return frecuencia;
}

void setup() {

  xbee_ss.begin(9600);
  xbee.setSerial(xbee_ss);
  Serial.begin(9600);
  pinMode(pinSensor, INPUT);
  pinMode(valvula, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(pinSensor), ContarPulsos, RISING);
}

void loop () {
 
  xbee.readPacket(); //read command

  if (xbee.getResponse().isAvailable()){
   
    if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
      // got a zb rx packet
      // now fill our zb rx class
      xbee.getResponse().getZBRxResponse(rx);

      for (int i = 0; i < rx.getDataLength(); i++) {
        comando[i] = rx.getData(i);
      }
     
      if(comando[0] == 'v' && comando[1] == '1'){
        digitalWrite(valvula, HIGH);
        t0 = millis();
      }
     
      if(comando[0] == 'v' && comando[1] == '0'){
        digitalWrite(valvula, LOW);
        volumen = 0;
      }
    }
  }
 
  if (comando[0] == 'v' && comando[1] == '1'){
   
    float frecuencia = ObtenerFrecuencia();
    caudal_L_m = frecuencia / factorConversion; // (L/m)
    dt = millis() - t0; //variaciĆ³n de tiempo
    t0 = millis();
   
    volumen += (caudal_L_m / 60) * (dt / 1000); // volumen(L)=caudal(L/s) * time(s)
   
    *(float*)(bytes) = volumen; //convert volumen to bytes before send data
   
    payload_1[0] = bytes[0];
    payload_1[1] = bytes[1];
    xbee.send(zbTx_1); //payload_1
   
    delay(100);
   
    payload_2[0] = bytes[2];
    payload_2[1] = bytes[3];
    xbee.send(zbTx_2); //payload_2
   
    xbee.readPacket();
   
    if (xbee.getResponse().isAvailable()) {
      // got a response!

      if (xbee.getResponse().getApiId() == ZB_TX_STATUS_RESPONSE) {
        xbee.getResponse().getZBTxStatusResponse(txStatus);
 
        // get the delivery status, the fifth byte

        if (txStatus.getDeliveryStatus() == SUCCESS) {
          Serial.println("Succes!");
        } else {
          // the remote XBee did not receive our packet. is it powered on?
          Serial.println("Error!");
        }
      }
    }
  }
}


JaBa

Ok, I have never used the Hardware... but, if you turn off Interrupts and Serial communication requires them... when and how, if ever are they being turned back on?

Quimera

The idea of the program is receive a command via wireless, after receive the command, arduino turn on the valve and send via wireless the flow sensor data. When arduino receives the command to turn off, it turn off the valve an stop to send flow sensor data. At the first time it works well, but if you try to do it again, I mean, try to turn on again the valve via wireless command, it seems like arduino doesn't receive anything.

Robin2

This has got the noInterrupts() all wrong
Code: [Select]
int ObtenerFrecuencia() {
  int frecuencia;
  numPulsos = 0;
  interrupts();
  delay(1000);
  noInterrupts();
  frecuencia = numPulsos;
  return frecuencia;
}


It should be something like this
Code: [Select]
int ObtenerFrecuencia() {
  int frecuencia;
  noInterrupts();
  numPulsos = 0;
  interrupts();
  delay(1000);
  noInterrupts();
  frecuencia = numPulsos;
  interrupts()
  return frecuencia;
}


That way the interrupts are only paused for the shortest time possible.


...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up