I'm not sure if this is really a coding or electronics question but...
is calling the digitalWrite function guaranteed to always write to the pin correctly?
The reason i ask is the following:
I have a test rig project which toggles a digital output pin (13) of the arduino using the digitalWrite function. It toggles it between high and low with a 500ms delay between each.
The output gets fed into a temperature controls input (which reads a value between 0-5v). The output of the temp controller switches based on the input it receives, when its input is less than 2.5v its output goes low, and it goes high when the input goes above this value.
To ensure that the temp controller is reacting as expected the temp controllers output then gets fed back into my arduino and gets read using the analogRead function. and reports if there is a problem.
On two occations now the arduino has reported that the temp controller has failed, however when I measure the voltage of the arduino when it should have been high the voltage is zero (or there abouts). Is it possible that the digitalWrite can fail?
int OutputPin = 13;
int RelayPin = 2;
int ADCinPin = A5;
int val = 0; // variable to store the value read
unsigned int ErrorCount = 0;
unsigned long timer = 0; // Time to see how long its been running and time errors
unsigned long errorTime = 0; // How long before error recovered
char errorString[40];
const char compile_date[] = __DATE__ " " __TIME__; // Macro for date and time of compile
#define UnitOffTime 2 // Seconds to turn unit off
#define UnitOnTime 7 // Turn unit on and wait for specified number of seconds
void setup() {
timer = millis();
// put your setup code here, to run once:
pinMode(OutputPin, OUTPUT);
pinMode(RelayPin, OUTPUT);
Serial.begin(9600); // setup serial
powerCycleUnit(); // Start unit up
}
void loop() {
//##### Set the output HIGH, wait a second then read to confirm
digitalWrite(OutputPin, HIGH); // set the output ON
delay(500);
val = analogRead(ADCinPin); // read the input pin
if (val < 500)
{
errorTime = millis(); // get the current up time so we can see how long it takes to recover
// Failed to go high as expected
errorFound(true);
}
//##### Set the output LOW, wait a second then read to confirm
digitalWrite(OutputPin, LOW); // sets the output off
delay(500);
val = analogRead(ADCinPin); // read the input pin
if (val > 500)
{
errorTime = millis(); // get the current up time so we can see how long it takes to recover
// Failed to go low as expected
errorFound(false);
}
}
void errorFound(bool highError)
{
bool error = true; // Used to jump out of the retry loop
unsigned long recoverTime = 0;
ErrorCount += 1; // Increment error count
if (highError)
sprintf(errorString, "High Error. Up time = %lu (%d)", errorTime, ErrorCount);
else
sprintf(errorString, "Low Error. Up time = %lu (%d)", errorTime, ErrorCount);
Serial.println(errorString);
// Sit in a loop until output is correct
while (error)
{
delay(500); // Wait before retrying
val = analogRead(ADCinPin); // read the input pin
if (((highError == true) && (val > 500))
|| ((highError == false) && (val < 500)))
{
recoverTime = millis() - errorTime;
// now correct so display recovery time and continue as normal
sprintf(errorString, "Fixed. Recover time = %lu (%d)", recoverTime, recoverTime/500);
Serial.println(errorString);
error = false;
}
}
}
void powerCycleUnit()
{
// Turn unit off for 2 seconds
Turn_Unit_Off();
delaySeconds(UnitOffTime);
//Turn unit on and wait for 10 seconds to ensure units has enough time to start
Turn_Unit_On();
delaySeconds(UnitOnTime);
}
// Turn unit on via relay
void Turn_Unit_On()
{
digitalWrite(RelayPin, LOW); // LOW will turn the unit on
}
// Turn unit off via relay
void Turn_Unit_Off()
{
digitalWrite(RelayPin, HIGH); // HIGH will turn the unit off
}
// Delay for specified number of seconds
void delaySeconds(int seconds)
{
delay(1000 * seconds);
}
To my understanding, the digitalWrite() can't fail. The firmware actually toggles the pin to the selected value, then read the active value to see if it's correct.
But follow up question: What arduino board are you using? The uno has a LED attached to pin 13, so you can see the state of pin 13.
Also, are your grounds connected? Do you have a schematic of your set-up?
The pin is not guaranteed to write to the relay correctly. Show us your circuit, because relay connections are notorious for causing interference to the microprocessor.