Hoy os mostrare como controlar un coche a radio control pero via bluetooth y ayudando me con PINGUINO.
La idea viene a rais de un MINI controlado por Android que venden en algunas tiendas y pensé, que sería facil de reproducir.
El control es basico pero he puesto un detalle muy interesante, ya que la dirección de este vehículo es exponencial ya que puedes indicarle que gire X grados (a diferencia de los coches de radio control tradicionales que son TOPE IZQUIERDA o TOPE DERECHA), para poder controlarlo finamente he puesto un servo para dirigirlo como si de un conductor se tratase, este puede girar la dirección tantos grados como le indiquemos, ahora en el ejemplo lo he puesto en máximos de ambos extremos, pero fácilmente puede indicarse que gire a la izquierda X grados.
El motor principal es controlado por un PUENTE H basico con BC548, y el pinguino es el tradicional 8bits 18f4550, el modulo bluetooth es el mismo que vengo utilizando en anteriores circuitos y facilmente comprable a traves de EBAY.
La comunicación bluetooth la realizo con un ordenador MAC, pero puede realizarse con cualquier equipo o distribución ya que utiliza los protocolos RS232 sobre Bluetooth, generando una interfaz serie virtual en el equipo cliente.
Tambien el código de PROCESSING es muy fácil y conciso, exportable a java para ser reproducido en cualquier ordenador.
Dejo el código fuente para que cada uno lo reproduzca en su PC de casa sea cual sea la distribución.
Este es el código de PINGUINO
[sourcecode language=»py»]
// PCBC v1
// Pinguino Car Bluetooth Control v1
// Walii.es 2011
// pinguino.walii.es
#define RUNLED PORTAbits.RA4
#define PIC18F4550 // control pin of servo
int counter; // counter used for interrupt
int position0=50; //pin0 servo vertical
int previous;
int i;
int key;
int pulseWidth = 20;
void setup()
{
T1CON=0x01; // configure timer 1
PIE1bits.TMR1IE=1; // set interrupt for timer 1
INTCON|=0xA0; // enable GIE and PEIE
for (i=1;i<8;i++) { //servos conections
pinMode(i,OUTPUT);
digitalWrite(i,LOW); // fixe un niveau 0 sur les sorties
}
pinMode(0,OUTPUT);
Serial.begin(9600);
}
void UserInterrupt()
{
if (PIR1bits.TMR1IF)
{
TMR1H=0xFF; // reload value timer 1
TMR1L=0x9C;
PIR1bits.TMR1IF=0; // clear interrupt flag
if (counter>position0+51) PORTBbits.RB0=0; // position
else PORTBbits.RB0=1;
if (counter==1500) counter=0; // value for ~20 mS
counter++;
}
}
void stop()
{
digitalWrite(2,LOW);
digitalWrite(1,LOW);
delay(10);
}
void stoptotal()
{
digitalWrite(2,LOW);
digitalWrite(1,LOW);
position0=50;
delay(10);
}
void w()
{
digitalWrite(2,HIGH);
digitalWrite(1,LOW);
}
void s()
{
digitalWrite(2,LOW);
digitalWrite(1,HIGH);
}
void a()
{
position0=10;
}
void d()
{
position0=80;
}
void q()
{
position0=10;
digitalWrite(2,HIGH);
digitalWrite(1,LOW);
}
void e()
{
position0=80;
digitalWrite(2,HIGH);
digitalWrite(1,LOW);
}
void z()
{
position0=80;
digitalWrite(2,LOW);
digitalWrite(1,HIGH);
}
void c()
{
position0=10;
digitalWrite(2,LOW);
digitalWrite(1,HIGH);
}
void loop()
{
if (Serial.available())
{
key=Serial.read();
if (key==’w’ && previous!=’w’) stop(),w();
if (key==’s’ && previous!=’s’) stop(),s();
if (key==’a’ && previous!=’a’) stop(),a();
if (key==’d’ && previous!=’d’) stop(),d();
if (key==’q’ && previous!=’q’) stop(),q();
if (key==’e’ && previous!=’e’) stop(),e();
if (key==’z’ && previous!=’z’) stop(),z();
if (key==’c’ && previous!=’c’) stop(),c();
previous=key;
} else; stoptotal();
Serial.printf(" %d", position0);
}
[/sourcecode]
y Este es el código de processing
[sourcecode language=»py»]
/**
PINGUINO CAR CONTROL via BLUETOOTH
Walii & walterleonardo
Pinguino.walii.es
*/
import processing.serial.*;
Serial myPort;
String port[];
int i;
final static int NORTH = 1;
final static int EAST = 2;
final static int SOUTH = 4;
final static int WEST = 8;
final static int STOP = 16;
int result;
float x,y;
void setup() {
size(512,400);
frameRate(30);
result = 0;
x = width/2;
y = height/2;
port=Serial.list();
println(port);
myPort=new Serial(this,port[10],9600);
}
void draw() {
background(0);
switch(result) {
case NORTH: myPort.write("w"); break;
case EAST: myPort.write("d"); break;
case SOUTH: myPort.write("s"); break;
case WEST: myPort.write("a"); break;
case NORTH|EAST: myPort.write("e"); break;
case NORTH|WEST: myPort.write("q"); break;
case SOUTH|EAST: myPort.write("c"); break;
case SOUTH|WEST: myPort.write("z"); break;
case STOP: myPort.write("x"); break;
}
fill(255);
rect(x,y,10,10);
}
void keyPressed(){
switch(key) {
case(‘w’):case(‘W’):result |=NORTH;break;
case(‘d’):case(‘D’):result |=EAST;break;
case(‘s’):case(‘S’):result |=SOUTH;break;
case(‘a’):case(‘A’):result |=WEST;break;
case(‘x’):case(‘X’):result |=STOP;break;
}
}
void keyReleased(){
switch(key) {
case(‘w’):case(‘W’):result ^=NORTH;break;
case(‘d’):case(‘D’):result ^=EAST;break;
case(‘s’):case(‘S’):result ^=SOUTH;break;
case(‘a’):case(‘A’):result ^=WEST;break;
case(‘x’):case(‘X’):result ^=STOP;break;
// case(‘w’):case(‘W’):result |=STOP;break;
// case(‘d’):case(‘D’):result |=STOP;break;
// case(‘s’):case(‘S’):result |=STOP;break;
// case(‘a’):case(‘A’):result |=STOP;break;
}
}
[/sourcecode]