2

Basically I want one LED to flash 5 times in the same amount of time it takes another LED to flash 4 times. This is what I have, but they are flashing independently and I need them to flash simultaneously.

//Making a 5/4 Polyrhythm with 2 LEDs
const int LED13 = 13;
const int LED7 = 7;
int i = 5; 

void setup() {
   pinMode(LED13, OUTPUT);
   pinMode(LED7, OUTPUT);
}

void loop() {

  for(i=0; i<5; i++)
  {
     digitalWrite (LED13, HIGH);
     delay(500);
     digitalWrite (LED13, LOW);
     delay(800);
  }

  for(i=0; i<4; i++)
  {
     digitalWrite (LED7, HIGH);
     delay(500);
     digitalWrite (LED7, LOW);
     delay(1000);
  }

}

James Waldby - jwpat7
  • 8,840
  • 3
  • 17
  • 32
  • Where it is feasible to do so, a problem with a simple ratio like this may be most readily addressed by running something at the least common multiple and acting, or not, on each output as appropriate. Likely this means you will need an event happening at 20 times the desired repeition rate, which (if you intend the flashes to be visible as such to a human), is not even remotely difficult for an Arduino to handle. One LED would flash on events 0, 4, 8, 12, and 16, and the other one events 0, 5, 10, and 15... – Chris Stratton Dec 11 '15 at 01:56
  • It is up to you to decide if you want each LED to be one for one 1/20th or something else, for example you could double the rate to 40x and generate distinct events for on and off. – Chris Stratton Dec 11 '15 at 01:58

2 Answers2

4

I generally calculate whether the led must be on or off, based on the current time.

//Making a 5/4 Polyrythm with 2 LEDs
const int LED13 = 13;
const int LED7 = 7;
int i = 5; 

void setup() {
   pinMode(LED13, OUTPUT);
   pinMode(LED7, OUTPUT);
}

void loop() {
    // led 13 flashes 5 times per interval of 6 seconds. So the led is on/off for 600ms ( 6000/(2*5) )
    // led  7 flashes 4 times per interval of 6 seconds. So the led is on/off for 750ms ( 6000/(2*4) )
    bool led13on = (millis()/600)%2!=0; // count the number of 600ms intevals have passed, and see if this number if odd or even. odd means led must be on, even means the led must be on
    bool led7on  = (millis()/750)%2!=0;
    digitalWrite (LED13, led13on);
    digitalWrite (LED7, led7on);
    delay(10);
}
Gerben
  • 11,286
  • 3
  • 20
  • 34
  • Thank you very much. Could you explain what the (millis() / 600) %2 means? Is the millis just the millisecond time (from 0 to 600) is modded (%) with 2 and if it comes out odd or even determines if the LED is on? – Scotch Jones Dec 04 '15 at 16:52
  • @JonStapchuck millis() is the number of milliseconds since the board powered on. This is then divided by 600, and if the result is odd, the LED turns on, otherwise it turns off. – NobodyNada Dec 04 '15 at 22:42
  • See the comments inside the code. – Gerben Dec 05 '15 at 15:13
1

See https://arduino.stackexchange.com/a/17929/6628 with code like:

const int onTime = 500;
const int measureTime = (int) (60*1000/10);  // 10 BPM, or 1500*4ms/measure
const int off4 = measureTime/4 - onTime;  // take care these don't go negative
const int off5 = measureTime/5 - onTime;  //
unsigned long next5;
unsigned long next4;


...
loop(){
  unsigned long now;
  now=millis();
  ...
  if(next5 < now) {
     if digitalRead(LED13) { next5 = now+off5;   digitalWrite(LED13,LOW );}
     else                  { next5 = now+onTime; digitalWrite(LED13,HIGH);}
  }
  if(next4 < now) {
     if digitalRead(LED7)  { next4 = now+off4;    digitalWrite(LED7,LOW );}
     else                  { next4 = now+onTime ; digitalWrite(LED7,HIGH);}
  }

}
Dave X
  • 2,332
  • 14
  • 28