Control servo with LDR's value and save LDR's Value to Micro SD at the same time

i have problem multitask arduino, i need control servo by ldr value and set interval(delay/speed) by dtime(potentiometer(A4), and then save ldr value every 5 seconds to micro sd card, i’ve tried with millis, code for save ldr’s value nothing problem, it work. but when i combine with servo it going crazy

*sorry for bad english

i’ve tried so far to combine code : test.ino

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

File myFile;
int pinCS = 53; // pin 10 on arduino 
long id = 1;
const unsigned long SaveInterval = 5000;
unsigned long SaveTimer;

int servoh = 90;     // stand horizontal servo
int servov = 90;     // stand vertical servo

class Sweeper1
{
  Servo vertical;              // the servo
  int  updateInterval;      // interval between updates
  unsigned long lastUpdateservov; // last update of position
  int ldrlt = 0; //LDR top left
  int ldrrt = 1; //LDR top rigt
  int ldrld = 2; //LDR down left
  int ldrrd = 3 ; //ldr down rigt
 
public: 
  Sweeper1(int interval)
  {
    updateInterval = interval;
  }
  
  void Attach(int pin)
  {
    vertical.attach(pin);
  }
  
  void Detach()
  {
    vertical.detach();
  }
  
  void Update()
  {
    if((millis() - lastUpdateservov) > updateInterval){  // time to update
      lastUpdateservov = millis();
       int lt = analogRead(ldrlt); // top left
       int rt = analogRead(ldrrt); // top right
       int ld = analogRead(ldrld); // down left
       int rd = analogRead(ldrrd); // down rigt
      
       int dtime = analogRead(4)/20; // read potentiometers  
       int tol = analogRead(5)/4;
      
       int avt = (lt + rt) / 2; // average value top
       int avd = (ld + rd) / 2; // average value down
       int avl = (lt + ld) / 2; // average value left
       int avr = (rt + rd) / 2; // average value right
    
       int dvert = avt - avd; // check the diffirence of up and down // checkperbedaan antara atas dan bawah
       int dhoriz = avl - avr;  // check the diffirence of left and rigt //check perbedaan antara kiri dan kanan
 
      if (-1*tol > dvert || dvert > tol) // check if the diffirence is in the tolerance else change vertical angle // check jika perbedaan adalah 
  {
  if (avt > avd)
  {
    servov = --servov;
     if (servov > 180) 
     { 
      servov = 180;
     }
  }
  else if (avt < avd)
  {
    servov= ++servov;
    if (servov < 0)
  {
    servov = 0;
  }
  }
  vertical.write(servov);
  }
  }
  }
};
class Sweeper2
{
  Servo horizontal;              // the servo
  int  updateInterval;      // interval between updates
  unsigned long lastUpdateservoh; // last update of position
  int ldrlt = 0; //LDR top left
  int ldrrt = 1; //LDR top rigt
  int ldrld = 2; //LDR down left
  int ldrrd = 3 ; //ldr down rigt
 
public: 
  Sweeper2(int interval)
  {
    updateInterval = interval;
  }
  
  void Attach(int pin)
  {
    horizontal.attach(pin);
  }
  
  void Detach()
  {
    horizontal.detach();
  }
  
  void Update()
  {
    if((millis() - lastUpdateservoh) > updateInterval){  
      lastUpdateservoh = millis();
       int lt = analogRead(ldrlt); // top left
       int rt = analogRead(ldrrt); // top right
       int ld = analogRead(ldrld); // down left
       int rd = analogRead(ldrrd); // down rigt
      
       int dtime = analogRead(4)/20; // read potentiometers  
       int tol = analogRead(5)/4;
      
       int avt = (lt + rt) / 2; // average value top
       int avd = (ld + rd) / 2; // average value down
       int avl = (lt + ld) / 2; // average value left
       int avr = (rt + rd) / 2; // average value right
    
       int dvert = avt - avd; // check the diffirence of up and down // checkperbedaan antara atas dan bawah
       int dhoriz = avl - avr;  // check the diffirence of left and rigt //check perbedaan antara kiri dan kanan
 
        if (-1*tol > dhoriz || dhoriz > tol) // check if the diffirence is in the tolerance else change horizontal angle
  {
  if (avl > avr)
  {  
    servoh = --servoh;
    if (servoh < 0)
    {
    servoh = 0;
    }
  }
  else if (avl < avr)
  {
    servoh = ++servoh;
     if (servoh > 180)
     {
     servoh = 180;
     }
  }
  else if (avl = avr)
  {
    // nothing
  }
  horizontal.write(servoh);
  }
  }
  }
};
int dtime = analogRead(4)/20; // read potentiometers 
Sweeper1 sweeper1(15);
Sweeper2 sweeper2(15);
void setup()
{
  Serial.begin(9600);
  pinMode(pinCS, OUTPUT);
// servo connections
// name.attacht(pin);
  sweeper2.Attach(3); 
  sweeper1.Attach(4);


  // SD card initialization
if (SD.begin())
{
  Serial.println("SD card siap digunakan.");
}else {
  Serial.println("SD card gagal menginisialisasi.");
  return;
}
// Create/Open file
myFile = SD.open ("test.csv", FILE_WRITE);
//jika file sudah terbuka dengan benar, data dimasukan
if(myFile) {
  //Write to file
  myFile.println(",");
  String header = "ID, Dvert, Dhoriz";
  myFile.println(header);
  myFile.close();// menutup file
  Serial.println(header);
}
else {
  Serial.println("gagal membuka test.txt");
}
}

void setSave(){
  if ( (millis () - SaveTimer) >= SaveInterval ) {
  SaveTimer = millis ();
  int lt = analogRead(0); // top left
  int rt = analogRead(1); // top right
  int ld = analogRead(2); // down left
  int rd = analogRead(3); // down rigt
  
  int avt = (lt + rt) / 2; // average value top
  int avd = (ld + rd) / 2; // average value down
  int avl = (lt + ld) / 2; // average value left
  int avr = (rt + rd) / 2; // average value right

  int dvert = avt - avd; // check the diffirence of up and down // checkperbedaan antara atas dan bawah
  int dhoriz = avl - avr;  // check the diffirence of left and rigt //check perbedaan antara kiri dan kanan
  String datastring = String(id) + "," + String(dvert) + "," + String(dhoriz);

// Create/Open file
myFile = SD.open ("test.csv", FILE_WRITE);
//jika file sudah terbuka dengan benar, data dimasukan
if(myFile) {
myFile.println(datastring);
myFile.close();
Serial.println(datastring);
}
// jika file tidak terbuka, munculkan pesan error
else {
  Serial.println("gagal membuka test.txt");
}

id++;
}
}
void loop() 
{
      setSave ();
      sweeper1.Update();
      sweeper2.Update();
}

*attachments :
save code : microsd.ino
servo control by ldr code: servo control by ldr(dual axis solar tracker).ino
i’ve tried so far to combine code : test.ino

servo Control by LDR(dual axis solar tracker).ino (1.97 KB)

micro sd.ino (1.91 KB)

Test.ino (5.61 KB)

If you only need to save data every 5 seconds it should be straightforward.

This

but when i combine with servo it going crazy

does not provide any useful information to use as a basis for helping you. Describe in detail what actually happens.

Is it not possible to keep the file open all the time? I imagine that would speed things up.

Why have you two classes - one for each servo? That seems to be completely contrary to the concept of classes. When you find yourself writing the same code twice it usually means poor program planning.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

...R

Robin2:
Why have you two classes - one for each servo? That seems to be completely contrary to the concept of classes. When you find yourself writing the same code twice it usually means poor program planning.

if i use one class for two servo, how can i command vertical.write(servov) for vertical servo, and horizontal.write(servoh) for horizontal servo? and the code isnt realy same, same model with different value.

abinrptaamra:
int dtime = analogRead(4)/20; // read potentiometers
Sweeper1 sweeper1(dtime);
Sweeper2 sweeper2(dtime);

you mean like this ?

int dtime = analogRead(4)/20; // read potentiometers 
Sweeper sweeper1(dtime);
Sweeper sweeper2(dtime);

and if use code above, when i attach them, how they know command is for them ?

void setup()
{
  Serial.begin(9600);
  pinMode(pinCS, OUTPUT);
// servo connections
// name.attacht(pin);
  sweeper2.Attach(3); 
  sweeper1.Attach(4);

.........

or i need to do ( i haven’t test it) something like this ?

class Sweeper
{
  Servo vertical;              
  Servo horizontal;
  int  updateInterval;      // interval between updates
  unsigned long lastUpdateservo; // last update of position
  int ldrlt = 0; //LDR top left
  int ldrrt = 1; //LDR top rigt
  int ldrld = 2; //LDR down left
  int ldrrd = 3 ; //ldr down rigt
 
public: 
  Sweeper(int interval)
  {
    updateInterval = interval;
  }
  
  void AttachV(int pin)
  {
    vertical.attach(pin);
  }
  void AttachH (int pin)
  {
    horizontal.attach(pin);
  }
  void Detach()
  {
    vertical.detach();
    horizontal.detach();
  }
  
  void Update()
  {
    if((millis() - lastUpdateservo) > updateInterval){  // time to update
      lastUpdateservo = millis();
       int lt = analogRead(ldrlt); // top left
       int rt = analogRead(ldrrt); // top right
       int ld = analogRead(ldrld); // down left
       int rd = analogRead(ldrrd); // down rigt
      
       int dtime = analogRead(4)/20; // read potentiometers  
       int tol = analogRead(5)/4;
      
       int avt = (lt + rt) / 2; // average value top
       int avd = (ld + rd) / 2; // average value down
       int avl = (lt + ld) / 2; // average value left
       int avr = (rt + rd) / 2; // average value right
    
       int dvert = avt - avd; // check the diffirence of up and down // checkperbedaan antara atas dan bawah
       int dhoriz = avl - avr;  // check the diffirence of left and rigt //check perbedaan antara kiri dan kanan
 
      if (-1*tol > dvert || dvert > tol) // check if the diffirence is in the tolerance else change vertical angle // check jika perbedaan adalah 
  {
  if (avt > avd)
  {
    servov = --servov;
     if (servov > 180) 
     { 
      servov = 180;
     }
  }
  else if (avt < avd)
  {
    servov= ++servov;
    if (servov < 0)
  {
    servov = 0;
  }
  }
  vertical.write(servov);
  }

   if (-1*tol > dhoriz || dhoriz > tol) // check if the diffirence is in the tolerance else change horizontal angle
  {
  if (avl > avr)
  {  
    servoh = --servoh;
    if (servoh < 0)
    {
    servoh = 0;
    }
  }
  else if (avl < avr)
  {
    servoh = ++servoh;
     if (servoh > 180)
     {
     servoh = 180;
     }
  }
  else if (avl = avr)
  {
    // nothing
  }
  horizontal.write(servoh);
  }
  }
  }
};

int dtime = analogRead(4)/20; // read potentiometers 
Sweeper sweeper1(dtime);
Sweeper sweeper2(dtime);
void setup()
{
  Serial.begin(9600);
  pinMode(pinCS, OUTPUT);
// servo connections
// name.attacht(pin);
  sweeper2.AttachH(3); 
  sweeper1.AttachV(4);
........
......

really thx for reply

I am not familiar with using classes in C++ but what you have suggested in Reply #2 is going the right direction.

And the obvious question - if you are also not familiar with classes why bother to use them?

...R Planning and Implementing a Program

Robin2:
And the obvious question - if you are also not familiar with classes why bother to use them?

cause i need to control servo and save data at the same time without using delay, i see this tutorial, and i’ve tried to implement to my code

but if you have another method, im glad if you want to tell me how

abinrptaamra: cause i need to control servo and save data at the same time without using delay,

That requires a program but it does not oblige you to write a program with classes.

Have you studied the link I gave you in Reply #3 - it does multiple things and does not use delay(). The shorter example is Several Things at a Time

By the way I am not saying there is anything wrong with using classes - just that if you want to use them you should spend some time learning how.

...R

abinrptaamra: if i use one class for two servo, how can i command vertical.write(servov) for vertical servo, and horizontal.write(servoh) for horizontal servo? and the code isnt realy same, same model with different value.

that is the point of creating/using classes, and yes you are on the correct path.

create and use one class and then create two instances of the class:

MyClass first;       // constructor, creates an instance of the class called "first"
MyClass second;

void setup()
{
  first.doSomething();      // calls the doSomething method on the first instance
  second.doSomething();  // calls the doSomething method on the second instance

to @Robin2's point, if this is at all above your current understanding, perhaps you should try to learn it ground up.