I have a project i am working on called single axis solar tracking system and i am using this rotary encoder https://diyshop.com.ua/image/cache/catalog/product/microcontroller/sensors/Encoder/ES38-06G1000BSC824/ES38-06G1000BSC824_1-650x650.jpg. The problem i having is after the tracking system have moved to its predetermined position, the rotary encoder keeps counting even though the system is not moving thereby making the whole setup unstable. i am thinking that my power source for the encoder is the problem which is a 12v adapter because the ac input is not a constant voltage, and this is my code
const byte A = 2; // Interruption pin 2 for the rotary encoder
const byte B = 3; // Interruption pin 3 for the rotary encoder
volatile int counter = 0; //This variable will increase or decrease depending on the rotation of encoder
int temp, counter_copy;
int target_slope;
//Assigning the relay port to digital pins
byte RelayPin1 = 7; // Digital pin 7
byte RelayPin2 = 8; // Digital pin 8
// Setting the constant parameters needed to calculate inclination of platform
const int std_me = -15;
const int DaysInMonth[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
const float Lat = 6.335;
const float Local_me = -5.6037;
// importing libraries for the rtc sensor
#include <Wire.h>
#include <Rtc_Pcf8563.h>
//init the real-time clock
Rtc_Pcf8563 rtc;
void setup() {
Serial.begin(9600);
Wire.begin();
// Set the relay pins as output
pinMode(RelayPin1, OUTPUT);
pinMode(RelayPin2, OUTPUT);
//Set the dc motor to off state at the start of the system
digitalWrite(RelayPin1, HIGH);
digitalWrite(RelayPin2, HIGH);
// Set encoder pins as inputs
pinMode(A, INPUT_PULLUP);
pinMode(B, INPUT_PULLUP);
// Setting interruptions for pin A and pin B
attachInterrupt(digitalPinToInterrupt(A), ai0, FALLING);
attachInterrupt(digitalPinToInterrupt(B), ai1, FALLING);
}
void loop() {
hourlyrotation(rtc.getHour());
}
// function to determine the day of the year whose value ranges from 0 to 365 inclusive
int dayofyear(byte day, byte month) {
if (month >= 1 && month <= 12) {
return DaysInMonth[month - 1] + day;
}
}
// function for determining the sign whether positive or negative attached to a value
int sign(float value) {
if (value > 0) {
return 1;
} else if (value < 0) {
return -1;
} else {
return 0;
}
}
// function that calculate the hour and to position the panel to in other to get maximum radiation
void inclination() {
int dofy = dayofyear(rtc.getDay(), rtc.getMonth()); // Value range from 0 to 365 inclusive
float B_ = (dofy - 1) * (360.0 / 365.0) * (PI / 180.0); // Constant
float equ_of_time = 229.2 * (0.000075 + 0.001868 * cos(B_) - 0.032077 * sin(B_) - 0.014615 * cos(2 * B_) - 0.04089 * sin(2 * B_)); // Value is in minutes
float decl = 23.45 * sin((284 + dofy) * (360.0 / 365.0) * (PI / 180.0)); // Declination value is in degrees
float tcf = (equ_of_time + 4 * (std_me - Local_me)) / 1440.0; // Time correction factor is in days
float s_t = tcf + (rtc.getHour() / 24.0); // Calculating solar time is in days
float ho_ang = (s_t - 0.5) * 360.0; // Hour angle is in degrees (simplified)
float cos_zenith = cos(Lat * (PI / 180.0)) * cos(decl * (PI / 180.0)) * cos(ho_ang * (PI / 180.0)) + sin(Lat * (PI / 180.0)) * sin(decl * (PI / 180.0));
float sin_zenith = sqrt(1 - pow(cos_zenith, 2));
float solar_azimuth = degrees(acos((cos_zenith * sin(radians(Lat)) - sin(radians(decl))) / (sin_zenith * cos(radians(Lat))))) * sign(ho_ang);
int surface_azimuth = (solar_azimuth > 0) ? 90 : -90; //azimuth is positive in the west and negative in the east
float slope = round(degrees(atan((abs(cos(radians(surface_azimuth - solar_azimuth))) * (sin_zenith / cos_zenith))))); // The value of slope is in degrees
// Rearrange the slope so that angles above horizontal are positive and vice versa
target_slope = (surface_azimuth > 0) ? -slope : slope;
}
void ai0() {
// ai0 is activated if DigitalPin 2 is going from HIGH to LOW
// Check pin 3 to determine the direction
if (digitalRead(B) == HIGH) {
counter--;
} else if (digitalRead(B) == LOW) {
counter++;
}
}
void ai1() {
// ai0 is activated if DigitalPin 3 is going from HIGH to LOW
// Check with pin 2 to determine the direction
if (digitalRead(A) == HIGH) {
counter++;
} else if (digitalRead(A) == LOW) {
counter--;
}
}
void rotationdirection() {
noInterrupts();
counter_copy = counter;
interrupts();
// Send the value of counter_copy
if (counter_copy != temp) {
Serial.println(counter_copy);
temp = counter_copy;
}
delay(1000);
if (counter_copy < target_slope) {
//rotate clockwise
digitalWrite(RelayPin1, LOW);
digitalWrite(RelayPin2, HIGH);
} else if (counter_copy > target_slope) {
//rotate counter clockwise
digitalWrite(RelayPin1, HIGH);
digitalWrite(RelayPin2, LOW);
}
delay(100);
digitalWrite(RelayPin1, HIGH);
digitalWrite(RelayPin2, HIGH);
delay(1000);
}
//hourly rotation from 10 in the morning to 15 in the evening
void hourlyrotation(byte hourtime) {
if (hourtime >= 10 && hourtime <= 15) {
inclination();
rotationdirection();
}
}
i would appreciate any suggestions, thanks.