ardunio 实现RS485通讯-下位机

#include <SoftwareSerial.h>
SoftwareSerial mySerial(4,5);    
byte ZERO=0x00;
byte Addr=0x03;
byte Status=0x00;
int buffLen=32;
char HexTable[] = "0123456789ABCDEF";
int pinTrigger=7;
int pinDirection=8;
void setup() {
  // put your setup code here, to run once:
  pinMode(pinDirection,OUTPUT);
  digitalWrite(pinDirection,LOW);
  pinMode(pinTrigger,OUTPUT);
  Off();
  
  mySerial.begin(9600);
  Serial.begin(9600);
  Serial.println("ok");
}


void On(){
  digitalWrite(pinTrigger,HIGH);
  Status=0x01;
}
void Off(){
   digitalWrite(pinTrigger,LOW);
  Status=0x00;
}

void loop() {

  byte crc[2];
  int count=0;
  byte rBytes[buffLen];
   while(mySerial.available()>0){
      byte b=mySerial.read();
      if(count<buffLen){
        rBytes[count]=b;
      }
      count++;
      delayMicroseconds(100);
   }
   if(count>0){
     String v= toHex(rBytes,count > buffLen? buffLen : count);
     Serial.println("r:" + v);
   }
   
   if(count<4)return;
   if(rBytes[0] !=Addr)return;
   if(count>buffLen)return;
   //Send To Me
 
     
     //check crc
     calculateCRC(rBytes,count-2,crc);
     if(crc[0]!=rBytes[count-2] || crc[1] !=rBytes[count-1]){
        Serial.println("crc error!"); 
        return;
     }
     
     digitalWrite(pinDirection,HIGH);
     byte resp[32];
     byte respLen=0;
     //Read status
     if(rBytes[1]==0x03){
             resp[0]=Addr;
             resp[1]=0x03;
             resp[2]=Status;
             respLen=3;
     }else if(rBytes[1]==0x06){ //Write Status
       //power on : 03 06 01
       //power off: 03 06 00
       if(rBytes[2]==0x01){
         On();
       }else{
         Off(); 
       }
       resp[0]=Addr;
       resp[1]=0x06;
       resp[2]=Status;
       respLen=3;
     }else{
       resp[0]=Addr;
       resp[1]=0x83;
       respLen=2;
     }
     
     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 = 0; i < arraySize; i++)
  {
    temp = temp ^ *(_regs+i);
    for (unsigned char j = 1; j <= 8; j++)
    {
      flag = temp & 0x0001;
      temp >>= 1;
      if (flag)
        temp ^= 0xA001;
    }
  }
  temp2 = temp >> 8;
  
//  Serial.print("b:");
//  Serial.println(temp,HEX);
//  Serial.println((byte)(temp & 0x00FF),HEX);
//  Serial.println( (byte)(temp >> 8)  ,HEX);
  
  temp = (temp << 8) | temp2;
  temp &= 0xFFFF; 
  
  crc[0]=(byte)(temp >> 8) ;
  crc[1]=(byte)(temp & 0x00FF);
  
  
  return temp;
}
void sendData(byte data[],int count)
{
   byte crc[2];
   calculateCRC(data,count,crc);
   for(int i=0;i<count;i++){
     mySerial.write(data[i]);
   } 
   mySerial.write(crc[0]);
   mySerial.write(crc[1]);
}
//=================================================
//==============byte to hex string===============
 String toHex(byte bs[],int count){
  String bundle="";
   for(int i=0;i<count;i++){
     bundle += (String)( HexTable[ bs[i] / 16]) + (String)( HexTable[bs[i] % 16]);
     
   }
   return bundle;
}
//==============End byte to hex string=============
View Code

中间2脚短后连到单片机数字口上,低电位收,高电位发数据

注意左边4脚 是指MUC的,所以串口收发线不需要互换,直接按标识连好。

服务端代码参考:华为网盘中的ZNJM2-20150612.rar

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
通常,在工业中,我们有几种机器和设备(PLC,CNC,变频器)来控制和监视最多样化的工业过程。 为了使所有这些设备一起工作,必须在它们之间建立通信网络。 但是,由于电动机,螺线管和其他执行器的激活,该行业环境中存在许多电磁干扰。 RS485通信标准是通信网络的物理层,可以实现多种协议,例如Modbus,Profibus等。 RS485通信标准适合在行业中实施,因为它接受几种网络拓扑,例如星形和环形。 它允许长距离通信,并使用双绞线电缆。由于我们具有差分通信信号,因此该电缆模型减少了电磁干扰,这有助于更好地抵抗噪声和电磁干扰。 除了RS485通讯之外,还有RS232通讯。它允许以点对点模式进行网络通信,并且遭受电磁干扰的影响更大。 但是,许多设备具有RS232通信,需要长距离传输数据。为此,我们需要使用称为MAX485的集成电路。 该集成电路在使TTL逻辑电平适应RS485通信所需的逻辑电平中发挥作用。 如今,已经有使用该集成电路的现成的低成本模块。它们允许信号调理并促进不同设备之间的通信。 因此,由于其坚固性,RS485通信可用于任何类型的环境。 因此,在本文中,我们将学习如何监视环境温度以及如何通过两个Arduino之间的串行/ RS485通信接收测量值。 Arduino Slave(发送器)将使用DS18B20数字传感器执行温度测量,并将测量值通过串行/ RS485发送到Arduino主设备(接收器),该设备将在LCD显示屏上写入20 x 4 I2C接收的温度值。 因此,通过本文您将学到: 在原型板上执行电路组装; 了解RS 485模块的操作; 了解DS18B20传感器的工作原理; 创建通信协议; 使用有线通信网络进行远程温度监控; 现在,我们将开始通过RS485串行通信使用DS18B20传感器进行温度监控项目的开发的完整介绍。 通过RS485串行通信使用DS18B20传感器开发温度监控项目 在图3中,我们具有项目组装所需的原理图电路。Arduino Uno将成为主机(接收器),它将接收温度测量值并将在LCD显示屏上显示20 x 4 I2C。 Arduino Nano将作为从设备(发送器),它将读取DS18B20传感器并通过RS485模块发送测量值。 现在,让我们转到设置项目所需的材料清单。 带有DS18B20和RS485模块的Arduino项目 温度传感器DS18B20是数字温度传感器,因为要传输信息,它使用协议1-Wire。 1-Wire协议由Dallas Semiconductor和Maxim制造。 1线总线对设备使用主/从概念。 微控制器是主机,外围设备是从机。 在制造过程中,每个设备都会收到一个唯一的ID,即设备标识号(地址),以便在有很多设备时可以在总线上对其进行标识。 信息格式: 1线仅使用一条数据线,并使用长脉冲和短脉冲表示1和0。60微秒脉冲表示0,15微秒脉冲表示1。 在VCC与DS18B20传感器的信号引脚之间必须使用4K7的上拉电阻,以使微控制器与传感器之间的通信稳定。 将发射器和接收器电路组装到原型板上之后,我们可以在图6中看到原型板上的物理组装。
一、概述 本Xtra实现基本的串口通信功能,能够在Director应用与下位机之间实现10进制数值的收发。 二、方法说明 1、new 用途: 创建xCom Xtra实例 参数:无 返回值: xCom Xtra实例 示例: xCom = new xtra("xCom") 说明: 建立xCom Xtra实例时,并没有约定通信协议,所以,强烈建议随后执行初始化,以避免通信失败。 2、init 用途: 初始化串口通讯配置 参数: object me xCom Xtra实例 integer portNum 端口号 整数 根据机器的串口状态设 integer BaudRate 波特率 整数 只能为4800/9600/19200之一,否则默认为9600 返回值: integer failNum 返回值为0,表示初始化成功,否则为失败 示例: xCom.init(1, 9600) 说明: a、在通常的串口通信中,还有数据位、停止位、奇偶校验位、电平控制等设置,为了简化应用,本Xtra默认设置为8位数据位,1位停止位,无奇偶校验,电平控制为默认。 b、考虑到应用标准化问题,本Xtra只支持3种固定波特率(4800/9600/1920) 3、close 用途: 关闭串口,释放资源 参数: object me xCom Xtra实例 返回值: integer failNum 返回值为0,表示成功关闭串口、释放资源,否则为失败 示例: xCom.close() 4、read object me --> list received 用途: 读取数据 参数: object me xCom Xtra实例 返回值: list received 列表中每个元素均为10进制整数,具体含义由通讯双方约定 示例: xCom.read() 5、write object me, list aList --> integer failNum 用途: 写入数据 参数: object me xCom Xtra实例 list received 列表中每个元素均为10进制整数,具体含义由通讯双方约定 返回值: integer failNum 返回值为0,表示数据写入成功,否则为失败 示例: myData = “MyData” aList = [] repeat with i = 1 to myData.length aChar = myData.char[i..i] aList.add(charToNum(aChar)) end repeat xCom.write(aList)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值