This project has a coordinator (MEGA 2560) that talks to several (2 so far to test) UNO stations. I am using XBEE XSC 900MHz wireless chips and SainSmart shields. Each field station has 2 inputs. The master has 2 outputs to relays. If 'Input1' on pin 8 or 'Input2' on pin 9 are true, I want the corresponding outputs to come on, energizing a relay. All of the XBEE on each line have the same DT parameter (Destination Address), which is needed for them to talk, and each one has a StationID in its program. This works perfectly when only one remote station is talking to the master, even using the same loops designed for multiple stations, but when I have 2 stations and with different input states, the corresponding output chatters the relay.
The master has a FOR loop that sends out an integer as a StationID. The remote that has that ID recognizes it and replies with a '0', '1', '2', or '3' representing the state of the inputs. The master does this for all stations (currently only 2) and reads the received data into the corresponding element of array StationStatus. After doing this for all stations, I was looping through the array and bitwise ORing the elements into a result, LineStatus. Then I used bitRead to examine the state of bits 0 and 1 and turn on the corresponding output. Like I said, works fine if I unplug one of the stations, but with both stations on and opposite states on input 1 or 2, that matching output goes on and off and random intervals. =( Anybody have any ideas?
I am new to Arduino and C, I've been programming ladder logic on PLCs (Programmable Logic Controllers for a long time. Thanks!
UNO Remote Station code:
//function to invert input state so
//contacts closed = false and contacts
//open = true
boolean invert(boolean Pin)
{
boolean result;
if (Pin == true)
{
result = false;
}
else if (Pin == false)
{
result = true;
}
return result;
}
//====================================
const int inputPin1 = 8;
//input from Problem Solve andon
const int inputPin2 = 9;
//input from Water Spider andon
const int ledPin = 13;
boolean inputState1; //inverted input 1
boolean inputState2; //inverted input 2
int MyStationID = 2;
//may make this configurable by dip switch
String TransmitData;
//byte to be sent as status response to master unit
int ch = 0; //recieved byte from master unit
//for testing
unsigned long StartBlink;
unsigned long StopBlink;
//-----------------------------------------
void setup()
{
//configure digital I/O pins
pinMode(ledPin,OUTPUT); //for testing
pinMode(inputPin1,INPUT);
pinMode(inputPin2, INPUT);
//Set input pins HIGH to enable Arduino's
//internal pullup resistor
digitalWrite(inputPin1,HIGH);
digitalWrite(inputPin2,HIGH);
Serial.begin(57600);
}
//------------------------------------------
void loop() {
//invert input state so closed contact = true
//and open contact = false
//inputState1 = invert(digitalRead(inputPin1));
//inputState2 = invert(digitalRead(inputPin2));
inputState1 = digitalRead(inputPin1);
inputState2 = digitalRead(inputPin2);
//Clear TransmitData
TransmitData = 0;
/*
//Read inputs on pins 8 & 9 and set corresponding
// bits in TransmitByte to be sent to master.
if (inputState1 == true)
{
bitSet(TransmitData, 0);
}
else
{
bitClear(TransmitData, 0);
}
if (inputState2 == true)
{
bitSet(TransmitData, 1);
}
else
{
bitClear(TransmitData, 1);
}
*/
//-----------------------------------------
if (Serial.available())
{
ch = Serial.read();
delay(20);
//-----------------------------------------
if ((ch - 48) == MyStationID)
{
if(inputState1 == false && inputState2 == false)
{
Serial.print(0);
}
else if(inputState1 == true && inputState2 == false)
{
Serial.print(1);
}
else if(inputState1 == false && inputState2 == true)
{
Serial.print(2);
}
else if(inputState1 == true && inputState2 == true)
{
Serial.print(3);
}
}
delay(20);
}
}
MEGA (Master unit) code:
//array of slave station status bytes received
int StationStatus[30];
int StationCount = 2;
int LineStatus;
boolean LineStatus0;
boolean LineStatus1;
int OutputPin1 = 8;
int OutputPin2 = 9;
unsigned long TimeoutMonitor;
boolean Timeout;
int ledPin = 13;
int i;
int x;
int z;
boolean WriteOutputs = false;
boolean Output1 = 0;
boolean Output2 = 0;
//==============================================
void setup()
{
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(57600);
}
//==============================================
void loop()
{
//Poll each station and wait to receive ascii status character
for(i=1; i<=StationCount;i++)
{
Serial.print(i);
delay(60);
if (Serial.available() > 0)
{
StationStatus[i] = (Serial.read()-48);
TimeoutMonitor = 0;
digitalWrite(ledPin, HIGH);
}
else if (Serial.available() <= 0)
{
if(TimeoutMonitor == 0)
{
TimeoutMonitor = millis() + 1000;
}
if (millis() >= TimeoutMonitor)
{
Timeout = true;
digitalWrite(ledPin, LOW);
}
}
if(i == StationCount)
{
WriteOutputs = true;
}
}
//=============================================
if(WriteOutputs == true)
{
LineStatus = 0;
for (x=1; x<=StationCount;x++)
{
int temp;
temp = StationStatus[x];
if bitRead(temp, 0)
{
bitSet(LineStatus, 0);
}
if bitRead(temp, 1)
{
bitSet(LineStatus, 1);
}
//LineStatus = LineStatus | StationStatus[x];
}
// if (LineStatus == 0)
if((bitRead(LineStatus, 0)== 0) && (bitRead(LineStatus, 1) == 0))
{
Output1 = 0;
Output2 = 0;
}
//else if(LineStatus == 1)
if((bitRead(LineStatus, 0)== 1) && (bitRead(LineStatus, 1) == 0))
{
Output1 = 1;
Output2 = 0;
}
if((bitRead(LineStatus, 0)== 0) && (bitRead(LineStatus, 1) == 1))
{
Output1 = 0;
Output2 = 1;
}
//else if(LineStatus == 3)
if((bitRead(LineStatus, 0)== 1) && (bitRead(LineStatus, 1) == 1))
{
Output1 = 1;
Output2 = 1;
}
if(Output1 == true)
{
digitalWrite(OutputPin1, HIGH);
}
else
{
digitalWrite(OutputPin1, LOW);
}
if(Output2 == true)
{
digitalWrite(OutputPin2, HIGH);
}
else
{
digitalWrite(OutputPin2, LOW);
}
WriteOutputs = false;
}