Timing issues with uspace and realtime

More
6 years 1 week ago #187021 by JR1050
Below is snippet of code that controls the coolant on my small lathe. I recently upgraded the operators panel using a usb Pokeys for an i/o board. Both the usb interface and pokeys component run in userspace. The component is compiled as a real time component. Issues, the push button will turn the coolant on and stay on some times, most of the time it runs for a couple seconds and shuts off. looking at hal show, a button push does not set the status bit(cs_coolant_on). If I issue M8, the coolant runs, bit is set. Attemping to interupt the auto cooling doesnt work and issuing M9 turns the bits off, but results in a large delay in the coolant pump turning off. Im suspecting timing issues , bits sticking in userspace. I have the same basic code on my big lathe with a toggle switch, it uses a mesa smart serial board-not Pokeys, and it works excellent. Suggestions? Version is 2.7.15 on stretch with rt preemept.




Code:
from hal net cool_auto_on iocontrol.0.coolant-flood => controlpanel.0.cool-auto-on net cr_idod_clnt controlpanel.0.cr-idod-clnt => hm2_5i20.0.gpio.054.out net pb_cool_on pokeys.0.in-2 => controlpanel.0.pb-cool-on #COOLANT ON PUSH BUTTON ins pin in bit cool_auto_on; pin in bit pb_cool_on; status bit pin io bit cs_coolant_off; outs pin out bit cr_idod_clnt; // relay for pump if((cool_auto_on)==1||((pb_cool_on)==1&&(cs_coolant_on)==0)) // coolant on { cr_idod_clnt=1; cs_coolant_on=1; } else if((cool_auto_on)==1&&((pb_cool_on)==1&&(cs_coolant_on)==1)) // auto interupt { cr_idod_clnt=0; cs_coolant_on=0; } else if((cool_auto_on)==1&&((pb_cool_on)==1&&(cs_coolant_on)==0)) // auto resume { cr_idod_clnt=1; cs_coolant_on=1; } else if((cool_auto_on)==0||((pb_cool_on)==1&&(cs_coolant_on)==1)) { cr_idod_clnt=0; cs_coolant_on=0; }

Please Log in to join the conversation.

More
5 years 11 months ago #188110 by andypugh
Did you solve this?
My suspicion would be that out-of-order changes to inputs are confusing the system.

I would generally code something like this as a state-machine, so that in the coolant-on state you have code to detect conditions that would turn it off, and vice-versa. (and possibly also some transitional states)

An example here, from a central heating system that I am working on:
github.com/andypugh/ESP-Heat/blob/master...gController.ino#L185
(Though looking at it, it currently has a testing overrride in place of one of the timeouts)

Please Log in to join the conversation.

More
5 years 11 months ago #188173 by JR1050
Hi Andy , its been a while since Id seen you answer a question , I had feared you had left the forum... excellent to know such is not the case.I have not solved this , I did initially write this as a finite state machine. It would fall through the cases , but would miss the button presses and wouldn't set the status bits ( cs_your_bit_name). Here is one of my iterations of this code.
Code:
component coolant; pin in bit cool_auto_on; // connected to iocontrol coolant pin in bit pb_cool_on; // connected to pokeys input bit pin io bit cs_coolant_auto_on; pin io bit cs_coolant_man_on; pin io bit cs_coolant_off; param rw bit cool_mode; pin out bit cr_idod_clnt; // connected to mesa output bit function _ nofp; license "gpl"; ;; FUNCTION(_) { switch(cool_mode) { case 0: if((cool_auto_on)==1&&(cs_coolant_auto_on)==0) // auto on { cs_coolant_auto_on=1; cs_coolant_man_on=0; cs_coolant_off=0; cr_idod_clnt=1; } else { cool_mode=1; } break; case 1: if((cs_coolant_auto_on)==1&&(pb_cool_on)==1) // auto interrupt { cs_coolant_off=1; cr_idod_clnt=0; } else { cool_mode=2; } break; case 2: if(((cs_coolant_auto_on)==1&&(cs_coolant_off)==1)&&(pb_cool_on)==1) // auto resume { cs_coolant_off=0; cr_idod_clnt=1; } else { cool_mode=3; } break; case 3: if((cool_auto_on)==0&&(cs_coolant_auto_on)==1) // auto off { cs_coolant_auto_on=0; cr_idod_clnt=0; } else { cool_mode=4; } break; case 4: if((pb_cool_on)==1&&(cs_coolant_man_on)==0) //man on { cs_coolant_man_on=1; cs_coolant_auto_on=0; cr_idod_clnt=1; } else { cool_mode=5; } break; case 5: if((cs_coolant_man_on)==1&&(pb_cool_on)==1) // man off { cr_idod_clnt=0; cs_coolant_man_on=0; } else { cool_mode=0; } break; }

This has been a part of larger component that runs my whole operator panel and has been a separate component like above. In both instances, the behavior of the button press and subsequent actions have been inconsistent. Sometimes they work, sometimes takes two pushes. Commanding coolant with M8 always works , shutting it off with M9 ,eventually-it hangs up. Sometimes the coolant will come on with a button press, often just for a couple seconds . It seems like logic is getting caught up between scans . This panel uses pokeys 55 usb, my other panel uses mesa smart serial. My guess was getting caught up in user space , maybe this would be better off as pure user space component? If I lose the code that uses m8/m9 and just keep as a button press, it engages the contractor on and off like a fluttering relay contact . Your thoughts?

Please Log in to join the conversation.

More
5 years 11 months ago #188231 by andypugh

JR1050 wrote: Hi Andy , its been a while since Id seen you answer a question , I had feared you had left the forum.


Lockdown and working from home have really changed the structure of my days, and I no longer have a lunch break at my desk and time to kill. Also I got a bit worn out with LinuxCNC doing the 2.8 release.
Code:
component coolant; ... param rw bit cool_mode; ... switch(cool_mode) ... case 0: ... case 1: ... case 2: ... case 4: ... case 5:

If cool_mode is a bit then most of those states can never run. But I think that probably was the correct approach.
But it is probably worth making a pen-and-paper (or excel) table of all input states and output states, deciding what needs to happen in each case and then going through your code to check what happens in each condition.

Please Log in to join the conversation.

Time to create page: 0.086 seconds
Powered by Kunena Forum