Xbox Controlled Camera Bot


Pi 4/ LPC1768 bot with Pi camera controlled by Xbox controller

You are viewing an older revision! See the latest version

xbox controlled camera bot

Table of Contents

  1. Wiring

Wiring

mbedhbridgeleft motorright motorDC battery pack
VOUTVCC
VM4.8V to 6V
gndgnd
AO1red
AO2black
BO1red
BO2black
p23PWMA
p24PWMB
p30AI1
p29AI2
p5BI1
p6BI2
VOUTSTBY
mbedtop servobottom servoDC battery pack
gndgnd (brown)gnd (brown)gnd
power (red)power (red)4.8V to 6V
p25signal (orange)
p26signal (orange)
mbedleft motor encoderright motor encoder
VUpower (red)power (red)
gndgnd (black)gnd (black)
p22signal (white)
p21signal (white)

Raspberry Pi Xbox Controller Interface

/**
 * The purpose of this program is to take advantage of the joystick api to read
 * in the inputs of an xbox controller on a raspberry pi and send them to the 
 * MBED via the COM port. The xbox controller is connected to the raspberry pi via
 * bluetooth and uses the xpadneo raspberry pi controller drivers. The API
 * documentation can be found here:
 * 
 * https://github.com/drewnoakes/joystick/blob/master/joystick-api.txt
 * 
 * The xpadneo xbox controller drivers can be found here:
 * 
 * https://atar-axis.github.io/xpadneo/
 * 
 * This program was written by Timothy Pierce as part of a group effort including
 * Loi Mac, Taia Modlin, and Nikhil Patel to create a spy bot. 
 */
 
#include <stdio.h>
#include <linux/joystick.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>

/*
 * This function will check that events are happening on the controller
 * to make sure the controller is connected.
 *  
 */
int controllerConnected(int fd, struct js_event *event)
{
    
    if (sizeof(*event) == read(fd, event, sizeof(*event))){
        return 1;
    }

    return -1;
}

//This struct stores the tag and movement data for each joystick action
struct botAction {
	char tag,movement;
};

//This struct stores the previous movement data for each joystick action
struct previousBotAction {
	char prevMovement;
};

/*
 * This function reads the controller input event, determines which joystick it is on, and determines which direction it is
 * For the left joystick the tag is '('
 * For the right joystick the tag is ')'
 * For the wheel motor movements 0=stop 1=forward and 2=reverse
 * 
 * For the directional pad controlling the camera direction, the tag is '!'
 * The servo movements are 0=stop, 1=left, 2=right, 3=up, and 4=down
 */
size_t controllerOutput(struct js_event *event, struct botAction action[7], struct previousBotAction prevAction[7])
{
	size_t joystick = event->number;
	prevAction[joystick].prevMovement = action[joystick].movement;

	if(joystick == 1){
		action[joystick].tag = '(';
		if(event->value > -2000 && event->value < 2000){
			action[joystick].movement = '0';
		}else if(event->value > 2000){
			action[joystick].movement = '2';
		} else if(event->value < -2000){
			action[joystick].movement = '1';
		} 
	} else if (joystick == 4) {
		action[joystick].tag = ')';
		if(event->value > -2000 && event->value < 2000){
			action[joystick].movement = '0';
		}else if(event->value > 2000){
			action[joystick].movement = '2';
		} else if(event->value < -2000){
			action[joystick].movement = '1';
		} 
	} else if (joystick == 6) {
		action[joystick].tag = '!';
		if(event->value > -2000 && event->value < 2000){
			action[joystick].movement = '0';
		}else if(event->value > 2000){
			action[joystick].movement = '2';
		} else if(event->value < -2000){
			action[joystick].movement = '1';
		} 
	} else if (joystick == 7) {
		action[joystick].tag = '!';
		if(event->value > -2000 && event->value < 2000){
			action[joystick].movement = '0';
		}else if(event->value > 2000){
			action[joystick].movement = '4';
		} else if(event->value < -2000){
			action[joystick].movement = '3';
		} 
	} 
	
	return joystick;
}

/*
 * This is the main function that will call the above functions and send the data 
 * to the MBED via the COM Port
 */
int main()
{
	struct js_event event;
	struct botAction action[7] = {0};
	struct previousBotAction prevAction[7] = {0};
	size_t joystick;
	int n;
	
	//Open the bluetooth port with the joystick
	int fdBT = open("/dev/input/js2", O_RDONLY);
	
	if(fdBT == -1){
		printf("No Joystick Found");
		return -1;
	}
	
	//Open the serial port with the mbed
	int fdCP = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);
	
	if (fdCP == -1) {  
		perror("open_port: Unable to open /dev/ttyACM0 - ");
		return(-1);
	}
	
	//Set the serial port settings
	struct termios options; 
	tcgetattr(fdCP,&options);   //Get current serial settings in structure
	cfsetspeed(&options, B9600);   //Change a only few
	options.c_cflag &= ~CSTOPB;
	options.c_cflag |= CLOCAL;
	options.c_cflag |= CREAD;
	cfmakeraw(&options);
	tcsetattr(fdCP,TCSANOW,&options);    //Set serial to new settings
	sleep(1);
	
	//Main loop to get the controller data and send it to the MBED
	while(controllerConnected(fdBT, &event) == 1)
	{
		if(event.type == JS_EVENT_AXIS){
			joystick = controllerOutput(&event, action, prevAction);
			if(joystick == 1 || joystick == 4 || joystick == 6 || joystick == 7)
			{
				if(prevAction[joystick].prevMovement != action[joystick].movement)
				{
					printf("%c%c\n", action[joystick].tag, action[joystick].movement);
					// Write to the port - just the tag
					n = write(fdCP,&action[joystick].tag,1);
					if (n < 0) {
						perror("Write failed - ");
						return -1;
					}
					
					//Write to the port - just the movement
					n = write(fdCP,&action[joystick].movement,1);
					if (n < 0) {
						perror("Write failed - ");
						return -1;
					}
				}
			}
		} 
		fflush(stdout);
	}
	
	close(fdBT);
	tcdrain(fdCP);
	close(fdCP);
	return 0;
}

All wikipages