problema con PORTD

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.

dr.benway:
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.

ho fatto qualche prova e anche a me "sballa" se attivo la seriale e metto Serial.print (PORTD, BIN) I PRIMI 16 CILCLI li stampa giusti

e gli ultimi 16 stampa meno bit, se leggo le memorie direttamente danno valore corretto :fearful:

come se i numeri memorizzati che iniziano con lo zero vicino alla B perdessero gli zero

dr.benway:
Si hai perfettamente ragione. A occhio è una cosa che non si nota.

Non ci siamo capiti, a parte l'analisi visiva, e l'ho fatta espandendo le traccie in modo da vedere bene tutti i fronti, ho provato ad acquisire 1 milione di fronti e ho fatto una ricerca su tutti gli otto bit per il valore 0x00, che non è presente nella tua sequenza, ma affermi verificarsi con una certa regolarità ogni 50-60 cicli, ebbene tale valore non compare mai su tutti i sample presi, e ho fatto l'acquisizione con relativo controllo più di una volta.

I numeri in uS scritti in bianco sulla fondamentale (la prima traccia partendo dal basso) sono i tempi di salita e discesa?

Sono i periodi tra i fronti.

Hai provato a misurare SOLO la fondamentale con l'oscilloscopio?
Se triggeri, ti apparirà un' onda quadra con duty cycle di CIRCA 50%.

E' la prima prova che ho eseguito senza riscontrare nessun problema, e se c'è un evento come lo descrivi si vede eccome su un DSO, proprio per questo motivo ho usato l'analizzatore di stati logici che consente una analisi di tutti e otto i segnali per un periodo molto prolungato.

A me interessa che le onde abbiano un tempo di salita/discesa costante.
Il programma dopo aver letto una locazione di memoria della ROM, incrementa il registro e controlla che il registro sia inferiore a 31.
QUANDO supera 31, siamo arrivati in fondo, quindi perdo qualche ciclo a resettare il registro.
Il risultato sarà un' onda fondamentale non perfettamente simmetrica.
Poco male, a questo posso rimediare ...
il problema è che invece ogni tanto c'è un ritardo di qualche uS, come se Arduino congelasse il tutto per fare altre operazioni.

gingardu:
come se i numeri memorizzati che iniziano con lo zero vicino alla B perdessero gli zero

Non è possibile quello che dici, la EEPROM non può fornire dati errati o incompleti, c'è sicuramente un errore di metodo di misura nel tuo test.

dr.benway:
il problema è che invece ogni tanto c'è un ritardo di qualche uS, come se Arduino congelasse il tutto per fare altre operazioni.

Arduino svolge varie operazione mentre gira il tuo sketch, per esempio deve gestire la millis, quindi è normale che un ciclo può durare qualche us più di un altro, però non è possibile che PORTD vada con tutti i bit a 0 da sola.
Se ti servono operazioni real time precise lascia perdere Wiring, devi lavorare esclusivamente in C ANSI, con eventuali routine in assembler se necessario.

Sono i periodi tra i fronti.

Come mai questi numeri cambiano?

E' un problema di scarsa definizione nella misura?

Dal listato del programma queste grandezze dovrebbero essere costanti, giusto?

Ovviamente c'è un errore di fase nel segnale di clock della scheda, che si ripercuote nelle uscite
Sto cercando solo di capire se il fenomeno è dovuto ad altri motivi

Grazie.

non è possibile che PORTD vada con tutti i bit a 0 da sola.

Si in effetti mi sono espresso male. Stavo considerando solo l'uscita legata alla fondamentale e nelle misurazioni il periodo "off" mi appariva allungato di un valore aleatorio.

Comunque mi sembra di aver identificato il problema : in parole povere mentre la scheda fa girare il programma, essa esegue ALTRE operazioni in background.
Sarebbe possibile disabilitare queste operazioni?
Fare in modo cioè che la scheda esegua solo quello che scrivo?

Grazie.

dr.benway:
Come mai questi numeri cambiano?
E' un problema di scarsa definizione nella misura?

E' un problema di arrotondamento e di cifre visualizzate, lo strumento adatta automaticamente i campi in funzione dello zoom e di conseguenza espande/contrae le cifre visualizzate e ne adatta i valori.

Dal listato del programma queste grandezze dovrebbero essere costanti, giusto?

No, wiring non è un sistema real time, le durate delle operazioni non sono garantite.

Se ti servono operazioni real time precise lascia perdere Wiring, devi lavorare esclusivamente in C ANSI, con eventuali routine in assembler se necessario.

Esiste una guida dove mi posso documentare a riguardo?
Ho cercato riferimenti alla programmazione diretta in assembler della scheda, ma con scarsi risultati.
Grazie.