Arduino使用sscanf读取浮点数

Arduino Reading floating point numbers with sscanf

本文关键字:浮点数 读取 sscanf 使用 Arduino      更新时间:2023-10-16

我试图用sscan((读取数字,但我用双变量没有成功,但可以读取int

双示例

//double var reading not working 
const char KBuffer[80] = "0x3:2.1:2.1:2.1";
int rt;
double p,i,d;
int n = sscanf(KBuffer, "%x:%lf:%lf:%lf", &rt, &p, &i, &d);
Serial.println();
Serial.print("rt "); Serial.print(rt);
Serial.print(" P ");Serial.print(p);
Serial.print(" i ");Serial.print(i);
Serial.print(" d ");Serial.print(d);

//输出rt 3 P 0.00 i ovf d 0.00

int 示例

// int reading working ok
const char KBuffer[80] = "0x3:2:2:2";
int rt;
int p,i,d;
int n = sscanf(KBuffer, "%x:%d:%d:%d", &rt, &p, &i, &d);
Serial.println();
Serial.print("rt "); Serial.print(rt);
Serial.print(" P ");Serial.print(p);
Serial.print(" i ");Serial.print(i);
Serial.print(" d ");Serial.print(d);
// output
rt 3 P 2 i 2 i 2 

所以你知道做错了什么吗

当我在c++在线编译器上运行时,同样的代码如下:https://onlinegdb.com/ryS8zfE3r

我得到了正确的结果

即使第一次转换顺利,arduino scanf也不会读取浮点数,printf也不会打印它们。默认情况下,scanf和printf族函数不支持浮点数。

第一个问题很容易分类:int n = sscanf(KBuffer, "0x%x:%d:%d:%d", &rt, &p, &i, &d);第二个问题需要通过添加-Wl,-u,vfscanf -lscanf_flt -lm来更改编译器(或链接器(操作,但irt将使图像大小增加约15kb。

在安装板库的目录中的hardware/tools/avr/doc/avr-libc/group__avr__stdio.html中阅读更多信息

花了一段时间后,我得出结论,sscanf不能处理浮点/双值,所以为了解决通过串行通信输入浮点的问题,我采用了另一种方法,我分享它可能会帮助

void setup() {
Serial.begin(9600);
}
void loop() {
char KBuffer[80] = "c:0x3;p:2.12;i:2.15;d:2.17";
bool top_pid_input = false;
// Read each command pair
char* command = strtok(KBuffer, ";");
while (command != NULL)
{  
//  Serial.print(command);
// Split the command in two values
char* separator = strchr(command, ':');
if (separator != 0)
{
// Actually split the string in 2: replace ':' with 0
*separator = 0;
// string
if(strcmp(command, "c") == 0 ){
top_pid_input = true;
Serial.println();Serial.print(" command: ");Serial.print(command);
++separator;
Serial.print(separator);
}else if(top_pid_input && strcmp(command, "p") == 0 ){
Serial.println();Serial.print(" p: ");Serial.print(command);
++separator;
Serial.print(separator);        
}else if(top_pid_input && strcmp(command, "i") == 0 ){
Serial.println();Serial.print(" i: ");Serial.print(command);
++separator;
Serial.print(separator);          
}else if(top_pid_input && strcmp(command, "d") == 0 ){
Serial.println();Serial.print(" d: ");Serial.print(command);
++separator;
Serial.print(separator);         
}
// convert char to float 
top_kd = atof(separator);  
}
// Find the next command in input string
command = strtok(0, ";");
}

delay(300000);
}

编辑:问题已编辑,因此此答案不再相关

根据scanf()系列功能的手册页:

返回值这些函数返回输入项的数量成功匹配和分配,数量可能少于提供的数量例如在早期匹配失败的情况下为零。

您应该在代码中检查返回值n,以查看转换是否失败。

这里,第一次转换失败:%d无法读取十六进制数字。再次从手册页:

d

匹配一个可选的带符号十进制整数;下一个指针必须是指向内部的指针

您必须改用%x

x

匹配一个无符号十六进制整数;下一个指针必须是指向无符号整数的指针

因为第一次转换失败,所以不会执行其他转换。