Timed servo control and led without RTC

Hey guys!!

I'm new here!! Really nice stuff around! Congrats!

I've just started trying to learn to code for arduino uno so bear with me :P. You see I'm a biologist with coding aspirations! lol.

Anyhow, I'm trying to make a simple circuit to work which would be using a servo and the built in led. Basically the idea is, that a servo will work every x hours (around 5h) four times and in between the led will blink to identify which part of the cycle is happening. So, when a push button is pressed the loop begins and the servo will move back and forth once and de-attach. A led will start blinking once every second for 9h, then again the servo and the led will blink twice repeatedly for 5h; then servo again and the led 3x repeatedly for 5h and lastly servo again and detach. Here the loops ends and only restarts when the button is pressed again.

I could probably do with millis, but I can get may head around it yet. So, I've tried (in a probably dumb way) as follows (see code)

#include <Servo.h>

Servo myservo;

const int servoPin = 9;
const int buttonPin = 12;
const int ledPin = 13;

void setup() {
myservo.attach(servoPin);
pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, HIGH);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
myservo.write(180);
delay(1000);
myservo.detach();
}

void loop() {
int buttonVal = digitalRead(buttonPin);
if(buttonVal == LOW) {
myservo.attach(servoPin);
myservo.write(30);
delay(575);
myservo.write(180);
delay(1500);
myservo.detach();
{
for (int x = 0; x < 6480000; x++) {
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(4000);
}
}
myservo.attach(servoPin);
myservo.write(30);
delay(575);
myservo.write(180);
delay(1500);
myservo.detach();
{
for (int x = 0; x < 3600000; x++) {
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(4400);
}
}
myservo.attach(servoPin);
myservo.write(30);
delay(575);
myservo.write(180);
delay(1500);
myservo.detach();
{
for (int x = 0; x < 3600000; x++) {
digitalWrite(ledPin, HIGH);
delay(120);
digitalWrite(ledPin, LOW);
delay(120);
digitalWrite(ledPin, HIGH);
delay(120);
digitalWrite(ledPin, LOW);
delay(120);
digitalWrite(ledPin, HIGH);
delay(120);
digitalWrite(ledPin, LOW);
delay(4400);
}
}
myservo.attach(servoPin);
myservo.write(30);
delay(575);
myservo.write(180);
delay(1500);
myservo.detach();
}
delay(13);
}

The problem is:

I tried with low repetition numbers like up to 10 for the led and it works the whole thing, but when I put those big number to account for the 9 and 5 hours, the cycle starts fine but then the led just keeps blinking once repeatedly for more than 10h and it doesn't continue the rest of the loop. I guess the way I'm doing is no accurate (obviously) and logically a not classy way to work, but as a newby it was what I managed.

So, any ideas on how to work around that??

Many thanks!

PS: I calculated the repetitions considering that each cycle of the led is 5s, hence 6480000x5= 32 400 000ms = 9h
and 3600000x5= 18 000 000 = 5h

for (int x = 0; x < 6480000; x++) {

That's an infinite loop. What's the maximum value for an int? Can an int ever count up to 6480000? WHy don't you use a long there?

Why don't you try to figure out Blink Without Delay. It really isn't that hard. It's something you do every day. If you look at the clock and it says it is 4:30 and I tell you that I started something at 4:05 then how long have I been working at it? How did you figure that out? It works the exact same way in milliseconds as it does in hours and minutes. Actually it is easier because you don't have to deal with the stupid 60 thing. Point being that not only do you already know how to do that, but it is trivial for you. It's just the fact that it has to be in code now that scares you.

Your numbers are too big to fit in an int. This:

for (int x = 0; x < 6480000; x++) {

would be better:

for (long x = 0; x < 6480000L; x++) {

Note the long declaration and the L suffix on the constant.

wildbill:
and the L suffix on the constant.

Which is totally superfluous and isn't needed at all. The compiler can tell that number must be a long.

Thanks Delta_G and wildbill,

So, declaring it long would solve the issue??

Delta_G, about using millis, I agree and understand the idea behind, but I still have issues in writting this kind of code. I really want to learn though! Mostly, I cannot get my head around on how to instead of only having a led blinking 1s repeatedly, I could code for my second and 3rd situations where they would blink 2x repeatedly or 3x. I know that this is probably very basic, but I can't find nice and simple examples that illustrates that. Instead they usually illustrate same blinking frequency or a certain time off and on.... If you are willing to help me out through the process I'll be more than grateful to you!

Many thanks again!

Btw, would I have any big advantages on using millis instead of the other code? Will it be more precise?

Ok well forget the code for a minute then. it's the logic you've gotta get straight. You can learn that without thinking in any particular programming language. If you were the humonculous in the processor and all you have is a watch and a sheet of paper to record times then how would you do it? If you can describe that then the code will write itself.

Delta_G, the idea behind I understand.

Which is basically check the time stamp, record and compare and based on that deliver the orders. Quite simplified, obviously. But, there are two things for me that right now are tough, first write the code because I know very little about it (as I said I'm trying to learn, but I'm not a code writer).

But forgetting about that, because I guess little by little I'll someday manage. The other issue is that as I said, all the examples I see are quite simplified and don't cover how to for instance, make a led blink twice repeatedly, or 3x....or any other frequency than rather only 1 time for on and 1 time for off (that could be different). Also, merging that into after a while changing the frequency of the same led and then again....usually the examples uses 2 or 3 leds that are flashing during the same period but in different frequencies.

Not sure If I was clear about it, was I?

I honestly would love to be able to write this way as it would be more classy. Despite that, would it make any real difference for this application, instead of using the long?

Despite that, I still want to learn and again, if you are whiling to teach me it will be great. Also if you have any recommended texts that would also be great!

Many thanks!

Yeah, you're still focused on getting an example of how to write the code. Forget that for now. I'll help you get it but you gotta work with me.

Like I said, if you were the humonculous (look that up if you don't know) then how would you do it with a clock and a piece of paper and a pencil. You don't need a code example to figure that out. I don't want you to try to write code yet. You shouldn't need anyone to explain to you how to do it. Just imagine that I gave you a stopwatch that only counts up and doesn't reset, a pencil and paper, and a light switch and told you to flick the light every so often.

You don't need to see someone else do that first. If I actually put you in that situation I'm sure you could manage. But you keep thinking about that code around the corner and you're letting that stop you from thinking this through. Forget the code. Put it out of your mind. Could you solve this problem if it wasn't a coding problem? Surely you can.

All right, I'll keep an eye on the stopwatch and depending on how you ask me (or when) to turn on the switch I would do it and make note. Then I would continue keeping an eye on the watch considering the time written down and would turn off according to your instructions - calculating the time difference - and I would continue the cycle. I hope I was clear :stuck_out_tongue:

Does it make sense?

Delta_G?

Btw, assigning as long didn´t work. It still stays stuck in the first part as it was a infinite loop.

Any other ideas? Or can someone help me to transpose this to millis?

Thanks

Theres a humonculus with a hammer under my dashboard. :slight_smile:

for (int x = 0; x < 6480000; x++) {
   digitalWrite(ledPin, HIGH);   
   delay(1000);              
   digitalWrite(ledPin, LOW);    
   delay(4000);              
   }

It's probably not infinite anymore. It just takes a really long time. Let's think about this for a second. You have a total of 5 seconds of delay in this for loop. It will be repeated 6480000 times. That adds up to 375 days. So you'd have to wait more than a year for this for loop to finish so the rest of the code can continue.

There are also a couple of more really long for loops in there. I'm guessing this loop should take about 3 or so years to run.

Hi

for (int x = 0; x < 6480000; x++) {
   digitalWrite(ledPin, HIGH);   
   delay(1000);     < the code STOP for 1 second        
   digitalWrite(ledPin, LOW);    
   delay(4000);     < the code STOP for 4 seconds           
   }

   So it takes 1 + 4 = 5 seconds for x to increment from 0 to 1.
   The for loop will continue for 6480000 iterations.
   So it will take 6480000 x 5 = 32400000 seconds to finish
   324000000/60/60 = 9000 hours
   9000/24 = 375 days

I hope that explains it.

At the moment the for will not work as you want because you have declared variable i as an int.

int can only be -32,768 to 32,767

long can be -2,147,483,648 to 2,147,483,647.

The delay function is called a blocking function.
delay uses milliseconds as its input variable.

ALL code STOPS during a delay operation even reading and writing I/O.

Tom.. :slight_smile:

Ohhh, silly me...Just realised it is just a calculation error. I messed with the ms/s thing and did an error by 1000. Ok ok....I'll adjust that and it should work. Many thanks!!!

Anyhow, can anyone suggest me a good dummy proof reading or video to learn how to use millis? I think it should be the proper way to do and I would be able to use for other things. Although I don't think that for this project matters much...

Thanks again!!

Anyhow, can anyone suggest me a good dummy proof reading or video to learn how to use millis?

Did you need a really good reference book or video to learn how to look at your watch or clock? That's really all that millis() is.

If I call you, and offer to buy you a beer at the local pub in one hour, do you run to the pub and stand around and wait for me? Or can you do other things until it is time to go to the pub?

If you can, how do you manage that? It's dirt simple, isn't it? When I call, you look at your watch. You know what time it is now. Periodically, you look at it again, and when enough time has ticked by, you sprint for the pub.

Now, define a scenario where you want to use millis(), and tell us about it. We'll help you understand how to properly use millis() to achieve your goals, IF your scenario is one where using millis(), as opposed to some other technique, is appropriate.

PaulS, I understand the concept and the idea and all, but my problem is in writing the code itself. You see, I don't have any formation in C++ or any other prog language. I'm just a biologist exploring new fields and due to that I have a huge gap in how to write codes because I never learn the commands, etc properly.

Thanks though

marcos_s_p:
because I never learn the commands, etc properly.

Well that's just foolish then. You've got the cart before the horse. Go run through some basic C++ tutorials and learn a bit about the language. It shouldn't take more than a few hours.

What would you think of me if I were trying to build plasmids but oh I never learned how these restriction enzymes work. I don't know what bases pair with each other. I'm not interested. Just dumb it down for me.

Could you write me a tutorial on cloning a gene into a plasmid without that kind of knowledge?

Delta_G, that's exactly what I'm trying to do. I've been reading and running basic tutorials and I'm trying to evolve on it. However, usually the examples or are very basic or further advanced without the middle. Besides I still am trying to get a better grasp on everything. But due to that, to try new things or just to do a more complete type of code, I feel I still lack the knowledge, but alone and without the a better formation on it it seems tough to me. That's why I though you guys could guide me in a better path of learning.

Although I'm asking you guys to help me with millis, I understand the concept and everything and already tried a few basic tutorials and made it work nicely. The issue is going a bit further and complicate this same thing. That is, increase the complexity. For that I'm not finding any tutorial and though I could learn here in the forum.

For that I'm not finding any tutorial and though I could learn here in the forum.

That's why I asked you to define a scenario, and explain what you can't do.

I suspect that if we were to show you how to do something more complex than blink an LED, using millis() for the timing, that it might click. But, just contriving an example won't help you learn.