You are on page 1of 5

/*

* Ardulab firmware 0.04
*
* febrero 2012
*
* www.complubot.org
*/

#define VERSION "0.04"

#include <Servo.h>
//varibles para el control de servos
Servo servos[3];
byte n_servo, pin_servo;
//Prototipos de funciones
int espera_byte();
void envia_ok();
void activa_salida_digital(int salida, int estado);
void actiba_salidas_byte(int salidas);
int lee_entrada_digital(int entrada);
int lee_entrada_analogica(int entrada);
int promedia_entrada_analogica(int entrada, int promedios);
void activa_pwm (int pin, int valor);
void genera_tono (int pin, int frecuencia, int duracion);
//Variables globales
int comando, dato, dato2, dato3, envio;

void setup()
{
Serial.begin(115200);
}

void loop()
{
if (Serial.available() > 0)
{
comando = Serial.read();

switch(comando)
{
case 'a':
//Entrada analogica
//Lee una entrada analogica y envia los 10 bits de la medida en dos byt
es
//primer byte: [b7, b6, b5, b4, b3, b2, b1, b0]
//segundo byte: [0, 0, 0, 0, 0, 0, b9, b8]
dato = espera_byte();
envio = lee_entrada_analogica(dato);
Serial.write(envio & 0x00FF);
Serial.write((envio & 0x0300)>>8);
break;

case 'B':
//Control de salida digital en forma de byte
//Este comando se usa para el secuenciador
//controla S[11,10,9,8,7,6,5,4] con b[7,6,5,4,3,2,1,0]
//siendo "S" el número de la salida de la placa Arduino
//y "b" el bit correspondiente del byte recibido
dato = espera_byte();
actiba_salidas_byte(dato);
envia_ok();
break;

case 'A':
//Salida analogica (PWM)
//Controlamos una de las salidas PWM
//
dato = espera_byte();
dato2 = espera_byte();
activa_pwm(dato,dato2);
envia_ok();
break;

case 'D':
//Salida digital
dato = espera_byte();

if (dato > 127)
{
//Salida a "1"
dato = dato & 127;
activa_salida_digital(dato,1);
}
else
{
//Salida a "0"
activa_salida_digital(dato,0);
}

envia_ok();
break;

case 'd':
//Entrada digital
dato = espera_byte();
envio = lee_entrada_digital(dato);
Serial.write(envio);
break;

case 'm':
//Entrada analogica con promedios
dato = espera_byte();
dato2 = espera_byte();
envio = promedia_entrada_analogica(dato,dato2);
Serial.write(envio & 0x00FF);
Serial.write((envio & 0x0300)>>8);
break;

case 'S':
//Control de servos
dato = espera_byte(); //control cxss pppp
// c = 1 => Atach servo ; c = 0 Detach servo
// ss [0..2] servo
// pppp pin asignado al servo

dato2 = espera_byte(); //posicion

n_servo = (dato & B00110000)>>4;
pin_servo = dato & B00001111;

if (bitRead(dato,7) ==1 )
{
//Comprueba si atach previo, si no, atach servo
if (servos[n_servo].attached() == false)
servos[n_servo].attach(pin_servo);

//Actualiza posicion del servo
servos[n_servo].write(dato2);
}
else
{
// Detach servo
servos[n_servo].detach();
}

envia_ok();
break;

case 'T':
//Salida en frecuencia con un d.c. del 50% en funcion de la tabla de no
tas musicales
dato = espera_byte(); //pin
dato2 = espera_byte(); //nota
dato3 = espera_byte(); //duracion
genera_tono(dato, dato2, dato3);
envia_ok();
break;

case 'v':
//Envia version
Serial.println(VERSION);
break;

default:
break;
}
}
}

int espera_byte()
{
while (Serial.available() == 0);

return (Serial.read());
}

void envia_ok()
{
Serial.print("K");
}

void activa_salida_digital(int salida, int estado)
{
if ((salida >1) && (salida < 20))
{
pinMode(salida, OUTPUT);
digitalWrite(salida, estado);
}
}

void actiba_salidas_byte(int salidas)
{
byte valor_puerto;

valor_puerto = salidas & 0x00FF;

DDRD = DDRD | B11110000; // configura 4..7 como salidas
DDRB = DDRB | B00001111; // configura 8..11 como salidas

PORTD = valor_puerto <<4;
PORTB = valor_puerto >>4;
}

int lee_entrada_digital(int entrada)
{
int respuesta = 255;

if ((entrada >1) && (entrada < 20))
{
pinMode(entrada, INPUT);
respuesta = digitalRead(entrada);
}

return (respuesta);
}

int lee_entrada_analogica(int entrada)
{
int respuesta = 0x0FFF;

if (entrada < 6)
{
respuesta = analogRead(entrada);
}

return (respuesta);
}

int promedia_entrada_analogica(int entrada, int promedios)
{
int x,respuesta = 0x0FFF;
long acumula=0;

if (entrada < 6)
{
for (x=0; x<promedios; x++)
acumula += analogRead(entrada);

acumula = acumula/promedios;
respuesta = acumula;
}

return (respuesta);
}

void activa_pwm (int pin, int valor)
{
if ((pin == 3)||(pin == 5)||(pin == 6)||(pin == 9)||(pin == 10)||(pin == 11))
{
analogWrite(pin,valor);
}
}

void genera_tono (int pin, int nota, int duracion)
{
//Tabla de notas musicales
//Dos octavas comenzando en C4
int frecuencias[] = {0, 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932
, 988,
1047, 1109, 1175, 1245, 1318, 1397, 1480, 1568, 1661, 1760, 1865, 1975 };

int frecuencia=0;

if (nota == 0)
{
//Paramos sonido
noTone(pin);
}
else
{
if (nota < 25)
frecuencia = frecuencias[nota];

if (duracion == 0)
{
//Genera sonido de forma continua hasta noTone, por seguridad ponemos un
limite de 10 segundos
tone(pin,frecuencia,10000);
}
else
{
tone(pin,frecuencia,duracion);
}
}
}