ardunio 实现RS485通讯-下位机
#include <SoftwareSerial.h>
SoftwareSerial mySerial(,);
byte ZERO=0x00;
byte Addr=0x03;
byte Status=0x00;
int buffLen=;
char HexTable[] = "0123456789ABCDEF";
int pinTrigger=;
int pinDirection=;
void setup() {
// put your setup code here, to run once:
pinMode(pinDirection,OUTPUT);
digitalWrite(pinDirection,LOW);
pinMode(pinTrigger,OUTPUT);
Off(); mySerial.begin();
Serial.begin();
Serial.println("ok");
} void On(){
digitalWrite(pinTrigger,HIGH);
Status=0x01;
}
void Off(){
digitalWrite(pinTrigger,LOW);
Status=0x00;
} void loop() { byte crc[];
int count=;
byte rBytes[buffLen];
while(mySerial.available()>){
byte b=mySerial.read();
if(count<buffLen){
rBytes[count]=b;
}
count++;
delayMicroseconds();
}
if(count>){
String v= toHex(rBytes,count > buffLen? buffLen : count);
Serial.println("r:" + v);
} if(count<)return;
if(rBytes[] !=Addr)return;
if(count>buffLen)return;
//Send To Me //check crc
calculateCRC(rBytes,count-,crc);
if(crc[]!=rBytes[count-] || crc[] !=rBytes[count-]){
Serial.println("crc error!");
return;
} digitalWrite(pinDirection,HIGH);
byte resp[];
byte respLen=;
//Read status
if(rBytes[]==0x03){
resp[]=Addr;
resp[]=0x03;
resp[]=Status;
respLen=;
}else if(rBytes[]==0x06){ //Write Status
//power on : 03 06 01
//power off: 03 06 00
if(rBytes[]==0x01){
On();
}else{
Off();
}
resp[]=Addr;
resp[]=0x06;
resp[]=Status;
respLen=;
}else{
resp[]=Addr;
resp[]=0x83;
respLen=;
} sendData(resp,respLen);
digitalWrite(pinDirection,LOW); } //================CRC 16==========================
//CRC校验函数
//参数1:待校验数组的起始地址
//参数2:待校验数组的长度
//返回值CRC校验结果,16位,低字节在前
unsigned int calculateCRC(unsigned char* _regs,unsigned char arraySize,byte* crc)
{
unsigned int temp, temp2, flag;
temp = 0xFFFF;
for (unsigned char i = ; i < arraySize; i++)
{
temp = temp ^ *(_regs+i);
for (unsigned char j = ; j <= ; j++)
{
flag = temp & 0x0001;
temp >>= ;
if (flag)
temp ^= 0xA001;
}
}
temp2 = temp >> ; // Serial.print("b:");
// Serial.println(temp,HEX);
// Serial.println((byte)(temp & 0x00FF),HEX);
// Serial.println( (byte)(temp >> 8) ,HEX); temp = (temp << ) | temp2;
temp &= 0xFFFF; crc[]=(byte)(temp >> ) ;
crc[]=(byte)(temp & 0x00FF); return temp;
}
void sendData(byte data[],int count)
{
byte crc[];
calculateCRC(data,count,crc);
for(int i=;i<count;i++){
mySerial.write(data[i]);
}
mySerial.write(crc[]);
mySerial.write(crc[]);
}
//=================================================
//==============byte to hex string===============
String toHex(byte bs[],int count){
String bundle="";
for(int i=;i<count;i++){
bundle += (String)( HexTable[ bs[i] / ]) + (String)( HexTable[bs[i] % ]); }
return bundle;
}
//==============End byte to hex string=============
中间2脚短后连到单片机数字口上,低电位收,高电位发数据
注意左边4脚 是指MUC的,所以串口收发线不需要互换,直接按标识连好。
服务端代码参考:华为网盘中的ZNJM2-20150612.rar
ardunio 实现RS485通讯-下位机的更多相关文章
- C# WPF上位机实现和下位机TCP通讯
下位机使用北京大华程控电源DH1766-1,上位机使用WPF.实现了电压电流实时采集,曲线显示.上午在公司调试成功,手头没有程控电源,使用TCP服务端模拟.昨天写的TCP服务端正好排上用场. 界面如下 ...
- STM32菜鸟成长记录---RS485通讯协议的应用
写作原因:近来蛋闲?非也 ! 昨天一同事合作的项目代码出现的bug-----他的上位机每200ms给我发送命令向我这边下位机读取一些数据,在此过程会按下按键做一些另外操作并给他返回数据:(通信是通 ...
- vb配置下位机CAN寄存器小结
2011-12-14 18:44:32 效果图 1,完成设计(由于没有eeprom等存储设备,所以每次上电后需要通过串口配置某些寄存器).在设计中,列出技术评估难度,并进行尝试,参看<我的设计& ...
- "废物利用"也抄袭——“完全”DIY"绘图仪"<二、下位机程序设计>
就不说怎么组装了吧,一把辛酸泪.说程序,因为这有两把辛酸泪……一把给下位机的C代码一把为了VB.NET的图像处理……不过就上上一篇说的,它们可以正确运行了,并且今天克服了Arduino上电过程中步进电 ...
- C#使用struct直接转换下位机数据
编写上位机与下位机通信的时候,涉及到协议的转换,比较多会使用到二进制.传统的方法,是将数据整体获取到byte数组中,然后逐字节对数据进行解析.这样操作工作量比较大,对于较长数据段更容易计算位置出错. ...
- C#做上位机软件——绘图并传输给下位机
拿到任务之后首先分成了几个部分: 1.绘图.学习了GDI+ 2.图片保存. 3.将图片转换成byte[].由于使用Socket通信,只能传输byte[]数据,所以这一步是向下位机传输的关键. 相应地, ...
- 下位机多个".c, .h"文件的相互包含及排版
一.背景: 自从接触单片机编程以来,由于工作上的需要,不可避免的时常会接手别人的代码,但常常由于上一位同事的编码随意性有点大,导致可读性非常的差,有时候不得不完全舍弃原有代码,推倒重来,无形中增加了工 ...
- MSP430G2333下位机乘法运算需要注意的一个问题
背景: 最近负责为主板管理电源的电源管理模块编写软体,使用的MCU为MSP430G2333.功能上很简单,即通过板子上的硬件拨码设定,或者通过IIC与主板通信,由主板的BIOS决定开机及关机的延时供电 ...
- ROS主题发布订阅控制真实的机器人下位机
先模拟控制小乌龟 新建cmd_node.ccpp文件: #include"ros/ros.h" #include"geometry_msgs/Twist.h" ...
随机推荐
- background-image,background-repeat, background-position 实现点赞图片(一个图片的多次使用)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Spring MVC 确定目标方法POJO 类型参数
1:确定一个Key 2. 在implicitMode 中存在Key 对应的对象, 若存在则作为参数传入 3. 在implicitMode 中不存在Key 对应的对象, 则检查当前@SessionAtr ...
- as3 三行三列 布满9个为一个界面
var n:int=int(iconIndex/3); e.x =(int(n/3)*3+iconIndex%3)*557; e.y = int(iconIndex / 3) % 3 * 260; i ...
- 前端开发-3-HTML-body标签
body标签 h.p.a.ul.ol.div.img. 想要在网页上展示出来的内容一定要放在body标签中. 把我们之前海燕那一段HTML代码贴过来,保存到一个HTML格式的文件中. <!DOC ...
- 转载:mysql binlog同步redis
ref: https://wenku.baidu.com/view/5d9d04ac6394dd88d0d233d4b14e852458fb39c4.html
- oracle惯用缩写的含义
$ORACLE_HOME/bin下的utilities解释Binary First Available Description----------------- ...
- 迷你MVVM框架 avalonjs 学习教程12、数据联动
在许多表单应用,我们经常遇到点击一个复选框(或下拉框)会引发旁边的复选框(或下拉框)发生改变,这种联动效果用avalon来做是非常简单的.在avalon里,存在各种绑定回调与$watch回调,完全满足 ...
- 吴裕雄 实战PYTHON编程(10)
import cv2 cv2.namedWindow("frame")cap = cv2.VideoCapture(0)while(cap.isOpened()): ret, im ...
- tensor flow 的两种padding方式
https://segmentfault.com/a/1190000007846181
- XML与HTML
一.什么是HTML 带着疑问走到这里,一句话:HTML(HyperTextMark-upLanguage)即超文本标记语言,是WWW的描述语言. 如果想了解更多请看以下博客: http://blog. ...