Problemone con PROGMEM :(

Salve a tutti, chiedo aiuto perchè sono bloccato da una giornata intera.
Devo inviare dei codici al mio condizionatore, bene ho decodificato tutti i tasti, e ho testato con la libreria IRlib.h e tutto funziona.
Il problema sorge quando provo a inviare al condizionatore i codici.(prima li provavo a uno a uno.. adesso che ho dichiarato nel codice 60 array penso si riempie la memoria)... Mi si impalla arduino e mi hanno detto qui:
http://forum.arduino.cc/index.php?topic=228773.0
di usare PROGMEM. Ho un 60 array.

PROGMEM prog_uint16_t  C30[] = {4492,4432,596,1600,592,508,592,1608,588,1608,596,504,588,508,596,1604,592,504,596,504,596,1604,592,504,600,500,592,1604,600,1600,596,504,596,1600,596,504,596,504,588,1608,596,1600,596,1604,588,1608,600,1600,592,1604,592,1604,600,1600,592,508,596,500,592,508,596,504,596,504,588,508,596,1604,588,508,596,1604,588,1608,600,1600,592,1604,592,508,592,508,596,500,592,1608,596,500,592,508,596,504,596,504,588,1608,596,1604,592,5268,4520,4424,592,1608,596,504,588,1608,596,1604,592,504,600,500,592,1608,596,500,592,508,592,1604,592,508,596,504,596,1600,596,1604,588,508,596,1604,592,504,596,504,600,1600,592,1604,592,1604,600,1600,596,1600,592,1608,588,1608,596,1604,592,504,596,504,600,500,592,508,592,504,600,500,592,1604,592,508,592,1604,592,1608,596,1600,592,1608,588,508,596,504,596,504,588,1608,596,504,600,500,592,504,596,504,588,1612,592,1604,592,1000}; //AnalysIR Batch Export - RAW
PROGMEM prog_uint16_t *IR[] = {C30, C29, C28, C27, C26, C25, C24, C23, C22, C21, C20, C19, C18, C17, F30, F29, F28, F27, F26, F25, F24, F23, F22, F21, F20, F19, F18, F17, OFF};

il C30[] è solo un array,, e gli altri a seguire.
All'interno c'è un webserver con dei bottoni, nulla di che... mi funziona tutto tranne l'invio dei codici perche mi hanno detto che devo leggere prima l'array della PROGMEM.

if(readString.indexOf("C=30") > 0)
            My_Sender.IRsendRaw::send(C30, sizeof(C30)/sizeof(int), khz);

Avevo fatto una cosa simile ma non mi si accende il condizionatore.
Potete farmi un esempio per quanto riguarda la lettura della PROGMEM con questo array?
vi posto un po di codice per capirci:

oid loop(){
  EthernetClient client = server.available();

  if (client) {
    boolean currentLineIsBlank = true;

    while (client.connected()) {
      if (client.available()) {  
        char c = client.read();
        readString.concat(c);   
        if (c == '\n' && currentLineIsBlank) {
          Serial.print(readString);

          // CONDIZIONATORE -- ARIA CALDA --
          if(readString.indexOf("C=30") > 0)
            My_Sender.IRsendRaw::send(C30, sizeof(C30)/sizeof(int), khz);
............
.......qui continua..........

          // INIZIO DICHIARAZIONE PAGINA HTML
          client.println(F("HTTP/1.1 200 OK"));
          client.println(F("Content-Type: text/html"));
          client.println();
          client.print(F("<html><head><title>ARDUINO Controllo via WEB</title><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' ></head><body>"));

Confido in voi e vi ringrazio anticipatamente.
Saluti

Se sono int16, devi leggere i dati con pgm_read_word(indirizzo).
prova così:

Leggi un pò di documentazione qui:

http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html

Ciao si ho letto la documentazione e penso che le dichiarazioni siano ok. Il problema che non riesco a leggere la progmem.
sono un uint_16t.
Avevo gia usato quella funzione. .

 oid loop() {
  
   displayInt = pgm_read_word_near(IR[0] + k);
   k++;
  Serial.println(displayInt);
  delay(1000);
}

il problema è quando mi legge l array... sfora e mi da numeri a caso.
ma devo salvarli su buffer prima di inviarli con un ir led?

Chiedo aiuto per qualche esempio per favore. Grazie mille

x iscrizione

Cosa????

Serve per seguire la discussione cliccando su "Unread replies".
Vuol dire che è interessato alla discussione e vuole seguire i sui sviluppi.
Piuttosto che mettere una faccina :grin: meglio scrivere "x iscrizione".

Scusate non lo sapevo. :slight_smile:
Qualche buon anima che mi fa un esempio di come lwggere l array C30 con la progmem?

Non capisco perchè utilizzi questo sistema, non puoi ottenere il codice hex del comando e darlo alla libreria per spedirlo?

che standard ha il tuo telecomando?
SONY, NEC, RC5, RC6, se nel caso non è tra questi lo aggiungi alla libreria

ciao

Ciao non posso perche ho decodificato il mio telecomando con il software AnalysIR che ho acquistato.
Devo per forza usare irlib. Il mio telecomando non funziona con la lib irremote,
http://forum.arduino.cc/index.php?PHPSESSID=i8p8imbetlg3ldn3dlrbavte47&topic=226454.0
non mi leggeva tutto il codice e me lo troncava nonostante aumentavo il rawbuff nella libreria, mentre con il software funziona!
Il problema non è irlib, ma la progmem che non riesco a leggere l'array per inviare il codice
help please :confused:

Intanto puoi iniziare dichiarando l'array const e vedere come il compilatore ottimizza il codice senza PROGMEM.

roxdragon:
il problema è quando mi legge l array... sfora e mi da numeri a caso.

Certo, non devi incrementare la variabile all'infinito, devi usare un for per la lunghezza del tuo vettore.
Il C non ha il controllo del buffer overflow.

roxdragon:
Il problema non è irlib, ma la progmem che non riesco a leggere l'array per inviare il codice

Credo dovresti crearti un vettore di puntatori a vettore.
Ma la vedo molto complessa come cosa.

Ma io ti avevo detto di usare pgm_read_word, non pgm_read_word_near. Quest'ultimo accetta 1 byte come indirizzo, quindi accedi solo ai primi 256 byte di memoria...

Scusa leo72 ho letto male..
ho un po di confusione. Ho messo in tutti gli array const....
adesso che sono in memoria , per inviare i codici all AC devo leggerli con
Pgm_read_word ...ma li devo salvare su un buffer [256] e poi inviarli direttamente?
Grazie a tutti intanto

Non so come deve operare il tuo programma.
Io ti dico che se vuoi leggere UN integer devi usare pgm_read_word(indirizzo). Poi dove lo metti o cosa ci fai non lo so e non è fondalmentale saperlo riguardo al comando di lettura del dato.

Ok ok!
pgm_read_word(indirizzo) indirizzo sta per C30?
int x;
x = pgm_read_word(&(C30))???
cosi facendo salvo il valore di ritorno in un int giusto?
poi il valore di x lo copio dentro buffer ??
EDIT: venendo a capo io devo avere
unsigned int buffer[] che sarebbe la stringa che leggo dalla progmem cosi posso farne cio che voglio
speroo che mi sia spiegato

roxdragon:
Scusa leo72 ho letto male..
ho un po di confusione. Ho messo in tutti gli array const....
adesso che sono in memoria , per inviare i codici all AC devo leggerli con
Pgm_read_word ...ma li devo salvare su un buffer [256] e poi inviarli direttamente?
Grazie a tutti intanto

Non sono sicuro ma credo di si, perchè la libreria che usi si aspetta un array nella SRAM e non nella Flash.
Forse si potrebbe modificare la libreria per leggere l'array da Flash (PROGMEM) usando il comando indicato da @Leo
Potrei provare (appena posso) se mi metti il link alla libreria e il tuo sketch.
Altra cosa, al primo post parli di array da 60, ora di 256, come mai ?

quindi:

int x;
unsigned int ircode[256];

void setup(){...}

void loop(){
for(x=0; ???
}
non sapendo quanti elementi ci sono nel mio array come faccio?
perche se ircodel ho dichiarato 256 e C30 (array in progmem ha 145 elementi per dire come faccio?
Il codice che non riesco a scrivere deve fare questo:

  • leggere C30 che sarebbe l array sulla progmem
  • copiare quell'array su un nuovo buffer non sapendo quanti elementi ha C30

nid69ita:
Non sono sicuro ma credo di si, perchè la libreria che usi si aspetta un array nella SRAM e non nella Flash.
Forse si potrebbe modificare la libreria per leggere l'array da Flash (PROGMEM) usando il comando indicato da @Leo

Tutto il codice è scritto per gestire dati in Ram per cui quando si vanno a modificare le cose va riscritto tutto il contorno.
Si potrebbe provare a usare un array temporaneo, popolandolo prima di passarlo alla libreria. Non so quanti array ha lui e non so se facendo così ha dei vantaggi oppure no ma sarebbe più semplice che andare a metter mani nella lib.

roxdragon:

  • copiare quell'array su un nuovo buffer non sapendo quanti elementi ha C30

Certo che sai quanti elementi ci sono anche senza contarli:

byte xdim=sizeof(C30)/sizeof(C30[0]);

Dimensione in byte di tutto l'array diviso la dimensione in byte della prima cella

Grazie ragazzi...
@leo72 ho 61 array circa

@nid69ita

unsigned int temp[256];
void loop(){

byte xdim=sizeof(C30)/sizeof(C30[0]); //cosi so quanto è grande l'array
for(int i=0; i< xdim; i++)

temp [i]=pgm_read_word(&(C30);
}

mi correggi se sbaglio? come dice leo72 vorrei popolare un array momentaneamente per poi spedire questo array temp alla lib
come va modificato questo codice?