Então, eu sou um novato completo e absoluto na programação. Eu fiz algumas coisas básicas em Arduinos (alternando literalmente LEDs e exibindo algo em um LCD) e estou tentando me ensinar como programar em C. Sou engenheiro de hardware, mas me incomoda que não consiga faça qualquer parte do firmware / software e não há cursos noturnos para ensiná-lo, e gostaria de aprimorar minhas opções de carreira. Estou lutando para entender como alguns desses comandos se encaixam e se deparam com um problema que simplesmente não consigo entender por que não está funcionando.
Então, eu tenho uma entrada e uma saída. Minha saída está alternando o portão de um FET que acende um LED. A entrada é proveniente de um portão AND. Assim, meu LED está sempre aceso e, quando recebo um sinal de entrada da porta AND (duas condições foram atendidas), quero que a saída (alternância de LED) fique LOW (desligue o LED. Como a saída também está conectada a uma das entradas AND, isso também tornará o sinal de entrada LOW.
O que eu quero fazer: Eu só quero ler a entrada como 'condições atendidas' e desligar o LED. Ele deve ser desligado por 1 segundo e ligado novamente. Se a entrada for ALTA novamente, o processo será repetido. Estou usando um simples toque para fazer a troca como a outra entrada AND e medi que a saída (entrada MCU) fica alta quando o botão é pressionado, mas a alternância do LED (saída) não se apaga. Meu código é (acho) bem simples, mas claramente não entendo algo corretamente, pois simplesmente não está funcionando.
Portanto, este é o código que estou 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;
}
}
E para mim, isso parece lógico. No estado usual, a saída é ALTA. Se a entrada receber o sinal da porta AND, o LED se apagará por 1 segundo e depois acenderá novamente.
O que fiz de errado, pois parece a maneira lógica de fazê-lo e simplesmente não consigo entender por que isso não funciona?
Se ajudar, estou usando o Nucleo F103RB. Quando uso o código 'piscar' e apenas acendo e apagando o LED dessa maneira, ele funciona bem; é apenas quando adiciono a instrução 'if' que dá errado.
Este é o circuito simplificado:
simular este circuito - esquemático criado usando o CircuitLab
PS: Sei que não os adicionei no esquema, mas os portões AND têm resistores de pulldown nas entradas e saídas.
DigitalIn
já incluavolatile
.Respostas:
Eu pensaria que você precisaria de um loop em torno do seu código -
Antes que você tenha a chance de pressionar o botão, o código será finalizado e encerrado. Você precisa de um tempo para manter repetidamente a instrução if.
fonte
loop()
, mas a estrutura do Arduino adiciona código que se comporta aproximadamenteint main() { setup(); while(1) { loop(); } }
.O processador executa as instruções sequencialmente . Começa com um salto para
main()
dentro do código de inicialização da biblioteca mbed deDigitalIn
eDigitalOut
.Em seguida, realiza a comparação
ip == 0
, executa a instrução dentro do{}
e entãomain()
termina ... sem mais instruções ... O que faz?Ele foi redefinido devido à localização de operandos ilegais na memória flash vazia. Ou ele pode travar em um manipulador de falhas e piscar o SOS como os mbeds fazem. Isso depende de como isso é implementado e provavelmente irá além de você agora.
Mas se você estiver curioso, poderá pesquisar o ARM Fault Handling ou descobrir de onde
main()
é realmente chamado.Agora, como consertar isso?
fonte
while(1 == 1)
vez de apenaswhile(1)
. O último é C idiomático, mas o primeiro é mais óbvio para um ser humano, pois "sempre será avaliado como verdadeiro". Qualquer compilador decente deve produzir o mesmo código binário para ambas as variantes.Como mencionado corretamente por outras pessoas, um loop permitiria que seu código fosse executado repetidamente. No entanto, existe uma maneira integrada de fazer isso no Arduino sem a necessidade de um
while
loop. Isso é feito pelaloop
função - sua aplicabilidade ao seu problema depende de você usar o IDE do Arduino.Deve ser algo como isto:
Sua função principal agora está oculta e só é adicionada ao seu programa quando compilada. Aqui está uma boa discussão sobre isso: http://forum.arduino.cc/index.php?topic=379368.0
fonte
loop()
esetup()
do Arduino não são usadas na maioria dos sistemas. Para referência, o Arduino simplesmente definemain()
algo parecido com isto:void setup(); void loop(); int main() { setup(); while (true) loop(); }
Se você está familiarizado com a montagem, isso também pode ser um pouco mais na sua zona de conforto:
int main () {
}
fonte
goto
** fortemente ** sugere "mágica acontecendo aqui", possivelmente com exceção degoto cleanup;
. No exemplo aqui, o leitor ficará com a pergunta intrigante "o que há de tão especial que você não usouwhile(1) { }
aqui ???".