Quantificare gli indirizzi

Buon giorno.
Vorrei testare una memoria RAM con la mia Arduino Mega.
La RAM ha 11 linee di indirizzo (2^11=2048) che verranno poi collegate ad altrettanti pin della Mega configurati come OUTPUT.
Sulle 11 linee dovrà comparire ciclicamente il valore [0 = 0000 0000 000], il valore [1= 0000 0000 001] e così via fino al valore [2048=1111 1111 111].
Non sono esperto in informatica (sono un hobbista autodidatta) e chiedo se esiste una procedura da inserire in un codice per ottenere quanto descritto.
Ho pensato ad un ciclo for es. [ for(int a=0; a<2048; a++) ] che scriva il valore della variabile "a" sulle undici uscite ma non so come fare. Non so come poter coinvolgere contemporaneamente le 11 uscite prima col valore "0" , poi col valore "1" e così via fino al valore "2048".
Chiedo un'indicazione.
Grazie a tutti.

Non ho capito, su ogni linea in contemporanea lo stesso valore ?
Se si, ti basta il for che hai indicato.
Dato il valore di a, devi leggere ogni singolo bit e mandarlo sulla linea. vedi bitRead()
dentro al for:

digitalWrite(pin[0], bitRead(a, 0) );   // leggo il bit 0 e mando su linea 
digitalWrite(pin[1], bitRead(a, 1));  etc.

dove pin[] è un array di byte che contiene il numero del pin della mega
che inizializzi come:
byte pin[]={4,5,6,7,8,9,...etc. fino ai tuoi undici pin};

Poi si può ulteriormente accorciare il codice con un for e una digitalWrite sola

Intanto ti ringrazio per la risposta.
Faccio un esempio più semplice così mi viene meglio spiegarmi.
Supponiamo abbia scelto sulla Mega quattro pin: 22,23,24,25 configurati come OUTPUT.
Su questi voglio rappresentare il numero 13. In binario esso vale: 1 1 0 1

Il pin 22 deve valere 1 [HIGH]
Il pin 23 deve valere 1 [HIGH]
Il pin 24 deve valere 0 [LOW]
Il pin 25 deve valere 1 [HIGH]

E' questa rappresentazione che non so fare.
Ti ringrazio ancora.

scusa

converti in binario un intero a 16 bit e ignori i bit alti

for (int i=0; i< b11111111111; i++)

ma non ti serve nemmeno una for per generare i numeri
lasci andare in overflow, quale sarebbe il problema?

e poi ne dividi le cifre binarie
qui si con una for
anzi nemmeno qui serve

{

int j=0;
while (i)
{
digitalWrite(array[j++], i%2);
i=i/2;

}

}

penso che da qui puoi proseguire da solo

Karma grazie

picluigi:
E' questa rappresentazione che non so fare.
Ti ringrazio ancora.

Esattamente come ti ho scritto sopra. L'array sarà:byte pin[]={22,23,24,25}; // indice 0,1,2,3dove pin[0] contiene 22, etc.
Quindi come ho scritto sopra

a=13;
digitalWrite(pin[0], bitRead(a, 0) );     // bit 0 di a in pin 22

e per farlo su tutti i pin usi un for

a=13;
for(i=0;i<=3;i++)
{ digitalWrite(pin[i], bitRead(a, i) );     // bit i-esimo di a in pin i-esimo
}

L'indice dell'array va da 0 a x, i bit vanno da 0 a x quindi basta un for
Nel tuo esempio vuoi però i bit da più alto al più basso, quindi:
o inverti la dichiarazione dei pin (cosa più semplice)
o si inverte la i di bitRead(a,3-i); dove 3 è il massimo di pin-1

picluigi:
Supponiamo abbia scelto sulla Mega quattro pin: 22,23,24,25 configurati come OUTPUT.
Su questi voglio rappresentare il numero 13. In binario esso vale: 1 1 0 1
Il pin 22 deve valere 1 [HIGH]
Il pin 23 deve valere 1 [HIGH]
Il pin 24 deve valere 0 [LOW]
Il pin 25 deve valere 1 [HIGH]
E' questa rappresentazione che non so fare.

L'argomento era già stato affrontato e risolto in questo thread del 2017... se non sbaglio è identico.

void scriviBusIndirizzi(unsigned int addr)
{
    digitalWrite(memA0,  addr & 1);
    digitalWrite(memA1,  addr & 2);
    digitalWrite(memA2,  addr & 4);
    digitalWrite(memA3,  addr & 8);
    digitalWrite(memA4,  addr & 16);
    digitalWrite(memA5,  addr & 32);
    digitalWrite(memA6,  addr & 64);
    digitalWrite(memA7,  addr & 128);
    addr >>= 8;
    digitalWrite(memA8,  addr & 1);
    digitalWrite(memA9,  addr & 2);
    digitalWrite(memA10, addr & 4);
}

E funziona in virtù del fatto che il valore passato alla funzione digitalWrite viene considerato HIGH se maggiore di zero, e LOW se uguale a zero.

I vari pin possono essere definiti con delle define:

#define memA0  22
#define memA1  23
#define memA2  24
#define memA3  25
#define memA4  26
ecc

C1P8:
converti in binario un intero a 16 bit e ignori i bit alti
penso che da qui puoi proseguire da solo

Diciamo che non è che la tua spiegazione sia poi tanto chiara, anche io (che novizio non sono) l'ho divuta leggere tre volte per capire cosa intendessi.. :wink: (e poi dai, pure un karma...:D).

nid69ita:
Esattamente come ti ho scritto sopra. L'array sarà:
byte pin[]={22,23,24,25}; // indice 0,1,2,3
...

Io approvo questa soluzione perché elegante, compatta, riusabile. :slight_smile:

Claudio_FF:
L'argomento era già stato affrontato e risolto in questo thread del 2017... se non sbaglio è identico.

Pare anche a me, ma quella soluzione fatta "a manella" con la sbrodolata di digitalWrite() e di #define non mi piace per niente per i motivi opposti a quella di nid69ita, per me è "'na pecionata"... :wink:

docdoc:
(e poi dai, pure un karma...:D).

magari non per la prima implementazione che ho scritto, mi trovi d'accordo

ma per questa:

byte piedini[11]={2,3,4,5,6,7,8,9,10,11,12};
int indirizzoram;

void setup(){

for (byte i=0; i<11; i++){

pinMode(piedini[i],OUTPUT);

}


}


void loop(){

scrivi(indirizzoram++);


}


void scrivi(int i){
byte j=0;

while(i){
digitalWrite(piedini[j++],i%2;
i=i/2;
}



}

che ne è la naturale evoluzione, basta applicarsi

per questo io dico che almeno un ringraziamento virtuale come un karma lo meriterei

se poi uno è tanto stitico da non fare nemmeno questo che magari poco varra', ma nulla gli costa
è evidente che non riuscira' nemmeno ad applicarsi, troppo sforzo

PS

per non dare agio a polemiche:

niente pappa fatta come dite da altre parti

questo programma non va, manca un piccolo elemento, un piccolo mattone di pensiero

quindi non parliamo di pappa fatta, grazie

Buona sera.
Ho risolto il mio problema applicando i suggerimenti che mi avete dato. E per questo ringrazio tutti. Un autodidatta ha sempre molto da imparare confrontandosi con chi più sa. Non ho usato le matrici. Ho usato queste istruzioni:
digitalWrite(Pin_A0,bitRead(Add,0));
Questa riga di codice l'ho scritta 11 volte variando di volta in volta Pin_Ax dove x va da 0 a 10. (11 bit per ogni indirizzo). Add, invece , è il valore della variabile del for che va da 0 a 2047. (2048 celle di memoria della RAM)

Ho scoperto che la RAM all'indirizzo 2048 non dà in uscita il dato a 8 bit precedentemente scritto.
Se gli 8 pin di INPUT della Mega sono configurati con le resistenze SW di pool-up, dà in uscita tutti 1(HIGH)
se non è configurata con le resisrtenze di pull-up dà in uscita tutti 0(LOW) anche se il dato scritto contiene si 1 che 0.
Questo per me è un risultato molto importante. Grazie anche a voi.

picluigi:
Ho scoperto che la RAM all'indirizzo 2048 non dà in uscita il dato a 8 bit precedentemente scritto.

Non esiste l'indirizzo 2048 in una RAM da 2k. Scrivendo e leggendo sul 2048 in realtà si ritorna a leggere/scrivere all'indirizzo zero. Quindi si deve comunque rileggere quello che c'è scritto.

Specifichiamo:
la RAM ha 11 linee di indirizzo. 2^11=2048, cioè 2048 indirizzi diversi.

picluigi:
la RAM ha 11 linee di indirizzo. 2^11=2048, cioè 2048 indirizzi diversi.

Si, da 0x000 a 0x7FF ... ovvero 2048 celle indirizzate dalla 0 a 2047 ... se tu però dici indirizzo 2048 si intende 0x800 che, con 11 bit di indirizzamento, NON è possibile :wink:

Guglielmo

Ciao Guglielmo. Un piacere ritrovarti.
Giusto quel che scrivi. Le linee di indirizzo sono 2048 che per identificarle tutte si deve ovviamente partire dall'indirizzo 0 fino a 2047. Per indirizzo 0 si intende piazzare sul bus degli indirizzi 11 segnali 0(LOW) i quali diventeranno 11 segnali 1(HIGH) all'ultimo indirizzo che è il 2047. E il mio cruccio sta proprio qui:
quando interrogo la mia RAM a quest'ultimo indirizzo invece di trovare sul Bus Dati il valore scritto (60 Dec - 3C Hex), trovo tutti 1(FF Hex). Se tolgo le resistenze di pull-up trovo invece tutti 0( 00 Hex). Forse è guasta. O forse ho sabgliato io a programmare la Arduino-Mega.

C1P8:

byte piedini[11]={2,3,4,5,6,7,8,9,10,11,12};

int indirizzoram;

void setup(){

for (byte i=0; i<11; i++){

pinMode(piedini[i],OUTPUT);

}

}

void loop(){

scrivi(indirizzoram++);

}

void scrivi(int i){
byte j=0;

while(i){
digitalWrite(piedini[j++],i%2;
i=i/2;
}

}





questo programma non va, manca un piccolo elemento, un piccolo mattone di pensiero

Soluzione elegante, e che ho capito pure io
Accetto scommesse che la parte mancante è un for
Se non si cicla tutto il numero non si spengono i bit alti

Caffè pagato SR ci ho preso?

E cosi abbiamo fatto la pappa...

Sì caffè pagato la prima fra che passo da Saronno, giusto

Però mi hai torto le castagne nel paniere

picluigi:
Buona sera.

Questa riga di codice l'ho scritta 11 volte variando di volta in volta Pin_Ax dove x va da 0 a 10.

Beh, la matrice/array serviva solo per avere un posto dove scrivere i pin se non sono in sequenza, e poi quindi usare un for che sfrutta l'indice dell'array da 0 a n

docdoc:
con la sbrodolata di digitalWrite() e di #define

Per le write posso concordare (anche se abbiamo più flash che RAM, e qualche istruzione in più risparmiando RAM male non fa). Le define (o in alternativa delle const quacchecosa) invece mi sembrano estremamente utili per definire ogni aspetto hardware all'inizio: cambi i collegamenti e cambi solo le define, senza cercare alcun numero (o livello HIGH LOW) nel codice.

Claudio_FF:
Per le write posso concordare (anche se abbiamo più flash che RAM, e qualche istruzione in più risparmiando RAM male non fa). Le define (o in alternativa delle const quacchecosa) invece mi sembrano estremamente utili per definire ogni aspetto hardware all'inizio: cambi i collegamenti e cambi solo le define, senza cercare alcun numero (o livello HIGH LOW) nel codice.

Si, sono anche d'accordo, ma non sono regole che valgono per qualsiasi programma.

Per fare discorsi generali, quando ho 2 o 3 "cose" faccio 2 o 3 "#define", se però poi sono di più meglio fare un array e usarlo con una for().
Se poi ci sono altre "cose" correlate (es. un array per i pin ed uno per un contatore associato ad ogni pin), allora preferisco fare due array "paralleli" (stesso dimensionamento) da usare sempre con for() e indice comune.
Se infine sono più "cose" in parallelo direttamente un array di struct con tutti i campi necessari.

Ma sono discorsi accademici, nel caso in questione del nostro OP a mio avviso la soluzione più elegante, leggibile, compatta, resta quella di un array di byte pin[] che usi con una semplice for() e l'indice lo usi per fare quello che devi fare.

PS: (premessa: non parlo di te, Claudio :wink: ) ma vorrei sottolineare che per "fair play" in genere i karma non si chiedono/sollecitano ma si danno/offrono se il destinatario ritiene utile il consiglio/suggerimento. Chiusa parentesi, chi deve capire capisca, pls no reply at all... :wink:

Nel post di risposta a Gugliemo esprimevo la mia perplessità per il fatto che all'indirizzo 2047 (0x7FF) la RAM, in lettura, non restituiva il dato precedentemente scritto (es. 150 dec) ma 255 dec ovvero 0xFF. Allora ho provato ad avviare il ciclo for, sia per la scrittura che per la lettura, all'incontrario partendo cioè da 2047 a decrescere fino all'indirizzo zero. Così facendo il dato 150 dec all'indirizzo 2047 viene correttamente letto. Mentre all'indirizzo 0 , cioè al 2047esimo ciclo, restituisce ancora 255 dec (0xFF). Non sò dove sia l'errore!
Saluti e grazie a tutti.

Ok, ma o ci fai vedere l'intero codice (e schema dei collegamenti), oppure è difficile/impossibile aiutarti.