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);
}
}
They already think they have their identifier number if another node is running
- how do you know that?