make_drone_controller
DJI Flight Simulator
Manual
14 buttons
BOM
Item | Qty | Price/p | Link | - |
---|---|---|---|---|
Seeeduino Xiao | 1 | 5.40 USD | Seeed | |
IO Expander MCP23017 | 1 | 1.44USD | Aliexpress | |
Push switch MS312 | 12 | 1 USD | Sato Denki | |
Toggle switch 3P MS500EB momentary(ON)-OFF-(ON) | 1 | 2 USD | Sato Denki | |
Joystick | 2 | 9 USD/5p | Amazon |
I2C I/O Expander MCP23017
- Xiao: 11 pins
- 2x2 pin for analog Joysticks(L R)
- 7 pins left
- 7 buttons or 3x4=12 matrix buttons
MCP23017
Xiao -(I2C)- MCP23017- 16 pins
Pin Name | Pin No. |
---|---|
GPA0 | 0 |
GPA1 | 1 |
GPA2 | 2 |
GPA3 | 3 |
GPA4 | 4 |
GPA5 | 5 |
GPA6 | 6 |
GPA7 | 7 |
GPB0 | 8 |
GPB1 | 9 |
GPB2 | 10 |
GPB3 | 11 |
GPB4 | 12 |
GPB5 | 13 |
GPB6 | 14 |
GPB7 | 15 |
Library
Adafruit MCP23017 Arduino Library
#include <Wire.h>
#include <Adafruit_MCP23017.h>
Adafruit_MCP23017 mcp;
//Adafruit_MCP23017 mcp1;// add more secondary
/*Expander I2C address
A0 A1 A2 address
0 0 0 0x00
1 0 0 0x01
0 1 0 0x02
1 1 0 0x03
0 0 1 0x04
1 0 1 0x05
0 1 1 0x06
1 1 1 0x07
*/
void setup(){
mcp.begin();// use default address 0
//mcp1.begin(0x01);// use other address
mcp.pinMode(0, INPUT);
mcp.pullUp (0, HIGH); // turn on a 100K pullup internally
// mcp1.pinMode(0, OUTPUT);//if output
}
uint8_t Key0;
void loop(){
Key0 = mcp.digitalRead(0);
//Key16 = mcp1.analogRead(0);//if analog
if (Key0 == LOW ){
Key0_act();
}
}
void Key0_act() {
//key command
}
Analog Joystick
// Right Joystick
int vertPin_R = 9; // Analog output of Vertical joystick pin
int horzPin_R = 10; // Analog output of horizontal joystick pin
int vertValue_R, horzValue_R;
int threshold_small = 300;
int threshold_large = 800;
void loop(){
vertValue_R = analogRead(vertPin_R);
horzValue_R = analogRead(horzPin_R);
if (horzValue_R < threshold_small) {
//Serial.print("<<:"); Serial.println(horzValue_R);//check direction
Key0_act(); //<
}
if (horzValue_R > threshold_large) {
//Serial.print(">>:"); Serial.println(horzValue_R);
Key1_act(); //>
}
if (vertValue_R < threshold_small / 1.1) {
//Serial.print("UP:"); Serial.println(vertValue_R);
Key2_act(); //^
}
if (vertValue_R > threshold_large) {
//Serial.print("DN:"); Serial.println(vertValue_R);
Key3_act(); //v
}
void Key0_act() {
//key command
}
}
PCB
Hardware
Program
Library
#include <TinyUSB_Mouse_and_Keyboard.h>
Adafruit MCP23017 Arduino Library
#include <Wire.h>
#include <Adafruit_MCP23017.h>
Arduino sketch
#include <TinyUSB_Mouse_and_Keyboard.h>
//IO Expander
#include <Wire.h>
#include <Adafruit_MCP23017.h>
Adafruit_MCP23017 mcp;
//Joystick pins
int horzPin_R = 0; // Analog output of horizontal joystick pin
int vertPin_R = 1;
int horzPin_L = 10; // Analog output of horizontal joystick pin
int vertPin_L = 9;
int vertValue_R, horzValue_R;
int vertValue_L, horzValue_L;
int threshold_small = 300;
int threshold_large = 800;
// Buttons
uint8_t pins[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
uint8_t pincount = sizeof(pins) / sizeof(pins[0]);
uint8_t Key0;
uint8_t Key1;
uint8_t Key2;
uint8_t Key3;
uint8_t Key4;
uint8_t Key5;
uint8_t Key6;
uint8_t Key7;
uint8_t Key8;
uint8_t Key9;
uint8_t Key10;
uint8_t Key11;
uint8_t Key12;
uint8_t Key13;
uint8_t Key14;
uint8_t Key15;
uint8_t KeyXiao2;
uint8_t KeyXiao8;
void setup() {
//keyboard
Keyboard.begin();
Serial.begin(9600);
pinMode(2, INPUT_PULLUP);//joystick button_R
pinMode(8, INPUT_PULLUP);//joystick button_L
/*Expander I2C address
A0 A1 A2 address
0 0 0 0x00
1 0 0 0x01
0 1 0 0x02
1 1 0 0x03
0 0 1 0x04
1 0 1 0x05
0 1 1 0x06
1 1 1 0x07
*/
//IO Expander
mcp.begin();// use default address 0
for (uint8_t i = 0; i < pincount; i++)
{
mcp.pinMode(pins[i], INPUT);// mcp.pinMode(0, INPUT);//A0=0,A7=7,B0=8,B7=15
mcp.pullUp(pins[i], HIGH); // mcp.pullUp(0, HIGH);// turn on a 100K pullup internally
}
pinMode(LED_BUILTIN, OUTPUT); // use the p13 LED as debugging
}
void loop() {
//Xiao joystick
vertValue_R = analogRead(vertPin_R);
horzValue_R = analogRead(horzPin_R);
vertValue_L = analogRead(vertPin_L);
horzValue_L = analogRead(horzPin_L);
//Xiao button
KeyXiao2 = digitalRead(2);//joystick button_R
KeyXiao8 = digitalRead(8);//jopystik button_L
//KeyXiao3 = digitalRead(3);//empty
//KeyXiao6 = digitalRead(6);//empty
//KeyXiao7 = digitalRead(7);//empty
//IO Expander
Key0 = mcp.digitalRead(0);
Key1 = mcp.digitalRead(1);
Key2 = mcp.digitalRead(2);
Key3 = mcp.digitalRead(3);
Key4 = mcp.digitalRead(4);
Key5 = mcp.digitalRead(5);
Key6 = mcp.digitalRead(6);
Key7 = mcp.digitalRead(7);
Key8 = mcp.digitalRead(8);
Key9 = mcp.digitalRead(9);
Key10 = mcp.digitalRead(10);
Key11 = mcp.digitalRead(11);
Key12 = mcp.digitalRead(12);
Key13 = mcp.digitalRead(13);
Key14 = mcp.digitalRead(14);
Key15 = mcp.digitalRead(15);
// Motor ON
if (vertValue_R > threshold_large && horzValue_R < threshold_small &&
vertValue_L < threshold_small && horzValue_L < threshold_small)
{
Serial.println("Motor ON:");
Key8_act();
} else {
// Joystic right
if (horzValue_R < threshold_small) {
Serial.print("<<:"); Serial.println(horzValue_R);
Key0_act();
}
if (horzValue_R > threshold_large) {
Serial.print(">>:"); Serial.println(horzValue_R);
Key1_act();
}
if (vertValue_R < threshold_small / 1.1) {
Serial.print("UP:"); Serial.println(vertValue_R);
Key2_act();
}
if (vertValue_R > threshold_large) {
Serial.print("DN:"); Serial.println(vertValue_R);
Key3_act();
}
//Joystic left
if (horzValue_L < threshold_small) {
Serial.print("D>:"); Serial.println(horzValue_L);
Key4_act();
}
if (horzValue_L > threshold_large) {
Serial.print("<A:"); Serial.println(horzValue_L);
Key5_act();
}
if (vertValue_L < threshold_small) {
Serial.print("Sv:"); Serial.println(vertValue_L);
Key6_act();
}
if (vertValue_L > threshold_large) {
Serial.print("W^:"); Serial.println(vertValue_L);
Key7_act();
}
//IO Extention
if (Key14 == LOW ) {//Pause
Keyboard.write('p');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key10 == LOW ) {//Shutter
Keyboard.write('h');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key6 == LOW ) {//record/stop
Keyboard.write('l');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key8 == LOW ) {//flight route
Keyboard.write(' ');//space
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key4 == LOW ) {//return home/cancel
Keyboard.write('o');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key5 == LOW ) {//jump
Keyboard.write(' ');//space
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key1 == LOW ) {//custom menu
Keyboard.press(KEY_RETURN);//enter
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key3 == LOW ) {//Gimbal Upward
Keyboard.write('r');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key2 == LOW ) {//Gimbal Down
Keyboard.write('f');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key12 == LOW ) {//switch view
Keyboard.write('c');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key7 == LOW ) {//flight mode
Keyboard.write('v');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key11 == LOW ) {//switch btm drone/pilot
Keyboard.write('j');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key9 == LOW ) {//minimap
Keyboard.write('m');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key13 == LOW ) {//indroducton panel
Keyboard.write('i');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
if (Key0 == LOW ) {
// not connected
}
if (Key15 == LOW ) {
// not connected
}
if (KeyXiao2 == LOW ) {//joystick button_R
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
}
if (KeyXiao8 == LOW ) {//joystick button_L
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
}
}
}
void Key0_act() {
Keyboard.press(KEY_LEFT_ARROW);
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
void Key1_act() {
Keyboard.press(KEY_RIGHT_ARROW);
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
void Key2_act() {
Keyboard.press(KEY_UP_ARROW);
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
void Key3_act() {
Keyboard.press(KEY_DOWN_ARROW);
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
void Key4_act() {
Keyboard.write('d');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
void Key5_act() {
Keyboard.write('a');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
void Key6_act() {
Keyboard.write('s');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
void Key7_act() {
Keyboard.write('w');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
void Key8_act() {
Keyboard.press(KEY_LEFT_ARROW);
Keyboard.press(KEY_DOWN_ARROW);
Keyboard.write('d');
Keyboard.write('s');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
void KeyE0_act() {
Keyboard.write('0');
delay(400);
Keyboard.releaseAll();
KeyRelease();
}
void KeyRelease() {
Keyboard.releaseAll();
delay(500);
}
/*
*/