前言

因项目需求,我们要从PC端去控制一些外部设备,比如激光器、光放大器等,这些设备一般使用到的都是低速的串口通信,所以我们需要设计一个上下位机串口通信系统来控制这些设备。这篇文章先讲如何使用Arduino Mega2560开发板来作为下位机控制各个外部设备。

上下位机工作原理

  • 通常来说,上位机指的是PC端的控制软件,比如可以设置读取参数的界面软件,下位机则是指单片机或者带微处理器的系统,这里我们使用Mega2560来作为下位机控制板。下位机可以把一些模拟信号经过AD采集后转换为数字信号,经过处理后通过串口发送给上位机;同理上位机也可以给下位机发送一些指令或者信息。
  • 我们这里需要通过PC端的界面软件发送命令参数到外部设备上,然后再把外部设备的某些功能参数返回给界面软件。就以前一篇文章Arduino(4)为例说明,我们已经把外部设备光开关相关的功能操作写成了类库,mega2560作为下位机控制板直接去调用这个类库就可以了。

下位机软件执行流程

在编写下位机软件之前,我们可以先自定义一种串口通信的数据帧,来确保上下位机之间的通信不会出现差错。上下位机串口通信下行协议:PC -> Mega2560,共有8字节构成,采用异或校验。帧头可以自定义一字节的数据,例如0xfb;命令字表示自定义一些命令操作,例如我将设置光开关通道号的操作定义为0x10#define OPTICALSWITCH_CHANNEL_SET 0x10;4个字节的数据值区域表示携带本次命令操作设置的参数值;帧尾自定义为数据帧的末尾,例如0xfe;校验码则是对整个数据帧进行左右异或后得到的一个字节的数据。

帧头 校验码 命令 数据值 数据值 帧尾
1 byte 1 byte 1 byte 2 byte 2byte 1 byte

接下来就是在Arduino IDE编写数据帧的处理流程,代码如下所示:

#include <OpticalSwitch.h>
#define FRAME 8 // frame length for host command
/*********** Module Command Keyword *************/
#define OPTICALSWITCH_CHANNEL_SET 0x10
#define OPTICALSWITCH_CHANNEL_READ 0x11/*********** Module Name Code *********************/
#define OpticalSwitch 0x03// global varibles for com
const int baud1 = 9600;        // inital baud rate for com with host
byte rxData[FRAME];     // bytes for received frames
int comError = 0;       // error count for communications
bool newCMD = false;    // flag for incoming new command
bool response = false;  // flag for outgoing data
int inbyte;             // use it to clear other data in serial buffervoid setup()
{// put your setup code here, to run once:Serial.begin(baud1);       //connect with host softwaredelay(10);modComSetup();  // setup and check communications to modules sequentially
}void loop()
{// put your main code here, to run repeatedly:delay(300);int rxLength = Serial.available();  //判断接收数据的长度if(rxLength > 0){if (rxLength == FRAME)    //接收数据的长度等于预设值才为指定命令帧,并将其接收下来;否则清除串口缓冲区{// get CMD in rxDataSerial.readBytes(rxData, FRAME); //接收数据,存进指定数组newCMD = true;}else{// clear incoming bufferclearBUF();// setup a error flag to notify host to resend commandcomError++;}}//当有新的命令帧下发时if(newCMD){newCMD = false;//校验码通过后才由Arduino继续下发命令给外部设备if (!checkCMD(rxData))  {comError = 0;//执行命令帧parseCMD(rxData);}else{comError++;}}clearBUF();//有错则重发命令if(comError) resendCMD();routine();
}//在此函数内循环读取外部设备的参数
void routine()
{}void modComSetup()
{// setup com ports and registers of modules one by oneif(OpticalSwitch_Setup()!=true)  return;
}void resendCMD()
{// in case COM error, ask host to resend the last commandresponse = true;comError = 0;// prepare data to be send to host
}void SendDataToHost(unsigned char ModuleCode)
{// frame data to fill up txData and send it to host    switch(ModuleCode){case OpticalSwitch:{Serial.write('D');Serial.write(OpticalSwitch);Serial.write(channel);break;   } default:break;}
}void clearBUF()
{delay(50);int rxLength = Serial.available();// clear incoming bufferfor (int i = 0; i < rxLength; i++){inbyte = Serial.read();}
}bool checkCMD(unsigned char *rxData)
{if(rxData[0]==0xfb && rxData[FRAME-1]==0xfe ){if(rxData[1] == calcBIP8(rxData)){return 0;}else{return 1;}}else{return 1;}// calculate to check the correctness of the received command// correct--> return 0;// uncorrect--> return 1;
}void parseCMD(unsigned char *rxData)
{// parse received command and setup flags accordingly for further processingswitch(rxData[2]){case OPTICALSWITCH_CHANNEL_SET:{OpticalSwitchChannel(rxData[4]);break;}case OPTICALSWITCH_CHANNEL_READ:{SendDataToHost(OpticalSwitch)break;}default:break;}
}//异或校验,用于校验下发命令的数据帧是否完整
unsigned char calcBIP8(unsigned char* data)
{unsigned char bip16 = data[0]^(data[1]&0x00)^data[2]^data[3]^data[4]^data[5]^data[6]^data[7];unsigned char bip8 = ((bip16&0xf0)>>4)^(bip16&0x0f);return bip8;
}
  • 首先引用我们之前写好的类库#include <OpticalSwitch.h>;然后void setup()函数内初始化Arduino mega2560和PC电脑相连的串口(该串口由mega2560上自带串口转USB线和电脑上USB口连接),然后对外部设备进行初始化,这部分程序已经写在了光开关的类库里了。void loop()函数内则是数据帧的整个处理流程
  • 从上位机下发的数据命令帧被与PC相连的串口(也就是Serial)接收后,首先判断其数据长度是否等于预设值,不然就是传输过程出错了,数据包出现了丢失;接着将接收到的数据存储到rxData数组内,由异或校验函数calcBIP8()来检测数据帧的正确性;然后执行派发函数parseCMD(),这个函数根据数据帧内的命令字来执行相应的命令,调用相应模块的指定函数;如果这个过程出错了就重发命令,执行resendCMD()函数,并且清空串口缓冲区,等待下一次数据命令帧;routine()内则循环读取外部设备的参数,存进相应的数组,等待上位机读取。整个执行过程放在了loop()函数内,循环执行,有新的命令帧就执行,没有就等待新的命令到来。
  • 这样整个控制外部设备的下位机软件就已经做好了,上位机发送带有命令字的数据帧到下位机,就可以控制各种外部设备了。

Arduino(5) 使用Mega2560设计上下位机串口通信系统的下位机相关推荐

  1. 上下位机串口通信 python_怎么将图片通过串口发送给下位机?

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 是这样的,本人小白一枚,最近有一个想法,想用python做上位机 C51做下位机做一台激光打印机,两个我都刚学不久,所以都不太了解,图像处理我用了抖动算法 ...

  2. C#工控上位机实例_工控学习,搞工控的到底什么是上位机,什么是下位机?

    上位机 上位机是指可以直接发出操控命令的计算机, 一般是PC/host computer/master computer/upper computer, 屏幕上显示各种信号变化(液压,水位,温度等). ...

  3. 上位机与下位机程序配合是 下位机程序崩溃

    最近作为一个菜鸟,一直测试同事用QT写好的上位机与下位机程序, 结果配置一个模块,连续点击多次下载时,下位机出现程序崩溃的情况.如图 根据提示得知 在下位机线程没有结束的时候,我通过上位机就把内容情况 ...

  4. 上位机发送与接收下位机数据

    用自带的SeriPort控件或者可以用seriport类,根据上位机与下位机同行寻得协议发送接收数据. 设置buttion控件,点击buttion 发送相应数据: private void send_ ...

  5. python编程与下位机通讯_ros 与下位机通信

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  6. python笔迹识别_关于机器视觉笔迹识别和Arduino控制机器人的设计

    0 引言 伴随着现在日益高性能的计算机硬件和完善的理论技术,机器视觉技术已开始得到广泛的应用.结合机器视觉技术的智能机器人在现今人工智能趋势下扮演一个重要角色,在智能制造推进.智慧城市建设.家居生活质 ...

  7. java实现上位机与下位机串口通信

    串口通信是在工程应用中很常见.在上位机与下位机通讯过程中常通过有线的串口进行通信,在低速传输模式下串口通信得到广泛使用.在说个之前先来简单解释一下上位机与下位机的概念. 上位机与下位机 通常上位机指的 ...

  8. C#上位机 串口上位机Modbus协议

    文章目录 前言 一.准备工作 二.界面设计 1.LED灯 2.图表 三.程序设计 1.串口配置 2.发送报文 3.CRC校验 4.读写寄存器函数 5.LED状态切换 6.串口接收事件 7.设置电压 8 ...

  9. 用python做一个上位机串口通信_【教程】简易Python上位机之LED控制

    电子爱好者应该不会对"上位机"这个词感到陌生,毕竟或多或少有过接触.但若是说到上位机的开发的话,大家就不一定熟悉了.很多电子爱好者完全没有接触过上位机的开发工作,他们真的没有相应的 ...

最新文章

  1. 《疯狂Java讲义》学习笔记(十)异常处理
  2. 用html做一个发送邮件验证,邮件发送还有问题吗?送大家一个写好的类吧,支持stmp认证、HTML格式邮件-PHP教程,PHP应用...
  3. Boost:计算一些tail统计数据,插入数据,更新数据
  4. list array解析(总算清楚一点了)
  5. 【渝粤教育】电大中专幼儿园课程论 (7)作业 题库
  6. 【数据结构基础笔记】【链表】
  7. 如何在A用户下建立视图,这个视图是A的表与B的表进行关联的?
  8. 声明变量baijq的HTML5同时
  9. div中定义局部变量_中高级前端必须要了解的--JS中的内存管理
  10. 卓有成效的管理者(笔记)——掌握自己的时间
  11. 湖南生物机电职院信息技术学院召开第一届思政工作会议
  12. 房地产投资占GDP比例畸高 中国房地产泡沫是一颗毒瘤
  13. c语言定义禁止优化变量,c语言防止优化
  14. OBS更改标题?标题一改,安能辨我是雌雄?
  15. Ubuntu的Spark 搭建实验(ssh配置没好,需要的看新发的,完整版)
  16. 服务器显示不兼容这是什么问题,服务器server0处于不兼容的状态,怎么办?
  17. Android APP签名和签名等信息查看
  18. 计算机专业top500,超级计算机TOP500最新名单公布
  19. Cg教程_可编程实时图形权威指南(扫描清晰版)+部分unity shader 知识
  20. (二)DSP28335基础教程——GPIO输入(矩阵按键扫描)

热门文章

  1. Substance Designer 井盖
  2. 3.6 使用透视裁剪工具修复透视图 [Ps教程]
  3. eclipse下maven调试的技巧(Re-run Maven using the -X switch to enable full debug logging.)
  4. 烧写工具DNW的使用
  5. 苹果自带输入法怎么换行_微信个性签名怎么弄成竖的?不仅可以竖着还可以加边框效果...
  6. layui登陆验证页面模板(滑块学习)
  7. 真实的上海IT圈:张江男vs漕河泾男
  8. 【java.lang.ref】当WeakReference的referent重写了finalize方法时会发生什么
  9. 通过百世单号自动识别快递公司,并查询大量物流情况
  10. 科技交流英语(2022秋)Unit 5 test