The below program runs as I would expect on a Uno R3 but not on the R4 The issue I am having is the when homing() is called the first while loop starts and waits for the switch to go HIGH on pin A0. When it goes HIGH it is supposed to wait until it goes LOW before moving on to the next while loop. Instead when the limit switch connected to A0 goes HIGH it moves onto the next while loop within homing(). This while loop does exactly the same and waits until A1 goes HIGH then instead of waiting until A1 goes LOW calls running().
The same program on the R3 works how I would expect.
#include <Wire.h>
#include <DS3232RTC.h>
#include <SolarPosition.h>
DS3232RTC myRTC;
#define MOTOR_ON LOW
#define MOTOR_OFF HIGH
const uint8_t digits = 3;
SolarPosition Home(15.898551, 101.539774); // Thailand
//SolarPosition Home(52.898551, -2.539774); // Home//RTC CODE
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;
const int azLimitSwitchPin = A0; // DEFINE PIN TO USE FOR AZIMUTH LIMIT SWITCH
const int elLimitSwitchPin = A1; // DEFINE PIN TO USE FOR AZIMUTH LIMIT SWITCH
const int azMotorPinPositive = 12;
const int azMotorPinNegative = 11;
const int elMotorPinPositive = 10;
const int elMotorPinNegative = 9;
bool nightime;
bool daytime;
bool trackerAzimuthRunning = false;
bool trackerElevationRunning = false;
bool sunRising = false;
int azLimitSwitch; // VARIABLE TO HOLD THE ABOVE VALUE
int elLimitSwitch;
int hours;
int minutes;
int seconds;
int trackerAzimuthAngle;
int trackerElevationAngle;
int start = 0;
int azimuthSun_position;
float sunElevation;
float newPosition;
float oldPosition;
void setup() {
Serial.begin(9600);
Wire.begin();
pinMode(azEncoder_a, INPUT_PULLUP);
pinMode(azEncoder_b, INPUT_PULLUP);
pinMode(elEncoder_a, INPUT_PULLUP);
pinMode(elEncoder_b, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), azEncoderPinChangeA, RISING);
attachInterrupt(digitalPinToInterrupt(3), elEncoderPinChangeB, RISING);
pinMode(azLimitSwitchPin, INPUT); // LIMIT SWITCH
pinMode(elLimitSwitchPin, INPUT); // LIMIT SWITCH
pinMode(azMotorPinPositive, OUTPUT);
pinMode(azMotorPinNegative, OUTPUT);
pinMode(elMotorPinPositive, OUTPUT);
pinMode(elMotorPinNegative, OUTPUT);
SolarPosition::setTimeProvider(myRTC.get);
}
void loop() {
rtcCode();
trackerAzimuthAngle = azEncoder / 1.67; //This change to degrees
trackerElevationAngle = elEncoder / 1.67; // 6This changes to degrees
azLimitSwitch = digitalRead(azLimitSwitchPin);
elLimitSwitch = digitalRead(elLimitSwitchPin);
if (newPosition > oldPosition) {
Serial.print("THE SUN IS GOING UP");
Serial.print('\n');
sunRising = true;
}
else if (newPosition < oldPosition) {
Serial.print("THE SUN IS GOING DOWN");
Serial.print('\n');
sunRising = false;
}
oldPosition = newPosition;
newPosition = sunElevation;
Serial.print("AZIMUTH LIMIT SWITCH STATUS =....."); //0 = Closed
Serial.print(azLimitSwitch);
Serial.print('\n');
Serial.print("ELEVATION LIMIT SWITCH STATUS =....."); // 0 = Closed
Serial.print(elLimitSwitch);
Serial.print('\n');
if (start < 1) {
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 >= 6 && 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) {
azimuthRunning();
} else {
Serial.print("PAUSED NOT MOVING UNTIL 6AM");
Serial.print('\n');
Serial.print('\n');
digitalWrite(azMotorPinPositive, HIGH);
}
// CHECK TO SEE IF ITS TIME TO HOME POSITIONE
if (hours == 17 && minutes == 47 && seconds == 0) {
homing();
}
}
void homing() {
digitalWrite(azMotorPinNegative, MOTOR_OFF);
digitalWrite(azMotorPinPositive, MOTOR_OFF);
digitalWrite(elMotorPinNegative, MOTOR_OFF);
digitalWrite(elMotorPinPositive, MOTOR_OFF);
//HOMING AZIMUTH
while (digitalRead(azLimitSwitchPin) == LOW) {
Serial.print("HOMING AZIMUTH");
Serial.print('\n');
digitalWrite(azMotorPinNegative, MOTOR_ON);
}
digitalWrite(azMotorPinNegative, MOTOR_OFF);
while (digitalRead(azLimitSwitchPin) == HIGH) {
Serial.print("BACKING OFF AZIMUTH"); //Change this to move motor
Serial.print('\n');
digitalWrite(azMotorPinPositive, MOTOR_ON);
}
azEncoder = 0; // Sets the encoder back to 0 once homed
digitalWrite(azMotorPinPositive, MOTOR_OFF);
//HOMING ELEVATION
while (digitalRead(elLimitSwitchPin) == LOW) {
Serial.print("HOMING ELEVATION");
Serial.print('\n');
digitalWrite(elMotorPinNegative, MOTOR_ON);
}
digitalWrite(elMotorPinNegative, MOTOR_OFF);
while (digitalRead(elLimitSwitchPin) == HIGH) {
Serial.print("BACKING OFF ELEVATION"); //Change this to move motor
Serial.print('\n');
digitalWrite(elMotorPinPositive, MOTOR_ON);
}
elEncoder = 0; // Sets the encoder back to 0 once homed
digitalWrite(elMotorPinPositive, MOTOR_OFF);
start++;
}
void azimuthRunning() {
if (azimuthSun_position > trackerAzimuthAngle && daytime == true && trackerElevationRunning == false) {
trackerAzimuthRunning = true;
digitalWrite(azMotorPinPositive, MOTOR_ON);
Serial.print("AZ RUNNING ");
} else {
trackerAzimuthRunning = false;
digitalWrite(azMotorPinPositive, MOTOR_OFF);
Serial.print("AZ Waiting ");
Serial.print('\n');
}
if (trackerAzimuthRunning == false) {
elevationRunning(); //Elevation Running only gets called if azimuth is not running
}
Serial.print('\n');
Serial.print('\n');
Serial.print('\n');
}
void elevationRunning() {
if (sunRising == true) {
elevationUp();
} else if (sunRising == false) {
elevationDown();
}
}
void elevationUp() {
if (sunElevation > trackerElevationAngle && daytime == true) {
trackerElevationRunning = true;
digitalWrite(elMotorPinPositive, MOTOR_ON);
Serial.print("EL RUNNING GOING UP ");
}
else {
trackerElevationRunning = false;
digitalWrite(elMotorPinPositive, MOTOR_OFF);
Serial.print("EL WAITING");
}
Serial.print('\n');
}
void elevationDown() {
if (sunElevation < trackerElevationAngle && daytime == true) {
trackerElevationRunning = true;
digitalWrite(elMotorPinNegative, MOTOR_ON);
Serial.print("EL RUNNING GOING DOWN ");
}
else {
trackerElevationRunning = false;
digitalWrite(elMotorPinNegative, MOTOR_OFF);
Serial.print("EL GOING DOWN WAITING");
}
Serial.print('\n');
}
void rtcCode() {
printTime(myRTC.get());
Serial.print(F("Home:\t"));
printSolarPosition(Home.getSolarPosition(), digits);
}
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"));
azimuthSun_position = (pos.azimuth);
sunElevation = (pos.elevation);
}
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;
}


