Skip to content

SBUS support for BeagleBone Blue #218

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions examples/src/rc_calibrate_sbus.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* @example rc_calibrate_sbus.c
*
* Running the rc_calibrate_sbus example will print out raw data to
* the console and record the min and max values for each
* channel. These limits will be saved to disk so future sbus reads
* will be scaled correctly.
*
* Make sure the transmitter and receiver are paired before
* testing. The satellite receiver remembers which transmitter it is
* paired to, not your BeagleBone.
*/

#include <stdio.h>
#include <rc/sbus.h>

int main()
{
printf("Please connect a SBUS satellite receiver and make sure\n");
printf("your transmitter is on and paired to the receiver.\n");
printf("\n");
printf("Do you want to proceed Y/N : \n");
char input = getchar();

if(input == 'Y' || input == 'y')
{
// run the calibration routine
rc_sbus_calibrate_routine();
}
else
{
printf("SBUS Calibration Program Terminated\n");
}

return 0;
}
176 changes: 176 additions & 0 deletions examples/src/rc_sbus_passthrough.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/**
* @example rc_sbus_passthrough.c
*
* This sends all sbus data straight out the servo channels as they
* come in. When running this program the BBB acts exactly like a
* normal SBUS receiver.
*
* You must specify SERVO or ESC mode with -s or -e to turn on or off
* the 6V power rail. Sending 6V into an ESC may damage it!!!
*
* Raw data is also printed to the terminal for monitoring.
*/

#include <stdio.h>
#include <getopt.h>
#include <signal.h>
#include <rc/sbus.h>
#include <rc/servo.h>
#include <rc/time.h>
#include <rc/adc.h>

#define BATT_VOLTAGE 6.0 // change this if using different battery

static int running;

typedef enum p_mode_t{
NONE,
POWERON,
POWEROFF
} p_mode_t;

// function to be called every time new a new SBUS packet is received.
static void __send_pulses(void)
{
int i, val;

// send single to working channels
for(i=1; i<=8; i++){
val=rc_sbus_ch_raw(i);
if(val>0) rc_servo_send_pulse_us(i,val);
}

// print all channels
printf("\r");
for(i=1;i<=RC_MAX_SBUS_ANALOG_CHANNELS;i++){
val = rc_sbus_ch_raw(i);
if (val != 0) {
printf("% 4d ", val);
}
}
for(i=1;i<=RC_MAX_SBUS_BINARY_CHANNELS;i++){
printf("% 1d ", rc_sbus_ch_binary(i));
}
fflush(stdout);
return;
}

// interrupt handler to catch ctrl-c
static void __signal_handler(__attribute__ ((unused)) int dummy)
{
running=0;
return;
}


// printed if some invalid argument was given
static void __print_usage(void)
{
printf("\n");
printf(" Options\n");
printf(" -s Enable power rail for servos.\n");
printf(" -e Disable power rail for ESCs.\n");
printf("Note: Please select only one mode at a time.\n");
printf(" -h Print this messege.\n\n");
return;
}

// main routine
int main(int argc, char *argv[])
{
int c;
p_mode_t mode = NONE;

// parse arguments
opterr = 0;
while ((c = getopt(argc, argv, "seh")) != -1){
switch (c){

case 's': // enable power for servos
mode = POWERON;
break;

case 'e': // disbable power for ESCs
mode = POWEROFF;
break;

case 'h': // show help messege
__print_usage();
return -1;
break;

default:
fprintf(stderr,"Invalid Argument \n");
__print_usage();
return -1;
}
}

if(mode == NONE){
fprintf(stderr,"You must select a power mode -s or -e\n");
__print_usage();
return -1;
}

if(rc_sbus_init()==-1) return -1;

// if power has been requested, make sure battery is connected!
if(mode == POWERON){
// read adc to make sure battery is connected
if(rc_adc_init()){
fprintf(stderr,"ERROR: failed to run rc_adc_init()\n");
return -1;
}
if(rc_adc_batt()<BATT_VOLTAGE){
fprintf(stderr,"ERROR: battery disconnected or insufficiently charged to drive motors\n");
return -1;
}
rc_adc_cleanup();

if(rc_servo_init ()){
fprintf(stderr,"failed to initialize servos\n");
return -1;
}
if(rc_servo_power_rail_en(1)){
fprintf(stderr,"failed to enable power rail\n");
return -1;
}
}

// print header
printf("1:Thr ");
printf("2:Roll ");
printf("3:Pitch ");
printf("4:Yaw ");
printf("5:Kill ");
printf("6:Mode ");
printf("7:Aux1 ");
printf("8:Aux2 ");
printf("\n");

printf("Waiting for SBUS Connection");
fflush(stdout);

// set signal handler so the loop can exit cleanly
signal(SIGINT, __signal_handler);
running=1;

rc_sbus_set_callback(&__send_pulses);
while(running){
if(rc_sbus_is_connection_active()==0){
printf("\rSeconds since last SBUS packet: ");
printf("%0.1f ", rc_sbus_nanos_since_last_packet()/1000000000.0);
printf(" ");
fflush(stdout);
}
rc_usleep(25000);
}
printf("\n");

if(mode == POWERON){
rc_servo_cleanup ();
}
rc_sbus_cleanup();

return 0;
}
159 changes: 159 additions & 0 deletions examples/src/rc_test_sbus.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/**
* @example rc_test_sbus.c
*
* Prints out the normalized sbus values. Make sure the transmitter
* and receiver are paired before testing. The satellite receiver
* remembers which transmitter it is paired to, not your BeagleBone.
*
* If the values you read are not normalized between +-1, then you
* should run the rc_calibrate_sbus example to save your particular
* transmitter's min and max channel values.
*/

#include <stdio.h>
#include <signal.h>
#include <getopt.h>
#include <rc/sbus.h>
#include <rc/time.h>

// possible printing modes, user selected with command line arguments
typedef enum p_mode_t{
P_MODE_NONE,
P_MODE_RAW,
P_MODE_NORM
} p_mode_t;

static int running = 0;
static p_mode_t print_mode;

// printed if some invalid argument was given
static void __print_usage(void)
{
printf("\n");
printf("-r print raw channel values in microseconds\n");
printf("-n print normalized channel values/s\n");
printf("-h print this help message\n");
printf("\n");
}

// interrupt handler to catch ctrl-c
static void __signal_handler(__attribute__ ((unused)) int dummy)
{
running=0;
return;
}

static void __new_sbus_data_callback(void)
{
int i,v;
printf("\r");// keep printing on same line
// print all channels
if(print_mode==P_MODE_NORM){
for(i=0;i<RC_MAX_SBUS_ANALOG_CHANNELS;i++){
if (rc_sbus_ch_raw(i+1) != 0) {
printf("%d:% 0.2f|", i+1, rc_sbus_ch_normalized(i+1));
}
}
}
else{
for(i=0;i<RC_MAX_SBUS_ANALOG_CHANNELS;i++){
v=rc_sbus_ch_raw(i+1);
if (v != 0) {
printf("%d:%4d|", i+1, rc_sbus_ch_raw(i+1));
}
}
}
for(i=0;i<RC_MAX_SBUS_BINARY_CHANNELS;i++){
printf("%d:%1d|", i+RC_MAX_SBUS_ANALOG_CHANNELS+1, rc_sbus_ch_binary(i+1));
}
printf("SQ:%d|FL:%d|TE:%d",
rc_sbus_signal_quality (), rc_sbus_lost_frames (), rc_sbus_total_errors ());
fflush(stdout);
}

int main(int argc, char *argv[])
{
int c;
print_mode = P_MODE_NONE;

// parse arguments
opterr = 0;
while ((c = getopt(argc, argv, "rnh")) != -1){
switch (c){
case 'r':
if(print_mode!=P_MODE_NONE){
printf("\ntoo many arguments given\n");
__print_usage();
return -1;
}
print_mode = P_MODE_RAW;
break;
case 'n':
if(print_mode!=P_MODE_NONE){
printf("\ntoo many arguments given\n");
__print_usage();
return -1;
}
print_mode = P_MODE_NORM;
break;
break;
case 'h':
__print_usage();
return 0;
default:
fprintf(stderr,"Invalid Argument\n");
__print_usage();
return -1;
}
}

if(print_mode==P_MODE_NONE){
fprintf(stderr, "Please select raw or normalized mode\n");
__print_usage();
return -1;
}


if(rc_sbus_init()) return -1;

printf("\n");
printf("Make sure transmitter and receiver are bound and on.\n");
printf("If data is received, the normalized values will be printed\n");
printf("here along with the bit resolution and the number of channels\n");
printf("\n");
printf("If connection is lost the number of seconds since last packet\n");
printf("will be displayed\n");
printf("\n");

// set signal handler so the loop can exit cleanly
signal(SIGINT, __signal_handler);
running =1;

printf("Waiting for first packet");
fflush(stdout);
while(rc_sbus_is_new_data()==0){
if(running==0){
rc_sbus_cleanup();
return 0;
}
rc_usleep(50000);
}

// first packet arrived, set the callback and run
rc_sbus_set_callback(__new_sbus_data_callback);

// main loop monitor if connection is active or now
while(running){
if(rc_sbus_is_connection_active()==0){
printf("\rSeconds since last SBUS packet: ");
printf("%0.1f ", rc_sbus_nanos_since_last_packet()/1000000000.0);
printf(" ");
fflush(stdout);
}
rc_usleep(500000);
}

rc_sbus_cleanup();
printf("\n");
return 0;
}
2 changes: 2 additions & 0 deletions library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ if(DEFINED __RC_V0_3)
other/rc_bb_model.c
other/rc_cpu_freq.c
other/rc_dsm.c
other/rc_sbus.c
other/rc_other.c
other/rc_pinmux.c
other/rc_pru.c
Expand All @@ -52,6 +53,7 @@ else()
src/button.c
src/cpu.c
src/dsm.c
src/sbus.c
src/led.c
src/mavlink_udp.c
src/model.c
Expand Down
Loading