1

Appreciate your time.

I am trying to convert "String" read from serial port in serialEvent() of Arduino IDE to integer values with exact representation.

For eg, if String myString = 200 then int myInt should be 200.

I have been somewhat successful but unable to convert String to exact int representation beyond 255.

Solutions I have tried:

1) used .toInt() function in Arduino.

2) used "atoi" and "atol" functions.

3) Serial.parseInt() in loop().

All of these methods start recounting from 0 after every 255 values.

I can't use parseInt since it only works inside loop(). My application requires to store variable value permanently until another value is given through port. For this Arduino Due's flash memory has been used.

The memory storing code seems to work only inside serialEvent().

Code snippet is as below:

#include <stdlib.h>
#include <DueFlashStorage.h>
DueFlashStorage memory;

String x = " ";
int x_size;
int threshold;

void setup(){
  Serial.begin(115200);
}

void loop{
  Serial.println(memory.read(0));
}

void serialEvent(){

  while(Serial.available()){

    x = Serial.readStringUntil('\n');

    x_size = x.length();
    char a[x_size+1];

    x.toCharArray(a, x_size+1);

    threshold = atoi(a);

    memory.write(0, threshold);
  }
}
Abstract123
  • 67
  • 1
  • 8

4 Answers4

0

1) Function .toInt() returns LONG and you want INT (I don't know why honestly but it is in documentation)... you need to cast it like this (tried on Arduino ATMEGA and it worked):

#include <stdlib.h>

String x = "1000";
int x_ = 0;

void setup() {
  Serial.begin(9600);

}

void loop() {
  x_ = (int) x.toInt();

  Serial.println(x_);
  delay(1000);
}

2) I’m not professional ... but serilEvent() is really old way of doing things and it isn't recommended to use it. You can do it "manually" in the loop() function.

Jakub Szlaur
  • 1,852
  • 10
  • 39
  • Hi, I did try this. The main issue is that all casting/conversion methods seem to have a limit of 0 to 255. Beyond 255, the exact representation of the number string into integer or long is not returned. I did try running the code in loop() initially, it's only later that I moved to serialEvent() which seems to be doing a better job in reading values from serial port in this code. Thanks. Let me know if you have any other suggestions. – Abstract123 Mar 31 '19 at 03:05
  • Even Serial.parseInt() doesn't go beyond 255. – Abstract123 Mar 31 '19 at 03:18
0

You're only converting 1 character a time, that's why the limit is 255. If you're not doing anything else, you could stay in a serial.read-loop until all characters are read. For example:

void loop() {
  if(Serial.available()) {
    byte count = 0;
    char number[10]; // determine max size of array
    bool wait = true;
    while(wait) { // stay in this loop until newline is read
      if(Serial.available()) {
        number[count] = Serial.read();
        if (number[count] == '\n') {
          wait = false; // exit while loop
        }
        count++;
      }
    }  
    int threshold = atoi(number);
    memory.write(0, threshold);
  }
}
Finn
  • 149
  • 1
  • 5
  • Tried. Printed both char array "number" and int form "threshold". Same thing. The number printed is correct but threshold has a limit of 255. Thanks for suggesting. – Abstract123 Apr 05 '19 at 06:08
  • The problem is not the converting: if you would add `Serial.println(threshold);` you would see the whole int. BUT: `memory.write(0, threshold);` writes (and reads!) only 1 byte. See [this](https://github.com/sebnil/DueFlashStorage#advanced-use-to-store-configuration-parameters) how to read and store more than 1 byte. – Finn Apr 05 '19 at 07:51
  • Agreed. Memory only stores single byte but as I mentioned I did try with "Serial.println(threshold)" as well. It didn't work. But could try again. Will update. – Abstract123 Apr 05 '19 at 09:22
0

For the lack of a good function in Arduino IDE for char/String type to int type conversion (has a limit of 255), I wrote my own conversion code which seems to work perfectly.

int finalcount=0;


void setup(){

Serial.begin(115200);
}



void loop(){
   if(Serial.available()) {
    int count = 0;   
    char number[5];         // determine max size of array as 5

    bool wait = true;
    while(wait) {                // stay in this loop until newline is read
      if(Serial.available()) {
        number[count] = Serial.read();

        if (number[count] == '\n') {
          finalcount = count;         //max array size for integer; could be less than 5
          wait = false; // exit while loop
        }


        count++;
      }
    }  

    int val[finalcount];   //array size determined for integer
    int placeValue;         
    int finalval[finalcount];  
    int temp=0;
    int threshold;

    for(int i = 0; i<finalcount; i++){

        val[i] = (int)number[i]-48;        //convert each char to integer separately
        placeValue = pow(10,(finalcount-1)-i);  //calculate place value with a base of 10

        finalval[i] = val[i]*placeValue;      //update integers with their place value

        temp += finalval[i] ;            //add all integers 
        threshold = temp;              //resulting number stored as threshold             
    }

        Serial.println(threshold);     //prints beyond 255 successfully !


  }
}
Abstract123
  • 67
  • 1
  • 8
0

I solved the problem using highByte and lowByte functions of Arduino. Works flawlessly.

#include <DueFlashStorage.h>
DueFlashStorage m;
byte a1,a2;
int val;

void setup() {
   
 Serial.begin(115200);           //start the serial communication
}

void loop()
{
 
 if (Serial.available()>0)
    {  

     val = Serial.parseInt();     //read the integer value from series

    if(val>0){
     a1 = highByte(val);          //get the higher order or leftmost byte
     a2 = lowByte(val);           //get the lower order or rightmost byte
    
     m.write(0,a1);              //save in arduino due flash memory address 0
     m.write(1,a2);              //save in arduino due flash memory address 1

    }
  
  int myInteger;

   myInteger = (m.read(0)*256)+m.read(1);     //convert into the true integer value
                                
   Serial.println(myInteger); 
      
 } 
Abstract123
  • 67
  • 1
  • 8