Arduino fonera + web cgis AYUDA!

Buenas a todos!! , necesito un poquitin de ayuda porque estoy un poco perdido, hace poco que empezé en esto de arduino y estoy todavia aprendiendo pero voy haciendo varias cosillas. Os explico que estoy haciendo y cual es mi problema a ver como me podeis orientar XD.

Tengo una placa Arduino duemilanove conectada por serie a una fonera y tanto recibo datos como los envio remotamente, dentro de la fonera he includo una pequeña pagina web que me ejecuta cgi vamos los comandos que necesito para mover un motor dc y un servo de un coche ( servo para la direccion y motor para el movimiento adelante y atras) , cada uno de los botones me envia un comando a arduino que arduino interpreta como adelante, atras , derecha , izquierda, hasta ahi todo bien, para manejar tanto el servo como el motor utilizo una placa shield que me he diseñado yo con un l298 ( puente H), lo tengo todo funcionando, pero mi problema viene a la hora de ejecutar 2 acciones a la vez, me explico si pulso adelante este se mueve adelante pero si pulso izquierda se para y mueve las ruedas a la izquierda entonces no consigo girar me tiene loco os pego el codigo que estoy usando para si me podeis ayudar.

#include <Servo.h>

int value = 100; // VELOCIDAD MOTOR 0 / 255
Servo direccion; // DEFINO EL SERVO COMO DIRECCION
const int button_c = 16; // boton golpeo
int buttonc_state = 0; // estado variable golpe
const int button_izq = 15;
int buttonizq_state = 0;
const int button_der = 14;
int buttonder_state = 0;
int cmdByte;
int dataByte1, dataByte2, pin, valor,i;
int cmdByted;
int dataByte1d, dataByte2d, direc;
int codigo;
int micro = 9; // MICROPULSACIONES DE DESPLAZAMIENTO
int anterior = 0;
void setup() {
direccion.attach(3); // EL SERVO ESTA EN EL PIN 6
pinMode(4,OUTPUT); // DEFINO EL PIN 4 COMO SALIDA
pinMode(5,OUTPUT); // DEFINO EL PIN 5 COMO SALIDA
pinMode(7,OUTPUT); // DEFINO EL PIN 6 COMO SALIDA
pinMode(button_c, INPUT);
pinMode(button_izq, INPUT);
pinMode(button_der, INPUT);
Serial.begin(9600);

}

void adelante() { analogWrite(5,value); digitalWrite(4,LOW); digitalWrite(7,HIGH); }
void paro() { digitalWrite(5,0); digitalWrite(4,LOW); digitalWrite(7,HIGH); }
void atras() { analogWrite(5,value); digitalWrite(4,HIGH); digitalWrite(7,LOW); }
void izquierda() {direccion.write(60); }
void derecha() {direccion.write(120); }
void centro() {direccion.write(90); }
void adl_izq() { adelante(); izquierda(); }
void adl_der() { adelante(); derecha(); }
void atr_izq() { atras(); izquierda(); }
void atr_der() { atras(); derecha(); }
void adl_microstep() { adelante(); delay(micro); paro(); adelante(); delay(micro); paro(); }
void atr_microstep() { atras(); delay(micro); paro(); atras(); delay(micro); paro(); }
void atr_variando() { for ( int i = 0 ; i <= 127 ; i++ ) {analogWrite(5,i); digitalWrite(4,HIGH); digitalWrite(7,LOW); delay(15);} }
void adl_variando() { for ( int i = 0 ; i <= 127 ; i++ ) { analogWrite(5,i); digitalWrite(4,LOW); digitalWrite(7,HIGH); delay(15);} }

void loop () {

inicio:
direc=0;

if (Serial.available()) {
cmdByte=Serial.read();
if (cmdByte==72) {
while(! Serial.available()){}
dataByte1=Serial.read();
while(! Serial.available()){}
dataByte2=Serial.read();
direc=(dataByte2-48); //*10+dataByte2-48;
valor=(dataByte1-48);
}
}

if (valor==1) {do { centro(); adl_microstep(); delay(100); goto inicio;} while (valor==1);}
if (direc==1) {do { derecha(); delay (1000); centro(); goto inicio;} while (direc==1);}
if (direc==2) {do { izquierda(); delay (1000); centro(); goto inicio;} while (direc==2);}
if (valor==0) {do { paro(); delay (100); digitalWrite(13,HIGH); goto inicio;} while (valor==0);}
if (valor==2) {do { centro(); atr_microstep(); delay(100); goto inicio;} while (valor==2);}
}

GRACIAS POR AGUANTAR EL TOSTON :wink:

he mirado el código por encima, y creo que no he entendido muy bien la pregunta. No se si te refieres a que no puedes ejecutar las dos órdenes a la vez, si es eso... es normal puesto que no se pueden ejecutar las órdenes en paralelo. Posiblemente con DuinOS, si que se pueda o quizás haya alguna otra forma de hacerlo... ¿te referías a eso?

Yo también estoy trasteando con la fonera y arduino desde hace una semana. Actualmente le he puesto el firmware dd-wrt v24 R3, que es el último que contiene el "stty" y me permite cambiar la velocidad de transferencia serie a 9600bps. ¿ cómo lo estás haciendo tú ? ¿como has resuelto que el firmware no use la salida de serie para sus propósitos? ( en mi caso el sistema operativo escribe ciertos eventos en /dev/tts/0 como cuando alguien se conecta por ssh, o si hay algún fallo en alguna conexión )

por cierto, esta parte de código:

if (valor==1) {do { centro(); adl_microstep(); delay(100); goto inicio;} while (valor==1);} 
if (direc==1) {do { derecha(); delay (1000); centro(); goto inicio;} while (direc==1);}
if (direc==2) {do { izquierda(); delay (1000); centro(); goto inicio;} while (direc==2);}
if (valor==0) {do { paro(); delay (100); digitalWrite(13,HIGH); goto inicio;} while (valor==0);}
if (valor==2) {do { centro(); atr_microstep(); delay(100); goto inicio;} while (valor==2);}

está bastante mal estructurado, los goto se deben de evitar usar para que sea más legible :-P, el bucle do while nunca se ejecuta puesto que lo rompes con el goto. Es decir, nunca se llega a ejecutar la comprobación de while (...==...)

Si no me equivoco, ésto haría lo mismo

void loop () {
direc=0;


if (Serial.available()) {
 cmdByte=Serial.read();
 if (cmdByte==72) {
   while(! Serial.available()){}
   dataByte1=Serial.read();
   while(! Serial.available()){}
   dataByte2=Serial.read();
   direc=(dataByte2-48); //*10+dataByte2-48;
   valor=(dataByte1-48);
 }
}  



if (valor==1)  { centro(); adl_microstep(); delay(100); } 
if (direc==1)  { derecha(); delay (1000); centro(); } 
if (direc==2)  { izquierda(); delay (1000); centro(); } 
if (valor==0)  { paro(); delay (100); digitalWrite(13,HIGH);} 
if (valor==2)  { centro(); atr_microstep(); delay(100); } 

}

Gracias por responder, el problema viene cuando lo meto dentro del propio if ya que tengo que hacer una nueva lectura del puerto serie entonces se me queda metido dentro del if y no sale de el , estoy perdido totalmente. No se como hacer que al mandarle el comando adelante lo siga ejecutando constantemente y que pueda variar la direccion puff me lio yo mismo XD , es que como esta ahora no es practico puesto que al ejecutar el comando este se ejecuta hasta que le digo que direccion tomar...

El envio de datos lo hago mediante el la lectura por puerto serie del caracter H mayuscula que es el codigo ascci 78 seguido de dos digitos quedando de la siguiente manera H10 movimiento hacia adelante y si meto H11 es movimiento hacia adelante y la derecha , en teoria XD, el problema que comentas de la velocidad del puerto serie lo puedes solucionar cambiando el firmware por el OPENWRT que trabaja siempre en 9600 y no solo al principio como en DDwrt.

por lo que veo, tienes el siguiente problema:

Cuando ejecutas
if (direc==1) {do { derecha(); delay (1000); centro(); goto inicio;} while (direc==1);}
ó
if (direc==2) {do { izquierda(); delay (1000); centro(); goto inicio;} while (direc==2);}

giras las ruedas, y luego las vuelves a centrar. El problema es que como no puedes ejecutar dos órdenes a la vez ( adelante y girar ) pues no consigues girar el coche. Para conseguirlo tienes dos opciones:

  • Al girar no volver a dejar las ruedas centradas (las dejas giradas) y cada vez que realices una pulsación (izquierda o derecha) cambias el ángulo del servo. Y así cuando le des adelante mantendrá ese giro. Otra opción es que antes de volver a centrar el servo, des uno o dos pasos adelante.

ó

  • No para el motor del coche, es decir, en vez de fijar el valor del PWM del motor a 100, le das valores incrementales cada vez que pulses adelante o atrás y no volver a para el motor (mantiene la velocidad constante mientras no vuelvas a pulsar el botón frenar ).

Si quieres hacer algo más complejo, tendrás que trastear con DuinOS, para poder ejecutar dos instrucciones a la vez :-P.

¿te referías a eso? o no te estoy ayudando :stuck_out_tongue:

Puede que duinOS sea la solucion, pero no se si hay alguna pagina de referencia para iniciarme voy a googlear un poco a ver si encuentro algo, muchas gracias por tu ayuda!! :slight_smile:

pero vamos, todo depende de cómo lo vayas a controlar y que es lo que quieres hacer con él. Si vas a hacer una interfaz web... no te merece la pena usar DuinOS, yo simplemente haría que la instrucción de girar izquierda o girar derecha diese un paso adelante antes de poner las ruedes rectas.

DuinOS es más para robots que por ejemplo, los puedes manejar a deistancia con un joystick, por ejemplo un cuadricóptero de esos qeu están tan de moda, y necesitas que se esté ejecutando una tarea que controle la estabilidad del robot, para que el viento no lo tire etc...

La idea era hacer una cruceta basica con 4 posibles botones para no sobracargar la pagina ya que lo siguiente era ver la camara ip que tengo conectada a la fonera y remotamente poder controlar el vehiculo ver la imagen real y poder variar la altura de la camara y todo desde un telefono movil o portatil.
Por cierto no encuentro nada de duinOS referencias o manuales comandos..

Bueno parece que la solucion venia por utilizar duinOS, pero resulta que no es compatible con la libreria <servo.h>... sigo intentandolo

Hola
He visto vuestro post de que se puede conectar la fonera al arduino y me he puesto manos a la obra, pero me ha pasado como a GabrielPerales yo tengo instalada la DD-WRT v24-sp2 y me he podido conectar, pero la fonera no hace mas que pedirme login y darme datos de la versión, así que me he puesto a buscar y he encontrado esto:

http://www.geocities.jp/arduino_diecimila/wifi/a2p_ddwrt_en.html

Como puedes ver en el código del cliente viene como se identifica arduino con la fonera.

Espero que os sea útil.

vic20, te recomiendo que te pongas OpenWRT. De primeras, porque el DD-WRT, solo tiene puesta la conexión serie a 9600bps durante el arranque, después pasa a 115000bps, por lo que no puedes comunicarte con la arduino, con el comando stty puedes cambiar los baudios y ponerlo a 9600, pero ese comando no está en las últimas versiones del DD-Wrt. La última que lo lleva es la v24 RC3. De todas formas, he estado utilizando el openWRT que si que va a 9600 y además me ha gustado más. Pronto colgaré un tutorial explicandolo todo, que se que bastante gente interesada. :wink:

Hola.

Para comunicar con dd-wrt no tenia problemas, lo que hacia es poner el arduino a 115200 y recibía la información sin problemas, al final he puesto openwrt y ya he conseguido mandar comandos a arduino por red, gracias a la página de otro forero, Igor R

Ese tutorial puede ser interesante.
Gracias

¡vaya! creía que la arduino solo aceptaba conexión a 9600bps! :-S

muy buenas he me han surgido un par de dudas:
1.Para conectar la fonera, le conectais al conector RJ45 un usb que viene de arduino? o es que lo que haces es enviar informacion desde el pc a traves de la fonera hacia arduino.

podrias explicar un poco el montaje que tienes? por favor?

  1. como se podria hacer para recibir senyal de una camara puesta en el coche?

saludos y gracias

Aqui te las respondo:

  1. Conectas el puerto serie de la fonera con el del Arduino con un par de cables (antes de montarlo ten cuidado con el voltaje, tendrás que adaptarlo si quieres mandar del Arduino a la fonera)

Si entiendes un poco el inglés, aquí está explicado: http://www.geocities.jp/arduino_diecimila/wifi/index_en.html

  1. En qué coche? Estará junto a la fonera? Supongo que querrás una cámara IP.

Un saludo