Looping something inside a program

hello,

im new to arduino and im beginning to understand it. i`m working on a project programming a model bridge. now i got this problem i want this line to repeat its self throughout the program.

digitalWrite(10,HIGH); // ROOD LICHT AUTOS KNIPPEREN
delay(200);
digitalWrite(10,LOW);
digitalWrite(11,HIGH);
delay(200);
digitalWrite(11,LOW);

if some one could help me with this please.
this is the whole program

void setup()

{
pinMode(11, OUTPUT) ; //auto
pinMode(10, OUTPUT) ; //auto
pinMode(9, OUTPUT) ; // boot rood licht boven LINKS
pinMode(8, OUTPUT) ; // boot groen licht LINKS
pinMode(7, OUTPUT) ;// boot rood licht onder LINKS
pinMode(6, OUTPUT) ; // boot rood licht boven RECHTS
pinMode(5, OUTPUT) ; // boot groen licht RECHTS
pinMode(4, OUTPUT) ;// boot rood licht onder RECHTS

}
void loop()
{
{

digitalWrite(10,HIGH); // ROOD LICHT AUTOS KNIPPEREN
delay(200);
digitalWrite(10,LOW);
digitalWrite(11,HIGH);
delay(200);
digitalWrite(11,LOW);

}

delay(3000);

digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
delay(5000);
digitalWrite(8, HIGH);
delay(5000);
digitalWrite(9, LOW);

delay(20000);
digitalWrite(8, LOW);
delay(1000);
digitalWrite(9, HIGH);

delay(5000);
digitalWrite(5, HIGH);
delay(5000);
digitalWrite(6, LOW);
delay(20000);
digitalWrite(5, LOW);
delay(1000);
digitalWrite(6, HIGH);
delay(5000);
}

BRUG_V2.ino (996 Bytes)

i want this line to repeat its self throughout the program

I am having trouble understanding what that means.

If you want the same bit of code to be used in many places, make a function with the code:

void repeatMe()
{  
  digitalWrite(10,HIGH); // ROOD LICHT AUTOS KNIPPEREN
  delay(200);
  digitalWrite(10,LOW);
  digitalWrite(11,HIGH);
  delay(200);
  digitalWrite(11,LOW);
}

Then, wherever you want that code to run, call the function:

  delay(3000);

  repeatMe();

  digitalWrite(6, HIGH);
  digitalWrite(9, HIGH);
  delay(5000);
  digitalWrite(8, HIGH);
  delay(5000);
  digitalWrite(9, LOW);

  repeatMe();
 
  delay(20000);

at present in loop() the statements

digitalWrite(10,HIGH); // ROOD LICHT AUTOS KNIPPEREN
  delay(200);
  digitalWrite(10,LOW);
  digitalWrite(11,HIGH);
  delay(200);
  digitalWrite(11,LOW);

executes then you move onto manipulate the other outputs

do you require the statements to execute continuously in parallel with mainipulating the other output pins?

if so rather than using delay use millis() to set a counter to control the other outputs
e.g. something along the lines of

void loop()
{
  static int counter=millis();
  digitalWrite(10,HIGH); // ROOD LICHT AUTOS KNIPPEREN
  delay(200);
  digitalWrite(10,LOW);
  digitalWrite(11,HIGH);
  delay(200);
  digitalWrite(11,LOW);
  if(millis()-counter == 3000)   
  {
    digitalWrite(6, HIGH);
  digitalWrite(9, HIGH)
  ... 
  }
  if((millis()-counter == 20000)
  {
  digitalWrite(8, LOW);

a better alternative is to move the control of the other output pins into a timer0 interupt routine and use a counter to count the interrupts

horace:
a better alternative is to move the control of the other output pins into a timer0 interupt routine and use a counter to count the interrupts

That sounds unnecessarily complicated for a beginner. I don't think there is anything in his project that needs to happen so fast that a HardwareTimer interrupt is required. He has thousands of millisecs of delay()s

@The_GreadZero, have a look at Planning and Implementing a Program

...R

the problem I see is that the delays executed every loop in

 digitalWrite(10,HIGH); // ROOD LICHT AUTOS KNIPPEREN
  delay(200);
  digitalWrite(10,LOW);
  digitalWrite(11,HIGH);
  delay(200);
  digitalWrite(11,LOW);

make it difficult to do tests such as

  if(millis()-counter == 3000)

the probablity of catching millis()-counter as value 3000 is not good
on a PC I would use seperate threads for this

void setup()

{
pinMode(11, OUTPUT) ; //auto
pinMode(10, OUTPUT) ; //auto
pinMode(9, OUTPUT) ; // boot rood licht boven LINKS
pinMode(8, OUTPUT) ; // boot groen licht LINKS
pinMode(7, OUTPUT) ;// boot rood licht onder LINKS
pinMode(6, OUTPUT) ; // boot rood licht boven RECHTS
pinMode(5, OUTPUT) ; // boot groen licht RECHTS
pinMode(4, OUTPUT) ;// boot rood licht onder RECHTS

}
void loop()
{
{
static int counter=millis();
digitalWrite(10,HIGH); // ROOD LICHT AUTOS KNIPPEREN
delay(200);
digitalWrite(10,LOW);
digitalWrite(11,HIGH);
delay(200);
digitalWrite(11,LOW);
if(millis()-counter == 3000)
}

delay(3000);

digitalWrite(6, HIGH);
digitalWrite(9, HIGH);
delay(5000);
digitalWrite(8, HIGH);
delay(5000);
digitalWrite(9, LOW);

delay(20000);
digitalWrite(8, LOW);
delay(1000);
digitalWrite(9, HIGH);

delay(5000);
digitalWrite(5, HIGH);
delay(5000);
digitalWrite(6, LOW);
delay(20000);
digitalWrite(5, LOW);
delay(1000);
digitalWrite(6, HIGH);
delay(5000);
}
{
if((millis()-counter == 20000)
}

i`ve got the code like this now and it says this error

exit status 1
expected primary-expression before '}' token

 if(millis()-counter == 3000)
 }

Unusual construct

Please remember to use code tags when posting code

horace:
the problem I see is that the delays executed every loop in

make it difficult to do tests such as

I agree completely. But there is no need to use an interrupt to deal with that. Just replace all the delay()s with millis()

...R

If you format your code using Ctrl-T you'll soon see what's wrong. Your {} are all over the place and so your if statements make no sense at all. An if statement is followed by some actions you want doing if the if is true. So having one as the last line of the code is never going to be any use.

Also millis() returns an unsigned long NOT an int and when you're testing it always use >= rather than ==. Your chances of catching it exactly on a specific one thousandth of a second are just about zero.

BTW when you have errors please post the WHOLE error message. Just above the part you quoted it told you what line the error was on, and that's often really helpful information.

Steve

Another thing: do name your pins, then use those names in your code. Much easier to remember what you're doing, and much easier to change pin assignments down the road. Like this:

byte bootRoodBovenLinks = 9;

void setup() {
  pinMode (bootRoodBovenLinks, OUTPUT);
}

slipstick:
Also millis() returns an unsigned long NOT an int and when you're testing it always use >= rather than ==. Your chances of catching it exactly on a specific one thousandth of a second are just about zero.

yes, which was why I thought that using an interrupt service routine would be more accurate
the code of post #1 has statements (with some delays) to be executed every loop plus multiple states with delays between each state
I guess some sort of state machine is required
e.g. blink LED every 100mSec and print time elapsed after 1,2, 4, 8 and 16 seconds

// Timer test using millis()
// print elapsed time in mSeconds

void setup() {
  Serial.begin(115200);
  Serial.println(F("print elapsed time in mSeconds "));
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  // elapsed time between each print
  static unsigned long int times[]={1000, 2000, 4000, 8000, 16000};
  static unsigned long int index=0, counter=millis(), seconds=millis();
  // blink LED
  delay(100);
  digitalWrite(LED_BUILTIN, HIGH);   
  delay(100);
  digitalWrite(LED_BUILTIN, LOW);   
  // if time has elapsed display mSeconds
  if((millis()-counter) > times[index])
    switch (index)
    {
      case 0: Serial.println(millis()-seconds);  index++; break;
      case 1: Serial.println(millis()-seconds);  index++; break;
      case 2: Serial.println(millis()-seconds);  index++; break;
      case 3: Serial.println(millis()-seconds);  index++; break;
      case 4: Serial.println(millis()-seconds); seconds=millis(); index=0;counter = millis(); break;
    }
}

which displays

print elapsed time in mSeconds
1200
2200
4200
8001
16003

due to delays in blinking the LED timings are not accurate

 if((millis()-counter) >= times[index])

You should also increment "counter" by "times[index]" rather than using millis.

horace:

Also millis() returns an unsigned long NOT an int and when you're testing it always use >= rather than ==. Your chances of catching it exactly on a specific one thousandth of a second are just about zero.

yes, which was why I thought that using an interrupt service routine would be more accurate

Two things about this ...
You are correct to say that using an interrupt would provide greater accuracy. But in this case microsecond accuracy is not required and @slipstick's comment was not about accuracy - it was about the potential complete failure to respond at the right time by trying to be too precise.

And the other thing is that I feel very strongly that advice should be tailored to the level of expertise of the student if it is to be useful.

...R

this application has two seperate things happening in parallel - one can code them in a single method but it can be simpler to implement one in loop() and the othere in an interrupt service routine
e.g. the program of #10 using a timer interrupt

// Timer test using millis()
// print elapsed time in mSeconds

void setup() {
  Serial.begin(115200);
  Serial.println(F("print elapsed time in mSeconds "));
  pinMode(LED_BUILTIN, OUTPUT);
  // Timer0 is already used for millis() - enable interrupts
  OCR0A = 0xAF;
  TIMSK0 |= _BV(OCIE0A);
}

volatile int timer=0, index=0;
void loop() {
  static unsigned long int seconds=millis();
  // if timer has gone off display elapsed time
  if(timer)
    {
    timer=0;
    Serial.println(millis()-seconds);
    if(index == 0)    // if at start of array reset seconds
        seconds=millis();
    }
}

// Timer 0 Interrupt is called once a millisecond
SIGNAL(TIMER0_COMPA_vect) 
{
 // elapsed time between each print
  static unsigned long int times[]={1000, 2000, 4000, 8000, 16000};
  static unsigned long int counter=millis(), blink=millis();
  // blink LED every 100mSec
  if(millis()-blink>100) 
     {
     blink=millis(); 
     digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));   
     }
  // if time elapsed set tomer and indrement array index etc
  if((millis()-counter) > times[index])
    {
    timer=1;
    // if at end of array reset to start etc
    if(++index>4)
     { counter=millis(); index=0; }  
    }
 }

a run now gives

print elapsed time in mSeconds
1002
2002
4002
8002
16002

horace:
but it can be simpler to implement one in loop() and the othere in an interrupt service routine

You may find it simpler, but you have to put yourself in the place of a newcomer and appreciate how difficult it would be for him or her.

...R

Thank you guys for responding, love the enthusiasm haha.
But still not progress remeber im not even as far that i know exactly what im typing.
I took what i learned from a few assignments and combined that to make this code.
What i learned in all of this that it`s way above my knowledge.

mark

The_GreadZero:
What i learned in all of this that it`s way above my knowledge.

I understand that it may be above your present level of knowledge but I also think you will have no trouble learning what you need to know if your take it slowly.

Have you studied the link I gave you in Reply #3? If there is something in it that you are having trouble with let us know and I will try to help.

...R