Wie in Array PROGMEM schreiben ?

Hallo,

wie lautet der Syntax für ein beschreibares Array was mittels Progmem im Flash liegen soll?

Mit const davor geht auch nicht, bekomme weiterhin einen read only Fehler.
const wäre auch falsch, denn die Werte im Array werden erst berechnet und dann abgelegt

Eine Funktion mit write statt read habe ich nicht gefunden.

pgm_read_word_near(PWM_Table + i)

Wenn ich alles im SRAM belasse funktioniert es. Nur soll es ins Flash. Nur wie?

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:28:0,

from sketch\Flash_Array_PROGMEM_001.ino.cpp:1:

Flash_Array_PROGMEM_001:17: error: variable ‘PWM_Table’ must be const in order to be put into read-only section by means of ‘attribute((progmem))’

unsigned int PWM_Table[128] PROGMEM = {}; // 10 Bit Auflösung, davon 128 Werte

^

exit status 1
variable ‘PWM_Table’ must be const in order to be put into read-only section by means of ‘attribute((progmem))’

/*
 Doc_Arduino - german Arduino Forum
 IDE 1.6.6
 Arduino Mega 2560

 PWM Table wird selbst berechnet
*/

#include <avr/pgmspace.h>

unsigned int PWM_Endwert = 1023;   // gleich 100% PWM Duty Cycle
unsigned int PWM_Stufen = 128;     // Anzahl der PWM Zwischenstufen
float Gamma = 3.0;  // Helligkeitlinearisierung
float Abstufung;    // wird berechnet
float Konstante;    // wird berechnet
unsigned int Indexeintrag;
unsigned int PWM_Table[128] PROGMEM = {};  // 10 Bit Auflösung, davon 128 Werte
           
void setup()  { 
  Serial.begin(9600);
  
  Konstante = (float) pow(PWM_Endwert,1/Gamma) / (PWM_Stufen-1);
  Serial.print("Abstufungskonstante\t"); Serial.println(Konstante,4);

  Serial.print("Abstufung\t"); Serial.print("Index Nr.\t"); Serial.println("Wert");
  
  for (int i=0; i<128; i++)  {    // i = Index für PWM_Table
    Serial.print(Abstufung,4); Serial.print("\t\t");
    Indexeintrag = round( pow(Abstufung,Gamma) ); 
    Abstufung = (Abstufung+Konstante);
    PWM_Table[i] = Indexeintrag;    // soll in Flash Array
    Serial.print(i); Serial.print("\t\t");
    Serial.println( pgm_read_word_near(PWM_Table + i) );  
    
  }  
}

Eine Funktion mit write statt read habe ich nicht gefunden.

PROGMEM ist für Konstanten! Nicht für Variablen. Die Werte müssen im Code stehen.

Du kannst nicht Werte zur Laufzeit berechnen und dann ins Flash schreiben

Hallo,

das heißt, wenn ich die Werte live berechnen möchte muß ich zwangsweise das RAM zu ballern? :wink:

Du kannst eine Tabelle einmal berechnen und dann per Hand in den Code kopieren. Dabei kannst du sie mit print() / println() schon genau so formatieren wie sie aussehen soll.

Hallo,

eine vorberechnete Tabelle habe ich bis jetzt immer verwendet, auch mit Progmem. Ich wollte jetzt versuchen das der µC das alleine macht um Änderungen schneller erledigen zu können. Bisher muß ich das erst in Excel anpassen und kopieren.

Jetzt muß ich mir eben überlegen ob ich das ohne Array immer live berechne oder bei einer fertigen Tabelle bleibe.

Es wäre natürlich interessant zu wissen wie lange ein Flash Zugriff benötigt und wie lange die Berechnung dauert. Also was schneller ist. Wird das mit micros() hinreichend genau? Oder macht man das anders?

Doc_Arduino:
eine vorberechnete Tabelle habe ich bis jetzt immer verwendet, auch mit Progmem. Ich wollte jetzt versuchen das der µC das alleine macht um Änderungen schneller erledigen zu können. Bisher muß ich das erst in Excel anpassen und kopieren.

Nur mal so als Info: Eine "berechnete Tabelle mit Konstanten" kannst Du ganz ohne Excel auch mit einem Arduino-Sketch berechnen und auf Serial ausgeben. Und aus dem seriellen Monitor kannst Du die Werte dann herauskopieren und wieder im Quelltext eines Sketches einfügen.

Das ist was ich in #3 gemeint hatte :slight_smile:

Hallo,

das ginge natürlich auch. Danke für den Hinweis.
Aha Serenifly. :slight_smile:

Wegen der Rechenzeitfrage. Das geht ganz klar nach Punkten an das Flash auslesen. Also bleibe ich bei der vorgefertigten Tabelle.

dauert 4-8µs

    start = micros();
    Indexeintrag = ( pgm_read_word_near(PWM_Table + i) );   
    ende = micros();

dauer 332 - 404µs

    start = micros();
    Indexeintrag = round( pow(Abstufung,Gamma) ); 
    Abstufung = (Abstufung+Konstante);
    ende = micros();