Computer Programming

1. Send data to a computer and write code to display results (e.g., visualization of sensor data, browser-based game with microcontroller-based interactions, etc.)

This week's project has a lot of applicability to my final project, so I used it to prototype one function I want in my final project. Previously in Internet of Things week, I figured out how to get my microcontroller to connect to my phone over BLE and send data using a specific app. For this week, I wanted to use BLE again, but this time send keypresses to my computer. Some research led me to this ESP32 BLE Keyboard library. The features included "Send key strokes," which was good, but it also said " Compatible with MacOS X (not stable, some people have issues, doesn't work with old devices)" which was... more worrying.

I started with their example code to see if I could get it running. The example code is in the README of the Github repo linked above, but I'll duplicate it here for the sake of completeness.

/**
 * This example turns the ESP32 into a Bluetooth LE keyboard that writes the words, presses Enter, presses a media key and then Ctrl+Alt+Delete
 */
#include <BleKeyboard.h>

BleKeyboard bleKeyboard;

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  bleKeyboard.begin();
}

void loop() {
  if(bleKeyboard.isConnected()) {
    Serial.println("Sending 'Hello world'...");
    bleKeyboard.print("Hello world");

    delay(1000);

    Serial.println("Sending Enter key...");
    bleKeyboard.write(KEY_RETURN);

    delay(1000);

    Serial.println("Sending Play/Pause media key...");
    bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE);

    delay(1000);
    
   //
   // Below is an example of pressing multiple keyboard modifiers 
   // which by default is commented out. 
   // 
   /* Serial.println("Sending Ctrl+Alt+Delete...");
    bleKeyboard.press(KEY_LEFT_CTRL);
    bleKeyboard.press(KEY_LEFT_ALT);
    bleKeyboard.press(KEY_DELETE);
    delay(100);
    bleKeyboard.releaseAll();
    */

  }
  Serial.println("Waiting 5 seconds...");
  delay(5000);
}

Great luck! After just a bit of finangling, "MyESP32" showed up in the Bluetooth list on my computer. And immediately caused some chaos, since the program types "Hello world" then presses the Play/Pause button on repeat. Once I muted my sound and removed the several Hello worlds from my code, I turned to writing something more specific. I had proven that I could send keypresses from my microcontroller to my laptop, but this wasn't a particularly great way of visualizing that data.

"Browser-based game" from this week's prompt sounded interesting, and the p5.js examples were neat, so I started there. I used art from GameArtGuppy and a few of the animation examples from the p5.js play library and came up with this simple game. It's controlled using WASD, so I needed to make my microcontroller send WASD commands to my computer.

This was just a mattter of combining things I already knew how to do. I wired up four buttons (tragically, the Feather doesn't have built-in resistors) and tweaked the code to match:

#include <BleKeyboard.h>
BleKeyboard bleKeyboard;

int buttonPins[] = {14, 32, 15, 33};

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  bleKeyboard.begin();

  for (int i = 0; i < 4; i++) {
    pinMode(buttonPins[i], INPUT);
  }
  bleKeyboard.setDelay(20);
}


void loop() {
  if (bleKeyboard.isConnected()) {
    if (digitalRead(buttonPins[0])) {
      bleKeyboard.write('w');
    } else if (digitalRead(buttonPins[1])) {
      bleKeyboard.write('a');
    } else if (digitalRead(buttonPins[2])) {
      bleKeyboard.write('s');
    } else if (digitalRead(buttonPins[3])) {
      bleKeyboard.write('d');
    }
  } else {
    Serial.println("ESP32 not connected! check your BLE");
    delay(2000);
  }
}

Success! I could now jump my frog around using the buttons without physical attachment to my computer. I experimented a little bit with how far away I could get, and managed to get about halfway across the classroom before it became unreliable.