Serielle Schnittschelle

hallo zusammen, ich versuche seit paar Tagen eine richtige Ausgabe in seriellen Monitor zu bekommen, aber klappt nicht.
normalerweise ich gebe zbs X10Y20Z100
angezeigt sollte : Az=10.00,Elv=20.00,Ach=100.00

hier ist mein Code:

float winkel_x,winkel_y,winkel_z; 
  char lineBuf[12];
  
  void setup() {
     Serial.begin(115200);
 
}

uint8_t receiveBuffer (float *winkel_x, float *winkel_y, float *winkel_z) ;

void loop() {
  if (receiveBuffer(&winkel_x,&winkel_y,&winkel_z)){
    snprintf(lineBuf,sizeof(lineBuf),"Az=%f,Elv=%f,Ach=%f",winkel_x,winkel_y,winkel_z);
    Serial.println(lineBuf); 
  }
}

boolean serialTask(char *text, float *winkel_x, float *winkel_y, float *winkel_z) {


                                                           if(text== NULL) return false;
                                                           char* XVAR= strchr(text,'X');
                                                           char* YVAR= strchr(text,'Y');
                                                           char* ZVAR= strchr(text,'Z');
                                                           
                                                           winkel_x[0]= atof(XVAR+1);
                                                           Serial.println(winkel_x[0]);
                                                           winkel_y[0]= atof(YVAR+1);
                                                           Serial.println(winkel_y[0]);
                                                           winkel_z[0]= atof(ZVAR+1);
                                                           Serial.println(winkel_z[0]);                                   
                                                           return true;
}

uint8_t receiveBuffer (float *winkel_x, float *winkel_y, float *winkel_z) {
                         static char lineBuffer[12];
                          static uint8_t lineCnt=0;
                          char c;
                          uint8_t rt=0;
                          
                          if( Serial.available() )
                          {
                               c = Serial.read();
                               if (c=='\n')  // Auswaerten
                               {
                               serialTask(lineBuffer, winkel_x, winkel_y, winkel_z);
                                lineCnt=0;
                                lineBuffer[0]=0;
                                rt=1; 
                               }
                               else if (c=='\r') ; // nix machen
                               else //sammeln 
                               {
                                  lineBuffer[lineCnt++]=c;
                                  lineBuffer[lineCnt]=0;
                                  
                               }
                          }
                          return rt;
}

es ist leider falsch angezeigt ( so zeigt es: Az=?, Elv=?,)
Weisst jemanden vielleicht wo der Fehler ist ?
Danke im Voraus.

Wenn Sie auf einem UNO oder MEGA laufen, unterstützt sprintf() Float nicht

   Serial.print("Az="); Serial.print(winkel_x, 3);
   Serial.print(" ,Elv ="); Serial.print(winkel_y, 3);
   Serial.print(" ,Ach ="); Serial.println(winkel_z, 3);

Alternativ, wenn Sie einen Float in einen String umwandeln möchten, verwenden Sie dtostrf()

Wie @J-M-L schon geschrieben hat %f funktioniert bei Arduino nicht...

Hier was "schnell geklöppeltes":

float winkel_x, winkel_y, winkel_z;
char lineBuf[35];

uint8_t receiveBuffer (char* buffer, float *winkel_x, float *winkel_y, float *winkel_z);

void setup() {
  Serial.begin(115200);
  Serial.println("Start");
}

void loop() {
  if (receiveBuffer(lineBuf, &winkel_x, &winkel_y, &winkel_z)) {
    char rValues[3][8];
    dtostrf(winkel_x, 7, 2, rValues[0]);
    dtostrf(winkel_y, 7, 2, rValues[1]);
    dtostrf(winkel_z, 7, 2, rValues[2]);
    snprintf(lineBuf, sizeof(lineBuf), "Az=%s,Elv=%s,Ach=%s", rValues[0], rValues[1], rValues[2]);
    Serial.println(lineBuf);
  }
}

uint8_t receiveBuffer (char* buffer, float *winkel_x, float *winkel_y, float *winkel_z) {
  while (!Serial.available()) {} 
  Serial.readBytesUntil("\r",buffer,11); 
  char* XVAR = strchr(buffer, 'X');
  char* YVAR = strchr(buffer, 'Y');
  char* ZVAR = strchr(buffer, 'Z');

  winkel_x[0] = atof(XVAR + 1);
  Serial.println(winkel_x[0]);
  winkel_y[0] = atof(YVAR + 1);
  Serial.println(winkel_y[0]);
  winkel_z[0] = atof(ZVAR + 1);
  Serial.println(winkel_z[0]);
  return strlen(buffer);
}

Kann man übrigens aktivieren, wenn man möchte...

Klingt geheimnisvoll... verrätst du auch wie? :slight_smile:

Gerne doch!

Du suchst die verwendete platform.txt
Daneben legst du eine platform.local.txt

Mit folgendem Inhalt:

# erlaubt float in sprintf und seinen Brüdern.
#compiler.c.elf.extra_flags=-Wl,-u,vfprintf -lprintf_flt

# erlaubt float in sscanf und seinen Brüdern.
#compiler.c.elf.extra_flags=-Wl,-u,vfscanf -lscanf_flt 

# erlaubt float in sscanf,sprintf und ihren   Brüdern.
compiler.c.elf.extra_flags=-Wl,-u,vfprintf -lprintf_flt  -Wl,-u,vfscanf -lscanf_flt

3 Varianten, nur eine aktivieren.
Da das Drama recht viel Flash isst, macht es Sinn, nur das zu aktivieren, wo einem der Sinn nach steht.

2 Likes

Danke. Sehr interessant.

Die printf - Varianten brauchen auch ohne das "Feature" schon recht viel Platz, sodass ich möglichst versuche die zu meiden, aber die Info könnte dennoch mal nützlich sein.

DANKE euch alle für die hilfe.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.