Go Down

Topic: How to fade all 20 pins in and out ... (Read 1 time) previous topic - next topic

Nick Gammon

I got inspired by the recent post from someone who wanted to copy an input bit to an output. So I thought "why not use that to fade all 20 pins?".

This sketch is the result. It's based on the Fade example, but by adding in a pin change interrupt, we detect when the pin (pin 9) is pulsed and make all the other pins mirror it. Thus, all 20 pins fade in and out together.

Code: [Select]

int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

const byte pwmPin = 9;
const byte maxPin = 19;

ISR (PCINT0_vect)
{
static byte val = 0;

val = !val;
for (byte i = 0; i <= maxPin; i++)
   if (i != pwmPin)
     digitalWrite (i, val);
}

void setup()
  {
  for (byte i = 0; i <= maxPin; i++)
    pinMode (i, OUTPUT);

  // pin change interrupt
  PCMSK0 = _BV (PCINT1);  // only want pin 9
  PCIFR  = _BV (PCIF0);   // clear any outstanding interrupts
  PCICR |= _BV (PCIE0);   // enable pin change interrupts for PCINT7..0
  }   // end of setup

void loop() 
  {
  // set the brightness of pin 9:
  analogWrite(pwmPin, brightness);   

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 0 || brightness == 255)
    fadeAmount = -fadeAmount ;

  // wait for 30 milliseconds to see the dimming effect   
  delay(30);                           
}  // end of loop
http://www.gammon.com.au/electronics

CrossRoads

Okay, now arrange the 20 pins in a circle, and work the fade up & down around the circle ...
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Nick Gammon

Let me get my hammer and saw ...

It's a bit silly, I know, because you could just make a loop anyway that did it. But still it shows how you can mirror what is on one pin to be on another one if you need to.
http://www.gammon.com.au/electronics

Udo Klein

Nice for learning but it shows a significant amount of flicker. Most probably due to the slow digitalWrites. I would implement it along the lines of my knight rider http://blog.blinkenlight.net/experiments/removing-flicker/knight-rider-no-flicker/ or heartbeat http://blog.blinkenlight.net/experiments/removing-flicker/heartbeat/ examples.
Check out my experiments http://blog.blinkenlight.net

robtillaart


Code: [Select]
for (byte i = 0; i <= maxPin; i++)
   if (i != pwmPin)
     digitalWrite (i, val);


use direct port manipulations?
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Nick Gammon

Yes you could do that, but it obscures the basic idea, that you can react to a pin changing. It isn't fabulously practical as such (there would be easier ways of fading 20 LEDs).

Actually what would be interesting would be to try to make a ripple effect, and make use of the delay (eg. pin 1 causes pin 2 to change which causes pin 3 to change and so on).
http://www.gammon.com.au/electronics

Nick Gammon


use direct port manipulations?


OK, if you replace the ISR with:

Code: [Select]
ISR (PCINT0_vect)
{
if (PINB & _BV (1))   // D9
   PORTB = PORTC = PORTD = 0xFF;
else
   PORTB = PORTC = PORTD = 0;
}


Then it is smoother.


I would implement it along the lines of my knight rider ... examples.


Done! And I tested with your Blinkenlight Shield, Udo.
http://www.gammon.com.au/electronics

Go Up