arduino双机通信 (单片机对单片机)-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2575|回复: 1

arduino双机通信 (单片机对单片机)

[复制链接]
发表于 2020-10-27 14:16 | 显示全部楼层 |阅读模式
本帖最后由 z01228 于 2020-10-29 22:27 编辑

作用

实现将一个 arduino 中的多个 String 类型变量准确地传到另一个 arduino 中对应的多个 String 类型变量
中。如果一个arduino 开发板不能满足目前的项目,就需要通过串口发送命令进行分步执行(即上下位机)

ps:程序是参考网络 我这里只是搬运工

    程序里可以添加校验的程序提高命令的稳定性。

接线图

(注意 TX 接另一个arduino的 RX !可以忽略图中的 LED )

代码1 号机器(主机)
  1. float data1=18.98;//要发送的数据
  2. float data2=56.73;//要发送的数据
  3. float data3=104.27;//要发送的数据

  4. float data4=0;//要接收的数据
  5. float data5=0;//要接收的数据
  6. float data6=0;//要接收的数据

  7. void setup()
  8. {

  9.   Serial.begin(9600);//两机的波特率要求相同
  10. }


  11. void loop()
  12. {
  13. transmit();//发送数据

  14. receive();//接收数据
  15.      Serial.println(data4);//显示接收到的数据
  16.       Serial.println(data5);//显示接收到的数据
  17.       Serial.println(data6);//显示接收到的数据

  18. }

  19. void transmit(){


  20.         Serial.print('a');
  21.         Serial.print(data1);
  22.         Serial.print('b');
  23.         Serial.print(data2);
  24.         Serial.print('c');
  25.         Serial.print(data3);
  26.         Serial.println('#');
  27.         delay(100);
  28.         //发送"a数据1b数据2c数据3#"的字符串必须停顿100毫秒

  29.   }

  30. void receive(){

  31.   String comdata = "";//存放接收到的原始字符串
  32.   String buf1="";//存放解析出的第一个字符串
  33.   String buf2="";//存放解析出的第二个字符串
  34.   String buf3="";//存放解析出的第三个字符串

  35.     while (Serial.available() > 0)  
  36.     {
  37.         comdata += char(Serial.read());
  38.         delay(2);//一个一个接收数据,每次停顿2毫秒
  39.     }
  40.     if (comdata.length() > 0)//如果有数据收到
  41.     {
  42.       int ja,jb,jc,jd;//存放收到的字符串中标志字母的下标

  43. for(int i = 0; i < comdata.length(); i++){

  44.   if(comdata[i]=='a'){ja=i;}
  45.   if(comdata[i]=='b'){jb=i;}
  46.   if(comdata[i]=='c'){jc=i;}
  47.   if(comdata[i]=='#'){jd=i;}

  48.   }//找到约定标志字母的下标

  49. for(int k=ja+1;k<jb;k++){
  50.   buf1+=char(comdata[k]);
  51.   }
  52.   for(int k=jb+1;k<jc;k++){
  53.   buf2+=char(comdata[k]);
  54.   }
  55.   for(int k=jc+1;k<jd;k++){
  56.   buf3+=char(comdata[k]);
  57.   }//根据约定字母所在的位置依次解析出各个数据
  58.          data4=buf1.toFloat();//将解析得到的字符串转换为float类型
  59.          data5=buf2.toFloat();
  60.          data6=buf3.toFloat();


  61.     }

  62.   }
复制代码


2 号机器(从机)
  1. float data4=22.23;//要发送的数据
  2. float data5=49.18;//要发送的数据
  3. float data6=347.59;//要发送的数据

  4. float data1=0;//要接收的数据
  5. float data2=0;//要接收的数据
  6. float data3=0;//要接收的数据

  7. void setup()
  8. {
  9.     Serial.begin(9600);//两机的波特率要求相同
  10. }

  11. void loop()
  12. {
  13.    transmit();//发送数据
  14.    receive();//接收数据
  15.       Serial.println(data1);//显示接收到的数据
  16.       Serial.println(data2);//显示接收到的数据
  17.       Serial.println(data3);//显示接收到的数据
  18. }



  19. void receive(){

  20.   String comdata = "";//存放接收到的原始字符串
  21.   String buf1="";//存放解析出的第一个字符串
  22.   String buf2="";//存放解析出的第二个字符串
  23.   String buf3="";//存放解析出的第三个字符串

  24.     while (Serial.available() > 0)  
  25.     {
  26.         comdata += char(Serial.read());
  27.         delay(2);//一个一个接收数据,每次停顿2毫秒
  28.     }
  29.     if (comdata.length() > 0)//如果有数据收到
  30.     {
  31.       int ja,jb,jc,jd;//存放收到的字符串中标志字母的下标

  32. for(int i = 0; i < comdata.length(); i++){

  33.   if(comdata[i]=='a'){ja=i;}
  34.   if(comdata[i]=='b'){jb=i;}
  35.   if(comdata[i]=='c'){jc=i;}
  36.   if(comdata[i]=='#'){jd=i;}

  37.   }//找到约定标志字母的下标

  38. for(int k=ja+1;k<jb;k++){
  39.   buf1+=char(comdata[k]);
  40.   }
  41.   for(int k=jb+1;k<jc;k++){
  42.   buf2+=char(comdata[k]);
  43.   }
  44.   for(int k=jc+1;k<jd;k++){
  45.   buf3+=char(comdata[k]);
  46.   }//根据约定字母所在的位置依次解析出各个数据
  47.          data1=buf1.toFloat();//将解析得到的字符串转换为float类型
  48.          data2=buf2.toFloat();
  49.          data3=buf3.toFloat();


  50.     }

  51.   }
  52. void transmit(){
  53.         Serial.print('a');
  54.         Serial.print(data4);
  55.         Serial.print('b');
  56.         Serial.print(data5);
  57.         Serial.print('c');
  58.         Serial.print(data6);
  59.         Serial.println('#');
  60.         delay(100);
  61. //发送"a数据1b数据2c数据3#"的字符串必须停顿100毫秒
  62.   }
复制代码
类型转换

由于以上双机通信传的是String类型,真正使用时肯定需要类型转换,所以特地收集了以下的转码大合集,总有几款适合你。

  1. char fc[50];
  2. char ic[20];

  3. void setup() {
  4.   Serial.begin(9600);
  5. }

  6. void loop() {

  7. String s="123.43212";//从一个String开始

  8. float f=s.toFloat();//String转float

  9. int i=s.toInt();//String转int

  10. dtostrf(f,1,5,fc);//将float转为char的数组,其中第三个传入值(5)是保留的位数(5位)

  11. snprintf (ic, 75, "%d", i);//将int转为char的数组.

  12. //以下为串口打印验证
  13. Serial.println(f,5);//打印保留float变量后五位的数
  14. delay(1000);
  15. Serial.println(i);//打印int变量
  16. delay(1000);
  17. Serial.println(fc);//打印float转成的char的数组
  18. delay(1000);
  19. Serial.println(ic);//打印int转成的char的数组
  20. delay(1000);


  21. }
复制代码


试验例子:
  1. //串口编解码程序--串口解码协议--编码是发送对应的字符串就可以
  2. //例如串口输入a12b16c18# 串口将数据分别分给指定变量(浮点数)(data4--12,data5--16,data6--18)
  3. //目前没有添加校验程序‘#’只有限位作用。
  4. float data4=0;//要接收的数据
  5. float data5=0;//要接收的数据
  6. float data6=0;//要接收的数据
  7. boolean b=0;
  8. String comdata1 = "";//存放接收到的原始字符串
  9. void setup()
  10. {

  11.   Serial.begin(9600);//两机的波特率要求相同
  12. }


  13. void loop()
  14. {


  15. receive();//接收数据
  16.       Serial.println(" ");//
  17.       Serial.print("串口输入的原始数据:");
  18.       Serial.println(comdata1);//显示接收到的数据
  19.       Serial.println("解析出来的数据");//显示接收到的数据
  20.       Serial.print("data4-A:");
  21.       Serial.println(data4);//显示接收到的数据
  22.       Serial.print("data5-B:");
  23.       Serial.println(data5);//显示接收到的数据
  24.       Serial.print("data6-C:");
  25.       Serial.println(data6);//显示接收到的数据
  26.       Serial.println("++");//显示接收到的数据
  27.       delay(2000);

  28. }


  29. void receive(){

  30.   String comdata = "";//存放接收到的原始字符串
  31.   String buf1="";//存放解析出的第一个字符串
  32.   String buf2="";//存放解析出的第二个字符串
  33.   String buf3="";//存放解析出的第三个字符串

  34.     while (Serial.available() > 0)  
  35.     {
  36.         if (b==0){comdata1 = "";b=1;}
  37.         comdata += char(Serial.read());
  38.         delay(2);//一个一个接收数据,每次停顿2毫秒
  39.         comdata1 = comdata;//存放接收到的原始字符串
  40.     }
  41.      b=0;
  42.     if (comdata.length() > 0)//如果有数据收到
  43.     {
  44.       int ja,jb,jc,jd;//存放收到的字符串中标志字母的下标

  45. for(int i = 0; i < comdata.length(); i++){

  46.   if(comdata[i]=='a'){ja=i;}
  47.   if(comdata[i]=='b'){jb=i;}
  48.   if(comdata[i]=='c'){jc=i;}
  49.   if(comdata[i]=='#'){jd=i;}

  50.   }//找到约定标志字母的下标

  51. for(int k=ja+1;k<jb;k++){
  52.   buf1+=char(comdata[k]);
  53.   }
  54.   for(int k=jb+1;k<jc;k++){
  55.   buf2+=char(comdata[k]);
  56.   }
  57.   for(int k=jc+1;k<jd;k++){
  58.   buf3+=char(comdata[k]);
  59.   }//根据约定字母所在的位置依次解析出各个数据
  60.          data4=buf1.toFloat();//将解析得到的字符串转换为float类型
  61.          data5=buf2.toFloat();
  62.          data6=buf3.toFloat();


  63.     }

  64.   }
复制代码

添加字符串长度计算: 主机命令发送
  1. //字符串的拼接,以及长度获取。comdata=a+数据+b+数据+c+数据长度+#(结束符)
  2. //命令字符串示例:a**b**c**#
  3. //数据长度进行后期校验使用
  4. /*试验结果:

  5. 原始数据:a211b4c
  6. 原始数据长度(加了“#”长度,上面没有显示“#”):8

  7. 最后的数据、长度a211b4c9#
  8. 完整命令字符串长度:9

  9. */
  10. String comdata = "";     //新建中间变量
  11. String id1="a";   //拼接数据1
  12. int id2=211;     //拼接数据1
  13. String id3="b";     //拼接2
  14. int id4=4;     //拼接数据1
  15. String id5="c";     //拼接2
  16. //
  17. String id6="#";     //结束符3

  18. void setup() {
  19.   Serial.begin(9600);     //硬串口
  20.   int strLength=0;
  21.   comdata += id1;
  22.   comdata += id2;
  23.   comdata += id3;
  24.   comdata += id4;
  25.   comdata += id5;
  26.   strLength=comdata.length();//原始命令字符串的长度获取
  27.   strLength=strLength+1;  //提前补充一个"#"的长度
  28.   
  29.   Serial.print("原始数据:");     //换行
  30.   Serial.println(comdata);     //打印原始数据
  31.   Serial.print("原始数据长度(加了“#”长度,上面没有显示“#”):");     //换行
  32.   Serial.println(strLength);     //打印原始数据长度
  33.   Serial.println("");     //换行

  34.   //下面的这个if函数是保证命令字符串在10位是正常的 总的长度不能超过99
  35.   if(strLength>=9){strLength=strLength+2;//如果原始数据没有加长度命令的时候是大于等于9,长度就只需要+2
  36.   } else{
  37.     strLength=strLength+1; //如果原始数据没有加长度命令的时候是小于9,长度就只需要+1
  38.   }
  39.   comdata += strLength;//**在命令字符串里加入计算完毕的长度
  40.   comdata += id6;//**在命令字符串里加入"#"
  41.   strLength=comdata.length();
  42.   
  43.   Serial.print("最后的数据、长度");     //换行
  44.   Serial.println(comdata);     //打印完整命令字符串
  45.   Serial.print("完整命令字符串长度:");     //换行
  46.   Serial.println(strLength);     //打印完整命令字符串长度
  47.   Serial.println("");     //换行
  48.   
  49. }

  50. void loop() {
  51.   // put your main code here, to run repeatedly:

  52. }
复制代码





发表于 2020-11-3 20:20 | 显示全部楼层
好的,学习一下,等第二个板子回来我也玩玩看看
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-28 07:40 , Processed in 0.116494 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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