Logic low relays

Hi
I am using the attached relays which I think are logic low.
[https://mm.digikey.com/Volume0/opasdata/d220001/medias/docus/5773/TS0010D%20DATASHEET.pdf]
I think this is causing my relays to switch opposite to how the code is written.
The below code bring the relays on when LOW and OFF when HIGH.
Is there a fix for this within the code so when I use "digitalWrite(11, HIGH) the relay is activated.

int relay_1 = 9;
int relay_2 = 10;
int relay_3 = 11;
int relay_4 = 12;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  pinMode(relay_1, OUTPUT);
  pinMode(relay_2, OUTPUT);
  pinMode(relay_3, OUTPUT);
  pinMode(relay_4, OUTPUT);
}

void loop() {

  digitalWrite(relay_1, HIGH);
  digitalWrite(relay_2, HIGH);
  digitalWrite(relay_3, HIGH);
  digitalWrite(relay_4, HIGH);

  Serial.println("All relays ON");
  

  delay(3000);

  digitalWrite(relay_1, LOW);
  digitalWrite(relay_2, LOW);
  digitalWrite(relay_3, LOW);
  digitalWrite(relay_4, LOW);

  Serial.println("All relays OFF     ");
  

  delay(3000);
}

Why not use

digitalWrite(11, LOW);

When you want to turn the relay on ?

I am aware of that but not happy having everything in my code the opposite way round.

Nothing is the opposite way round. Writing LOW turns the relay on. Get over it

You cannot write HIGH to the relay and have the relay turn on. You could, if you wanted to, #define ON as LOW and OFF as HIGH then write ON or OFF to the relay but it would still actually be writing LOW to turn the relay on

1 Like

Brilliant. Lot less confusing know thank you.

#include <SolarPosition.h>
#include <DS1307RTC.h>

#define on LOW
#define off HIGH

const uint8_t digits = 3;


SolarPosition Home(52.898551, -2.539774);  // Home//RTC CODE
int sun_position;


const int azEncoder_a = 2;  // Green - pin 2 - Digital
const int azEncoder_b = 4;  // White - pin 4 - Digital
long azEncoder = 0;

const int elEncoder_a = 3;  // Green - pin 3 - Digital
const int elEncoder_b = 5;  // White - pin 5 - Digital
long elEncoder = 0;


int trackerAzimuthAngle;
int trackerElevationAngle;
int start = 0;
const int azLimitSwitchPin = A0;  // DEFINE PIN TO USE FOR AZIMUTH LIMIT SWITCH
int azLimitSwitch = 0;           // VARIABLE TO HOLD THE ABOVE VALUE
const int azMotorPinPositive = 12;
const int azMotorPinNegative = 11;


bool nightime;
bool daytime;


int hours;
int minutes;
int seconds;


void setup() {
  Serial.begin(9600);

  pinMode(azEncoder_a, INPUT_PULLUP);
  pinMode(azEncoder_b, INPUT_PULLUP);

  pinMode(elEncoder_a, INPUT_PULLUP);
  pinMode(elEncoder_b, INPUT_PULLUP);

  attachInterrupt(0, azEncoderPinChangeA, RISING);
  attachInterrupt(1, elEncoderPinChangeB, RISING);

  pinMode(azLimitSwitchPin, INPUT);  // LIMIT SWITCH

  pinMode(azMotorPinPositive, OUTPUT);
  pinMode(azMotorPinNegative, OUTPUT);


  SolarPosition::setTimeProvider(RTC.get);
}

void loop() {

  rtcCode();

  trackerAzimuthAngle = azEncoder / 1.67;    //This change to degrees
  trackerElevationAngle = elEncoder / 1.67;  // This changes to degrees
  azLimitSwitch = digitalRead(azLimitSwitchPin);

  Serial.print("LIMIT SWITCH STATUS =.....");
  Serial.print(azLimitSwitch);
  Serial.print('\n');

  if (start < 1) {
    Serial.print("start ");
    Serial.print(start);
    Serial.print('\n');
    homing();  // This statement checks to see if the programs has just started.
  }

  Serial.print("TRACKER AZIMUTH ANGLE IS   ");
  Serial.print(trackerAzimuthAngle);
  Serial.print('\n');

  Serial.print("TRACKER ELEVATION ANGLE IS   ");
  Serial.print(trackerElevationAngle);
  Serial.print('\n');

  //ADJUST THESE TIMES FOR TESTING
  if (hours >= 5 && hours <= 21 && minutes < 59 && seconds <= 59) {
    daytime = true;
    nightime = false;
  } else {
    nightime = true;
    daytime = false;
  }
  Serial.print("DAYTIME  ");
  Serial.print(daytime);
  Serial.print('\n');
  Serial.print("NIGHTIME  ");
  Serial.print(nightime);
  Serial.print('\n');


  // CHANGE THE BELOW FOR TESTING
  if (daytime == true) {
   running();
  } else {
    Serial.print("PAUSED NOT MOVING UNTIL 6AM");
    Serial.print('\n');
    digitalWrite(azMotorPinPositive, HIGH);
  }
  // CHECK TO SEE IF ITS TIME TO HOME POSITIONE
  if (hours == 10 && minutes == 35 && seconds <= 2) {
    homing();
  }

  delay(1000);
}

void homing() {

  digitalWrite(azMotorPinNegative, off);
  digitalWrite(azMotorPinPositive, off);
  while (digitalRead(azLimitSwitchPin)  == LOW) {
    Serial.print("HOMING");  // Change this to move the motor
    Serial.print('\n');
    digitalWrite(azMotorPinNegative, on);
  }
  digitalWrite(azMotorPinNegative, off);

  while (digitalRead(azLimitSwitchPin) == HIGH) {
    Serial.print("BACKING OFF");  //Change this to move motor
    Serial.print('\n');
    digitalWrite(azMotorPinPositive, on);
    azEncoder = 0;  // Check this in main program
  }
  digitalWrite(azMotorPinPositive, off);
  start++;
}
void running() {

  if (sun_position > trackerAzimuthAngle && daytime == true) {
    digitalWrite(azMotorPinPositive, on);
    Serial.print("RUNNING ");
    Serial.print('\n');
  } else {
    digitalWrite(azMotorPinPositive, off);
    Serial.print("Waiting ");
    Serial.print('\n');
  }
}

void rtcCode() {
  printTime(RTC.get());
  Serial.print(F("Home:\t"));
  printSolarPosition(Home.getSolarPosition(), digits);
  Serial.println();
  Serial.print('\n');
}

void azEncoderPinChangeA() {
  azEncoder += digitalRead(azEncoder_a) == digitalRead(azEncoder_b) ? -1 : 1;
}
void elEncoderPinChangeB() {
  elEncoder += digitalRead(elEncoder_a) == digitalRead(elEncoder_b) ? 1 : -1;
}


void printSolarPosition(SolarPosition_t pos, int numDigits) {
  Serial.print(F("el: "));
  Serial.print(pos.elevation, numDigits);
  Serial.print(F(" deg\t"));

  Serial.print(F("az: "));
  Serial.print(pos.azimuth, numDigits);
  Serial.println(F(" deg"));
  sun_position = (pos.azimuth);
}

void printTime(time_t t) {
  tmElements_t someTime;
  breakTime(t, someTime);

  Serial.print(someTime.Hour);
  Serial.print(F(":"));
  Serial.print(someTime.Minute);
  Serial.print(F(":"));
  Serial.print(someTime.Second);
  Serial.print(F(" UTC on "));
  Serial.print(dayStr(someTime.Wday));
  Serial.print(F(", "));
  Serial.print(monthStr(someTime.Month));
  Serial.print(F(" "));
  Serial.print(someTime.Day);
  Serial.print(F(", "));
  Serial.println(tmYearToCalendar(someTime.Year));

  hours = someTime.Hour;
  minutes = someTime.Minute;
  seconds = someTime.Second;
}


LOL.

The basic trick of turning things upside down so they aren't the opposite way around will be handy all over the place.

a7

I am surprised that if you are triggered by a relay being on when its input is LOW then I am surprised that you find this acceptable

  while (digitalRead(azLimitSwitchPin) == HIGH)

Meanwhile, back at the relay, as it is a Double Throw switch, you could use the common and normally closed contacts to switch whatever it is controlling and then writing HIGH would turn off the relay and close the contacts

This whole thing has confused the hell out of me over the last few days. Had me changing code and getting in a mess. I didn't realise why the relays were working opposite. think I have got my head around the limit switch side being LOW when closed and HIGH when open.
Using the "define" makes it easier to follow as the program gets longer.
It all seems to work well now. Just need to write the code to move the "Elevation" ram.
Thanks for your help.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.