final version (i hope)

This commit is contained in:
Benny 2025-05-25 18:31:30 +02:00
parent 864de6cbff
commit 883e12542d
2 changed files with 100 additions and 153 deletions

View File

@ -14,3 +14,4 @@ board = uno
framework = arduino
lib_deps =
arduino-libraries/Stepper@^1.1.3
waspinator/AccelStepper@^1.64

View File

@ -1,187 +1,133 @@
// Includes the Arduino Stepper Library
#include <Stepper.h>
#include <Arduino.h>
#include <AccelStepper.h>
// Define
#define PHOTO_DIODE_1 A0 // Photodiode 1 connected to A0
#define PHOTO_DIODE_2 A1 // Photodiode 2 connected to A1
#define LDR_PIN_TL A0 // Top-Left
#define LDR_PIN_BL A1 // Bottom-Left
#define LDR_PIN_TR A2 // Top-Right
#define LDR_PIN_BR A3 // Bottom-Right
// Defines the number of steps per rotation
const int stepsPerRevolution = 4096;
// Initialize steppers
AccelStepper stepperX(AccelStepper::HALF4WIRE, 8, 10, 9, 11);
AccelStepper stepperY(AccelStepper::HALF4WIRE, 4, 6, 5, 7);
// TODO: fix rounding errors
// int stepsPerDegree = stepsPerRevolution / 360;
// const float stepsPerDegree = stepsPerRevolution / 360.0;
const float stepsPerDegree = 11;
// --- Configuration Constants ---
const int TOLERANCE = 30; // Combined tolerance for error signals.
// Creates an instance of stepper class
// Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence
Stepper stepperX = Stepper(stepsPerRevolution, 8, 10, 9, 11);
Stepper stepperY = Stepper(stepsPerRevolution, 4, 5, 6, 7);
// Proportional Gain (Kp): Increased for faster response, decrease if it overshoots
const float KP_X = 0.35;
const float KP_Y = 0.3;
// Pins für Widerstände
const int ldrPin1 = A0;
const int ldrPin2 = A1;
int offset;
// LDR Reading
const int LDR_SAMPLES = 5;
const int LDR_DELAY_MS = 1;
// Stepper Speed and Acceleration: INCREASED FOR FASTER MOVEMENT
const float MAX_SPEED_X = 4000.0;
const float ACCELERATION_X = 50000.0;
const float MAX_SPEED_Y = 4000.0;
const float ACCELERATION_Y = 50000.0;
// --- Global Variables ---
long offsetX_cal = 0; // Calibration offset for X-axis calculation
long offsetY_cal = 0; // Calibration offset for Y-axis calculation
// Helper function to read LDR value with averaging
int readLDR(int pin)
{
long sum = 0;
const int samples = 10;
for (int i = 0; i < samples; i++)
for (int i = 0; i < LDR_SAMPLES; i++)
{
sum += analogRead(pin);
delay(5); // Small delay for stability
if (LDR_DELAY_MS > 0)
{
delay(LDR_DELAY_MS);
}
}
return sum / samples;
}
void turnDegrees(Stepper stepper, int deg)
{
stepperX.setSpeed(100);
stepperY.setSpeed(100);
stepper.step(deg * stepsPerDegree);
return sum / LDR_SAMPLES;
}
void setup()
{
// Nothing to do (Stepper Library sets pins as outputs)
Serial.begin(9600); // Open serial port at 9600 baud rate
// pinMode(PHOTO_DIODE_1, INPUT);
// pinMode(PHOTO_DIODE_2, INPUT);
Serial.begin(9600);
Serial.println("Solar Tracker Initializing (45-deg sensors)...");
stepperX.setSpeed(10);
stepperY.setSpeed(10);
stepperX.setMaxSpeed(MAX_SPEED_X);
stepperX.setAcceleration(ACCELERATION_X);
stepperY.setMaxSpeed(MAX_SPEED_Y);
stepperY.setAcceleration(ACCELERATION_Y);
turnDegrees(stepperX, 40);
Serial.println("Calibrating LDRs... Point sensor at reference light.");
delay(2000);
int ldrValue1 = readLDR(ldrPin1);
int ldrValue2 = readLDR(ldrPin2);
int valTL_cal = readLDR(LDR_PIN_TL);
int valTR_cal = readLDR(LDR_PIN_TR);
int valBL_cal = readLDR(LDR_PIN_BL);
int valBR_cal = readLDR(LDR_PIN_BR);
offset = ldrValue1 - ldrValue2;
}
// Calculate combined values for calibration
long sumLeft_cal = valTL_cal + valBL_cal;
long sumRight_cal = valTR_cal + valBR_cal;
offsetX_cal = sumLeft_cal - sumRight_cal;
void processCommand(String command)
{
stepperX.setSpeed(10);
stepperX.step(command.toInt() * stepsPerDegree);
Serial.println(command);
}
long sumTop_cal = valTL_cal + valTR_cal;
long sumBottom_cal = valBL_cal + valBR_cal;
offsetY_cal = sumTop_cal - sumBottom_cal;
void search()
{
turnDegrees(stepperX, 180);
delay(10);
turnDegrees(stepperY, 45);
delay(10);
turnDegrees(stepperX, -180);
delay(10);
turnDegrees(stepperY, 45);
delay(10);
// back to zero:
turnDegrees(stepperY, -90);
}
void search2()
{
turnDegrees(stepperX, 30);
delay(100);
turnDegrees(stepperY, 15);
delay(100);
turnDegrees(stepperX, 30);
delay(100);
turnDegrees(stepperY, 15);
delay(100);
turnDegrees(stepperX, 30);
delay(100);
turnDegrees(stepperY, 15);
delay(100);
turnDegrees(stepperX, 30);
delay(100);
turnDegrees(stepperY, 15);
delay(100);
turnDegrees(stepperX, 30);
delay(100);
turnDegrees(stepperY, 15);
delay(100);
turnDegrees(stepperX, 30);
delay(100);
turnDegrees(stepperY, 15);
delay(100);
turnDegrees(stepperX, -360);
delay(100);
// back to zero:
turnDegrees(stepperY, -90);
}
void track()
{
// compare sensors
// move towards strongest light signal
Serial.print("Calibration offsetX_cal: ");
Serial.println(offsetX_cal);
Serial.print("Calibration offsetY_cal: ");
Serial.println(offsetY_cal);
Serial.println("Setup Complete. Starting tracking loop.");
}
void loop()
{
int ldrValue1 = readLDR(ldrPin1);
int ldrValue2 = readLDR(ldrPin2);
// --- Read LDR Values ---
int valTL = readLDR(LDR_PIN_TL); // Top-Left
int valTR = readLDR(LDR_PIN_TR); // Top-Right
int valBL = readLDR(LDR_PIN_BL); // Bottom-Left
int valBR = readLDR(LDR_PIN_BR); // Bottom-Right
int diff = ldrValue1 - ldrValue2;
int diffOhneOffset = diff - offset;
// --- Calculate Combined Light for Sides ---
long sumLightLeft = valTL + valBL;
long sumLightRight = valTR + valBR;
long sumLightTop = valTL + valTR;
long sumLightBottom = valBL + valBR;
if (diffOhneOffset > 0)
// --- Calculate Differences (Error Signals) ---
// diffX_raw: Positive if more light on Left diagonal sum, Negative if more on Right
long diffX_raw = sumLightLeft - sumLightRight;
long errorX = diffX_raw - offsetX_cal; // Apply calibration
// diffY_raw: Positive if more light on Top diagonal sum, Negative if more on Bottom
long diffY_raw = sumLightTop - sumLightBottom;
long errorY = diffY_raw - offsetY_cal; // Apply calibration
if (errorX > errorY + 2 * TOLERANCE)
{
Serial.println("got here 1");
stepperX.setSpeed(10);
turnDegrees(stepperX, 40);
}
else
{
Serial.println("got here 2");
stepperX.setSpeed(10);
turnDegrees(stepperX, -40);
long stepAdjustmentX = -(long)(errorX * KP_X);
long newTargetX = stepperX.currentPosition() + stepAdjustmentX;
stepperX.moveTo(newTargetX);
}
Serial.print("LDR1: ");
Serial.print(ldrValue1);
Serial.print(" | LDR2: ");
Serial.println(ldrValue2);
Serial.print("Difference:");
Serial.println(diffOhneOffset);
// --- X-Axis (Horizontal) Control ---
if (abs(errorX) > TOLERANCE)
{
// Positive errorX means more light on the left side (TL+BL).
long stepAdjustmentX = -(long)(errorX * KP_X);
long newTargetX = stepperX.currentPosition() + stepAdjustmentX;
stepperX.moveTo(newTargetX);
}
delay(500);
// if (Serial.available() > 0) { // Check if data is available
// String command = Serial.readStringUntil('\n'); // Read input until newline
// command.trim(); // Remove any extra whitespace or newline characters
// processCommand(command); // Process the received command
// --- Y-Axis (Vertical) Control ---
if (abs(errorY) > TOLERANCE)
{
// Positive errorY means more light on the top side (TL+TR).
long stepAdjustmentY = (long)(errorY * KP_Y);
long newTargetY = stepperY.currentPosition() + stepAdjustmentY;
stepperY.moveTo(newTargetY);
}
// // Serial.println(command);
// }
// turnDegrees(stepperY, 180);
// search();
// turnDegrees(stepperX, 180);
// int light1 = analogRead(PHOTO_DIODE_1); // Read light intensity from PD1
// int light2 = analogRead(PHOTO_DIODE_2); // Read light intensity from PD2
// // Print in a format suitable for Arduino Serial Plotter
// Serial.print(light1);
// Serial.print(",");
// Serial.println(light2);
// delay(100); // Small delay for readability
// // Rotate CCW quickly at 10 RPM
// stepperX.setSpeed(10);
// stepperX.step(-stepsPerRevolution);
// delay(1000);
// // Rotate CCW quickly at 10 RPM
// stepperY.setSpeed(10);
// stepperY.step(stepsPerRevolution);
// delay(1000);
// --- Run Steppers ---
stepperX.run();
stepperY.run();
}