This code should enable current sensing for the motors,setting of current stall value, setting the current sense resistor value and the voltage reference. It will also be possible to write statistics to a sd card file if there's a GPS or time server available. It's written by chatgpt because I have severe problems coding due to dyscalculia, and that also affects programming. The chips used is 2X DRV8251A. You can find the stall current by disconnecting the motor and measuring the winding resistance. Turn the motor by hand looking for the lowest resistance. The stall current is the applied voltage divided by the (lowest) winding resistance. The code will be organized as follows: 1. Current Sensing and Stall Detection Subroutine: Detects if azimuth or elevation motors have stalled based on a configurable current value and time limit. 2. SD Card Logging: Logs current data to an SD card with timestamps in UTC+0 when available, using GPS or a time server. 3. Placement of Code Snippets: Clearly specifies where each code section should be placed in files like rotator_features.h and k3ng_rotator_controller.ino. Part 1: Current Sensing and Stall Detection 1.1 Code Snippets for Current Sensing Configurations in rotator_features.h Add the following lines to define configurable parameters for current sensing, time limits, and the default settings for stall detection: // Current sensing configuration values #define DEFAULT_VREF 3.3 // Default reference voltage in volts #define DEFAULT_RIPROPI 1300 // RIPROPI resistor value in ohms #define DEFAULT_AIPROPI 1575 // AIPROPI sensitivity in μA/A #define AZIMUTH_STALL_TIME_LIMIT 2000 // Stall time limit for azimuth motor in milliseconds #define ELEVATION_STALL_TIME_LIMIT 2000 // Stall time limit for elevation motor in milliseconds #define ENABLE_ELEVATION true // Set to true if elevation motor is enabled #define ENABLE_AZIMUTH true // Set to true if azimuth motor is enabled These values can be adjusted based on the system requirements. Implementation in k3ng_rotator_controller.ino Place the following code in the k3ng_rotator_controller.ino file to handle stall detection and stopping of the motors: #include // Global variables for current monitoring float vref = DEFAULT_VREF; // Reference voltage float ripropi = DEFAULT_RIPROPI; // RIPROPI resistor value in ohms float aipropi = DEFAULT_AIPROPI; // AIPROPI value in μA/A float itrip = 0.0; // Calculated trip current limit in Amps unsigned long stallStartTimeAzimuth = 0; unsigned long stallStartTimeElevation = 0; bool azimuthStalled = false; bool elevationStalled = false; // Function to calculate ITRIP value based on VREF and RIPROPI void calculateItrip() { itrip = (vref / ripropi) * (1 / (aipropi / 1000000.0)); } // Function to check if a motor is stalled void checkMotorStall(int current_mA, unsigned long &stallStartTime, bool &stalled, int motorType, unsigned long timeLimit) { if (current_mA > (itrip * 1000)) { // Check if current exceeds threshold if (stallStartTime == 0) { stallStartTime = millis(); } else if (millis() - stallStartTime > timeLimit) { stalled = true; stopMotor(motorType); // Function to stop the motor (0 = Azimuth, 1 = Elevation) displayStallInfo(motorType, current_mA); } } else { stallStartTime = 0; // Reset stall timer if current drops below limit } } // Function to display stall information on the display void displayStallInfo(int motorType, int current_mA) { Serial.print(motorType == 0 ? "Azimuth" : "Elevation"); Serial.print(" motor stalled. Current sensed: "); Serial.print(current_mA); Serial.println(" mA"); } Motor Stop Function (It looks like this is the relevant stop function in the K3NG controller ino file: // Define the state variables to STOPPED byte az_state = STOPPED; byte el_state = STOPPED; ) // Call the update_az_variable_outputs() function to stop the azimuth motor update_az_variable_outputs(0); // Call the update_el_variable_outputs() function to stop the elevation motor update_el_variable_outputs(0); Create a function to stop the relevant motor: void stopMotor(int motorType) { if (motorType == 0) { // Code to stop azimuth motor Serial.println("Azimuth motor stopped."); } else { // Code to stop elevation motor Serial.println("Elevation motor stopped."); } } 1.2 Initialization Code Add the following code to the setup() function in k3ng_rotator_controller.ino to initialize current sensing: void setup() { Serial.begin(9600); // Initialize serial communication for debugging calculateItrip(); // Calculate the trip current threshold based on default parameters // Other initialization code... } 1.3 Integration into Main Loop Modify the main loop to include stall detection checks: void loop() { // Example current values read from analog sensors (replace with actual sensor readings) int azimuthCurrent_mA = readAzimuthCurrent(); // Function to read azimuth current int elevationCurrent_mA = readElevationCurrent(); // Function to read elevation current if (ENABLE_AZIMUTH) { checkMotorStall(azimuthCurrent_mA, stallStartTimeAzimuth, azimuthStalled, 0, AZIMUTH_STALL_TIME_LIMIT); } if (ENABLE_ELEVATION) { checkMotorStall(elevationCurrent_mA, stallStartTimeElevation, elevationStalled, 1, ELEVATION_STALL_TIME_LIMIT); } } Part 2: SD Card Logging for Current Sensing 2.1 SD Card Initialization Include the SD card initialization at the beginning of k3ng_rotator_controller.ino: #include #define SD_CHIP_SELECT_PIN 10 // Define the chip select pin for your SD card module void initializeSDCard() { if (!SD.begin(SD_CHIP_SELECT_PIN)) { Serial.println("SD Card initialization failed!"); } else { Serial.println("SD Card initialized."); } } Call this function in the setup() section: initializeSDCard(); 2.2 Logging to SD Card Add the logging function to store data in a CSV format with timestamps: bool currentLoggingEnabled = true; // Set to true to enable logging void logCurrentToSD(int motorType, int current_mA, unsigned long durationMillis) { if (currentLoggingEnabled && SD.begin(SD_CHIP_SELECT_PIN)) { File dataFile = SD.open("current_log.csv", FILE_WRITE); if (dataFile) { String timestamp = getUTCTimestamp(); // Placeholder function for UTC time dataFile.print(timestamp); dataFile.print(","); dataFile.print(motorType == 0 ? "Azimuth" : "Elevation"); dataFile.print(","); dataFile.print(current_mA); dataFile.print(","); dataFile.println(durationMillis); dataFile.close(); } else { Serial.println("Error opening current_log.csv file for writing."); } } } String getUTCTimestamp() { // Placeholder code to retrieve UTC timestamp from GPS or time server return "2024-10-16T00:00:00Z"; } 2.3 Integration into Main Loop for Logging Add a condition to log data if a motor stalls in the main loop: if (azimuthStalled) { logCurrentToSD(0, azimuthCurrent_mA, millis() - stallStartTimeAzimuth); } if (elevationStalled) { logCurrentToSD(1, elevationCurrent_mA, millis() - stallStartTimeElevation); } Part 3: Placement of Code Snippets 1. rotator_features.h: Place the configurable values for current limits, resistor values, time limits, and motor enable flags. Example: #define DEFAULT_VREF 3.3 2. k3ng_rotator_controller.ino: Place the functions for stall detection, SD card logging, and motor control. Initialization code goes in the setup() function. The main loop includes the stall detection and logging calls. Summary Configurable Parameters: Added to rotator_features.h for easy adjustment. Core Logic: Implemented in k3ng_rotator_controller.ino for current sensing, stall detection, and logging. SD Card Initialization and Logging: Properly integrated into the setup and loop sections. This structure ensures that the code is modular, well-organized, and easy to configure for your specific use case. There are more things that could be implemented,- such as getting and setting the time from GPS or internet,- and updating the TLE file automatically. Look in https://github.com/Supermagnum/k3ng_rotator_controller_Norwegian/tree/master/Todo-files