Nano33 BLE Sense data as Keyboard Output

I wanted to make a simple tilt controller using the gyro/accelerometer on my Nano33 BLE Sense to get the orientation and turn that data into WASD inputs. (Tilting right = press 'd', Tilting Left = press 'a')

But I only realised that I can't use the default <Keyboard.h> on Nano series after I started coding for it. So I've replaced the keyboard input with Serial.print for now and it types out the WASD when I rotate in Serial Monitor but obviously it doesn't work as keyboard input to play games. Is there a way around this? How do I use these as proper inputs for the computer?

CODE

#include <Arduino_LSM9DS1.h>

float x, y, z;
int degreesX = 0;
int degreesY = 0;

void setup() {
  Serial.begin(9600);
   while (!Serial);

 if (!IMU.begin()) {
Serial.println("ERROR: Failed to initialize IMU!");
while (1);
 }
}


void loop() {

if (IMU.accelerationAvailable()) {
IMU.readAcceleration(x, y, z);
if (x == 0){
  Serial.print("null");
}
if (x > 0.1) {
  x=100*x;
  degreesX = map(x, 0, 97, 0, 90);
  if (degreesX >= 1)
  Serial.print('w');
}

if (x < -0.1) {
  x=100*x;
  degreesX = map(x, 0, 100, 0, 90);
  if (degreesX >= -90)
  Serial.print('s');
}

if (y > 0.1) {
  y=100*y;
  degreesY = map(y, 0, 97, 0, 90);
  if (degreesY >= 1)
  Serial.print('a');
}

if (y < -0.1) {
  y=100*y;
  degreesY = map(y, 0, 100, 0, 90);
  if (degreesY > -90)
  Serial.print('d');
}

 delay(100);

 }
 }

I added #include <Keyboard.h> to your sketch and got the following error when compiling for an 'Arduino Nano 33 BLE':

In file included from /Users/john/Documents/Arduino/sketch_aug24a/sketch_aug24a.ino:2:0:
/Applications/Arduino1.8.13.app/Contents/Java/libraries/Keyboard/src/Keyboard.h:25:10: fatal error: HID.h: No such file or directory
 #include "HID.h"
          ^~~~~~~
compilation terminated.

I think that means that the Nano 33 BLE can't emulate a USB keyboard? Maybe it can emulate a bluetooth keyboard but I don't see a built-in library for that.

1 Like

Welcome to the forum.

Have a look at the following post:

https://forum.arduino.cc/t/arduino-nano-33-ble-sense-hid/675014

Just in case, the board support package for the Arduino Nano 33 BLE has changed since this was posted. Let us know if you get any errors.

Edit: Just tested it on my board and it still works as expected.

1 Like

I tried using Mbed and USBKeyboard.h but it wasn't working as well as i thought.

So i was digging around a bit more and I found this guy using Nano33 for his media controller using gestures,

Apparently Mbed and USB keyboard isn't as intuitive than the default Keyboard.h and he had to add more codes in setups and at the end so it doesn't override the user redefinition (???) Honestly I don't really understand what's going on but he shared his code an I used it as a template and I managed to modified the code for gyroscope and I got it working.

Right now it's just a loop to 'push down' the button so it's kind of annoying to go through the game menus but if it's flat on the ground it doesn't do anything and you can use the mouse to navigate

#include <Arduino.h>
#include "mbed.h"
#include "USBKeyboard.h"
#include <Arduino_LSM9DS1.h>

USBKeyboard key;

float x, y, z;
int degreesX = 0;
int degreesY = 0;

// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) {
 return 0;
}
// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }
void setupUSB() __attribute__((weak));
void setupUSB() { }

void setup() {ds
 pinMode(13, OUTPUT);
 digitalWrite(13, HIGH);
 if (!IMU.begin()) {
digitalWrite(13, LOW);
Serial.println("ERROR: Failed to initialize IMU!");
}
}


void loop() {

 if (IMU.accelerationAvailable()) {
IMU.readAcceleration(x, y, z);

if (x == 0) {
  Serial.print("0");
}

if (x > 0.1) {
  x = 100 * x;
  degreesX = map(x, 0, 97, 0, 90);
  if (degreesX >= 1) {
    key.key_code('w');
  }
}

if (x < -0.1) {
  x = 100 * x;
  degreesX = map(x, 0, 100, 0, 90);
  if (degreesX >= -90) {
    key.key_code('s');
  }
}

if (y > 0.1) {
  y = 100 * y;
  degreesY = map(y, 0, 97, 0, 90);
  if (degreesY >= 1) {
    key.key_code('a');
  }
}

if (y < -0.1) {
  y = 100 * y;
  degreesY = map(y, 0, 100, 0, 90);
  if (degreesY > -90) {
    key.key_code('d');
  }
}
// Change the delay value to change sensitivity. But longer delays make the 'press' a bit jittery. 
// Might be better to change in game sensitivity
delay(17);
 }
}

int main(void)
{
  init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
 setup();
for (;;) {
 loop();
 if (serialEventRun) serialEventRun();
}
return 0;
}