I'm completely new to Modbus protocoll. My setup consists of three devices with different addresses. They're all connected to COM1 via RS232. I've used Modbus Poll to check the input-data, which works properly. What I want to do now, is reading the holding registers in a vc++ (MFC) application. For serial communication I use the MSComm class. I have written a little code, but I don't get Input at all.
My code at the moment:
BOOL Crs232test4Dlg::OpenConnection ()
{
char error [513];
try
{
if (! m_MSComm.GetPortOpen ())
{
m_MSComm.SetCommPort (1);
m_MSComm.SetSettings ("9600,N,8,1");
m_MSComm.SetInputLen (4);
// Receive Data as Text
m_MSComm.SetInputMode (0);
m_MSComm.SetPortOpen (true);
m_MSComm.SetCommID (1);
return m_MSComm.GetPortOpen ();
}
AfxMessageBox ("Success!!!!", MB_OK);
return TRUE;
}
catch (CException *e)
{
e->GetErrorMessage (error, 512);
AfxMessageBox (error, MB_OK);
return FALSE;
}
}
void Crs232test4Dlg::OnVaisalaComm ()
{
if (m_MSComm.GetCommEvent () == 2)
{
COleVariant in_dat;
in_dat = m_MSComm.GetInput ();
Sleep (100);
CString strInput (in_dat.bstrVal);
m_Input = m_Input + strInput;
UpdateData (FALSE);
}
}
I want to put out m_Input now, but it hasn't changed a bit. I also get the warning (Property is read-only) when setting SetCommID, which I don't think is important.
Can anyone please guide me, since I'm really clueless at the moment.
Regards
EDIT: According to a communication example, I've tried to handle the device like a file.
m_hCom = CreateFile(m_sComPort,
GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security
OPEN_EXISTING,
0, // no overlapped I/O
NULL); // null template
// :(colon) Address=1 Function=3 Starting register= 40001 (To write 400001 or 0?)
Registers to read=4 checksum CR LF
char strASCII[] = "3A 30 31 30 33 30 30 30 30 30 30 30 34 46 38 0D 0A";
bWriteRC = WriteFile (m_hCom, strASCII, strlen(strASCII), &iBytesWritten, NULL);
memset(sBuffer,0,sizeof(sBuffer));
// Reading output of the M3
bReadRC = ReadFile (m_hCom, &sBuffer, 1, &iBytesRead, NULL);
if (bReadRC && iBytesRead > 0)
{
sResult = sBuffer;
}
else
{
sResult = "Read Failed";
dwError = GetLastError();
sprintf(sMsg, "Read length failed: RC=%d Bytes read=%d, "
"Error=%d ",
bReadRC, iBytesRead, dwError);
AfxMessageBox(sMsg);
}
I get the read length failed error. strASCII isn't separated normally, only for better overview now. I have checked the communication in Modbus Poll. My output is right, but it doesn't seem to get the data.
EDIT: I got it. Thank you very much for your help. I had put the wrong checksum.
not an answer, but a guide for trouble shotting.
your best friends should be:
1) null modem 232female<->232female cable with second computer that has com port (or laptop with usb->serial converter) ... soldering cable by your self wire to wire is maybe best solution.
2) windows hyper-terminal simple but reliable application preinstalled on most windows... started in comPort mode, with same bitrate/parity/stopbits parameters that you expect from modules.
... with all respects to windows signaling queues and MSCOmm class that is probably ok, but to eliminate all possible reasons for communication failure in project start, maybe you should prefer simple threating COM port as file, and reading from it inside some while loop ... some short version of this example... Setting serial parameters at start and reading file named comX.
above link has good cSerialClass implementation on download, but simple primer without any error checking is here at pastebin .