Compare commits

...

2 Commits
mo ... main

Author SHA1 Message Date
Benny
883e12542d final version (i hope) 2025-05-25 18:31:30 +02:00
Benny
864de6cbff it works 2025-05-23 10:01:07 +02:00
3 changed files with 127 additions and 99 deletions

17
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,17 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/home/benny/.platformio/packages/framework-arduino-avr/cores/arduino",
"/home/benny/.platformio/packages/toolchain-atmelavr/avr/include"
],
"defines": [],
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "linux-clang-x64"
}
],
"version": 4
}

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,123 +1,133 @@
// Includes the Arduino Stepper Library
#include <Stepper.h>
#include <Arduino.h>
#include <AccelStepper.h>
// Defines the number of steps per rotation
const int stepsPerRevolution = 4096;
#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
// TODO: fix rounding errors
// int stepsPerDegree = stepsPerRevolution / 360;
// const float stepsPerDegree = stepsPerRevolution / 360.0;
const float stepsPerDegree = 11;
// Initialize steppers
AccelStepper stepperX(AccelStepper::HALF4WIRE, 8, 10, 9, 11);
AccelStepper stepperY(AccelStepper::HALF4WIRE, 4, 6, 5, 7);
// 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);
// --- Configuration Constants ---
const int TOLERANCE = 30; // Combined tolerance for error signals.
// Proportional Gain (Kp): Increased for faster response, decrease if it overshoots
const float KP_X = 0.35;
const float KP_Y = 0.3;
// 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;
for (int i = 0; i < LDR_SAMPLES; i++)
{
sum += analogRead(pin);
if (LDR_DELAY_MS > 0)
{
delay(LDR_DELAY_MS);
}
}
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
stepperX.setSpeed(10);
stepperY.setSpeed(10);
}
Serial.begin(9600);
Serial.println("Solar Tracker Initializing (45-deg sensors)...");
void turnDegrees(Stepper stepper, int deg)
{
stepperX.setSpeed(10);
stepperY.setSpeed(10);
stepper.step(deg * stepsPerDegree);
}
stepperX.setMaxSpeed(MAX_SPEED_X);
stepperX.setAcceleration(ACCELERATION_X);
stepperY.setMaxSpeed(MAX_SPEED_Y);
stepperY.setAcceleration(ACCELERATION_Y);
void processCommand(String command)
{
stepperX.setSpeed(10);
stepperX.step(command.toInt() * stepsPerDegree);
Serial.println(command);
}
Serial.println("Calibrating LDRs... Point sensor at reference light.");
delay(2000);
void search()
{
turnDegrees(stepperX, 180);
delay(10);
turnDegrees(stepperY, 45);
delay(10);
turnDegrees(stepperX, -180);
delay(10);
turnDegrees(stepperY, 45);
delay(10);
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);
// back to zero:
turnDegrees(stepperY, -90);
}
// 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 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);
long sumTop_cal = valTL_cal + valTR_cal;
long sumBottom_cal = valBL_cal + valBR_cal;
offsetY_cal = sumTop_cal - sumBottom_cal;
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()
{
// --- 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
// 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
// --- Calculate Combined Light for Sides ---
long sumLightLeft = valTL + valBL;
long sumLightRight = valTR + valBR;
long sumLightTop = valTL + valTR;
long sumLightBottom = valBL + valBR;
// // Serial.println(command);
// }
// --- 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
turnDegrees(stepperY, 180);
// 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
// search();
// turnDegrees(stepperX, 180);
delay(100);
// // 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);
if (errorX > errorY + 2 * TOLERANCE)
{
long stepAdjustmentX = -(long)(errorX * KP_X);
long newTargetX = stepperX.currentPosition() + stepAdjustmentX;
stepperX.moveTo(newTargetX);
}
// --- 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);
}
// --- 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);
}
// --- Run Steppers ---
stepperX.run();
stepperY.run();
}