🔍

ESP32/TTGO 1.2 gyroscope data to BLE to p5.js

sketch.js

let w, h;
let speed = 3;
let xpos = 222;
let ypos = 222;

function setup() {
  createCanvas(window.innerWidth, window.innerHeight);
  w = width;
  h = height;
}

function draw() {
  
  if (gamepad == undefined) {return;}
  readGamepadInput();

  background(222, 2);
  fill(22);
  noStroke();

  // add current magnitude to cursor pos
  xpos += gamepad.a1 * speed;
  ypos += gamepad.a2 * speed;

  
  // ignore stage bounds > space invaders sytle
  if (xpos < 0) { xpos = w;}
  if (ypos < 0) {ypos = h;}
  if (xpos > w) { xpos = 0;}
  if (ypos > h) { ypos = h;}

  // draw mirrored circles - cursor style
  circle(xpos, ypos, 133);
  circle(w - xpos, ypos, 133);
  circle(w - xpos, h - ypos, 133);
  circle(xpos, h - ypos, 133);
}

This comes as helpful library to manage the gamepad events in p5.js says Leonard.
gamepad.js

let controllers = [];
 
let gamepad;
 
// -------------------------------------
// ---------  READ CONTROLLER ----------------
// -------------------------------------
 
function initGamepad(e){
   
   console.log("Gamepad connected at index %d: %s. %d buttons, %d axes.",
    e.gamepad.index, e.gamepad.id,
    e.gamepad.buttons.length, e.gamepad.axes.length); 
    
  let gamepads = navigator.getGamepads();
 
  gamepad = gamepads[0];
   
  gamepad.btn1 = null;
  gamepad.btn2 = null;
  gamepad.btn3 = null;
  gamepad.btn4 = null;
  gamepad.btn5 = null;
  gamepad.a0 = 0;
  gamepad.a1 = 0;
  gamepad.a2 = 0;
  gamepad.a3 = 0;
  gamepad.a4 = 0;
  gamepad.a5 = 0;
  gamepad.a6 = 0;
  gamepad.a7 = 0;
   
}
 
 
// -------------------------------------
// ---------  READ CONTROLLER ----------------
// -------------------------------------
 
 
function readGamepadInput(){
  
  if(gamepad!=null){
     
    gamepad.a0 = gamepad.axes[0];
    gamepad.a1 = gamepad.axes[1];
    gamepad.a2 = gamepad.axes[2];
    gamepad.a3 = gamepad.axes[3];
    gamepad.a4 = gamepad.axes[4];
    gamepad.a5 = gamepad.axes[5];
    gamepad.a6 = gamepad.axes[6];
    gamepad.a7 = gamepad.axes[7];
     
     
    if (gamepad.buttons)
    {
     
      gamepad.btn1 = gamepad.buttons[0];
      gamepad.btn2 = gamepad.buttons[1];
      gamepad.btn3 = gamepad.buttons[2];
      gamepad.btn4 = gamepad.buttons[3];
      gamepad.btn5 = gamepad.buttons[4];
      gamepad.btn6 = gamepad.buttons[5];
     
    }
     
     
     
  }else{
     
    console.log("gamepad throws error");
  }
   
}
 
  
// -------------------------------------
// ---------  CONNECTION ROUTINES ----------------
// -------------------------------------
 
window.addEventListener("gamepadconnected", function(e) {
 
  
   gamepadHandler(e, true);
  
   initGamepad(e);
});
 
 
window.addEventListener("gamepaddisconnected", function(e) {
   
  console.log("Gamepad disconnected from index %d: %s",
    e.gamepad.index, e.gamepad.id);      
    
    gamepadHandler(e, false);
   
  }); 
 
 
function gamepadHandler(event, connecting) {
  let gamepad = event.gamepad;
  if (connecting) {
      
    print("Connecting to controller "+gamepad.index)
    controllers[gamepad.index] = gamepad
  } else {
    delete controllers[gamepad.index]
  }
}

ESP Code

sourced by: https://github.com/asukiaaa/MPU9250_asukiaaa/blob/master/examples/GetMagOffset/GetMagOffset.ino

DO not forget to install the inherited lib from asukiaaa > MPU9250_asukiaaa > props 🙂

#include <Adafruit_GFX.h>                                  // Core graphics library
#include <Adafruit_ST7735.h>  
Adafruit_ST7735 tft = Adafruit_ST7735(16, 17, 23, 5, 9); // CS,A0,SDA,SCK,RESET

#include <BleGamepad.h> 
BleGamepad bleGamepad("ESP_GYROMAN","hello",99);

#include <MPU9250_asukiaaa.h>

#ifdef _ESP32_HAL_I2C_H_
 
#define SDA_PIN 19
#define SCL_PIN 18
#endif

#define CALIB_SEC 20

MPU9250_asukiaaa mySensor;

uint8_t sensorId;
float mDirection, mX, mY, mZ;

void setup() {


  pinMode(27,INPUT);//Backlight:27
  digitalWrite(27,HIGH);//New version added to backlight control
  tft.initR(INITR_18GREENTAB);                             // 1.44 v2.1
  tft.fillScreen(ST7735_BLACK); 
  
  Serial.begin(115200);
  while(!Serial);
  Serial.println("started");

  

#ifdef _ESP32_HAL_I2C_H_ // For ESP32
  Wire.begin(SDA_PIN, SCL_PIN); // SDA, SCL
#else
  Wire.begin();
#endif

  mySensor.setWire(&Wire);
  
 
  while (mySensor.readId(&sensorId) != 0) {
    Serial.println("Cannot find device to read sensorId");
    delay(2000);
  }
 
  mySensor.beginMag();

  float magXMin, magXMax, magYMin, magYMax, magZ, magZMin, magZMax;

  Serial.println("Start scanning values of magnetometer to get offset values.");
  Serial.println("Rotate your device for " + String(CALIB_SEC) + " seconds.");
  tft.fillScreen(ST7735_RED);
  setMagMinMaxAndSetOffset(&mySensor, CALIB_SEC);
  Serial.println("Finished setting offset values.");

   tft.fillScreen(ST7735_WHITE); 
   bleGamepad.begin();
  
}

void setMagMinMaxAndSetOffset(MPU9250_asukiaaa* sensor, int seconds) {
  unsigned long calibStartAt = millis();
  float magX, magXMin, magXMax, magY, magYMin, magYMax, magZ, magZMin, magZMax;

  sensor->magUpdate();
  magXMin = magXMax = sensor->magX();
  magYMin = magYMax = sensor->magY();
  magZMin = magZMax = sensor->magZ();

  while(millis() - calibStartAt < (unsigned long) seconds * 1000) {
    delay(100);
    sensor->magUpdate();
    magX = sensor->magX();
    magY = sensor->magY();
    magZ = sensor->magZ();
    if (magX > magXMax) magXMax = magX;
    if (magY > magYMax) magYMax = magY;
    if (magZ > magZMax) magZMax = magZ;
    if (magX < magXMin) magXMin = magX;
    if (magY < magYMin) magYMin = magY;
    if (magZ < magZMin) magZMin = magZ;
  }

  sensor->magXOffset = - (magXMax + magXMin) / 2;
  sensor->magYOffset = - (magYMax + magYMin) / 2;
  sensor->magZOffset = - (magZMax + magZMin) / 2;
}
bool is_connected = false;
bool p_is_connected = false;

void loop() {
  //Serial.println("sensorId: " + String(sensorId));

  mySensor.magUpdate();
  
  mX = mySensor.magX();
  mY = mySensor.magY();
  mZ = mySensor.magZ();
  
  mDirection = mySensor.magHorizDirection();


  is_connected = bleGamepad.isConnected();


  if(is_connected != p_is_connected){
    

    if(is_connected){
      tft.fillScreen(ST7735_GREEN);
    }else{
        tft.fillScreen(ST7735_BLUE);
    }
    p_is_connected = is_connected;
    
  }

  

  
   if(is_connected) 
  {
   

    uint16_t x = uint16_t((mySensor.magX()*.01) * 32767);
    bleGamepad.setX( x );

    uint16_t y = uint16_t((mY*.01) * 32767);
    bleGamepad.setY( y );


     uint16_t z = uint16_t((mZ*.01) * 32767);
    bleGamepad.setZ( z );

  }
 
  /*
  Serial.println("mySensor.magXOffset = " + String(mySensor.magXOffset) + ";");
  Serial.println("mySensor.maxYOffset = " + String(mySensor.magYOffset) + ";");
  Serial.println("mySensor.magZOffset = " + String(mySensor.magZOffset) + ";");
  Serial.println("magX: " + String(mX));
  Serial.println("maxY: " + String(mY));
  Serial.println("magZ: " + String(mZ));
  Serial.println("horizontal direction: " + String(mDirection));

  Serial.println("at " + String(millis()) + "ms");
  Serial.println(""); // Add an empty line
  */
  delay(20);
}