Basil,
Bulit up a protoboad with 16F886 and 2004A LCD which allowed me to test.
My LCD was miss behaving , giving me repeating chars and it took awhile to figure out it wasn't the program doing it.
ComTestPro is a very handy tool
You can send your chars to the HR in the slave with cmd 16
and you can read them back with cmd 3 That proved that the modbus slave was working.
wanted to do the modbus all in the background but I could not get it to run reliably that way.
So I had to leave the "frame analysis" to start from the main loop. This means the loop has to cycle often ( right now it is 1 sec) and you will need to turn the timeout timer up on comporttest.
To give you a program to run I needed to copy from my running version (16f886) to your processor and I used the v1.55 to copy into.
Basil,
I was playing with comtestpro and trying to send from HR 17 and 3 HRs. ComTestPro sent the correct command and starting address to the slave but sent the data off of the write screen from HR 1 thru 3 not HR 17-19. I checked the comtestpro log and that is what happened.
So I tried a read from HR17 and 3 HR's and the slave sent the right wrong stuff back to the first spots HR1 - 3
Just so you know ComTestpro isn't quite right .
BR
Mike
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Mike,
now the chars are steady...the communication error remains....when I set the time out 600ms and over the error became response error from timeout error...how can I send more than 32 chars in single frame ? what is the number at the bottom ?
best regards
Basil
Basil,
Mine writes and reads 32 regs just fine.. And valid responses.
Up your timeout timer to 1000ms
OR
make "wait 1 s" less like 500ms
There is a limit because Holding registers was dimensioned to 80 and we are only using the lower byte so that is 40 But you could dimension HR to a larger number or make some fancy code to use the high byte for char storage too.
Your code in the plc would write messages and tranfer them to the slave.
Then your code in the slave would read the messages from the different holding register and
send them to the GLCD. Does it need to be a long string? Strings lengths are limited in GCB.
Comtestpro is useful enough! You just have to remeber its limitation of display on screen always starts at 1.
Maybe there is something I am missing?
Number at bottom is a counter that count the loops of the main.
Mike,
ok thanks...now I'll try to send graphics and text....in your opinion how can do that ? is there a need an extra memory to store symbols and pages, or to use glcd memory? I need to use 40-50 symbols for several purposes. is it possible to access these symbols from modbus master and send to glcd,? or to store pages in GCB and call them from code.? I would like to control the glcd from modbus master (plc)....
best regards
Basil
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@Basil - you have to decide re the GLCD.
How many symbols! Considering that two weeks ago you said the LCD was all you needed then 40-50 symbols has changed the scope.
So, of the 40-50 symbols. How many pixels for all the symbols? then, divide that by 8.
Some of the 18f devices have a lot of RAM so you many be able to use an 18F, I2C eeprom then how long will it take to transmit the symbols via modus.
And/or. if you designed the GLCD symbols and the symbol layout correctly you should be able to get all these diagrams in the GLCD device and recall them dynamically from the RAM of the GLCD device to GLCD page being displayed.
Lots of options - insufficient data to make any recommendation at the moment.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Mike,
it's not my decision το use and graphic mode...I'm prototype designer mainly at hardware...so my colleague saw the glcd and ask me if it possible to work that in graphic and text mode. with control from RS-485 line.....he would like to use the glcd as terminal to monitor some devices...my first approach about that is as follows ..
I'll use a font creator for glcd with a tool that converts bitmaps to byte arrays (Lcd assistant). and import to glcd, then to glcd page ...I think that we'll start to use a small number of symbols το fit in max. capacity of glcd memory (eg.about 10 ). the page configuration maybe as below
small font1 about 20x20 pixels(fire symbol)....................warning message (text)
small font 2about 25x20 pixels (motor symbol)............. warning message (text)
small font 3....and so on......
my question is : it possible to select the fonts and or pages from master, and locate them with code and how ?
Basil
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Basil,
I think at this point you are creating somethng that already exists, HMI Human machine Interface. There are a lot of good ones out there. I don't have the time to do a full fledged HMI.
Maplesystems.com and EZautomation.net , I have used and they serve well. EZ has eztouch on which there are already a host of normal icons and you can put your own pictures and symbols on. There are others like Fanuc and AB but thoses get pricey and proprietary.
I think I will continue to improve the slave interface code that we were working with as time permits.
Good Luck with your project
Mike
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Mike,
I would like to thank you for your efforts...about ΗΜΙ, in no way I would ask to spent your time to make a project like that...I know that this monitor exists, and only I would like to make some experiments to see if it's possible to make something similar with lowest cost, cause the industrial HMI is relatively expensive...any way I continue with the last code trying to set up graphic and text mode. many thanks again.
best regards
Basil
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Mike,
I try to make a merge of modbus code with the grarhic-text code....as it seems I send a text at a preload bmp ....sending text works ok....my target is to sending both graphic and text from master ....for example, to send a byte, or char that loads a var and print a bmp to glcd....also it would be useful to locate from master the bmp graphic...Here is the code .....
when I try to open GLCD_modbus_V2.2 I get an error "Error in custom hardware settings for library <glcd.h> "</glcd.h>
Anobium,
I've installed all new libraries....I havn't compiling problems...only when I try to open the file I've that meessage....no problem about that, maybe it's my lap-top issue....I'll found it....now I would like to send to glcd and locate if it possible, a bmp graphic from master. like the text....
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anobium,
as you can see in the code, I send characters with modbus command to the glcd....characters displayed ok at glcd....I would like to select a bitmap icon , one of the preloaded at code..( 2 are at this code , Anobium and GCB-lines 115,116 ), and print at glcd....not with the code but with a byte from master, with the same way as to send characters...to display a character to glcd, I send with master an ASCII code....with the same way , I would like to send an ASCII code that selects an bmp (at slave ) and prints to glcd ...in other words I try to send both bmp icons and text from master with modbus command.....I hope to explain that, for any info please let me know...thanks.
Basil
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Line 114... has this 'Then, call the subroutine, an example GLCDBMPLoad ( 0, 0, Anobium )
Where the method GLCDBMPLoad ( GLCDXPos, GLCDYPos, SelectedTable ), pass this function three paramters X,Y, Table constant (like @GLCDTable1 or Anobium or a table of BMP bits you define)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anobium,
ok, but how can I decode the word that I send with master and pass the 3 parameters to GLCDBMPLoad ? in text mode we use the var LCDstring( passed from lines 144-152) ....in the case of graphic ? is there an example on decoding of 3 parameters and pass them to GLCDBMPLoad ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Basil,
This modbus interface does commands 3 and 16, Read holding registers and write holding registers. So the master,TM221, can read (cmd3) what is in your holding registers or write stuff to your holding registers(cmd16). How do you know when to read your HR's?
If dnf = 1 Then
' fill LCD string with value received
StrLen = StrLen / 2
LCDString(0) = StrLen
StrAddr++
for mbB0 = 1 TO StrLen ' is number of char in string
LCDstring(mbB0) = HoldingReg( StrAddr )
StrAddr = StrAddr +2
NEXT mbB0
At present for my demo code, I set a flag " dnf" "do new frame" which is set when you get a new frame from the master. The problem that i did not fix was the new frame a cmd 16 or a cmd 3 which is why it messes up the message when the master reads HR's.
So a new frame came in, so now this little program segment builds a new string for you to print from the Holding registers HR's that were just filled. When I decoded the cmd16 i knew I would need to know how many(StrLen) and Where(StrAddr), so I saved them. We read the HR and put it into the string. for your graphics command you could read 3 HR's and put them in for theparameters of GLCDBMPLoad ( GLCDXPos, GLCDYPos, SelectedTable ).
Your bitmaps should be in the PIC program space not being sent over the modbus. The choice of which bitmap to display can be sent over the modbus. This would be a nightmare for any PLC programmer. He is making the PLC program run not imagining the operator display and where and what to display.
Modbus is slow and limited amount of data. A frame is up to 256 long but actually with overhead is at most?248 data? and the buffers in my slave program are much shorter. The serial buffer is only 74 bytes long and the Holding register array is 80 bytes which is only 40 HR's because they are 16bits. It was developed when PLCs had at most several K of memory. PLC's work with Inputs,outputs, analog measurement,timers. The newPLC's have megs of memory and work off of cat5 buses.
The HMI's I have worked with were all master to the PLC being slave. So when you touched the display to start a motor the HMI would send the modbus cmd to the PLC. There was no waiting to the plc to send a message asking if you had anything to do?
So the bottom line is have your program look at the HR's in the PIC chip(stuff that came in) and build your display by decode what those HR's contain.
You would not need the "dnf" , you can just use one of the HR's as a flag for new data and reset it to 0 when you processes the data.
Figure out your protocol. who is charge? What actions you want. What data is sent? received?
GL
Mike
Last edit: mmotte 2019-02-22
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Mike,
some more details to explain :
1. PLC as master ...modbus command 16 , device x.
A....ASCII code to send chars (text)....OK
B....the same code to send 3 parameters for graphics, or to use extended ASCII code ?
2. PICwith GLCD as slave ....modbus command 16, device x.
C.....bitmaps at pic code , as TableGLCDTable(x)....OK
D.....receive data and print chars to glcd (text)....OK
E.....receive data ( parameters for GLCBBMPLoad ) , select table(x) and dislpay to glcd.
so, finally the glcd must displays .....bmp graphic (tablex) with text in the same line ..as 20190221_141112.jpg that I send 23 hours before.....
I would like to have your opinion for (B) , (E).....better for me is to add a code example in the merged code below, on how to display at glcd, some ascii chars that I send from PLC ( eg TESTDEMO12345 ) , in line with GLCDTable1 (GCB).
thanks for info....
Basil
Basil,
The command "GLCDBMPLoad ( 10, 0, GCB )" contains 3 parameters.
The first two are numbers which are easy for holding registers to contain.
The third is a string naming the table. which has to be reconstructed from the holding registers after it is sent from the master. This involves two steps, 1) copying the contents of the registers to the string variable and then knowing how long the string is and putting that length into the string(0) byte.
In the code above(lastnights post) I told your I remembered the length and addr when I decoded command 16. How are you going to know how long your string is? How are you going to know that it is a graphics command that contains three fields? Are you going to make sub commands to saying decode this as text, decode this asdrawing object, decode this as an icon?
Using a sub command may be good plan. the first holding register would contain the type of command the plc is sending. Run that HR into a select command and choose to decode it as a string, a graphic char/object, a GLCDBMPLoad, an analog value, display a graph of the following values, ...
One alternative is to have a standard list of graphical objects that are numbered, That way you don't need to send the ascii for the name of the icon, just send the number of the object. The plc programmer can choose the object off of the list that you hand him(er). Then for this command you could send the sub command and three numbers.
When learning to program the teachers would always require a flow chart or pseudo code, examples of your input and output for each of the possible conditions(even error). I don't do exactly that but before programming I do try to break it down into smaller segments and do them one at a time. I make the list in comment at the top of the program.
At work we had "Function specs" that were written before , during and after the coding on the DCS. You need to know what you want to accomplish.
Maybe discuss with the plc programmer how he would prefer to send commands and data. This may help you in forming your program. Don't get too far ahead before you discover ,maybe, the plc can't do what you are imagining.
GL
Mike
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Mike,
thanks for your help and advices...I try to make some changes to code to decode 3 parameters of GLCDBMPLoad, but I get a line instead of graphic on glcd...what's wrong ? below is the code...
Basil,
It will take a bit to answer your code and I will be away for the morning tommorrow.
I see you are trying to make a command decoder.
I see you don't know how to make a subroutine.
Isee you have broken the "main"loop ," do forever" by executing your command everytime through the loop, and putting too much time in the loop with the waitsfor which the modbus will timeout too.
Basil,
Bulit up a protoboad with 16F886 and 2004A LCD which allowed me to test.
My LCD was miss behaving , giving me repeating chars and it took awhile to figure out it wasn't the program doing it.
ComTestPro is a very handy tool
You can send your chars to the HR in the slave with cmd 16
and you can read them back with cmd 3 That proved that the modbus slave was working.
wanted to do the modbus all in the background but I could not get it to run reliably that way.
So I had to leave the "frame analysis" to start from the main loop. This means the loop has to cycle often ( right now it is 1 sec) and you will need to turn the timeout timer up on comporttest.
To give you a program to run I needed to copy from my running version (16f886) to your processor and I used the v1.55 to copy into.
see attached ver2
GL
Mike
Basil,
I was playing with comtestpro and trying to send from HR 17 and 3 HRs. ComTestPro sent the correct command and starting address to the slave but sent the data off of the write screen from HR 1 thru 3 not HR 17-19. I checked the comtestpro log and that is what happened.
So I tried a read from HR17 and 3 HR's and the slave sent the right wrong stuff back to the first spots HR1 - 3
Just so you know ComTestpro isn't quite right .
BR
Mike
Mike,
now the chars are steady...the communication error remains....when I set the time out 600ms and over the error became response error from timeout error...how can I send more than 32 chars in single frame ? what is the number at the bottom ?
best regards
Basil
Mike,
just now I saw your last post....do you think that must change ComTestPro with another ? is enough accurate as master ?
Basil,
Mine writes and reads 32 regs just fine.. And valid responses.
Up your timeout timer to 1000ms
OR
make "wait 1 s" less like 500ms
There is a limit because Holding registers was dimensioned to 80 and we are only using the lower byte so that is 40 But you could dimension HR to a larger number or make some fancy code to use the high byte for char storage too.
Your code in the plc would write messages and tranfer them to the slave.
Then your code in the slave would read the messages from the different holding register and
send them to the GLCD. Does it need to be a long string? Strings lengths are limited in GCB.
Comtestpro is useful enough! You just have to remeber its limitation of display on screen always starts at 1.
Maybe there is something I am missing?
Number at bottom is a counter that count the loops of the main.
Last edit: mmotte 2019-02-16
Mike,
ok thanks...now I'll try to send graphics and text....in your opinion how can do that ? is there a need an extra memory to store symbols and pages, or to use glcd memory? I need to use 40-50 symbols for several purposes. is it possible to access these symbols from modbus master and send to glcd,? or to store pages in GCB and call them from code.? I would like to control the glcd from modbus master (plc)....
best regards
Basil
@Basil - you have to decide re the GLCD.
How many symbols! Considering that two weeks ago you said the LCD was all you needed then 40-50 symbols has changed the scope.
So, of the 40-50 symbols. How many pixels for all the symbols? then, divide that by 8.
Some of the 18f devices have a lot of RAM so you many be able to use an 18F, I2C eeprom then how long will it take to transmit the symbols via modus.
And/or. if you designed the GLCD symbols and the symbol layout correctly you should be able to get all these diagrams in the GLCD device and recall them dynamically from the RAM of the GLCD device to GLCD page being displayed.
Lots of options - insufficient data to make any recommendation at the moment.
Mike,
it's not my decision το use and graphic mode...I'm prototype designer mainly at hardware...so my colleague saw the glcd and ask me if it possible to work that in graphic and text mode. with control from RS-485 line.....he would like to use the glcd as terminal to monitor some devices...my first approach about that is as follows ..
I'll use a font creator for glcd with a tool that converts bitmaps to byte arrays (Lcd assistant). and import to glcd, then to glcd page ...I think that we'll start to use a small number of symbols το fit in max. capacity of glcd memory (eg.about 10 ). the page configuration maybe as below
small font1 about 20x20 pixels(fire symbol)....................warning message (text)
small font 2about 25x20 pixels (motor symbol)............. warning message (text)
small font 3....and so on......
my question is : it possible to select the fonts and or pages from master, and locate them with code and how ?
Basil
Basil,
I think at this point you are creating somethng that already exists, HMI Human machine Interface. There are a lot of good ones out there. I don't have the time to do a full fledged HMI.
Maplesystems.com and EZautomation.net , I have used and they serve well. EZ has eztouch on which there are already a host of normal icons and you can put your own pictures and symbols on. There are others like Fanuc and AB but thoses get pricey and proprietary.
I think I will continue to improve the slave interface code that we were working with as time permits.
Good Luck with your project
Mike
Still playing with the slave code and I found an error on the holding register indexing. Fixed it and here is the lastest version.
Mike,
I would like to thank you for your efforts...about ΗΜΙ, in no way I would ask to spent your time to make a project like that...I know that this monitor exists, and only I would like to make some experiments to see if it's possible to make something similar with lowest cost, cause the industrial HMI is relatively expensive...any way I continue with the last code trying to set up graphic and text mode. many thanks again.
best regards
Basil
Basil,
I found another small error on cmd 3.
Here is the latest.
Mike,
I try to make a merge of modbus code with the grarhic-text code....as it seems I send a text at a preload bmp ....sending text works ok....my target is to sending both graphic and text from master ....for example, to send a byte, or char that loads a var and print a bmp to glcd....also it would be useful to locate from master the bmp graphic...Here is the code .....
when I try to open GLCD_modbus_V2.2 I get an error "Error in custom hardware settings for library <glcd.h> "</glcd.h>
Last edit: BASIL HATZILAIOS 2019-02-21
Mike,
below is the code.....
Compiles here. No compiling issues. You installed all the new and updated libraries?
what is the error message?
Anobium,
I've installed all new libraries....I havn't compiling problems...only when I try to open the file I've that meessage....no problem about that, maybe it's my lap-top issue....I'll found it....now I would like to send to glcd and locate if it possible, a bmp graphic from master. like the text....
Confused. What is it you are trying to do?
Anobium,
as you can see in the code, I send characters with modbus command to the glcd....characters displayed ok at glcd....I would like to select a bitmap icon , one of the preloaded at code..( 2 are at this code , Anobium and GCB-lines 115,116 ), and print at glcd....not with the code but with a byte from master, with the same way as to send characters...to display a character to glcd, I send with master an ASCII code....with the same way , I would like to send an ASCII code that selects an bmp (at slave ) and prints to glcd ...in other words I try to send both bmp icons and text from master with modbus command.....I hope to explain that, for any info please let me know...thanks.
Basil
Line 114... has this 'Then, call the subroutine, an example GLCDBMPLoad ( 0, 0, Anobium )
Where the method GLCDBMPLoad ( GLCDXPos, GLCDYPos, SelectedTable ), pass this function three paramters X,Y, Table constant (like @GLCDTable1 or Anobium or a table of BMP bits you define)
Anobium,
ok, but how can I decode the word that I send with master and pass the 3 parameters to GLCDBMPLoad ? in text mode we use the var LCDstring( passed from lines 144-152) ....in the case of graphic ? is there an example on decoding of 3 parameters and pass them to GLCDBMPLoad ?
Basil,
This modbus interface does commands 3 and 16, Read holding registers and write holding registers. So the master,TM221, can read (cmd3) what is in your holding registers or write stuff to your holding registers(cmd16). How do you know when to read your HR's?
At present for my demo code, I set a flag " dnf" "do new frame" which is set when you get a new frame from the master. The problem that i did not fix was the new frame a cmd 16 or a cmd 3 which is why it messes up the message when the master reads HR's.
So a new frame came in, so now this little program segment builds a new string for you to print from the Holding registers HR's that were just filled. When I decoded the cmd16 i knew I would need to know how many(StrLen) and Where(StrAddr), so I saved them. We read the HR and put it into the string. for your graphics command you could read 3 HR's and put them in for theparameters of GLCDBMPLoad ( GLCDXPos, GLCDYPos, SelectedTable ).
Your bitmaps should be in the PIC program space not being sent over the modbus. The choice of which bitmap to display can be sent over the modbus. This would be a nightmare for any PLC programmer. He is making the PLC program run not imagining the operator display and where and what to display.
Modbus is slow and limited amount of data. A frame is up to 256 long but actually with overhead is at most?248 data? and the buffers in my slave program are much shorter. The serial buffer is only 74 bytes long and the Holding register array is 80 bytes which is only 40 HR's because they are 16bits. It was developed when PLCs had at most several K of memory. PLC's work with Inputs,outputs, analog measurement,timers. The newPLC's have megs of memory and work off of cat5 buses.
The HMI's I have worked with were all master to the PLC being slave. So when you touched the display to start a motor the HMI would send the modbus cmd to the PLC. There was no waiting to the plc to send a message asking if you had anything to do?
So the bottom line is have your program look at the HR's in the PIC chip(stuff that came in) and build your display by decode what those HR's contain.
You would not need the "dnf" , you can just use one of the HR's as a flag for new data and reset it to 0 when you processes the data.
Figure out your protocol. who is charge? What actions you want. What data is sent? received?
GL
Mike
Last edit: mmotte 2019-02-22
Mike,
some more details to explain :
1. PLC as master ...modbus command 16 , device x.
A....ASCII code to send chars (text)....OK
B....the same code to send 3 parameters for graphics, or to use extended ASCII code ?
2. PICwith GLCD as slave ....modbus command 16, device x.
C.....bitmaps at pic code , as TableGLCDTable(x)....OK
D.....receive data and print chars to glcd (text)....OK
E.....receive data ( parameters for GLCBBMPLoad ) , select table(x) and dislpay to glcd.
so, finally the glcd must displays .....bmp graphic (tablex) with text in the same line ..as 20190221_141112.jpg that I send 23 hours before.....
I would like to have your opinion for (B) , (E).....better for me is to add a code example in the merged code below, on how to display at glcd, some ascii chars that I send from PLC ( eg TESTDEMO12345 ) , in line with GLCDTable1 (GCB).
thanks for info....
Basil
Basil,
The command "GLCDBMPLoad ( 10, 0, GCB )" contains 3 parameters.
The first two are numbers which are easy for holding registers to contain.
The third is a string naming the table. which has to be reconstructed from the holding registers after it is sent from the master. This involves two steps, 1) copying the contents of the registers to the string variable and then knowing how long the string is and putting that length into the string(0) byte.
In the code above(lastnights post) I told your I remembered the length and addr when I decoded command 16. How are you going to know how long your string is? How are you going to know that it is a graphics command that contains three fields? Are you going to make sub commands to saying decode this as text, decode this asdrawing object, decode this as an icon?
Using a sub command may be good plan. the first holding register would contain the type of command the plc is sending. Run that HR into a select command and choose to decode it as a string, a graphic char/object, a GLCDBMPLoad, an analog value, display a graph of the following values, ...
One alternative is to have a standard list of graphical objects that are numbered, That way you don't need to send the ascii for the name of the icon, just send the number of the object. The plc programmer can choose the object off of the list that you hand him(er). Then for this command you could send the sub command and three numbers.
When learning to program the teachers would always require a flow chart or pseudo code, examples of your input and output for each of the possible conditions(even error). I don't do exactly that but before programming I do try to break it down into smaller segments and do them one at a time. I make the list in comment at the top of the program.
At work we had "Function specs" that were written before , during and after the coding on the DCS. You need to know what you want to accomplish.
Maybe discuss with the plc programmer how he would prefer to send commands and data. This may help you in forming your program. Don't get too far ahead before you discover ,maybe, the plc can't do what you are imagining.
GL
Mike
Mike,
thanks for your help and advices...I try to make some changes to code to decode 3 parameters of GLCDBMPLoad, but I get a line instead of graphic on glcd...what's wrong ? below is the code...
Basil,
It will take a bit to answer your code and I will be away for the morning tommorrow.
I see you are trying to make a command decoder.
I see you don't know how to make a subroutine.
Isee you have broken the "main"loop ," do forever" by executing your command everytime through the loop, and putting too much time in the loop with the waitsfor which the modbus will timeout too.
I'll write something tommorrow
BR
Mike
Last edit: mmotte 2019-02-27