Go Down

Topic: Problems with R/C 6ch transmission (Read 10847 times) previous topic - next topic

Carlos mononoke

Hi,

I´m trying to read the RC signal on the receiver with pulseIn() function, i am using 6 ch rx tx turnigy equip.
What i am trying is to read the value and print in the serial monitor but
I´ve tryed:
-Power the receiver with arduino regulator and power with 7805 regulator
-Connect the GND pin in the receiver´s channel slot to arduino gnd pin
- Read the high value and the low value time
- Use analogRead too

Allways I´ve readed 17731 value,in the beggining I was trying to read the six values
but now I am trying to read only one value,and if I disconnect the receiver from arduino´s pins in the serial monitor read 17731 again,but a bit slowly.
someone knows why or what is happening????
Thanks!!!!!!

DuaneB

I can probably help.

First of all, are you reading the channels individually through six three wire connections or are you reading a PPM Stream which contains all of the six channels in a single connection ?

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

Carlos mononoke


I am reading the channels individually,first I connected six single wire,the receiver signal pin to arduino I/0 and then y tryed to connect the receiver gnd pin to arduino gnd pin too
(six double wire)

DuaneB

That sounds fine.

Lets try and read one signal first, try the sketch in this link

http://rcarduino.blogspot.com/2012/01/how-to-read-rc-receiver-with.html

connect one of your channels to pin 2 of your Arduino to read it

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

Carlos mononoke

thanks, I will read and try this afternoon.

DuaneB

Let me know how you get on, I can point you to the links for more channels and when your up and running - my new library.

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

Carlos mononoke

hi!!!
I read and try your sketch for one channel and work perfectly.
Thanks!!! now I will start with the oder two tutorial(for more channels),I will tell you.

DuaneB

Its good to read and understand this one -

http://rcarduino.blogspot.com/2012/04/how-to-read-multiple-rc-channels-draft.html

but if your feeling brave try this one -

http://rcarduino.blogspot.com/2012/11/how-to-read-rc-channels-rcarduinofastlib.html

Its going to be a big benefit with six channels, the sensitive parts of the code are much faster than the original link.

If you need help with it let me know.

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

Carlos mononoke

Hi again,
I was understanding the first one, but when upload the example code,
the servo start to move like little crazy.
So I added a serial print inside  the interrups,in the else stament,just before updating the flag,for see the variable
that is passed to the servo but it was randomly,always between 17000 and 25000.
I have use first the 2,03 version and them 1.81 library,but no.
it´s that normal????

thanks for your help :D

DuaneB

#9
Nov 06, 2012, 05:57 am Last Edit: Nov 06, 2012, 09:19 am by DuaneB Reason: 1
Hi,
   Its going to be something simple, my first guess is that you have the receiver channel connected to digital pin 2 still.

The multi channel code expects channels to be connected to pins 5,6,7

Code: [Select]

// Assign your channel in pins
#define THROTTLE_IN_PIN 5
#define STEERING_IN_PIN 6
#define AUX_IN_PIN 7


And servos to 8,9,10 so that the channel on pin 5 drives the servo on pin 8, 6 drives 9, 7 drives 10

Code: [Select]

// Assign your channel out pins
#define THROTTLE_OUT_PIN 8
#define STEERING_OUT_PIN 9
#define AUX_OUT_PIN 10


I would also suggest that you remove the serial commands you have added, they are not the problem, but they should not be inside any of the time sensitive sections of code.

If this doesn't help, PM me the sketch and what board you are using.

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

Carlos mononoke

Good morning!!!
No, I have connected well the receiver channel and servo,now I am using one nano v3.0.But when RC works i want to use in oder proyect in ARduino Mega 2560.
I put the code for try to understand what´s happening,or see what is reading from the receiver.
Thanks!!!!

the sketch:


-----------------------------------------------------------------------------------------------------------------------------------------------------------------
// MultiChannels
//
// rcarduino.blogspot.com
//
// A simple approach for reading three RC Channels using pin change interrupts
//
// See related posts -
// http://rcarduino.blogspot.co.uk/2012/01/how-to-read-rc-receiver-with.html
// http://rcarduino.blogspot.co.uk/2012/03/need-more-interrupts-to-read-more.html
// http://rcarduino.blogspot.co.uk/2012/01/can-i-control-more-than-x-servos-with.html
//
// rcarduino.blogspot.com
//

// include the pinchangeint library - see the links in the related topics section above for details
#include <PinChangeInt.h>

#include <Servo.h>

// Assign your channel in pins
#define THROTTLE_IN_PIN 5
#define STEERING_IN_PIN 6
#define AUX_IN_PIN 7

// Assign your channel out pins
#define THROTTLE_OUT_PIN 8
#define STEERING_OUT_PIN 9
#define AUX_OUT_PIN 10

// Servo objects generate the signals expected by Electronic Speed Controllers and Servos
// We will use the objects to output the signals we read in
// this example code provides a straight pass through of the signal with no custom processing
Servo servoThrottle;
Servo servoSteering;
Servo servoAux;

// These bit flags are set in bUpdateFlagsShared to indicate which
// channels have new signals
#define THROTTLE_FLAG 1
#define STEERING_FLAG 2
#define AUX_FLAG 4

// holds the update flags defined above
volatile uint8_t bUpdateFlagsShared;

// shared variables are updated by the ISR and read by loop.
// In loop we immediatley take local copies so that the ISR can keep ownership of the
// shared ones. To access these in loop
// we first turn interrupts off with noInterrupts
// we take a copy to use in loop and the turn interrupts back on
// as quickly as possible, this ensures that we are always able to receive new signals
volatile uint16_t unThrottleInShared;
volatile uint16_t unSteeringInShared;
volatile uint16_t unAuxInShared;

// These are used to record the rising edge of a pulse in the calcInput functions
// They do not need to be volatile as they are only used in the ISR. If we wanted
// to refer to these in loop and the ISR then they would need to be declared volatile
uint32_t ulThrottleStart;
uint32_t ulSteeringStart;
uint32_t ulAuxStart;

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

  Serial.println("multiChannels");

  // attach servo objects, these will generate the correct
  // pulses for driving Electronic speed controllers, servos or other devices
  // designed to interface directly with RC Receivers
  servoThrottle.attach(THROTTLE_OUT_PIN);
  servoSteering.attach(STEERING_OUT_PIN);
  servoAux.attach(AUX_OUT_PIN);

  // using the PinChangeInt library, attach the interrupts
  // used to read the channels
  PCintPort::attachInterrupt(THROTTLE_IN_PIN, calcThrottle,CHANGE);
  PCintPort::attachInterrupt(STEERING_IN_PIN, calcSteering,CHANGE);
  PCintPort::attachInterrupt(AUX_IN_PIN, calcAux,CHANGE);
}

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;

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

  if(bUpdateFlags & STEERING_FLAG)
  {
    if(servoSteering.readMicroseconds() != unSteeringIn)
    {
      servoSteering.writeMicroseconds(unSteeringIn);
    }
  }

  if(bUpdateFlags & AUX_FLAG)
  {
    if(servoAux.readMicroseconds() != unAuxIn)
    {
      servoAux.writeMicroseconds(unAuxIn);
    }
  }

  bUpdateFlags = 0;
}


// simple interrupt service routine
void calcThrottle()
{
  // if the pin is high, its a rising edge of the signal pulse, so lets record its value
  if(digitalRead(THROTTLE_IN_PIN) == HIGH)
  {
    ulThrottleStart = micros();
  }
  else
  {
    // else it must be a falling edge, so lets get the time and subtract the time of the rising edge
    // this gives use the time between the rising and falling edges i.e. the pulse duration.
    unThrottleInShared = (uint16_t)(micros() - ulThrottleStart);
    // use set the throttle flag to indicate that a new throttle signal has been received
    bUpdateFlagsShared |= THROTTLE_FLAG;
    Serial.println(unThrottleInShared,DEC);
  }
}

void calcSteering()
{
  if(digitalRead(STEERING_IN_PIN) == HIGH)
  {
    ulSteeringStart = micros();
  }
  else
  {
    unSteeringInShared = (uint16_t)(micros() - ulSteeringStart);
    bUpdateFlagsShared |= STEERING_FLAG;
    Serial.println(unSteeringInShared,DEC);
  }
}

void calcAux()
{
  if(digitalRead(AUX_IN_PIN) == HIGH)
  {
    ulAuxStart = micros();
  }
  else
  {
    unAuxInShared = (uint16_t)(micros() - ulAuxStart);
    bUpdateFlagsShared |= AUX_FLAG;
    Serial.println(unAuxInShared,DEC);
  }
}

DuaneB

Hi,
   Can you take the serial commands out of the interrupt routines, thats the last place you would want to put them.

Lets focus on just the throttle channel for now, put a serial print inside this section in the main loop -

Code: [Select]

if(bUpdateFlags & THROTTLE_FLAG)
  {
    if(servoThrottle.readMicroseconds() != unThrottleIn)
    {
      servoThrottle.writeMicroseconds(unThrottleIn);
    }
    // Serial print here ....
  }


The only reasons I would expect random values are -

1) Floating inputs - your ISR is pointing to a pin that is not connected

2) No common ground - check that the receiver ground is connected to the arduino ground

3) Some difference in pin/port mappings on Nano3.0 that makes pinchangeint reference the incorrect pin

It might not be any of these, but an easy way to check is to connect each digital pin to ground one by one and watch the output, if the output stop we know that the pin you just grounded was the one that the signal was being read from.

Use a 10K resistor as the connection to ground to limit the current in case one of the pins is set to output.

Does this make sense ? let me know how you get on

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

Carlos mononoke

So, the experiment will be, throttle thah is pin 5 in arduino, trought a 10k resistor conected to ground, and the output in the serial monitor will stop becouse there is no change for interrupt no???, and if this don´t happen change looking for the real pin.
I will do, but yesterday when I power down the transeiver (buttom off),the serial monitor stop. well I´ll try and say what happend in a moment.

DuaneB

Let me know what happens, I am eager to get to the bottom of this ...

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

Carlos mononoke

Worksss!!!!!!!!!!
it was my foult I sopouse that first i try reading the serial monitor and when i saw the random read values i connected the servos and nothing works.
it was what you say I must read out of the interrupt,but i don´t understand this so well.What was the diference between read the shared value just before give  this value to the loop, and  read the value when you use in the loop???

Thanks a lot!!!!!!

Go Up