Go Down

Topic: Encender luces led en coche controlado por bluetooth (Read 479 times) previous topic - next topic

3Dadicto

Buenas,

Me he hecho un coche controlado por bluetooth y le he puesto las luces del coche fantastico con leds.

El coche ya consigo manejarlo con el móvil por bluetooth pero cuando pongo las luces no me funciona, o sea, mejor dicho cuando pongo el void de las luces en el void loop no me funciona el bluetooth pero si las luces y cuando quito el void de las luces entonces si me funciona el bluetooth.
No se si me he explicado.

Adjunto el código.

A ver si alguien me puede echar una mano.

Gracias

Arduinito


Los delay detienen todo. Volvemos a lo de siempre, usar timers con millis() no delay().
Luego si pones las luces no puede entrarte en el bluetooth hasta finalizar y al acabar dará la vuelta al loop y sin tiempo necesario volverá a ejecutar las luces. 

El código es un poco... "repetitivo" Lo podrías hacer en un tercio de esas líneas. ¡Por cierto reitero hasta la saciedad, cuando se cogen dos códigos de internet y se unen sin entender da problemas!

Recomendación aparte de los millis() es que hagas o busques un código de leds mejor que ese.

3Dadicto

Ok, gracias

No soy programador y lo que se lo he aprendido por mi cuenta, pido perdón por los disparates que podáis ver en el código.

Según he visto, con millis no se detiene el microprocesador y se pueden hacer cosas en paralelo, no?  


Arduinito

#3
May 07, 2017, 02:32 pm Last Edit: May 07, 2017, 02:34 pm by Arduinito
Ok, gracias

No soy programador y lo que se lo he aprendido por mi cuenta, pido perdón por los disparates que podáis ver en el código.

Según he visto, con millis no se detiene el microprocesador y se pueden hacer cosas en paralelo, no? 


No hay que disculparse, lo que hay que tener cuidado con los tutoriales que hay sobre arduino porque el 90% de los códigos como son ejemplos y para no liar a quienes empiezan usan delay(). Piensa que hasta los propios libros de proyectos de Arduino usan delay para todo. Es decir que una vez se entienden las bases hay que salirse del camino de esos tutoriales.
Y sí, con millis() puedes hacer que algo se ejecute cada X tiempo, por ejemplo los leds, sin detener el resto del código.
Es un poco más tedioso de hacer al principio porque delay al ser más corto es intuitivo y un timer hay que hacer alguna línea más, no obstante también hay librerías ya hechas de timers usando millis() que te ahorrarán trabajo.

Hay muchos ejemplos de un timer hecho con millis en el foro, pero cualquier cosa pregunta aquí mismo.

3Dadicto

Ok, voy a buscar un ejemplo de un timer hecho con millis a ver si me aclaro.

Gracias

surbyte

He modificado tu código creando una máquina de estados para tu Luces
Dime si funciona como se espera.

Code: [Select]
/* Mecanum Wheel controlado por Bluetooth
 * APP: Arduino Bluetooth RC Car
 Creado por 3Dadicto
 Mayo 2017
 */

#define bluetooth Serial
#include <SoftwareSerial.h>
#include <AFMotor.h>


#define rxPin 10
#define txPin 9

// Creamos el puerto serie, le pasamos los pines que serán
// Tx (donde esta conectado en Rx del bluetooth)
// y Rx (donde esta conectado el Tx del bluetooth)
SoftwareSerial miPuertoSerie(rxPin, txPin);

// Definicion de motores

AF_DCMotor Motor1(1);  //Trasero Izquierdo
AF_DCMotor Motor2(2);  //Delantero Izquierdo
AF_DCMotor Motor3(3);  //Delantero Derecho
AF_DCMotor Motor4(4);  //Trasero Derecho

//Velocidades motores
int v1=150;  //velocidad de motor 1
int v2=150;  //velocidad de motor 2
int v3=175;  //velocidad de motor 3
int v4=175;  //velocidad de motor 4

//Luces Coche fantastico
int pinArray[] = {A0, A1, A2, A3, A4, A5};  // PINs
int count = 0;  // Contador
int espera = 30;  // Temporizador
byte estado = 0;
bool tipoCiclo  = true; // true Ascendente false descendente
unsigned long start;

void setup ()
{
delay(500); // wait for bluetooth module to start

// Y lo inicializamos como cualquier puerto serie

miPuertoSerie.begin(9600);

Serial.begin(9600);    // set up Serial library at 9600 bps

// Definimos la velocidad de los Motores. 255 es el 100% de la velocidad
Motor1.setSpeed(v1);         
Motor2.setSpeed(v2);
Motor3.setSpeed(v3);
Motor4.setSpeed(v4);

// Luces coche fantastico
for (count=0;count<6;count++) { // Configuramos todas los PINs de golpe
pinMode(pinArray[count], OUTPUT);
}
}

void Luces_coche_fantastico()
{   // count  = 0
// estado = 0
// valores de arranque

    switch (estado) {
    case 0: digitalWrite(pinArray[count], HIGH);
        start = millis()+espera;
    estado = 1;
    break;
    case 1: if (millis()> start) {
    if (tipoCiclo)
        digitalWrite(pinArray[count + 1], HIGH);
    else
        digitalWrite(pinArray[count - 1], HIGH);
    start = millis()+espera;
    estado = 2;
    }
    break;
    case 2: if (millis()> start) {
    digitalWrite(pinArray[count], LOW);
    start = millis()+espera*2;
    estado = 3;
    }
    break;
    case 3: if (millis()> start) { // termina el tiempo en LOW
    estado = 4;
    }
    break;
    case 4: if (tipoCiclo)
    if (++count > 4) { // fin ciclo ascendente
    count = 4;
        tipoCiclo = false; // cambio a modo descendente
       
    }
    else
        if (--count < 0) {
        count = 0;
        tipoCiclo = true;
        }
    estado = 0;
    break;
    }
}

void Adelante ()
{
Motor1.run(FORWARD);   
Motor2.run(FORWARD);
Motor3.run(FORWARD);
Motor4.run(FORWARD);
         
}

void Atras ()
{
Motor1.run(BACKWARD); 
Motor2.run(BACKWARD);
Motor3.run(BACKWARD);
Motor4.run(BACKWARD); 
}


void Parar ()
{
Motor1.run(RELEASE);   
Motor2.run(RELEASE);
Motor3.run(RELEASE);
Motor4.run(RELEASE);
}


void Izquierda() 
{
    Motor1.run(FORWARD); 
    Motor2.run(BACKWARD);
    Motor3.run(FORWARD);
    Motor4.run(BACKWARD);
}


void Derecha()
{
    Motor1.run(BACKWARD); 
    Motor2.run(FORWARD);
    Motor3.run(BACKWARD);
    Motor4.run(FORWARD);
}


void Giro_Derecha() 
{
    Motor1.run(FORWARD); 
    Motor2.run(FORWARD);
    Motor3.run(BACKWARD);
    Motor4.run(BACKWARD);
}


void Giro_Izquierda() 
{
    Motor1.run(BACKWARD); 
    Motor2.run(BACKWARD);
    Motor3.run(FORWARD);
    Motor4.run(FORWARD);
}

void Diagonal_Derecha_Adelante() 
{
    Motor1.run(RELEASE); 
    Motor2.run(FORWARD);
    Motor3.run(RELEASE);
    Motor4.run(FORWARD);
}


void Diagonal_Izquierda_Adelante() 
{
    Motor1.run(FORWARD); 
    Motor2.run(RELEASE);
    Motor3.run(FORWARD);
    Motor4.run(RELEASE);
}

void Diagonal_Derecha_Atras() 
{
    Motor1.run(BACKWARD); 
    Motor2.run(RELEASE);
    Motor3.run(BACKWARD);
    Motor4.run(RELEASE);
}


void Diagonal_Izquierda_Atras() 
{
    Motor1.run(RELEASE); 
    Motor2.run(BACKWARD);
    Motor3.run(RELEASE);
    Motor4.run(BACKWARD);
}


void loop ()
{

Luces_coche_fantastico();

if (miPuertoSerie.available()) {
switch (miPuertoSerie.read())
{
case 'F':
Adelante();
break;
case 'B':
Atras();
break;
case 'R':
Derecha();
break;
case 'L':
Izquierda();
break;
case 'G':
Giro_Izquierda();
break;
case 'I':
Giro_Derecha();
break;
case 'H':
Diagonal_Izquierda_Atras();
break;
case 'J':
Diagonal_Derecha_Atras();
break;
case 'S':
Parar();
break;
default: break;
}
}
}

Arduinito

#6
May 08, 2017, 01:13 am Last Edit: May 08, 2017, 01:20 am by Arduinito
Vaaaaya surbyte se me adelantó  :'( :smiley-mr-green: :smiley-mr-green: :smiley-mr-green:.
Con tanto post de timers lo obligaré por ello a que revise mi librería de un uso de "timers" sencillito y con múltiples instancias. Ya sabes surbyte, serás molestado (no te asustes también sabes que me gustan los códigos reducidos).


Bueno yo quería enseñar un código de leds estilo K.I.T.T sin delay() porque hay cada ejemplo en internet que... en fin...
A mí me gusta el código en un párrafo.

Code: [Select]
#define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0]))

byte pinesLed[] = {3,4,5,6};
unsigned int intervalo = 500; //medio segundo
unsigned long tiempo;
bool direccion = true; //hacia la izquierda o la derecha
byte
contador = 0, //numeros de leds recorridos
indice = 0; //posición del array pinesLed por donde empezará a encenderse

void setup() {
  for (byte i = 0; i < ARRAY_LENGTH(pinesLed); i++) {
    pinMode(pinesLed[i], OUTPUT);
  }
  tiempo = millis();
}

void loop() {
  if(millis() >= tiempo + intervalo ){ // al pasar el tiempo
    for(byte i = 0; i < ARRAY_LENGTH(pinesLed); i++){ //recorremos todos los leds
      digitalWrite(pinesLed[i], (i == indice) ? HIGH : LOW); //encendemos el led que coincida con ese indice
    }
    if(contador == ARRAY_LENGTH(pinesLed) - 1){ // cada vez el contador sea igual al número de leds es que ha dado la vuelta
      direccion = !direccion; //cambiamos la dirección de encendido
      contador = 0; //reiniciamos el contador
    }
    indice += (direccion) ? 1 : - 1; //según la direccion movemos un índice hacia arriba o hacia abajo
    contador++; //aumentamos el contador
    tiempo = millis(); //reiniciamos el tiempo para el siguiente intervalo
  }
}


No te asustes, si quitas las líneas de comentarios verás que es corto y limpio.

Esquema:


Edito: Con este código no tendrás el problema con otras partes, millis() no detiene a diferencia de delay()
Ya algún día haré "publicidad" en Documentación de cierta web de índole personal donde hay muchos ejemplos realizados... un día que considere que hay suficiente contenido.  :smiley-draw: :smiley-mr-green:

3Dadicto

Muchísimas gracias a los dos, surbyte y Arduinito.

Da gusto entrar a un foro y que te ayuden de esta manera :)

3Dadicto

Bueno, pues ya he probado el código de surbyte y no termina de ir bien, se queda la segunda luz parpadeando y la tercera encendida.  Esos si, ahora puedo conectar el bluetooth sin problemas.

También he probado la propuesta de Arduinito y esta si funciona sin problemas.

Gracias

surbyte

Cambia los tiempos de espera = 30 a algo mayor. A mi me parece muy rápido.
Solo para ver que funciona correctamente ponle 250 o 500 en lugar de 30. Si esta lento luego lo bajas y se verá mas rápido.

Por cierto, no me gusta perder pero diré una cosa a mi favor:
Esta hecho en función de TU CODIGO, que supuse funciona. No lo analicé solo lo convertí en máquina de estado.

EDITO: Jajajaja que mal funciona jajaja.

Aca lo tienes corregido
Code: [Select]
void Luces_coche_fantastico()
{   // count  = 0
  // estado = 0
  // valores de arranque

    switch (estado) {
      case 0: digitalWrite(pinArray[count], HIGH);
              start = millis()+espera;
              estado = 1;
              break;
      case 1: if (millis()> start) {
                if (tipoCiclo)
                    digitalWrite(pinArray[count + 1], HIGH);
                else
                    digitalWrite(pinArray[count - 1], HIGH);
                start = millis()+espera;
                estado = 2;
              }
              break;
      case 2: if (millis()> start) {
                digitalWrite(pinArray[count], LOW);
                start = millis()+espera*2;
                estado = 3;
              }
              break;
      case 3: if (millis()> start) { // termina el tiempo en LOW
                estado = 4;
              }
              break;
      case 4: if (tipoCiclo) {
                  if (++count > 4) { // fin ciclo ascendente
                      count = 4;
                      tipoCiclo = false; // cambio a modo descendente
                  }
              }
              else {
                  if (--count < 0) {
                      count = 0;
                      tipoCiclo = true;
                  }
              }
              estado = 0;
              break;
    }
}


una tontería como siempre pasa

3Dadicto

Ahora si funciona pero al segundo ciclo se queda la primera luz encendida y ya no se apaga mientras las siguen funcionando bien.

Arduinito

#11
May 10, 2017, 11:45 pm Last Edit: May 10, 2017, 11:46 pm by Arduinito
Por cierto, no me gusta perder pero diré una cosa a mi favor:
Esta hecho en función de TU CODIGO, que supuse funciona. No lo analicé solo lo convertí en máquina de estado.
¿Perder? Yo no compito contigo, surbyte :smiley-cry: ¿Hace 5 meses quien me ayudaba por aquí (y lo que me queda por aprender)? Lo que yo no partía de cero, sino que C lo ví en mi primer año de estudios y de eso hace ¿8-9 años quizás? Pero resto de lenguajes lo que quieras.
Bromas aparte, sé que nadie compite aquí, te doy la razón. No es lo mismo hacer un código en base a un enunciado como hice yo que adaptar el código de otro, que es muchísimo más difícil sobre todo si está muy alejado a tu forma de hacer las cosas. Es más, es duro evaluar un código a nivel de profesorado o como examen previo a una entrevista de trabajo.

A comentar sólo para 3Dadicto que ambos códigos pese a que funciona la edición de su código proporcionada por surbyte apaga el led tras encender el siguiente y en mi caso se apagan todos menos el correspondiente. Ambas opciones son válidas y ambas opciones se pueden transformar en el funcionamiento del otro. Para gustos colores.

¿Resuelto entonces? Por lo de editar el título añadiendo "Solucionado / Resuelto".

Un saludo.

Go Up