Kevin Rivera and Andrew Bryant
Controller:
Description:
Our Controller is extremely simple in its design and went through different changes to make it easier to use. In the beginning, we were planning to use just the accelerometer to control the mouse movement. We then realized this wasn’t very intuitive to control the mouse so we added a magnetometer to control the x axis of the mouse while the accelerometer controls the y axis of the mouse. We decided to use the idea of a knob at the top of the car to control the left click and a sound sensor to control the spacebar. So inside the 3D printed car model that was inspired from the vehicles in the chosen game, The Game of Life, the magnetometer is plugged into the Playground Express and is aligned so that it controls the mouse accurately. The most difficult part was attaching everything inside the car securely but not permanently. We decided to keep everything inside and hot glue the car together which was time consuming as we had to redo it a couple of times because we forgot to attach a wire to the Playground Express. The signifier is the car which is picked up and the mouse movements is the feedback, the knob as it sticks out at the top and the player would twist it and the feedback is that it would select in game. Overall the way the controller works, the knob on top of the car serves as a select button when choosing cards, the car itself serves as a mouse to navigate the screen and menus, and sound sensor to pick if the player says “spin the wheel” to spin the wheel in game.
Andrew did most of the coding and making sure everything worked well with the game, Kevin did the modeling of the car and some coding. Together we created the controller and made sure it worked.
One question we have is how can we create a signifier so that the player knows to use the sound sensor and say “spin the wheel” to spin the wheel in game.
Schematics:
Code:
#include <Adafruit_Circuit_Playground.h>
#include <Mouse.h> // Include the Mouse library
#include <Keyboard.h>
#include <Adafruit_ICM20X.h>
#include <Adafruit_ICM20948.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
const int soundPin = A1; // Sound sensor connected to analog pin A1
const int threshold = 280; // Adjust this threshold based on your sound sensor's response
const int potPin = A3; // Adjust this to the pin you connected to
Adafruit_ICM20948 icm;
uint16_t measurement_delay_us = 65535; // Delay between measurements for testing
// For SPI mode, we need a CS pin
#define ICM_CS 10
// For software-SPI mode we need SCK/MOSI/MISO pins
#define ICM_SCK 13
#define ICM_MISO 12
#define ICM_MOSI 11
void setup() {
// Start serial communication
Serial.begin(200);
while (!Serial)
delay(10); // will pause Zero, Leonardo, etc until serial console opens
Serial.println("Adafruit ICM20948 test!");
// Initialize the Circuit Playground
CircuitPlayground.begin();
// Start the Mouse library
Mouse.begin();
// Initialize the Keyboard library
Keyboard.begin();
// Try to initialize!
if (!icm.begin_I2C()) {
// if (!icm.begin_SPI(ICM_CS)) {
// if (!icm.begin_SPI(ICM_CS, ICM_SCK, ICM_MISO, ICM_MOSI)) {
Serial.println("Failed to find ICM20948 chip");
while (1) {
delay(10);
}
}
Serial.println("ICM20948 Found!");
// icm.setAccelRange(ICM20948_ACCEL_RANGE_16_G);
Serial.print("Accelerometer range set to: ");
switch (icm.getAccelRange()) {
case ICM20948_ACCEL_RANGE_2_G:
Serial.println("+-2G");
break;
case ICM20948_ACCEL_RANGE_4_G:
Serial.println("+-4G");
break;
case ICM20948_ACCEL_RANGE_8_G:
Serial.println("+-8G");
break;
case ICM20948_ACCEL_RANGE_16_G:
Serial.println("+-16G");
break;
}
Serial.println("OK");
// icm.setGyroRange(ICM20948_GYRO_RANGE_2000_DPS);
Serial.print("Gyro range set to: ");
switch (icm.getGyroRange()) {
case ICM20948_GYRO_RANGE_250_DPS:
Serial.println("250 degrees/s");
break;
case ICM20948_GYRO_RANGE_500_DPS:
Serial.println("500 degrees/s");
break;
case ICM20948_GYRO_RANGE_1000_DPS:
Serial.println("1000 degrees/s");
break;
case ICM20948_GYRO_RANGE_2000_DPS:
Serial.println("2000 degrees/s");
break;
}
// icm.setAccelRateDivisor(4095);
uint16_t accel_divisor = icm.getAccelRateDivisor();
float accel_rate = 1125 / (1.0 + accel_divisor);
Serial.print("Accelerometer data rate divisor set to: ");
Serial.println(accel_divisor);
Serial.print("Accelerometer data rate (Hz) is approximately: ");
Serial.println(accel_rate);
// icm.setGyroRateDivisor(255);
uint8_t gyro_divisor = icm.getGyroRateDivisor();
float gyro_rate = 1100 / (1.0 + gyro_divisor);
Serial.print("Gyro data rate divisor set to: ");
Serial.println(gyro_divisor);
Serial.print("Gyro data rate (Hz) is approximately: ");
Serial.println(gyro_rate);
// icm.setMagDataRate(AK09916_MAG_DATARATE_10_HZ);
Serial.print("Magnetometer data rate set to: ");
switch (icm.getMagDataRate()) {
case AK09916_MAG_DATARATE_SHUTDOWN:
Serial.println("Shutdown");
break;
case AK09916_MAG_DATARATE_SINGLE:
Serial.println("Single/One shot");
break;
case AK09916_MAG_DATARATE_10_HZ:
Serial.println("10 Hz");
break;
case AK09916_MAG_DATARATE_20_HZ:
Serial.println("20 Hz");
break;
case AK09916_MAG_DATARATE_50_HZ:
Serial.println("50 Hz");
break;
case AK09916_MAG_DATARATE_100_HZ:
Serial.println("100 Hz");
break;
}
Serial.println();
}
void loop() {
// Read the accelerom eter values (x, y, z)
float x = CircuitPlayground.motionX();
float y = CircuitPlayground.motionY();
// Map the accelerometer values to screen coordinates (make sure the values are within screen size)
int mouseX = map(x, -10, 10, -10, 10); // Adjust the mapping range based on the screen size
int mouseY = map(y, -10, 10, -10, 10);
// Move the mouse based on the accelerometer values
Mouse.move(mouseX, mouseY);
// Read the analog value from the sound sensor
int soundValue = analogRead(soundPin);
// Print the value for debugging
Serial.println(soundValue);
// If the sound exceeds the threshold, simulate a spacebar key press
if (soundValue > threshold) {
// Send spacebar key press
Keyboard.press(' ');
delay(100); // Short delay to simulate the key press duration
Keyboard.release(' ');
}
// Read the potentiometer value (0-1023)
int potValue = analogRead(potPin);
// Print the value to the Serial Monitor
Serial.println(potValue);
if (potValue > 100){
Mouse.click();
delay(200);
}
// Add a delay to avoid excessive movement
delay(10);
// /* Get a new normalized sensor event */
sensors_event_t accel;
sensors_event_t gyro;
sensors_event_t mag;
sensors_event_t temp;
icm.getEvent(&accel, &gyro, &temp, &mag);
Serial.print("\t\tMag X: ");
Serial.print(mag.magnetic.x);
Serial.print(" \tY: ");
Serial.print(mag.magnetic.y);
Serial.print(" \tZ: ");
Serial.print(mag.magnetic.z);
Serial.println(" uT");
/* Display the results (acceleration is measured in m/s^2) */
Serial.print("\t\tGyro X: ");
Serial.print(gyro.gyro.x);
Serial.print(" \tY: ");
Serial.print(gyro.gyro.y);
Serial.print (" \tZ: ");
Serial.print(gyro.gyro.z);
Serial.println(" radians/s ");
Serial.println();
delay(100);
}
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.