modbus读写器如何读取多个仪表,请各位指点一二

pkou123 2014-07-24 05:49:33
最近在修改一个modbus读写工具遇到一个问题,我要链接2个以上的仪表,并且读取数据,而这个程序本来只能读取一个,怎么修改也没办法读取2个,请教各位
我把2个主要读取的button和定时器放上来,源码在最后面

void CMy12Dlg::OnButton1()
{
// TODO: Add your control notification handler code here
comconut=0;
m_button1.EnableWindow(false);
//显示初始化====================================================
//CGridCtrl grid;
UpdateData();
grid.DeleteAllItems();
grid.SetColumnCount(2);
if(regnum<23)
grid.SetRowCount(23);
else
grid.SetRowCount(regnum+1);
grid.SetItemText(0,0,"寄存器地址");
grid.SetItemText(0,1,"寄存器值");
//for(int i=0;i<2;i++)
//{
grid.SetColumnWidth(0,75);
grid.SetColumnWidth(1,65);
//}
for(int i=0;i<regnum;i++)
{
str1.Format("%d",40000+regbegin+i);
grid.SetItemText(i+1,0,str1);
}
KillTimer(1);
//串口初始-----------------------------------------------
if (comnew()==0)
return;
//===============================================================================
//发送读取仪表系数命令===========================================================
int ADDR[5];
ADDR[0]=m_address;
int len=0;
//CModbus modbus;


len=modbus.PackRead(out_meter,ADDR[0],regbegin-1,regnum);
com_meter.Write(out_meter,len);
comdata(0,len);
//===============================================================================
//启动定时器-----------------------------------------------------------------------
SetTimer(1,timer,NULL);
//UpdateData(false);
}
void CMy12Dlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
int len=0;
int tttt=0,tt=0;
com_meter.Read(input_meter, 300);
//str2=input_meter;
for(int m=0;m<300;m++)
{
if(input_meter[m]!=0)
tt=m;
}
tt=tt+1;
tttt=strlen((const char*)input_meter);
if (tt>tttt)
tttt=tt;
if(tttt==1)
comdata(1,0);
else
comdata(1,tttt);

//CModbus modbus;
// len=modbus.PackRead(out_meter,m_address,regbegin-1,regnum);

int ADDR[5];
ADDR[0]=m_address;
ADDR[1]=m_address2;

len=modbus.PackRead(out_meter,ADDR[0],regbegin-1,regnum);
com_meter.Write(out_meter,len);
comdata(0,len);
if(modbus.UnpackRead(input_meter,value))
{
for(int m=0;m<regnum;m++)
{
str1.Format("%d",value[m]);
// grid.SetItemText(m+1,1,str1);
switch (m+1)
{
case 1:
SetDlgItemText(IDC_EDIT7,str1);
case 2:
SetDlgItemText(IDC_EDIT8,str1);
case 3:
SetDlgItemText(IDC_EDIT9,str1);
case 4:
SetDlgItemText(IDC_EDIT13,str1);
case 6:
SetDlgItemText(IDC_EDIT14,str1);
case 8:
SetDlgItemText(IDC_EDIT15,str1);

break;


}

}
// len=modbus.PackRead(out_meter,m_address,regbegin-1,regnum);
// com_meter.Write(out_meter,len);
// comdata(0,len);
// if(modbus.UnpackReadA(input_meter,value))

}
// grid.Refresh();
//KillTimer(1);
CDialog::OnTimer(nIDEvent);
}

本想着是把程序里面涉及到设备地址的地方copy一份,然后放入另一个设备的地址,但是这样行不通,直接就无法读取了
本来是加入以下代码
len=modbus.PackRead(out_meter,ADDR[1],regbegin-1,regnum); //ADDR[0]是第一个仪表地址,ADDR[1]是第二个仪表地址
com_meter.Write(out_meter,len);
但是无法获取到数据,请各位大神指教一下,
就是在读取一个仪表的基础上修改成读取2个,
以下是部分定义
int CModbus::PackRead(LPBYTE pBuffer, int iAddress, int iBegin, int iCount)
{
pBuffer[0] = iAddress;
pBuffer[1] = 0x03;
pBuffer[2] = HIBYTE(iBegin);
pBuffer[3] = LOBYTE(iBegin);
pBuffer[4] = HIBYTE(iCount);
pBuffer[5] = LOBYTE(iCount);
*(WORD*)(pBuffer + 6) = Check_CRC(pBuffer, 6);
return 8;
}

DWORD CCom::Write(LPVOID lpBuffer, DWORD dwNumberOfBytesToWrite, bool bRTS)
{
if (!IsOpen())
return 0;

if (bRTS)
SetRts(true);

PurgeComm(m_hCom,
PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

DWORD dwNumberOfBytesWrite = 0;
if (!WriteFile(m_hCom, lpBuffer, dwNumberOfBytesToWrite, &dwNumberOfBytesWrite, NULL))
{
DWORD dwErrors;
COMSTAT Stat;
ClearCommError(m_hCom, &dwErrors, &Stat);
dwNumberOfBytesWrite = 0;
}

if (bRTS)
{
Sleep(10);
SetRts(false);
}

return dwNumberOfBytesWrite;
}

bool CModbus::UnpackRead(LPBYTE pBuffer, int *pValue)
{
if (*(WORD*)(pBuffer + pBuffer[2] + 3) != Check_CRC(pBuffer, pBuffer[2] + 3))
return false;
for (int i = 0; i < pBuffer[2] / 2; i++)
pValue[i] = MAKEWORD(pBuffer[4 + i * 2], pBuffer[3 + i * 2]);
return true;
}





源码包在这里面
链接: http://pan.baidu.com/s/1eQJ2z9S 密码: 2wgk
...全文
1014 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
schlafenhamster 2014-07-25
  • 打赏
  • 举报
回复
modbus rtu 协议, 要 注意 发出去的 字节之间的 停顿时间 必须 小与 1.5t(即 第一个 字节 与 弟2.个字节之间上 不能 大于 1.5 个 单字节发送时间)。
pkou123 2014-07-25
  • 打赏
  • 举报
回复
引用 2 楼 schlafenhamster 的回复:
len=modbus.PackRead(out_meter,ADDR[0],regbegin-1,regnum); 没看到 out_meter
unsigned char input_meter[300]; unsigned char out_meter[300]; 这样定义的,具体源码包内有
schlafenhamster 2014-07-25
  • 打赏
  • 举报
回复
len=modbus.PackRead(out_meter,ADDR[0],regbegin-1,regnum); 没看到 out_meter
schlafenhamster 2014-07-25
  • 打赏
  • 举报
回复
网络结构 ? 主机 -> 仪表1 (232)? 主机 -> 仪表 2 (232)?
pkou123 2014-07-25
  • 打赏
  • 举报
回复
引用 4 楼 schlafenhamster 的回复:
modbus rtu 协议, 要 注意 发出去的 字节之间的 停顿时间 必须 小与 1.5t(即 第一个 字节 与 弟2.个字节之间上 不能 大于 1.5 个 单字节发送时间)。
具体是哪里出问题了? 现在是一个仪表就可以获取,2个以上就不可以了
pkou123 2014-07-24
  • 打赏
  • 举报
回复
这论坛死了?

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧