Problemone con 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?

roxdragon:

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?

Non conosco la pgm_read_word
ma di sicuro devi passargli un singolo elemento del array e non tutto l'array (usando l'indice i anche per lui)
quindi qualcosa del genere:

pgm_read_word(&C30[i]);

Non sono sicuro tu debba mettere quella & @Leo72 penso possa consigliarti meglio

Mmh...questo è lo sketch che sto usando...
Allora confido in leo72!

static const uint16_t  C30[] PROGMEM ={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
int i;
unsigned int buffer[256];

void setup(){
  Serial.begin(9600);
}

void loop(){
   
  byte lenght = sizeof(C30)/sizeof(C30)[0];

  for (byte i=0; i < lenght; i++) {
    buffer[i] = pgm_read_word(&(C30[i]));
  }
  Serial.println(lenght);  

}

Come lunghezza mi stampa: 200

roxdragon:
byte lenght = sizeof(C30)/sizeof(C30)[0];

Errato

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

Eventualmente visto che sai che C30 sono unsigned int anche così va bene:

  byte lenght = sizeof(C30)/sizeof(int);

Ricorda poi che nel tuo programmone dovrai fare la copia da array a temporaneo sempre prima di spedire e quando spedisci i parametri sono relativi all'array temporaneo:

if( readString.indexOf("C=30") > 0 )
  My_Sender.IRsendRaw::send(C30, sizeof(C30)/sizeof(int), khz);
if ( readString.indexOf("C=30") > 0 )
{ byte lenght = sizeof(C30)/sizeof(int);
  for (byte i=0; i < lenght; i++) 
  { buffer[i] = pgm_read_word( &C30[i] );        // forse senza &
  }
  My_Sender.IRsendRaw::send(buffer, lenght, khz);
}

Sì, dovrebbe andare:

pgm_read_word(&C30[i]);

Ecco! funziona al momento... però avendo 60 array vorrei evitare di ricopiare il codice, quindi mi sono fatto una funzione chiamata ReadFlash()

unsigned int buffer[256];
unsigned int ReadFlash(string x){
  
  byte lenght = sizeof(x)/sizeof(int);
  for (byte i=0; i < lenght; i++){
    buffer[i] = pgm_read_word( &x[i] );        // forse senza &
  }
  return buffer;
}
void loop(){ .....
....
         // CONDIZIONATORE -- ARIA CALDA --
          if ( readString.indexOf("C=30") > 0 )
          buffer = ReadFlash("C=30");
             My_Sender.IRsendRaw::send(buffer, lenght, khz);
          }

errore del compilatore:

sketch_arduino_con_raw:10: error: 'string' was not declared in this scope
sketch_arduino_con_raw:62: error: redefinition of 'unsigned int ReadFlash'
sketch_arduino_con_raw:10: error: 'unsigned int ReadFlash' previously defined here
sketch_arduino_con_raw:62: error: 'string' was not declared in this scope

vorrei passare x alla funzione che in questo caso avrebbe "C=30"

L'oggetto stringa si indica con la S maiuscola, quindi String.
Ma perché fare queste cose??? Passagli il puntatore, no?
In un array il puntatore indica il primo elemento quindi poi sommando il n° di cella ottieni il suo indirizzo.