求解关于arduino的485通讯问题-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 21843|回复: 18

[已解决] 求解关于arduino的485通讯问题

[复制链接]
发表于 2018-8-1 20:15 | 显示全部楼层 |阅读模式
41金币
本帖最后由 暗杀星 于 2018-8-4 15:20 编辑

我现在有一个ttl转485芯片,一个uno和一个用485通讯的蠕动泵,我想用uno来控制蠕动泵,来读取转速(03),控制转速等(06)!哪位大佬知道怎么编程么,我在网上搜了一些程序,调试都失败了。蠕动泵通讯协议见附件!,我自己的03读取功能程序如下,但是没实现读取。求大神拯救
#include <ModbusMaster.h>//modbusmaster库,03读取功能

uint16_t m_startAddress = 2;//要读取的从站起始地址
uint8_t m_length = 2;//从从站起始地址开始你需要读取的数据的长度
uint8_t result;//串口通信结果,不用明白是什么,只要知道这不是你最终需要的数据就行

ModbusMaster node(1);//对1号从站进行通信
int LED = 8;
void setup() {
  node.begin(9600);//定义arduino与从站之间的串口波特率
  pinMode(LED,OUTPUT);
//Serial.begin(9600); //端口的波特率设置
Serial.begin(9600, SERIAL_8N2);        //数据位8,无校验位,停止位2

}

void loop() {  
  result = node.readHoldingRegisters(m_startAddress, m_length);//调用相关函数
  if (result == node.ku8MBSuccess) {//如果通信成功
    digitalWrite(LED,HIGH);
    delay(500);
    digitalWrite(LED,LOW);
    delay(500);

  }
  else {
    digitalWrite(LED,HIGH);
  }
}

调速系列蠕动泵产品通讯协议.pdf

154.64 KB, 下载次数: 67

发表于 2018-8-2 09:04 | 显示全部楼层
首先 我看到这样的代码 第一反应就是  为什么没有调试信息  你想要知道为什么不行 那么就老老实实加调试信息  看看代码运行到哪里出错了 大神
 楼主| 发表于 2018-8-2 09:25 | 显示全部楼层
单片机菜鸟 发表于 2018-8-2 09:04
首先 我看到这样的代码 第一反应就是  为什么没有调试信息  你想要知道为什么不行 那么就老老实实加调试信 ...

代码拷到arduino运行后,读不到转速,串口接收区显示01 03 00 02 00 02 65 CB   正确的话第二个0002显示的是转速,但是我改变转速,他不变,断开与步进电机连线,他依然还是那样,显然就没有通信啊。而且我最想实现的是06写入功能,就是可以调转速。但是我不会写代码,所以来求助。
发表于 2018-8-2 10:26 | 显示全部楼层
本帖最后由 跑龙套的保 于 2018-8-2 15:01 编辑

就那么难么,问了那么久了,用了TTL转485,你就别把它当做485通讯的了,arduino 里的程序就是读写串口,直接帮你写好吧
[mw_shl_code=cpp,true]#include <SoftwareSerial.h>
const byte rxPin = 2;
const byte txPin = 3;

//ttl转485接软串
SoftwareSerial TTL2485(rxPin, txPin);

// #define TTL2485 Serial

#define MAX_PACKETSIZE 128 //自定义的缓冲buff长度

uint8_t softUart_Receive_Buff [ MAX_PACKETSIZE ]; //定义缓冲buff

unsigned int softUart_Receive_Index = 0; //收到的字节实际长度

unsigned long preSoftUartTime = 0; //记录读取最好一个字节的时间点


/*
  计算crc16校验
  modbus
*/
uint16_t calcCRC16 (uint8_t *ptr, size_t size)
{
  unsigned short a, b, tmp, CRC16, V;
  CRC16 = 0xffff;               //CRC寄存器初始值
  for (a = 0; a < size; a++)      //N个字节
  {
    CRC16 = *ptr ^ CRC16;
    for (b = 0; b < 8; b++)      //8位数据
    {
      tmp = CRC16 & 0x0001;
      CRC16 = CRC16 >> 1;     //右移一位
      if (tmp)
        CRC16 = CRC16 ^ 0xa001;  //异或多项式
    }
    *ptr++;
  }
  //大小端转换
  V = ((CRC16 & 0x00FF) << 8) | ((CRC16 & 0xFF00) >> 8); //高低字节转换
  return V;
}

/*
  校验crc16
  modbus
*/
bool checkCRC16(uint8_t *p, size_t len)
{
  if (p[len - 2] * 256 + p[len - 1] == calcCRC16(p, len - 2))
    return true;
  else
    return false;
}

/*
  16进制转字符串
*/
void printHex(uint8_t *p, uint16_t len)
{
  char *pbuff = (char*)malloc(len * 3 + 1);
  if (pbuff == NULL ) return;
  pbuff[0] = 0x00;
  char t[5];
  for (int i = 0; i < len; i++)
  {
    sprintf(t, "%02X ", p);
    strcat(pbuff, t);
  }

  Serial.println("[printHex]");
  Serial.println(pbuff);

  free(pbuff);
}

/*
  处理串口数据函数,可以在函数内编写处理函数数据的程序
*/
void parseSoftUartPackage(uint8_t *p , int len) {
  //打印日志到串口
  Serial.print(F("[SoftUart Read]:"));
  printHex(p, len);

  if (len != 8) {
    Serial.println(F("[ERROR]:len != 8"));
    return;
  }

  if (!checkCRC16(p, len)) {
    Serial.println(F("[ERROR]:check CRC16 error"));
    return;
  }

  if(p[1] == 0x03){
      Serial.println(F("cmd 03 responded successfully"));

      //发送启动指令
      uint8_t cmd06[8] = {0x01,0x06,0x00,0x00,0x00,0x01,0x48,0x0a};
      send2SoftUart(cmd06,8);
  }

  else if(p[1] == 0x06){
      Serial.println(F("cmd 06 responded successfully"));

  }

}

//发送数据到串口
void send2SoftUart(uint8_t *p, size_t len)
{
  Serial.print(F("[send to SoftUart ]:"));
  printHex(p, len);
  TTL2485.write(p,len);
}


/*
  软串串口数据接受进程
*/
void doSotfUartTick()
{
  if (TTL2485.available())
  { //读取串口数据
    //每次读取一个字节的数据存储在这个buff中
    softUart_Receive_Buff [ softUart_Receive_Index ++ ] = TTL2485.read();
    //记录下读取这个数据的时间点
    preSoftUartTime = millis();

    //判断读取到的数据长度是否超过设定的记录长度,超过长度时间点往前200ms 立即执行分析函数
    if (softUart_Receive_Index >= MAX_PACKETSIZE - 1) {
      softUart_Receive_Index = MAX_PACKETSIZE - 2;
      preSoftUartTime = preSoftUartTime - 200;
    }
  }
  //判断收到的最后一个字节后超过100ms开始执行分析函数
  if (softUart_Receive_Index > 0 && (millis() - preSoftUartTime >= 100))
  { //处理串口数据
    //把buff最后一个字节设为0,在字符串处理中很有用
    softUart_Receive_Buff [ softUart_Receive_Index ] = 0x00;
    TTL2485.flush();

    //执行串口数据处理函数
    parseSoftUartPackage(softUart_Receive_Buff, softUart_Receive_Index);
    softUart_Receive_Index = 0;
  }
}

void setup() {
  TTL2485.begin(9600);
  Serial.begin(9600);

  //发送查询指令
  uint8_t cmd03[8] = {0x01,0x03,0x00,0x02,0x00,0x01,0x25,0xca};
  send2SoftUart(cmd03,8);
}

void loop()
{
  //调用串口数据处理进程
  doSotfUartTick();
}[/mw_shl_code]
 楼主| 发表于 2018-8-2 14:20 | 显示全部楼层
跑龙套的保 发表于 2018-8-2 10:26
就那么难么,问了那么久了,用了TTL转485,你就别把它当做485通讯的了,arduino 里的程序就是读写串口,直 ...

非常感谢!现在可以写入了,可以调速了。但是读取转速还有点问题,串口监视器是这样显示的:
[send to SoftUart ]:[printHex]
01 03 00 02 00 01 25 FFCA
 楼主| 发表于 2018-8-2 14:46 | 显示全部楼层
暗杀星 发表于 2018-8-2 14:20
非常感谢!现在可以写入了,可以调速了。但是读取转速还有点问题,串口监视器是这样显示的:
[send to So ...

为什么写入速度指令只能是:char cmd06[8] = {0x01,0x06,0x00,0x02,0x01,0x2c,0x28,0x47};
  send2SoftUart(cmd06,8);
我把它改为char cmd06[8] = {0x01,0x06,0x00,0x02,0x00,0x11,0xe8,0x06};
  send2SoftUart(cmd06,8);换个速度就不行了呢?
还有我输入停止指令char cmd06[8] = {0x01,0x06,0x00,0x00,0x00,0x00,0x89,0xca};
  send2SoftUart(cmd06,8);它并没有停止啊。
大佬再来给我解答一下,非常感谢!!
发表于 2018-8-2 15:00 | 显示全部楼层
暗杀星 发表于 2018-8-2 14:20
非常感谢!现在可以写入了,可以调速了。但是读取转速还有点问题,串口监视器是这样显示的:
[send to So ...

这条回应什么,打印多了个ff是printhex这个函数出的问题,不影响,发到485的没变,改下无符号类型就行了,我更新了下上文的代码
 楼主| 发表于 2018-8-2 15:39 | 显示全部楼层
跑龙套的保 发表于 2018-8-2 15:00
这条回应什么,打印多了个ff是printhex这个函数出的问题,不影响,发到485的没变,改下无符号类型就行了 ...

大神完美的解决了我的问题,我还有一个小小的请求,能不能帮我在这个程序基础上修改一下,比如我输入“a”对应一个速度,输入b对应一个速度....输入1停止,输入2启动,输入A正转,输入B反转。万分感谢!
发表于 2018-8-2 16:23 | 显示全部楼层
暗杀星 发表于 2018-8-2 15:39
大神完美的解决了我的问题,我还有一个小小的请求,能不能帮我在这个程序基础上修改一下,比如我输入“a ...

根据现有的代码,复制修改添加一套读取硬件串口的就可以了
 楼主| 发表于 2018-8-2 16:25 | 显示全部楼层
跑龙套的保 发表于 2018-8-2 16:23
根据现有的代码,复制修改添加一套读取硬件串口的就可以了

您就好人做到底,帮帮我吧,我不会编程,正在学。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-29 04:32 , Processed in 0.096077 second(s), 16 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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