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.
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: