Publi

Luces del coche fantástico con Arduino (I)

Leds con Arduino

Un pequeño proyecto con Arduino, para probar todas las salidas con posibilidad de PWM (pulse width modulation), es como una salida parecida a analógica, aunque lo que estamos haciendo es enviar pulsos cuadrados, el valor medio de la tensión será la tensión analógica que buscamos.

Os acordáis de aquella serie de los 80, El Coche Fantástico, en la que podíamos ver unas luces que se desplazaban de derecha a izquierda dejando un rastro, en eso me basé.

Montaje 1El montaje es muy sencillo, sólo tenemos que conectar diodos led a cada una de las salidas PWM de nuestro Arduino, los que utilizan ATmega328 o ATmega168 tendrán dichos pins en las salidas 3, 5, 6, 9, 10 y 11 ; las conexiones, las haremos a través de resistencias, depende de los diodos led que utilicemos, ya que la salida de cada pin de Arduino a nivel alto es de 5v, con unos 220 ó 330 ohmios basta, aunque yo he utilizado de 1K, no tenía otras a mano.fantastico_esquema

A partir de aquí nos podemos poner a introducir un pequeño programa. Aunque no es totalmente necesario, quise probar la programación orientada a objetos  (OOP) de este compilador, por lo que creé una clase LedManager. Más adelante, cuando tenga tiempo haré el código más bonito y legible, aunque por ahora, funciona.

Por otra parte, no saqué la clase como biblioteca, está todo en el mismo archivo de código fuente.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#define MAX_LEDS 6
#define LED_CHANGE_MS 90
#define LED_FADE_MS 2

class LedManager
{
public:
  ~LedManager();
  LedManager();
  LedManager(const int pin, const int fadems);
  void addLed(const int pin);
  void setFadeMs(const int fadems);
  void setLedChangeMs(const int ledchangems);
  void begin();
  void step();
private:  
  struct LedDef
  {
    int pin;
    int value;
    int step;
  };
  LedDef leds[MAX_LEDS];
  int ledcount;
  int fadems;
  int ledchangems;
  // Para probar el control de desbordamiento
  // int time;
  // int time2;
  unsigned long time;
  unsigned long time2;
  int direction;
  int currentled;
  int changes;

  void writeLed(int num, int value);
  void writeLed(int num);
};

LedManager::~LedManager()
{
}

LedManager::LedManager():fadems(LED_FADE_MS),
             ledcount(0),
             direction(1),
             ledchangems(LED_CHANGE_MS)
{
}

void LedManager::setLedChangeMs(const int ledchangems)
{
  this->ledchangems=ledchangems;
}

void LedManager::addLed(const int pin)
{
  leds[ledcount].pin=pin;
  leds[ledcount].value=0;
  leds[ledcount].step=-1;
  ledcount++;
  pinMode(pin, OUTPUT);
  writeLed(currentled, 0);
}

void LedManager::setFadeMs(const int fadems)
{
  this->fadems=fadems;
}

void LedManager::begin()
{
  time=millis();
  time2=time;
  currentled=0;
  changes=1;
  writeLed(currentled, 255);
}

void LedManager::step()
{
  int tmp=millis();

  // Controlamos el desbordamiento
  if (tmp<time2)
    time2=tmp;

  if (tmp<time)
    time=tmp;

  if ( (tmp>time2) && ( (tmp-time2)%fadems == 0) )
    {
      for (unsigned i=0; i<ledcount; i++)
    writeLed(i);
     
      time2=tmp;
    }
 
  if ( (tmp>time) &&  ( (tmp-time)%ledchangems ==0) )
    {
      if ( ( (direction>0) && (currentled==ledcount-1) ) ||
       ( (direction<0) && (currentled==0) ) )
    direction=-direction;
     
      currentled+=direction;
      writeLed(currentled, 255);
     
      time=tmp;
    }
     
}

void LedManager::writeLed(int num, int value)
{
  leds[num].value=value;
  analogWrite(leds[num].pin, leds[num].value);
}

void LedManager::writeLed(int num)
{
  int tmp=leds[num].value+leds[num].step;
  if ((tmp>0) && (tmp<255))
    {  
      leds[num].value=tmp;
      analogWrite(leds[num].pin, leds[num].value);
    }
}


const int ledpins[MAX_LEDS]={3, 5, 6, 9, 10, 11};
LedManager ledmgr;

void setup()
{
  Serial.begin(19200);
  for (unsigned i=0; i<MAX_LEDS; ++i)
    {
      ledmgr.addLed(ledpins[i]);
    }

  ledmgr.begin();  
}

void loop()
{
  ledmgr.step();
}

Otra cosa importante, es que podemos incluir este programa (3.1K aunque se puede optimizar algo más) en cualquier proyecto y que se ejecute junto con el resto del programa. Puede que estas luces sean parte de un robot, por ejemplo; la tarea de las luces se lanzará escribiendo ledmgr.step() y podremos seguir realizando las demás tareas del robot.

Bueno, ahora veréis que con este diseño escribo un código en principio innecesario, porque poniendo un condensador en paralelo con cada led puedo conseguir un efecto parecido, y no necesito controlar los valores analógicos de las salidas ni nada, sólo mover el 1 lógico de led en led, aunque eso me lo reservo para la segunda parte de este proyecto.

También podría interesarte...

There are 3 comments left Ir a comentario

  1. Pingback: Bitacoras.com /

  2. Pingback: BlogESfera.com /

  3. Pingback: Píldora: Modificar a mano la velocidad de los ventiladores de nuestro ordenador – Poesía Binaria /

Leave a Reply