Go Down

Topic: #define zu const PROGMEM ändern --> merkwürdiges Verhalten (Read 372 times) previous topic - next topic

harryberlin

Da mir nahegelegt wurde, define sollte man so weit es geht reduzieren...
Ich möchte ein string "CK", der aktuell per define angelegt ist, zu const char PROGMEM ändern.
aber die Ausgabe dessen ist dann völliger mist.
Ohne PROGMEM klappt es, aber war nicht das Ziel.
Wisst ihr wieso?

Code: [Select]

#define CK F("CK") // good

//const char CK[] PROGMEM  = {"CK"};  // bad result

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); 
 
  while (!Serial) {
    ; // wait for serial ports to connect. Needed for native USB port only
  }   
   
  Serial.print(F("CKSTRING:"));
  Serial.println(CK);
}

Serenifly

Das geht natürlich schief. Die Print Klasse kann nicht wissen dass der String nur im Flash steht. Genau deshalb gibt es ja das F()-Makro! Dabei wird der String auf eine Klasse gecastet von der nur eine Deklaration existiert. Einfach damit man einen anderen Datentyp hat

combie



Quote
Wisst ihr wieso?
Ja, Weil deine Zeiger ins RAM zeigen, die Adresse aber eine Flash Adresse ist.


Experiment:
Code: [Select]

const char CK[] PROGMEM  = "Check";  

void setup() {
  Serial.begin(9600);  
  
  while (!Serial); // wait for serial ports to connect. Needed for native USB port only
    
  Serial.print(F("CKSTRING: "));
  Serial.println((__FlashStringHelper*)CK);
}

void loop(){}
Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

harryberlin

D.h. ich müsste überall, wo ich CK verwende, den (__FlashStringHelper*) davor setzen?
Ist man da mit #define nicht besser bedient?

combie

Quote
Ist man da mit #define nicht besser bedient?
#define ist dir lieber?

Auch gut ...
Code: [Select]

#define FPSTR(str) reinterpret_cast<const __FlashStringHelper*>(str)


const char CK[]  PROGMEM  = "Check"; 

 

void setup()
{
  Serial.begin(9600); 
 
  while (!Serial); // wait for serial ports to connect. Needed for native USB port only
     
  Serial.print(F("CKSTRING: "));

  Serial.println(FPSTR(CK));
}

void loop(){}
Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

harryberlin


combie

Ja, so bin ich manchmal...
(abgrundtief böse)



#define gefällt dir also auch nicht....

Dann vielleicht so:
Code: [Select]


#include <Streaming.h>


constexpr const __FlashStringHelper *f(const char *str)
{
  return reinterpret_cast<const __FlashStringHelper*>(str);
}

const char cs[]  PROGMEM  = "CKSTRING: "; 
const char ck[]  PROGMEM  = "Check"; 

 

void setup()
{
  Serial.begin(9600); 
 
  while (!Serial); // wait for serial ports to connect. Needed for native USB port only
     
  Serial << "Start" << endl
         << f(cs) << f(ck) << endl
         << F("Date: ") << __DATE__ << endl
         << F("File: ") << __FILE__ << endl;


}

void loop(){}


Es gibt grundsätzlich nur 2 Möglichkeiten...
Entweder sorgst du dafür, dass Print erfährt, dass es einen Pointer ins Flash bekommt, oder holst den String selber aus dem Flash.
Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

Go Up