Is this Possible....Curious? -Check it out

Hi,

I have a Arduino Unos with a continuous 360 servo. I have a RTC (Real Time Clock) emulator by Michael Margolis the Library is called "Time" v.1.5. I do not have a mosfet, resistor or hardware time clock. I'm trying to do the following below without extra hardware.

*To note:
On a continuous rotation servo, this will set the speed of the servo (with 0 being full-speed in one direction, 180 being full speed in the other, and a value near 90 being no movement).

Is it possible to do the following? Attached is my uncompleted code. It does the trigger based on a specific time just fine only if step 1 doesn't exist. If I have step 1 in there it seems to ignore the time trigger it just keeps to step 1.

How do I interrupt step 1 to run step 2?

and I can control the servo. But I don't know if it's possible to do action 2.

Any ideas?

Action 1:
Have the servo turn a wheel slowly Servowrite (80) for a long time like 9999999ms (2.7 hours) :slight_smile:

Action 2:
Then if the time is say 9pm the. Interrupt Action 1 and process Action 3.

Action 3:
Turn the wheel faster reversing direction --Servowrite (110)-- for 2 seconds... Then do Action 4

Action 4: Hold position by using Servowrite (90 )for 9999999ms (2.7 hours)

Basically here's the crux of the problem:

When code is uploaded - I'm supposed to open up the Serial Monitor to input a epoch time like T1542739240

The problem: it does not take the epoch time because I think Action 1 is still running and getting in the way. When I comment out Action 1 then, and run the program it lets me open the serial monitor and put the Epoch time of like T1542739240

When Action 1 is not commented out, just runs and runs action 1 and don't respond to the time trigger in Action 2.

ServoTimeTrigger1.1.ino (2.63 KB)

Action 1:
Have the servo turn a wheel really slowly for a long time like 999999 :slight_smile:

Action 2:
Then if the time is say 9pm the. Interrupt Action 1 and process Action 3.

Action 3:
Turn the wheel/servo for 2 seconds... Then do Action 4

Action 4: Hold position for 9999999 - basically a long time

All perfectly possible, but without an RTC or other external source of time data it will not be very accurate.

Do NOT power the servo form an Arduino 5V pin. Connect it directly to an external power source with a common GND with the Arduino

I understand the time won't be accurate which is fine.

But what type of code would I need to make Action 2 happen? Could you give me an example of code that would interrupt step 1 and process step 2 ?

SquirrelFX:
I understand the time won't be accurate which is fine.

But what time of code would I need to make Action 2 happen?

You will need to get user input of the current time when the program starts or provide a method for it to be entered later. Once you have the time you increment the minutes variable every 60 seconds (use millis() for timing) and the hour variable every hour. Given the two variables you can check the current time and act on it as you want.

Thank you sorry I had a typo. I meant to say what type of code or is there an example you can give me that would accomplish step 2?

I have been using the serial output monitor to set the time using epoch T2848383 (whatever the number is) that part works for me but I haven't found a way to interrupt step 1.

I'm hoping I can do it without user input other than when I set the time initially.

I haven't found a way to interrupt step 1.

How are you doing step 1 ?

I would create a state machine. Give each state a name and use switch/case

In the code for each state, only one of which will be active at a time, test whether an exit condition has been met and if so move to the appropriate state

I don't understand what there is to interrupt with action 1. You start the servo moving. You no longer have to do anything to make the servo continue to move. So, there is nothing to interrupt.

I'm actually wanting the speed to change, and the direction to change between each action. I'm hoping someone might know how to accomplish action 2.

I'm hoping someone might know how to accomplish action 2.

When in the first state check the time each time through loop() and when it is 9pm change to state 3. Note that there is actually no state 2

What is the problem ?

From just what was written, depending on the Arduino being used, it is possible to interrupt step one. A Mega or DUE, especially the DUE, has the capacity to run a RTOS ( something like uMT) where such things, as you are asking about, are quite easy to do.

Assuming you are sending for x amount of time a signal to the servo, there has to be a routine checking for the time to expire, and that is where a interrupting factor can be inserted. Such as a type of semaphore. Or inside the timer checking routine add in a Boolean variable that must be true in order for the timer to continue. The Boolean variable could be modified by an external routine. Or you can use one of the available light weight schedulers that will allow an interrupting flag to be set in the timer checking routine.

But without seeing the code, I'm only guessing. No, I am not going to knowingly download some ones code into my computer.

Don't complicate things. The program will be in one of a number states and events will cause it to change to another state. No need for interrupts. It's a simple state machine

State 1 : the servo turns slowly in forward direction
Exit condition 1 : 9999999ms elapsed time
Target state : not specified by OP but may be state 2

Exit condition 2 : time is 9pm
Target state : state 2

State 2 : Servo runs in reverse direction at a higher speed
Exit condition : 2 seconds elapsed time
Target state : state 3

State 3 : Servo runs in forward direction
Exit condition : 9999999ms elapsed time
Target state : not specified by OP

I uploaded a refreshed version of the code titled TimeTriggerServo.ino see the 1st post.

Basically here's the crux of the problem:

When code is uploaded - I'm supposed to open up the Serial Monitor to input a epoch time like T1542739240

The problem: it does not take the epoch time because I think Action 1 is still running and getting in the way. When I comment out Action 1 then, and run the program it lets me open the serial monitor and put the Epoch time of like T1542739240

When Action 1 is not commented out, just runs and runs action 1 and don't respond to the time trigger in Action 2.

I'm catching up reading the last few posts. Mean while I'll paste some of the code that better explains it than my original code did.

#include <TimeLib.h>
#include <Servo.h>
#define TIME_HEADER "T" // Header tag for serial time sync message
#define TIME_REQUEST 7 // ASCII bell character requests a time sync message
const int SERVO = 9;
Servo myServo;

void setup()
{
myServo.attach(SERVO);
Serial.begin(9600);
while (!Serial) ;
pinMode(13, OUTPUT);
setSyncProvider( requestSync); //set function to call when sync required
Serial.println("Waiting for sync message");
}

void loop(){
if (Serial.available()) {
processSyncMessage();
}
if (timeStatus()!= timeNotSet) {
digitalClockDisplay();
}
if (timeStatus() == timeSet) {
digitalWrite(13, HIGH); // LED on if synced
} else {
digitalWrite(13, LOW); // LED off if needs refresh
}

myServo.write(85); // Action 1 - set servo speed 85 is a slow spin in the left direction
delay(9999999); // this delay is in ms about 2.7 hours

// when code is uploaded - I'm supposed to open up the Serial Monitor to input a epoch time like T1542739240
// problem: it does not take the epoch time because I think Action 1 is still running and getting in the way
//objective Action 1 should run until Action 2 kicks in and triggers Action 3
delay(1000);
if ( hour() == 9 && second() == 19 && minute()== 50) // Action 2 - this sets the trigger time
{
myServo.write(98); // Action 3: reverse spin direction
delay(2000); // go for 2 seconds

myServo.write(90); // Action 4: 90 makes the servo hold position
delay(99999999); // hold position for about 2.7 hours
}
}

// when code is uploaded - I'm supposed to open up the Serial Monitor to input a epoch time like T1542739240
// problem: it does not take the epoch time because I think Action 1 is still running and getting in the way

It WILL read the serial data you enter, approximately 2.7 hours after you enter it. Are you waiting long enough?

A state machine has been suggested, and using millis(), as in the blink without delay example, but you seem welded to the stickYourHeadInTheSand() function instead.

When you get unwelded from that function, you can expect your program to become more responsive.

PaulS:
It WILL read the serial data you enter, approximately 2.7 hours after you enter it. Are you waiting long enough?

A state machine has been suggested, and using millis(), as in the blink without delay example, but you seem welded to the stickYourHeadInTheSand() function instead.

When you get unwelded from that function, you can expect your program to become more responsive.

Lol HeadIntheSand --- Thanks guys! I'm new to programming so I'm still sorting this out. I will try the suggested changes. -Paul you crack me up lol

yeah had one too many 9's in there, thanks for the heads up

What happens if you comment out the long delays, like this:

// delay(9999999);  // this delay is in ms about 2.7 hours

It's working now I'll post an update to how it's working.

Thanks for all the help