I have been working on this program for a few weeks now and finally got it somewhere near finishing. It uploads and seems to do what I want it to do on a R3 board but will not run on my R4 Wifi board although it says upload is successful.
The serial monitor shows nothing.
I think its something to do with the DS1307 library, as I have tried changing the library to DS3232 which improved the situation and the program did run, But I was unable to get the board to read the RTC. The RTC I am using is the DS3231. What could be causing the issue?
#include <SolarPosition.h>
#include <DS1307RTC.h>
#define MOTOR_ON LOW
#define MOTOR_OFF HIGH
const uint8_t digits = 3;
//SolarPosition Home(134.898551, -25.539774); // Home//RTC CODE
SolarPosition Home(32.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 = 0; // VARIABLE TO HOLD THE ABOVE VALUE
int elLimitSwitch = 0;
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);
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(elLimitSwitchPin, INPUT); // LIMIT SWITCH
pinMode(azMotorPinPositive, OUTPUT);
pinMode(azMotorPinNegative, OUTPUT);
pinMode(elMotorPinPositive, OUTPUT);
pinMode(elMotorPinNegative, 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);
elLimitSwitch = digitalRead(elLimitSwitchPin);
if (newPosition > oldPosition) {
Serial.print("Going Up");
Serial.print('\n');
sunRising = true;
}
else if (newPosition < oldPosition) {
Serial.print("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) {
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 >= 2 && 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');
digitalWrite(azMotorPinPositive, HIGH);
}
// CHECK TO SEE IF ITS TIME TO HOME POSITIONE
if (hours == 9 && minutes == 18 && seconds == 0) {
homing();
}
delay(1000);
}
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);
start++;
//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 ");
Serial.print('\n');
} 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
}
}
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 ");
Serial.print('\n');
}
else {
trackerElevationRunning = false;
digitalWrite(elMotorPinPositive, MOTOR_OFF);
Serial.print("EL GOING UP WAITING");
Serial.print('\n');
}
}
void elevationDown() {
if (sunElevation < trackerElevationAngle && daytime == true) {
trackerElevationRunning = true;
digitalWrite(elMotorPinNegative, MOTOR_ON);
Serial.print("EL RUNNING GOING DOWN ");
Serial.print('\n');
}
else {
trackerElevationRunning = false;
digitalWrite(elMotorPinNegative, MOTOR_OFF);
Serial.print("EL GOING DOWN 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"));
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;
}
The code uploads and runs with Wire.h
in this position but does not read from the RTC.
#include <Wire.h>
#include <DS1307RTC.h>
#include <SolarPosition.h>
With Wire.h
in the below position, the code uploads but does not run or show anything on the Serial monitor.
#include <DS1307RTC.h>
#include <SolarPosition.h>
#include <Wire.h>
Either way round adding Wire.begin()
doesn't make any difference to the output.
1 Answer 1
I have found that adding #include <Wire.h>
in the header and Wire.begin()
in the set up, the program uploads and runs on the R4 Wifi board. The only issue being the RTC is not working.
I have since changed the RTC library to DS3232RTC.h
and added <DS3232RTC myRTC>
in the header. I have also amended the functions to get and print the RTC.
#include <DS3232RTC.h>
#include <SolarPosition.h>
DS3232RTC myRTC;
Void setup (){
SolarPosition::setTimeProvider(myRTC.get);}
void rtcCode() {
printTime(myRTC.get());}
The program now works as expected and displays the time and date accurately.
-
Congrats on finding a solution, but is it possible to investigate a bit further to see if you can isolate what the cause of the problem was? Could you go back to it not working (if you kept the code) and then just add the
#include<wire.h>
line and see if the fault is cured by the include file or bywire.begin()
?Code Gorilla– Code Gorilla02/14/2025 08:24:43Commented Feb 14 at 8:24 -
The code load and runs with Wire.h in this position but does not read from the RTC.user115219– user11521902/14/2025 13:53:03Commented Feb 14 at 13:53
attachInterrupt(0, azEncoderPinChangeA, RISING);
Don't use magic numbers here, use digitalPinToInterrupt() instead to better ensure compatibility over board types. What pin is meant here anyway? It is the same with the other attachInterrupt() statement.