Crimson 3 u16 array to u32

ERCfarcontrol

Member
Join Date
Apr 2015
Location
Fresno, Ca
Posts
63
Hi, all. I have some experience with Modbus... somehow I always get lucky. After reading, fiddling, and searching for most of the day, I'm stumped. I'm using a Graphite communicating over modbus to read error history from a controller. The error history is stored in 8 consecutive registers that MUST ALL be read in one message. The first 6 registers are individual u16 data values. The last 2 registers make up a single u32 data value. I've successfully setup a data tag array to read all individual registers, but cannot figure out how to combine the last 2 registers into a u32. Any help would be appreciated. Thanks.
 
Try multiplying the last register by 65536 and adding it to the second-to-the-last register.

Or vice-versa, if the High/Low Word order is different.
 
With Crimson there are probably several different ways to do this.

One that comes to mind is to make a tag whose data source is something like:

HMI_Int[6]*65536+HMI_Int[7]

I happened to have a 3.0 app open with those array tags available...I have not tested this to see if it works...

Can you share your file? If not, can you share some screenshots?

EDIT: I did a test in the emulator in 3.0 and what I suggested does work, but you do need to ensure that the tags are set to integer and on the format tab, set them to unsigned.

Snippet of emulator screenshot:

crimson_u32.png
 
Last edited:
When you create that tag, you can just set it up as "General" and type the expression directly into the field.

If you set up the tag as "Complex", then you preface the expression with "return" and end it with a semicolon.

I do love the Crimson emulator !

Crimson_U32_TagDef.PNG Crimson_U32.PNG
 
I should really just defer to Paul when it's a Crimson question.

It's like "OkiePC: Battle Angel".
 
It didn't work... and then I swapped the tags in the expression as Ken Mentioned. The device transmits low word first. Works fantabulous!


I have some questions about logging these fault codes in the alarm log. Should I start a new thread?
 
It didn't work... and then I swapped the tags in the expression as Ken Mentioned. The device transmits low word first. Works fantabulous!


I have some questions about logging these fault codes in the alarm log. Should I start a new thread?

If you start a new thread, it might help for future searches being separate if it is a separate type of issue.
 
I've ran into another problem with arrays in this device that I'm communicating to. In specific it is a 3 register(u16) array for the date:

date[0] = year
date[1] = month
date[2] = day

It seems that I MUST read AND write all in one message. The device freezes when I read the registers individually. I can read it as a 3 item array successfully. When I try to write to any of the registers individually the device freezes, so I'm assuming I need to write the entire array in one message. How would this be done?
 
Hmmm. That is interesting.

Try setting up a tag array just for those addresses with the Data Read Mode property set to Entire Array. That should take care of the reading. As for forcing Crimson to always write to all three tags...I am not sure ... It might always write to them if you have a program with assigment operators for all three of them. So maybe to write to them, use internal tags to store the values and a button that calls a program and in the program something like:

date[0] := Internal_Year;
date[1] := Internal_Month;
date[2] := Internal_Day;

EDIT: Another method might be to use a gateway block with the update policy set to continuous or timed.
 
Last edited:
The great thing about Modbus is that it's so universal and simple.

The awful thing about Modbus is that people have found lots of ways to work around the fact that it's so universal and simple.

What they're doing is using the service code (16, Write Multiple Holding Registers) and the Offset (0) and the Length (3) in order to imply "Apply Clock Settings".

When you write them individually, you are using Service Code 6, "Write Single Holding Register", which the device rejects.

Have you tried putting those three registers into their own Data Block under the PLC configuration in Crimson ?
 
Yeah, I tried disabling code 6 in comms setup, but I got to thinking it is probably just utilizing 3 successive code 16's, lol.

A "set clock" program was a thought I had but thought it would have just set each register consecutively rather than in one lump. This is easy to give a shot.

I've watched a few videos on gateway blocks when I was looking into converting modbus to BACnet, but I never dug into it. Would I be making a gateway block from an internal tag to each register?
 
Yeah, I tried disabling code 6 in comms setup, but I got to thinking it is probably just utilizing 3 successive code 16's, lol.

A "set clock" program was a thought I had but thought it would have just set each register consecutively rather than in one lump. This is easy to give a shot.

I've watched a few videos on gateway blocks when I was looking into converting modbus to BACnet, but I never dug into it. Would I be making a gateway block from an internal tag to each register?

When you create the block, you can choose a starting address in the device and a size. Each element of the group will be listed. You then can click on each one and assign it to another device address or tag.
 
The program route worked! Just when you think you know Crimson... :confused:

Just for S&G's, I threw 1ms intervals of the "sleep()" function between the actions:

Boiler1.Configuration.Date[0]=System.internalyear;
Sleep(2000);
Boiler1.Configuration.Date[1]=System.internalmonth;
Sleep(2000);
Boiler1.Configuration.Date[2]=System.internalday;


It still wrote successfully. I increased the sleep function to 2000ms and it freezes comms for a short period but comes back with a successful write. Hmm.
 
On thing that popped into my head late last night: the Modbus Ping.

Crimson has a function in the Modbus master driver that "pings" the destination device periodically to be sure it's online. By default it does that by reading just the first Holding Register (40001).

I encountered a problem with that once with a machine that only supported reads of specific-length blocks that started at the first register. It would throw an error if you tried to read just one.

You can change the address used by the "Modbus ping" function, or I think that setting the register to zero disables the feature.
 

Similar Topics

Hey guys, hoping someone here could give me a little advice. I'm working with a CR1000-04000 in Crimson 3.1 and I was interested in adding the...
Replies
4
Views
149
Hi, I'm having an issue in crimson 3.0 when I create a programme using a case statement referencing a fault word that each bit needs to change the...
Replies
5
Views
298
How do you install update on Red Lion Crimson ver 3.1. Do I just need to run the exe file on the host server?
Replies
1
Views
128
Has anyone found a way to convert/replace/update the firmware on old Parker TS80xx series HMIs (i.e. TS8010, TS8006, etc) to accept Crimson...
Replies
0
Views
109
Has anyone setup communications with Red Lion 3.0 MODBUS to Baker Hughes Centrilift GCS VFD? Thanks
Replies
0
Views
97
Back
Top Bottom