Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

12.1 Blackbox

23. November 2011

Diese Übung befasste sich mit dem Lagesensor, Vibrationsmotor und selbst gewählten Komponenten. Mit diesen Bauteilen galt es eine Box zu erstellen, welche auf Benutzerinteraktionen reagiert. Verwendete Teile: Lagesensor, Lautsprecher, LED, Arduino-Board, Vibrationsmotor... Auf der Oberseite der Box ist eine LED montiert, welche langsam blinkt, wenn die Box horizontal steht. In Seitenlage blinkt die LED schneller und steht die Box auf dem Kopf am schnellsten. Je weiter die Box von der vertikalen Achse abweicht desto höher wird der Ton. In horizontaler Lage ist die Box stumm. Steht die Box auf dem Kopf zittert zusätzlich noch der Aluminiumschwanz. Der Schwanz besteht aus einem Vibrationsmotor, der mit Aluminiumfolie umwickelt ist.

In horizontaler Lage blinkt nur die LED

Unterseite Box innen

Arduino-Board, Lautsprecher, Lagesensor, LED

Aluminiumschwanz zittert, wenn die Box Kopf steht

Vibrationsmotor in Action

....

Arduino-Code

#include <Wire.h>
#include <MMA_7455.h>

MMA_7455 mySensor = MMA_7455();
char xVal, yVal, zVal;
char prevxVal=0, prevyVal=0, prevzVal=0;
float smoothPrev = 0.8;
float smoothNew = 0.2;

#define BUFFER_SIZE 20 // actual size of the buffer for integer values: (numberOfValsToRead*6)+(numberOfValsToRead-1)
#define LED_PIN1 11
#define LED_PIN2 10
#define LED_PIN3 6
#define SOUND_PIN 5

char incommingBuffer[BUFFER_SIZE]; // buffer to store incomming values
char incomming; // primary buffer to store single incommning bytes
int incommingCounter = 0; // counter for counting the positions inside the buffer
 
float firstValue, secondValue, thirdValue; // fourthValue, fifthValue, ... // add more if needed
 
void setup()
{
  Serial.begin(9600);
  mySensor.initSensitivity(2);
  mySensor.calibrateOffset(2, 19, -5);
  pinMode(LED_PIN1,OUTPUT);
  pinMode(LED_PIN2,OUTPUT);
  pinMode(LED_PIN3,OUTPUT);
  pinMode(SOUND_PIN, OUTPUT);
}
 
void readSerial()
{
  while(Serial.available())
  {
    incomming = Serial.read(); // read single incommning bytes
 
    if(incomming != '\r') //if no carriage return is received proceed in reading the serial port
    {
      incommingBuffer[incommingCounter++] = incomming; // go on the next position in the buffer
    }
    else //read until a carriage ('\r') is received
    {
      incommingBuffer[incommingCounter] = '\0'; // set the last byte to NULL to sign it for the string operators
 
      char *a = strtok(incommingBuffer, "|;"); // split the string after delimiters into tokens
      char *b = strtok(NULL, "|;"); // ...
      char *c = strtok(NULL, "|;"); // ...
      //char *d = strtok(NULL, ",.;"); // add another line if needed
 
      firstValue = atoi(a); // convert the strings into integers
      secondValue = atoi(b); // ...
      thirdValue = atoi(c); // ...
 
      incommingCounter = 0; // reset the counter
      memset(incommingBuffer, 0, BUFFER_SIZE); //overwrite the incommingBuffer
    }
  }
}
 
void loop()
{
  
  analogWrite(LED_PIN1, firstValue);
  analogWrite(LED_PIN2, secondValue);
  analogWrite(LED_PIN3, thirdValue);
  
  readSerial(); // read the values available at the serial port
  
  // SENSOR
  xVal = mySensor.readAxis('x');
  yVal = mySensor.readAxis('y');
  zVal = mySensor.readAxis('z');
  xVal = (smoothPrev * prevxVal) + (smoothNew * xVal);
  yVal = (smoothPrev * prevyVal) + (smoothNew * yVal);
  zVal = (smoothPrev * prevzVal) + (smoothNew * zVal);
  
  if (xVal<20 && yVal<20 && zVal<-40) {
    tone(SOUND_PIN, abs(zVal)*4, 100);
  } else {
    tone(SOUND_PIN, 2*(abs(xVal)+abs(yVal)), 100);
  }
  Serial.print(xVal, DEC);
  Serial.print('\t');
  Serial.print(yVal, DEC);
  Serial.print('\t');
  Serial.print(zVal, DEC);
  Serial.print('\t');
  Serial.println();
  
  prevxVal = xVal;
  prevyVal = yVal;
  prevzVal = zVal;
}
 

Processing-Code

import processing.serial.*;  // Import the Processing Serial Library for communicating with arduino
Serial myPort;               // The used Serial Port

float firstValue = 0;
float secondValue = 0;
float thirdValue = 0;

float xVal, yVal, zVal; // fourthValue, fifthValue, ... // add more if needed
int xPosition = 0;
float xRotation, yRotation;
int ledTime=0;
int ledOn = 0;
int ledTimeLimit = 100;

void setup()
{
  smooth();
  background(0);
  size(500, 500);
  println(Serial.list()); // Prints the list of serial available devices (Arduino should be on top of the list)
  myPort = new Serial(this, Serial.list()[0], 9600); // Open a new port and connect with Arduino at 9600 baud
}
 
void draw()
{
  float xValCorrected = (xVal)/64;
  float yValCorrected = (yVal)/64;
  float zValCorrected = (zVal)/64;
  
  println(xVal+"\t"+yVal+"\t"+zVal);
  String direction = whichPlaneTop(xValCorrected,yValCorrected,zValCorrected);
  println(direction);
  
  // RED
  firstValue=0;
  fill(102,0,0);
  if (mouseOver(width/2, 100, 100/2)) {
    firstValue = 255;
    fill(255,0,0);
  }
  if (ledTime>=ledTimeLimit) {
    ledTime=0;
    ledOn = (ledOn==0) ? 255 : 0;
  }
  ledTime++;
  firstValue = ledOn;
  
  ledTimeLimit=20;
  if (direction=="top") ledTimeLimit=100; 
  if (direction=="bottom") ledTimeLimit=2; 
  
  ellipse(width/2, 100, 100,100);
  // YELLOW
  thirdValue=0;
  fill(102,102,0);
  if (mouseOver(width/2, 250, 100/2)) {
    thirdValue = 255;
    fill(255,255,0);
  }
  ellipse(width/2, 250, 100,100);
  // GREEN
  secondValue=0;
  fill(0,102,0);
  if (mouseOver(width/2, 400, 100/2)) {
    secondValue = 255;
    fill(0,255,0);
  }
  ellipse(width/2, 400, 100,100);
 
  // VIBRATE WHEN BOTTOM UP
  if (direction=="bottom") secondValue = 255;

  myPort.write(str(firstValue));
  myPort.write("|");
  myPort.write(str(secondValue));
  myPort.write("|");
  myPort.write(str(thirdValue));
  myPort.write("|");
  myPort.write("\r");
  //delay(10);
}

void serialEvent(Serial myPort) // Is called everytime there is new data to read
{
  if (myPort.available() > 0)
  {
    String completeString = myPort.readStringUntil(10); // Read the Serial port until there is a linefeed/carriage return
    if (completeString != null) // If there is valid data insode the String
    {
      trim(completeString); // Remove whitespace characters at the beginning and end of the string
      String seperateValues[] = split(completeString, "\t"); // Split the string everytime a delimiter is received
      xVal = int(seperateValues[0]);
      yVal = int(seperateValues[1]);
      zVal = int(seperateValues[2]);
    }
  }
}

boolean mouseOver(int x, int y, int r) {
  //println(x+" : "+y+" : "+r);
  if (mouseX>x-r && mouseX<x+r && mouseY<y+r && mouseY>y-r ) {
    return true;
  } else {
    return false; 
  } 
}

String whichPlaneTop(float x, float y, float z) {
  //println(x+"\t"+y+"\t"+z);
  String sideTop = "";
  if (x<0.2 && y<0.2 && z>0.8) {
    sideTop = "top";
  } else if (x<0.4 && y<0.4 && z<-0.6) {
    sideTop = "bottom";
  } else if (x<0.2 && y<-0.8 && z<0.2) {
    sideTop = "right";
  } else if (x<0.2 && y>0.8 && z<0.2) {
    sideTop = "left";
  } else if (x>0.8 && y<0.2 && z<0.2) {
    sideTop = "front";
  } else if (x<-0.8 && y<0.2 && z<0.2) {
    sideTop = "back";
  }
  return sideTop;
}