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"));
}
}
}
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
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.
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.
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"));
}
}
}