Pages: 1 [2] 3   Go Down
Author Topic: Reading data from RC Receiver trouble with noise  (Read 2167 times)
0 Members and 1 Guest are viewing this topic.
Queens, New York
Offline Offline
Faraday Member
**
Karma: 84
Posts: 3413
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think I understand whats going on here, but to help clearify for everyone else I'll break it down.
When the remote is on, your values are steady, that we know. Now when the remote is off the values go crazy, I may have an explanation for this.

For the normal wiring to just the servos (with the controller on), the servos are steady, but to anyone who owns those kind of RC receivers (any kind, they all do the same thing) when the radio is off, the servos begin to vibrate or twitch. This of course is due to interference, we know that, HOWEVER, because the data is going into the arduino, it takes time for the arduino to process the data. Now most amature programmers, (no offense to lacion or anyone else, just new programmers in general) think that when a program is running, the program is instantaneous, but it is not. The arduino uno/mega is rather slow when it comes to sorting it's data and sending it where it needs to go. But a receiver do not have to sort THAT MUCH data, so it is very quick to respond to a command, and that is where the problem lies.

lacion is getting data from the receiver and is going into the arduino, not fully aware, (again no offense), that the amount of time it takes the arduino to process one command, the receiver has already put out 5 or even 10 commands. SO when the remote is off, those twitchs are not being sampled correctly and because your also sending data to a monitor or LCD, that is even more processing time the arduino has to do before it is able to get a new command. And all that processing time puts out a very, almost seziure like movement, and your values show that on your display.

Now it is a different story when the remote is on, because the data is MUCH more steady and so the arduino appears to be working hand and hand, but really is it still not able to fully catch up.

So the bottom line is, the arduino is unable to fully keep up with the data from the receiver, so now lacion has to take that into consideration, and set limiters, constrain the data and hopefully that will make it work a little better; appear to work better.

Any objections?
« Last Edit: November 19, 2012, 07:54:16 pm by HazardsMind » Logged

Created Libraries:
NPV2 (NewPasswordV2),  TFT_Extension, OneWireKeypad, SerialServo.
Will provide libraries if asked in PM or forum.

Dubai, UAE
Offline Offline
Edison Member
*
Karma: 22
Posts: 1675
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

This is not correct, the arduino is easily able to process rc signal, there are only a few hundred per second.

What is happening is that the servo library will continue to send the last signal you gave it, so if you set it for full speed ahead, that is what it will do. Now if you turn the receiver off, it will still go full speed ahead because now there is nothing to tell it not to.

The code sample i provided will set the throttle to neutral if not valid signals are received for a short period it will also auto recover if a good signal is received.

Looking at the no receiver values i suugest that you build on the code provided with one of the suggestion provided by PeterH which is to count five of six good pulses consecutive pulses before allowing incoming signals to pass out to the channels.

Just out of interest, what transmitter and receiver are you using ?

Duane B
Logged


Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17261
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think I understand whats going on here, but to help clearify for everyone else I'll break it down.
When the remote is on, your values are steady, that we know. Now when the remote is off the values go crazy, I may have an explanation for this.

For the normal wiring to just the servos (with the controller on), the servos are steady, but to anyone who owns those kind of RC receivers (any kind, they all do the same thing) when the radio is off, the servos begin to vibrate or twitch. This of course is due to interference, we know that, HOWEVER, because the data is going into the arduino, it takes time for the arduino to process the data. Now most amature programmers, (no offense to lacion or anyone else, just new programmers in general) think that when a program is running, the program is instantaneous, but it is not. The arduino uno/mega is rather slow when it comes to sorting it's data and sending it where it needs to go. But a receiver do not have to sort THAT MUCH data, so it is very quick to respond to a command, and that is where the problem lies.

lacion is getting data from the receiver and is going into the arduino, not fully aware, (again no offense), that the amount of time it takes the arduino to process one command, the receiver has already put out 5 or even 10 commands. SO when the remote is off, those twitchs are not being sampled correctly and because your also sending data to a monitor or LCD, that is even more processing time the arduino has to do before it is able to get a new command. And all that processing time puts out a very, almost seziure like movement, and your values show that on your display.

Now it is a different story when the remote is on, because the data is MUCH more steady and so the arduino appears to be working hand and hand, but really is it still not able to fully catch up.

So the bottom line is, the arduino is unable to fully keep up with the data from the receiver, so now lacion has to take that into consideration, and set limiters, constrain the data and hopefully that will make it work a little better; appear to work better.

Any objections?

I've been involved with R/C for decades and arduinos for around three years and what you say above makes absolutely no sense to me at all. Not saying what your wrote is wrong or not wrong, just makes no sense. There is nothing about the speed of the arduino that would factor in the symptoms being seen.

 I would strongly suspect that the problem is just that the R/C receiver with no valid RF signal being received (transmitter turned off or out of range) is just randomly generating false intermittent pulses on it's servo output pins due to random RF noise. Keep in mind that such R/C receivers use AGC in their receiver circuitry so when there is no valid RF carrier signal on the frequency channel the receiver's internal gain is at maximum and subject to any random RF noise that might be around. And yes a better receiver design should or could 'clamp' all the servo channel outputs off unless there is some minimum signal level being received, but there is no information of this specific receivers features.

Note that it's standard R/C practice to always first turn on the transmitter, ensure the controls are in the desired position and then turn on the receiver/model. Having a 'hot' receiver on with no valid signal is an invitation for servo glitches.
Lefty
« Last Edit: November 20, 2012, 12:46:46 am by retrolefty » Logged

Dubai, UAE
Offline Offline
Edison Member
*
Karma: 22
Posts: 1675
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Something like this, you will need to declare the variables somewhere in your code but this is the basic idea -

Code:
void loop()
{
  // create local variables to hold a local copies of the channel inputs
  // these are declared static so that thier values will be retained
  // between calls to loop.
  static uint16_t unThrottleIn;
  static uint16_t unSteeringIn;
  static uint16_t unAuxIn;
  // local copy of update flags
  static uint8_t bUpdateFlags;

  static unsigned long ulLastThrottleTime;

  // check shared update flags to see if any channels have a new signal
  if(bUpdateFlagsShared)
  {
    noInterrupts(); // turn interrupts off quickly while we take local copies of the shared variables

    // take a local copy of which channels were updated in case we need to use this in the rest of loop
    bUpdateFlags = bUpdateFlagsShared;
  
    // in the current code, the shared values are always populated
    // so we could copy them without testing the flags
    // however in the future this could change, so lets
    // only copy when the flags tell us we can.
  
    if(bUpdateFlags & THROTTLE_FLAG)
    {
      unThrottleIn = unThrottleInShared;
    }
  
    if(bUpdateFlags & STEERING_FLAG)
    {
      unSteeringIn = unSteeringInShared;
    }
  
    if(bUpdateFlags & AUX_FLAG)
    {
      unAuxIn = unAuxInShared;
    }
    
    // clear shared copy of updated flags as we have already taken the updates
    // we still have a local copy if we need to use it in bUpdateFlags
    bUpdateFlagsShared = 0;
  
    interrupts(); // we have local copies of the inputs, so now we can turn interrupts back on
    // as soon as interrupts are back on, we can no longer use the shared copies, the interrupt
    // service routines own these and could update them at any time. During the update, the
    // shared copies may contain junk. Luckily we have our local copies to work with :-)
  }
 
  // do any processing from here onwards
  // only use the local values unAuxIn, unThrottleIn and unSteeringIn, the shared
  // variables unAuxInShared, unThrottleInShared, unSteeringInShared are always owned by
  // the interrupt routines and should not be used in loop
 
  // the following code provides simple pass through
  // this is a good initial test, the Arduino will pass through
  // receiver input as if the Arduino is not there.
  // This should be used to confirm the circuit and power
  // before attempting any custom processing in a project.
 
  // we are checking to see if the channel value has changed, this is indicated
  // by the flags. For the simple pass through we don't really need this check,
  // but for a more complex project where a new signal requires significant processing
  // this allows us to only calculate new values when we have new inputs, rather than
  // on every cycle.
  if(bUpdateFlags & THROTTLE_FLAG)
  {
    // DB 19/11/2012 added range test and timestamp if valid  - ulLastThrottleTime
    if(unThrottleIn > 1000 && unThrottleIn < 2000)
    {
      if(gMode == MODE_FAIL_SAFE)
      {
       if(sGoodPulseCounter > 6)
       {
        gMode = MODE_NORMAL;
       }
      }
      if(gMode == MODE_NORMAL)
      {
        servoThrottle.writeMicroseconds(unThrottleIn);
      }

      ulLastThrottleTime = millis();
      sGoodPulseCounter++;
    }
    else
    {
      sGoodPulseCounter = 0;
    }
  }
 
  bUpdateFlags = 0;

  // if we didnt get a signal for 3 times the expected interval, enter neutral
  // this condition self clears if a signal is available
  if((millis() - ulLastThrottleTime) > 60)
  {
    // set a warning LED or BUZZER so we know whats happening
    // for you to do

    // set throttle to neutral
    servoThrottle.writeMicroseconds(1500);    
    gMode = MODE_FAIL_SAFE;
  }
}

Just to be clear, if your receiver decides to output junk when it does not have a signal, we cannot change that, what we are try to do is to contain it by not sending the junk signals to the servos or ESC.

I will add a full example which deals with all channels to the rcarduino blog when I get home tonight.

Duane B
« Last Edit: November 20, 2012, 01:25:06 am by DuaneB » Logged


Queens, New York
Offline Offline
Faraday Member
**
Karma: 84
Posts: 3413
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thought I had it. smiley-cry
Anyway the reason I thought it was the arduino's processing time was because I used an accelerometer going into two arduino's. both controlled the speed of a motor, but the one that was sending the data to the screen was a little slower to change the speed of the motor, as opposed to the one that just controlled the motor. So I thought that is what was happening here because the first arduino had that extra data to process.

« Last Edit: November 20, 2012, 08:02:45 am by HazardsMind » Logged

Created Libraries:
NPV2 (NewPasswordV2),  TFT_Extension, OneWireKeypad, SerialServo.
Will provide libraries if asked in PM or forum.

UK
Offline Offline
Shannon Member
****
Karma: 222
Posts: 12534
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

the one that was sending the data to the screen was a little slower to change the speed of the motor, as opposed to the one that just controlled the motor.

Of course - the Serial port is glacially slow in Arduino terms, and if you  sketch stops and waits for messages to dribble out over the serial port then it will run much slower. This has nothing to do with what is going on inside an R/C car unless, for some strange reason, you decided to run a serial cable out to it and have your controller stop and print stuff over the serial port.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Madrid
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@HazardsMind no offense taken whatsoever, i'm not new at programming its what i do for a living, but i do have a big handicap in electronics as its what i'm learning while working with arduino projects.

@DuaneB thanks a lot for the explanation its been very helpful i been doing some more test's around and i discovered that while working on my studio i get lots and lots of garbage but on the street is minimize a lot i guess all stuff around creates a lot of interference i believe a have a very cheap emitter and receiver and probably old (i got a second hand RC kit to start working on my project and went on the cheap as its my first time trying to replace or add electronic controls to something and working with electronics in general.)

the receiver its a DR-r102-06 AM 2CH the emitter does not have a visible model number on it but its a AM 27Mhz, i'm going to try to find someone to lend me one of the 2.4Ghz or buy a cheap one like this one http://www.hobbyking.com/hobbyking/store/__12177__HK_300_3_Channel_2_4ghz_FHSS_Ground_Radio.html

Logged

Madrid
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

a friend had an extra futaba 3PRKA with a R203GF receiver a 2.4GHz emitter, all is good now, theres absolutly no noise, the signal is very steady and when i turn the remote off the it does 1 of 2 things, it either keeps sending the last value or it jumps to what i guess is max values as it jumps to 53152.

i'm going to try to get the PPM out of that receiver but i'm not sure i have anything here for that the componets are very small SMD chips.

this is my latest reading:
Code:
Throttle: 1116 Yaw: 1504
Throttle: 1116 Yaw: 1504
Throttle: 1116 Yaw: 1504
Throttle: 1116 Yaw: 1504
Throttle: 1116 Yaw: 1504
Throttle: 1116 Yaw: 1504
Throttle: 1116 Yaw: 1504
Throttle: 1112 Yaw: 1504
Throttle: 1112 Yaw: 1504
Throttle: 1116 Yaw: 1504
Throttle: 1116 Yaw: 1504
Throttle: 1116 Yaw: 1504
Throttle: 1116 Yaw: 1504
Throttle: 1112 Yaw: 1504
Throttle: 1112 Yaw: 1500
Throttle: 1116 Yaw: 1500
Throttle: 1116 Yaw: 1504
Throttle: 1112 Yaw: 1504
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1504
Throttle: 1116 Yaw: 1504
Throttle: 1116 Yaw: 1500
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1504
Throttle: 1112 Yaw: 1504
Throttle: 1112 Yaw: 1504
Throttle: 1108 Yaw: 1504
Throttle: 1108 Yaw: 1504
Throttle: 1112 Yaw: 1504
Throttle: 1112 Yaw: 1500
Throttle: 1116 Yaw: 1500
Throttle: 1116 Yaw: 1500
Throttle: 1116 Yaw: 1500
Throttle: 1116 Yaw: 1504
Throttle: 1112 Yaw: 1504
Throttle: 1112 Yaw: 1500
Throttle: 1116 Yaw: 1500
Throttle: 1116 Yaw: 1504
Throttle: 1116 Yaw: 1504
Throttle: 1116 Yaw: 1500
Throttle: 1112 Yaw: 1500
Throttle: 1108 Yaw: 1504
Throttle: 1108 Yaw: 1504
Throttle: 1112 Yaw: 1504
Throttle: 1112 Yaw: 1500
Throttle: 1108 Yaw: 1500
Throttle: 1108 Yaw: 1504
Throttle: 1112 Yaw: 1504
Throttle: 1112 Yaw: 1500
Throttle: 1108 Yaw: 1500
Throttle: 1108 Yaw: 1504
Throttle: 1112 Yaw: 1504
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1500
Throttle: 1112 Yaw: 1504
Throttle: 1112 Yaw: 1504
Throttle: 1112 Yaw: 1500
Throttle: 1116 Yaw: 1500
Throttle: 1116 Yaw: 1504
Throttle: 1124 Yaw: 1504
Throttle: 1124 Yaw: 1504
Throttle: 1164 Yaw: 1504
Throttle: 1164 Yaw: 1504
Throttle: 1236 Yaw: 1504
Throttle: 1236 Yaw: 1504
Throttle: 1308 Yaw: 1504
Throttle: 1308 Yaw: 1504
Throttle: 1380 Yaw: 1504
Throttle: 1380 Yaw: 1500
Throttle: 1440 Yaw: 1500
Throttle: 1440 Yaw: 1504
Throttle: 1492 Yaw: 1504
Throttle: 1492 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1504 Yaw: 1504
Throttle: 1504 Yaw: 1504
Throttle: 1504 Yaw: 1504
Throttle: 1504 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1500 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504
Throttle: 1496 Yaw: 1504


and when the remote if off:
Code:
Throttle: 53152 Yaw: 53152
Throttle: 53152 Yaw: 53152
Throttle: 53152 Yaw: 53152
Throttle: 53152 Yaw: 53152
Throttle: 53152 Yaw: 53152
Throttle: 53152 Yaw: 53152
Throttle: 53152 Yaw: 53152
Throttle: 53152 Yaw: 53152
Throttle: 53152 Yaw: 53152
Throttle: 53152 Yaw: 53152

this new receiver also has a failsafe built in, that basicly does the same Duane posted. thought i have it turn off and handling it by code.
Logged

Dubai, UAE
Offline Offline
Edison Member
*
Karma: 22
Posts: 1675
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Unless you have a lot of channels to deal with, there is not very much to gain from ppm - its worth the effort to find if you have six channels but with just two it really is not worth it.

Duane B
Logged


Madrid
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello DuaneB,

i'm trying to undestand what RCArduinoFastLib is doing, but i hit a small roadblock that i'm sure is just something i'm missing.

if i try to setup the timers as you do basicly copying the begin method my arduino hangs and restarts itself, but if i use the copyed method and import your lib everything works as expected.

does importing RCArduinoFastLib set anything else? i cant seem to see it.
Logged

Dubai, UAE
Offline Offline
Edison Member
*
Karma: 22
Posts: 1675
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
if i use the copyed method and import your lib everything works as expected.

Your saying it works fine, so why change it ?

Duane B.


Logged


Madrid
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

becouse i dont want to use any servos so i dont want to include the full functionaly of the RCArdionoFastLib i just want to read from the receiver.

that and i usually like to understand what i'm doing.

Logged

Dubai, UAE
Offline Offline
Edison Member
*
Karma: 22
Posts: 1675
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, thats reasonable, but are you planning on a project that will not use any servos or ESCs ?

If so I will have a look this evening at providing a define statement that will prevent anything servo related from being included.

Duane B
Logged


Madrid
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i was thinking in something like this https://gist.github.com/4131554

as you can see is bastly based on your code, i havent test it yet as i'm not home with access to my arduino yet.

but thats the idea i'm getting so far.

i dont care about server becouse my plan was to use something like an ATTINY45/85 to process RC signal and them the ATMEGA328p for everything else.
Logged

Dubai, UAE
Offline Offline
Edison Member
*
Karma: 22
Posts: 1675
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
   You have two problems that I can see,

1) you declare rx as a pointer, but never actually point it to anything
2) your try to use class member functions inside the interrupt service routines - you can only do this with static members

   I will try to find time this weekend to add the option to compile the lib with no servo code included.

Duane B

Logged


Pages: 1 [2] 3   Go Up
Jump to: