RC Failsafe

Hi

Does anyone have some code for reading input from a RC receiver that will trigger a failsafe function? I know exactly what I want to happen as a result of a failsafe function, but don’t know what code should be used. Clearly it must notice when the signal becomes static?

I am using the <PinChangeInt.h> and the <Servo.h> libraries.

Any ideas gratefully received.

John

Hi

To make this clear, I want the failsafe to begin a function 4 seconds following the transmitter being turned off. Didn't make that clear :slight_smile:

use pulseIn to read one of the rx signals.
Your tx is always sending out signals right: It is a timed pulse.
So, if your arduino does not see ANY pulse on your input pin for a certain length of time; there is an issue, and go to failsafe.
for example;
I have 4 channels from my rx tied to my arduino. all four WILL get a pulse. So, just pick one of them, and throw a little if/then into the code:
rcSignal = pulseIn(channel,HIGH, 20000); // 20000 should see something in that time range!

if (rcSignal<100 || rcSignal>5000); // no signal or weird signal!
{ failsafe();}

Hi

What I find is that if I turn the Tx off, the signal, whatever it is, remains frozen at that level. Therefore the failsafe isn't likely to work. What else should I measure?

There may not be a simple solution if you only have access to the output from the receiver and if the receiver does not take any distinctive action when it loses the signal from the transmitter.

A lot will depend on whether, in normal operation, the receiver outputs would remain constant for the period of 4 seconds that you want to use as your failsafe margin.

If it is never the case that the outputs remain constant for that time then you could use millis() to manage a timer. You will need some code that notices when a value changes and when that happens it resets the timer. If there is no change in the outputs the timer will run to completion and trigger the failsafe. You may or may not need to monitor changes on all channels and reset the timer whenever any one of them changes.

...R

It sounds like your rc receiver has a failsafe built in. What type of rc receiver is it? surface or air?

Most receivers will continue to output the last known good transmission for a few cycles, but not for very long.
However, most rc air receivers can be programmed to perform a failsafe condition on loss of tx signal. If you have one like that, then you could program an unused rc channel to go to minimum, and watch that channel for your failsafe.
Do you follow me?

most rc air receivers can be programmed to perform a failsafe condition on loss of tx signal. If you have one like that, then you could program an unused rc channel to go to minimum, and watch that channel for your failsafe.

If the receiver has the ability to recognise that the Tx signal has been lost then it is almost certain that it can be set to move any/all of the channels to preset positions which is surely the whole point of failsafe.

A common way to set the failsafe condition is to bind the Rx to the Tx with the controls in the failsafe positions but let's wait and see which Rx the OP has.

I fly helis too!
I was making the basic asumption he did not want to use the rc failsafe in that manner.
He might not be using 2.4ghz, either. But i recall that some of the old hitec and fubata 72mhz could be programmed for failsafe( for planes, anyways!) however, I can't think of any surface rx's that have a failsafe. Myself, I use both 72 mhz and 2.4ghz for my stuff.And, with my helis, failsafe is not activated.

Hi

yes and yes. I will be using a 36 mhz 7 channel system, which works well for subs. While I am building however I am using a 2.4 which I have spare. what I have found is that the 2,4 ‘freezes’ when the Tx is turned off on whatever signals it has, however the old 36 goes crazy, just what I would prefer.

However, despite all cajoling the following code fires the relay immediately and it stays on. (note the relay fires on ‘low.’)

#include <Servo.h>

#define FAILSAFE_MS 1000    //stop sketch if no data received in this many milliseconds


int servopin = 3;
Servo myservo;
int PISTON_DIVE_PIN = 6;

void setup()
{
    Serial.begin(9600);
    myservo.attach(servopin);
    pinMode(PISTON_DIVE_PIN, OUTPUT);
    
}

void loop()
{
    static unsigned long msLastRX;        //time of most recent reception
    
    if (Serial.available()){
        int servoAng = Serial.read();
        myservo.write(servoAng);
        msLastRX = millis();
    }
    
    if (millis() - msLastRX >= FAILSAFE_MS) {
        digitalWrite(PISTON_DIVE_PIN, LOW); //do whatever you need here
        while (1);        //stops the sketch
    }
}

Moderator edit: code tags corrected

Further to that, I am using the 36 and it triggers the relay when the Tx is OK and on

However, despite all cajoling the following code fires the relay immediately and it stays on. (note the relay fires on 'low.')

Well, if there is no Serial data available then msLastRX is going to be zero, so millis() will exceed 1000 a second later and the relay will turn on and the infinite while loop will be entered. This seems to be what you are describing.

Just out of interest what range of numbers are you expecting to receive on the serial interface and where from ?

Hi

With this last sketch, I boot up with the transmitter on, and the relay fires and stays 'on'. It is triggering with the Tx on. The range of numbers I am getting off is anywhere between 1-2000.

John

On a semi related note, the Futaba SBUS protocol does indicate lost link and failsafe from the RX, but I'm not sure if they have 36Mhz units that support SBUS as I've only used the 2.4 stuff. It's also a fairly simple inverted 115200 serial connection so decoding it is pretty easy

OK

I have an early and less complicated script attached. I have added some lines from one of you. The lines I have added are at 17, and 149-161.

If I disable these lines and use my 36 MHZ Tx and Rx and measure the signal of ‘unballastin’ (line 173) I get a nice even spread from 1220 – 1820, as to be expected. When I turn the Tx off, this goes crazy all over the place.

With the Tx ON, when I activate the added lines, (and pls note that LOW triggers a relay), it waits for 8 seconds ( I made it 8) and while the 8 seconds are passing unballastin works perfectly, then when 8 seconds are past the reading freezes on whatever it was, and the relay is triggered.

What I want is for nothing to happen, obviously, until the Tx is turned off. Then I want to have the wait and the relay turns on following the Tx going off.

My plan is that when I have a gap of say 4 seconds of random noise from the Rx as a result of the Tx going off, all the relays will go off other than the one that brings the sub to the surface.

It seems there must be something wrong with this code as it is. Any help??

subsketchlatestfailsafe.ino (12.3 KB)

Not part of your problem with failsafe, but in this portion of code

       int servoAng = Serial.read();
        servoBallast.write(servoAng);

what range of values do you expect to get in servoAng ?

Under normal operation 1200-1800, but when disconnected between 0 - 2000. How should that be represented in the code?

Try this and you will see that it is not doing what you think

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  if (Serial.available())
  {
    int servoAng = Serial.read();
    Serial.println(servoAng);
  }
}

This is better

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  if (Serial.available())
  {
    int servoAng = Serial.parseInt();
    Serial.println(servoAng);
  }
}

but still not perfect.

Hi

Not sure here what to expect but I see nothing in the serial monitor??

John

Does the baud rate in the monitor match that in the sketch ?

Yes I changed the baud rate and nothing…

More to the point. Is there something I need to add in this code to recognize the parameters I mentioned above. it shuts everything down and starts the relay as I want, but does it immediately, whether or not the Tx is off or on. And when the Tx is off the input is crazy, so it should work. i have the feeling I am nearly there…

#include <Servo.h>

#define FAILSAFE_MS 1000 //stop sketch if no data received in this many milliseconds

int servopin = 3;
Servo myservo;
int PISTON_DIVE_PIN = 6;

void setup()
{
Serial.begin(9600);
myservo.attach(servopin);
pinMode(PISTON_DIVE_PIN, OUTPUT);

}

void loop()
{
static unsigned long msLastRX; //time of most recent reception

if (Serial.available()){
int servoAng = Serial.read();
myservo.write(servoAng);
msLastRX = millis();
}

if (millis() - msLastRX >= FAILSAFE_MS) {
digitalWrite(PISTON_DIVE_PIN, LOW); //do whatever you need here
while (1); //stops the sketch
}
}