[RISOLTO]Creare Matrici di bit x Immagini B/W

Ho la necessita' di creare una matrice di valori booleani e possibilmente costanti facilmente interrogabile.
Quale e' la strada piu' semplice?
Avevo pensato di usare la funzione String, pero' vorrei trovare una soluzione migliore e meno dispendiosa.
Vorrei fare una matrice 100x100 e se utilizzassi la funzione String con valori booleano occuperei 10Kb di memoria.
Invece io vorrei sfruttare bit per bit (quindi 0 o 1) diminuendo la memoria usata a 1,2Kb.
in pratica la matrice dovrebbe essere tipo:
0,0,0,0,1,1,1,1,0,0,1.........
0,0,0,0,1,1,1,0,1,0,1.........
e cosi' via.....
cosa mi consigliate?

Puoi usare singoli byte. Così 100 celle diventano 100/8=12,50->13 celle
Per cui con 100*13=1300 byte memorizzi tutto.

Se come dici sono costanti, memorizzale in Flash con PROGMEM perché con 2 soli K di RAM se ci metti dentro 1,2K di dati l'hai già riempita :wink:

Se ben capisco ti servono 100 bit x 100 bit da cui, arrotondando per eccesso, una matrice da 13 x 100 bytes in cui accedi ai singoli bit :wink:

Mi sembra abbastanza semplice ... perché vuoi scomodare le String ?

Ti fai una piccola funzione che trasforma X e Y della matrice in X1, Y1 e Z dove X1 e Y1 sono la coordinata del byte e Z è, in quel byte, la posizione del bit ... dopo di che leggi/scrivi il singolo bit ...

Lettura e scrittura del singolo bit, se sai giocare con gli operatori OR ed AND è una "scheggia", altrimenti ci sono sempre le funzioni per manipolare i bit (vd. nel reference alla sezione Bits and Bytes) :wink:

Guglielmo

@ Lock : Stessa idea, stesso momento ... :grin:

lock:
eh, le ho dovute usare per tenere traccia dei data_block liberi in un filesystem bislacco

Beh ... in generale, nella gestione dei filesystems ... le bitmap sono all'ordine del giorno XD XD XD

Guglielmo

ok, aggiungo pero' qualche dettagli cosi' mi indirizzate meglio sulla strada da percorrere.
Per il discorso memoria uso il 1284P che ne ha abbastanza.
Io ho bisogno di velocita' di lettura (x confronto ed eventuale funzione di richiamo), quindi potrei optare per l' uso degli operatori OR, AND ecc, pero' credo di aver capito da come dice Lock che questo utilizzo mi fa perdere velocita'....

Edit: la lettura in flash e' piu' veloce o lenta della lettura in ram? credo piu' lenta giusto?

Edit...

ho buttato giu' qualcosa al volo.
che ve ne pare?
e' ottimizzabile in termini di velocita' di lettura?

boolean matrici(byte x,byte y){  //funzione che da come risultato il valore del bit alle coordinate x,y
  boolean risultato;
  byte matrice[13][100];         //matrice da creare nell' assegnazione delle costanti e variabili
  byte val,xmat,xrest;
  xmat=x/8;                    
  val=matrice[xmat][y];             //mi restituisce il byte che contiene il bit richiesto
  xrest=x%xmat;                //numero del bit da leggere nel byte
  risultato=bitRead(val,xrest);     
  return risultato;
}

x iscrizione

andrea86:
x iscrizione

non l' ho mai capito e approfitto per chiedere....
ma che significa : x iscrizione!! ?? :roll_eyes:

E' utile a chi frequenta il forum saltuariamente, così se magari la discussione è andata in 2a o 3a pagina rischi di perdertela, così invece hai l'elenco di quelle che ti interessano sotto "Unread replies".

oooo finalmente l' ho capito! :smiley:
Grazie...
Tra poco torno sull' argomento perché sto facendo mille prove.

bhe' no, non e' il cruscotto dello scooter, ma un progetto molto molto piu' complesso, che comprende tante funzioni tra cui la visualizzazione di manometri analogici.
A fine progetto vi mostrero' il tutto finito.
Comunque perdonami ma il tuo ultimo suggerimento non sono riuscito a svilupparlo, perché fai riferimento probabilmente a funzioni del C++ (o altro linguaggio) che nell' ide di arduino (per ora conosco solo quello) non corrispondono....
Per ora sto lavorando con un array bidimenzionale ""const byte matrice[100][13]{....."" con la quale sembra che ci sto riuscendo.
Quando ho finito posto tutta la funzione cosi' mi dite se puo' essere ottimizzata.
Il difficile sara' inizializzare tutta la matrice la prima volta bit per bit per ottenere lo sfondo desiderato, ma poi ci arrivo, magari se c'e' qualche strumento da poter usare ditemelo, tipo ricavare la mappatura in bit di un' immagine di pari dimensioni, da un bitmap monocromatico o da un raster..booo
Altra domanda: ma per assegnare a tutta la matrice lo stesso valore si fa cosi? : const byte matrice[100][13]={0); ?

si si hai ragione, la logica l' avevo capita, ma poi non riuscivo a svilupparla con l' ide, soprattutto sulla creazione del mapper.
Lo so che l' ideale e' sganciarsi da arduino, ma per ora conosco bene quella e non ho tempo di studiarmi i comandi e le funzioni di altri linguaggi.
E' gia' tanto che dopo 20 anni mi sono rimesso a inciarmare nella programmazione (usavo il pascal).
Ripeto, la logica di sviluppo ce l' ho tutta, ma per ora resto ancorato ad arduino puramente per il fatto che non ho il tempo di "studiare". Ma prima o poi lo faro'!

Allora, ecco la funzione che ho creato. Gli passo le coordinate X e Y e la funzione mi dice se a quelle coordinate all' interno della matrice il pixel esiste o meno.
la matrice l' ho inizializzata (per ora vuota) cosi:
const byte matrice[100][13]={};
la funzione e' questa:

boolean matrici(byte y,byte x){  //funzione che da come risultato il valore del bit alle coordinate x,y
  boolean esiste;                      //per sapere se il pixel e' gia' esistente True
  byte val,xmat,xrest;
        xmat=x/8;                      //mi restituisce in numero del byte nella riga                
        val=matrice[y][xmat];          //mi restituisce il byte che contiene il bit richiesto
        xrest=x%xmat;                  //numero del bit da leggere nel byte
        esiste=bitRead(val,xrest);     
        return esiste;
}

Come vi sembra? e' ottimizzabile?
la velocita' di rinfresco non e' male, per ora ho provato con singolo manometro, ma poi ne vorrei mettere almeno 4.

perfetto....quindi e' come ti dicevo..la logica era quella... poi come svilupparla varia dal linguaggio (e dalle mie poche capacita'.. XD).
Quindi ho seguito la strada migliore? meglio di cosi' non posso fare? (semre riferito all' IDE).
TNX

lock:
per la matrice, ti conviene farti una matrice_init
dove ti fai un bel doppio ciclo e schiaffi dentro un po' di valori furbi
eventualmente anche 0x00 o 0xff

nel caso giocando sporco, e passando in toto il size di tutta la matrice
c'e' a corredo delle librerie base C, la funzioncina memset

da usarsi per cose bovine tipo cosi':

value= … 0x00 o 0xff o altro
memset(matrice,value,matrice_size);

(occhio che se sbagli il size, non perdona, asfalta)

Mi era sfuggito questo suggerimento . Utile per inizializzarla in qualche modo, ma nel mio caso non la posso usare, visto che la matrice a me serve come sfondo di un dispaly, quindi devo impostarla io a monte.
E qui viene il difficile.
O faccio tutto a mano la prima volta....un casino davvero..
O trovo un modo per buttare nella matrice le stesse coordinate che la libreria grafica usa per spedire i dati al display e creo la matrice (che funzionera' come controllo per lo sfondo) nello stesso momento che creo la crafica con i comandi che uso per la normale scrittura su display, ad esempio quando do un comando di tracciare un cerchio vado a prelevare le coordinate che la libreria spedisce al display e le memorizzo nella matrice....un casino ancora peggiore e per me credo impossibile da perseguire.

OPPURE adotto un altro sistema per farmi gli sfondi: ho un programma che da una immagine mi crea il bitmapper nel formato .c che posso passare direttamente all' IDE. Il problema pero' e' che lo crea a colori, quindi nel formato RGB565, ed io ho la necessita di trasformarlo in Booleano (diciamo Bianco e Nero ma in realta' e' Vero o Falso, poi assegno io i 2 valori di colore).
Non so se esiste qualche programmino in Windows che posso usare, altrimenti posso usare arduino e creo il file su SD, leggo le singole celle a colori, se c'e' il nero (0x0000) scrivo 0 sul file, se non c'e' ( qualunque altro valore) scrivo 1 sul file.
Oppure sparo i codici in seriale e dal monitor me li copio...
Ad ogni modo in queso caso mi risulterebbe piu' utile utilizzare un array unico, come da te cosigliato all' inizio, piuttosto che la matrice che ho usato io (che ho provato e funziona alla grande). Cosi' mi allineo al normale uso dei bitmapper.

Sono riuscito a ricavare in Windows da un' immagine B/W il suo corrisponde bitmapper binario, pero' riesco a ricavare tutti gli 0 e 1 attaccati.
in pratica in questo modo:
00001101010101000101111001110001010011
0010110101010101111110010101001011010101
.......
per poterlo incollare nell' ide devo assegnargli il preffisso Bx e separarli da 1 virgola ogni gruppo da 8.
come posso fare in modo semiautomatico? sto diventando matto.

Deltoz:
come posso fare in modo semiautomatico? sto diventando matto.

Forse QUESTO link ti può aiutare ???

Guglielmo

X Lock :
Si dopo svariato tentativi con programmini vari, tra cui anche Gimp, che pero' trasforma in .c o .h ma utilizzando l' RGB quindi non 1 bit per ogni pixel, sempre in Gimp salvando in .PBM riesco ad ottenere la inconversione in bit ma come ho descritto sopra.
allora ho deciso di scaricarmi il pacchetto Visual Studio Express...installato...e stavo tentando....ma non riesco, devo perderci un po di tempo per prendere dimestichezza, ma ora non riesco.
Ho trovato un sorgente in c# in rete che trasforma un' immagine BW in una sequenza di 0 e 1, come Gimp, pero' avendo il sorgente volevo modificarlo per aggiungerci appunto il prefisso "B" ( e non Bx, ho letto in una guida che e' il formattatore binario in Arduino), raggrupparli x 8 e aggiungerci la ",".....ma non ci sono riuscito, mi da errore...booo, se magari ve lo posso passare potete darci uno sguardo?

X Guglielmo:
Ottimo, e' quello che cerco, ma caricando un' immagine in BW mi restituisce tutti 0xFF...non corrisponde, non so perché.
Certo avere un programmino mio sarebbe l' ideale.

Deltoz:
X Guglielmo:
Ottimo, e' quello che cerco, ma caricando un' immagine in BW mi restituisce tutti 0xFF...non corrisponde, non so perché.
Certo avere un programmino mio sarebbe l' ideale.

Gli devi passare il tipo giusto di file : "To convert an image from bitmap file (.jpg/.png/.gif, RGB/Grayscale)"

Guglielmo