Go Down

Topic: Reading data from RC Receiver trouble with noise (Read 2823 times) previous topic - next topic

lacion

I say noise for lacking a better word, I'm using pinchangeint lib to read from pins 2,3 CH1 and CH2 from an RC Receiver the receiver is a DR-R102-06 i think its a cheap AM Receiver.

The problem I'm having while reading from the arduino is that whenever the remote its turn off, i get all sorts of noise on my inputs from 0 to 30000 peaks i seem in the values, while when my remote is on i see the standart 1500/1000 variations with just small jumps 1480/1500 every few secs.

The problem with this is that when ever the remote if off or the i get out of range the RC car I'm trying to drive just goes crazy.

when i use the Receiver conected directly to the servos/ESC everything seems cleam does receivers do something to clean noise?

i'm pretty much using the same code as in  http://rcarduino.blogspot.co.uk, but i also tryied diferent methods likes the ones used in arducopter and ardupilot and i'm seing the same thing this is offcourse always the raw data i get directly from the receiver.

PaulS

Quote
I'm using pinchangeint lib to read from pins 2,3

Those are the external interrupt pins. Why are you using the pin change interrupt library to add interrupts to those pins? Use attachInterrupt() instead.

HazardsMind

Please post your code in FULL! and any errors you may get. used the "#" button about to insert your code or just put your code within "
Code: [Select]
{your code here} "
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

PeterH


The problem with this is that when ever the remote if off or the i get out of range the RC car I'm trying to drive just goes crazy.


In this case you need to do a sanity check of the values you're reading to make sure it is a valid signal and not just random noise. For example you could find the minimum and maximum positions of each axis on your controller and detect when all channels are outside the valid range for longer than say a second, and revert to some fail-safe values (i.e. center the steering and stop the motors).
I only provide help via the forum - please do not contact me for private consultancy.

lacion

sorry about pins 2,3 it was a mistake i'm using 5,6

my code is in visual studio right now with a bunch of external files, so i'm to use a code example that has exactly the same problem.

from http://rcarduino.blogspot.co.uk, thought it acutally dosent matter as i said i used several diferent methods and i always see the error when the remote if off, as soon as the remote is on the values are what they should be.

knowing the range wont help as when the remote if off the noise goes trought the same ranges.
Code: [Select]

#include <RCArduinoFastLib.h>
#include <PinChangeInt.h>

#define THROTTLE_IN_PIN 5
#define STEERING_IN_PIN 6
#define AUX_IN_PIN 7

#define THROTTLE_OUT_PIN 8
#define STEERING_OUT_PIN 9
#define AUX_OUT_PIN 10

#define SERVO_THROTTLE 0
#define SERVO_STEERING 1
#define SERVO_AUX 2
#define SERVO_FRAME_SPACE 3

#define THROTTLE_FLAG 1
#define STEERING_FLAG 2
#define AUX_FLAG 4

volatile uint8_t bUpdateFlagsShared;

volatile uint16_t unThrottleInShared;
volatile uint16_t unSteeringInShared;
volatile uint16_t unAuxInShared;

uint16_t unThrottleInStart;
uint16_t unSteeringInStart;
uint16_t unAuxInStart;

uint16_t unLastAuxIn = 0;
uint32_t ulVariance = 0;
uint32_t ulGetNextSampleMillis = 0;
uint16_t unMaxDifference = 0;

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

  Serial.println("multiChannels");

  CRCArduinoFastServos::attach(SERVO_THROTTLE,THROTTLE_OUT_PIN);
  CRCArduinoFastServos::attach(SERVO_STEERING,STEERING_OUT_PIN);
  CRCArduinoFastServos::attach(SERVO_AUX,AUX_OUT_PIN);

  CRCArduinoFastServos::setFrameSpaceA(SERVO_FRAME_SPACE,7*2000);

  CRCArduinoFastServos::begin();
 
  PCintPort::attachInterrupt(THROTTLE_IN_PIN, calcThrottle,CHANGE);
  PCintPort::attachInterrupt(STEERING_IN_PIN, calcSteering,CHANGE);
  PCintPort::attachInterrupt(AUX_IN_PIN, calcAux,CHANGE);
}

void loop()
{
  static uint16_t unThrottleIn;
  static uint16_t unSteeringIn;
  static uint16_t unAuxIn;
 
  Serial.println(unThrottleIn);
 
  static uint8_t bUpdateFlags;

  if(bUpdateFlagsShared)
  {
    noInterrupts();

    bUpdateFlags = bUpdateFlagsShared;
 
    if(bUpdateFlags & THROTTLE_FLAG)
    {
      unThrottleIn = unThrottleInShared;
    }
 
    if(bUpdateFlags & STEERING_FLAG)
    {
      unSteeringIn = unSteeringInShared;
    }
 
    if(bUpdateFlags & AUX_FLAG)
    {
      unAuxIn = unAuxInShared;
    }
   
    bUpdateFlagsShared = 0;
 
    interrupts()
  }
 
  if(bUpdateFlags & THROTTLE_FLAG)
  {
    CRCArduinoFastServos::writeMicroseconds(SERVO_THROTTLE,unThrottleIn);
  }

  if(bUpdateFlags & STEERING_FLAG)
  {
    CRCArduinoFastServos::writeMicroseconds(SERVO_STEERING,unSteeringIn);
  }

  if(bUpdateFlags & AUX_FLAG)
  {
   CRCArduinoFastServos::writeMicroseconds(SERVO_AUX,unAuxIn);
   }

  bUpdateFlags = 0;
}

void calcThrottle()
{
  if(PCintPort::pinState)
  {
    unThrottleInStart = TCNT1;
  }
  else
  {
    unThrottleInShared = (TCNT1 - unThrottleInStart)>>1;
    bUpdateFlagsShared |= THROTTLE_FLAG;
  }
}

void calcSteering()
{
  if(PCintPort::pinState)
  {
    unSteeringInStart = TCNT1;
  }
  else
  {
    unSteeringInShared = (TCNT1 - unSteeringInStart)>>1;

    bUpdateFlagsShared |= STEERING_FLAG;
  }
}

void calcAux()
{
  if(PCintPort::pinState)
  {
    unAuxInStart = TCNT1;
  }
  else
  {
    unAuxInShared = (TCNT1 - unAuxInStart)>>1;
    bUpdateFlagsShared |= AUX_FLAG;  }
}

HazardsMind

Did you try to set a fail-safe program for when your remote is off or out or range, maybe to set the break or turn on a circle?
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

lacion


Did you try to set a fail-safe program for when your remote is off or out or range, maybe to set the break or turn on a circle?


Not yet i wanted to understand what the issue was first, my reading of several other post and blogs about this dont point to any noise so i'm assuming is something i'm doing wrong.

HazardsMind

Your getting those wild values because the arduino is not seeing the correct data, it is probably getting interference from other sources other than the one it wants, so the car goes crazy.
Set a fail safe.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

lacion


Your getting those wild values because the arduino is not seeing the correct data, it is probably getting interference from other sources other than the one it wants, so the car goes crazy.
Set a fail safe.


thats what i dont understand, i'm not reading the data from the PPM Stream i'm reading from the output channels of the receiver, does receivers have thoose fail safes? if they do shouldn't that be happening at the receiver?

as i said when i connect the motors to the receiver i dont observe any issue.

i can implement a fail safe but i still thing there is a problem somewhere, i seem several project on github controlling rc cars havent seen any fail safe yet.

HazardsMind

Can you post a picture of what your doing, and any data values your getting?
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

PeterH


thats what i dont understand, i'm not reading the data from the PPM Stream i'm reading from the output channels of the receiver,
does receivers have thoose fail safes? if they do shouldn't that be happening at the receiver?

as i said when i connect the motors to the receiver i dont observe any issue.


Whether the receiver has fails-safes built in is up to the design of the receiver - some do, but in my experience only the more expensive ones.

You seem to be saying that if you use the original RC system and switch off the transmitter, the model just sits inertly. In my experience with RC systems in this situation it's common for them to sit inertly but occasionally take random and extreme actions (presumably in response to radio noise). It is possible that the Arduino is more susceptible to this than an ordinary servo because of the way it is connected to the receiver without any conditioning or smoothing. Although it might be possible to improve that slightly I don't think this solves the fundamental problem that you need your sketch to know whether it is getting a valid signal from the receiver before it acts on it.

On reflection, rather than looking for the pulse length being within the sensible range you should be looking for the pulse being received at the expected interval. You should be receiving the pulse at 40-50 Hz for each channel, and if you miss several pulses then it would be sensible to invoke the failsafe and keep it active until you have received several 'good' pulses.
I only provide help via the forum - please do not contact me for private consultancy.

DuaneB

#11
Nov 19, 2012, 05:34 pm Last Edit: Nov 19, 2012, 05:41 pm by DuaneB Reason: 1
Hi,
   It might be that when your RC is off, your inputs are floating - quick and simple hardware solution, try adding pull down resistors on the inputs.

   A software variation on what others have suggested is to pick one of the channels (throttle is a good one) and take a time stamp every time you receive a valid signal on this channel, if the difference between the time stamp and current time is greater than 60ms set the throttle to neutral. In my experience it is better to allow a signal through if its available than it is to enter a failsafe mode - i.e. car is out of range, enters neutral, you start walking towards the car, SUV comes around the corner, your back in range and drive your car away from the SUV - if you entered failsafe, you will need a new RC Car at this point.

In air applications something else might be perferable, but generally if a valid signal is available, try to use it.

Code not tested - I am in Cairo this week.

Code: [Select]

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(servoThrottle.readMicroseconds() != unThrottleIn)
      {
        servoThrottle.writeMicroseconds(unThrottleIn);
      }
      ulLastThrottleTime = millis();
    }
  }

  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);   
  }
}


Duane B

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

PeterH


In air applications something else might be perferable, but generally if a valid signal is available, try to use it.


The failsafe does not prevent valid signals from being acted on, it places all the outputs to a defined state when there is no valid signal. In other words, your car will stop and wait for you to get back into range, rather than flailing around randomly.
I only provide help via the forum - please do not contact me for private consultancy.

DuaneB

Quote
In other words, your car will stop and wait for you to get back into range, rather than flailing around randomly.


Thats what the posted code will do

Duane B
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

lacion

here are some pics of the testings i'm doing right now.

i tryed waiting to get the correct data with the solution posted by Duane with several time variation and i do get less noise but the noise its still there. so i'm implementing a save mode.

here are some reading samples.

Remote Turn On:
Code: [Select]

Throttle: 1488.00 Yaw: 1484.00
Throttle: 1488.00 Yaw: 1484.00
Throttle: 1488.00 Yaw: 1485.00
Throttle: 1488.00 Yaw: 1487.00
Throttle: 1488.00 Yaw: 1485.00
Throttle: 1488.00 Yaw: 1488.00
Throttle: 1488.00 Yaw: 1488.00
Throttle: 1487.00 Yaw: 1488.00
Throttle: 1484.00 Yaw: 1488.00
Throttle: 1485.00 Yaw: 1488.00
Throttle: 1489.00 Yaw: 1487.00
Throttle: 1490.00 Yaw: 1485.00
Throttle: 1486.00 Yaw: 1488.00
Throttle: 1490.00 Yaw: 1488.00
Throttle: 1485.00 Yaw: 1487.00
Throttle: 1489.00 Yaw: 1484.00
Throttle: 1491.00 Yaw: 1484.00
Throttle: 1488.00 Yaw: 1484.00
Throttle: 1489.00 Yaw: 1485.00
Throttle: 1491.00 Yaw: 1488.00
Throttle: 1488.00 Yaw: 1488.00
Throttle: 1488.00 Yaw: 1488.00
Throttle: 1488.00 Yaw: 1487.00
Throttle: 1488.00 Yaw: 1485.00
Throttle: 1488.00 Yaw: 1488.00
Throttle: 1489.00 Yaw: 1488.00
Throttle: 1490.00 Yaw: 1489.00
Throttle: 1485.00 Yaw: 1490.00
Throttle: 1487.00 Yaw: 1485.00
Throttle: 1486.00 Yaw: 1487.00
Throttle: 1492.00 Yaw: 1485.00
Throttle: 1490.00 Yaw: 1488.00
Throttle: 1486.00 Yaw: 1487.00
Throttle: 1492.00 Yaw: 1485.00
Throttle: 1491.00 Yaw: 1486.00
Throttle: 1488.00 Yaw: 1482.00
Throttle: 1489.00 Yaw: 1487.00
Throttle: 1491.00 Yaw: 1485.00
Throttle: 1488.00 Yaw: 1488.00
Throttle: 1489.00 Yaw: 1487.00
Throttle: 1491.00 Yaw: 1484.00
Throttle: 1489.00 Yaw: 1484.00
Throttle: 1491.00 Yaw: 1484.00
Throttle: 1489.00 Yaw: 1484.00
Throttle: 1491.00 Yaw: 1485.00
Throttle: 1489.00 Yaw: 1487.00



Remote Turn Off:
Code: [Select]

Throttle: 3992.00 Yaw: 5611.00
Throttle: 10314.00 Yaw: 4931.00
Throttle: 12025.00 Yaw: 6948.00
Throttle: 4272.00 Yaw: 990.00
Throttle: 6472.00 Yaw: 1386.00
Throttle: 4270.00 Yaw: 3195.00
Throttle: 2598.00 Yaw: 2532.00
Throttle: 2041.00 Yaw: 318.00
Throttle: 3748.00 Yaw: 2936.00
Throttle: 8518.00 Yaw: 8635.00
Throttle: 942.00 Yaw: 3337.00
Throttle: 1402.00 Yaw: 4885.00
Throttle: 2865.00 Yaw: 2906.00
Throttle: 1350.00 Yaw: 1680.00
Throttle: 1600.00 Yaw: 2080.00
Throttle: 1002.00 Yaw: 1560.00
Throttle: 724.00 Yaw: 2724.00
Throttle: 1846.00 Yaw: 1053.00
Throttle: 2152.00 Yaw: 2206.00
Throttle: 2688.00 Yaw: 3835.00
Throttle: 2435.00 Yaw: 751.00


also tried the pull down resistor with no luck.

Go Up