Code working not as supposed

I got small servo device that need to turn to exact position, then go back. This action must execute in exact time. I got Nano with RTC module, connected SG90 servo and transistor to it (when servo idle, transistor working as some sort of relay and turning off power to servo, cuz this servo while in idle can make some noise). All this connected to 2A power supply. Problem that servo sometimes in random time executing move action, while it supposed to execute it only at exact time (in exact time it either executing move action). So here is my code and I hope you will help me to understand where is issue. And yes, i know that code made kinda too dumb, but it works. Im not programmer myself. It also got serial control, to manually enter letter (rx tx) and execute move command or check RTC time.

#include <Servo.h>
#include <string.h>
#include <Wire.h>
#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS1307);

String hrs;
String mins;
String timenow;

int angle = 112; 
Servo myservo;  // create servo object to control a servo
const int servoPWcontrol = 5;     // the number of serwo porwe control 


void setup() 
{  
  delay(300);
  Serial.begin(9600);
  
  time.begin();
    time.settime(0,51,11,18,05,22,3); // 0  сек, 51 мин, 11 час, 18, май месяй (5ый), 2022 года, вторник       
    myservo.attach(9);
    myservo.write(angle); 
    pinMode(servoPWcontrol, OUTPUT);
    digitalWrite(servoPWcontrol, LOW);   // Turn powersource od servo OFF
    
    Serial.println("Type Command by first letter (feednow - F, gettime - G)");
}

void loop()
{
  timenow=time.gettime("H:i:s");
  delay(500);
   digitalWrite(servoPWcontrol, LOW);
   if(timenow=="10:00:00")
    {  
    digitalWrite(servoPWcontrol, HIGH);
    delay(1000);
    myservo.write(70);
    delay(1500);
    myservo.write(112);
    delay(1000);
    digitalWrite(servoPWcontrol, LOW);
    Serial.println("They need more...");
    delay(61000);
    }
     if(Serial.available()){
      int aChar = Serial.read();
     if (aChar == 'F') {
     digitalWrite(servoPWcontrol, HIGH);
     delay(1000);
    myservo.write(70);
    delay(1500);
    myservo.write(112);
    delay(1000);
    digitalWrite(servoPWcontrol, LOW);
      Serial.println("They need more...");
    }
    else if (aChar == 'G') {
      Serial.println(time.gettime("H:i:s"));
    }
               }
}

Sorry servos are not exact they have some error depending on there encoder. Expect an accuracy of about 0.5 degrees.

What does "in random time" mean?
Describe very precise if you average the unexpected moves over one hour how often?

What does "move action" mean?
Describe very precise moving how far 0,5 degrees ? 5 degress? does it the exact same move as when it should but only at a random time?

I haven't tested this explicit but I think you can't do a comparison like that

if(timenow == "10:00:00")

the variable is of type String and Strings can't be compared like that.
You are assigning the String-variable new values very often. Especially for variables of type String this is a problem that can lead to program-crashes because the new assigning eats up all RAM-memory over time.

The RTC-library should offer function with which you can get the time-information as integers and then you can calculate minutes of day or seconds of day

minutesOfDay = hours * 60 + minutes;
secondsOfDay = hours * 3600 + minutes * 60 + seconds;

best regards Stefan

Variables of the String class can be compared using equality (==). Variables of the string type (null terminated character arrays) cannot. For strings use strcmp().

Another concern is that if you miss that exact time, your if statement will never turn true.
May be better to use >, if comparing integer values. Not sure how that would work out with String comparison.

@groundFungus Thank you for clarifying this.

there only one "move action" for servo, as you can see in code.
it can happen at 15:00... even double time - 2 times in 15:00. that could be even later. i mean, there no declaration in code, except 10:00:00, when it should do servo move action. i cant see mistakes in code. RTC got new battery. it shows time correct via serial. total anomaly. guess its only malfunction reason could be.

it not miss. i set delay in beginning of loop, to 500ms, so it cant miss that time. it working in correct time successfully. but why it activating in other time (can be 5 hours later) - unknown. maybe something can send like letters to RX somehow.... i think i will try to disable serial command for F in code.... maybe board malfunction and sending some junk to rx somehow.

@cookins
I did not understand what you tried to explain in your last posting.

Please do me a favor and write a new and very detailed answer in your native language.
and then use google-translate.

best regards Stefan

If the uncorrect moves occur after 5 hours I guess it is this effect

test this version

// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * 

// a detailed explanation how these macros work is given in this tutorial
// https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298

#define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);
// usage: dbg("1:my fixed text",myVariable);
// myVariable can be any variable or expression that is defined in scope

#define dbgi(myFixedText, variableName,timeInterval) \
  do { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  } while (false);
// usage: dbgi("2:my fixed text",myVariable,1000);
// myVariable can be any variable or expression that is defined in scope
// third parameter is the time in milliseconds that must pass by until the next time a 
// Serial.print is executed
// end of macros dbg and dbgi
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * 

#include <Servo.h>
#include <SafeString.h>
#include <Wire.h>
#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS1307);

createSafeString(hrs_SS,  32);
createSafeString(mins_SS,  32);
createSafeString(timenow_SS, 32);

int hours;
int minutes;
int minutesOfDay;

int angle = 112;
Servo myservo;  // create servo object to control a servo
const int servoPWcontrol = 5;     // the number of servo porer-control


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

  time.begin();
  time.settime(0, 51, 11, 18, 05, 22, 3); // 0  сек, 51 мин, 11 час, 18, май месяй (5ый), 2022 года, вторник
  myservo.attach(9);
  myservo.write(angle);
  pinMode(servoPWcontrol, OUTPUT);
  digitalWrite(servoPWcontrol, LOW);   // Turn powersource of servo OFF

  Serial.println("Type Command by first letter (feednow - F, gettime - G)");
}

void loop() {
  //timenow_SS = "12:34:00";
  timenow_SS = time.gettime("H:i:s");
  dbg("0;",timenow_SS);
  timenow_SS.substring(hrs_SS,  0, 2); // start at character 0 up to 2??
  dbg("1:",hrs_SS); // result "12"
  
  timenow_SS.substring(mins_SS, 3, 5); // start at character 3 up to 5???
  dbg("2:",mins_SS); // result "34" 

  
  hrs_SS.toInt(hours);
  mins_SS.toInt(minutes);
  minutesOfDay = hours * 60 + minutes;
  dbg("3:",minutesOfDay);
  
  delay(500);
  digitalWrite(servoPWcontrol, LOW);
  //if (timenow_SS == "10:00:00"){
  if (minutesOfDay >= 600){ // 10 hours * 60 + 0 minutes = 600
    digitalWrite(servoPWcontrol, HIGH);
    delay(1000);
    myservo.write(70);
    delay(1500);
    myservo.write(112);
    delay(1000);
    digitalWrite(servoPWcontrol, LOW);
    Serial.println("They need more...");
    delay(61000);
  }
  
  if (Serial.available()) {
    int aChar = Serial.read();
    if (aChar == 'F') {
      digitalWrite(servoPWcontrol, HIGH);
      delay(1000);
      myservo.write(70);
      delay(1500);
      myservo.write(112);
      delay(1000);
      digitalWrite(servoPWcontrol, LOW);
      Serial.println("They need more...");
    }
    else if (aChar == 'G') {
      Serial.println(time.gettime("H:i:s"));
    }
  }
}

best regards Stefan

i will test all suggestions.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.