RedBullSimulator is an empty can of Red Bull with an AltIMU-10 v4 Gyroscope tucked inside. This device serially communicates the accelerometer/gyro measurements to an Arduino Uno via I2C. This data is captured by the Processing IDE (through USB) which interprets the data and displays a live simulation of the Red Bull's orientation in space (with textures and everything).

I was inspired to work on this project while I was trying to teach myself serial communication and interfacing the Arduino with the AltIMU sensor. At the time, I had already finished two energy drinks and it only seemed natural to work with what I had: an Arduino, empty cans and a sensor.

Azure: link

#include <Wire.h>
#include <LSM6.h>

LSM6 imu;

char report[80];

void setup()
{
  Serial.begin(9600);
  Wire.begin();

  if (!imu.init())
  {
    Serial.println("Failed to detect and initialize IMU!");
    while (1);
  }
  imu.enableDefault();
}

void loop()
{
  imu.read();

  snprintf(report, sizeof(report), "%6d,%6d,%6d,%6d,%6d,%6d",
    imu.a.x, imu.a.y, imu.a.z,
    imu.g.x, imu.g.y, imu.g.z);
  Serial.println(report);

  delay(50);
}
import processing.serial.* ;

Serial myPort;
String[] globalval;
String[] valX;
String[] valY;
String[] valR;
int i;
int j;
int k;
float val_intX;
float val_intY;
float val_intR;
float data1target = 0;
float data2target = 0;
float data3target = 0;
int vall;
float data1;
float data2;
float data3;
float val_tempX;
float val_tempY;
float val_tempR;
float x;
float y;
float r;
float targetX;
float targetY;
float targetR;
int data = 0;
int intensity = 250;
float xspeed;
float prevx;
float a;
float ease = 0.05;
int[] dataout;
float easing = 0.3;

//cylinder
int tubeRes = 32;
float[] tubeX = new float[tubeRes];
float[] tubeY = new float[tubeRes];
PImage img;
PImage imglid;
PShape lid;
PImage photo, maskImage;

//LID
int numParts = 80;
float diam = 100;
PImage bg;

void setup() {  
  myPort = new Serial(this, "/dev/tty.usbmodem1421", 9600);
  //smooth();
  size(800,500, P3D);
  println(Serial.list());
  img = loadImage("texture2.png");
  imglid = loadImage("texture3.png");
  float angle = 360.0 / tubeRes;
  for (int k = 0; k < tubeRes; k++) {
    tubeX[k] = cos(radians(k * angle));
    tubeY[k] = sin(radians(k * angle));
  }
  noStroke();

  photo = loadImage("masktex.jpg");
  maskImage = loadImage("mask.jpg");
  photo.mask(maskImage);

  bg = loadImage("bg-hd-normal3.jpg");
  background(bg);
}

void draw() {
  globalval = split(myPort.readStringUntil('\n'), ',');
  data1 = getMeasurementX(globalval);
  data2 = getMeasurementY(globalval);
  data3 = getMeasurementR(globalval);
  //background(0);
  background(bg);
  directionalLight(150, 150, 150, 0, 0, -1);
  pointLight(210, 210, 210, width/1.5, height/2, 500);
  pointLight(255, 255, 255, 0, height/2, -500);

  ambientLight(230, 230, 230);
  shininess(25.0); 
  data1target += (data1 - data1target)*ease;
  data2target += (data2 - data2target)*ease;
  data3target += (data3 - data3target)*ease;

  translate(width * 0.6, height / 2, 100);
  specular(175, 175, 175);
  rotateX(-radians((data1target)));
  rotateZ(-radians((data2target)));
  rotateY(PI*0.85 + radians((data3target)));
  beginShape(QUAD_STRIP);
  shininess(20.0);
  texture(img);
  for (int i = 0; i < tubeRes; i++) {
    float x = tubeX[i] * 40;
    float z = tubeY[i] * 40;
    float u = img.width / tubeRes * i;
    vertex(x, -100, z, u, 0);
    vertex(x, 100, z, u, img.height);
  }
  endShape();

  beginShape();
  texture(photo);
  specular(175, 175, 175);
  float theta = TWO_PI / numParts+0.5;
  for (int i=0; i<numParts; i++) {
   float angle = theta * i;
   float x = cos(angle);
   float y = sin(angle);
   vertex(x * diam, y * diam, (x+1)/2, (y+1)/2);
  }
  endShape();

  //image(photo, 0, 0, 80, 80);
  //rotateX(PI/2.0);

  ellipseMode(RADIUS);  // Set ellipseMode to RADIUS
  translate(0, -100, 0);
  fill(150);
  rotateX(PI/2.0);
  ellipse(0, 0, 40, 40);

  ellipseMode(RADIUS);  // Set ellipseMode to RADIUS
  fill(30);
  translate(0, 0, 0.1);
  ellipse(0, 16, 13, 10);

  ellipseMode(RADIUS);  // Set ellipseMode to RADIUS
  translate(0, 0, -201);
  fill(40);
  ellipse(0, 0, 40, 40);
}

float getMeasurementX(String[] rrr) {
  valX = rrr;
  if (valX != null) {
    j = 0;
    while (valX[2].charAt(j) == ' ') {
      j++;
    }
    val_intX = float(valX[2].substring(j))/intensity;
    val_tempX = val_intX;
  } else {
    val_intX = val_tempX;
  }
  return val_intX;
}

float getMeasurementY(String[] rrr) {

  valY = rrr;

  if (valY != null) {
    i = 0;
    while (valY[1].charAt(i) == ' ') {
      i++;
    }
    val_intY = float(valY[1].substring(i))/intensity;
    val_tempY = val_intY;
  } else {
    val_intY = val_tempY;
  }

  return val_intY;
}

float getMeasurementR(String[] rrr) {

  valR = rrr;

  if (valR != null) {
    k = 0;
    println(valR[3]);
    while (valY[3].charAt(k) == ' ') {
      k++;
    }
    val_intR = float(valR[3].substring(k))/intensity;
    val_tempR = val_intR;
  } else {
    val_intR = val_tempR;
  }

  return val_intR;
}

Built With

  • processing-ide
  • arduino-uno
  • red-bull
Share this project:
×

Updates