6

I got a String which as I understand is an Arduino object, and got some C++ code:

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <string.h>

LiquidCrystal_I2C lcd(0x20,16,2); 

boolean borrar = false;
String IP;

void setup()
{
  lcd.init();
  lcd.backlight();
  pinMode(13,OUTPUT);
  Serial.begin(9600);
  Serial1.begin(9600);

}

void loop() {

  while (Serial1.available()) { 

    char caracter = Serial1.read(); //Comprobamos el caracter 

    switch(caracter) {

    default:
                if (borrar) { 
                              IP = ""; 
                              lcd.clear();
                }

                lcd.print(caracter);
                delay(125);
                borrar = false;

                IP.concat(caracter);
                break;  

    case '\r':                
    case 0x0F:
    case 0x0A:  

                String res = "";
                borrar = true;
                int num= atoi(IP.c_str());
                if (num < 127) 
                  res="Clase A";
                if (num == 127) 
                  res="Direccion reservada";
                if (num > 127 && num < 192)
                  res="Clase B ";
                if (num >= 192 && num < 224)
                  res="Clase C ";
                if (num >= 224 && num < 240)
                  res="Clase D ";
                if (num >= 240 && num < 255)
                  res="Clase E ";
                break;  

  } //fin switch

}//serial disponible


}//fin programa

However, this won't compile because of this line:

int num= atoi(IP.c_str())

As IP is a String and such method works for string. How can I make it compatible (convert it)?

2

Your code could be improved by removing the use of IP string altogether, and directly calculating its numeric value while characters come in through Serial1:

...
boolean borrar = false;
int IP = 0;
...

void loop() {
  while (Serial1.available()) { 
    char caracter = Serial1.read(); //Comprobamos el caracter 
    switch(caracter) {

    // NOTE it is better to replace default by the list of all digits...    
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
                if (borrar) { 
                              IP = 0; 
                              lcd.clear();
                }

                lcd.print(caracter);
                delay(125);
                borrar = false;

                IP *= 10;
                IP += (int) (caracter - '0');
                break;  

    case '\r':                
    case 0x0F:
    case 0x0A:  

                String res = "";
                borrar = true;
                int num= IP;
                if (num < 127) 
                  res="Clase A";
                if (num == 127) 
                  res="Direccion reservada";
                if (num > 127 && num < 192)
                  res="Clase B ";
                if (num >= 192 && num < 224)
                  res="Clase C ";
                if (num >= 224 && num < 240)
                  res="Clase D ";
                if (num >= 240 && num < 255)
                  res="Clase E ";
                break;  

  } //fin switch

}//serial disponible

}//fin programa

This way would bring you 2 advantages:

  1. a bit faster than working with String
  2. no dynamic memory allocation/deallocation (String does a lot of these) which might lead your program to heap fragmentation and eventually crash.

Note that I have not further refactored your code as I guessed it was just a snippet, not the complete code for your program. Otherwise, I would have performed further refinement like:

  • remove num variable since it is the same as IP now
  • replace res from String to const char* (to further reduce heap fragmentation due to String usage)
6

Try

unsigned char z[100];
IP.getBytes(z, 100);
z[IP.length()] = 0;
int n = atoi(z);

To retrieve bytes inside the string. This assumes IP string's length is shorter than 100.

6
  • I tried and got: BluetoothLCD.cpp:51:35: error: invalid conversion from ‘char*’ to ‘unsigned char*’ BluetoothLCD.cpp:51:35: error: initializing argument 1 of ‘void String::getBytes(unsigned char*, unsigned int, unsigned int) const’ Apr 24 '14 at 8:42
  • I have updated char to unsigned char
    – rmi
    Apr 24 '14 at 8:44
  • Something weird is going on, now I obtain: BluetoothLCD.cpp:53:33: error: invalid conversion from ‘unsigned char*’ to ‘const char*’ BluetoothLCD.cpp:53:33: error: initializing argument 1 of ‘int atoi(const char*)’ Apr 24 '14 at 8:45
  • If it does not support, IP.toCharArray(z, 100); may be used.
    – rmi
    Apr 24 '14 at 8:46
  • How would code look like? Apr 24 '14 at 8:49
2

Try updating to the latest version of the Arduino libraries/IDE.

The c_str() method was introduced to the Arduino String class quite recently, I believe. That line of code certainly works fine for me on Arduino IDE 1.0.5.

3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.