在Arduino IDE中将大于255的“字符串”转换为精确的“整数”或“长整数”类型

Convert “String” above 255 to exact “Integer” or “Long” type in Arduino IDE

感谢您的时间。

我正在尝试将从Arduino IDE的serialEvent()中的串行端口读取的"字符串"转换为具有精确表示形式的整数值。

例如,如果String myString = 200,则int myInt应该为200。

我取得了一些成功,但无法将String转换为超过255的精确int表示形式。

我尝试过的解决方案:

1)在Arduino中使用了.toInt()函数。

2)使用了" atoi"和" atol"功能。

3)在loop()中使用Serial.parseInt()。

所有这些方法在每255个值后都从0开始重新计数。

我不能使用parseInt,因为它只能在loop()内部工作。 我的应用程序需要永久存储变量值,直到通过端口给出另一个值为止。 为此使用了Arduino Due的闪存。

内存存储代码似乎仅在serialEvent()内部起作用。

程式码片段如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#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('\
');

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

    x.toCharArray(a, x_size+1);

    threshold = atoi(a);

    memory.write(0, threshold);
  }
}

我使用Arduino的highByte和lowByte函数解决了这个问题。 完美地工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#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);
     
 }

由于在Arduino IDE中缺少从char / String类型到int类型转换(限制为255)的良好功能,我编写了自己的转换代码,该代码似乎运行得很好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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] == '\
') {
          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 !


  }
}

您一次只转换1个字符,因此限制为255。
如果您没有执行其他任何操作,则可以停留在serial.read-loop中,直到读取所有字符为止。 例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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] == '\
') {
          wait = false; // exit while loop
        }
        count++;
      }
    }  
    int threshold = atoi(number);
    memory.write(0, threshold);
  }
}


1)函数.toInt()返回LONG,并且您想要INT(老实说,我不知道为什么,但是在文档中)...您需要像这样进行转换(在Arduino ATMEGA上尝试过并起作用):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#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)我不是专业人士,但是serilEvent()确实是旧的处理方式,不建议使用它。 您可以在loop()函数中"手动"执行此操作。