Objective: Create a foot pad controller using an arduiono system that will activate w,a,s,d keydown functions when the controller is tilted.
Parts:
Arduino MKR 1010 wifi
Adafruit BNO085 9DOF IMU
breadboard
LED
on/off switch
jumper wires
skateboard (or similar plank)
balance block (I used a 10/6/3in foam yoga block)
Method:
The Adafruit BNO085 9DOF imu can output tilt over the x,y,z axis. This can send output data via I2C to an Arduino board. I'm using the MKR 1010 wifi because it is compatable with the keyboard.h library. This library allows the arduino to send out keystrokes such that when it is pluggedd into a computer it is recognized as an external keyboard.
The IMU board's SDA and SCL are wired to pins 11 and 12 of the arduino. The IMU is powerd by the 5V of the Arduino and grounded as well.
The on/off switch is wired to arduino pin 7 ising its pullup resistor, and ground such that when the switch is closed, pin7 is grounded and LOW. When the switch is open the pin 7 is high
I've wired an LED to arduino pin 5 using a 220phm resistor. This will light when the board is on and in the neutral zone.
The code is below and flows like this:
when the on/off switch is closed pin 7 is grounded/LOW and the arduino enters a while loop that has the code. When the switch is open the boards are powered but nothing else is happening.
In the while loop, the x and z gyrometer data is collected using the Adafruit BNO8x.h library's SH2_GAME_ROTATION_VECTOR and stored to variables. if/else if statements then analyze this data.
There are 9 possible gyrometer positions:
center or neutral zone
up (w), down (s), left (a), right (d).
and the 4 corners (wa, wd, sa, sd).
as defined by either positive or negative rotation around the x axis or positive or negative rotation around the z axis.
I started by connecting the boards and printing the IMU data to the Arduino IDE serial port using serial.print. From this I determined that a forward tilt greater than 0.2 should trigger a 'w' and a backward tilt of -0.2 should trigger an 's'. Luckily it was the was the same +- 0.2 to trigger either 'a' or 's'. This defines the neutral zone as a square from -0.2 to 0.2 in both directions. In addition drift / inappropriate trigger did not happen in this zone.
The if/else statements first analyze for the corners and then for up,down,left,right and the final else is the neutral zone.
for each condition 3 things occur:
release all the other buttons
press the desired button
turn on or off the neutral zone LED. (this LED is on when the plank is in the neutral zone. It is a nice way to ensure that you aren't accidentally sending a keypress). The neutral zone LED goes off when any keypress event is being sent or if the board is outside of the while loop.) and note that the MKR onboard LED is set to on when inside the while loop and off when outside (as toggled by the on/off switch).
I considered using switch/case rather than if/else however switch/case required integers and the imu data is decimals thus requiring float variables.
I was initially going to run this entire setup using an Arduino nano which has an onboard imu however the keyboard.h library isn't compatable w the nano (or at least i couldn't get it to work).
Having the on/off switch and associated while loop is really important. It allows you to keep the board plugged into the computer without worrying about it accidentally sending keypress events.
tedd 3/28/2021
the code