Boolean IF function help please for a random glitch in my tractor hedge cutter.

Hi guys

I have made a 3 axis joystick controller, attached to an UNO board and an 8x relay board to operate my tractor mounted hedge cutter.

I previously had help from here on setting up the IF function and that has got me able to use it, however, there is a random glitch that I cant seem to get to the bottom of.

so the joystick controls 7 functions:
6 hydraulic directional valves
1 hydraulic lock/dump valve

when ever 1 or more of the 6 directional valves open, I also need to open the lock/dump vale simultaneously

there is also provision in the code for a push button to operate a separate function but I have not set that up yet, so we can ignore that for now.

the problem is - randomly - the lock/dump is not activated. This might happen 1 in 30 joystick movements, or it might happen 4 times in a row - either way it is a problem as the machine doesn't function when it happens.

it does appear to get worse with time - the longer I work the machine, the more frequently the problem occurs

I have adjusted the switching positions of the joystick and also the loop rate to see if that makes a difference, but it hasn't.

I have marked the code that I think is the issue with // notes - its at the bottom of the code.

#define joyX A0;
#define joyY A2;
#define joyZ A5;

int pbuttonPin = 2;
int relayPin = 12;
int val = 0; 
int lightON = 0;
int pushed = 0;

void setup() {

  Serial.begin(9600);
  
  pinMode(pbuttonPin, INPUT_PULLUP); 
  pinMode(relayPin, OUTPUT); //diverter valve to swap to swing control
  
  pinMode (11, OUTPUT); // hydraulic boom down
  pinMode (10, OUTPUT); // hydraulic boom up
 
  pinMode (9, OUTPUT); // hydraulic boom in
  pinMode (8, OUTPUT); // hydraulic boom out
 
  pinMode (7, OUTPUT); // rotor head rotate
  pinMode (6, OUTPUT); // rotor head rotate

  pinMode (4, OUTPUT); // hydraulic oil dump valve - must be open when any other function is in use

}

void loop() {

val = digitalRead(pbuttonPin);
  if(val == HIGH && lightON == LOW){
    pushed = 1-pushed;
    delay(100); }    
  lightON = val;
      if(pushed == HIGH){
        Serial.println("Light ON");
        digitalWrite(relayPin, LOW);  
      }else{
        Serial.println("Light OFF");
        digitalWrite(relayPin, HIGH);
      }   
  
 int xValue = analogRead(A0);
 int yValue = analogRead(A2);
 int zValue = analogRead(A5);

  if ( xValue > 550)
  {digitalWrite(11, HIGH);}
    else{digitalWrite(11, LOW);}
    
  if ( xValue < 470)
  {digitalWrite(10, HIGH);}
    else{digitalWrite(10, LOW);}
 
  if ( yValue > 550)
  {digitalWrite(9, HIGH);}
    else{digitalWrite(9, LOW);}
  
  if ( yValue < 470)
  {digitalWrite(8, HIGH);}
    else{digitalWrite(8, LOW);}

  if ( zValue > 550)
  {digitalWrite(6, HIGH);}
    else{digitalWrite(6, LOW);}
 
  if ( zValue < 470)
  {digitalWrite(7, HIGH);}
    else{digitalWrite(7, LOW);}
 
  if (digitalRead(6) || digitalRead(7) || digitalRead(8) || digitalRead(9) || digitalRead(10) || digitalRead(11)) {
  digitalWrite(4, LOW);}  // This is the part that I think is causing the issue.
    else {
  digitalWrite(4, HIGH);} // would anyone know a better way of coding it?

  delay(50);
}

thanks in advance guys

Is it possible the lock/dump needs to be activated BEFORE the boom or head operates? Maybe this will work:

#define joyX A0;
#define joyY A2;
#define joyZ A5;

int pbuttonPin = 2;
int relayPin = 12;
int boomDownPin = 11;
int boomUpPin = 10;
int boomInPin = 9;
int boomOutPin = 8;
int headRotRPin = 7;
int headRotLPin = 6;
int dumpValvePin = 4;
int val = 0;
int lightON = 0;
int pushed = 0;

void setup() 
{
  Serial.begin(9600);

  pinMode(pbuttonPin, INPUT_PULLUP);
  pinMode(relayPin, OUTPUT); //diverter valve to swap to swing control

  pinMode (boomDownPin, OUTPUT); // hydraulic boom down
  pinMode (boomUpPin, OUTPUT); // hydraulic boom up

  pinMode (boomInPin, OUTPUT); // hydraulic boom in
  pinMode (boomOutPin, OUTPUT); // hydraulic boom out

  pinMode (headRotRPin, OUTPUT); // rotor head rotate
  pinMode (headRotLPin, OUTPUT); // rotor head rotate

  pinMode (dumpValvePin, OUTPUT); // hydraulic oil dump valve - must be open when any other function is in use
}

void loop() 
{
  val = digitalRead(pbuttonPin);
  if (val == HIGH && lightON == LOW) 
  {
    pushed = 1 - pushed;
    delay(100);
  }
  lightON = val;
  if (pushed == HIGH) 
  {
    Serial.println("Light ON");
    digitalWrite(relayPin, LOW);
  } 
  else 
  {
    Serial.println("Light OFF");
    digitalWrite(relayPin, HIGH);
  }

  int xValue = analogRead(joyX);
  int yValue = analogRead(joyY);
  int zValue = analogRead(joyZ);

  bool functionInUse = false;
  
  if ( xValue > 550)
  {
    digitalWrite(dumpValvePin, LOW);
    digitalWrite(boomDownPin, HIGH);
    functionInUse = true;
  }
  else 
  {
    digitalWrite(boomDownPin, LOW);
  }

  if ( xValue < 470)
  {
    digitalWrite(dumpValvePin, LOW);
    digitalWrite(boomUpPin, HIGH);
    functionInUse = true;
  }
  else 
  {
    digitalWrite(boomUpPin, LOW);
  }

  if ( yValue > 550)
  {
    digitalWrite(dumpValvePin, LOW);
    digitalWrite(boomInPin, HIGH);
    functionInUse = true;
  }
  else 
  {
    digitalWrite(boomInPin, LOW);
  }

  if ( yValue < 470)
  {
    digitalWrite(dumpValvePin, LOW);
    digitalWrite(boomOutPin, HIGH);
    functionInUse = true;
  }
  else 
  {
    digitalWrite(boomOutPin, LOW);
  }

  if ( zValue > 550)
  {
    digitalWrite(dumpValvePin, LOW);
    digitalWrite(headRotLPin, HIGH);
    functionInUse = true;
  }
  else 
  {
    digitalWrite(headRotLPin, LOW);
  }

  if ( zValue < 470)
  {
    digitalWrite(dumpValvePin, LOW);
    digitalWrite(headRotRPin, HIGH);
    functionInUse = true;
  }
  else 
  {
    digitalWrite(headRotRPin, LOW);
  }

  if (!functionInUse) 
  {
    // No function is in use
    digitalWrite(dumpValvePin, HIGH);
  }

  delay(50);
}

Why no use a variable to determine if you need your dump value on or not rather than re-reading all the pins?

#define joyX A0;
#define joyY A2;
#define joyZ A5;

int pbuttonPin = 2;
int relayPin = 12;
int val = 0;
int lightON = 0;
int pushed = 0;

void setup() {

  Serial.begin(9600);

  pinMode(pbuttonPin, INPUT_PULLUP);
  pinMode(relayPin, OUTPUT); //diverter valve to swap to swing control

  pinMode (11, OUTPUT); // hydraulic boom down
  pinMode (10, OUTPUT); // hydraulic boom up

  pinMode (9, OUTPUT); // hydraulic boom in
  pinMode (8, OUTPUT); // hydraulic boom out

  pinMode (7, OUTPUT); // rotor head rotate
  pinMode (6, OUTPUT); // rotor head rotate

  pinMode (4, OUTPUT); // hydraulic oil dump valve - must be open when any other function is in use

}

void loop() {

  val = digitalRead(pbuttonPin);
  if (val == HIGH && lightON == LOW) {
    pushed = 1 - pushed;
    delay(100);
  }
  lightON = val;
  if (pushed == HIGH) {
    Serial.println("Light ON");
    digitalWrite(relayPin, LOW);
  } else {
    Serial.println("Light OFF");
    digitalWrite(relayPin, HIGH);
  }

  int xValue = analogRead(A0);
  int yValue = analogRead(A2);
  int zValue = analogRead(A5);
  bool needDumpOn = false;
  
  if ( xValue > 550)
  {
    digitalWrite(11, HIGH);
    needDumpOn = true;
  }
  else {
    digitalWrite(11, LOW);
  }

  if ( xValue < 470)
  {
    digitalWrite(10, HIGH);
    needDumpOn = true;
  }
  else {
    digitalWrite(10, LOW);
  }

  if ( yValue > 550)
  {
    digitalWrite(9, HIGH);
    needDumpOn = true;
  }
  else {
    digitalWrite(9, LOW);
  }

  if ( yValue < 470)
  {
    digitalWrite(8, HIGH);
    needDumpOn = true;
  }
  else {
    digitalWrite(8, LOW);
  }

  if ( zValue > 550)
  {
    digitalWrite(6, HIGH);
    needDumpOn = true;
  }
  else {
    digitalWrite(6, LOW);
  }

  if ( zValue < 470)
  {
    digitalWrite(7, HIGH);
    needDumpOn = true;
  }
  else {
    digitalWrite(7, LOW);
  }

  if (!needDumpOn) {
    digitalWrite(4, LOW);
  }  // This is the part that I think is causing the issue.
  else {
    digitalWrite(4, HIGH);
  } // would anyone know a better way of coding it?

  delay(50);
}

OOPS! pin 4 is LOW true, never mind. :-[
How 'bout:

   if((PINB & 0x0F) | (PIND & 0xC0)) // if any of pins 6,7,8,9,10,11
                                    // is HIGH
     digitalWrite(4,LOW);
   else
     digitalWrite(4,HIGH);

How are the valves switched (relays or transistors)? Do you have kickback suppressors on the valves?

Hi hedley,

this code should work very good. So I suspect an electrical problem.
Did you clearly see directional valve gets activated but lock/dump-valve gets not activated?
I mean real optical feedback that it happened this way?
Do the valves have a control LED?

How is everything wired? What relay / relay-boards do you use? Where do the relays get their power from?
Do the relays have kick-back-protection-diodes?
Could it be that the relays are under vibration?

Do you have a second Arduino who could be used as a analysing device.In this way:
The output-IO-pin for lock/dump-valve of your joystick-arduino is connected to one input-pin of the analyser-arduino
Over an optocoupler the 24V-voltage is feeded into a second IO-pin of the analyser-arduino.
The analyser-arduino runs a program whenever the two IO-pins don't have the values expected within a few milliseconds send a serial message and/or count up a variable.
This would show if the relays does really switch its contact or not

Another idea is if your joystick is at the edge of the condition for example Value > 550 and is jumping above/below this value this would create a quick sequence of on/off-switching the dump/lock-valve which it may not likes.

So some additional "analog debouncing" could be added

best regards Stefan

Hi guys,
thank you very much for the replies, just been trying to work through each suggestion.

ToddL - I tried to verify the code and it kept showing an error for missing ")" and no matter which way I tried to rectify this (I am still not great at this coding lark!) it still came up with errors.
but thank you for your input - the dump only needs to open at the same time as the directional valve.

blh64 - I uploaded this sketch to the UNO and tried it on the machine, but it isn't functioning in practice - there seems to be a missing definition of 'needDumpOn= true' linking to 'Pin4' - I haven't had chance to look up what the correct code for this define function is, so I haven't got any further with it yet, but thank you for your input.

-Edit to say- I have just seen the section of code that links needDumpOn to pin4 so my mistake!
there might be a difference between your code being high/low and mine being low/high, which would explain it not working - I am just about to go and trial it again

JCA34F - I haven't had chance yet to try your suggestion yet, I will shortly - thank you

Stefan -

StefanL38:
Did you clearly see directional valve gets activated but lock/dump-valve gets not activated?
I mean real optical feedback that it happened this way?

there is a valve pack on the hedge cutter, consisting of a hydraulic shuttle valve, operated buy a coil to magnetize and 'pull' the shuttle open, with spring return once de-magnetized.

optical - no, audible - yes! there is a distinctive 'snick' noise when the shuttle moves and you can hear the difference between the dump valve and a directional valve, also its easy to pull the wire off the directional valve to only hear the dump noise.

the reason I have thought the software at fault, is that when I put a multimeter on the dump coil, the times when the fault happens, there is no voltage coming to the dump valve - so I checked back inside my enclosure at the relays and when the fault happens, there is no power coming from the relay. I didn't get as far as knowing if the relay was switching at that point, I presumed it wasn't, but I must go back and check

StefanL38:
How is everything wired? What relay / relay-boards do you use? Where do the relays get their power from?
Do the relays have kick-back-protection-diodes?
Could it be that the relays are under vibration?

wiring - I have one 12v 20amp switched, fused, feed entering my enclosure from the tractor, and a live 'pin' (M4 bolt attached to the base of the enclosure) that everything is fed from. The UNO is fed from a DC-DC converter putting out 5v, 5A.

the 8 relay board module is a basic one bought from eBay, I have a spare as it was a pack of two, so I can swap this out if needed.
the 12v power to the relays are all connected in series - with both ends connected to the 12v pin, so its a loop of 8 relays with both ends connected to 12v (so the last relay isn't deprived of power if several earlier ones are consuming power)
the dump relay is the last relay, so also directly connected to 12v.

I have not added any kick-back-protection-diodes - I didn't think they would be needed

there is a possibility of vibration, but sometimes it works perfectly and sometimes it does not, so I am less inclined to think that is the cause - yes the tractor does vibrate, but it is running at a constant engine rpm to create the correct PTO rpm to run the flail hydraulics (completely separate system to these controls), so it should be creating a constant vibration when the problem is not constant - also the problem occurs when the tractor is not running, when I was testing with the multimeter, the engine was not running and I was still getting 0v at the coil & relay.

No, I don't have a second Arduino I can use

StefanL38:
Another idea is if your joystick is at the edge of the condition for example Value > 550 and is jumping above/below this value this would create a quick sequence of on/off-switching the dump/lock-valve which it may not likes.

So some additional "analog debouncing" could be added

This is a strong possibility, I just have no idea how to write the code to do this - maybe if the dump stayed open for half a second after the joystick returns to the center position? - I just have no clue how I would do it.

thanks again for your help everyone - it is much appreciated!

I have not added any kick-back-protection-diodes - I didn't think they would be needed

You should have these for the valve solenoids if only to extend the life of the relay contacts. Avoid heavy current carrying conductors near signal wires - definitely not in the same bundle. If it's unavoidable route them at ninety degrees to each other.

hedley:
ToddL - I tried to verify the code and it kept showing an error for missing ")" and no matter which way I tried to rectify this (I am still not great at this coding lark!) it still came up with errors.
but thank you for your input - the dump only needs to open at the same time as the directional valve.

Change:

#define joyX A0;
#define joyY A2;
#define joyZ A5;

to:

#define joyX A0
#define joyY A2
#define joyZ A5

Right! I have the issue sorted now (I think!)

After all that messing with the software, I went back checking and double checking the hardware.
The fault is with the relay for the dump valve on the 8x relay board.
For every joystick operation, the LED connected to it works as it should, and the relay clicks as it should, but it does not always provide power out the contact!
So as dougp has said, maybe I should put some diode’s in place to stop and the ‘kick back current’

Thanks a lot for everything lads!

Just a quick update - its was working great for a couple of days, then started to give trouble and then stopped working altogether!
I quickly realised that I only had about 6v at the hydraulic valve coils, and the cause was my relays have burned out!
I did work it out before I built the system that they would only be pulling about 2.5A, so they shouldn't have burned out that fast, however I didn't have the kick-back diodes in from the start, so the damage may have been done before I fitted them and has just deteriorated since.

I have another identical 8 relay board that I'm about to fit, but have ordered (what I think is) a better quality 8 relay board that will be here next week - fingers crossed!

thanks again for your help lads.

You get what you pay for when it comes to relays. Those cheap 2,4,8 up relay boards will not last. Going to SSR will cost more, but are more suited for industrial use.

the 12v power to the relays are all connected in series

You REALLY need to post a wiring diagram.

Those cheap 2,4,8 up relay boards will not last. Going to SSR will cost more, but are more suited for industrial use.

SSR (short for Solid State Relay) are pure semiconductor devices with no mechanical parts at all. So there is nothing inside a SSR that could "wear out"

Solenoids are inductive devices so voltage-spikes will always occur on switching off the current and must be supressed through using kick-back-protection diodes.

I guess some SSR are designed for use with inductive loads . If the datasheet clearly states something like

"integrated protection-diodes - suitable for use with inductive loads" and if there is room left in the amperage specs You wrote one solenoid has a current of 2.5A a SSR for 4A or some more will fit.

such a SSR should work with a high reliablity.

best regards Stefan