char to INT

hallo beim konvertieren eines Zeichens in eine Zahl bekomme ich einen Fehler

C:\Users\Ralf\Documents\Arduino\Test_Schrittmotor7_Accelstepper_BT\Test_Schrittmotor7_Accelstepper_BT.ino:61:15: warning: invalid conversion from 'char' to 'const char*' [-fpermissive]

       b=atoi(a);

               ^

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

                 from sketch\Test_Schrittmotor7_Accelstepper_BT.ino.cpp:1:

c:\program files (x86)\arduino\hardware\tools\avr\avr\include\stdlib.h:276:12: note:   initializing argument 1 of 'int atoi(const char*)'

 extern int atoi(const char *__s) __ATTR_PURE__;

Evtl mag mir einer sagen, wo das Problem ist. Danke vorab

/*Example sketch to control a stepper motor with A4988 stepper motor driver, AccelStepper library and Arduino: continuous rotation. More info: https://www.makerguides.com */
// Include the AccelStepper library:
#include <AccelStepper.h>
// Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:
#define dirPin 8
#define stepPin 9
#define motorInterfaceType 1
// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);


#include <SoftwareSerial.h>
SoftwareSerial BT(5, 6); 
char a;
int b;

void setup() {
  Serial.begin(9600);
  
  // Set the maximum speed in steps per second:
  stepper.setMaxSpeed(8000);

// Bluetooth --------------------------------  
  BT.begin(9600);                    
  BT.println("Hello from Arduino");
  //Serial.println("SET BT NAME Arduino_BT");
// ------------------------------------------  

  // Microstepping ----------------------------
//  Low   Low   Low   Full step
//  High  Low   Low   Half step
//  Low   High  Low   1/4 step
//  High  High  Low   1/8 step
//  Low   Low   High  1/16 step
//  High  Low   High  1/32 step
//  Low   High  High  1/32 step
//  High  High  High  1/32 step

  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);
  pinMode(12, OUTPUT);
  digitalWrite(12, HIGH);
// ------------------------------------------

  stepper.setSpeed(0);
  
}
void loop() {
  // Set the speed in steps per second:

  // Step the motor with a constant speed as set by setSpeed():
  stepper.runSpeed();

  if (BT.available()){
    a=(BT.read());             
    if (a>0){               
      BT.println("Empfange");
      Serial.println(a);
      b=atoi(a);
      Serial.println(b);
      stepper.setSpeed(a);

    }   
  }
}

atoi will eine Zeichenkette (Char-Array) und kein Einzelzeichen.
Infos zu Zeichenketten hier.

Gruß Tommy

Edit: Sollten es nur Zahlen von 0 bis 9 sein, kannst Du einfach b = a - ‘0’ rechnen, aber nur dann.

Sollte es ein ASCII sein b= a-47 dann bekommst du die Ziffer raus.

Gruß DerDani

volvodani: Sollte es ein ASCII sein b= a-47 dann bekommst du die Ziffer raus.

'0' ist 48 oder 0x30. Deshalb macht man am besten wie oben gesagt -'0'. Dann muss man nicht darüber nachdenken welchen Wert das genau hat

Ich frage mich, ob ich überhaupt damit weiter komme. Eigentlich möchte ich ja per Bluetooth den String "M100" oder wenns besser mit Trenner wäre dann "M,100" (nur ein Beispiel ) übergeben und daraus

String a = M Int b = 100

haben, um mit diesen Werten weiterzuarbeiten

Wenn Du die Infos, die ich Dir verlinkt hatte, gelesen und verstanden hättest, könntest Du es problemlos tun.

Gruß Tommy

Dann musst du das auch tun und nicht einfach nur ein Zeichen mit read() auslesen.

Das habe ich hier auch schon unzählige male gezeigt: https://forum.arduino.cc/index.php?topic=634159.msg4293510#msg4293510

mit Trenner wäre dann "M,100"

Kann man machen, aber muss nicht sein. Man kann auch "M100" und "A100" einlesen und dann mit switch/case auf das erste Zeichen abfragen. Dank Zeiger-Arithmetik kommt man für die Wandlung ganz einfach an das Zeichen dahinter

z.B. mit dem obigen Code:

unsigned int value;

void loop()
{  
  char* txt = readLine(Serial);
  if (txt != nullptr)
  {
     switch(txt[0])
     {
        case 'M':
        case 'm':
          value = atoi(txt + 1);
          Serial.println(value);
     }
  }
}

Ansonsten strtok() verwenden um an die Teil-Strings zu kommen wenn du mit Trennzeichen arbeitest

danke.

habe mal versucht, das einzubauen. aber wieder eine warnung…

C:\Users\Ralf\Documents\Arduino\Test_Schrittmotor7_Accelstepper_BT\Test_Schrittmotor7_Accelstepper_BT.ino: In function 'void loop()':

C:\Users\Ralf\Documents\Arduino\Test_Schrittmotor7_Accelstepper_BT\Test_Schrittmotor7_Accelstepper_BT.ino:56:23: warning: invalid conversion from 'int' to 'char*' [-fpermissive]

     char* txt=(BT.read());           

                       ^
/*Example sketch to control a stepper motor with A4988 stepper motor driver, AccelStepper library and Arduino: continuous rotation. More info: https://www.makerguides.com */
// Include the AccelStepper library:
#include <AccelStepper.h>
// Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:
#define dirPin 8
#define stepPin 9
#define motorInterfaceType 1
// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);


#include <SoftwareSerial.h>
SoftwareSerial BT(5, 6); 

unsigned int value;

void setup() {
  Serial.begin(9600);
  
// Set the maximum speed in steps per second:
stepper.setMaxSpeed(8000);

// Bluetooth --------------------------------  
  BT.begin(9600);                    
  BT.println("Hello from Arduino");
  //Serial.println("SET BT NAME Arduino_BT");
// ------------------------------------------  

  // Microstepping ----------------------------
//  Low   Low   Low   Full step
//  High  Low   Low   Half step
//  Low   High  Low   1/4 step
//  High  High  Low   1/8 step
//  Low   Low   High  1/16 step
//  High  Low   High  1/32 step
//  Low   High  High  1/32 step
//  High  High  High  1/32 step

  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);
  pinMode(12, OUTPUT);
  digitalWrite(12, HIGH);
// ------------------------------------------

  stepper.setSpeed(0);
  
}
void loop() {

  stepper.runSpeed();

  if (BT.available())
  {
    char* txt=(BT.read());           
    if (txt>0)
    {               
      BT.println("Empfange");
        if (txt != nullptr)
        {
           switch(txt[0])
           {
              case 'M':
              case 'm':
                value = atoi(txt + 1);
                Serial.println(value);
                stepper.setSpeed(value);
           }
        }
    
    }
    else
    {
    stepper.setSpeed(0);  
    } 
  }
}
char* txt=(BT.read());

Was soll das?! Mit read() liest du ein Zeichen ein. Wie kommst du darauf damit ganze Strings einlesen zu wollen?

In dem Link ist eine selbst geschriebene Funktion um eine ganze Zeile einzulesen die mit einem Linefeed abgeschlossen ist. Und anders als die Standard Arduino Funktionen ist das blockierungsfrei. Wieso hast du die ignoriert und den Funktionsaufruf ersetzt?

In C sind Zeichenketten Null-terminierte Arrays aus char. Man muss Zeichen für Zeichen bis zu einem Endzeichen in ein Array einlesen und dann den String terminieren. Erst wenn alle Zeichen da sind kann man das verarbeiten. Das geht nunmal nicht mit read()

if (txt>0)

Hier hast du auch nicht verstanden was gemacht wird. Die Abfrage ob man was Empfangen hat ist schon hier:

if (txt != nullptr)

Zu dem Zeitpunkt hast du noch einen Text. Die Konvertierung in einen Integer kommt erst mit atoi()

Sorry, aber das readLine will er irgendwie nicht

char* txt=BT.readLine();
char* txt=readLine(BT);
char* txt=readLine(Serial);

→ ‘class SoftwareSerial’ has no member named ‘readLine’
oder
→ ‘readLine’ was not declared in this scope

#include <AccelStepper.h>
#define dirPin 8
#define stepPin 9
#define motorInterfaceType 1
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);


#include <SoftwareSerial.h>
SoftwareSerial BT(5, 6); 

unsigned int value;

void setup() {
  Serial.begin(9600);
  
// Set the maximum speed in steps per second:
stepper.setMaxSpeed(8000);

// Bluetooth --------------------------------  
  BT.begin(9600);                    
  BT.println("Hello from Arduino");
  //Serial.println("SET BT NAME Arduino_BT");
// ------------------------------------------  

  // Microstepping ----------------------------
//  Low   Low   Low   Full step
//  High  Low   Low   Half step
//  Low   High  Low   1/4 step
//  High  High  Low   1/8 step
//  Low   Low   High  1/16 step
//  High  Low   High  1/32 step
//  Low   High  High  1/32 step
//  High  High  High  1/32 step

  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);
  pinMode(12, OUTPUT);
  digitalWrite(12, HIGH);
// ------------------------------------------

  stepper.setSpeed(0);
  
}
void loop() {

  stepper.runSpeed();

  if (BT.available())
  {
    char* txt=readLine(Serial);                              
        if (txt != nullptr)
        {
          BT.println("Empfange");
           switch(txt[0])
           {
              case 'M':
              case 'm':
                value = atoi(txt + 1);
                Serial.println(value);
                stepper.setSpeed(value);
           }
        }
    else
    {
    stepper.setSpeed(0);  
    } 
  }
}
char* txt=(BT.read());

hiermit estellst du einen Zeiger. Aber wo zeigt der hin?

--> 'readLine' was not declared in this scope

hast du das auch gelesen und verstanden?

hiermit estellst du einen Zeiger. Aber wo zeigt der hin?

Das geht gar nicht, weil read() keinen Zeiger zurück gibt

Korrekt so:

char* txt=readLine(BT);

readLine() hat eine Referenz auf ein Stream Objekt als Parameter. Das ist die Oberklasse aller Serial Klassen (und auch ein paar anderer Klassen). Damit kann man dann einfach die Quelle angeben

-> 'class SoftwareSerial' has no member named 'readLine'

Natürlich. Das ist ja auch keine Methode der Klasse

Die readLine() Funktion musst du aber schon in deinen Sketch kopieren. Wieso lässt du die weg? Das ist eine selbst geschriebene Funktion und nicht Teil der Arduino Software. Die steht in dem Link den ich dir gegeben habe. Das solltest du dir auch mal ansehen Dir mangelt es gewaltig an Grundlagen Wissen. Wenn du nur willkürlich Code hinschreibst bis etwas kompiliert wird das nichts.

Auch das weg:

 if (BT.available())

Schau dir mal die readLine() Funktion an! Die Abfrage ob was da ist ist da schon drin

er kompiliert fehlerfrei mit

#include <AccelStepper.h>
#define dirPin 8
#define stepPin 9
#define motorInterfaceType 1
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);


#include <SoftwareSerial.h>
SoftwareSerial BT(5, 6); 

unsigned int value;
const unsigned int READ_BUFFER_SIZE = 17;    //16 Zeichen + Terminator

void setup() {
  Serial.begin(9600);
  
// Set the maximum speed in steps per second:
stepper.setMaxSpeed(8000);

// Bluetooth --------------------------------  
  BT.begin(9600);                    
  BT.println("Hello from Arduino");
  //Serial.println("SET BT NAME Arduino_BT");
// ------------------------------------------  

  // Microstepping ----------------------------
//  Low   Low   Low   Full step
//  High  Low   Low   Half step
//  Low   High  Low   1/4 step
//  High  High  Low   1/8 step
//  Low   Low   High  1/16 step
//  High  Low   High  1/32 step
//  Low   High  High  1/32 step
//  High  High  High  1/32 step

  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);
  pinMode(12, OUTPUT);
  digitalWrite(12, HIGH);
// ------------------------------------------

  stepper.setSpeed(0);
  
}
void loop() {

  stepper.runSpeed();

    char* txt=readLine(Serial);                              
        if (txt != nullptr)
        {
          BT.println("Empfange");
           switch(txt[0])
           {
              case 'M':
              case 'm':
                value = atoi(txt + 1);
                Serial.println(value);
                stepper.setSpeed(value);
           }
        }
    else
    {
    stepper.setSpeed(0);  
    } 

}



char* readLine(Stream& stream)
{
  static byte index;
  static char buffer[READ_BUFFER_SIZE];

  while (stream.available())
  {
    char c = stream.read();

    if (c == '\n')          //wenn LF eingelesen
    {
      buffer[index] = '\0';   //String terminieren
      index = 0;
      return buffer;        //melden dass String fertig eingelesen wurde
    }
    else if (c >= 32 && index < READ_BUFFER_SIZE - 1)   //solange noch Platz im Puffer ist
    {
      buffer[index++] = c;    //Zeichen abspeichern und Index inkrementieren
    }
  }
  return nullptr;           //noch nicht fertig
}

bekomme nun aber natürlich keine werte mehr per BT.
Ich guck nochmal, muss wohl nochmal bei Null anfangen.

Danke…

char* txt=readLine(Serial);

Wenn du von Bluetooth empfangen willst, dann musst da auch dein SoftwareSerial Objekt übergeben. Das geht schon.

Und daran denken dass du gesendete Zeile mit einem Linefeed abschließt. Entweder per Hand oder es gibt auch Methoden wie println() auf dem Arduino die das automatisch machen