problema con PORTD

Salve a tutti.
Sto realizzando il progetto per la mia tesi di Laurea con Arduino.
Ho riscontrato un problema con il controllo PORTD.
Ho cercato sul formu qualche dritta a riguardo, però probabilmente non sono molto bravo ad usare la funzione search e non ho trovato molto. :frowning:
Quindi ho deciso di aprire questo post.
Mi scuso in anticipo se l'argomento è stato discusso e ridiscusso (credo sia cosa probabile)

Il progetto è il seguente.

Ho scritto sulla EEPROM alcuni byte,
Voglio che uesti byte (sono 32) vengano letti ciclicamente e riportati in toto sulle porte digitali.
Ho utilizzato la sintassi PORTD = EEPROM.read(addr);
Dove addr è l'indirizzo che si incrementa .

Dove sta il problema?

Il problema è che ogni tot istruzioni (in media una cinquantina), la porta va a zero per un paio di cicli.
Per me è FONDAMENTALE che questo non accada.

E' possibile porvi rimedio?

Grazie.

dr.benway:
Dove sta il problema?

Intanto dovresti spiegare cosa intendi esattamente con "un paio di cicli" e poi se non posti tutto lo sketch è impossibile fare una analisi esatta del problema.
Posso solo azzardare una ipotesi, sei sicuro che durante il ciclo non vai a leggere locazioni della EEPROM che valgono 0x00 con il conseguente riporto su PORTD ?

dr.benway:
Salve a tutti.
Sto realizzando il progetto per la mia tesi di Laurea con Arduino.
Ho riscontrato un problema con il controllo PORTD.
Ho cercato sul formu qualche dritta a riguardo, però probabilmente non sono molto bravo ad usare la funzione search e non ho trovato molto. :frowning:
Quindi ho deciso di aprire questo post.
Mi scuso in anticipo se l'argomento è stato discusso e ridiscusso (credo sia cosa probabile)

Il progetto è il seguente.

Ho scritto sulla EEPROM alcuni byte,
Voglio che uesti byte (sono 32) vengano letti ciclicamente e riportati in toto sulle porte digitali.
Ho utilizzato la sintassi PORTD = EEPROM.read(addr);
Dove addr è l'indirizzo che si incrementa .

Dove sta il problema?

Il problema è che ogni tot istruzioni (in media una cinquantina), la porta va a zero per un paio di cicli.
Per me è FONDAMENTALE che questo non accada.

E' possibile porvi rimedio?

Grazie.

Ho usato la manipolazione diretta della PORTD per il mio Micrologio senza riscontrare problemi.
Intanto sai che l'accesso alla EEPROM è un'operazione lenta, vero? Non è che hai bisogno di molta velocità?
Perché non carichi in anticipo su 4 variabili il valore di questi 32 bit?
Potresti postare lo sketch che stai usando?
Cosa comandano questi pin?

Non sarebbe malvagio anche sapere quale Arduino hai.
Ciao Uwe

Anch'io ho usato il PORTD sul mio Programmatore HV, senza alcun particolare problema, quindi decisamente serve vedere lo sketch, oppure bisogna rispolverare l'UweBox che mi pare sia ferma da un bel po' di tempo :smiley:

Mi sa tanto che qua serve la Uwebox(tm) 2.0, però è ancora in fase di sviluppo :slight_smile:

Grazie a tutti per le risposte.

Questo è il codice del mio programma:

#include <EEPROM.h>
int addr = 0;
k=0;
void setup()
{

** DDRD = B11111111; //tutti i pin sono uscite**

}
void loop()
{
** while (k<100)**
{
PORTD = EEPROM.read(addr);

** ++ addr;**

** if (addr > 31)**
{addr = 0;}
}
** }**

Ho utilizzato la EEprom , proprio perché mi serve la velocità.
Le operazioni in lettura avvengono infatti molto rapidamente.
Il byte viene letto dalla cella e portato direttamente sulle porte, che è ESATTAMENTE quello che mi serve.

Accade però che per qualche ciclo l'intera porta si resetti portandosi a livello logico zero.

Vi posto anche il contenuto della mia rom

/*
* EEPROM Write
*
* Stores values read from analog input 0 into the EEPROM.
* These values will stay in the EEPROM when the board is
* turned off and may be retrieved later by another sketch.
*/
#include <EEPROM.h>
void setup()
{
}
int write = 1;
void loop()
{
** if (write == 1)**
** {**
EEPROM.write( 0 , B10000000 );
EEPROM.write( 1 , B10000000 );
EEPROM.write( 2 , B10001010 );
EEPROM.write( 3 , B10001010 );
EEPROM.write( 4 , B10101000 );
EEPROM.write( 5 , B10101000 );
EEPROM.write( 6 , B10100010 );
EEPROM.write( 7 , B10100010 );
EEPROM.write( 8 , B10100010 );
EEPROM.write( 9 , B10100010 );
EEPROM.write( 10 , B10101000 );
EEPROM.write( 11 , B10101000 );
EEPROM.write( 12 , B10001010 );
EEPROM.write( 13 , B10001010 );
EEPROM.write( 14 , B10000000 );
EEPROM.write( 15 , B10000000 );
EEPROM.write( 16 , B00101010 );
EEPROM.write( 17 , B00101010 );
EEPROM.write( 18 , B00100000 );
EEPROM.write( 19 , B00100000 );
EEPROM.write( 20 , B00000010 );
EEPROM.write( 21 , B00000010 );
EEPROM.write( 22 , B00001000 );
EEPROM.write( 23 , B00001000 );
EEPROM.write( 24 , B00001000 );
EEPROM.write( 25 , B00001000 );
EEPROM.write( 26 , B00000010 );
EEPROM.write( 27 , B00000010 );
EEPROM.write( 28 , B00100000 );
EEPROM.write( 29 , B00100000 );
EEPROM.write( 30 , B00101010 );
EEPROM.write( 31 , B00101010 );
** }**

write = 0;

}

La rom è scritta correttamente altrimenti il problema si presenterebbe periodicamente e per un solo ciclo.

Invece mediamente ogni 50-80 letture, l'uscita va zero per qualche ciclo.

Ancora grazie per la cortese disponibilità.

Sto utilizzando una scheda Arduino duemilanove - atmega328P

solo come prova, introduci un piccolo ritardo tra una lettura e la successiva
il codice racchiudilo tra i tag "code" così diventa molto più leggibile

si ho già provato ad introdurre il ritardo, ma il fenomeno continua a presentarsi.

ripropongo il codice taggato.

#include <EEPROM.h>
int addr = 0;
k=0;


void setup()
{
 
  DDRD = B11111111; //tutti i pin sono uscite
 
}

void loop()
{
  while (k<100)
{
 PORTD = EEPROM.read(addr);
   
    ++ addr;
   
    if (addr > 31)
{addr = 0;}

}

  }

contenuto rom

#include <EEPROM.h>


void setup()
{
}
int write = 1;
void loop()
{
  if (write == 1)
  {
EEPROM.write(    0 , B10000000 );
EEPROM.write(    1 , B10000000 );
EEPROM.write(    2 , B10001010 );
EEPROM.write(    3 , B10001010 );
EEPROM.write(    4 , B10101000 );
EEPROM.write(    5 , B10101000 );
EEPROM.write(    6 , B10100010 );
EEPROM.write(    7 , B10100010 );
EEPROM.write(    8 , B10100010 );
EEPROM.write(    9 , B10100010 );
EEPROM.write(   10 , B10101000 );
EEPROM.write(   11 , B10101000 );
EEPROM.write(   12 , B10001010 );
EEPROM.write(   13 , B10001010 );
EEPROM.write(   14 , B10000000 );
EEPROM.write(   15 , B10000000 );
EEPROM.write(   16 , B00101010 );
EEPROM.write(   17 , B00101010 );
EEPROM.write(   18 , B00100000 );
EEPROM.write(   19 , B00100000 );
EEPROM.write(   20 , B00000010 );
EEPROM.write(   21 , B00000010 );
EEPROM.write(   22 , B00001000 );
EEPROM.write(   23 , B00001000 );
EEPROM.write(   24 , B00001000 );
EEPROM.write(   25 , B00001000 );
EEPROM.write(   26 , B00000010 );
EEPROM.write(   27 , B00000010 );
EEPROM.write(   28 , B00100000 );
EEPROM.write(   29 , B00100000 );
EEPROM.write(   30 , B00101010 );
EEPROM.write(   31 , B00101010 );
  }
 
 write = 0;
 


}

grazie ancora.

Scusa ma il debug sul serial monitor lo hai mai fatto? giusto per visualizzare se a quell'indirizzo c'e' quello che vorresti ci fosse.
Sicuro che sia la strada più semplice scrivere B10000000 ... perchè non provi con un numero 0-255 (byte) e poi lo passi PORTD = EEPROM.read(addr);

scrivere PORTD = 255;
oppure PORTD = B1111111;
fa la stessa cosa

EEPROM.write( 0 , B10000000 );
EEPROM.write( 1 , B10000000 );
EEPROM.write( 2 , B10001010 );
EEPROM.write( 3 , B10001010 );
...
...

EEPROM.write( 0 ,128);
EEPROM.write( 1 ,128);
EEPROM.write( 2 ,138);
EEPROM.write( 3 ,138);
...
...

Scusa ma il debug sul serial monitor lo hai mai fatto?

si, è stato fatto.

Sicuro che sia la strada più semplice scrivere B10000000

Si, per quello che devo fare io è la strada più semplice e più sicura.

grazie.

può usare anche la notazione esadecimale
PORTD = 255; -> PORTD = B11111111; (@ Paolo, con 8 "1" :)) -> PORTD = 0xFF

Il debug lo hai fatto... ok.. quindi ci sono quei byte che ti servono quando vai a leggere la eeprom?

Io avevo registrato su eeprom direttamente il byte 0-255 e lo riportavo al PORTD = 'byte da eeprom' non ho avuto problemi.

Il debug lo hai fatto... ok.. quindi ci sono quei byte che ti servono quando vai a leggere la eeprom?

Si funziona tutto.
l'unico problema che è ogni 50-80 letture di byte la porta va a zero per 2-3 cicli

dr.benway:
Salve a tutti.
Sto realizzando il progetto per la mia tesi di Laurea con Arduino.
Ho riscontrato un problema con il controllo PORTD.
Ho cercato sul formu qualche dritta a riguardo, però probabilmente non sono molto bravo ad usare la funzione search e non ho trovato molto. :frowning:
Quindi ho deciso di aprire questo post.
Mi scuso in anticipo se l'argomento è stato discusso e ridiscusso (credo sia cosa probabile)

Il progetto è il seguente.

Ho scritto sulla EEPROM alcuni byte,
Voglio che uesti byte (sono 32) vengano letti ciclicamente e riportati in toto sulle porte digitali.
Ho utilizzato la sintassi PORTD = EEPROM.read(addr);
Dove addr è l'indirizzo che si incrementa .

Dove sta il problema?

Il problema è che ogni tot istruzioni (in media una cinquantina), la porta va a zero per un paio di cicli.
Per me è FONDAMENTALE che questo non accada.

E' possibile porvi rimedio?

Grazie.

MAh.. devi dire esattamente come fai, e cosa stai facendo messo cosi non ha troppo senso ,

come te ne accorgi che succedono pastrocchi? se usi la seriale forse la disturbi con il PORTD
pin 0-1 sono della seriale oppure la seriale disturba il PORTD mentre printa

ciao,

devi dire esattamente come fai

Per questo motivo ho postato INTERAMENTE il codice che sto usando.

Se leggi il codice noterai chi NON è attiva la comunicazione seriale.

Ho collegato le 8 uscite digitali alla sonda logica di un oscilloscopio agilent.

Purtroppo non sono in università al momento e non posso postare uno screenshoot del comportamento.
Pero' posso dire che tutto funziona come dovrebbe, solo che ogni 50-80 letture la porta va a zero per qualche ciclo.

Per me il problema è nel modo in cui hai fatto la misura, ho caricato il tuo sketch su una UNO, previo setup della EEPROM, ho collegato PORTD ad un analizzatore di stati logici, ho provato ad acquisire fino a un mega di campioni, oltre 30.000 cicli completi, e facendo una ricerca per il valore 0x00 su i dati acquisiti non risulta nessun sample con questo valore.
Anche ad una analisi visiva non si vede nessun ciclo con PORTD pari a 0x00.

gentile Astrobeed,
per prima cosa ti ringrazio per la risposta.
Si hai perfettamente ragione. A occhio è una cosa che non si nota.
I numeri in uS scritti in bianco sulla fondamentale (la prima traccia partendo dal basso) sono i tempi di salita e discesa?

Hai provato a misurare SOLO la fondamentale con l'oscilloscopio?
Se triggeri, ti apparirà un' onda quadra con duty cycle di CIRCA 50%.
Dovresti notare anche una traccia "fantasma" sfasata di qualche uS dovuta al fatto che ogni tanto la porta "ferma" di qualche ciclo di clock
Questo almeno è quello che ho misurato in laboratorio, e questo è il problema, perchè questo tipo di sganciamento non mi va per niente bene ...

Grazie ancora per il tempo che mi dedichi.

Giorgio.