Created Wed, 29 Feb 2012 02:04:42 +0000 by alphamike
Wed, 29 Feb 2012 02:04:42 +0000
what is the best way to read a rc receiver output? I am building a robot that is controlled by a airplane controller, but I was wondering if the compiler has been fixed to be able to use attach interrupt ? this is the code that i am currently using, but it is too jumpy and it does not always read the output (ie. the output shows up as a zero).
unsigned long counter = 0;
unsigned long Channel1Value;
unsigned long Channel2Value;
unsigned long lastgood1;
unsigned long lastgood2;
unsigned long InitialSteer;
unsigned long InitialThrottle;
boolean Right;
//motor stuff
long Steer;
int Thrust;
int RightMotor;
int LeftMotor;
int Chan1 = 2;
int Chan2 = 3;
int newVal1;
int newVal2;
#define MotorLimit 3200
/**************************************************************
* Subroutine to exit saft start;
***************************************************************/
void exitSafeStartBoth()
{
Serial3.print(0x83, BYTE);
}
void motorStopBoth()
{
Serial3.print(0xE0, BYTE);
}
/**************************************************************
* Subroutine to control right motor= motorRight(speed, direction);
***************************************************************/
void setMotorSpeedleft(int speedleft)
{
if (speedleft < 0)
{
Serial3.print(0xAA, BYTE);
Serial3.print(0xa, BYTE);
Serial3.print(0x6, BYTE); // motor reverse command
speedleft = -speedleft; // make speed positive
}
else
{
Serial3.print(0xAA, BYTE);
Serial3.print(0xa, BYTE);
Serial3.print(0x5, BYTE); // motor forward command
}
Serial3.print((unsigned char)(speedleft & 0x1F), BYTE);
Serial3.print((unsigned char)(speedleft >> 5), BYTE);
}
/**************************************************************
* Subroutine to control left motor
***************************************************************/
void setMotorSpeedright(int speedright)
{
if (speedright < 0)
{
Serial3.print(0xAA, BYTE);
Serial3.print(0xd, BYTE);
Serial3.print(0x06, BYTE); // motor reverse command
speedright = -speedright; // make speed positive
}
else
{
Serial3.print(0xAA, BYTE);
Serial3.print(0xd, BYTE);
Serial3.print(0x05, BYTE); // motor forward command
}
Serial3.print((unsigned char)(speedright & 0x1F), BYTE);
Serial3.print((unsigned char)(speedright >> 5), BYTE);
}
void setup()
{
Serial3.begin(19200);
Serial.begin(19200);
Serial.println("Ready");
pinMode (Chan2, INPUT);
pinMode (Chan1, INPUT);
InitialSteer = pulseIn (Chan1, HIGH); //read RC channel 1
lastgood1 = InitialSteer;
InitialThrottle = pulseIn (Chan2, HIGH); //read RC channel 2
lastgood2 = InitialThrottle;
}
void loop()
{
newVal1 = pulseIn(Chan1, HIGH, 50000);
newVal2 = pulseIn(Chan2, HIGH, 35000);
if (newVal1 > 0 || newVal2 > 0)
{
// counter++; // this just increments a counter for benchmarking the impact of the pulseIn's on CPU performance
if(newVal1 >= Channel1Value || newVal1 <= Channel1Value)
{
Channel1Value = newVal1;
}
if(newVal2 >= Channel2Value || newVal2 <= Channel2Value)
{
Channel2Value = newVal2; //read RC channel 2
}
if (Channel1Value == 0)
{
Channel1Value = lastgood1;
}
else
{
lastgood1 = Channel1Value;
}
if (Channel1Value < InitialSteer)
{
Right = false;
}
else
{
Right = true;
}
Steer = Channel1Value - InitialSteer;
RightMotor = Thrust - Steer;
LeftMotor = Thrust + Steer;
if (RightMotor > 3200)
{
RightMotor = 3200;
}
if (LeftMotor > 3200)
{
LeftMotor = 3200;
}
Thrust = map(Channel2Value, 3645, 5565, -(MotorLimit), MotorLimit);
Thrust = constrain (Thrust, -(MotorLimit), MotorLimit); //just in case
LeftMotor = constrain (LeftMotor, -3200, 3200);
RightMotor = constrain (RightMotor, -3200, 3200);
exitSafeStartBoth();
setMotorSpeedleft(LeftMotor);
setMotorSpeedright(RightMotor);
}
else
{
motorStopBoth();
}
Serial.print ("Channel 1: "); // if you turn on your serial monitor you can see the readings.
Serial.println (Channel1Value);
Serial.print("Channel 2: ");
Serial.println (Channel2Value);
Serial.println(LeftMotor);
Serial.println(RightMotor);
Serial.println("");
Serial.println("");
Serial.println("");
Serial.println("");
delay(50);
}
sorry if the code is confusing, im not all that good as you can tell
Wed, 29 Feb 2012 19:38:39 +0000
I'd use the Servo Decode function. I hope it's ready for ChipKIT.
[url]http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230065255[/url]
Alan KM6VV
Sun, 04 Mar 2012 13:36:51 +0000
I'm trying to decode all six channels from the receiver. I read somewhere that unless you use attach interrupt, the code will run too slow.
Sun, 04 Mar 2012 16:56:29 +0000
Have you ever thought of using the input capture module? There are 5 of them on the uno, so you would have to softcode your last channel. I've been able to use two channels for a pair of ultrasonic sensor and they worked great for range testing (better than pulsein). I'm sure it could be adjusted to fit you needs and save some processing overhead.
Sun, 04 Mar 2012 22:39:50 +0000
What is that command and how do you use it. I am using the max32 plugged into a pcb I produced and the channels are pinned to 7-2. If i need to I could make a new pcb
Mon, 05 Mar 2012 00:08:28 +0000
It's not really a command, but a module inside the chip that would need to be configured. I'm attaching a sketch of how I used it, but understand that because of the way I'm using it I know when the pulse goes low and am just timing until the pulse goes high. I like this better than pulsein because it can be used as non-blocking so I could process other things while waiting for the rising edge. You may be able to configure it to start counting on a negative going edge then capture the timer value on the positive edge. You will have to read the datasheet though for more details. The Max 32 also only has 5 I.C. modules located on pins 48,74,38,49, and 8 which are not remappable unfortunately. Sorry if the code seems sloppy, it was hastily thrown together to test out the range finders. I actually just modified some code that was posted on the forum and used it.
Hope it is of some use.
Jason
Mon, 05 Mar 2012 02:03:05 +0000
I'm not sure if the input capture will work for me. just because i Would rather not make a new pcb. is attach interrupt even possible for what I am trying to do? I also looked into servo decode and could not find anything about it for chipkit..
Mon, 05 Mar 2012 04:25:30 +0000
I'm not sure which interupt you are refering too (assuming Change Notification (CN)), but looking at the pins that are used for it you may not have much luck either. Looking at the Pinout table provided by Digilent the only pin that would fit your pins is pin 4. I don't know about the servo decode library, so maybe someone else could enlighten you on the topic.
Good luck what ever you decide.
Mon, 05 Mar 2012 14:18:24 +0000
Alternatively depending on your RC receiver you can hack on the receiver to get just one input for the 6 channels. I played around with this awhile ago to connect to a different processor (Basic Atom Pro)... I did it for the Hitec 6... More details in the forum thread: http://www.lynxmotion.net/viewtopic.php?f=21&t=6629
I found details for doing this type of receiver as well as some others by goggle of terms like "intercept ppm" or the like.
Kurt
Mon, 16 Apr 2012 02:22:57 +0000
We just posted the chipKIT source for the PONTECH UAV100 to github today:
https://github.com/pontech/uav100
Product details:
http://www.pontech.com/details/138
In this code we are capturing 8 PPM signals with 15-bit resolution using the CN interrupts.
This may help some people trying to do the same.
Jacob
Mon, 16 Apr 2012 19:47:12 +0000
Hi Jacob,
is the GitHub Zip complete? Looks like the pic32lib has no files, and GPS only has GPS.h. TokenParser has no files, but needs at least TokenParser.h.
19 files?
Maybe I need something else?
Maybe point me to the notes needed to compile?
I am not current on the PIC lib, come to think of it.
Thanks!
Alan KM6VV
Tue, 17 Apr 2012 00:34:21 +0000
Hi Jacob, is the GitHub Zip complete? Looks like the pic32lib has no files, and GPS only has GPS.h. TokenParser has no files, but needs at least TokenParser.h. 19 files? Maybe I need something else? Maybe point me to the notes needed to compile? I am not current on the PIC lib, come to think of it.
the pic32lib and TokenParsers are submodules so you need to do a submodule update. The gps code is not complete and there is only a header.
If you look at github.com/pontech you should see the submodules. I was able to pull and update the whole project.
Jacob
NOTE: There are a couple of other issues as well that have been fixed in MPIDE to get this to compile, I'll will have to put a readme together.
Tue, 17 Apr 2012 00:48:55 +0000
OK, I get it!
Thanks,
Alan KM6VV
Tue, 15 May 2012 05:10:06 +0000
What voltage are the signals from the RC receiver you are using? I ask because a lot of the PIC32 I/O lines don't seem to be 5 volt tolerant, especially on on the smaller packages like the PIC32MX250F128B etc. I know having built a few multi-copters myself, that RC receivers can have a lot of channels. I have mostly used ATmega chips which run on 5volts, I haven't tried a PIC32 as a flight controller yet, though no doubt will one day.
Tue, 15 May 2012 05:39:48 +0000
The UAV100 has buffered inputs.
Jacob
Mon, 19 Nov 2012 10:43:25 +0000
you can download simple bare program on chipkit32 using mpide IDE 023
you will start receiving data.
ex:
void setup() { } void loop() { }
and open serial monitor to view the data