working demo (hopefully) + readme
This commit is contained in:
parent
60469f1a0f
commit
5943413731
433
Arduino-Satellite-Dish/src/README
Normal file
433
Arduino-Satellite-Dish/src/README
Normal file
@ -0,0 +1,433 @@
|
||||
# Arduino IR Tracker with Stepper Motors (Optimized)
|
||||
|
||||
**Version:** 2.2.2 (Production Ready Candidate)
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
**CRITICAL WARNINGS:**
|
||||
|
||||
> **1. HARDWARE VERIFICATION:** Failure to verify **ALL** pin assignments in the code's `SYSTEM CONFIGURATION & TUNING` section against your physical hardware **WILL** lead to malfunction or system halt. Default pins are provided but **MUST** be confirmed.
|
||||
>
|
||||
> **2. I2C PIN CONFLICT:** The default pins for the limit switches (`limitSwitchPinX = A4`, `limitSwitchPinY = A5`) directly conflict with the Arduino Uno's I2C pins (SDA/SCL). If you plan to use **ANY** I2C devices (displays, sensors, etc.) with this project, you **MUST** change `limitSwitchPinX` and `limitSwitchPinY` to other unused digital or analog pins in the configuration block.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Overview](#overview)
|
||||
2. [Features](#features)
|
||||
3. [Hardware Requirements](#hardware-requirements)
|
||||
4. [Wiring Instructions](#wiring-instructions)
|
||||
- [Stepper Motors & Drivers](#stepper-motors--drivers)
|
||||
- [IR Sensors](#ir-sensors)
|
||||
- [Limit Switches](#limit-switches)
|
||||
- [Status LEDs](#status-leds)
|
||||
- [Power Supply](#power-supply)
|
||||
5. [Software Setup](#software-setup)
|
||||
- [Dependencies](#dependencies)
|
||||
- [Flashing](#flashing)
|
||||
6. [Code Configuration](#code-configuration)
|
||||
- [Build Mode](#build-mode)
|
||||
- [Pin Definitions](#pin-definitions)
|
||||
- [Motor & Movement Parameters](#motor--movement-parameters)
|
||||
- [Tracking Control (P-Controller)](#tracking-control-p-controller)
|
||||
- [Local Search Parameters](#local-search-parameters)
|
||||
- [Timing Parameters](#timing-parameters)
|
||||
- [Stall Detection Parameters](#stall-detection-parameters)
|
||||
7. [Software Overview](#software-overview)
|
||||
- [Core Loop](#core-loop)
|
||||
- [State Machine](#state-machine)
|
||||
- [Key Algorithms](#key-algorithms)
|
||||
- [Optimizations](#optimizations)
|
||||
- [Coordinate System](#coordinate-system)
|
||||
8. [**CRITICAL: Tuning Guide**](#critical-tuning-guide)
|
||||
- [Methodology](#methodology)
|
||||
- [Tuning Order](#tuning-order)
|
||||
- [1. Speeds & Acceleration](#1-speeds--acceleration)
|
||||
- [2. Proportional Control (Kp & Deadband)](#2-proportional-control-kp--deadband)
|
||||
- [3. Stall Detection](#3-stall-detection)
|
||||
- [4. Timings & Local Search](#4-timings--local-search)
|
||||
9. [Troubleshooting](#troubleshooting)
|
||||
10. [Future Improvements](#future-improvements)
|
||||
11. [License](#license)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
This project implements firmware for an Arduino Uno to control a 2-axis (Pan/Tilt) platform equipped with stepper motors. Its primary goal is to automatically track a moving infrared (IR) light source using an array of five IR sensors (Left, Right, Up, Down, Center).
|
||||
|
||||
The system performs automatic homing using limit switches, searches for the IR signal using sweep patterns, tracks the signal using Proportional (P) control logic, and attempts to re-acquire the signal using a local search pattern if it's lost. The code is optimized for performance on the resource-constrained Arduino Uno, utilizing direct port I/O for faster input reading and LED updates, and fixed-point arithmetic for the control calculations.
|
||||
|
||||
This firmware is designed for platforms using 28BYJ-48 stepper motors driven by ULN2003 driver boards and common active-LOW IR receiver modules (like TSOP series).
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
- **2-Axis Stepper Control:** Drives two stepper motors (e.g., 28BYJ-48) via ULN2003 drivers using the `AccelStepper` library for smooth acceleration and non-blocking operation.
|
||||
- **Automatic Homing:** Uses limit switches on both axes to establish a known starting position (0,0).
|
||||
- **IR Signal Tracking:** Employs 5 active-LOW IR sensors (L, R, U, D, C) to detect the direction of an IR source.
|
||||
- **Proportional (P) Control:** Uses fixed-point P-control logic to smoothly move the platform towards the detected IR signal for tracking.
|
||||
- **Sweep Search:** Performs a configurable wide-angle sweep pattern across both axes if the signal is not initially detected.
|
||||
- **Local Search:** Initiates a multi-phase local search pattern (probe -> perpendicular sweep -> expanding box) if the signal is lost during tracking, attempting re-acquisition.
|
||||
- **Stall Detection:** Includes a safety feature to detect if a motor is commanded to move but fails to do so (indicating a stall or obstruction), triggering an error state.
|
||||
- **State Machine Logic:** Organizes functionality into distinct states (Homing, Sweeping, Centering, Tracking, Local Search, Error, etc.) for robust control flow.
|
||||
- **Status LEDs:** Provides visual feedback on the current system state (Searching, Tracking, Lost/Error) via LEDs.
|
||||
- **Performance Optimizations:** Utilizes direct port manipulation for faster I/O and fixed-point math for control calculations, crucial for Arduino Uno performance.
|
||||
- **Highly Configurable:** Allows tuning of speeds, acceleration, P-control gains, deadbands, search patterns, timings, and pin assignments via constants in the code.
|
||||
- **Debug/Production Builds:** Supports conditional compilation to enable/disable Serial output for debugging or maximum performance.
|
||||
|
||||
---
|
||||
|
||||
## Hardware Requirements
|
||||
|
||||
1. **Microcontroller:** Arduino Uno R3 (or compatible ATmega328P-based board).
|
||||
2. **Stepper Motors:** 2 x 28BYJ-48 5V Stepper Motors (or similar, ensure `stepsPerRevolution` is adjusted if different).
|
||||
3. **Stepper Motor Drivers:** 2 x ULN2003 Driver Boards (or equivalent darlington array driver).
|
||||
4. **IR Sensors:** 5 x Active-LOW IR Receiver Modules (e.g., TSOP38238, TSOP4838, VS1838B). Must output LOW when IR is detected. Ensure they operate at the correct voltage (usually 3.3V or 5V).
|
||||
5. **Limit Switches:** 2 x Mechanical Limit Switches (Microswitches preferred). Configuration assumes Normally Open (NO) wiring connected to GND and Signal pins (Active LOW when pressed).
|
||||
6. **Status LEDs:** 3 x Standard LEDs (e.g., Red, Yellow, Green) with appropriate current-limiting resistors (e.g., 220-330 Ohm for 5V).
|
||||
7. **Power Supply:**
|
||||
- **CRITICAL:** A stable **external 5V power supply** capable of providing sufficient current for **both** stepper motors running simultaneously (e.g., 1A-2A minimum, depending on motor draw). **Do not** attempt to power the motors directly from the Arduino's 5V pin or USB, as this will cause instability and potentially damage the Arduino.
|
||||
- The Arduino itself can be powered via USB or a separate 7-12V supply into the VIN pin/barrel jack.
|
||||
8. **Jumper Wires & Breadboard (Optional):** For connections.
|
||||
9. **Pan/Tilt Mechanism:** A physical structure to mount the motors, sensors, and Arduino.
|
||||
|
||||
---
|
||||
|
||||
## Wiring Instructions
|
||||
|
||||
**IMPORTANT:** Double-check all connections before applying power. Refer to the `Pin Definitions` section in the code configuration and verify these defaults match your wiring.
|
||||
|
||||
### Stepper Motors & Drivers
|
||||
|
||||
- Connect the 28BYJ-48 motor connector to the output connector on its corresponding ULN2003 board.
|
||||
- Connect the ULN2003 board's VCC/+ and GND/- pins to your **external 5V power supply**.
|
||||
- Connect the ULN2003 board's IN1, IN2, IN3, IN4 pins to the Arduino pins defined for the respective motor (X or Y).
|
||||
- **X-Axis Motor (Defaults):**
|
||||
- ULN2003 IN1 -> Arduino D8 (`stepperX_pin1`)
|
||||
- ULN2003 IN2 -> Arduino D10 (`stepperX_pin2`)
|
||||
- ULN2003 IN3 -> Arduino D9 (`stepperX_pin3`)
|
||||
- ULN2003 IN4 -> Arduino D11 (`stepperX_pin4`)
|
||||
- _(Note the AccelStepper library sequence P1,P3,P2,P4)_
|
||||
- **Y-Axis Motor (Defaults):**
|
||||
- ULN2003 IN1 -> Arduino D4 (`stepperY_pin1`)
|
||||
- ULN2003 IN2 -> Arduino D6 (`stepperY_pin2`)
|
||||
- ULN2003 IN3 -> Arduino D5 (`stepperY_pin3`)
|
||||
- ULN2003 IN4 -> Arduino D7 (`stepperY_pin4`)
|
||||
- _(Note the AccelStepper library sequence P1,P3,P2,P4)_
|
||||
|
||||
### IR Sensors
|
||||
|
||||
- Connect the VCC pin of each sensor to Arduino 5V (or 3.3V if required by the sensor module).
|
||||
- Connect the GND pin of each sensor to Arduino GND.
|
||||
- Connect the OUT/Signal pin of each sensor to the corresponding Arduino digital input pin:
|
||||
- Left Sensor OUT -> Arduino D2 (`sensorPinL`)
|
||||
- Right Sensor OUT -> Arduino D3 (`sensorPinR`)
|
||||
- Up Sensor OUT -> Arduino D12 (`sensorPinU`)
|
||||
- Down Sensor OUT -> Arduino D13 (`sensorPinD`)
|
||||
- Center Sensor OUT -> Arduino A0 (`sensorPinC`)
|
||||
|
||||
### Limit Switches
|
||||
|
||||
- The code assumes Active LOW switches connected between the Arduino pin and GND.
|
||||
- Connect one terminal of the switch (usually COM - Common) to Arduino GND.
|
||||
- Connect the **Normally Open (NO)** terminal of the switch to the corresponding Arduino digital input pin. (The internal pull-up resistor on the Arduino pin will keep it HIGH until the switch is pressed, pulling it LOW).
|
||||
- X-Axis Limit Switch (NO) -> Arduino A4 (`limitSwitchPinX`) **(!!! I2C CONFLICT !!!)**
|
||||
- Y-Axis Limit Switch (NO) -> Arduino A5 (`limitSwitchPinY`) **(!!! I2C CONFLICT !!!)**
|
||||
- _(If using Normally Closed (NC) contacts, you'll need to connect COM to 5V, NC to the pin, and potentially disable the internal pull-up and invert the logic in `readInputsOptimized`)_.
|
||||
|
||||
### Status LEDs
|
||||
|
||||
- Connect the **Anode** (longer lead) of each LED to the corresponding Arduino digital output pin _through_ its current-limiting resistor (e.g., 220 Ohm).
|
||||
- Connect the **Cathode** (shorter lead, flat side) of each LED to Arduino GND.
|
||||
- Searching LED Anode (+ resistor) -> Arduino A1 (`ledPinSearching`)
|
||||
- Tracking LED Anode (+ resistor) -> Arduino A2 (`ledPinTracking`)
|
||||
- Lost/Error LED Anode (+ resistor) -> Arduino A3 (`ledPinLost`)
|
||||
|
||||
### Power Supply
|
||||
|
||||
- Connect the **External 5V Power Supply Positive (+)** output to the VCC/+ pins of **both** ULN2003 driver boards.
|
||||
- Connect the **External 5V Power Supply Ground (-)** output to the GND/- pins of **both** ULN2003 driver boards **AND** to one of the Arduino GND pins. **This common ground connection is essential!**
|
||||
- Power the Arduino board itself via its USB port or a separate 7-12V supply connected to the VIN pin or barrel jack.
|
||||
|
||||
---
|
||||
|
||||
## Software Setup
|
||||
|
||||
### Dependencies
|
||||
|
||||
1. **Arduino IDE** or **PlatformIO:** Install your preferred development environment.
|
||||
2. **AccelStepper Library:** This library is required.
|
||||
- **Arduino IDE:** Go to `Sketch` -> `Include Library` -> `Manage Libraries...`. Search for "AccelStepper" by Mike McCauley and install it.
|
||||
- **PlatformIO:** Add `AccelStepper` to the `lib_deps` list in your `platformio.ini` file (e.g., `lib_deps = mikemccauley/AccelStepper @ ^1.61`). PlatformIO will usually install it automatically on build.
|
||||
|
||||
### Flashing
|
||||
|
||||
1. **Download/Clone:** Get the project code (`IR_Tracker_Optimized_ProdReady.ino` or similar).
|
||||
2. **Configure:** **CRITICALLY REVIEW AND EDIT** the parameters in the `SYSTEM CONFIGURATION & TUNING` section of the code, especially the `Pin Definitions`, to match your exact hardware wiring. Resolve the I2C conflict if necessary.
|
||||
3. **Open:** Load the `.ino` file in your Arduino IDE or open the project folder in PlatformIO.
|
||||
4. **Select Board & Port:**
|
||||
- **Arduino IDE:** Go to `Tools` -> `Board` and select "Arduino Uno". Go to `Tools` -> `Port` and select the correct serial port for your connected Arduino.
|
||||
- **PlatformIO:** Ensure your `platformio.ini` specifies `board = uno`. PlatformIO usually auto-detects the port.
|
||||
5. **Upload:**
|
||||
- **Arduino IDE:** Click the "Upload" button (right arrow icon).
|
||||
- **PlatformIO:** Use the "Upload" task (e.g., click the alien head icon in the VS Code status bar and select `PlatformIO: Upload`).
|
||||
6. **Monitor (Optional):** If `DEBUG_BUILD` is defined in the code, open the Serial Monitor (Arduino IDE: `Tools` -> `Serial Monitor`; PlatformIO: `PlatformIO: Serial Monitor` task) and set the baud rate to **115200**. You should see startup messages and telemetry data.
|
||||
|
||||
---
|
||||
|
||||
## Code Configuration
|
||||
|
||||
All user-configurable parameters are located at the top of the `.ino` file within the `SYSTEM CONFIGURATION & TUNING` section. **Tuning these values is essential for proper operation.**
|
||||
|
||||
### Build Mode
|
||||
|
||||
- `#define DEBUG_BUILD`: Uncomment this line to enable detailed `Serial` output for debugging, state changes, and telemetry. Comment it out for a production build (disables most `Serial` calls for maximum performance and reduced code size).
|
||||
|
||||
### Pin Definitions
|
||||
|
||||
- `stepperX_pin1`, `stepperX_pin3`, `stepperX_pin2`, `stepperX_pin4`: Arduino pins connected to the X-axis ULN2003 driver (IN1, IN3, IN2, IN4 respectively due to AccelStepper).
|
||||
- `stepperY_pin1`, `stepperY_pin3`, `stepperY_pin2`, `stepperY_pin4`: Arduino pins connected to the Y-axis ULN2003 driver.
|
||||
- `sensorPinL`, `sensorPinR`, `sensorPinU`, `sensorPinD`, `sensorPinC`: Arduino pins connected to the respective IR sensor output pins.
|
||||
- `limitSwitchPinX`, `limitSwitchPinY`: Arduino pins connected to the limit switches. **WARNING: Defaults A4/A5 conflict with I2C!**
|
||||
- `ledPinSearching`, `ledPinTracking`, `ledPinLost`: Arduino pins connected to the status LEDs (via resistors).
|
||||
|
||||
### Motor & Movement Parameters
|
||||
|
||||
- `stepsPerRevolution`: Total steps for one full 360° motor rotation (2038 for 28BYJ-48 in half-step mode).
|
||||
- `homingSpeed`, `homingAcceleration`: Speed/acceleration during the homing sequence. Must be reliable enough to trigger switches without stalling.
|
||||
- `sweepSpeedDefault`, `sweepAccelerationDefault`: Speed/acceleration during the wide-angle sweep search. Can be faster than homing/tracking if the motors handle it.
|
||||
- `trackSpeedDefault`, `trackAccelerationDefault`: Base speed/acceleration used during centering and tracking adjustments. Higher values react faster but may overshoot.
|
||||
- `localSearchSpeed`, `localSearchAccel`: Speed/acceleration during the local search patterns. Often slower for more precise small movements.
|
||||
- `searchRangeX_deg`, `searchRangeY_deg`: Maximum range (in degrees) the system will sweep during the initial search.
|
||||
- `postHomingMoveOffSwitchSteps`: Small number of steps to move away from the limit switch immediately after it's triggered during homing. Prevents sitting directly on the switch.
|
||||
- `HOMING_OVERSHOOT_MULTIPLIER`: Used internally to calculate the initial large move distance during homing to ensure the switch is definitely hit.
|
||||
|
||||
### Tracking Control (P-Controller)
|
||||
|
||||
- `Kp_X_float`, `Kp_Y_float`: **CRITICAL TUNING PARAMETERS.** Proportional gain for each axis. Determines how strongly the system reacts to tracking errors. Start low (e.g., 5.0-10.0) and increase carefully. Too high causes oscillation/overshoot; too low causes sluggish response/loss of target.
|
||||
- `trackingDeadband_steps`: **CRITICAL TUNING PARAMETER.** A zone (in steps) around the target position where small errors are ignored. Prevents jitter/hunting when centered. Too high makes centering less precise; too low causes constant small adjustments.
|
||||
|
||||
### Local Search Parameters
|
||||
|
||||
- `localSearchProbeSteps`: Initial distance (steps) to move in the last known direction of the target when signal is lost. Tune based on sensor beam width and expected target speed.
|
||||
- `localSearchSweepSteps`: Distance (steps) for the perpendicular sweeps in the local search cross pattern.
|
||||
- `localSearchBoxStepSize`: Step size for each leg of the expanding box pattern.
|
||||
- `localSearchMaxCycles`: Number of full box layers to attempt before giving up local search and reverting to a full sweep.
|
||||
|
||||
### Timing Parameters
|
||||
|
||||
- `debounceDelayMs`, `limitSwitchDebounceMs`: Software debounce time for sensors and switches to filter out noise/bouncing. Increase if inputs seem flaky.
|
||||
- `signalLostTimeoutMs`: Duration (ms) the system will wait in TRACKING state without any sensor input before declaring the signal lost and entering LOCAL_SEARCH.
|
||||
- `searchFailDelayMs`: Delay (ms) before retrying a full sweep after completing one without finding the signal (`SEARCH_FAILED` state).
|
||||
- `stateTimeoutMs`, `homingTimeoutMs`, `localSearchTimeoutMs`: Safety timeouts (ms) for specific states to prevent the system from getting stuck indefinitely. Triggers an error if exceeded.
|
||||
- `telemetryIntervalMs`: How often (ms) telemetry data is printed to Serial (if `ENABLE_TELEMETRY` is active).
|
||||
- `postHomingPauseMs`: Brief pause (ms) after successful homing before starting the first search sweep.
|
||||
|
||||
### Stall Detection Parameters
|
||||
|
||||
- `stallCheckIntervalMs`: How frequently (ms) the code checks for potential motor stalls.
|
||||
- `stallTimeoutThresholdMs`: Duration (ms) a motor must appear stuck (not moving despite being commanded) before a stall error is triggered.
|
||||
- `stallPositionTolerance`: Minimum number of steps the motor position must change between checks to be considered _not_ stalled. Increase slightly if getting false positives during slow moves or vibration.
|
||||
|
||||
---
|
||||
|
||||
## Software Overview
|
||||
|
||||
### Core Loop
|
||||
|
||||
The `loop()` function performs the essential tasks repeatedly:
|
||||
|
||||
1. **`stepperX.run()` / `stepperY.run()`:** Calls the AccelStepper library functions to manage motor stepping, acceleration, and non-blocking movement based on current targets. **This is critical and must be called frequently.**
|
||||
2. **`readInputsOptimized()`:** Reads the state of all IR sensors and limit switches using direct port I/O and applies software debouncing. Updates global state variables (`sensorActive[]`, `limitSwitchActiveX/Y`).
|
||||
3. **Update `lastSignalTime`:** If in TRACKING or CENTERING state and a sensor is active, updates the timestamp of the last known signal detection.
|
||||
4. **`handleStateMachine()`:** The core logic router. Based on the `currentState`, it calls the appropriate function or performs actions for that state (e.g., `handleHomingStates`, `handleTrackingLogicFixedPoint`, `handleLocalSearch`).
|
||||
5. **`updateStatusLEDsOptimized()`:** Sets the status LEDs according to the `currentState` using direct port I/O.
|
||||
6. **`checkMotorStall()`:** Periodically checks if motors appear stalled.
|
||||
7. **`checkStateTimeouts()`:** Checks if certain states have run longer than their allowed safety timeout.
|
||||
8. **`printTelemetry()`:** (Conditional) Prints status information to the Serial Monitor at regular intervals if `ENABLE_TELEMETRY` is defined.
|
||||
|
||||
### State Machine
|
||||
|
||||
The system operates based on a finite state machine (`enum class State`). This ensures predictable behavior and handles different operational modes cleanly. The primary states and transitions are:
|
||||
|
||||
- **INITIALIZING -> CHECK_PIN_CONFLICTS:** Initial power-up state.
|
||||
- **CHECK_PIN_CONFLICTS -> HOMING_X:** After setup and pin checks.
|
||||
- **HOMING_X -> POST_HOMING_MOVE_OFF_X -> HOMING_Y -> POST_HOMING_MOVE_OFF_Y -> POST_HOMING_DELAY:** Sequence to home both axes using limit switches.
|
||||
- **POST_HOMING_DELAY -> SWEEP_X:** Homing complete, start searching.
|
||||
- **SWEEP_X:** Sweeps the X-axis back and forth.
|
||||
- If signal found -> **CENTERING**
|
||||
- If full X sweep complete (no signal) -> **SWEEP_Y**
|
||||
- **SWEEP_Y:** Sweeps the Y-axis back and forth.
|
||||
- If signal found -> **CENTERING**
|
||||
- If full Y sweep complete (no signal) -> **SEARCH_FAILED**
|
||||
- **CENTERING:** Signal detected, performing fine adjustments to center the target using tracking logic.
|
||||
- If move completes and signal still present -> **TRACKING**
|
||||
- If move completes and signal lost -> **LOCAL_SEARCH**
|
||||
- **TRACKING:** Continuously adjusts position to keep the signal centered using tracking logic.
|
||||
- If signal lost (timeout) -> **LOCAL_SEARCH**
|
||||
- **LOCAL_SEARCH:** Signal lost during tracking, executing probe/sweep/box patterns to re-acquire.
|
||||
- If signal re-acquired -> **CENTERING**
|
||||
- If local search times out or exhausts patterns -> **SWEEP_X** (restart full search)
|
||||
- **SEARCH_FAILED:** Full sweep completed without finding signal. Pauses, then restarts search -> **SWEEP_X**.
|
||||
- **(Any State) -> ERROR:** Triggered by fatal errors (stall detected, safety timeout, config error). System halts.
|
||||
|
||||
### Key Algorithms
|
||||
|
||||
- **Fixed-Point P-Control (`handleTrackingLogicFixedPoint`)**: Calculates an error value based on which IR sensors are active. This error (represented as a small integer) is multiplied by a pre-scaled gain (`Kp_X/Y_scaled`) using integer math. The result is scaled back down (using bit-shifting) to determine the number of steps to move. A deadband ignores very small calculated moves.
|
||||
- **Local Search (`handleLocalSearch`)**: A multi-phase strategy:
|
||||
1. _Probe:_ Moves a short distance in the direction the target was last seen.
|
||||
2. _Sweep:_ Performs a cross-pattern sweep perpendicular to the last known direction.
|
||||
3. _Box:_ If the above fail, executes an expanding square spiral pattern.
|
||||
- **Direct Port I/O (`readInputsOptimized`, `updateStatusLEDsOptimized`)**: Reads multiple input pins or writes multiple output pins belonging to the same AVR port (PORTB, PORTC, PORTD) in a single operation using bit masks, significantly faster than multiple `digitalRead`/`digitalWrite` calls.
|
||||
|
||||
### Optimizations
|
||||
|
||||
- **Non-Blocking Stepper Control:** `AccelStepper` library handles movement without blocking the main loop.
|
||||
- **Direct Port I/O:** Faster reading of sensors/switches and writing to LEDs.
|
||||
- **Fixed-Point Math:** Avoids slow floating-point calculations in the time-critical tracking loop.
|
||||
- **Conditional Serial Output:** `Serial` printing is computationally expensive; disabling it via `DEBUG_BUILD` provides a significant performance boost.
|
||||
- **`F()` Macro / PROGMEM:** Stores constant strings in Flash memory instead of RAM.
|
||||
- **Optimized Data Types:** Uses smallest appropriate data types (`uint8_t`, etc.) where possible.
|
||||
- **Inlining:** Suggests inlining for small utility functions.
|
||||
|
||||
### Coordinate System
|
||||
|
||||
- **Origin (0, 0):** Defined by the limit switches during homing. Typically the bottom-left or top-left corner depending on switch placement and motor direction.
|
||||
- **X-Axis:** Positive steps generally move the platform Right. Negative steps move Left.
|
||||
- **Y-Axis:** Positive steps generally move the platform Down. Negative steps move Up.
|
||||
_(Note: This depends on motor wiring and mounting. If movement is inverted, you might need to reverse the motor direction logic or simply invert the sign in the P-control calculations if that's easier.)_
|
||||
|
||||
---
|
||||
|
||||
## **CRITICAL: Tuning Guide**
|
||||
|
||||
**This system WILL NOT WORK correctly or reliably without careful tuning.** Default values are starting points ONLY and are unlikely to be optimal for your specific hardware (motors, power supply, mechanism friction, sensor spacing, IR source characteristics).
|
||||
|
||||
### Methodology
|
||||
|
||||
1. **Patience:** Tuning takes time and observation.
|
||||
2. **One Parameter at a Time:** Change only _one_ value, upload, test its effect, then decide on the next change. Changing multiple values makes it impossible to know what caused an improvement or regression.
|
||||
3. **Observe & Listen:** Watch the physical movement. Is it smooth? Jerky? Does it overshoot? Listen to the motors. Do they sound strained or skip steps (clicking noise)?
|
||||
4. **Use Serial Monitor (with `DEBUG_BUILD`):** Enable `DEBUG_BUILD` during tuning. The telemetry output (`TLM: ...`) provides valuable information about the current state, position, and sensor readings.
|
||||
5. **Start Conservatively:** Begin with lower speeds, accelerations, and Kp values, then gradually increase them.
|
||||
|
||||
### Tuning Order
|
||||
|
||||
Follow this general order for best results:
|
||||
|
||||
1. **Speeds & Acceleration:** Find the physical limits of your motors and mechanism.
|
||||
2. **Proportional Control (Kp & Deadband):** Tune the tracking responsiveness and stability. This is the most critical part for tracking performance.
|
||||
3. **Stall Detection:** Fine-tune the safety net once movement is generally reliable.
|
||||
4. **Timings & Local Search:** Adjust timeouts and search patterns based on observed performance.
|
||||
|
||||
### 1. Speeds & Acceleration
|
||||
|
||||
- **Goal:** Find the highest `...Speed...` and `...Acceleration...` values your motors can reliably handle without stalling (buzzing without turning) or skipping steps under load.
|
||||
- **Parameters:** `homingSpeed`, `homingAcceleration`, `sweepSpeedDefault`, `sweepAccelerationDefault`, `trackSpeedDefault`, `trackAccelerationDefault`, `localSearchSpeed`, `localSearchAccel`.
|
||||
- **Testing:**
|
||||
- Start with low values (e.g., Speed=300, Accel=300).
|
||||
- Trigger a long move (like the initial sweep after homing). Listen carefully.
|
||||
- Gradually increase Speed first. If it stalls, reduce speed and try increasing Acceleration. Sometimes higher acceleration helps overcome initial friction, but too high also causes stalls.
|
||||
- Find the maximum reliable values for sweep/homing first. `trackSpeed` can often be slightly lower for smoother fine adjustments. `localSearchSpeed` is usually slower still.
|
||||
- **Symptoms:**
|
||||
- _Too High:_ Motors stall, buzz, vibrate heavily, skip steps (lose position accuracy).
|
||||
- _Too Low:_ Movement is unnecessarily slow.
|
||||
|
||||
### 2. Proportional Control (Kp & Deadband)
|
||||
|
||||
- **Goal:** Achieve smooth, responsive tracking that centers accurately without oscillation (shaking) or excessive jitter.
|
||||
- **Parameters:** `Kp_X_float`, `Kp_Y_float`, `trackingDeadband_steps`.
|
||||
- **Testing:**
|
||||
- Get the system into the `TRACKING` state (have it find and lock onto the IR source).
|
||||
- Slowly move the IR source side-to-side and up-and-down across the sensors.
|
||||
- Observe how the platform reacts.
|
||||
- **Start with `Kp` LOW (e.g., 5.0-10.0)** and `trackingDeadband_steps` relatively low (e.g., 2-5).
|
||||
- **Symptoms & Adjustments:**
|
||||
- **Oscillation/Shaking:** Target bounces back and forth past the center. -> **Decrease `Kp_float`** for the relevant axis.
|
||||
- **Overshooting:** Moves quickly past the center, then corrects back. -> **Decrease `Kp_float`**. Possibly increase `trackAccelerationDefault` if the overshoot happens _during_ deceleration (less common).
|
||||
- **Sluggish/Slow Response:** Takes a long time to center, might lose target easily if it moves quickly. -> **Increase `Kp_float`** slowly. Ensure `trackSpeedDefault` is adequate.
|
||||
- **Jitter/Hunting when Centered:** Constantly making tiny movements back and forth even when the target seems centered. -> **Increase `trackingDeadband_steps`**. `Kp_float` might also be slightly too high.
|
||||
- **Large Dead Zone:** Target has to move significantly off-center before the platform reacts. -> **Decrease `trackingDeadband_steps`**.
|
||||
- **Note:** Kp and Deadband interact. You may need to adjust both iteratively. Tuning Kp is usually the primary focus.
|
||||
|
||||
### 3. Stall Detection
|
||||
|
||||
- **Goal:** Reliably detect genuine motor stalls without triggering falsely during normal, possibly slow or jerky, operation.
|
||||
- **Parameters:** `stallCheckIntervalMs`, `stallTimeoutThresholdMs`, `stallPositionTolerance`.
|
||||
- **Testing:**
|
||||
- Operate the system normally after tuning speeds and P-control.
|
||||
- If you get unexpected "Stall Detected" errors during normal moves:
|
||||
- Try increasing `stallTimeoutThresholdMs` (gives it more time to recover).
|
||||
- Try increasing `stallPositionTolerance` slightly (allows for more vibration/tiny movements).
|
||||
- Less likely, slightly increase `stallCheckIntervalMs`.
|
||||
- If you physically stall a motor (carefully!) and it's _not_ detected:
|
||||
- Decrease `stallTimeoutThresholdMs`.
|
||||
- Ensure `stallPositionTolerance` is not too high.
|
||||
- Verify your `...Speed...` and `...Acceleration...` values aren't simply too high, causing the stall in the first place (see Step 1).
|
||||
- **Note:** This is a safety net. Frequent stalls usually mean speeds/accel are too high or there's a mechanical issue.
|
||||
|
||||
### 4. Timings & Local Search
|
||||
|
||||
- **Goal:** Optimize how the system handles signal loss and searching based on your environment and IR source.
|
||||
- **Parameters:** `signalLostTimeoutMs`, `localSearch...` parameters, `searchFailDelayMs`.
|
||||
- **Testing:**
|
||||
- Observe behavior when the IR signal is temporarily blocked or moves out of range.
|
||||
- If it enters `LOCAL_SEARCH` too quickly for brief dropouts -> Increase `signalLostTimeoutMs`.
|
||||
- If `LOCAL_SEARCH` fails to re-acquire a nearby target -> Adjust `localSearchProbeSteps`, `localSearchSweepSteps`, `localSearchBoxStepSize`. Make steps larger if the target might have moved further; smaller for finer searching. Consider increasing `localSearchMaxCycles`.
|
||||
- If `LOCAL_SEARCH` takes too long before giving up -> Decrease `localSearchTimeoutMs` or `localSearchMaxCycles`.
|
||||
- Adjust `searchFailDelayMs` based on how long you want to wait before a full retry after a failed search.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **No Serial Output:**
|
||||
- Ensure `DEBUG_BUILD` is uncommented in the code.
|
||||
- Verify Serial Monitor baud rate is set to 115200.
|
||||
- Check Arduino connection, port selection in IDE/PlatformIO.
|
||||
- Check Arduino power.
|
||||
- **System Doesn't Start / No LEDs:**
|
||||
- Check Arduino power supply (USB or VIN).
|
||||
- Check wiring, especially power and ground connections.
|
||||
- **Motors Buzz/Vibrate, Don't Turn:**
|
||||
- **Insufficient Power:** External 5V supply cannot provide enough current for the motors. Use a higher current rating supply.
|
||||
- **Wiring Error:** Double-check ULN2003 IN1-4 connections to Arduino pins match the code _exactly_. Order matters! Check motor connector is fully seated.
|
||||
- **Speed/Acceleration Too High:** Lower the `...Speed...` and `...Acceleration...` values significantly and try again.
|
||||
- **Mechanical Binding:** Ensure the platform moves freely by hand.
|
||||
- **Homing Fails:**
|
||||
- **Switch Not Triggered:** Check limit switch wiring (GND to COM, Arduino Pin to NO). Check physical actuation. Decrease `homingSpeed` if moving too fast past switch. Increase `HOMING_OVERSHOOT_MULTIPLIER` move if it stops short. Check `homingTimeoutMs`.
|
||||
- **Doesn't Move Off Switch:** Increase `postHomingMoveOffSwitchSteps`. Check switch isn't stuck. Verify switch logic is Active LOW in code (`readInputsOptimized`).
|
||||
- **Tracking Issues (Oscillation, Sluggish, Jitter):**
|
||||
- See the **Proportional Control (Kp & Deadband)** tuning section above. This requires careful adjustment.
|
||||
- **False Stall Detection:**
|
||||
- See the **Stall Detection** tuning section above. Adjust timeouts and tolerance. Check speeds/mechanics.
|
||||
- **Stall Not Detected:**
|
||||
- See the **Stall Detection** tuning section. Decrease timeout. Verify speeds aren't too high.
|
||||
- **I2C Devices Not Working:**
|
||||
- **PIN CONFLICT!** You are likely using limit switches on A4/A5. You **MUST** change the `limitSwitchPinX` and `limitSwitchPinY` definitions in the code to unused pins and rewire accordingly.
|
||||
- **Movement Direction Reversed:**
|
||||
- Easiest fix: In `handleTrackingLogicFixedPoint`, invert the sign of the calculated `stepsToMoveX` or `stepsToMoveY` if only one axis is reversed. Alternatively, physically reverse the connection order for the problematic motor on the ULN2003 board (e.g., swap IN1<->IN4, IN2<->IN3) or reverse the motor connector itself if possible.
|
||||
|
||||
---
|
||||
|
||||
## Future Improvements
|
||||
|
||||
- **Smoother Acceleration Profiles:** Implement S-curve acceleration instead of linear acceleration (AccelStepper might support this or require modification/alternative library).
|
||||
- **PID Control:** Replace the P-controller with a full PID (Proportional-Integral-Derivative) controller for potentially better handling of overshoot and steady-state error, though tuning becomes more complex.
|
||||
- **Adaptive Tuning:** Implement logic to adjust Kp or other parameters dynamically based on performance.
|
||||
- **Improved Sensor Filtering:** Use more advanced digital filtering techniques on sensor readings if noise is an issue.
|
||||
- **Web Interface/Remote Control:** Add an ESP8266 or ESP32 for Wi-Fi connectivity, allowing remote monitoring, control, and tuning via a web interface.
|
||||
- **Support for Different Hardware:** Abstract hardware interactions (pin definitions, sensor reading logic) to make porting to different microcontrollers or sensors easier.
|
||||
- **Obstacle Avoidance:** Integrate distance sensors to prevent collisions.
|
||||
- **Target Prediction:** Implement basic prediction algorithms (e.g., Kalman filter) if tracking fast-moving targets.
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file (if included) or the link below for details.
|
||||
|
||||
[https://opensource.org/licenses/MIT](https://opensource.org/licenses/MIT)
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user