Take the 2-minute tour ×
Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It's 100% free, no registration required.

I am trying to blink a led as well as switch a motor on/off parallely using attiny44A below is my code:

Pump Controller:

   digitalWrite(pump1, HIGH);
   delay(5000);
   digitalWrite(pump1, LOW);
   digitalWrite(pump2, HIGH);
   delay(5000);

Led Blink:

    digitalWrite(ledB, HIGH);
    delay(500);
    digitalWrite(ledB, LOW);
    delay(500);

How do I make this run paralley together

share|improve this question

3 Answers 3

up vote 5 down vote accepted

There are a few ways to go about it, such as using timer interrupts etc, but another way is to use a simple state machine to keep track of when events last occurred. Treat this as more as an example of how to do it because it's untested and I'm not an Arduino user so may have a few data types wrong. But one approach would be something like:

boolean led_on = false;
unsigned long led_toggle_ms = 0;
boolean pump1_on = false;
unsigned long pump_toggle_ms = 0;

void loop()
{
    if (millis() - led_toggle_ms >= 500)
    {
        led_toggle_ms = millis();
        led_on = !led_on;
        digitalWrite(ledB, led_on);
    }
    if (millis() - pump_toggle_ms >= 5000)
    {
        pump_toggle_ms = millis();
        pump1_on = !pump1_on;
        digitalWrite(pump1, pump1_on);
        digitalWrite(pump2, !pump1_on);
    }
}

By keeping track of the time something last occurred rather than using delay it allows the rest of the code to continue running. Note that as per the millis() documentation the value will overflow after approximately 50 days, so if you want the application to run for longer that will need to be taken in consideration. If you don't mind a momentary glitch after 50 days that could be something simple like:

if ((millis() - led_toggle_ms >= 500) || (millis() < led_toggle_ms))
share|improve this answer
    
Thanks this helped a lot –  Daniel Euchar Apr 24 at 18:40

You can also simulate some parallel tasks that runs at some preconfigured intervals.

Note: I used direct bitwise operation to control led blink, but you can do it using digitalWrite of course

#include <Arduino.h>

//------------------------------------------------------------------------------
// Declarations // should be in the .h file

#define THA 0
void threadA(unsigned long time);

#define THB 1
void threadB(unsigned long time);

#define THC 1
void threadC(unsigned long time);

//------------------------------------------------------------------------------
// Initializations

const unsigned int pump1 = _BV(0);  //0b00000001, bit position, bit 0 in PORTB, == digital pin 9
const unsigned int ledB = _BV(1); //0b00000010, bit position, bit 1 in PORTB, == digital pin 10

// Threads definitions
// You can add or remove threads here
void (*THREADS[])(unsigned long) = {threadA, threadB, threadC};
int THINT[] = {0, 500, 5000}; // Interval for each threads

//------------------------------------------------------------------------------
// Threads

// Main loop, no interval
void threadA(unsigned long time){

}

// Every 500ms
void threadB(unsigned long time){
  PORTB ^= ledB; // Just toggle a led ON/OFF on bit ledB on PORTB
}

// Every 5000ms
void threadC(unsigned long time){
  PORTB ^= pump1; // Toggle the motor
}

//------------------------------------------------------------------------------
// Arduino core

void setup(){
  DDRB |= ledB | pump1; // Enable ledB and pump1 as output
}

// The loop method handle threads by launching each threads one after the other when their time come
void loop(){
  const int nbThread = sizeof(THREADS)/sizeof(&threadA); // Number of threads
  unsigned long threadTime[nbThread];
  char nextThread = 0;

  while(1){
    if((threadTime[nextThread] + THINT[nextThread]) < millis()){
      threadTime[nextThread] = millis();
      (*THREADS[nextThread])(threadTime[nextThread]);
    }

    if(++nextThread >= nbThread)
      nextThread = 0;
  }
}
share|improve this answer

There are two ways of doing this. The crude way is to replace the

delay(5000);

in the pump controller code with 5 times the led blink code. Crude, but works. Not very flexible though...

To other way is to use timer interrupts. Basically, you start a timer and have it generate an interrupt at set intervals. You then count the interrupts and when you reach a certain number of 'pulses', you take the required action.

To do this, you have to know your arduiono's clock speed, set timer multipliers/dividers etc. and create to appropriate interrupt code. This is a but too much for an answer here, but a Google for 'timer interrupts' should help you get started.

Arduino has a timer library: http://playground.arduino.cc/Code/Timer - I'm not sure if there's something similar for the ATTiny.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.