This is a new Library for managing RC input channels which will replace the current way of storing RC input in Arrays and most of the Radio.pde tab

git-svn-id: https://arducopter.googlecode.com/svn/trunk@902 f9c3cf11-9bcb-44bc-f272-b75c42450872
This commit is contained in:
jasonshort@gmail.com 2010-11-23 19:28:19 +00:00
parent f30bf9cab7
commit 4fa2491adf
4 changed files with 355 additions and 0 deletions

View File

@ -0,0 +1,140 @@
/*
RC_Channel.cpp - Radio library for Arduino
Code by Jason Short. DIYDrones.com
This library is free software; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
*/
#include "RC_Channel.h"
#define ANGLE 0
#define RANGE 1
RC_Channel::RC_Channel() : _high(1)
{
}
void
RC_Channel::set_radio_range(int r_min, int r_max)
{
_radio_min = r_min;
_radio_max = r_max;
}
// setup the control preferences
void
RC_Channel::set_range(int high, int low)
{
_type = RANGE;
_high = high;
_low = low;
}
void
RC_Channel::set_angle(int angle)
{
_type = ANGLE;
_high = angle;
}
// call after first read
void
RC_Channel::set_trim(int pwm)
{
_radio_trim = pwm;
}
// read input from APM_RC - create a control_in value
void
RC_Channel::set_pwm(int pwm)
{
if(_radio_in == 0)
_radio_in = pwm;
else
_radio_in = ((pwm + _radio_in) >> 1); // Small filtering
if(_type == RANGE){
control_in = pwm_to_range();
}else{
control_in = pwm_to_angle();
}
}
// are we below a threshold?
boolean
RC_Channel::get_failsafe(void)
{
return (_radio_in < (_radio_min - 50));
}
// returns just the PWM without the offset from radio_min
void
RC_Channel::calc_pwm(void)
{
if(_type == RANGE){
pwm_out = range_to_pwm();
}else{
pwm_out = angle_to_pwm();
}
radio_out = pwm_out + _radio_min;
}
void
RC_Channel::load_eeprom(int address)
{
//Serial.println("load gains ");
//Serial.println(address, DEC);
//_kp = (float)(eeprom_read_word((uint16_t *) address)) / 1000.0;
//_ki = (float)(eeprom_read_word((uint16_t *) (address + 2))) / 1000.0;
//_kd = (float)(eeprom_read_word((uint16_t *) (address + 4))) / 1000.0;
//_imax = eeprom_read_word((uint16_t *) (address + 6)) * 100;
}
void
RC_Channel::save_eeprom(int address)
{
//eeprom_write_word((uint16_t *) address, (int)(_kp * 1000));
//eeprom_write_word((uint16_t *) (address + 2), (int)(_ki * 1000));
//eeprom_write_word((uint16_t *) (address + 4), (int)(_kd * 1000));
//eeprom_write_word((uint16_t *) (address + 6), (int)_imax/100);
}
// ------------------------------------------
int16_t
RC_Channel::pwm_to_angle()
{
if(_radio_in < _radio_trim)
return _high * ((float)(_radio_in - _radio_trim) / (float)(_radio_trim - _radio_min));
else
return _high * ((float)(_radio_in - _radio_trim) / (float)(_radio_max - _radio_trim));
}
int16_t
RC_Channel::angle_to_pwm()
{
if(servo_out < 0)
return (((float)servo_out / (float)_high) * (float)(_radio_max - _radio_trim));
else
return (((float)servo_out / (float)_high) * (float)(_radio_trim - _radio_min));
}
// ------------------------------------------
int16_t
RC_Channel::pwm_to_range()
{
return _low + _high * ((float)(_radio_in - _radio_min) / (float)(_radio_max - _radio_min));
}
int16_t
RC_Channel::range_to_pwm()
{
return (((float)servo_out / (float)(_high - _low)) * (float)(_radio_max - _radio_min));
}

View File

@ -0,0 +1,76 @@
/*
RC_Channel library.
Code by Jason Short. 2010
DIYDrones.com
*/
#ifndef RC_Channel_h
#define RC_Channel_h
#include <inttypes.h>
#include "WProgram.h"
class RC_Channel
{
public:
RC_Channel();
// startup
void load_eeprom(int address);
void save_eeprom(int address);
void set_radio_range(int r_min, int r_max);
// setup the control preferences
void set_range(int high, int low);
void set_angle(int angle);
// call after first read
void set_trim(int pwm);
// read input from APM_RC - create a control_in value
void set_pwm(int pwm);
// did our read come in 50µs below the min?
boolean get_failsafe(void);
// value generated from PWM
int16_t control_in;
// current values to the servos - degrees * 100 (approx assuming servo is -45 to 45 degrees except [3] is 0 to 100
int16_t servo_out;
// generate PWM from servo_out value
void calc_pwm(void);
// PWM is without the offset from radio_min
int16_t pwm_out;
int16_t radio_out;
// includes offset from PWM
//int16_t get_radio_out(void);
private:
int16_t channel_filter();
int16_t pwm_to_angle();
int16_t angle_to_pwm();
int16_t pwm_to_range();
int16_t range_to_pwm();
byte _channel;
boolean _type;
boolean _filter;
int16_t _radio_in;
int16_t _radio_min;
int16_t _radio_trim;
int16_t _radio_max;
int16_t _high;
int16_t _low;
};
#endif

View File

@ -0,0 +1,70 @@
/*
Example of RC_Channel library.
Code by Jason Short. 2010
DIYDrones.com
*/
#include <APM_RC.h> // ArduPilot Mega RC Library
#include <RC_Channel.h> // ArduPilot Mega RC Library
RC_Channel rc_1;
RC_Channel rc_2;
RC_Channel rc_3;
RC_Channel rc_4;
#define CH_1 0
#define CH_2 1
#define CH_3 2
#define CH_4 3
void setup()
{
Serial.begin(38400);
Serial.println("ArduPilot RC Channel test");
delay(1000);
// setup radio
// read eepom or set manually
rc_1.set_radio_range(1100,1900);
rc_2.set_radio_range(1100,1900);
rc_3.set_radio_range(1100,1900);
rc_4.set_radio_range(1100,1900);
// set type of output, symmetrical angles or a number range;
rc_1.set_angle(4500);
rc_2.set_angle(4500);
rc_3.set_range(0,1000);
rc_4.set_angle(3000);
// set midpoint value
rc_1.set_trim(APM_RC.InputCh(CH_1));
rc_2.set_trim(APM_RC.InputCh(CH_2));
rc_3.set_trim(APM_RC.InputCh(CH_3));
rc_4.set_trim(APM_RC.InputCh(CH_4));
}
void loop()
{
delay(20);
rc_1.set_pwm(APM_RC.InputCh(CH_1));
rc_2.set_pwm(APM_RC.InputCh(CH_2));
rc_3.set_pwm(APM_RC.InputCh(CH_3));
rc_4.set_pwm(APM_RC.InputCh(CH_4));
print_pwm();
}
void print_pwm()
{
Serial.print("ch1 ");
Serial.print(rc_1.control_in, DEC);
Serial.print("\tch2: ");
Serial.print(rc_2.control_in, DEC);
Serial.print("\tch3 :");
Serial.print(rc_3.control_in, DEC);
Serial.print("\tch4 :");
Serial.print(rc_4.control_in, DEC);
}

View File

@ -0,0 +1,69 @@
/*
Example of RC_Channel library.
Code by Jason Short. 2010
DIYDrones.com
*/
#include <APM_RC.h> // ArduPilot Mega RC Library
#include <RC_Channel.h> // ArduPilot Mega RC Library
RC_Channel rc_1;
RC_Channel rc_2;
RC_Channel rc_3;
RC_Channel rc_4;
#define CH_1 0
#define CH_2 1
#define CH_3 2
#define CH_4 3
void setup()
{
Serial.begin(38400);
Serial.println("ArduPilot RC Channel test");
delay(1000);
// setup radio
// read eepom or set manually
rc_1.set_radio_range(1100,1900);
rc_2.set_radio_range(1100,1900);
rc_3.set_radio_range(1100,1900);
rc_4.set_radio_range(1100,1900);
// set type of output, symmetrical angles or a number range;
rc_1.set_angle(4500);
rc_2.set_angle(4500);
rc_3.set_range(0,1000);
rc_4.set_angle(3000);
// set midpoint value
rc_1.set_trim(APM_RC.InputCh(CH_1));
rc_2.set_trim(APM_RC.InputCh(CH_2));
rc_3.set_trim(APM_RC.InputCh(CH_3));
rc_4.set_trim(APM_RC.InputCh(CH_4));
}
void loop()
{
delay(20);
rc_1.set_pwm(APM_RC.InputCh(CH_1));
rc_2.set_pwm(APM_RC.InputCh(CH_2));
rc_3.set_pwm(APM_RC.InputCh(CH_3));
rc_4.set_pwm(APM_RC.InputCh(CH_4));
print_pwm();
}
void print_pwm()
{
Serial.print("ch1 ");
Serial.print(rc_1.control_in, DEC);
Serial.print("\tch2: ");
Serial.print(rc_2.control_in, DEC);
Serial.print("\tch3 :");
Serial.print(rc_3.control_in, DEC);
Serial.print("\tch4 :");
Serial.print(rc_4.control_in, DEC);
}