8 Channel switches over one DO_SET_SERVO channel

Last weekend I managed successfully the DO_SET_SERVO option for the first time, turning a bright LED-spotlight on and off on my ArduBoat when reaching certain waypoints. I thought of the possibilities of utilizing only one servo-output channel for controlling up to 8 switches/relays ON/OFF.

So I wrote a simple Arduino Code for switching 8 outputs depending on the PWM-input in microseconds. The code pulls the output-pin LOW to activate a cheap Arduino relay. There are 1,2,4 and 8 relay-boards as far as I know, ready to be used. I ordered them but haven’t received them yet. I’ll update this blog post with results. (I think you can set the relay boards to either being triggered by a HIGH or LOW input, depending on jumper-settings. Otherwise I’ll adjust the code accordingly)

The idea is setting a certain PWM-value for the DO_SET_SERVO-channel of your flightcontroller which is connected to the Arduino, in the Plan-tab in Missionplanner. Thus, when the DO_SET_SERVO is utilized when reaching that waypoint, a desired relay is switched.

For example:

DO_SET_SERVO, ch6 = 1100, relay 1 is switched. All others are OFF
DO_SET_SERVO, ch6 = 1500, relay 4 is switched, All others are OFF
DO_SET_SERVO, ch6 = 1800, relay 8 is switched, All others are OFF and so on.

Code:

const int pwmInputPin = A0;
const int numOutputs = 8;
const int outputPins[numOutputs] = {3, 4, 5, 6, 7, 8, 9, 10};
const unsigned long timeoutThreshold = 1000000;  // Timeout threshold in microseconds (1 second)
const unsigned long hysteresisThreshold = 20;  // Hysteresis threshold in microseconds

void setup() {
  pinMode(pwmInputPin, INPUT);
  for (int i = 0; i < numOutputs; i++) {
    pinMode(outputPins[i], OUTPUT);
    digitalWrite(outputPins[i], HIGH);  // Set all outputs HIGH initially
  }
}

void loop() {
  unsigned long pwmDuration = pulseIn(pwmInputPin, HIGH);

  if (pwmDuration > 0) {
    // PWM signal detected
    for (int i = 0; i < numOutputs; i++) {
      if (pwmDuration >= 1000 + i * 100 && pwmDuration <= 1100 + i * 100) {
        if (pwmDuration > (1000 + i * 100 + hysteresisThreshold) || pwmDuration < (1100 + i * 100 - hysteresisThreshold)) {
          digitalWrite(outputPins[i], LOW);
        }
      } else {
        digitalWrite(outputPins[i], HIGH);
      }
    }
  } else {
    // No PWM signal detected, set all outputs HIGH
    for (int i = 0; i < numOutputs; i++) {
      digitalWrite(outputPins[i], HIGH);
    }
  }

  delay(10);  // Optional delay to avoid rapid checking, adjust as needed
}

Next step (not too difficult), is writing another piece of code outputting certain PWM-values on the 8 outputs so you can set 8 servo’s or ESC’s or whatever accepts PWM-pulses in a desired position. For those who don’t want relays but pwm-related gear. Or a mix of 4 relays and 4 PWM-fixed-outputs. :slight_smile:

Edit:

Found two 2-way relays in a box, before I got my order from AliX. So for demonstration purposes only 4 outputs are currently activated:

1 Like