Jump to content

DCS BIOS and controlling a solenoid


Studsmcgee

Recommended Posts

So first timer here with DCS BIOS

Short version is I want a switched action in DCS (huey idle stop button) to activate a solenoid.

 

Like I said first time doing this. 

I got the button working through my arduino nano (just two leads that I touch together to simulate a momentary switch)

 

Next I'm using a single channel MOSFET board to control the solenoid.

I have the ground connected to a ground on the Nano

I have the Signal from the MOSFET connected to a digital pin on the nano

And the VCC is connected to a 5V pin on the nano.

 

The VIN and GND lugs on the board are connected to a 12V adapter and the V+ and V- lugs go to the solenoid leads.

When I touch the leads to activate the button in DCS the LED on the MOSFET board also turns on. So I got that far at least.

 

The issue is that as soon as i plug the 12V power in the "button" stops working and the solenoid activates and the idle stop command does not switch the solenoid off.

I used a code example from The Warthog Project as he recently used a similar setup to run his DIY magnetic switches. I thought this would work the same way but now I'm not sure. 

 

Here is the Code I have:

/*
  Tell DCS-BIOS to use a serial connection and use interrupt-driven
  communication. The main program will be interrupted to prioritize
  processing incoming data.
  
  This should work on any Arduino that has an ATMega328 controller
  (Uno, Pro Mini, many others).
 */
#define DCSBIOS_IRQ_SERIAL

#include "DcsBios.h"

/* paste code snippets from the reference documentation here */

int ThrottleStop_Solenoid = 2;


DcsBios::Switch2Pos throttleStop("THROTTLE_STOP", 3);

void onThrottleStopChange(unsigned int newSolenoidValue) {
  switch (newSolenoidValue){
    case 0:
    digitalWrite(ThrottleStop_Solenoid, LOW);
    break;
    case 1:
    digitalWrite(ThrottleStop_Solenoid, HIGH);
    break;
  }
}
DcsBios::IntegerBuffer throttleStopBuffer(0x14be, 0x0008, 3, onThrottleStopChange);


void setup() {
  DcsBios::setup();
  pinMode (ThrottleStop_Solenoid, OUTPUT);
}

void loop() {
  DcsBios::loop();
}

 

 

I don't know much about how the code works but it currently works for the momentary press of the idle stop button, and it sends some kind of signal to the MOSFET board because the led lights up. Beyond that I don't know what to try.

 

I'd appreciate any tips or code examples.

Thanks!

 

Link to comment
Share on other sites

Which particular MOSFET board are you using?

The first thing I'd do is eliminate DCS-BIOS as a problem.

Try this:

const int ThrottleStop_Solenoid = 2; //const int is for the coding only
const int button = 3;  // It doesn't use device memory


void setup() {
  pinMode (ThrottleStop_Solenoid, OUTPUT);
  pinMode (button, INPUT_PULLUP);
}

void loop() {
  digitalWrite (ThrottleStop_Solenoid,!digitalRead(button));
  digitalWrite (13,!digitalRead(button));  // Makes the built-in LED mimmick the solenoid output
}

That should turn on your solenoid and the arduino's built-in LED when you press a button connected from pin 3 to GND.

 

Link to comment
Share on other sites

10 hours ago, No1sonuk said:

I have some of those drivers, but I've not used them yet.  However, all the drawings I've seen of their use show no connection to VCC.  Try removing that.

Appreciate the tip. 

I tried your code example and it does indeed light up the led. When I have 12v connected to the MOSFET the solenoid actuates and stays on regardless of the button position. I removed the VCC connection and got the same result.

I just don't know what I need to tell the MOSFET to switch the 12v power on and off.

I wish I knew more about the code so I could try more things.

 

Link to comment
Share on other sites

OK. It might be nothing to do with the code...

Have you got another one of those boards?
It seems to me like the MOSFET itself (the transistor) is possibly faulty.

Take a look at the schematic attached.

It's a very simple circuit.

Your solenoid should be where the motor is shown.
With 12V connected to the VIN terminal, 5V on SIG on the input side should turn on the solenoid.
Removing the 5V input ( or grounding that pin like an arduino output would ) should turn off the MOSFET.

How it works:
The LED with 1K resistor in series gives an indication that the input is receiving a voltage.
The other 1K resistor pulls the input low to turn off the MOSFET when no signal is present, but is easily overridden by a voltage on the SIG input.
There's nothing in the circuit that could turn on the MOSFET without a voltage present on the SIG input.
This means that if the solenoid is turned on as soon as you connect the 12V, with no input connection, you have a faulty MOSFET.
And FYI, the common fault state for MOSFETs is on.

IRF520_module.jpg

  • Like 1
Link to comment
Share on other sites

3 hours ago, Studsmcgee said:

I wired the 12v input with the - side as ground and the + side as VIN. Is that correct?

That's correct.

Disconnect it from the arduino.  Only connect the solenoid and 12V.  The solenoid should be off.
If that's OK:
Connect the arduino GND to the MOSFET input GND, and use a 5V line from the arduino (not a signal line) to trigger the MOSFET either with a switch, or just touching the wire.
If the MOSFET turns on and off when you connect and disconnect the 5V line, the MOSFET is OK.

If all that works, try loading the "blink" example sketch and connect the arduino pin 13 (the LED) to the MOSFET signal input line.
That should turn the MOSFET on and off with the LED.

Link to comment
Share on other sites

Ok so this is interesting. If I disconnect the arduino and only have the 12v and solenoid hooked up the solenoid actuates when the 12v is applied. 

Does that indicate a faulty mosfet?

I tried the next step just incase and the 5v from the arduino applied to the signal input of the mosfet lights up the mosfet led but does not affect the solenoid.

 

Link to comment
Share on other sites

Yup. To me (electronics engineer) that indicates a faulty MOSFET.

Do you have a meter you can measure resistance with?
With nothing connected at all, the resistances I get are:
Black lead on V- (output), Red Lead on GND (12V terminals) = too high for the meter to read ("OL") on my meter.
Red lead on V- (output), Black Lead on GND (12V terminals) = 8.3Mohms

If either of those are significantly lower, you have a faulty MOSFET.

BTW, I just tried the "disconnected from arduino signal" thing I described above on one of my modules like yours.  It worked exactly as I described it should.


Edited by No1sonuk
Link to comment
Share on other sites

Yup. Seems like the MOSFET is faulty.

Though I had expected the 15 M ohms to be much lower. More like 0.5 ohms.

Did you include a diode reversed across the solenoid?  This kills the back-EMF generated by the coil closing down. It might have killed the MOSFET if the coil is big enough and it worked once or twice.

Try getting it working using a light bulb first. There's no danger of that killing a MOSFET with a back-EMF.

Link to comment
Share on other sites

I have lots of experience operating 12V solenoid valves from Arduinos, but I use relays instead of MOSFET.  But its basically the same principle.  Are you powering both the solenoid and the Arduino from the same power source?  If so, the current draw from the solenoid could actually be starving the Arduino and may cause it to reset.  I've had problems with this in the past and will often provide a separate, isolated power supply to the solenoid valves so that current draw does not affect the Arduino.  I've run as many as 16 rapid fire 5-way pneumatic solenoid valves off a single Arduino, but isolated power supply is a must for that.  The current draw from the relays was also a problem, so I use a separate 5V regulator that is fed from the same power source going to the Arduino.  The grounds are connected between that separate 5V regulator and the Arduino (necessary in order for the digital IO signal to work with the relay boards).  I should point out these relay boards use opto isolators and flyback diodes for the relays.  I would have to add those things if I were going to use a raw relay.  And for the record, I have controlled a solenoid from an Arduino directly, using a TIP transistor.

Here's a demo without solenoids connected:

 


Edited by Xpendable
Link to comment
Share on other sites

31 minutes ago, Xpendable said:

Are you powering both the solenoid and the Arduino from the same power source?  If so, the current draw from the solenoid could actually be starving the Arduino and may cause it to reset. 

If you read a couple of posts above, you'll see he's having trouble with the MOSFET not working properly even when it's not connected to an Arduino.

Link to comment
Share on other sites

On 1/25/2022 at 1:48 PM, No1sonuk said:

Yup. Seems like the MOSFET is faulty.

Though I had expected the 15 M ohms to be much lower. More like 0.5 ohms.

Did you include a diode reversed across the solenoid?  This kills the back-EMF generated by the coil closing down. It might have killed the MOSFET if the coil is big enough and it worked once or twice.

Try getting it working using a light bulb first. There's no danger of that killing a MOSFET with a back-EMF.

I am having similar trouble and may have toasted a MOSFET due to back EMF.  Would you nominate a diode (to order - AliExpress maybe) and add it to your circuit diagram for clarity, please?  I am using the 4 channel version of the same board as @Studsmcgee, and have single channel version on order.  

DCS:Bios - I am also very new to C++ and DCS Bios.  My controls are combined with other controls of the Left Hand Rear Panel of the F-18.  So, I am intending Coils for; APU, Crank Left, Crank Right and Fuel Dump switches.  Hence the 4 Channel MOSFET board.  I am also working on the Launch Bar and Hook Bypass switches.  

For these I need to detect the Release conditions:

All switches - Loss of all electrical power to the aircraft. It is hard to identify which combination of Batt, L Gen & R Gen causes each switch to release.  

APU - “Returns to OFF 1 minute after the second generator comes on the line provided the bleed air knob is not in AUG PULL.”

Crank Left & Right - Engine reaching “self-sustaining rpm” (I am assuming >60% Ng)

Fuel Dump - “BINGO” signal, “FUEL LO” signal and I am researching anything else.  

Launch Bar - “At the completion of the catapult stroke, launch bar/catapult separation occurs and the return springs cause launch bar retraction …”.  So we can detect this with Weight on Wheels maybe. I don’t know if WonW is a DCS Bios signal! Or Gear up (which is a bit backwards)!!!

Hook Bypass - “… automatically goes to CARRIER when the arresting hook is lowered or aircraft power is removed.”

I have yet to consider the four Ground Power switches or the Laser Arm switch.  


Edited by Gosling
Link to comment
Share on other sites

5 hours ago, Gosling said:

I am having similar trouble and may have toasted a MOSFET due to back EMF.  Would you nominate a diode (to order - AliExpress maybe) and add it to your circuit diagram for clarity, please?  I am using the 4 channel version of the same board as @Studsmcgee, and have single channel version on order.  

Have a look here:
http://robojax.com/node/912
There's a version of the schematic with the diode in place.
Just remember that it's placed "the wrong way round" - pointing up.
This is so that it won't conduct when the coil is turned on, but it will basically short-circuit the back-EMF when the coil is turned off.

The switches thing is a bit more complicated.
I've been grappling with a similar thing WRT the bomb, gear and flaps levers of the Mosquito.
The problem is that DCS-BIOS overrides the game's control of switches - if it's held on by DCS-BIOS, the game can't override it.
This is a problem for switches and controls that the game needs to change automatically.
So, my current plan is a kind of hybrid device.
My THEORY so far (untested):
The Pro Micro and Leonardo can act as joystick devices. You can program them so that the computer sees them as a keyboard or joystick, then you bind the buttons in DCS. A Leo Bodnar board could also be used for the switch input.
Then you use DCS-BIOS to read the game's position of the switch and turn on the holding coil.
Theoretically, this should make the coil automatically hold the switch when you turn it on, and then release it when the game wants to.

So how to read the switches?
Switch the control reference view to "advanced" and you'll see output code lines.
For the F-18 APU, you get this:

void onApuControlSwChange(unsigned int newValue) {
    /* your code here */
}
DcsBios::IntegerBuffer apuControlSwBuffer(0x74c2, 0x0100, 8, onApuControlSwChange);

Or this:

DcsBios::LED apuControlSw(0x74c2, 0x0100, PIN);

Now I THINK you could use the "LED" code line to drive this switch's coil as it only has one position.

The 3-position crank one has this:

void onEngineCrankSwChange(unsigned int newValue) {
    /* your code here */
}
DcsBios::IntegerBuffer engineCrankSwBuffer(0x74c2, 0x0600, 9, onEngineCrankSwChange);

and further up it says the expected values are "0 = held left/down, 1 = centered, 2 = held right/up"
You then put some code where it says "/* your code here */" that interpret the number.
e.g:

void onEngineCrankSwChange(unsigned int newValue) {

 switch (newValue) {
  case 0:
    // Held left/down
    digitalWrite (CrankLeftHold, HIGH); // Turn on left hold coil
    digitalWrite (CrankRightHold, LOW); // Turn off right hold coil
    break;
  case 1:
    // centred
    digitalWrite (CrankLeftHold, LOW); // Turn off left hold coil
    digitalWrite (CrankRightHold, LOW); // Turn off right hold coil
    break;
  case 2:
    // Held right/up
    digitalWrite (CrankLeftHold, LOW); // Turn off left hold coil
    digitalWrite (CrankRightHold, HIGH); // Turn on right hold coil
    break;
  default:
    // failsafe
    digitalWrite (CrankLeftHold, LOW); // Turn off left hold coil
    digitalWrite (CrankRightHold, LOW); // Turn off right hold coil
    break;
 }

}
DcsBios::IntegerBuffer engineCrankSwBuffer(0x74c2, 0x0600, 9, onEngineCrankSwChange);


NOTEs:
My code is written without testing - I am no arduino expert and I don't have the F-18.
The DCS-BIOS code comes from the Flightpanels fork control reference, and so some parts may not work in Hub.


Edited by No1sonuk
Typo in my text
Link to comment
Share on other sites

L

16 hours ago, No1sonuk said:

Have a look here:
http://robojax.com/node/912
There's a version of the schematic with the diode in place.
Just remember that it's placed "the wrong way round" - pointing up.
This is so that it won't conduct when the coil is turned on, but it will basically short-circuit the back-EMF when the coil is turned off.

The switches thing is a bit more complicated.
I've been grappling with a similar thing WRT the bomb, gear and flaps levers of the Mosquito.
The problem is that DCS-BIOS overrides the game's control of switches - if it's held on by DCS-BIOS, the game can't override it.
This is a problem for switches and controls that the game needs to change automatically.
So, my current plan is a kind of hybrid device.
My THEORY so far (untested):
The Pro Micro and Leonardo can act as joystick devices. You can program them so that the computer sees them as a keyboard or joystick, then you bind the buttons in DCS. A Leo Bodnar board could also be used for the switch input.
Then you use DCS-BIOS to read the game's position of the switch and turn on the holding coil.
Theoretically, this should make the coil automatically hold the switch when you turn it on, and then release it when the game wants to.

So how to read the switches?
Switch the control reference view to "advanced" and you'll see output code lines.
For the F-18 APU, you get this:

void onApuControlSwChange(unsigned int newValue) {
    /* your code here */
}
DcsBios::IntegerBuffer apuControlSwBuffer(0x74c2, 0x0100, 8, onApuControlSwChange);

Or this:

DcsBios::LED apuControlSw(0x74c2, 0x0100, PIN);

Now I THINK you could use the "LED" code line to drive this switch's coil as it only has one position.

The 3-position crank one has this:

void onEngineCrankSwChange(unsigned int newValue) {
    /* your code here */
}
DcsBios::IntegerBuffer engineCrankSwBuffer(0x74c2, 0x0600, 9, onEngineCrankSwChange);

and further up it says the expected values are "0 = held left/down, 1 = centered, 2 = held right/up"
You then put some code where it says "/* your code here */" that interpret the number.
e.g:

void onEngineCrankSwChange(unsigned int newValue) {

 switch (newValue) {
  case 0:
    // Held left/down
    digitalWrite (CrankLeftHold, HIGH); // Turn on left hold coil
    digitalWrite (CrankRightHold, LOW); // Turn off right hold coil
    break;
  case 1:
    // centred
    digitalWrite (CrankLeftHold, LOW); // Turn off left hold coil
    digitalWrite (CrankRightHold, LOW); // Turn off right hold coil
    break;
  case 2:
    // Held right/up
    digitalWrite (CrankLeftHold, LOW); // Turn off left hold coil
    digitalWrite (CrankRightHold, HIGH); // Turn on right hold coil
    break;
  default:
    // failsafe
    digitalWrite (CrankLeftHold, LOW); // Turn off left hold coil
    digitalWrite (CrankRightHold, LOW); // Turn off right hold coil
    break;
 }

}
DcsBios::IntegerBuffer engineCrankSwBuffer(0x74c2, 0x0600, 9, onEngineCrankSwChange);


NOTEs:
My code is written without testing - I am no arduino expert and I don't have the F-18.
The DCS-BIOS code comes from the Flightpanels fork control reference, and so some parts may not work in Hub.

 

Thanks. I will try this out. We will slowly get there. !!!

Edit: diodes added

https://drive.google.com/file/d/101dL8J1KsUmTymxrboTi0x-fKPqR-cGt/view?usp=drivesdk


Edited by Gosling
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...