Today is...
Saturday, August 17, 2019
Welcome to Control.com, the global online
community of automation professionals.
Featured Video...
Featured Video
A demonstration of EtherCAT control of linear motors using the CTC EtherCAT master.
Our Advertisers
Help keep our servers running...
Patronize our advertisers!
Visit our Post Archive
ModBus C++ source code on DOS
I惴 looking for free source code (or examples) of ModBus protocol in C or C++.

I惴 looking for free source code (or examples) of ModBus protocol in C or C++. I would like to establish a communication between a computer (DOS) and a messure equipment, that communicates via ModBus protocol. The physical Layer is RS485 or TCP/IP.

Hallo

See the following, hope to help.


// 檔名: RS232_x.C--
// 緣由:為了VIGOR PLC modbus與PC圖控軟體的RS232連線
// 使用說明:
//
/*
01: Read coil status
02: Read input status
03: Read holding register
04: Read input registers
05: Force single coil
06: Preset single register
15: Force multiple coils
16: Preset multiple registers
22: Mask write register
23: Read/Write registers
*/
#pragma option w32

#include "msvcrt.h--"
#include "windows.h--"
#include "wingdi.h--"
//2006/10/19 HK
#include "winbase.h--"
#include "winerror.h--"
#include "advapi.h--"
#include "winuser.h--"

#define NUM 50
#define NUM_1 NUM+1
#define PI 3.141592654
#define ID_TIMER 1

byte Text="歡迎您 RS232 MODBUS測試程式 2006/10/19 ";
// 還是取好記一點的名字較好,避免用 a、b、c 來取名
WNDCLASS wc;
//WNDCLASSEX wc;

HWND hwnd;
DCB dcb; //2006/9/29 HK
// 用小寫 p 開頭的變數多半是指標功能。
//站號為1,Y0設為ON
byte spd[8]={1,5,0,0,255,0,140,58}; //1,5,0,0,ff,0,8c,3a
//站號為1,Y0設為OFF
byte spdx[8]={1,5,0,0,0,0,205,202}; //1,5,0,0,0,0,cd,ca
byte abcd[8];
MSG msg;
HDC hdc;
HMENU hMenu ;
HANDLE hFile;
void main()
{
/*
wc.cbSize=sizeof(WNDCLASSEX);//無此行用RegisterClassEx會看不到視窗
*/
wc.hInstance = hThisInst;
wc.lpszClassName = "Hi" ;
wc.lpfnWndProc = #WndProc ;
wc.style = CS_HREDRAW | CS_VREDRAW ;
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(0,IDC_CROSS);

RegisterClass(#wc);

hwnd=CreateWindowEx(0,"Hi",#Text,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
0,0,hThisInst,0) ;
SetTimer (hwnd, ID_TIMER, 1000, NULL);
hFile=CreateFile("Com4",
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if ( hFile == INVALID_HANDLE_VALUE ) //判斷COM開啟是否成功
{
MessageBox(0,"開啟通訊埠 錯誤!!","Comm Error",MB_OK);
return;
}

//將dcb位址傳入,以開啟通序參數
GetCommState(hFile ,#dcb ); //得知目前COM的狀態
dcb.BaudRate = 19200; //設定鮑率19200
dcb.ByteSize = 8; // 8 bits位元組
dcb.Parity = NOPARITY; //同位元檢查為none
dcb.StopBits = ONESTOPBIT; //Stop bit =1

//設定通訊埠
if( !SetCommState(hFile,#dcb) )
{
MessageBox(0,"通序埠設定錯誤!!!","Set Error",MB_OK);
CloseHandle(hFile);
return;
}
ShowWindow(hwnd,1);

while (GetMessage(#msg,0,0,0))
DispatchMessage(#msg);
}

POINT pt[50];

long WndProc(HWND hwnd, UINT msg,WPARAM wparam, LPARAM lparam) // 視窗函式
{
static int cxClient, cyClient ;
static POINT pt [NUM_1] ;
static BOOL fFlipFlop = FALSE ;
HBRUSH hBrush ;
int i;
float f;
PAINTSTRUCT ps ;
RECT rect ;
switch (msg)
{
case WM_TIMER :
!fFlipFlop ;
InvalidateRect (hwnd, NULL, FALSE) ;
if(fFlipFlop)
WriteFile(hFile,#spd,8,#abcd,NULL);
else
WriteFile(hFile,#spdx,8,#abcd,NULL);
return 0 ;

case WM_SIZE :
cxClient = LOWORD (lparam) ;
cyClient = HIWORD (lparam) ;
break;

case WM_PAINT :
hdc = BeginPaint (hwnd, #ps) ;
GetClientRect (hwnd, #rect) ;

if(fFlipFlop)
{
hBrush = CreateSolidBrush ( RGB(255,0,0) ) ;
FillRect (hdc,#rect, hBrush) ;
DrawText (hdc, "站號為1,Y0設為ON", 16, #rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
}
else
{
hBrush = CreateSolidBrush ( RGB(0,255,0) ) ;
FillRect (hdc,#rect, hBrush) ;
DrawText (hdc, "站號為1,Y0設為OFF", 17, #rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
}
MoveToEx (hdc, 0, cyClient / 2, NULL) ;
LineTo(hdc, cxClient, cyClient / 2) ;
for (i = 0 ; i <= NUM ; i++)
{
pt[i].x = i * cxClient /NUM;
f = sin(PI * 2 / NUM * i);
pt[i].y = float 1-f * cyClient/2 ;
}
Polyline (hdc, #pt,NUM_1) ;

EndPaint (hwnd, #ps) ; // 這行原本有錯喔!改了變數名字就看出來了
DeleteObject (hBrush) ;
break;
case WM_DESTROY :
KillTimer (hwnd, ID_TIMER) ;
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd,msg,wparam,lparam);
}

For those of you wanting some C++ you can stick in anywhere here some code (derived from the last post). This is confirmed to work for me.


DCB dcb;
byte byReceive[27];
byte bySend[8]={0x01,0x03,0x00,0x64,0x00,0x0B,0x45,0xD2};
DWORD dwBytesWritten;
MSG msg;
HDC hdc;
HMENU hMenu ;
HANDLE hFile;

void modbusTest()
{

hFile=CreateFile("Com4",
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if ( hFile == INVALID_HANDLE_VALUE )
{
//TODO: An error occured notify user with a message
return;
}

GetCommState(hFile ,&dcb );
dcb.BaudRate = 115200;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;

if( !SetCommState(hFile,&dcb) )
{
//TODO: An error occured notify user with a message
CloseHandle(hFile);
return;
}

static bool fFlipFlop = true;

while(true)
{
if(fFlipFlop == true) fFlipFlop = false;
else fFlipFlop = true;

if(fFlipFlop) {
ReadFile(hFile,&byReceive,27,&dwBytesWritten,NULL);
Sleep(1000);
}
else
WriteFile(hFile,&bySend,8,&dwBytesWritten,NULL);

}
}

Sourcecode documentation:
http://pvbrowser.org/pvbrowser/sf/manual/rllib/html/classrlModbus.html

Download:
http://pvbrowser.de/pvbrowser/index.php?menu=8&topic=8&subtopic=4

It is in C++.
This works on Linux/Unix, Windows and OpenVMS.
You would have to extend it to support DOS.

By ankur bagul on 27 August, 2009 - 5:55 am

I'm looking for free source code (or examples) of ModBus protocol in vhdl or C. I would like to establish a communication between two fpga, that communicates via ModBus rtu protocol. The physical Layer is RS323 rtu.

thanks
Ankur Bagul

By curt wuollet on 27 August, 2009 - 9:43 am

Modbus in vhdl? now, that would be interesting. They do have some C examples on Modbus.org, or did, last time I looked which was quite
a while ago.

Regards
cww

Have a look on Sourceforge for C Modbus libraries.