SolarTracker with Time

I want to make a solar tracker with Arduino. It is single axis only in azimuth direction - this is my code - when I run the code my DC motor does not start

#include <SD.h>
#include <SPI.h>
#include <RTClib.h>

// Pin connections
#define SD_CS 10
#define MOTOR_IN1 5
#define MOTOR_IN2 6
#define MOTOR_ENA 9

RTC_DS3231 rtc;
File myFile;

void setup() {
  Serial.begin(9600);

  // Initialize SD card
  if (!SD.begin(SD_CS)) {
    Serial.println("SD card initialization failed!");
    while (1);
  }
  Serial.println("SD card initialized.");

  // Initialize RTC
  if (!rtc.begin()) {
    Serial.println("RTC initialization failed!");
    while (1);
  }
  Serial.println("RTC initialized.");

  // Display current date and time
  DateTime now = rtc.now();
  Serial.print("Current RTC Date: ");
  Serial.print(now.month());
  Serial.print("/");
  Serial.print(now.day());
  Serial.print("/"); 
  Serial.println(now.year());

  // Initialize motor pins
  pinMode(MOTOR_IN1, OUTPUT);
  pinMode(MOTOR_IN2, OUTPUT);
  pinMode(MOTOR_ENA, OUTPUT);
}

void loop() {
  DateTime now = rtc.now();
  // Format date for CSV comparison: MM/DD/YY
  String currentDate = String(now.month()) + "/" + String(now.day()) + "/" + String(now.year() % 100);

  Serial.print("Searching for date in CSV: ");
  Serial.println(currentDate);

  if (readCSVAndControlMotor(currentDate)) {
    Serial.println("Motor control completed for today.");
  } else {
    Serial.println("No matching date found in CSV.");
  }

  delay(60000); // Recheck every minute
}

bool readCSVAndControlMotor(String currentDate) {
  myFile = SD.open("test.csv");
  if (!myFile) {
    Serial.println("Failed to open CSV file!");
    return false;
  }

  bool dateFound = false;
  bool isHeader = true;

  while (myFile.available()) {
    String line = myFile.readStringUntil('\n');
    line.trim();

    if (isHeader) {
      isHeader = false;
      continue;
    }

    // Split the values using commas
    int commaIndex[4];
    int indexCounter = 0;
    for (int i = 0; i < line.length(); i++) {
      if (line[i] == ',') {
        if (indexCounter < 4) { // Prevent overflow of the array
          commaIndex[indexCounter++] = i;
        }
      }
    }

    if (indexCounter != 4) {
      Serial.println("Invalid CSV line format: " + line); // Print invalid line
      continue;
    }

    String date = line.substring(0, commaIndex[0]);
    String sunrise = line.substring(commaIndex[0] + 1, commaIndex[1]);
    String sunset = line.substring(commaIndex[1] + 1, commaIndex[2]);
    String delayTimeStr = line.substring(commaIndex[3] + 1);

    Serial.print("Comparing RTC date: ");
    Serial.println(currentDate);
    Serial.print("With CSV date: ");
    Serial.println(date);

    if (date == currentDate) {
      dateFound = true;
      Serial.println("Date matched!");
      Serial.print("Sunrise: "); Serial.println(sunrise);
      Serial.print("Sunset: "); Serial.println(sunset);
      Serial.print("Delay Time: "); Serial.println(delayTimeStr);

      // Convert delay time to an integer and check its value
      long delayTime = delayTimeStr.toInt();
      if (delayTime <= 0) {
        Serial.println("Invalid delay time, setting to default (1000ms)");
        delayTime = 1000;  // Default delay value
      }

      if (delayTime > 0) {
        controlMotor(15, delayTime);  // 15 is for motor steps
      } else {
        Serial.println("Invalid DELAY value in CSV.");
      }
      break;
    }
  }

  myFile.close();
  return dateFound;
}

void controlMotor(int numStep, int delayTime) {
  Serial.print("Starting motor control. Steps: ");
  Serial.print(numStep);
  Serial.print(", Delay: ");
  Serial.println(delayTime);

  for (int i = 0; i < numStep; i++) {
    // Motor movement counterclockwise
    digitalWrite(MOTOR_IN1, HIGH);
    digitalWrite(MOTOR_IN2, LOW);
    digitalWrite(MOTOR_ENA, HIGH); // Set enable to HIGH
    delay(1500); // Run motor for 1500 milliseconds

    // Stop motor
    digitalWrite(MOTOR_IN1, LOW);
    digitalWrite(MOTOR_IN2, LOW);
    delay(delayTime); // Use delay time from CSV
  }

  Serial.println("Motor control finished.");
}

Hi there, welcome to the forum!

Do you have schematics or diagram for the hardware?

If you run a sketch with just the motor included, will it activate the motor?

Hii
No, unfortunately.
But
2. Module Connections to Arduino

a) Connecting the RTC Module (DS3231):
The DS3231 module uses I2C communication, so it should be connected to the SDA and SCL pins on the Arduino.
| DS3231 Pin | Arduino Connection | |------------|--------------------| | VCC | 5V | | GND | GND | | SDA | A4 (Uno) or 20 (Mega) | | SCL | A5 (Uno) or 21 (Mega) |

b) Connecting the SD Card Module:
The SD card module uses SPI communication.
| SD Card Module Pin | Arduino Connection | |--------------------|--------------------| | VCC | 5V | | GND | GND | | CS | 10 | | MOSI | 11 | | MISO | 12 | | SCK | 13 |

Note: The CS pin may vary on the SD card module. Ensure the CS pin is correctly connected to the Arduino.

c) Connecting the L298N Motor Driver for DC Motor Control:
The L298N module is used to control DC motors. Use the following connections:

  1. Power Pins:

VCC: Connect to the motor power supply (usually 9-12V)

GND: Connect to the GND of the Arduino and the motor power supply

5V (optional): If the L298N has a regulator, it can supply 5V.

  1. Motor Connections:

Connect the DC motor to the OUT1 and OUT2 pins of the L298N module.

  1. Control Connections to Arduino:

IN1: Connect to pin 5 on Arduino

IN2: Connect to pin 6 on Arduino

ENA: For speed control (optional), connect to a PWM pin on Arduino (e.g., pin 9) or connect to VCC.

d) Connecting DC Motor or Stepper Motor:

For a DC motor, use the OUT1 and OUT2 pins of the L298N module.

If using a stepper motor, two channels of the L298N module are required (OUT1, OUT2, and OUT3, OUT4).

The motoe does not react.

The sun does not move around the horizon at a constant rate, it moves slower at rise / set than at noon. At this time of year at my location, at sunrise it moves about 9.3° per hour, at noon about 15° per hour.

The tracking algorithm is as follows: The time interval between sunrise and sunset is to be performed in different steps and also with different delays depending on the day.And this data is in an Excel file that is going to be read from that file.

Ok, focus first on getting the motor to run. Disconnect the other peripherals, and program a sketch for the motor only. Make sure the power is connected right, and that the power supply can provide enough current to the motor.

Feel free to post your circuit diagram.

2 Likes

In fact, I have a gear with 105 teeth, the angle between each tooth is about 3.42 degrees, which is supposed to be, for example, if the azimuth angle between sunrise and sunset is about 120 degrees: 120/3.42 = 35, which is 35 times the number of movements that we travel with a delay between each step of the entire angle.

I tested it with a separate engine code and it is absolutely correct.

Remove the SD and all its calls. Test the motor again.

Not sure what code that is...

.. but I guess this is still valid.

This is my problem, my code doesn't work :smiling_face_with_tear:

That is an excellent exercise in mapping of date/time to rotation.

1 Like

I wrote a separate code just to test the motor and it worked.

SD uses a lot of power during writing. What is your power supply? And see Post #9.

A 10-volt adapter

I do not understand 10v adapter. From what to what? Motors need 10v? SD does not use 10v. See post #9.

1 Like

How many teeth on the motor gear? How much torque is required to turn your tracker? How much torque can your motor provide? What is your motor's voltage and current ratings? What kind of power supply?