Arduino串口接收16进制,如何转换成10进制?-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 27543|回复: 31

[未解决] Arduino串口接收16进制,如何转换成10进制?

[复制链接]
发表于 2018-5-30 17:37 | 显示全部楼层 |阅读模式
本帖最后由 kmaxzm 于 2018-5-30 17:37 编辑

一个甲醛传感器串口接收一串16进制数据,例如 FF,17,04,00,01,1a,07,D0,0E,其中01,1a为高位和低位的2个数据,为16进制,公式为 ((hi*256)+low)/1000;。
在树莓派上用java很容易实现:  //hcho格式:FF,17,04,00,01,1a,07,D0,0E
String asd[] = hcho.split(",");
hi = Integer.parseInt(asd[4],16);low = Integer.parseInt(asd[5],16);
rzt = ((hi*256)+low)/1000;
fin = String.format("%.3f",rzt);  


fin即最终结果。

这段代码请问如何在Arduino上实现?谢谢!




发表于 2018-7-24 16:17 | 显示全部楼层
本帖最后由 fairsky888 于 2018-7-24 16:33 编辑
t1k2 发表于 2018-7-24 14:22
非常感谢。但有两个问题请教:1,我要求是时时同步的,所以,这一句是否改为:(comdata.length()>0){
int ...

当然是Arduino啦!!我不知道你用的什么气体传感器,我用过测甲醛,一氧化碳,臭氧的传感器,他们有两种模式,一种是问答式和主动上传式。应该默认是主动上传方式。一秒钟上传一次。ARDUINO只要接收信号, 然后分解出来就可以了,当然是时时同步的!!!。当然你可以为了是数据准确,你也可以做校验。我之前做的一个测臭氧的。[mw_shl_code=c,true]#include <SoftwareSerial.h>
SoftwareSerial mySerial(12, 13); // RX, TX
String comdata="";
unsigned char DEC1,DEC2;float o3Val;
int CheckSum;
byte Command[]={0xFF,0x01,0x78,0x40,0x00,0x00,0x00,0x00,0x47};//主动上传
byte Command1[]={0xFF,0x01,0x78,0x41,0x00,0x00,0x00,0x00,0x46};//问答上传
byte Command2[]={0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};//问答读取
void setup() {
Serial.begin(9600);
mySerial.begin(9600);
delay(1000);
mySerial.write(Command,9);
}
void loop() {
while(mySerial.available()>0){
    comdata+=char(mySerial.read());
     delay(2);
  }
if(comdata.length()>0){
  CheckSum=0x00;
  for(int x=0;x<comdata.length();x++){
  if(x<8)CheckSum+=comdata[x];   //计算校验和
  myPtHex(comdata[x]);  //16进制串口输出。接收的是什么代码。
  }   
  CheckSum=~(CheckSum&&0xFF);  //取反
  if(comdata[8]==CheckSum){
   DEC1=comdata[4];
   DEC2=comdata[5];
   int o3val=DEC1*256+DEC2;
   o3Val=o3val/1000.0;  
  }
  Serial.println(o3Val,3);
  comdata="";
}   
}
void myPtHex(int g){ // 把 g 最右邊 byte 印成 Hex 倆位
  int a = g& 0xf0;  // 左邊 4 bits
  a = a >> 4;  // 右移 4 bits
  int b = g& 0x0f;  // 右邊 4 bits
  char c = a < 10 ? a + '0' : a + 'A' - 10;
  Serial.write(c);
  c = b < 10 ? b + '0' : b + 'A' - 10;
  Serial.write(c);
}[/mw_shl_code]


发表于 2018-7-24 18:52 | 显示全部楼层
t1k2 发表于 2018-7-24 17:04
另外,返回的16位二氧化碳浓度值出现在第2,3位,如:FF 86 04 05 50 00 00 00 21(红字)。 ...

虽然没有看到说明书,这已经很明显了啦,第一位FF是固定的开头,第二位86或第五位50应该是气体类型的一个代码,最后一位是校检码,算法是前8位累加再取反。和我用的传感器差不多的,只是你的数据在2,3位。你只要把我们面的程式的数组4,5改成2,3就可以了。你如果要想WIN桌面软件来实现我帮不了你,如果用ARDUINO我可以帮你改一下。
[mw_shl_code=c,true]#include <SoftwareSerial.h>
SoftwareSerial mySerial(12, 13); // RX, TX
String comdata="";
unsigned char DEC1,DEC2;
char CheckSum;
float o3Val;
//byte Command[]={0xFF,0x01,0x78,0x40,0x00,0x00,0x00,0x00,0x47};//主动上传
//byte Command1[]={0xFF,0x01,0x78,0x41,0x00,0x00,0x00,0x00,0x46};//问答上传
byte Command2[]={0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};//问答读取
void setup() {
Serial.begin(9600);
mySerial.begin(9600);
//delay(1000);
//mySerial.write(Command,9);
}
void loop() {
mySerial.write(Command2,9);
while(mySerial.available()>0){
    comdata+=char(mySerial.read());
     delay(2);
  }
if(comdata.length()>0){
  CheckSum=0x00;
  for(int x=0;x<comdata.length();x++){
  if(x<8)CheckSum+=comdata[x];   //计算校验和
// myPtHex(comdata[x]);  //16进制串口输出。接收的是什么代码。
  }
  CheckSum=~(CheckSum&&0xFF);  //取反
  if(comdata[8]==CheckSum){
   DEC1=comdata[2];
   DEC2=comdata[3];
   int o3val=DEC1*256+DEC2;
   o3Val=o3val/1000.0;  
  }
  Serial.println(o3Val,3);
  comdata="";
}
delay(1000);   
}
void myPtHex(int g){ // 把 g 最右邊 byte 印成 Hex 倆位
  int a = g& 0xf0;  // 左邊 4 bits
  a = a >> 4;  // 右移 4 bits
  int b = g& 0x0f;  // 右邊 4 bits
  char c = a < 10 ? a + '0' : a + 'A' - 10;
  Serial.write(c);
  c = b < 10 ? b + '0' : b + 'A' - 10;
  Serial.write(c);
}[/mw_shl_code]

点评

高手!留个QQ号,请教关于串口读取的数据处理。我的QQ:263522492  发表于 2018-9-8 14:22
非常专业!  发表于 2018-7-25 10:04
发表于 2018-5-31 09:08 | 显示全部楼层
给你讲一下思路。
Serial.readString(),接收到字符串。
确定有无浮点。
把字符串里的数字提出来,把字符串变成int型。
把浮点加进去转化成float。
发表于 2018-5-31 14:13 | 显示全部楼层
接收为一个数组,,比如为p={0xFF,0x17,0x04,0x00,0x01,0x1a,0x07,0xD0,0x0E}然后直接操作该字节
float val = (p[4]*256+p[5])/1000.00;
 楼主| 发表于 2018-5-31 17:08 | 显示全部楼层
跑龙套的保 发表于 2018-5-31 14:13
接收为一个数组,,比如为p={0xFF,0x17,0x04,0x00,0x01,0x1a,0x07,0xD0,0x0E}然后直接操作该字节
float val ...

感谢回复,如何操作才能将接受到的这些hex写进一个数组呢?
发表于 2018-5-31 18:07 | 显示全部楼层
kmaxzm 发表于 2018-5-31 17:08
感谢回复,如何操作才能将接受到的这些hex写进一个数组呢?

https://www.arduino.cn/forum.php?mod=viewthread&tid=46248
第二段代码
发表于 2018-7-23 17:13 | 显示全部楼层
版主,我有一个非常类似的需求。也是气体传感器的16进制数据时时同步转换成10进制。要求在win7以上(含)电脑屏幕显示(弹窗方式即可,如有应用程序界面更好)。
发表于 2018-7-23 17:24 | 显示全部楼层
FF 86 04 05 50 00 00 00 21
发表于 2018-7-23 17:26 | 显示全部楼层
8位,16进制,需要的数据在第2,3位(即红色字体)。
发表于 2018-7-23 17:28 | 显示全部楼层
要求开放源代码。先预估费用和支付条件。
发表于 2018-7-23 18:05 | 显示全部楼层
本帖最后由 fairsky888 于 2018-7-23 18:21 编辑

嘿嘿,[mw_shl_code=bash,true]String comdata="";
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
}
void loop()
{

while(Serial1.available()>0){
   comdata+=char(Serial.read());
    delay(2);
}  
if(comdata.length()>0){
int data=comdata[4]*256+comdata[5];Serial.print(data);
comdata="";
}
}

[/mw_shl_code]

仅供参考
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 00:44 , Processed in 0.338590 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表