2

I created a few Arduino-XBee temperature sensor nodes that send data to another XBee node.js server. I'm running into a few issues trying to write a function to initiate a handshake and receive an identifier number to start sending data (so its scalable rather than hard-coded on each) while the receiver is already communicating with pre-established nodes.

The first issue I'm having is that the Arduino nodes do not seem to start from the beginning of their code when I unplug them and then reapply power. They already think they have their identifier number if another node is running, and I have to push the reset button on them to get them to run their code fresh and establish their own handshake ID. Is there anything I can put in the code or a way that I can easily modify the circuitry to make them actually reset and start fresh when they lose power?

The circuitry I'm using is a basic thermistor voltage-divider, XBee module, and 5V battery pack. Here's what I've got so far for the code on the Arduino side:

#include <SoftwareSerial.h>
#include <math.h>

// Global variables
int AnalogPin = A2; // has much less jumpy readings than A0 (maybe A0 slightly damage from overuse)
float V_source = 4.90; // measured
SoftwareSerial XBee(2,3); // RX, TX
String identifier = "";
int receivedID = 0;

// Calculate thermistor voltage
float Voltage(float RawADC) {
  float meter_calibration = 0; // don't seem to need, matches my multimeter exactly
  float V_therm = (V_source * RawADC) / 1024.0;
  V_therm += meter_calibration;
  return V_therm;
}

// Calculate thermistor resistance
// sometimes a bit off what voltage divider eq says it should be (probably due to input impedance of ADC)
float Thermistor(float V_therm) {
  float resistance_calibration = 25; // possibly small breadboard/wires resistance
  float R_known = 560 + resistance_calibration; // measured (1% tol resistor)
  float R_therm =  ((R_known * V_therm) / (V_source - V_therm));
  return R_therm;
}

// Base conversion
float log2(float num) {
  return (log(num) / log(2));
}

// Calculate temperature
float Temperature(float R_therm) {
  float A = 0.0164872;
  float B = -0.00158538;
  float C = 0.0000033813;
  float temp_K = 1 / (A + B*log2(R_therm) + C*pow(log2(R_therm),3));
  return temp_K;
}

// Convert to Celsius or Fahrenheit
float ConvertTemp(float temp_K, char T) {
  if (T == 'C')  
    return (temp_K - 273.15);
  else if (T == 'F') 
    return (temp_K * 1.8 - 459.67);
}



// Setup
void setup() {
  int idStart = 0;
  receivedID = 0;
  Serial.begin(9600);
  pinMode(AnalogPin, INPUT);
  XBee.begin(9600);
  for (int i=0; i<100; i++) {
    Serial.print("\n");
  }
  Serial.println("Broadcasting...");
}

// Main
void loop() {
  delay(1000);

  // Initiate handshake
  if (identifier == "") {
      XBee.print("BROADCASTING"); // ascii text
      XBee.write("\n");  // binary data
  }
  delay(3000);



  // Receive buffer, check for and confirm ID
  if (XBee.available() && (identifier == "")) { 
    String msg = "";
    char r = XBee.read();

/*  
    // Error checking for first-only numeric ID (testing)
    msg = msg + r;
    String intString = "";
    int intStart = 0;
    int i = 0;
    while (intStart != 2 && i < msg.length()) {
      if (intStart == 0) {
        if (isDigit(msg[i])) {
              intString += msg[i];
              intStart = 1;
           }
      }
      else if (intStart == 1) {
        if (isDigit(msg[i])) {
              intString += msg[i];
              intStart = 1;
           }
      }
      else if (!isDigit(msg[i])) {
        intStart = 2;
      }
      i++; 
    } 
    Serial.print("testing: ");
    Serial.println(intString);
    identifier = intString;
*/

    identifier = r;
  }

  // handshake established
  if ((identifier != "") && (receivedID == 0)) {
    Serial.println();
    Serial.print("RECEIVED IDENTIFIER: ");
    Serial.println(identifier);
    Serial.println();
    receivedID = 1;
  }




  // Calculate and send temperature along with identifier
  while (receivedID == 1) {
        // ADC and V_therm values
    /* Good to get two or more analog readings and discard the first or take the average
    apparently analog pins are multiplexed so this gives it time to settle */
    float RawADC_1 = analogRead(AnalogPin); // toss 1
    float RawADC_2 = analogRead(AnalogPin); // average 2,3
    float RawADC_3 = analogRead(AnalogPin);
    float RawADC_avg = (RawADC_2 + RawADC_3) / 2.00;
    Serial.print("Raw ADC value: ");
    Serial.println(RawADC_avg);
    float V_therm = Voltage(RawADC_avg);
    Serial.print("Voltage across thermistor: ");
    Serial.println(V_therm);

    // Thermistor resistance
    float R_therm = Thermistor(V_therm);    
    Serial.print("Resistance of thermistor: ");
    Serial.println(R_therm);

    // Temperature in Kelvin, Celsius, Fahrenheit
    float temp_K = Temperature(R_therm);
    Serial.print(temp_K);
    Serial.print("K   ");
    float temp_C = ConvertTemp(temp_K, 'C');
    float temp_F = ConvertTemp(temp_K, 'F');
    Serial.print(temp_C);
    Serial.print("C   ");
    Serial.print(temp_F);
    Serial.println("F   ");

    // XBee
    String mytemp = String(temp_F);
    String msg = String(identifier + " " + mytemp);  
    XBee.print(msg); // ascii text
    XBee.write("\n");  // binary data
    Serial.print("Message sent to XBee: ");
    Serial.println(msg);
    Serial.println();


    delay(2000);
  }


}
5
  • 1
    You can put that idea out of your head right now! Do you think that the compiler inserts some "jump to random location" code? Of course it starts at the start. The problem is somewhere else.
    – Nick Gammon
    Sep 25 '16 at 8:09
  • They already think they have their identifier number if another node is running - how do you know that?
    – Nick Gammon
    Sep 25 '16 at 8:10
  • @NickGammon because they start sending temp data as if they have already received their identifier which is the same as the currently running node. If I hit the reset button as I plug them in, this problem goes away. Is there any capacitance on the board or something? Also if I have one node running on battery and plug the other node into my computer then upload the sketch it works properly. For some reason if I plug the second to battery, it uses the same identifier as the first.
    – Austin
    Sep 25 '16 at 15:17
  • 2
    My guess is that the problem is with the XBee. Variables don't keep their values between power cycles or resets.
    – Gerben
    Sep 25 '16 at 15:45
  • Yeah so my pre-connected nodes were broadcasting to everything and sending their identifier to the new nodes. I still don't know exactly why using the reset/upload buttons made it work properly, but I fixed the issue with correct addressing.
    – Austin
    Sep 25 '16 at 17:29

Your Answer

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

Browse other questions tagged or ask your own question.