Relays unresponsive until interaction

I am using a uLCD32-PTu on an Arduino Nano with 3 Dallas Temperature DS18B20 sensors and a 2 Channel Sainsmart relay board.

Everything about my project works just fine, however, upon start-up and after the setup portion of my Arduino code has completed it's cycle, my relays both turn on and stay on until otherwise commanded to turn off through manual slider value adjustment, thereby activating the if statements. I have not added any statements to my code that would command the relays to go HIGH until the corresponding Slider reported it's first message.

How can I keep both relays off until the temperature reaches the preset slider temperature without any interaction with the device after start-up?
As you can tell from my code, I am setting my preset value from the Arduino itself upon start-up. All the controls on the LCD are for user adjustment IF preferred, but I want it to be a plug and play kind of thing.

Here is my Arduino code, let me know if you need any more than this to help me fix this issue... Thanks in advance!

#define CHANNEL1 8 //fan
#define CHANNEL2 9 //Valve
#include <genieArduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 3 
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
DeviceAddress basementTemp = { 0x28, 0xB6, 0x58, 0x66, 0x04, 0x00, 0x00, 0x07}; //BLUE wire Dallas 
DeviceAddress furnaceWater = { 0x28, 0xCB, 0x4F, 0x66, 0x04, 0x00, 0x00, 0xF8}; //GREEN wire Dallas Temperature Sensor address
DeviceAddress houseWater = { 0x28, 0xDE, 0x57, 0x66, 0x04, 0x00, 0x00, 0x0A}; //GREEN wire Dallas

//int tempLeeway = 5; //Temperature buffer for relay so it won't flip on and off all the time
float sliderPreset1 = 80;//Preset slider values so you don't have to set values manually upon start-up and relays stay off until temp sensor reaches this number
float sliderPreset2 = 81;//Ditto

int slider0_val;//Set point 
int slider1_val;//Set point 
int t, temp;//for celcius to fehrenheit conversion

void setup() 
{ 

pinMode(CHANNEL1, OUTPUT); //Low Speed Fan RELAY
pinMode(CHANNEL2, OUTPUT); //High Speed Fan RELAY

genieBegin (GENIE_SERIAL, 56000); //Serial1
genieAttachEventHandler(myGenieEventHandler);
//genieSetup(9600); //Make sure this is the same baud rate of the LCD and the genieBegin command.

sensors.begin();
sensors.setResolution(basementTemp, 10);
sensors.setResolution(furnaceWater, 10); 
sensors.setResolution(houseWater, 10);

//Reset the Display (change D4 to D2 if you have original 4D Arduino Adaptor)
pinMode(4, OUTPUT); // Set D4 on Arduino to Output (4D Arduino Adaptor V2 - Display Reset)
digitalWrite(4, 1); // Reset the Display via D4
delay(100);
digitalWrite(4, 0); // unReset the Display via D4

delay (3500); //let the display start up

genieWriteObject(GENIE_OBJ_LED_DIGITS, 6, sliderPreset1);//TEST
genieWriteObject(GENIE_OBJ_SLIDER, 0, sliderPreset1);//TEST
genieWriteObject(GENIE_OBJ_LED_DIGITS, 5, sliderPreset2);
genieWriteObject(GENIE_OBJ_SLIDER, 1, sliderPreset2);//TEST
}


void loop() 
{
//digitalWrite(CHANNEL1, LOW); //Test to see if this will keep relay off until temps reach preset point... FAIL.... 
static long waitPeriod = millis();
genieDoEvents();

//Read from sensor every 100ms and write to the display
if (millis() >= waitPeriod) 
{
temp = (t * 1.8) + 32; //Convert *C to *F.

float basement = sensors.getTempF(basementTemp);
float furnace = sensors.getTempF(furnaceWater);
float waterHeater = sensors.getTempF(houseWater);
//float tempC = sensors.getTempC(insideThermometer);
float tempF;
sensors.requestTemperatures(); 


//genieWriteObject(GENIE_OBJ_LED_DIGITS, 1, basement);//The first line of code in the section gets ignored for some reason...?? copy and paste 
genieWriteObject(GENIE_OBJ_LED_DIGITS, 1, basement);/
genieWriteObject(GENIE_OBJ_LED_DIGITS, 0, waterHeater);
genieWriteObject(GENIE_OBJ_LED_DIGITS, 2, basement);
genieWriteObject(GENIE_OBJ_LED_DIGITS, 3, furnace); 
genieWriteObject(GENIE_OBJ_LED_DIGITS, 7, waterHeater);
waitPeriod = millis() + 10; // rerun this code in another 100ms time.

if (slider0_val > basement)//For some reason it's responding in polar opposites of the command? 
{
digitalWrite(CHANNEL1, HIGH); 
}
else
{
digitalWrite(CHANNEL1, LOW); 
}
/////////////////////////////////////////////////////

if (slider1_val > waterHeater)
{
digitalWrite(CHANNEL2, HIGH);
}
else
{
digitalWrite(CHANNEL2, LOW);
}
}//Closes Millis
}//Closes Loop


void myGenieEventHandler(void)
{
genieFrame Event;
genieDequeueEvent(&Event);

//If the cmd received is from a Reported Event
if (Event.reportObject.cmd == GENIE_REPORT_EVENT)
{
if (Event.reportObject.object == GENIE_OBJ_SLIDER) // If the Reported Message was from a Slider
{
if (Event.reportObject.index == 0) // If Slider0
{
slider0_val = genieGetEventData(&Event); // Receive the event data from the Slider0
}
}
}

//If the cmd received is from a Reported Event
if (Event.reportObject.cmd == GENIE_REPORT_EVENT)
{
if (Event.reportObject.object == GENIE_OBJ_SLIDER) // If the Reported Message was from a Slider
{
if (Event.reportObject.index == 1) // If Slider1
{
slider1_val = genieGetEventData(&Event); // Receive the event data from the Slider1
}
}
}


//If the cmd received is from a Reported Object, which occurs if a Read Object is requested in the main code, reply processed here.
if (Event.reportObject.cmd == GENIE_REPORT_OBJ)
{
//Put code in here, like the above, if you want to process data when you have used a genieReadObject in your main loop
//Currently there are none, so this section has no code.
//Filter out the Object and the Index like above, and then same the data into a variable as required.
}
}

I have not added any statements to my code that would command the relays to go HIGH until the corresponding Slider reported it's first message.

What makes you think they start LOW? Give a GOOD link to a document that says this.

Mark

The relays are driven "active LOW", a LOW on the Arduino output energizes the relay, HIGH will turn it off.

The relay board will draw about 200mA if both relays are energized, so this may work if the Arduino and relay board powered through USB 5V, but the Arduino's 5V regulator may overheat if using VIN @ 12V. In this case, you'll need to use a separate supply for the relay board.

@holmes4

What makes you think they start LOW? Give a GOOD link to a document that says this.

Is that supposed to be sarcasm or passive aggression of some sort? If the relays were responding to the loop portion of my code correctly according to the if statements, the relays should either turn on or off depending on what the actual temperature in accordance to the set temperature by the Arduino... SO in theory, if the actual temperature data from the corresponding sensor is lower than that set point, the relays should be turned off or "LOW" and vice versa if the temperature is higher than said set point upon loop. Correct??? Find me a document that contradicts that logic if your so confident... ::slight_smile:

Why not use digitalWrite() within setup() to set them to whatever initial state you want?
The Atmega default state may not be suitable.

...R

@dlloyd

The relays are driven "active LOW", a LOW on the Arduino output energizes the relay, HIGH will turn it off.

Can you explain that a little more? Are you saying I need to ad a output, LOW command at the beginning of my loop? Upon start-up of the arduino, the temperature being received from the temp sensors may be signalling to the relays to turn on, so I can't just have the relays always off. I just don't understand why my if/else commands are being ignored until I adjust the set point manually on the LCD.

The relay board will draw about 200mA if both relays are energized, so this may work if the Arduino and relay board powered through USB 5V, but the Arduino's 5V regulator may overheat if using VIN @ 12V. In this case, you'll need to use a separate supply for the relay board.

As a matter of fact, I have already wired my relays to be powered through their own separate power 5v regulator and 12v power source. I have done a lot of testing on the power source side of this project and I have pretty much ruled it out completely as a factor in this problem. Everything works perfectly, but only after I manually set the temp set point on the LCD screen.

I'll repeat the HINT

What makes you think they start LOW? Give a GOOD link to a document that says this.

Mark

Give a GOOD link to a document that says this.

Since the OP was inappropriately offended by your helpful comment, here is the link to the schematic: 2-Channel 5V Relay Module | SainSmart – SainSmart.com

As other posters have tried to point out, the relay coil is active low. Most likely, the relay output wiring or the program logic is wrong.

@holmes4 OBVIOUSLY it doesn't start LOW otherwise I wouldn't be asking for help on working this bug out. I don't care whether it starts high or low on start-up...

what I care about is that I have programmed my code to not turn on the relay until the temperature gets to the set point, but it ignores my commands entirely until I manually set the desired temperature on the LCD. Maybe I am missing something very obvious here.. but you're not helping at all unless you actually point it out and show me how to fix it instead of continually "hinting" at it...

@Jremington

As other posters have tried to point out, the relay coil is active low. Most likely, the relay output wiring or the program logic is wrong.

I apologize if I am coming across as offended, I do not mean to be ungrateful for any and all help here, even in the form of "hints." I am frustrate with this however, and I am almost positive this is a program logic issue. I am still fairly new to Arduino and I do not know how to make sense of this seeing as how I did not add anything to this code that should cause this program bug, to my knowledge. I have modeled everything from example libraries and kept everything as simple as I could to avoid things like this. I am not good at taking "hints" because I simply don't know what I don't know here

Again, I apologize if I have offended any of you as that was not my intention. I am simply trying to be very direct to the point in everything I say so this all makes sense

How can I keep both relays off until the temperature reaches the preset slider temperature without any interaction with the device after start-up?

Can you explain that a little more? Are you saying I need to ad a output, LOW command at the beginning of my loop? Upon start-up of the arduino, the temperature being received from the temp sensors may be signalling to the relays to turn on, so I can't just have the relays always off.

In your setup loop, set both ouputs that control the relays to HIGH.
This will turn both of them off.

I just don't understand why my if/else commands are being ignored until I adjust the set point manually on the LCD.

Your conditions to control the relays are:

if (slider0_val > basement)...
if (slider1_val > waterHeater)...

There is nowhere else in your main loop the relays are being controlled.

You have 2 problems,

  1. The state of the pins between reset and the call to setup(), this takes just over 0.5 of a second

  2. The state of the pins between setup() and the first control input you send, (as your not setting them to any thing in setup(). )

The solution to the first would be a pull UP resistor about 20K should do it.

and for the second .....

Mark

holmes4:
and for the second .....

The OP seems to have missed the solution to this part in Reply #4

Feels like I was wasting my time.

...R

OK one last attempt. The answer is staring you in the face but you choose to ignore all the answer that give you the correct answer.

within your setup you have the lines

pinMode(CHANNEL1, OUTPUT); //Low Speed Fan RELAY
pinMode(CHANNEL2, OUTPUT); //High Speed Fan RELAY

YET you don't do any digital.write to set the value on those pins. Now, use your best guess what the default value will be on those pins.?

Now bear in mind what you just guessed and that most relay sheilds are ACTIVE LOW. What state do you expect your relays to be in?

Just put the following in your setup function.

digitalWrite(CHANNEL1, HIGH); 
digitalWrite(CHANNEL2, HIGH);

end of story.

Just put the following in your setup function.
Code: [Select]

digitalWrite(CHANNEL1, HIGH);
digitalWrite(CHANNEL2, HIGH);

end of story.

I did exactly that! Relays stay off through the setup portion of the code, but as soon as the loop starts, the relays go high, regardless of my if/else statements and live temperature data... UNTIL I manually set the temperature set point on my LCD. Then my if/else statements work perfectly and it's happy as a clam.

Try this for your conditions:

if ((slider0_val = 0) || (slider0_val > basement))
{
  digitalWrite(CHANNEL1, HIGH); //relay OFF
}

if ((slider0_val > 0) && (slider0_val <= basement))
{
  digitalWrite(CHANNEL1, LOW); //relay ON
}

/////////////////////////////////////////////////////

if ((slider1_val = 0) || (slider1_val > waterHeater))
{
  digitalWrite(CHANNEL2, HIGH); // relay OFF
}

if ((slider1_val > 0) && (slider1_val <= waterHeater))
{
  digitalWrite(CHANNEL2, LOW); // relay ON
}

Gustermaximus:
but as soon as the loop starts, the relays go high, regardless of my if/else statements and live temperature data...

In that case there is an error in your code.

Study the part of your code that does work properly and see how it differs from the part that does not.

Fairly obviously, if digitalWrite(CHANNEL1, HIGH); keeps the relays OFF something in your code is doing a digitalWrite(CHANNEL1, LOW); when it shouldn't.

...R

@dlloyd

Try this for your conditions:

if ((slider0_val = 0) || (slider0_val > basement))
{
digitalWrite(CHANNEL1, HIGH); //relay OFF
}

if ((slider0_val > 0) && (slider0_val <= basement))
{
digitalWrite(CHANNEL1, LOW); //relay ON
}

/////////////////////////////////////////////////////

if ((slider1_val = 0) || (slider1_val > waterHeater))
{
digitalWrite(CHANNEL2, HIGH); // relay OFF
}

if ((slider1_val > 0) && (slider1_val <= waterHeater))
{
digitalWrite(CHANNEL2, LOW); // relay ON
}

I tried exactly that, my results were: The relays now stay off under all conditions. The if commands are completely ignored. However, the relays did not turn on and stay on upon the loop starting! I do not understand exactly how that worked, but it seems we are heading in the right direction! :smiley:

@Delta_G I tried adding the serial.println command as you suggested... The problem remains. The relays still went high until LCD interaction, but the problem with the LCD I am using, is that there is tremendous lag and blocking upon any interaction at all from the screen when I am running serial.println commands, so I must keep them out of the code at all costs.

@Delta_G

Statements in code are never ignored. If they don't work the way you want then you wrote them wrong. But you can't say they are ignored.

Fair enough, I just couldn't think of an easier way to describe what was happening with the actual arduino.

Do you know the values of those variables at startup? What are the values of slider1_val and basement when the code first starts?

I preset the set values during the setup portion of the code, as far as live temperatures values go, they fluctuate upon the condition of the weather.

As you can see in my master code I posted at the beginning of this thread, I set them like this:

float sliderPreset1 = 80;
float sliderPreset2 = 81;

and in my setup portion I have:

    genieWriteObject(GENIE_OBJ_LED_DIGITS, 6, sliderPreset1);//TEST
    genieWriteObject(GENIE_OBJ_SLIDER, 0, sliderPreset1);//TEST
    genieWriteObject(GENIE_OBJ_LED_DIGITS, 5, sliderPreset2);
    genieWriteObject(GENIE_OBJ_SLIDER, 1, sliderPreset2);//TEST