Ejecutar un programa en Arduino una sola vez

Joaquín, gracias.
F
unciona pero al intentar ser mas precisos con el valor umbral este ya no funciona correctamente, o-sea, haciendo este cambio.
while (
analogRead(A0)== LIMITE)


Porque quisiera que sólo al estar este valor 102, haga por una sola vez la función prender y apagar, y no importara si fuera mayor el valor del potenciómetro.

Saludos.
 
Última edición por un moderador:
Por eso se llama umbral: si supera el límite, se sale y termina el bucle while().

El problema de poner un '==' es que a lo peor el conversor A/D 'salta' el valor, debido a un cambio brusco en la entrada.

Eres tú el que decide el comportamiento. Yo lo que puse era esperar a que se superara el LIMITE, y en ese caso, salir del bucle. Entonces, solo hay que cambiar el valor del LIMITE.

Otra cosa es que queramos lo contrario: esperar en el bucle a que el valor baje del LIMITE. En ese caso, vale con cambiar '<' por '>' para que haga lo mismo.

P.D.: Acostúmbrate a usar comas y puntos. Están en el teclado, y no muerden.
 
Última edición por un moderador:
Pido disculpas por mis faltas y le agradesco su valiosa ayuda Joaquin .

Por lo que entiendo de su mensaje , solamente puedo usar para mi objetivo estos simbolos >< yo al intentar usar el signo == me daba una accion no esperada en la practica , encendia en cualquier valor el led , al ver los ejemplos , el while es importante lo trate de reemplazar por el if obteniendo resultados no esperados



Manana en mi trabajo voy a probar el codigo , con la señal del potenciometro que hace de acelerador el vehiculo , hoy probe con la señal del velocimetro sin obtener buenos resultados , el led se activa al momento de encender el vehiculo , el motivo es que en ese momento se hace 5 voltios por un instante esa linea, con lo que el arduino me lo reconoce como un valor mayor al umbral y se activa el led .

Ahora me queda una duda , si podria poner y como lo podria hacer , si coloco esta linea de codigo

potenciometro=analogRead(A0);

potenciometro=(potenciometro*100.0)/1024.0;

con esto obtengo un valor mas preciso aparentemente saludos.
 
Última edición:
El rango de valor que dan las entradas analógicas es de 0 a 1023.

Si el valor de tensión de referencia es 5 V, entonces por cada unidad de entrada analógica corresponde 5 V / 1024 = 0.00488 V.

Un valor de límite de 102 corresponde entonces a 102 * 0.00488 = 0.49804 V.

Debes echar cuentas para saber qué valor debes poner como umbral a partir de la tensión que consideres como límite.

Para evitar el caso de que al inicio se produzca un pico de tensión de 5 V, eso lo puedes solucionar poniendo un delay() delante del while(). Una espera lo suficientemente larga como para evitar el pico y se estabilice. (Hay otros métodos).
 
Joaquin tienes una solucion para cada inconveniente jejeje buena es , voy aprobar como tu dices anteponiendo un delay () me imagino que no perjudica al funcionamiento del programa ,por otro lado este calculo lo e optenido con buenos resultados para sensar temperatura en otro ejercico :

parametro=analogRead(A4); //Realiza la conversión del sensor de temperatura conectado al A4
parametro=(parametro*100.0)/1024.0;

Queria anadirlo a nuestro ejemplo , pero desconosco como y en que parte lo puedo colocar , ahora voy a aprobar de nuevo anteponiendo el delay , en breve comento resultados gracias y saludos
 
Saludos amigos, buenas noches.
Les comento que realicé la prueba pero mantenía el problema de activación y resulta que la señal que estoy tomando varía incluso al hacer cambio de velocidad.
El carro es uno modelo automático, el día de mañana buscaré otra señal, ya que esta me está dando muchos problemas.

Ahora esta pregunta va para Joaquín.
Como le dije, quisiera tener un umbral preciso para poder tener un mayor control y precisión.
Este ejemplo lo he realizado y quisiera que de esta manera me funcione.
He cambiado los valores y no me ha resultado.

Este es el ejemplo:
Código:
int potenciometro;

void setup()
{
 pinMode(10,OUTPUT);
 Serial.begin(9600);
}
void loop()
{
 potenciometro=analogRead(A0);
 potenciometro=(potenciometro*500.0)/1024;
 if (potenciometro>200&&potenciometro<250)
 {
  digitalWrite(10,HIGH);
 }
 else digitalWrite(10,LOW);
}
De esta forma pongo limites a los valores y me manejo en un rango de 50, esto espero hacerlo en el código facilitado por el maestro Joaquín.
Lo he intentado yo pero no he conseguido buenos resultados.

if (potenciometro >200 && potenciometro < 250)

PD. Esta es la línea que no puedo implementar.
 
Última edición por un moderador:
¿Cuál es la tensión de referencia del potenciómetro y del conversor A/D? ¿5 voltios?

Pues en el mensaje anterior ya te dí las fórmulas para saber cómo interpretar los valores que devuelve el A/D analógico.

Lo que no sabemos es de dónde viene ese 500...

La línea que dices que no puedes implementar yo la veo que es correcta, en el sentido de la sintaxis del C. Veo que se activa el if() cuando el valor de la variable potenciometro está entre esos dos valores.

Otra cosa es que sea eso lo que quieres hacer. O que sean esos los valores que te interese usar.
 
Última edición por un moderador:
efectivamente joaquin son 5 voltios , en esa formula donde esta el numero 500.0 lo que me hace es tener menos digitos en el resultado ,osea mi maximo numero va hacer 499 y mi minimo 0 , si fuera 100.0 seria mi maximo numero 99 y minimo 0 , en esta formula hay que respetar el .0 al final de cada cifra , y si amigo la linea esta correcta el problema radica en que al usar este tipo de linea juntando al while ejemplo :

while (analogRead>200&&analogRead<250)
{
delay(1000);

}

digitalWrite(10,HIGH);
delay(1000);
digitalWrite(10,LOW);

este codigo lo realiza incorrectamente solo al alimentar el circuito y al volver a reset de igual forma .



los valores que quiero usar, como usted dice deben de estar dentro de esos rangos ,cualquiera que sea el valor que ponga como maximo o minimo , y su funcionamiento tendria que ser como lo planteado desde el principio , solo encender una vez, Gracias por su ayuda
 
Última edición:
En esa fórmula donde está el número 500.0 lo que me hace es tener menos dígitos en el resultado, o sea, mi máximo número va hacer 499 y mi mínimo 0. Si fuera 100.0 sería mi máximo número 99 y mínimo 0. En esta fórmula hay que respetar el .0 al final de cada cifra.
No necesitas hacer esa operación. En las bibliotecas que incluye de base Arduino está la map(). Quedaría así:
PHP:
potenciometro = map(analogRead(A0),0,1023,0,500);
Y el resultado es también un número entero (recordemos que potenciometro es una variable entera).

Y sí, amigo, la línea está correcta. El problema radica en que al usar este tipo de línea juntando al while(). Ejemplo:

while (analogRead>200 && analogRead<250) {
delay(1000);
}

digitalWrite(10,HIGH);
delay(1000);
digitalWrite(10,LOW);

Este código lo realiza incorrectamente solo al alimentar el circuito y al hacer el reset.

Los valores que quiero usar, como usted dice, deben de estar dentro de esos rangos, cualquiera que sea el valor que ponga como máximo o mínimo, y su funcionamiento tendría que ser como lo planteado desde el principio: solo encender una vez.
Pero... es que el código que pones... ¿qué hace? Solo es un bucle de espera de 1 segundo en el caso de que el valor leído esté entre 200 y 250. En todos los demás casos (menor que 200 y mayor que 250, el bucle termina/no entra, y parpadea el LED... O sea, que esa es la razón por la que termina al arrancar: como casi seguro que estás leyendo un valor fuera de ese rango, termina inmediatamente.

Sería algo así (no probado):
PHP:
#define RANGO           500
#define LIMITE_INFERIOR 200
#define LIMITE_SUPERIOR 250

int potenciometro = 0;

void setup() {
    pinMode(10,OUTPUT);                  // definimos las entradas y las salidas
    Serial.begin(9600);

    delay(3000);                         // espera inicial para evitar los picos

    // esperamos mientras el valor esté fuera de los límites
    while (potenciometro < LIMITE_INFERIOR || potenciometro > LIMITE_SUPERIOR) {

        delay(1000);                     // esperamos 1 s hasta la siguiente comprobación

        potenciometro = map(analogRead(0), 0, 1023, 0, RANGO);

        //Serial.println(potenciometro);   // mostrar valor que se ha leído ahora
    }

    Serial.println(potenciometro);       // mostrar valor que ha provocado el disparo

    digitalWrite(10,HIGH);               // flash LED
    delay(1000);
    digitalWrite(10,LOW);
}

void loop() {
}
El valor de espera de 3000 ms es puramente intuitivo, así que no tiene una validez para todos los casos. Si quisiéramos estar seguros de un buen comportamiento, necesitamos conocer el sistema a fondo. Muchas veces, esa espera de 3 segundos será excesivo, ya que querremos que nuestro programa esté preparado cuanto antes.

Supongamos que al iniciar o al reiniciar se produce un pico de tensión, y que luego el valor se reduce rápidamente a 0 (o muy bajo). Entonces, podemos sustituir la línea anterior por algo como esto:
PHP:
#define UMBRAL_BAJO   11
#define UMBRAL_CONT   10
#define UMBRAL_WAIT  100

    int contador = 0;

    do {
        delay(UMBRAL_WAIT);

        potenciometro = analogRead(0);

        if (potenciometro < UMBRAL_BAJO) {
            contador++;         // sigue estabilizado, contamos uno más
        }
        else {
            contador = 0;       // se detectó un pico, reiniciamos cuenta
        }
    } while (contador < UMBRAL_CONT);
Este código nos garantiza que, durante el último segundo (10*100 ms), el valor analógico no superó los 0.053 V (5 V / 1024 * 11).
 
Buenas tardes tras probar el codigo facilitado por Joaquin , puedo decir que funciona , en unos minutos le hago la prueba en el vehiculo , le agradesco a joaquin el tiempo que se ha tomado para responder y ayudarme desinteresadamente con este proyecto . es bueno aprender y gracias a el lo estoy logrando .

Me doy cuenta que dejamos a un lado los signos de mayor(>) y menor(<) y en este caso el signo que yo proponia && no era el adecuado , por lo que entendi , lo que yo plantaeba en mi codigo era que, el led en el pin 10 del arduino uno tendria que prender cuando estuviera fuera del rango de 200 a 250 por ese motivo siempre me encendia apenas alimentaba el arduino uno. Luego de probar el codigo con el vehiculo estare de regreso comentado, saludos y gracias
 
Que tal amigos hice una prueba rapida debido a que en el carro donde estaba haciendo las pruebas , estaba pedido y toco armar todo el desorden jejeje , bueno del porque estaba pedido resulta que trabajo en un tipo de consecionario , me encargo de la parte de reparacion electrica y electronica o trato de hacerlo je je , bueno tal y como estaba provisto funciono lo malo es que hay que acelerar despacio ya que al hacerlo muy rapido no hace caso a los valores del potenciometro por lo tanto el led no enciende , entonces tendria que extender un poco mas los valores de umbral 200 y 250 , como dato adicional en reposo el valor medido es de aproximadamente +- 75 y un valor maximo de 424 , este ultimo valor en realidad no lo usariamos seria acelerar al maximo, use este codigo guiandome por los facilitados por el maestro Joaquin ,

int potenciometro;
# define VALOR 500
void setup()
{
Serial.begin(9600);
}

void loop()
{
potenciometro=analogRead(A0);
potenciometro=map(analogRead(A0),0,1023,0,VALOR);
Serial.println(potenciometro);
}

este codigo lo hice para tomar de referencia los valores del pedal de aceleracion



Despues de analizar y practicar gracias a su ayuda en especial la de Joaquin , e conseguido lo que queria en cierta forma ,ahora bien llegue a una conclusion de que necesito realmente obtener el valor de las revoluciones para obtener una activacion exacta del cierre centralizado a 10 ,20 km etc , pues con el potenciometro no obtuve buenos resultados tampoco , tocara buscar en los diagramas electronicos la informacion del vehiculo , y ver donde se genere una senal que se incremente o decremente dependiendo de la velocidad y de ahi convertir esos pulsos en la info que necesito ,

No se, si sera posible complementar el codigo creado por joaquin, con un codigo que lea constatemente la velocidad dada en pulsos para que , segun eso transmita esta informacion al segundo codigo y este haga su trabajo de activar los seguros una sola vez , es posible esto? y disculpen mi preguntadera amigos
 
Última edición:
Amigo Joaquín, saludos.
Estuve revisando, existe una que otra información parecida pero de igual forma no explicita y en la mayoría queda la pregunta suelta, o sea no existe solución.
Sería bueno concluir con este tipo de preguntas y quede solucionado el tema para así poder ayudar a los demás compañeros que al igual que yo queremos aprender y transmitir ese conocimiento como bien lo hace usted, mi estimado amigo Joaquín .

Estuve revisando las señales de la rueda izquierda del vehículo con el multímetro a pesar de ser una onda cuadrada que envía este sensor tipo hall.
Pude revisar que al estar en reposo, existen 0.7 voltios y en movimiento me marca 1.4 voltios.

Ahora bien, hice un código guiándome con todo lo aprendido para visualizar los valores en la pc.

Código:
int potenciometro;
# define rango 100

void setup()
{
 pinMode(10,OUTPUT);
 Serial.begin(9600);
}
void loop()
{
 potenciometro=map(analogRead(A0),0,1023,0,rango);
 Serial.println(potenciometro);
 delay(200);
}
Donde al estar en reposo el vehículo (prendido, relanti) visualizo 13-14-13-14, a veces pasando de tres 13 o cuatro 14.
Al acelerar a 15km, este varía bruscamente de 29-14-13-29-29-28-29-14-13 y este patrón no cambia por más que incremente a 30 km.
Teniendo estos datos, no tengo un patrón para poder realizar lo que necesito.
He escuchado que vale colocar un convertidor de frecuencia/voltaje, ya que como ven, la señal de rueda la estoy colocando directamente a la entrada analógica A0.

Quiero comentarles que el otro pin es llamado potencia y este lleva 12 voltios, mientras que el que estoy usando es señal.

Saludos.
 
Última edición por un moderador:
Amigo Joaquín, no se preocupe.
Como le comentaba, este sensor me está generando ese tipo de señal y el voltaje es bajo máximo, por lo que medí no supera 1.5 voltios.

¿Se podrá tratar este tipo de voltaje con arduino?
Yo lo hice como lo mostré, no sé si de una forma incorrecta.

Saludos y buenas noches amigos.
 
Última edición por un moderador:
Creo que no se debe medir el voltaje eficaz de un tren de pulsos, ya que puede darte lecturas similares con distintos valores del tren.

Si el Arduino es capaz de muestrear al menos al doble de la frecuencia de los pulsos, podrías leerlos en una entrada digital, y de ahí sacar los valores del tren de pulsos. Pero yo ya no sé nada de ese tema :(

A ver si otro te puede echar una mano.
 
Amigo gracias por su respuesta , seria la mejor opcion ya con eso lograria controlar otros modulos etc, pero resulta que aca en mi pais no venden ese shield can bus , si existiera otra forma de realizar el proyecto plantaedo le agradeceria su respuesta
 
Atrás
Arriba