Proyecto luces RC "sencillas"

Hola a todos!!! después de rebuscar y probar varias maneras, os expongo aquí mi pequeño proyecto; Se trata de controlar las luces de freno y marcha atras aprovechando el canal pwm del receptor que va también al variador del coche… he estado leyendo y he conseguido lo que os expongo aquí, pero mi intención era que me pudiera diferenciar el estado de freno del de marcha atras, pero no lo consigo… a ver si me podéis ayudar! muchas gracias!!

int LEDFRENO = 9;
int LEDLUCESDELANTERAS = 8;
byte PWM_PIN = 3;
const int freno_min = 1680; 
const int freno_max = 1942;
const int neutro_min = 1535;
const int neutro_max = 1539;
const int gas_min = 1100;
const int gas_max = 1500;
int pwm_value;
int contador=0;
boolean freno_last=false;
boolean freno=false;
boolean gas=false;
boolean neutro=false;
boolean atras=false;
 
 
void setup() {
  pinMode(PWM_PIN, INPUT);
  pinMode(LEDFRENO, OUTPUT);
  Serial.begin(115200);
}
 
void loop() {
  analogWrite(LEDFRENO,0);
  pwm_value = pulseIn(PWM_PIN, HIGH);
  //Serial.println(pwm_value);
 if (pwm_value >= freno_min && pwm_value <= freno_max){
    freno=true;
    gas=false;
    neutro=false;
    atras=true;
    Serial.println("FRENO!!!");
    analogWrite(LEDFRENO,255 );
    }
 //   delay(250);
  if (pwm_value <= neutro_max && pwm_value >= neutro_min){
    Serial.println("NEUTRO!!");
    freno=false;
    gas=false;
    neutro=true;
    atras=false;
    }
  if (pwm_value <= gas_max && pwm_value >= gas_min){
    Serial.println("GAS!!!");
    freno=false;
    gas=true;
    neutro=false;
    atras=false;
    }
  if (freno==true && neutro==true){
     contador=++contador;
     Serial.println(contador,DEC);
    }
  if (contador >=30 && freno==true){
    contador=0;
    freno=false;
    gas=false;
    neutro=false;
    atras=false;
    digitalWrite(LEDFRENO,LOW);
    }
  delay(100);
  
}

Y dime como podemos ayudarte? Para hacerlo no haría falta un diagramade tiempos de las luces que mencionas? Tu estas haciendo esto como prueba error pero nosotros no contamos con las luces de tu auto y entonces es dificil aconsejarte.

No mencionas el vehículo, no has aportado ningún enlace que clarifique lo que estas haciendo o un diagrama de tiempos en un borrador que diga como son los tiempos.

todo se basa en medir el ancho de pulso de modo que en principio esta bien. No entiendo porque en cada if, ajustas todas las variables bool No es mas facil negarlas todos al comienzo del loop y activar la que se cumpla.?

Gracias por responder!!! te comento mi intención para ver si puedo aportar mas datos;

La instalación es bastante simple; son dos leds de 3mm de color rojo y dos leds de color blanco de 3mm para simular la luz de marcha atrás. Los leds tienen un consumo de unos 8-15mA e irán montados en la carrocería de un coche de radio-control fabricado artesanal.

Con el código que he publicado, lo que quiero conseguir es lo siguiente:

con el coche funcionando en dirección normal la luz de freno debe permanecer encendida, pero a una intensidad luminosa menor que cuando esta frenando

cuando el coche esta frenando (detectando los valores pwm entre 1680 y 1942) los dos led rojos que están encendidos), se iluminan con una intensidad mas alta, que simulan el sistema de frenado normal de un vehículo real

A partir de aquí es donde tengo el problema; se supone que para que entre la marcha atrás, y se iluminen los led blancos, debe cumplirse esta secuencia: frenado (valores pwm entre 1680 y 1942) ---- volver a punto neutro (valor pwm entre 1535 y 1539) y volver a la posición de frenado (valores pwm entre 1980 y 1942)

después de encenderse los led blancos, que se mantengan encendidos hasta que se vuelvan a detectar los valores de dirección normal (detectando los valores pwm correspondientes al gas, que van entre 1100 y 1500). En ese momento los leds blancos apagan y solo permanecen encendidos los rojos en intensidad luminosa mejor

Agradezco mucho tu ayuda!!!

Estimado usuario! Este foro está moderado y se detectó su mal comportamiento sin justificación alguna. Hoy le fue borrado el contenido de su publicación, en la próxima oportunidad, que espero que no se presente nunca más. Ud será sancionado! Héctor

Venga, motoreto; intentemos ser constructivos ;). Si te soy sincero, la frase

Se trata de controlar las luces de freno y marcha atras aprovechando el canal pwm del receptor que va también al variador del coche

tal vez sea muy fácil de entender para el aficionado a radiocontrol (a mí me gusta mucho verlo, pero no tengo ni idea); pero a mí me hizo abandonar el intentar ayudar, pues no sabía por dónde iban los tiros. Con el segundo post que ha puesto ya lo veo mucho más claro, pues entiendo qué quiere hacer. DavidTGN: Ahora mismo no tengo tiempo, pero igual esta noche puedo proponerte un código sobre el que puedas trabajar. La ideas generales serían:

Una variable enum de estado actual del vehículo (andando, frenando, parado, marcha atrás). Una variable enum de estado del variador (ahora entiendo que es algo así como el acelerador) (andando, neutro, frenado). Leer el variador, y establecer la variable estado del variador. (primer grupo de if) Sabiendo el estado actual del vehículo y el estado actual del variador tomar decisiones y establecer nuevo estado del vehículo. (segundo grupo de if) Ajustar luces al estado actual del vehículo (switch / case)

Igual así te parece complicado, pero ya verás que no lo es tanto.

Primero vamos a armar un programa que detecte los anchos de pulso que refieres. Dame un tiempito... o lo esperamos al que menosprecia mis respuestas, tal vez el aporte algo, mas allá de su comentarios fuera de lugar?

Cuando te pedia enlaces era porque entendía por tu primer post que hablabas de un vehículo de línea, de una marca X, no que era un RC. No vi tu título o no lo entendí.

Este es el tipo de diagrama de tiempos que te pedía y que clarificaría tu problema con los tiempos indicados claro está. |500x265

Bueno; lo prometido es deuda. Mira a ver si entiendes este código y si puede servirte para decidir en el switch del final cómo establecer las luces. No está probado, pero al menos sí compila y creo que te puede dar alguna pista de por dónde tirar.

byte PWM_PIN = 3;
const int gas_min = 1100;
const int gas_max = 1500;
const int neutro_min = 1535;
const int neutro_max = 1539;
const int freno_min = 1680; 
const int freno_max = 1942;

int contador=0;

enum {marchando, frenando, parado, atras} estadoCoche = parado;
enum {indeterminado, gas, neutro, freno} estadoMando, estadoMandoAnt;

void setup() {
  pinMode(PWM_PIN, INPUT);
  Serial.begin(115200);
}

void loop() {
  int pwm_value = pulseIn(PWM_PIN, HIGH);

  // Estado del mando será indeterminado, de no cumplirse ninguna de las siguientes combinaciones
  estadoMando = indeterminado;
  if (pwm_value <= gas_max && pwm_value >= gas_min){
    estadoMando = gas;
  } 
  else if (pwm_value <= neutro_max && pwm_value >= neutro_min){
    estadoMando = neutro;
  } 
  else if (pwm_value >= freno_min && pwm_value <= freno_max){
    estadoMando = freno;
  }

  //si ha cambiado el estado del mando
  if (estadoMando != estadoMandoAnt) {
    estadoMandoAnt = estadoMando;
    if (estadoMando == gas) { // si estamos acelerando
      estadoCoche = marchando;
    }
    else if (estadoMando == neutro) { // si estamos en neutro
      estadoCoche = parado;
    }
    else if (estadoMando == freno) { // si estamos frenando con el mando
      if (estadoCoche == parado) { // y el coche estaba en parado o bien ya estaba marcha atrás
        estadoCoche = atras; // estamos marcha atrás 
      }
      else {
        estadoCoche = frenando; // si no estabamos en neutro estamos frenando
      }
    }

    // Aquí deberíamos establecer la iluminación para cada situación
    switch (estadoCoche) {
      case marchando:
      Serial.println(F("Arreeee"));
      break;
      case parado:
      Serial.println(F("ZZZZZZZZZ"));
      break;
      case atras:
      Serial.println(F("Patrasssss"));
      break;
      case frenando:
      Serial.println(F("Soooooo"));
      break;
    }
  }
  delay(100);
}

Supongo que ya sabes que hay unos rangos del acelerador que están indeterminados, pues has dejado “huecos” en los valores pwm.
Saludos

Hola a todos, como ya le he comentado al compañero noter por privado;

Agradezco a todos las respuestas sobre el tema. La verdad es que he estado apartado durante una semana y media de la vida normal sin poderme dedicar en el proyecto.

El esquema que propone el compañero, lo probare durante los próximos días y os comentaré como ha ido; Aparte, quiero agradecer a todos los que han colaborado en esta idea, en especial a surbyte y al compañero mencionado lineas arriba. Entiendo que tiene que ser muy frustrante estar ayudando a gente constantemente y al final no te llevas ni las "gracias". Si entre todos conseguimos que funcione, se quedara la información aquí publicada y si los compañeros que han ayudado, están conforme, se repartiría en los foros especializados en radiocontrol.

Os agradezco a todos la ayuda, ojala pudiera ayudar yo mas, pero no soy tan apañao como vosotros!!!

Si el mal redactado de mi proyecto, ha prestado a confusión, pido disculpas.

noter los rangos del acelerador que están indeterminados (los "huecos" los he dejado debido a que la posición pwm no es siempre 100% exacta, es decir, los extremos de los valores de el punto neutro, a veces varían dos o tres valores +-, opté por dejar ese rango para no falsear las lecturas de los valores.

gracias!

Hola. Acabo de realizar una pequeña modificación al código anterior. Justo después de la comparación if (estadoMando != estadoMandoAnterior) había, evidentemente que poner estadoMandoAnterior = estadoMando. Saludos.

Hola de nuevo

Acabo de probar el codigo que publicaste y solo consigo que funcione el estado neutro y el estado adelante.. he comprobado los valores pwm y son los correctos. Durante este fin de semana investigaré por que en el monitor serie no se reflejan los estados Patrasss y Soooo! :D

Saludos!!

De momento cambia en línea 45 if (estadoCoche==neutro || ... por... if (estadoCoche==parado ||... ya que neutro es un estado de pedal, no de coche. Seguimos revisando.

buenas noter;

He probado los cambios que has sugerido y el resultado es el siguiente:

Si la emisora esta en la posición "ZZZZZZ" al accionar el freno, no aparece el estado "sooo"

eso si; si paso de la posición de gas "arreeeee" rápidamente a la posición "sooo"; si que aparece el estado "sooo"

el estado "patras" se resiste....

muchísimas gracias por tu ayuda!!!

¡¡¡Venga!!!

¡Vamos a buscar una buena pared y a darnos cabezazos!

estadoCoche == atras;

¡He comparado en vez de asignar!
Lo he editado en el post del código que te propuse.

No obstante, te propongo este otro para que no tengas que pasar rápidamente de “arre” a “sooo”. Creo que no considerará el coche en “Zzzzzzz” si no hay freno anteriormente, así que si has dejado parar suavemente el coche sin frenar, deberás frenar-neutro-frenar para que entre el “patrass”, que creo que era lo que buscabas.
Como ves, también he sustituido los if de estadopedal por otro switch, que es lo normal cuando evaluamos varias posibilidades para una misma variable, en lugar de else-if.

byte PWM_PIN = 3;
const int gas_min = 1100;
const int gas_max = 1500;
const int neutro_min = 1535;
const int neutro_max = 1539;
const int freno_min = 1680; 
const int freno_max = 1942;

int contador=0;

enum {marchando, frenando, parado, atras} estadoCoche = parado;
enum {indeterminado, gas, neutro, freno} estadoMando, estadoMandoAnt;

void setup() {
  pinMode(PWM_PIN, INPUT);
  Serial.begin(115200);
}

void loop() {
  int pwm_value = pulseIn(PWM_PIN, HIGH);

  // Estado del mando será indeterminado, de no cumplirse ninguna de las siguientes combinaciones
  estadoMando = indeterminado;
  if (pwm_value <= gas_max && pwm_value >= gas_min){
    estadoMando = gas;
  } 
  else if (pwm_value <= neutro_max && pwm_value >= neutro_min){
    estadoMando = neutro;
  } 
  else if (pwm_value >= freno_min && pwm_value <= freno_max){
    estadoMando = freno;
  }

  //si ha cambiado el estado del mando
  if (estadoMando != estadoMandoAnt) {
    estadoMandoAnt = estadoMando;
    switch (estadoMando) {
      case gas:
        estadoCoche = marchando;
        break;
      case neutro:
        if (estadoCoche == frenando) {
          estadoCoche = parado;
        }
        break;
      case freno:
        if (estadoCoche == parado) { // y el coche estaba en parado o bien ya estaba marcha atrás
          estadoCoche = atras; // estamos marcha atrás 
        }
        else {
          estadoCoche = frenando; // si no estabamos en neutro estamos frenando
        }
        break;
      default:
        Serial.println(F("Estado de mando indeterminado"));
    }
    // Aquí deberíamos establecer la iluminación para cada situación
    switch (estadoCoche) {
      case marchando:
        Serial.println(F("Arreeee"));
        break;
      case parado:
        Serial.println(F("ZZZZZZZZZ"));
        break;
      case atras:
        Serial.println(F("Patrasssss"));
        break;
      case frenando:
        Serial.println(F("Soooooo"));
        break;
    }
  }
  delay(100);
}

Pd: como se te pegue esta jerga que nos hemos inventado y se te escape delante de otros radioaficionados (“Le he colocado a mi coche unas luces de patrás y sooo”), igual te linchan :P.

Muchas gracias por ayudarme noter!!!! cuando llegue a casa lo pruebo y te comento...

por cierto, las anteriores pruebas las he realizado en casa de un amigo y alguna risa si que se nos escapa con los mensajes del serial monitor... :stuck_out_tongue:

es posible que la placa se "confunda" al leer tantas señales en tan poco tiempo??

Saludos!

es posible que la placa se "confunda" al leer tantas señales en tan poco tiempo??

El único que se ¨confude¨ es uno mismo al programarlas. El programa hace lo que uno le dice que haga. Si comete errores es porque no hemos contemplado alguna condición o nuestras condiciones se superponen y no las vemos.

Estoy de acuerdo con surbyte. El confundido, el 99,999% de las veces es el usuario (en mi experiencia propia el 100%), y en esta ocasión (cómo no) también. Aunque espero y deseo que nos estamos acercando al objetivo, ¿no?

Hola de nuevo!!! de momento, el codigo funciona casi correctamente :-) faltan un par de cosillas, pero esta tarde con mas paciencia procederé a explicarlo para ver si se puede terminar de pulir. Gracias por todo!!

Bueno, pues después de quedarme sin receptor... (murió sin causa aparente) ayer probé el código con un nuevo receptor y lo ultimo que falta por pulir es que una vez entre el estado de "atras" se quede permanente en este estado hasta que vayamos hacia adelante.. con eso se queda añapao!!! esto ya casi esta!!!

Saludos!!!

¿Y ahora mismo en qué situación no deseada está perdiendo el estado “patras”?