Por lo tanto, soy un novato COMPLETO y absoluto en programación. He hecho algunas cosas básicas en Arduinos (literalmente alternando los LED y mostrando algo en una pantalla LCD) y estoy tratando de enseñarme a mí mismo cómo programar en C. Soy un ingeniero de hardware por profesión, pero me molesta que no pueda hacer cualquier parte del firmware / software y no hay cursos nocturnos para enseñarlo, y me gustaría ampliar mis opciones de carrera. Me cuesta entender cómo se combinan algunos de estos comandos y me he encontrado con un problema que no puedo entender por qué no funciona.
Entonces, tengo una entrada y una salida. Mi salida es alternar la puerta de un FET que enciende un LED. La entrada proviene de una puerta AND. Por lo tanto, mi LED siempre está encendido, y cuando recibo una señal de entrada de la compuerta AND (se han cumplido 2 condiciones) quiero que la salida (alternar LED) sea BAJA (apague el LED. Como la salida también está conectada a una de las entradas AND, esto también hará que la señal de entrada sea BAJA.
Lo que quiero hacer: solo quiero leer la entrada como 'condiciones cumplidas' y apagar el LED. Luego debe estar apagado durante 1 segundo y volver a encenderse. Si la entrada vuelve a ser ALTA, el proceso se repite. Estoy usando un simple impulso para hacer el cambio como la otra entrada de compuerta AND y he medido que la salida (entrada de MCU) sube cuando se presiona el botón, pero el interruptor LED (salida) no se apagará. Mi código es (creo) bastante simple, pero claramente no entiendo algo correctamente, ya que simplemente no funciona.
Entonces este es el código que estoy usando:
#include "mbed.h"
DigitalIn ip(D7);
DigitalOut op(D8);
int main() {
if (ip == 1){
op = 0;
wait (1.0);
op = 1;
}else{
op = 1;
}
}
Y para mí, eso parece lógico. En el estado habitual, la salida es ALTA. Si la entrada recibe la señal de la puerta AND, el LED se apagará durante 1 segundo y luego se encenderá nuevamente.
¿Qué es lo que he hecho mal ya que parece la forma lógica de hacerlo y no puedo entender por qué eso no funciona?
Si ayuda, estoy usando el Nucleo F103RB. Cuando uso el código de 'parpadeo' y simplemente enciendo y apago el LED de esa manera, funciona bien, es solo cuando agrego la declaración 'si' que sale mal.
Este es el circuito simplificado:
simular este circuito : esquema creado con CircuitLab
PD: Sé que no los agregué en el esquema, pero las compuertas AND tienen resistencias pulldown en las entradas y salidas.
DigitalIn
ya incluyavolatile
.Respuestas:
Pensé que necesitarías un bucle alrededor de tu código.
Antes de tener la oportunidad de presionar el botón, su código habrá terminado y salido. Necesita el tiempo para mantener la instrucción if ejecutándose repetidamente.
fuente
loop()
, pero el marco Arduino agrega código que se comporta más o menos comoint main() { setup(); while(1) { loop(); } }
.El procesador ejecuta las instrucciones secuencialmente . Comienza con un salto
main()
desde dentro del código de inicialización de la biblioteca mbed deDigitalIn
yDigitalOut
.Luego realiza la comparación
ip == 0
, ejecuta las instrucciones dentro de{}
y luegomain()
termina ... no más instrucciones ... ¿Qué hace?Podría restablecerse debido a la búsqueda de operandos ilegales en la memoria flash vacía. O podría colgarse en un controlador de fallas y parpadear SOS como lo hacen los mbeds. Esto depende de cómo se implemente, y probablemente irá más allá de usted en este momento.
Pero si tiene curiosidad, puede investigar ARM Fault Handling o averiguar de dónde
main()
se llama realmente.Ahora, ¿cómo arreglar esto?
fuente
while(1 == 1)
lugar de solowhile(1)
. Este último es idiomático C, pero el primero es más obvio para un ser humano ya que "siempre se evaluará como verdadero". Cualquier compilador decente debería producir el mismo código binario para ambas variantes.Como otros han mencionado correctamente, un bucle permitiría que su código se ejecute repetidamente. Sin embargo, hay una forma integrada de hacer esto para Arduino sin la necesidad de un
while
bucle. Laloop
función lo hace: su aplicabilidad a su problema depende de si usa el IDE de Arduino.Debería verse más o menos así:
Su función principal ahora está oculta y solo se agrega a su programa cuando se compila. Aquí hay una buena discusión sobre esto: http://forum.arduino.cc/index.php?topic=379368.0
fuente
loop()
ysetup()
de Arduino no se usan en la mayoría de los sistemas. Como referencia, Arduino simplemente define unmain()
algo como esto:void setup(); void loop(); int main() { setup(); while (true) loop(); }
Si no eres muy hábil con el montaje, esto también podría estar un poco más en tu zona de confort:
int main () {
}
fuente
goto
** fuertemente ** sugiere "magia sucediendo aquí", posiblemente con la excepción degoto cleanup;
. En el ejemplo aquí, el lector se quedará con la pregunta desconcertante "¿qué es tan especial que nowhile(1) { }
usaste aquí?".