Timing issues with uspace and realtime

More
23 Oct 2020 21:00 #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.




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 or Create an account to join the conversation.

More
02 Nov 2020 14:00 #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 or Create an account to join the conversation.

More
03 Nov 2020 04:32 #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.
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 or Create an account to join the conversation.

More
03 Nov 2020 15:00 #188231 by andypugh

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.
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.
The following user(s) said Thank You: JR1050, tommylight

Please Log in or Create an account to join the conversation.

Time to create page: 0.205 seconds
Powered by Kunena Forum