Un PIC o cualquier integrado no manejan demasiada corriente, y si pones varios leds tampoco maneja mas que 5V, asi que lo que lo mas comun es utilizar un transistor NPN, por ejemplo esto es para un rele, que normalmente se maneja a 12V y tiene su consumo mas grande
En ves del rele podrias poner tus diodos leds.
Otra forma que es mas compacta, pero depende de la cantidad de corriente que pase por los mismos es utilizar un integrado que es el ULN2003A. Lo bueno es que no necesitas componentes externos ya que lo posee todo el integrado:
http://www.ti.com/lit/ds/symlink/ulq2003a.pdfSupone que el de la izquierda es tu PIC.
Lo malo es que necesitas un poco mas de tension de alimentacion.
Hilando un poco mas finoEl procedimiento es igual para ambos en la seccion de salida.
En la entrada, solo para cuando usas un transistor conectado de la forma que mostre, debes preocuparte por simplemente saturar el transistor, ya que estamos tratando de utilizarlo como un switch
Si usas una resitencia de 4.7K el PIC solo pondria 1mA sobre ese pin.
El ULN2003A ya posee resistencia interna asi que no te preocuparias.
SalidaEsta parte es la involucra la carga ( resistencia + led ). Y lo que mas hay que tener en cuenta es la caida minima de tension que puede dar el transistor, esto esta dado por Vce saturacion en los datasheet.
Siguiendo el ejemplo de antes. Deberia poder cumplirse que:
Valimentacion = Vled + Vtransistor + Vresistencia
//Igual a
Valimentacion = Vled + VceSat + Iled * R
Ejemplo : Si el led tiene 3V, y lo alimentamos con 5V el transistor deberia tener un Vce menor a 2V ( suponiendo nula la resistencia), el BC548A mirando su datasheet dice que su VceSat pra una Ic de 100mA es de 200mV a 600mV ( 0.2 a 0.6V ) lo cual este transistor va a servir. Ahora deberiamos calcular la resistencia. Suponemos una corriente de 120mA
Valimentacion = Vled + VceSat + I * R
5V = 3V + 0.2V + 120mA * R
R = 15ohms
Ahora si Usamos el ULN2003A como es un par de transistores ( conectados en darlington ) va a tener una mayor tension de VceSat.
Mirando el datasheet si observas el VceSat para 100mA es de 0.9 a 1.2V. Si hacemos el mismo ejemplo que antes
Valimentacion = Vled + VceSat + I * R
5V = 3V + 0.9V + 120mA * R
R = 9.16ohms
Utilizo el valor tipico y no el maximo, de esa forma si en ves de 0.9 ofrece 1.1V la corriente nunca es superior al limite que le dimos. Para proteger al led.
Si tenes otra tension de alimentacion, la resistencia sera distinta.
--------------------------------
Si usas la interrupcion, esto te podria servir:
#include <stdint.h>
struct DestelloLed
{
uint8_t Cantidad;
uint8_t RepetirVeces;
const uint8_t * patron;
const uint8_t * delaypatron;
};
// Patrones, todos
const uint8_t patron1[] = {0b00000000,0b01111110}; //10
const uint8_t dpatron1[] = {100,50}; //10
const uint8_t patron2[] = {0b00001110,0b01110000,0b00000000}; //10
const uint8_t dpatron2[] = {150,150,50}; //10
const uint8_t patron3[] = {0b00000000,0b00011000,0b00111100,0b01111110,0b00111100,0b00011000,0b00000000}; //5
const uint8_t dpatron3[] = {50,50,50,50,50,50,50}; //5
const uint8_t patron4[] = {0b00000000,0b01000010,0b00100100,0b00011000,0b00000000,0b00011000,0b00100100,0b01000010,0b00000000,0b01111110,0b00000000}; //5
const uint8_t dpatron4[] = {50,50,50,50,50,50,50,50,50,50,50}; //5
const uint8_t patron5[] = {0b00000000,0b01000010,0b01100110,0b01111110,0b00000000}; //5
const uint8_t dpatron5[] = {50,50,50,50,50}; //5
// Estructuras con los patrones
const struct DestelloLed Spatron1 = {sizeof patron1,10,patron1,dpatron1};
const struct DestelloLed Spatron2 = {sizeof patron2,10,patron2,dpatron2};
const struct DestelloLed Spatron3 = {sizeof patron3,5,patron3,dpatron3};
const struct DestelloLed Spatron4 = {sizeof patron4,5,patron4,dpatron4};
const struct DestelloLed Spatron5 = {sizeof patron5,5,patron5,dpatron5};
const struct DestelloLed * Patrones[] = {&Spatron1,&Spatron2,&Spatron3,&Spatron4,&Spatron5};
volatile int1 activo=1;
void main()
{
while(1)
{
if(activo)
{
unsigned int i,j,k;
for(i=0;i < (sizeof Patrones/sizeof Patrones[0]);i++)
{
for(j=0;j < Patrones[i]->RepetirVeces;j++)
{
for(k=0;k < Patrones[i]->Cantidad;k++)
{
if(!activo) break;
output_b(Patrones[i]->patron[k]);
delay_ms(Patrones[i]->delaypatron[k]);
}
}
}
}
}
}
Solo decirte que te falta configurar la interrupcion, y crear la funcion de interrupcion que lo unico que haga es :
activo ^= 1;
Y listo.
En este codigo, Si queres modificar los patrones simplemente tenes que cambiar estos:
const uint8_t patron1[] = {0b00000000,0b01111110}; //10
const uint8_t dpatron1[] = {100,50}; //10
Ejemplo, si quiero cambiar el delay del 0b00000000 a 70 quedaria asi:
const uint8_t patron1[] = {0b00000000,0b01111110}; //10
const uint8_t dpatron1[] = {70,50}; //10
Si quiero agregarle 1 forma mas, agrego en ambos, el valor del puerto y ademas el delay:
const uint8_t patron1[] = {0b00000000,0b01111110,0b00011000}; //10
const uint8_t dpatron1[] = {100,50,50}; //10
Si quiero agregar un patron totalmente nuevo, creo uno que se llame patron6 por ejemplo respetando que siempre dpatron6 tenga la misma cantidad de elementos.
Creo la estructura y finalmente lo agrego. La estructura se forma con la cantidad de elementos ( eso lo ahce solo el sizeof), las veces a repetirse y las direcciones del patron y su delay
Ejemplo, patron6 que se repita 7 veces:
const uint8_t patron6[] = {0b10101010,0b01010101};
const uint8_t dpatron6[] = {50,50};
const struct DestelloLed Spatron6 = {sizeof patron6,7,patron6,dpatron6};
// Finalmente lo agrego al ultimo:
const struct DestelloLed * Patrones[] = {&Spatron1,&Spatron2,&Spatron3,&Spatron4,&Spatron5,&Spatron6};
Si queres cambiar solo el orden de los patrones, podes hacerlo simplemente modificando lo ultimo, ejemplo, que haga en este orden 4, 3, 1, 2 y 5
const struct DestelloLed * Patrones[] = {&Spatron4,&Spatron3,&Spatron1,&Spatron2,&Spatron5};
PD: Este programa ocupa 20% del PIC16F84A
Me olvide decirte que si vas a usar un PIC, busques otro, porque el PIC16F84A es muy viejo y CARO, hay micros mucho mas baratos y mejores. Busca el que tenga los suficientes pines como para que puedas manejarte con esto donde sea que lo compres y de ahi empeza. Ya que tu proyecto no requiere demasiado micro