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=============

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

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

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

时间: 2024-07-29 17:49:36

ardunio 实现RS485通讯-下位机的相关文章

上位机 下位机

上位机是指:人可以直接发出操控命令的计算机,一般是PC,屏幕上显示各种信号变化(液压,水位,温度等).下位机是直接控制设备获取设备状况的的计算机,一般是PLC/单片机之类的.上位机发出的命令首先给下位机,下位机再根据此命令解释成相应时序信号直接控制相应设备.下位机不时读取设备状态数据(一般模拟量),转化成数字信号反馈给上位机.简言之如此,真实情况千差万别不离其宗.上下位机都需要编程,都有专门的开发系统. 在概念上 控制者和提供服务者是上位机 被控制者和被服务者是下位机 也可以理解为主机和从机的关

4.PMAC下位机-工具安装和使用

PMAC应该看成一台独立的电脑,它有自己的实时操作系统,为了更方便简单的使用,PMAC有自己的一套操作语言来对PMAC的输入输出信号进行控制(IO.电机等信号).和大多数的嵌入式开发一样,PMAC提供一套PC工具来方便查看PMAC控制卡的各种状态变量和编写.调试PMAC程序. 本文介绍PMAC配套工具PEWin32(这里推荐使用PEWin32 PRO,不推荐使用PEWin32 PRO 2,这个新版本有很多bug且不稳定),下一节介绍下位机相关知识,再下一节讲PMAC的下位机编程,这些都是在pew

ROS主题发布订阅控制真实的机器人下位机

先模拟控制小乌龟 新建cmd_node.ccpp文件: #include"ros/ros.h" #include"geometry_msgs/Twist.h" //包含geometry_msgs::Twist消息头文件 #include <stdlib.h> #include<stdlib.h> int main(int argc, char **argv) { ros::init(argc, argv, "cmd_node&quo

下位机单片机c语言发送数据到串口,上位机pc机java语言获取端口数据

环境: Windows7 64b,jdk64b,myeclipse8.5,rxtx开发包,STC,keil,格西烽火,51单片机,rs232USB转串口线. 下位机c代码 #include <reg51.h> #include <string.h> #define INBUF_LEN 7   //数据长度 unsigned char inbuf1[INBUF_LEN]; unsigned char checksum,count3,count=0; bit           rea

MSP430G2333下位机乘法运算需要注意的一个问题

背景: 最近负责为主板管理电源的电源管理模块编写软体,使用的MCU为MSP430G2333.功能上很简单,即通过板子上的硬件拨码设定,或者通过IIC与主板通信,由主板的BIOS决定开机及关机的延时供电时间. 正文: 所有功能均按预期实现,但有一个bug在最后蹦了出来,即在延时关机设定时,明明设定为15.18.48个小时,却每次在9个多小时的时候,电源被执行关闭动作.9个多小时,很有意思的数字.不用深究,问题直接锁定在时间比对函数内. 1 // when the current time less

6.PMAC下位机-下位机编程

PMAC的下位机编程包括三种程序:命令序列程序.运动(Program)程序和PLC程序. PMAC中编写程序,直接在File->new新建文件会打开编辑器,所有文件为PMC后缀. 查看当前程序可以在File->Uplaod Programs查看当前已有的Program程序和PLC程序及他们的编号.状态. 1.命令序列程序 上节讲到,PMAC卡中可以使用手动操作,在命令行设置参数状态.控制电机等,但是它一次只能发送一条命令,那么为了一次性运行多个命令序列,即可在PMC程序中如下编写: i620=

串口操作包括 java上位机 嵌入式c下位机

一环境 1.1 Keil uVision4 http://pan.baidu.com/s/1o6A331w 1.2 STC http://pan.baidu.com/s/1jGpCUTC 1.3 Myeclipse 8.5 http://pan.baidu.com/s/1jGABEaM 1.4 需导入的jar包RXTX http://pan.baidu.com/s/1ntwsvRr 首先把rxtxParallel.dll和rxtxSerial.dll复制到jdk目录的bin目录下面 然后把RXT

局域网控制系统-下位机-单片机

1 /*----------------------------------- 2 多功能下位机 3 STC89C52RC 11.0592MHz 4 5 -----------------------------------*/ 6 #include<reg52.h> 7 #include<intrins.h> 8 9 char code huanhang[3]={0x0d,0x0a,0}; // "\r\n" 10 //-----------------普通输

5.PMAC下位机-下位机编程简介

PMAC的下位机编程涉及三方面的内容:手动操作.运动(Program)程序和PLC程序.这里主要是介绍各个方面的基础编程方面的东西,还有许多需要自行去探索. 变量 PMAC的下位机实际上是一种类Basic的编程语言,但是又类似汇编语言,所有变量的存储空间都是预先分配好的,操作的时候存储数据只能在指定的几种变量类型和变量名中存储,整个系统的参数也是存储在变量中. 变量类型和作用如下: I变量:卡,电机和编码器等的参数变量,用于设置电机的速度,精度,回零等数值,以及坐标系的状态,编码器的反馈形式,P