Ciao , ho un problema con Arduino ,devo intercettare quando viene premuto un pulsante , direte voi e che ci vuole semplice , lo pensavo anche io ma dato che il codice che ho scritto non funziona a dovere ve lo chiedo .
il mio problema è che riesco a leggere il valore del pin e se il pulsante è premuto è a 1 , il problema capita spesso che quando premo il pulsante l Arduino non sta leggendo lo stato del pin e dunque perdo l azione che è stato premuto il pulsante , mi funziona solo se lo tengo premuto per 1 o 2 secondi il tempo che gira il codice e fa la lettura del pin.
Ora chiedevo ma esiste un qualcosa ad eventi ? ho provato ad usare i task ma non credo di averlo fatto a dovere perché comunque la lettura funziona solo tenendo premuto il pulsante .
avete qualche idea ???
grazie mille
Ci fai vedere il codice che usi? Scommetto che contiene dei lunghi delay()...
inserisco la parte di codice di loop , i Delay non ci sono lunghi , ho usato i task per vedere se funziona ...ma è la stessa cosa ...
void bt12Callback();
//
Task b12task(10, TASK_FOREVER, &bt12Callback);
void bt12Callback() {
valb1=digitalRead(button1PIN);
if(valb1)
{
piumenol=2;
}
//delay(5);
valb2=digitalRead(button2PIN);
if(valb1)
{
piumenol=-2;
}
if((valb1) && (valb2))
{
piumenol=0;
motorminl=0;
}
}
void loop() {
//
runner.execute();
delay(10);
//
valtrimlr = analogRead(trimlrPIN);
strim.setValue(map(valtrimlr,rangmintrim,rangmaxtrim,100,0));
valtrimlr = map(valtrimlr, rangmintrim,rangmaxtrim,minValueMotor,maxValueMotor);
valStickThrottle = analogRead(throttlePIN);
pbarthrottle.setValue(map(valStickThrottle,rangminjoythr,rangmaxjoythr,0,100));
itoa(map(valStickThrottle,rangminjoythr,rangmaxjoythr,0,100), sbuffer, 10);
tthrottle.setText(sbuffer); //map(valStickThrottle,rangminjoythr,rangmaxjoythr,0,100));
valStickThrottle = map(valStickThrottle, rangminjoythr,rangmaxjoythr,minValueMotor,maxValueMotor);
valStickYaw = analogRead(yawPIN);
pbaryaw.setValue(map(valStickYaw,rangminjoyyaw,rangmaxjoyyaw,100,0));
itoa(map(valStickYaw,rangminjoyyaw,rangmaxjoyyaw,0,100), sbuffer, 10);
tyaw.setText(sbuffer);
valStickYaw = map(valStickYaw, rangminjoyyaw, rangmaxjoyyaw, minValueMotor, maxValueMotor);
//
motorminl=motorminl+piumenol;
motorminr=motorminr+piumenor;
piumenol=0;
piumenor=0;
//
pbarmotl.setValue(motorminl);
pbarmotr.setValue(motorminr);
itoa(motorminl, sbuffer, 10);
lmot.setText(sbuffer);
itoa(motorminr, sbuffer, 10);
rmot.setText(sbuffer);
//
commands="";
commands=String(valStickThrottle)+"|"+String(valStickYaw)+"|"+String(valtrimlr)+"|"
+ String(valb1)+"|"+String(valb2)+"|"+String(valb3)+"|"+String(valb4)
+ "|"+String(motorminl)+"|"+String(motorminr)+"|";
serialRadio.println(commands);
Serial.println(commands);
commands.toCharArray(sbuffer,100);
txtlog.setText(sbuffer);
delay(10);
//
}
Non conosco "i task" e non mi posso esprimere.
Quei delay(), per quanto non causa del problema, mi pare siano completamente inutili e servano solo a rallentare il programma.
Un consiglio per la leggibilità e manutenibilità: quei map(...) che usi più volte, falli una volta sola memorizzando il risultato in una variabile, e poi usa questa.
per verificare (a spanne) quanto dura un ciclo di loop
inserisci come prima istruzione del loop
unsigned long inizio=micros();
e come ultime istruzioni
unsigned long fine= micros();
Serial.println(fine - inizio);
delay(1000); //pausa di un secondo tra 2 cicli di loop
ovviamente devi attivare la seriale nel setup...
se il loop ti dura veramente 1-2 secondi.... hai dei problemi e devi trovare cos'è che blocca il programma per così tanto tempo
SukkoPera:
Non conosco "i task" e non mi posso esprimere.Quei delay(), per quanto non causa del problema, mi pare siano completamente inutili e servano solo a rallentare il programma.
Un consiglio per la leggibilità e manutenibilità: quei map(...) che usi più volte, falli una volta sola memorizzando il risultato in una variabile, e poi usa questa.
ma I map che effettua sono tutti diversi , non ha senso memorizzarli , non li riuso .....
ho provato altre strade una fra queste quella degli interrupts , solo che nella scheda pro-mini che uso sono solo due i pin a cui sono associati gli interrupts e il mio joystick ne ha 4 ....
soluzioni ???
potresti utilizzare 4 diodi sui pulsanti e un solo pin di interrupt, ai tempi che utilizzavo i pic per un telecomando con diversi pulsanti utilizzavo appunto un piccolo diodo per svegliare il pic dallo sleep con uno qualsiasi dei pulsanti premuti.
matteogiovagnini:
ho provato altre strade una fra queste quella degli interrupts , solo che nella scheda pro-mini che uso sono solo due i pin a cui sono associati gli interrupts ...
... mai sentito parlare dei "pin-change interrupts"? Dato che non sono esattamente banali da applicare, ti consiglio l'uso dell'ottima libreria EnableInterrupt che gestisce tutti i tipi di interrupt. Il relativo WiKi QUI.
Guglielmo
Accodandomi ai precedenti validi consigli, mi chiedevo che senso abbia la seconda if() ossia se per caso non debba essere "if(valb2)" e non "if(valb1)", perché mi sfugge la logica:
void bt12Callback() {
valb1=digitalRead(button1PIN);
if(valb1)
{
piumenol=2;
}
//delay(5);
valb2=digitalRead(button2PIN);
// ----------------
// QUESTO!!
if(valb1)
{
piumenol=-2;
}
// ----------------
if((valb1) && (valb2))
{
piumenol=0;
motorminl=0;
}
}
Ossia se è premuto il pulsante 1 imposti piumenol a 2, poi vedi se è premuto il pulsante 2 ma se è premuto il primo imposti piumenol a -2 (!), ed infine se sono premuti entrambi lo metti a zero...
Insomma, io avrei fatto una cosa del genere:
void bt12Callback() {
valb1=digitalRead(button1PIN);
valb2=digitalRead(button2PIN);
if( (valb1) && !(valb2) ) // Pulsante 1 premuto e 2 non premuto, incremento
piumenol=2;
else if(!(valb1) && (valb2) ) // Pulsante 1 non premuto e 2 premuto, decremento
piumenol=-2;
else if((valb1) && (valb2)) // Entrambi premuti, fermo
{
piumenol=0;
motorminl=0;
}
}
Infine una nota, scusami, tutta sta sparata di istruzioni tutte attaccate senza uno straccio di commento:
valtrimlr = analogRead(trimlrPIN);
strim.setValue(map(valtrimlr,rangmintrim,rangmaxtrim,100,0));
valtrimlr = map(valtrimlr, rangmintrim,rangmaxtrim,minValueMotor,maxValueMotor);
valStickThrottle = analogRead(throttlePIN);
pbarthrottle.setValue(map(valStickThrottle,rangminjoythr,rangmaxjoythr,0,100));
itoa(map(valStickThrottle,rangminjoythr,rangmaxjoythr,0,100), sbuffer, 10);
tthrottle.setText(sbuffer); //map(valStickThrottle,rangminjoythr,rangmaxjoythr,0,100));
valStickThrottle = map(valStickThrottle, rangminjoythr,rangmaxjoythr,minValueMotor,maxValueMotor);
valStickYaw = analogRead(yawPIN);
...eccetera eccetera...
non è il massimo, non solo per te (se tra un anno o due devi riprendere in mano il codice, sicuro di ricordare come funziona e perché?) ma anche per chi (come noi) magari vorrebbe cercare di aiutarti...
Scusate ma mi intrometto un attimo:
piumeno1=2*letturap1-2*letturap2;
altravariabile=altravariabile*!(letturap1*letturap2);
Se é premuto solo p1
Piumeno=21-20=2
Altravariabile=se stessa*!(10)= sestessa!0=sestessa*1=sestessa
Viceversa l'altro
E se tutti e due
Piumeno=2-2=0
Altra=sestessa*0=0
Any fool can write code that a computer can understand. Good programmers write code that humans can understand. — Martin Fowler
Programs should be written for people to read, and only incidentally for machines to execute. — Abelson and Sussman
Ok, forse mi son fatto prendere un po la mano con sta roba dello "accorcia e restringi"
Forse.
Grazie mille dei consigli , il codice era abbozzato al volo per provare i pulsanti .....
Il mio problema sono gli interrupt, usando ardui no pro mini non posso applicare la soluzione di Guglielmo xche mi sembra di aver capito che non è supportata dalla mia scheda , credo che userò il metodo descritto da Zef ...
Minimatte77:
Il mio problema sono gli interrupt, usando ardui no pro mini non posso applicare la soluzione di Guglielmo xche mi sembra di aver capito che non è supportata dalla mia scheda
:o :o :o ... ma non hai una Pro Mini? ... e non è basata su ATmega328P?
Guglielmo
... un altra cosa ... non avevi l'account "matteogiovagnini"? ... REGOLAMENTO, punto 16.12 ... che debbo fare?
Guglielmo
gpb01:
... un altra cosa ... non avevi l'account "matteogiovagnini"? ... REGOLAMENTO, punto 16.12 ... che debbo fare?Guglielmo
Era una vita che non mi ricollegavo e non riuscivo a trovare la password e le mail associata all account ...
... e quindi, quale account devo eliminare (e con lui tutti i post/thread)? ? ? Il REGOLAMENTO parla chiaro !
Guglielmo