Page 1 of 1

Problem/Bug with Modbus Master Beta 1.0003

PostPosted: Sun Jul 15, 2018 5:16 pm
by jvalencia
I've made an small arduino pendant using the modbus slave library and it works great.

It only consists of a reset switch and a potentiometer for setting the feed rate.

I'm able to read both values with the modbus master plugin and a macro loop updates everything else. It works great at this moment.

The problem comes when I disconnect the pendant (usb-serial).

No error happens. My macro is expected to set Reset ON when a modbus function returns error, but it never happens.

Now, if I quit UCCNC and restart it without the pendant attached, it works, it sets the Reset ON due to modbus errors until I connect the pendant again.

I expected that if something happened to the pendant (accidently pulling the cable or something), the modbus would throw errors.

This is the macro loop:

Code: Select all
ushort Potvalue;
ushort Buttonvalue;

if(exec.GetModbusregister(0, out Potvalue))
{
   AS3.Setfield(Potvalue, 232);
   AS3.Validatefield(232);
}
else
{
   // on error, set feed to 0
   AS3.Setfield(0, 232);
   AS3.Validatefield(232);
}

if(!exec.GetModbusregister(1, out Buttonvalue) || (Buttonvalue == 0))
{
   // on error or button pressed, set reset ON
   exec.Callbutton(512);
}

Re: Problem/Bug with Modbus Master Beta 1.0003

PostPosted: Sun Jul 15, 2018 5:38 pm
by cncdrive
The modbus array is modificable by not only one communication source and so the software can't return you an error if the communication is wrong or not, because reading the modbus register has nothing to do with the communication, it just reads one element of an array which can be modified by several sources.
The return value of the GetModbusregister only indicates if you trying to read the wrong register number which is outside of the size of the modbus array table,
the return value can't and does not tell you if a communication is OK or not.

Re: Problem/Bug with Modbus Master Beta 1.0003

PostPosted: Mon Jul 16, 2018 4:05 pm
by jvalencia
ahh, I suspected something like that.

It would be great if there were some reserved registers in the UCCNC table where the modbus plugin could write error codes or something.

Some way to report connection errors to macros.

Re: Problem/Bug with Modbus Master Beta 1.0003

PostPosted: Mon Jul 16, 2018 5:17 pm
by cncdrive
Yes, that's a good idea.
For now what you could do to detect a lost communication is for example increase a register in a cycle and write it to a register and then readback.
If the register readback value does not match, if it did not increase then stop increasing and write the same value in cycle until you get the proper value back.
When the readback is not matching then is a communication problem, lost connection of the device etc.

Re: Problem/Bug with Modbus Master Beta 1.0003

PostPosted: Mon Jul 16, 2018 8:31 pm
by jvalencia
like a ping protocol, sounds right.

Will try this week, thanks!

Re: Problem/Bug with Modbus Master Beta 1.0003

PostPosted: Tue Jul 17, 2018 6:33 pm
by jvalencia
I solved it this way:

1) The pendant, when present, continuosly sets a register to 1.

2) The Macro Loop, before each iteration it will check that the register value is 1 to see if the pendant is working.

3) If the pendant is there, the macro code is executed (sets feed rates, reset condition, etc).

4) Last line of the macro loop sets the register back to 0, so the next loop iteration will be skipped if the pendant doesn't set it to 1 again.

This way, some iterations may be skipped due to timing, but at 50hz it's still fast enough.

This is the final code for reference:

Code: Select all
ushort Online;
ushort Potvalue;
ushort Buttonvalue;

// check for pendant presence
if(exec.GetModbusregister(0, out Online) && Online == 1)
{
   if(exec.GetModbusregister(1, out Potvalue))
   {
      AS3.Setfield(Potvalue, 232);
      AS3.Validatefield(232);
   }
   else
   {
      // on error, set feed to 0
      AS3.Setfield(0, 232);
      AS3.Validatefield(232);
   }

   if(!exec.GetModbusregister(2, out Buttonvalue) || (Buttonvalue == 0))
   {
      // reset ON
      exec.Callbutton(512);
   }
}

// reset pendant presence bit
exec.SetModbusregister(0, 0);