delay non rispettato pin A4-A5-A8-A12 arduino mega

Ciao,
vi copio solo parte del codice perchè è lungo, se poi c'è necessità, vi allego lo sketch.
In pratica uso dei pin Ax come out digitali, anche se ho letto pareri discordanti sui pin A4 e A5 (che sarebbero sda e scl), ma comunque dovrebbero essere utilizzati come pin digitali...

void apri_chiudi()
{
    digitalWrite(chiudi, HIGH);       // chiudo la centralizzata
    digitalWrite(frecce, HIGH);       // accendo le 4 frecce
    digitalWrite(cica, HIGH);         // accendo cicalino
    delay(1000);                      // attendo un secondo
    digitalWrite(chiudi, LOW);        // stacco comando
    digitalWrite(frecce, LOW);        // spengo 4 frecce
    digitalWrite(cica, LOW);          // spengo cicalino
}

In pratica il delay non viene rispettato, sento i relè appena eccitati, roba di millisecondi, e subito diseccitati. Questi i settaggi:

#define frecce   A12                // pin uscita comando 4 frecce
#define cica     A8                 // pin uscita cicalino
#define chiudi  A5                 // pin uscita apertura centralizzata

void setup()
{
  pinMode(frecce, OUTPUT);
  pinMode(cica, OUTPUT);
  pinMode(chiudi, OUTPUT);
}

IL resto del codice funziona perfettamente, a voi chiedo se c'è qualcosa con queste porte, magari non si possono usare come pin digitali, ma nel datasheet non trovo nulla, sembra siano tutti pin utilizzabili anche come digitali.
Nel caso, allego tutto il codice.
Grazie a tutti

Mmm ... non confondere i pin di Arduino UNO con quelli della MEGA, le assegnazioni sono tutte diverse, guarda l'allegata rappresentazione e basati su quella (analogici in verde e corrispondenti digitali in viola).

Guglielmo

mega.pdf (1.92 MB)

Avevo immaginato si riferivano alla UNO, quindi come avevo visto nel refrence, i pin analogici sono utilizzabili anche come digitali, tutti, da A0 ad A15...

Mi sorge un dubbio, ma per caso i pin Ax vanno dichiarati col numero corrispondente in viola? Esempio A0 va dichiarato come pin 54??? Dove sta scritto ciò? Finora li ho sempre dichiarati come Ax ed ha sempre funzionato tutto, alcuni funzionano e alcuni no? :o

Non so cosa non fuziona. Non so neanche cosa come dovrebbe funzionare. Percui non so cosa sia l' errore o la causa del malfunzinamento.

1 secondo dovrebbe bastare che un relais attacchi e stacchi ma siamo abbastanza al limite. Per prova puoi allungare il delay() e cosí sei sicuro se funziona o no.

Se vuoi una soluzione per il Tuo problema mandaci tutto lo sketch o un sketch minimale dove si verifica il problema. Inoltre anche schema elettrico e tipo di relá.
Ciao Uwe

Per usarli come digitali a rigor di logica dovresti usare il numero del pin, come dici tu appunto 54, mentre per analogRead si deve usare A0÷A15.

A0÷A15 dovrebbero essere delle macro anche per la mega ed equivale a scrivere 0÷15.

Ciao.

A me viene invece un'altro dubbio ... come colleghi e come alimenti i tuoi relé? Metti uno schema esatto, inclusa l'alimentazione ... ::slight_smile:

Guglielmo

uwefed:
Non so cosa non fuziona. Non so neanche cosa come dovrebbe funzionare. Percui non so cosa sia l' errore o la causa del malfunzinamento.

1 secondo dovrebbe bastare che un relais attacchi e stacchi ma siamo abbastanza al limite. Per prova puoi allungare il delay() e cosí sei sicuro se funziona o no.

Se vuoi una soluzione per il Tuo problema mandaci tutto lo sketch o un sketch minimale dove si verifica il problema. Inoltre anche schema elettrico e tipo di relá.
Ciao Uwe

Ciao,
cosa non funziona l'ho descritto, tra l'altro è una funzione semplice semplice, non ho postato completamente il codice per problemi di regolamento e omologazione, se comunque preferisci, lo allego...
Un secondo non è certo poco per un relè, abitualmente faccio pilotaggi con 250 ms, per il mio utilizzo è un tempo enorme, comunque sia, anche aumentando a 2 - 3 - 4 secondi, non cambia nulla, il relè viene appena eccitato e si stacca subito.
Lo schema è semplice, non ho problemi di alimentazione, le uscite vanno direttamente a un driver ULN2003A, il quale pilota il relè.
Quella funzione comanda ben 3 relè (su 3 pin diversi), e su tutti e 3 si verifica la stessa cosa.
Ho provato a inizio programma a mettere le uscite a 1 e i relè si eccitano regolarmente (escludo sicuramente problemi hardware)

Utilizzo un interrupt:

attachInterrupt(0, rpm, CHANGE);    //interrupt sul pin 2

Ho pensato potesse entrarci qualcosa, ma da schema non noto interrupt nei pin A4 - A5 - A8 - A12.
Ho cambiato l'assegnazione del pin, rispettivamente in 58 - 59 - 62 - 66, ma stesso problema.
Se posso, allego tutto lo sketch

Hai selezionato il microcontrollore giusto, con la giusta frequenza di clock?

Non è che la citata funzione apri_chiudi() la chiami all'interno dell'interrupt? Perchè nel caso il delay() non funziona...

Ciao, Ale.

Ciao Datman, si da ide è selezionato arduino mega...
Ilguargua, no, l'interrupt è gestito dentro un'altra funzione, e fa solo quello:

void leggi()
{
  Giri = 0;                           // azzera il numero di giri per il calcolo
  interrupts();                       // Attiva gli interrupt
  delay (50);                         // Aspetta
  noInterrupts();                     // disattiva gli interrupt
  giri_m = (Giri * 12);
}



void rpm()      //Funzione che viene cambiata dall'interrupt
{
  Giri++;
}

ilguargua:
Non è che la citata funzione apri_chiudi() la chiami all'interno dell'interrupt? Perchè nel caso il delay() non funziona...

Ciao, Ale.

Ciao, ora che ci ripenso e riguardo le cose, mi hai detto che il delay all'interno dell'interrupt non funziona, ma allora nella funzione che ho allegato nel precedente post (leggi()), dove noto che c'è un delay, non viene eseguito?? Eppure quella funzione (copiata) lavora regolarmente....

Vi allego il codice, sperando di non andare contro al regolamento del forum...
vi indico le righe per velocizzare....
la funzione leggi() viene chiamata subito all'inizio del loop
la funzione apri_chiudi() viene chiamata alla riga 272 e si trova alla riga 403

Grazie

Antifurto_Avvio_Alfa_164.ino (31.4 KB)

thedrifter:

void leggi()

{
 Giri = 0;                           // azzera il numero di giri per il calcolo
 interrupts();                       // Attiva gli interrupt
 delay (50);                         // Aspetta
 noInterrupts();                     // disattiva gli interrupt
 giri_m = (Giri * 12);
}

void rpm()      //Funzione che viene cambiata dall'interrupt
{
 Giri++;
}

A me verrebbe da dire che delay funziona solo dentro la funzione 'leggi' e solo per quei 50ms. Se si disabilitano gli interrupt, delay e qualsiasi altra cosa portata avanti in background, non funziona più.

Ciao Claudio,
io di questa cosa non so nulla, perdonatemi, vuoi dire che se si disabilitano gli interrupt non funziona più la delay? E perchè? Quindi in qualsiasi programma se non si scrive nulla, gli interrupt sono sempre attivi?
Puoi aiutarmi? Non saprei come risolvere, puoi anche consigliarmi un reference? O dove se ne parla?
Grazie, scusatemi l'ignoranza :-[

Scuasmi, sono moderatore e temi che quando Ti chiedo il sketch completo o almeno uno dove si verifica l' errore non puoi postarlo?
Ostinandoti che tutto é giusto, sia Sketch che Hardware ma non funziona. Questo non puó essere perché se tutto fosse giusto funzionerebbe.

Non hai fato vedere lo schema elettrico e quello che descrivi non ha abbastanza informazioni da poterTi controllare la part Hardware. ok usi un relé usi un ULN2003.

Inoltre solo adesso col Tuo Sketch noto che vuoi usarlo all interno di un automobile.

Come pensi di misurare in 50mS i giri del motore? Che sensore usi? Uno che produce 2,5 Impulsi ogni giro del albero?

Poi 2 cose:
Il sistema elettrico di un automobile specialmente se é a benzina é molto disturbato.
Facendo modifiche all'impianto elettrico perdi l'omologazione.

Ciao Uwe

thedrifter:
Ciao Claudio,
io di questa cosa non so nulla, perdonatemi, vuoi dire che se si disabilitano gli interrupt non funziona più la delay? E perchè? Quindi in qualsiasi programma se non si scrive nulla, gli interrupt sono sempre attivi?
Puoi aiutarmi? Non saprei come risolvere, puoi anche consigliarmi un reference? O dove se ne parla?
Grazie, scusatemi l'ignoranza :-[

Perchè si basa sull'interrupt di un timer, se disabiliti gli interrupts non funziona più, così come non funziona all'interno della callback associata ad un interrupt, perchè all'ingresso della funzione gli interrupts vengono disabilitati.

Infatti non capisco questa logica :

void leggi()
{
  Giri = 0;                           // azzera il numero di giri per il calcolo
  interrupts();                       // Attiva gli interrupt
  delay (50);                         // Aspetta
  noInterrupts();                     // disattiva gli interrupt
  giri_m = (Giri * 12);
}

void rpm()      //Funzione che viene cambiata dall'interrupt
{
  Giri++;
}

Che casomai dovrebbe essere il contrario, cioè disabilitare gli interrupts solo nel momento che leggi il dato (che così non cambia) e lasciarli sempre abilitati, tipo :

void leggi()
{
  noInterrupts();                     // disattiva gli interrupt
  giri_m = (Giri * 12);
  interrupts();                       // Attiva gli interrupt
  Giri = 0;                           // azzera il numero di giri per il calcolo
}

void rpm()      //Funzione che viene cambiata dall'interrupt
{
  Giri++;
}

E la variabile Giri deve essere dichiarata come volatile.

Ciao, Ale.

uwefed:
Scuasmi, sono moderatore e temi che quando Ti chiedo il sketch completo o almeno uno dove si verifica l' errore non puoi postarlo? ....

Ciao Uwe,
Il motivo per cui non ho postato lo sketch era appunto per i problemi di regolamento, come ho già detto... Altrimenti l'avrei postato subito, avevo messo solo le parti incriminate per fare un tentativo, poi ovvio che se è necessario lo posto, ci mancherebbe, nulla da nascondere...

Non mi ostino a nulla, ho solo detto che l'hardware funziona e ne sono certo (ho le competenze), sul programma non ho mai detto sia corretto, altrimenti non avrei chiesto aiuto quà sul forum; lo schema non ce l'ho, dovrei disegnarlo, e ora non vorrei perdere altro tempo, un'uscita che va a un 2003A e un relè, non c'è nulla di strano e complicato...

Faccio schede da anni, una a settimana, sia per lavoro che per hobby, l'errore può capitare, ma se dico che l'hardware funziona, ne sono certo (ho già più che controllato); anche perchè questo specifico progetto sta girando già da tempo su altri veicoli (ma non ho mai utilizzato il delay).

Sono attuati tutti gli accorgimenti per i disturbi del motore, inoltre io preparo auto da corsa, e queste schede sono installate su vetture con omologazione sportiva, non soggette ad uso stradale (ecco il motivo perchè non volevo postare lo sketch, per evitare sempre i soliti discorsi :slight_smile: )

I giri motore vengono rilevati da un sensore magnetico che legge una ruota fonica con 58 denti, a livello hardware è presente uno squadratore filtro per pulire e rendere il segnale a onda quadra 0-5V; i giri che vengono rilevati sono corretti, la lettura funziona, il tutto attualmente sta funzionando tranne il solo delay.

Non intendo essere polemico, ho spiegato le cose in modo pacato, starei chiedendo semplicemente un aiuto, grazie :slight_smile:

ilguargua:
Perchè si basa sull'interrupt di un timer, se disabiliti gli interrupts non funziona più .....

Grazie per la spiegazione, non sapevo che il delay lavorasse su un timer controllato da interrupt... Sorry
Non so il perchè la funzione sia così, come ho già detto l'ho copiata da un programma per la lettura di giri, posso solo dirti che funziona e la lettura avviene.
Posso provare il tuo esempio e verifico...
Grazie :slight_smile:

Ripensadoci, la temporizzazione di 50 ms ti servire per il calcolo dei giri, quindi usa un timer o controlla il millis() nel loop principale per chiamare la funzione leggi() ogni 50 ms

NB Ho modificato il codice sopra, tienine conto!

Ciao, Ale.