![]() |
Working Controller Plug and Play
1 Attachment(s)
Hi all
If the filesystem wasn't weird enough, I have yet another piece (a rather large piece) of code to share with you. During this year I implemented a kind of Plug and Play interface for controllers. Essentially, it tries to mimic the behaviour of controllers on a PC. What I mean is, you can plug in a set of controllers into any port on the OI and without any recompiling your code, and your controllers will do the same thing they did before even if they weren't plugged in the same spot. :ahh: But there is more, the code also detects whether buttons are pressed or released or are being held. It also provides a way to quickly switch between controller configurations for different drivers. So if I want to use an XBOX controller, but my friend wants to use 2 joysticks, the framework allows you to program in two different configurations and switch between them on the fly. Also, it contains a configurable analog noise filter and a configurable deadband. Of course, adding this framework to your project might be slightly difficult as it requires a few low level things to be done. I highly recommend you make a backup of your code before trying to add this to your project as we will be changing a lot of the "Do not change" sections. Warning: If you have data in your EEPROM it will be erased as the filesystem must be used with HAL. See my thread on the filesystem to learn how it works and how to use it. Prerequisites: 1. Kevin's Serial Port Code 2. Kevin's EEPROM Code Installation Guide: 1. Download the zip file below and unzip the files into a new folder. 2. Open your MPLAB project 3. Open ifi_aliases.h and delete all the #defines as listed in the Removed ifi_aliases.txt file given to you 4. Open ifi_default.h, and find the rx_data_record structure 5. Replace it with the structure found in the given Rx_Data_Record.txt file 6. Add all the other *.c and *.h files to your project 7. Open Timer Interrupt Handler.txt and copy the code into your InterruptHandlerLow(). Be sure to #include "timers.h" into the file containing you InterruptHandleLow() routine. 8. Remove your slow/fast loops, they are no longer needed and will break the new code. Get/Putdata are handled in the timer interrupt. See below for timing help. Configuring the Code: When the robot starts up, it has to initialize the HAL subsystem and it has to find a writable filesystem on the EEPROM. The following code will initalize the filesystem and HAL. Code:
#include "hal.h"By default HAL has builtin drivers for a joystick and an xbox controller. It also provides support for custom control boxes, but for that you will have to write your own driver for that. If you just use joysticks, the hard part is done, if you use the USB chicklet however, you must tell HAL your USB chicklet mappings. To do this, open xbox.c and find: Code:
Code:
#define XBOX_BUTTON_LOGO CONTROLLER_TYPE_XBOX | 0x00#define MAP_AUX1_BIT_1 XBOX_SHOULDER_LEFT_1 to #define MAP_AUX1_BIT_1 XBOX_BUTTON_LOGO Your input drivers are now configured. The next thing you must do is assign tasks to your buttons. This is done in hal_out.c. This file contains all the output drivers. An output driver is essentially a controller configuration. If you wanted two configurations you'de have two output drivers. Three drivers are provided by default. They are: a null output driver that does nothing, HAL_Out_AAP, the driver we used during the competition, and HAL_Out_Analog, the analog output driver. To create your own output driver you must make a function with the following prototype: Code:
void HAL_Out_MyDriver(unsigned char exec, unsigned char subid){...}To act on a certain button press, an if statement can be used to compare the exec byte to the defined buttons in joystick.h and xbox.h. Examples follow bellow: Code:
void HAL_Out_MyDriver(unsigned char exec, unsigned char subid){Code:
const rom hal_output_driver drivers_out[STUDENT_DRIVERS] = { &HAL_Out_AAP };Code:
const rom hal_output_driver drivers_out[2] = { &HAL_Out_AAP, &HAL_Out_MyDriver };Code:
HAL_Load_Student_Driver(1);The last step is to call the HAL function everytime new data is sent to the controller. Ideally you'de call HAL() every 26ms, but I'de recommend 13ms for safety. You'll notice HAL() takes one argument, simply send NULL to it since that was used for our task scheduler code. Your function call should look like this: Code:
HAL(NULL);When you restart the robot the configuration will be read out of the EEPROM and you will never have to configure again unless you change your controllers around. To force a reconfiguration, press any button on any controller and reset the robot. You're now done! :D Timing Issues: As you noticed, this code requires our timer code to be used. This code will get rid of the need for slow/fast loops since it handles Get/Putdata for you. This may make timing things like HAL a little tricky. The solution is to use our dynamic timer support. Simply put, dynamic timers run off the main system timer and can have custom intervals set to them. A simple timing example is presented below for HAL. Code:
Even more configuration Options: In hal.h, you are given 7 defines that let you enable/disable/tune the analog noise/deadband filters. These are: Code:
/* Deadband filter options */#define HAL_CONFIG_FILE 0 the proper file number. HAL will choose a default output drive at startup, this can be changed by changing: #define HAL_DEFAULT_DRIVER 0 to the correct output driver. Other defines that are important, but work well with the defaults are: Code:
/* Default time to wait for controller responses (seconds) */P.S. You'll notice I included our modified ifi_* files.. Use them at your own risk, they've been heavily modified to save on codespace and to make our systems work better for us. P.P.S. I apologize if I forgot to tell you something important. |
Re: Working Controller Plug and Play
Great Job
|
Re: Working Controller Plug and Play
That is really impressive; I have never even contemplated doing that.
|
| All times are GMT -5. The time now is 20:15. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi