Modbus
Jon Keinath
Posts: 146
Has anyone been able to connect the Javelin (or BASIC Stamp) to a Modbus network (Javelin to Modicon 984 is my goal)? I just want to ask before I attempt it on my own. I don't want to reinvent the wheel if somebody already has.
Thanks,
Jon
Thanks,
Jon
Comments
I do have a modbus specification reference
http://forums.parallax.com/attachment.php?attachmentid=37327
regards peter
·
and extract data from modbus messages.
regards peter
I have a question on the CRC routine,
C++Code (note i's converted to ii's for forum):
My converted Javelin Code:
In my code the if (flag) gives me an error (not boolean), and having never used C++, I don't know how C++ Evaluates an if statement that has an int for an argument.
So C++ if (value) { }
becomes java if (value != 0) { }
also, if (!value) { }
becomes if (value == 0) { }
regards peter
you use an int array where the original code uses char array (param buf)
also for reversing the bits, I suggest you use >>> instead of >>
The >> does sign extend (leaves b15 intact) whereas >>> clears b15
I believe the c++ >> acts like >>>
You don't pass the number of bytes in buf that make up the message,
so the buf size must always equal messagesize.·That works only if
all messages are equal size.
regards peter
Post Edited (Peter Verkaik) : 3/29/2006 6:52:48 PM GMT
I have been able to get the CRC to calculate, and a simple query and return of the coils 00001 --> 00100
I will definitely post the finished code when I get it all completed.
Thanks Again
-Jon
I think it has something to do with having to send a 0xFF, it either messes up my CRC calculator or ends up sending a 0xFFFF, which throws the byte count off. I assume this is the problem because I get no data reply or action from the modicon. Also a print out or debug value of my char buffer shows 0xFFFF when it should show 0xFF. I know they are both -1, but they are definitely not the same unsigned.
I could do a force multiple coils after reading the previous state of coils and changing the one i want to change and then re-outputting it, but this seems rather difficult. Especially if I am just missing something in trying to send an 0xFF.
I am attaching my code if anyone wants to take a look at it and offer suggestions.
Modbus is the object and ModbusTest is my driver to test it.
Thanks for your time,
-Jon Keinath
Try this
· //Calculate and the CRC.
· private static int crc(char buf[noparse]/noparse,int start,int length)
··· {
··· temp=(short)0xFFFF;
··· for (int i = 0;i<length;i++)
····· {
····· temp = temp ^ (buf[noparse][[/noparse]i]&0xFF);
····· for (int j=1;j<=8;j++)
······· {
······· flag=temp & 0x0001;
······· temp=temp>>>1;
······· if (flag !=0)
········· {
········· temp = temp^(short)0xA001;
········· }
······· }
····· }
··· temp2 = temp >>> 8;
··· temp = (temp << 8) | temp2;
··· return (temp);
··· }
regards peter
·
You defined some methods static but that is not necessary.
Also you defined character arrays inside send(), that leads to
outofmemory error if send() is called frequently.
I added an address parameter to the public methods.
regards peter
Post Edited (Peter Verkaik) : 3/31/2006 5:36:35 AM GMT
····· case 'c':
······· System.out.println("Register Number:?");
······· Terminal.getString(line,6); //read up to 6 chars from terminal
······· junk = Format.bscanf(line,0," %d",intin); //read int value skipping any leading whitespace
······· System.out.println("Register Value:?");
······· Terminal.getString(line,6); //read up to 6 chars from terminal
······· Format.bscanf(line,0," %d",intin); //read int value skipping any leading whitespace
······· M.setReg(0x01,junk,intin[noparse][[/noparse]0]);
junk is not the entered register number but the number of bytes bscanf scanned.
I think you need this
····· case 'c':
······· System.out.println("Register Number:?");
······· Terminal.getString(line,6); //read up to 6 chars from terminal
········Format.bscanf(line,0," %d",intin); //read int value skipping any leading whitespace
······· junk = intin[noparse][[/noparse]0];
······· System.out.println("Register Value:?");
······· Terminal.getString(line,6); //read up to 6 chars from terminal
······· Format.bscanf(line,0," %d",intin); //read int value skipping any leading whitespace
······· M.setReg(0x01,junk,intin[noparse][[/noparse]0]);
regards peter
Post Edited (Peter Verkaik) : 3/31/2006 5:37:34 AM GMT
-Jon
(stamp.protocol.modbus)
and also passed the modbus device address to the constructor.
That is the best way to define a modbus device.
Modbus devices are now just accessed by name, no need to
pass device address to any method.
What you need to check is the reply you receive.
You use
· while (rx.byteAvailable())
but what if the last byte is delayed for some reason?
Check for reply completeness by counting the number
of bytes received (if that is known for any command)
or check for end of message marker.
I have not studied the modbus protocol but since it
is an acknowledge protocol there·must be a way
for you to tell if a reply is completely received.
While not completely received, you should wait
until some timeout value. That will turn your class
into a foolproof class.
regards peter
Post Edited (Peter Verkaik) : 3/31/2006 3:23:16 PM GMT