Warning: invalid conversion from 'const char*' to 'char' [-fpermissive] char str = currentLine.c_str();

Hallo zusammen,

ich habe seit einiger Zeit Probleme, mein Programm zu kompilieren und ich verstehe die Fehlermeldung nicht. Hat hier jemand eine Idee, woran das liegen könnte? Das Problem tauchte von jetzt auf gleich auf, ohne dass ich irgendeine Änderung vorgenommen hatte.

/////////////////////////////////////////////////////////////////////// POKERMASCHINE ////////////////////////////////////////////////////////////////////////////
// 
//        Ablaufplan
//
// 0.)    WiFi-Server starten // Serial Monitor starten // WiFi-Status printen // Einige Meldungen ausgeben
// 1.)    Client auslesen
// 2.)    Warten auf irgendeine Eingabe der App, um den Programmstart zu triggern
// 3.)    Motor läuft, bis über den Schalter ein Interrupt ausgelöst wird und die aktuelle Encoder-Position (Pos.1) gespeichert wird (Kalibrierung)
// 4.)    Es wird auf die Pos.1 eingeregelt
// 5.)    Es wird eine Position angefahren, die der ersten Karte im Karten-Lagerhaus entspricht (Pos.1 + Position der ersten Karte)
// 5.1)   Servo auf 180° und dann auf 0°, um Karte auszuschieben
// 6.)    Es wird eine weitere Position angefahren, die der zweiten Karte im Karten-Lagerhaus entspricht (Pos.1 + Position der zweiten Karte)
// 7.1)   Servo auf 180° und dann auf 0°, um Karte auszuschieben
// 7.)    Einnehmen der Ausgansposition (Pos.1) und dann Pos.1 auf 0 setzen
// 8.)    gehe zu 1.)
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//        Init
//
#include <SPI.h>
#include <WiFiNINA.h>
//
#include <PIDController.h>                                                    // Inkludieren Bibliothek fuer PID-Controller
PIDController pos_pid; 
//
#include <Servo.h>                                                            // Inkludieren Bibliothek fuer Servo
Servo myServo;
Servo myServo2;
//
#include "arduino_secrets.h" 
//
int schalter_kali =0;                                                         // Schalter fuer Kalibrierung
//
int counter=0;                                                                // Counter fuer das Auslesen der Zufallskartenwerte
//
int z=-1;                                                                     // Zaehler zum Speichern der Zufallskartenwerte im integer karte
//
int karte[52];                                                                // Speicher-Integer fuer die Zufallskartenwerte zur Weiterverarbeitung
//
volatile long int encoder_pos = 0;
int akt_encoder_pos = 0;
int akt_encoder_pos_2 = 0;
//
char incomingByte;                                                            // Eingehende Bytes fuer Trigger Serial Monitor
//
char ssid[] = "bla";
char pass[] = "bla";
int keyIndex = 0;
int status = WL_IDLE_STATUS;
//
WiFiServer server(80);
//
int motor_value = 255;                                                        // Motor-Wert
unsigned long start0;                                                         // Startwert fuer millis() 
unsigned long start1;                                                         // Startwert fuer millis()
unsigned long start2;                                                         // Startwert fuer millis()
unsigned long start3;                                                         // Startwert fuer millis()
unsigned long run_led_servo;                                                  // Startwert fuer millis()
//
//
//  Erklaerung zu cards_value
//
//  Jeder der 52 Karten wird ein Impulswert zugeordnet, auf den mit dem PID-Regler eingeregelt wird
//  Der Ecnoder registriert 823,13 PPR (pulses per revolution)
//  Es gibt 52 Anfahrpositionen
//  Der Abstand zwischen jeder der 52 Positionen ist also 823,13/52=15,8294 Impulse
//  Durch das Getriebe von 100/17=5,88 ergeben sich also 15,8294*5,88=93,114 Impulse zwischen zwei Karten     
int cards_value[ 52 ][ 2 ] = {
{1,  2328  },
{2, 2235  },
{3, 2142  },
{4, 2049  },
{5, 1955  },
{6, 1862  },
{7, 1769  },
{8, 1676  },
{9, 1583  },
{10,  1490  },
{11,  1397  },
{12,  1304  },
{13,  1210  },
{14,  1117  },
{15,  1024  },
{16,  931 },
{17,  838 },
{18,  745 },
{19,  652 },
{20,  559 },
{21,  466 },
{22,  372 },
{23,  279 },
{24,  186 },
{25,  93  },
{26,  0 },
{27,  4749  },
{28,  4656  },
{29,  4563  },
{30,  4469  },
{31,  4376  },
{32,  4283  },
{33,  4190  },
{34,  4097  },
{35,  4004  },
{36,  3911  },
{37,  3818  },
{38,  3725  },
{39,  3631  },
{40,  3538  },
{41,  3445  },
{42,  3352  },
{43,  3259  },
{44,  3166  },
{45,  3073  },
{46,  2980  },
{47,  2887  },
{48,  2793  },
{49,  2700  },
{50,  2607  },
{51,  2514  },
{52,  2421  }
};
//
//
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//        VOID SETUP
//
//
//  0.)
void setup() {
//    
Serial.begin(9600);                                                           // Starten des Serial Monitors mit Baudrate 9600 
//
  while (!Serial) {                                                           //Warten, bis die serielle Schnittstelle verbunden ist
  ;                             
  }
//

if (WiFi.status() == WL_NO_MODULE) {                                          // Wenn die Kommunikation mit dem WiFi-Modul fehltschlägt, dann Meldung
  Serial.println("Communication with WiFi module failed!");
  while (true);
 } 
//
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {                                      // Wenn die aktuelle Firmware-Version veraltet ist, dann Meldung, dies zu beheben
    Serial.println("Please upgrade the firmware");
  }
//
while (status != WL_CONNECTED) {                                              // Wenn Kommunikation mit dem WiFi-Modul erfolgreich etabliert, dann Meldungen zu WFi ausgeben
  Serial.print("Attempting to connect to SSID: ");
  Serial.println(ssid);
  status = WiFi.begin(ssid, pass);
  delay(10000); 
  }  
//
server.begin();                                                               // start listening for incoming connections (start listening for clients) 
printWifiStatus();
//
myServo.attach(6);                                                            // Servo wird auf PIN 6 gelegt (Servo zum Ausschieben der Karten)
myServo2.attach(8);                                                           // Servo2 wird auf PIN 8 gelegt (Servo zum Kalibrieren)
myServo.write(0);                                                             // Servo wird auf Null gefahren
myServo2.write(0);                                                            // Servo2 wird auf Null gefahren
delay(500);
pinMode(2, INPUT);                                                            // PIN 2 ist ein INPUT (A-Signal Encoder)
pinMode(3, INPUT);                                                            // PIN 3 ist ein INPUT (B-Signal Encoder)
pinMode(4, OUTPUT);                                                           // PIN 4 ist ein OUTPUT fuer Kontrolllampe (Karten werden verteilt)
pinMode(5, INPUT);                                                            // PIN 5 ist ein INPUT (Interrupt-PIN fuer Speicherung Pos.1, siehe Ablaufplan oben)
pinMode(7, OUTPUT);                                                           // PIN 7 ist ein OUTPUT fuer Kontrolllampe (LED an/aus)
pinMode(9, OUTPUT);                                                           // PIN 9 ist ein OUTPUT (POWER DC-MOTOR fuer Steuergeraet)
pinMode(10, OUTPUT);                                                          // PIN 10 ist ein OUTPUT (POWER DC-MOTOR fuer Steuergeraet)
//
attachInterrupt(digitalPinToInterrupt(2), encoder, RISING);                   // Interrupt fuer DC-MOTOR-REGELUNG
attachInterrupt(digitalPinToInterrupt(5), schalter, RISING);                  // Interrupt fuer Speicherung Pos.1 zur Kalibrierung, siehe Ablaufplan oben
//
pos_pid.begin();                                                              // Beginn PID   
pos_pid.tune(100, 0, 2000);                                                   // Tuning Anteile P I D 
pos_pid.limit(-255, 255);                                                     // Grenzen Motor-Wert
}
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//        VOID LOOP
//
void loop() {
//  
//
//  1.)
WiFiClient client = server.available();                                       // Abfrage, ob WiFi-Client verfuegbar ist
  if (client) {                                                               // Wenn der Client verfuegbar ist, dann
  String currentLine= "";                                                     // einen leeren String namens currentLine anlegen
//
    while (client.connected()) {                                              // waehrend der Client verfuegbar ist, tue
      if (client.available()) {                                               // wenn der Client verfuegbar ist, dann
        char c = client.read();                                               // in c wird die Info, die aus dem Client kommt, geschrieben
//
          if (c == '\n') {                                                    // wenn ein Newline-Character auftritt ... 
            if (currentLine.length() == 0) {                                  // ...und die Laenge des Newline-Characters Null ist
              client.println("HTTP/1.1 200 OK");
              client.println("Content-Type:text/html");
              client.println();                                               // the connection will be closed after completion of the response
              client.print("Value at A0 is ");                                // refresh the page automatically every 5 sec
              client.print(analogRead(A0));
              client.print("<br>");
              client.println();
              break;
              }
           else {
  if (counter ==1) {                                                          // Programm zum Speichern der als String uebermittelten Zufallszahlen in einem Array karte
  z=-1; 
  Serial.println(F("\nProgrammstart"));
  Serial.println(currentLine.indexOf('['));
  Serial.println(currentLine.lastIndexOf(']'));
  currentLine = currentLine.substring(1 + currentLine.indexOf("["), currentLine.lastIndexOf(']'));
  Serial.println(currentLine);
  currentLine.replace("%22", "");
  currentLine.replace("%20", "");
  currentLine.replace(",[]", "");
  Serial.println(currentLine);
  char * str = currentLine.c_str();
  char * pch;
  pch = strtok (str, ",");
  while (pch != NULL)
  {
    z=z+1;
    Serial.print(pch);
    Serial.print('\t');
    Serial.println(atoi(pch));
    karte[z]=atoi(pch);                                                        // Achtung !!! karte enthält nicht nur alle Karten, sondern als letzten zahlenbehafteten Eintrag auch die Anzahl der Spieler
    pch = strtok (NULL, " ,.-");
    //Serial.println(karte[z]);
    } 
  for(int i = 0; i < 22; i++){
  Serial.println(karte[i]);
  } 
 }
counter=counter+1;       
//
//                      
             currentLine = "";
             }
           } else if (c != '\r') {                                             // wenn ein Character in der current line ist, dann
              currentLine += c;                                                // currentLine = currentLine +c
              }
//
//
//  2.1)
if (currentLine.endsWith("GET /H")) {                                          // wenn die aktuelle Line mit /H endet, dann Test-LED an
          digitalWrite(7, HIGH);
          Serial.println("check_an");
}                                                                              
//
//
//  2.2)        
if (currentLine.endsWith("GET /L")) {                                          // wenn die aktuelle Line mit /L endet, dann Test-LED aus
          digitalWrite(7, LOW);
          Serial.println("check_aus");          
   }
//
//
//  2.3)
if (currentLine.endsWith("GET /M")) {                                          // wenn die aktuelle Line mit /M endet, dann Mischen
counter=1;
          Serial.println("check_mix");    
}
//
//
//  2.4)       
if (currentLine.endsWith("GET /P")) {                                          // wenn die aktuelle Line mit /P endet, dann folgt der POKER-CODE
//
//
//  2.4.1)
digitalWrite(4, HIGH);                                                         // rote LED anschalten, um zu signalisieren, dass er Motor jetzt laeuft
//
//
//  2.4.2)
  for(int i = 0; i < 22; i++){                                                 // nur zur Info. Es wird ausgegeben im Serial Monitor, was in karte steht. Der letzte zahlenbehaftete Eintrag in karte ist die Anzahl der Spieler
  Serial.println(karte[i]);
  }
//
//
// 2.4.3)
int anzahl_spieler=0;                                                          // Die Anzahl der Spieler wird aus dem Vektor karte extrahiert (neben der Spielkarten wird im vektor karte ebenso die Anzahl der Spieler uebermittelt
for(int i = 21; i > 0; i--){
  if (karte[i] == 0){
    anzahl_spieler=karte[i-1];
  }
}
if (anzahl_spieler == 0){
  anzahl_spieler=8;
}
Serial.println("Die Anzahl der Spieler ist");
Serial.println(anzahl_spieler);                                                // Ausgabe Anzahl Spieler zur Kontrolle
Serial.println("Die Anzahl der auszuteilenden Karten ist");
int anzahl_aller_karten=anzahl_spieler*2+5;
Serial.println(anzahl_aller_karten);                                           // Ausgabe Anzahl der auszuteilenden Karten
//
//
//  2.4.4)
int integerValue[anzahl_aller_karten];                                         // integerValue enhaelt nach der Schleife alle Impulswerte, welche nacheinander angefahren werden muessen
for(int i = 0; i < anzahl_aller_karten; i++){
   for(int j = 0; j < 52; j++){
      if (karte[i] == cards_value[j][0]){
      integerValue[i]=cards_value[j][1];
      }
   }
}
for(int i = 0; i < anzahl_aller_karten-1; i++){                                // nur zur Info. Es wird ausgegeben, was in integerValue steht
Serial.println(integerValue[i]);
}
//
// 
//  2.4.5)
myServo.write(0);
delay(500);
//
do{                                                                           // Motor dreht sich so lange, bis ein Interrupt kommt (wenn der Kalibrierungsschalter gedrueckt wird)
schalter_kali=digitalRead(5);
MotorCounterClockwise(255);
//Serial.println(encoder_pos);
}while(schalter_kali == LOW);
//
//
//  2.4.6) Kalibrieren
start0=millis();    
for (int i = 1; i <= 1; i++) {
   do{
   pos_pid.setpoint(akt_encoder_pos-1225);
   motor_value = pos_pid.compute(encoder_pos); //+255 oder -255
     if(motor_value > 0){
     MotorCounterClockwise(motor_value);
       }else{
        MotorClockwise(abs(motor_value));
        }
    //Serial.println(encoder_pos);
    delay(10);
     }while(millis()-start0<3000);
      start0=millis();
   }
encoder_pos=0;
Serial.println(encoder_pos);
myServo2.write(90);
delay(500);   
//  
//
//  2.4.7) Ausgeben aller Karten
start1=millis();    
for (int i = 0; i <= anzahl_aller_karten-1; i++) {
   do{
   pos_pid.setpoint(integerValue[i]);
   //pos_pid.setpoint(4842);
   motor_value = pos_pid.compute(encoder_pos); //+255 oder -255
     if(motor_value > 0){
     MotorCounterClockwise(motor_value);
       }else{
        MotorClockwise(abs(motor_value));
        }
     delay(10);   
     }while(millis()-start1<7000);
      start1=millis();
   delay(500);
   myServo.write(60);
   delay(250);
   myServo.write(0);
   delay(250);
   }
delay(1000);
//Serial.println("Position Karo 2");  
//Serial.println(encoder_pos);
//    
//
// 2.4.8) Zurueckfahren auf Start, encoder_pos nullen, Ausgangsposition einnehmen und LED ausschalten
start3=millis();    
for (int j = 1; j <= 1; j++) {
   do{
   pos_pid.setpoint(0-1225);
   motor_value = pos_pid.compute(encoder_pos); //+255 oder -255
     if(motor_value > 0){
     MotorCounterClockwise(motor_value);
       }else{
        MotorClockwise(abs(motor_value));
        }
//    Serial.println(encoder_pos);
    delay(10);
     }while(millis()-start3<7000);
      start3=millis();
   }
encoder_pos=0;
digitalWrite(4, LOW);
myServo2.write(0);
akt_encoder_pos=0;
delay(500);
//
}
//
//
//      
   }                                                                           // Ende if client available
  }                                                                            // Ende if client connected                               
client.stop();                                                                 // Client stop 
 }                                                                             // Ende if client
}                                                                              // Ende void loop
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//        VOIDS
//
//  Interrupt fuer Kalibrierung
//
void schalter() {
akt_encoder_pos = encoder_pos;
}
//
//  Interrupt fuer Motorsteuerung
//
void encoder(){

  if(digitalRead(3) == HIGH){
    encoder_pos++;
  }else{
    encoder_pos--;
  }
}
//
//  Motor im Uhrzeigersinn drehen
//
void MotorClockwise(int power){
  if(power > 100){
  analogWrite(9, power);
  digitalWrite(10, LOW);
  digitalWrite(13, HIGH);
  }else{
    digitalWrite(9, LOW);
    digitalWrite(10, LOW);
    digitalWrite(13, LOW);
  }
}
//
// Motor gegen den Uhrzeigersinn drehen
//
void MotorCounterClockwise(int power){
  if(power > 100){
  analogWrite(10, power);
  digitalWrite(9, LOW);
  digitalWrite(12, HIGH);
  }else{
    digitalWrite(9, LOW);
    digitalWrite(10, LOW);
    digitalWrite(12, LOW);
  }
}
//
// WiFi-Status printen
//
void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  Serial.print(F("IP: "));Serial.println(WiFi.localIP());
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

Viele Grüße
oppaernst

Das glaubt sowieso keiner.

Die Fehlermeldung ist geheim?

Gruß Tommy

Das kann ich mir zwar nicht vorstellen, aber dennoch, zeige mal die Zeile wo der Fehler auftritt.

Hallo, naja die Zeile, um die es geht, ist im Betreff:

char * str = currentLine.c_str();

Am besten mal mit STR+F suchen
Irgendwas stimmt da nicht mehr...
Kann das auch an einem fehlenden Update oder irgendwelche Boards-Settings liegen?

Grüße

Achja....du willst Hilfe und wir sollen suchen ?

Im übrigen ist doch schon klar wo dein Fehler liegt.
Baue die Übergabe richtig und gut ist.

Ja, die Übergabe hat ja einwandfrei funktioniert, bis ich ein Update ausgeführt habe, danach ging nichts mehr, deshalb frage ich mich, was ich überhaupt ändern soll. Aber ich schaue nochmal nach der Übergabe.

Das kann ich mir nicht vorstellen.
c_string ist kein char. Sollte das wirklich funktionieren, müsste ich mich arg irren.
Was durchaus passieren kann. :wink:

c_str() liefert keinen char* sondern const char*

Es wäre sehr schlecht wenn man einen Zeiger auf das Array bekäme über den man den Inhalt verändern kann

Ok Danke, wenn ich const char* str =... vergebe, motzt er, dass pch = strtok (str, ","); ebenfalls "invalid conversion from 'const char*' to 'char*' [-fpermissive]" ist. Das sollte aber doch dann eigentlich klappen...?

strtok verändert das Augangsarray und kann damit nicht auf konstant Arrays angewandt werden.

Gru0 Tommy

Ja und wie löse ich das jetzt? Sitze auf dem Schlauch...

Um es mal mit ernst gemeinten Worten zu sagen:
Was denkst Du denn, wer sich das antut?

Aus der eigenen Erfahrung: da gibt es ne fehlermeldung und die letzte Zeile wird kopiert.
Der Fehler ist aber schon hunderte zeilen vorher.

Also gib die gesamte Ausgabe her.
Alles andere ist raten und ergibt keinen Sinn!

Es geht nicht. Punkt.
Entweder das c_str() mit strcpy in ein Array kopieren oder gleich das Gedöns mit String weg lassen und mit char-Arrays arbeiten.

Gruß Tommy

1 Like

JA!

Also die ganze Fehlermeldung ist:

E:\PHILO\ARDUINO\POKER-MASCHINE\DEBUGGING\POKER-MASCHINE_debug\POKER-MASCHINE_debug.ino: In function 'void loop()':
E:\PHILO\ARDUINO\POKER-MASCHINE\DEBUGGING\POKER-MASCHINE_debug\POKER-MASCHINE_debug.ino:222:33: warning: invalid conversion from 'const char*' to 'char*' [-fpermissive]
   char * str = currentLine.c_str();
                ~~~~~~~~~~~~~~~~~^~
C:\Users\PK\Documents\Arduino\libraries\WiFiNINA\src\utility\spi_drv.cpp: In static member function 'static void SpiDrv::begin()':
C:\Users\PK\Documents\Arduino\libraries\WiFiNINA\src\utility\spi_drv.cpp:87:24: error: 'PINS_COUNT' was not declared in this scope
       if (SLAVERESET > PINS_COUNT) {
                        ^~~~~~~~~~
C:\Users\PK\Documents\Arduino\libraries\WiFiNINA\src\utility\spi_drv.cpp:87:24: note: suggested alternative: 'PING_CMD'
       if (SLAVERESET > PINS_COUNT) {
                        ^~~~~~~~~~
                        PING_CMD
C:\Users\PK\Documents\Arduino\libraries\WiFiNINA\src\utility\spi_drv.cpp:97:15: error: 'NINA_GPIO0' was not declared in this scope
       pinMode(NINA_GPIO0, OUTPUT);
               ^~~~~~~~~~
C:\Users\PK\Documents\Arduino\libraries\WiFiNINA\src\utility\spi_drv.cpp: In static member function 'static int SpiDrv::available()':
C:\Users\PK\Documents\Arduino\libraries\WiFiNINA\src\utility\spi_drv.cpp:581:25: error: 'NINA_GPIO0' was not declared in this scope
     return (digitalRead(NINA_GPIO0) != LOW);
                         ^~~~~~~~~~
exit status 1
Fehler beim Kompilieren für das Board Arduino Uno WiFi.

String hat auch toCharArray() um das direkt zu kopieren. Das wird sehr oft falsch und unnötig verwendet, weil eben meistens c_str() ausreicht. Das hier ist aber einer der wenigen Fälle wo es tatsächlich sinnvoll ist.

Lese dir die Doku von strtok() mal genau durch. Und überlege dir was ein const Zeiger bedeutet - statt das einfach nur hinzuschreiben damit es kompiliert. Das ist alles völlig logisch

z.B. hier: strtok - C++ Reference

Das wichtige ist das hier:
"This end of the token is automatically replaced by a null-character"

Der Fachbegriff dafür ist in-situ oder in-place Algorithmus

Ja. Da ich String nur sehr selten benutze (alter Ansi-C Programmierer) habe ich das nicht so im Fokus.

Gruß Tommy

Ach:

  char * str = currentLine.c_str();
  char * pch;
  pch = strtok (str, ",");

Siehste, wenn die Fehlermeldung vollständig ist, wird das klar...

Na denn. Es wird. Da gibts Spezis...

Ja, aber warum klapp dann dieses Beispiel und meins nicht?

void setup(){
    char AnimalNames[] = "Bog,Cat";
    char firstName = strtok(AnimalNames,",");
}

Gut, dann muss ich mich trotzdem nochmal genau damit befassen... Danke

weil Du den Unterschied nicht erkannt hast.

ja.
Gute Nacht!