how could i get int type value from char array?

103 Views Asked by At

i want get three different int values from one input text (I will type "nn_nn_n").

for example. if i type "60_25_5", my code is seperating a recieved text into three part by using underbar(_) and setting 'null', and i think three char array (text1, text2, text3) will have each value (60, 25, 5) finally, to use these values as a integer, i used atoi() .

this is my code:

#include <String.h>
#include <stdlib.h>
#include <SoftwareSerial.h> 

void setup {    
   Serial.begin(9600);  
   Serial.println("start");
}
void loop() {
    if(Serial.available()){   
      char *data = Serial.read();// = nn_nn_n
      data[2]='\0';     
      data[5]='\0';     
      char *str ;       
      str = data ;      
      
      char text1[4]; 
      strcpy(text1,str);
      str = data + 3;   
      char text2[4];    
      strcpy(text2, str);
      str = data + 6;   
      char text3[4];    
      strcpy(text3, str);

      int a= atoi(text1);
      int b= atoi(text2);
      int c= atoi(text3);
      Serial.print(a);
      Serial.print(b);
      Serial.print(c);
     }
}

but the resutl of this:

start
000000000000000000000000

i know that im a super noob, but i'm ready to learn what you teach me! I waiting your comment, thanks.

3

There are 3 best solutions below

0
Peter Plesník On

If you are want teach how things works, don't use arduino IDE, because there is not good tool for watch what MCU doing. I use Atmel studio to show you how debug some parts of your code. Here is tools named debugger (and simulator) which allow as make look inside whole MCU parts (look at attached picture).

Basically, you have three basic misunderstandings in your code :

  • How serial communication works
  • How Serial.read() works
  • What char *data is.
  1. Transferring one character over a serial line takes some time. For baud rate 9600 baud this time is 10*1/baudRate. This is approximately 1ms.
    During this time MCU is capable execute loop function maybe thousand times. Of course, mostly doing nothing because Serial.available() returns false. When first characters of transmitted message arrive Serial.available() returns true and code in conditions is start execute. But whole code is executed very quickly. No others characters is transmitted yet. Next character arrive again after 1ms. So your code process only one characters and again waits to next arrived characters. Because message have 8 characters (6 + CR LF), your code eight times write values variables a b c and you get this responds 000 000 000 000 000 000 000 000 Space is not sending, but it represents waiting for next chars in loop function. So after every chars what MCU receive print values 000 Let's find out why all variables was evaluated to 0 value.

  2. Serial.read() not return String or string as you are expected. You must read Arduino documentation and understand it. Function returns -1 if no data available or first available byte from message. In other words you get number representing ASCII value of arrived characters. In your example you get first value 0x36 because ASCII value of digits six is 0x36 ('6'). This is reason because I change your command char *data = Serial.read();// = nn_nn_n to char *data = '6'; which represent situation after first chars arriving.

  3. What this command doing? (spoiler - very bad things in this case) This command create local variable what is a pointer to char. This variable is created on the stack and take two bytes. You can see it in watch window on first row. You can see that address of this variable is 0x08E6. This variable is automatically created in loop function and is here inserted value returned from calling Serial.read(). So in first character is there value 0x36. But remember this is pointer to char It's mean that data pointer now point to address '0x36'. This is bad, really very bad. What is on address 0x36. You can see this portion of MCU memory in window Memmory1. Unfortunately this is part of memory reserved for access to IO registers. This registers control HW of MCU like Timers, Converters, SPI, IIC, UARTS ... It is very bad idea write random values to this area.
    data[2]='\0'; This will try write zero to 0x0038 register
    data[5]='\0'This will try write zero to 0x003B register
    You are lucky in this case as you can see all registers in this portion has zero values and you don't break any hw configuration. All others commands can be easy checked by stepping and it is easy understand that you are still play wits zero length strings. So at finally values variables a b c became zero.

(all this story line it's a deal in case that MCU is ATMEGA328) Simulator view

0
ScottJ On

You might consider using strtok() to parse the numbers apart. Then still use atoi() to get your values.

Look at this example:

https://www.best-microcontroller-projects.com/arduino-strtok.html

void setup(void) {
char *token;
char *mystring = "apples,pears,bananas";
const char *delimiter =",";

   Serial.begin(115200);

   token = strtok(mystring, delimiter);

   while (token != NULL) {
      Serial.println(token);
      token=strtok(NULL, delimiter);
   }

}

void loop(void) {

}
0
Mohammadreza Askari On

Just use standard libraries:

#include <String.h>
#include <stdlib.h>
#include <SoftwareSerial.h>

#include <stdio.h>

void setup {
    Serial.begin(9600);
    Serial.println("start");
}

void loop() {
    int a, b, c;
    if(Serial.available()){
        char* str = Serial.read(); // any in format of: "##_##_##", Ex: "60_25_5"
        sscanf(text, "%d_%d_%d", &a, &b, &c);
        printf("\nGiven numbers: %d, %d, %d", a, b, c);
    }
}