Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - njlaw

Pages: [1]
Technical support / Re: Handling more than 1000 #Define entries
« on: June 28, 2021, 06:10:00 PM »
I'm just following up to say that I appreciate the increase of the #Define table limit in v7.4!

Thank you!

Nathanael Law

Technical support / Re: Headless CO5 Uploads
« on: March 31, 2021, 07:14:43 AM »
What version of CO5uploader do you have? Since version 2.3 that had been launched in 2016, the CO5uploader can be operated from the command line. Please see the command line user guide:

Hopefully this works for you.

Unfortunately, even when run from the command line, it requires a GUI, so we can't run in on our headless (no GUI) computers that are deployed alongside the PLCs.  From the Command Line User Guide:
Quote from: CommandLineUserGuide
This is a semi automatic process that requires the user to both manually click 'Reset' and close CO5 Uploader after each transfer completes.

In the next product that will be launched later this year the PLC will be able to download a CO5 file from a webserver to upgrade its own software with auto rollback in case of unsuccessful upgrade.

If you like some preliminary information about the new product please contact for more details.

Thank you!  I will reach out to your e-mail!

Technical support / Headless CO5 Uploads
« on: March 30, 2021, 10:54:34 AM »
Hello All,

I'm wondering if anyone else would benefit from a headless (no GUI) CO5 uploader or a uploader library that we could call from our own code?  As we see the demand for IIoT grow among our customers, the ability to self-manage updates from a web console has been requested a number of times.  "I can update my smart speaker at home from the office.  Why can't I update our equipment myself?  Why do we have to call you and schedule a time to create a remote connection to our equipment to perform an update?  Our equipment is all Internet connected anyway.  I should be able to update with the click of a button."

It would definitely be helpful from our end too.  E.g., yesterday we discovered a bug that presents itself under rare circumstances.  We would like to update all our customers' equipment with the fixed version.  We now have to call all our customers and schedule a separate upgrade time for each of their units since I have to create a network tunnel, launch the CO5Uploader, click Reset, and click close.  If we were able to avoid the GUI, we could simply display an alert on our web portal that tells our customers an update is available for their equipment: "Click here to update.  The update will take up to 10 minutes during which your equipment will not be operable.  View the CHANGELOG here."  We already have a small headless PC running with every PLC we have deployed that can manage retries, rollbacks, etc.  But to do that programmatically, we need to be able to upload without a GUI.

Best regards,

Nathanael Law

Technical support / Re: Handling more than 1000 #Define entries
« on: March 30, 2021, 08:36:28 AM »
How many more entries would you need in the #Define table?

I think it would be difficult to put a definite number to that: I've lost track of the number of times I thought, "I'll never use that much RAM, CPU, etc."  A total of 2000 (1000 more) would certainly get us past the immediate squeeze for quite some time.

What PLC model are you using?

The program that we are running into the #Define limit with is running on a Fx1616-BA.  We have other programs on Nano-10s, but the complexity of those programs is significantly less, and we're around 250 #Define entries there.

Technical support / Re: Handling more than 1000 #Define entries
« on: March 08, 2021, 09:42:07 AM »
Hi Gary,

Thank you for all the tips!  In particular, I hadn't considered using another variable reference inside the Value of a #Define entry.  I've also been avoiding using the EEPROM, but might need to look at that since I'm down to 240 free DM addresses and 90 free FP addresses.

Thanks again!

Nathanael Law

Technical support / Re: Handling more than 1000 #Define entries
« on: March 06, 2021, 11:50:15 AM »
Hi Gary,

If you would be willing to share some snippets, that would be appreciated.  I am already trying to use arrays and offsets (basically like pointer math in C) to reduce the need for #Defines where possible, but any other techniques would be helpful.

Code: [Select]
ingredientMatched = 0
FOR I = 0 TO 5
IF FP[fpSrcStart + CONST_MD_Ingredient_FPOffset + I * CONST_MD_Ingredient_FPLength + CONST_MD_IngredientDosage_FPOffset] > 0.0 OR FP[fpSrcStart + CONST_MD_Ingredient_FPOffset + I * CONST_MD_Ingredient_FPLength + CONST_MD_IngredientMinDosage_FPOffset] > 0.0 OR FP[fpSrcStart + CONST_MD_Ingredient_FPOffset + I * CONST_MD_Ingredient_FPLength + CONST_MD_IngredientMaxDosage_FPOffset] > 0.0 THEN
matched = 0
FOR J = 0 TO 5
IF TestBit(DM16_ActiveComponents1, CONST_ActiveComponents1_Ingredient1 + J) AND CompDMMem(dmSrcStart + CONST_MD_Ingredient_DM16Offset + I * CONST_MD_Ingredient_DM16Length + CONST_MD_IngredientName_DM16Offset, CONST_Ingredient1Name_DM16Addr + J * 8, 8) = 0 THEN
matched = 1
SetBit ingredientMatched, J
ret = CopyDM(dmSrcStart + CONST_MD_Ingredient_DM16Offset + I * CONST_MD_Ingredient_DM16Length, dmDstStart + CONST_MD_Ingredient_DM16Offset + J * CONST_MD_Ingredient_DM16Length, CONST_MD_Ingredient_DM16Length)
ret = CopyFP(fpSrcStart + CONST_MD_Ingredient_FPOffset + I * CONST_MD_Ingredient_FPLength, fpDstStart + CONST_MD_Ingredient_FPOffset + J * CONST_MD_Ingredient_FPLength, CONST_MD_Ingredient_FPLength)
IF matched = 0 THEN
SetBit DM16_StageMDErrFlags2, (CONST_StageMDErrFlags2_Ingredient1DoesNotMatch + I)

In the above code, fpSrcStart points to the FP address at the start of the recipe that has been pushed from the cloud and fpDstStart points to the FP address of the recipe used in live batches.  (dmSrcStart and dmDstStart work the same way.)  It then goes through all the ingredients in the recipe and matches them to the ingredients loaded into the machine slots, and copies the dosage and other parameters from the recipe to the correct slot for operation.

This way, I don't use #Defines for all the components of each recipe (5 can be loaded into the PLC from the cloud at once), but only need the starting location and relative offsets for all six data structures (5 recipes from the cloud that can be selected at run time by the operator and the live recipe).

Best regards,


Technical support / Handling more than 1000 #Define entries
« on: March 05, 2021, 02:15:47 PM »

I have a program that continues to increase in size and complexity and am now out of #Define entries.  Since this is compiler-side and doesn't actually impact memory usage on the PLCs, 1000 seems like a rather arbitrary limit.  Is there any chance this could be increased?

And since I am sure that someone will be curious why we are using so many #Define entries, I'll try to explain.  We have a little computer (IoT gateway) that is deployed along side the PLCs.  It translates the content of the PLC memory to JSON and sends certain portions of it to the cloud live and certain portions on demand.  It is also able to take JSON documents from the cloud and use them to write to the PLC memory.  As such the program needs to be able to map between PLC memory and the JSON documents.  By using #Define entries for every variable, we are able to update memory addresses and mapping relatively easily: the PLC program stays the same and just by regenerating the #Define table from a database, we can move memory and preserve the mapping to JSON.

E.g. say we have,
DM32Arr_LUT1 | DM32[225]
DM32Arr_LUT2 | DM32[250]

Due to product / program revisions, we need to increase the size of the LUT1 lookup table.  With our system, I can just publish a new #Define table:

DM32Arr_LUT1 | DM32[225]
DM32Arr_LUT2 | DM32[270]

And I don't have to change the code in the TRiLOGI program at all.

Any thoughts or alternatives are welcome.

Best regards,


Technical support / Integer Stack Overflow
« on: August 19, 2020, 04:09:22 PM »
Hello All,

I'm having a rather confusing problem on a Nano-10 that has me thinking I'm just overlooking something simple.  One of my PLCs keeps giving an "Integer Stack Ovrflw" error.  I know what a Call Stack Overflow is and what an Integer Overflow is, but I'm not familiar with an Integer Stack Overflow.

The actual error output is:
Code: [Select]
Integer Stack Ovrflw
CF #0008:0D20

And the code listing indicates that it's happening in my calculation of DM32_LUTOutput:
Code: [Select]
0CF9 | IF (DM32[Jmid+1] - DM32[Jmid]) = 0 THEN
0D0B | DM32_LUTOutput = DM32[Imid] + (DM32[Imid+1] - DM32[Imid]) * (DM32_LUTInput - DM32[Jmid]) / (DM32[Jmid+1] - DM32[Jmid])

The funny thing is I've tried populating the same LUT in a lab Nano-10 as in the problem unit and I have no problem calculating DM32_LUTOutput.

Any pointers would be appreciated!


Apparently changing the calculation to
Code: [Select]
N = (DM32[Imid+1] - DM32[Imid]) * (DM32_LUTInput - DM32[Jmid])
O = (DM32[Jmid+1] - DM32[Jmid])

DM32_LUTOutput = DM32[Imid] + N / O
caused the issue to go away.  Why, however, I have no idea.  With the way the compiler writes the instructions, is there a specific integer arithmetic stack that is overflowing?  It also doesn't explain why the same code seems to work perfectly on another Nano-10 that is also r84J.  As an aside, is there a way to retrieve runtime exceptions via Modbus?  It would be very nice to report on those automatically.


Technical support / Re: RS485 Baud Rate Between Nano-10 and Fx1616-BA
« on: June 04, 2020, 03:10:23 PM »
Thank you kindly for the detailed response and testing!  We will proceed with testing communication over Ethernet if we can't achieve our target responsiveness via other optimization.

Technical support / RS485 Baud Rate Between Nano-10 and Fx1616-BA
« on: June 03, 2020, 03:00:56 PM »
The manuals for both the Nano-10 and the Fx1616-BA indicate that they should support up to a baud rate of 230.4kbps; however, I am unable to successfully communicate between them over 100k.

The Fx1616-BA COMM2 is connected to the Nano-10 COMM port with 18 AWG shielded twisted pair.  They are less than 1 metre apart.  I have tried both with and without 120 ohm terminating resistors, but at this distance, it really shouldn't make a difference.

Fx1616-BA Test Code (Simplified)

1st.Scan                      Init
---| |-----------------------{dCusF}

Clk:1.0s                    ReadSlave
---| |-----------------------{dCusF}


T = STATUS(21)
READMB2 12,8,64,DM[1],8
V = STATUS(21) - T

Nano-10 Test Code

1st.Scan                      Init
---| |-----------------------{dCusF}


This setup works perfectly fine at the default, at &H07 (56.7k), at &H08 (100k), but not at all at &H09 (115.2k) and &H0A (230.4k).

Statistics (100 samples per baud rate)
Baud Rate | Mean ReadSlave Time | Std Dev
   38,400 |             17.59ms |  1.92ms
   57,600 |             15.11ms |  1.99ms
  100,000 |             12.77ms |  1.97ms

The ultimate goal in this is to minimize latency between the Fx1616-BA, which acts as the master and 3 Nano-10s along with a third party RS485 device that act as slaves.  From the time the user pushes a button on the HMI that requires a change in the devices controlled by the Nano-10s, too much time is passing before the slave devices receive the command via Modbus RTU from the Fx1616-BA.  Just as a note, we are working on other ways to optimize the speed (e.g., batching multiple WRITEMODBUS commands into a single WRITEMB2 command, etc.)

Any advice would be appreciated!

Pages: [1]