Sensoreffekte visualisieren und Arduino grafisch bedienen

Aus Werkraum - Wiki
Wechseln zu: Navigation, Suche

Schwierigkeitsgrad

Gering

Idee

Wir wollen in diesem Projekt Sensoreffekte grafisch darstellen und die grafische Oberfläche nutzen, um Hardware außerhalb des PC's zu steuern.

Umsetzung

  • Als Hardware-Controller werden wir Arduino-Microcontroller-Boards verwenden
  • Das Visualisierungsprogramm werden wir mit Processing schreiben, einer auf Java basierenden Programmiersprache mit mächtigen und einfach bedienbaren Grafikbibliotheken
  • Über den seriellen Port werden dann Daten zwischen den beiden Schnittstellen übertragen
  • Dem Spaß sind keine Grenzen gesetzt bei der Konstruktion von kleinen Hardware-Gimmicks, die man dann bedienen kann oder zur Bedienung nutzt.
  • Das Projekt ist ausbaubar und kann beliebig weit fortgeführt werden, je nachdem, was unterwegs für Ideen aufkommen.

Relevante Websiten

Umsetzungsfortschritt

Hier werden während des Semesters erste Bilder und Beschreibungen des Fortschritts veröffentlicht. > https://www.mediawiki.org/wiki/Thread:Project:Support_desk/File_Upload_Error


Zunächst sollen eine Reihe von Sensoren (Abstandsmesser, Gyrosensor, Halleffektmesser, Temperatursensor, ...) Sensorsignale an den PC weitergeben und dort visualisiert werden. Dabei soll vor allem Spaß am Kennenlernen der Sensoren und der Software im Vordergrund stehen.

Basis

Zunächst müssen Processing und Arduino miteinander reden lernen: Der Controller (Arduino) soll Signale auf die serielle Schnittstelle schreiben, die dann von Processing gelesen werden.

Nach Herunterladen der Arduino und Processing software (z.B. über die Links, die oben zu finden sind), können die Programme geöffnet werden und folgender Code implementiert werden.


Arduino code for hardware connection and data transfer with processing

Arduinocode.png
/*
  Reads sensor values, prints values to serial port and
  reads commands from the serial port
 */


String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(57600); //set communication speed to a baud-rate of 57600 (quite fast)

  pinMode(13, OUTPUT); //Define output pins to see the control from processing 
  //(pin 13 on arduino is the onboard-LED)
  inputString.reserve(200); //reserve some bytes for the incoming data
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 1 and 0:
  int xValue = analogRead(A1);
  int yValue = analogRead(A0);
  int touch = digitalRead(8); //read digital pins, for example from a touch sensor
  //and so on ...
  
  // print out the value you read:
  Serial.print(xValue); // it is very important not so send "println(xValue)" because of the read out-method used in processing
  Serial.print(" "); //this split is important for processing to identify the different values with a "split"-function
  Serial.print(yValue);
  Serial.print(" ");
  Serial.print(touch);
  //and so on if you have more sensor values
  Serial.println(); //to signalize the end of a line which will show processing that all sensor values have arrived
    
  delay(100);        // delay in between reads for stability

  serialEvent(); //call the function for receiving commands below
  if(stringComplete) //if a string command was received 
  {
    stringComplete = false;
    //Serial.print(inputString);
    if(inputString=="on\n")
    {
      digitalWrite(13, HIGH); //Led onboard LED light up
    }
    else
    {
      digitalWrite(13, LOW);
    }
    inputString = "";
  }
  
}


/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void serialEvent() {
  while (Serial.available()) { //only act if stuff comes along
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

Processing code for data transfer (back and forth) with Arduino

Processingcode.png
/*

 reads values of analog inputs of arduino board
 and vizualizes them as a graph

 */
// libraries
import processing.serial.*; //for reading out the serial port
// serial connection
Serial port;
String message = null; //defines a String
String elements[] = null; //defines an array of Strings
// arduino
int numberOfSensors = 3; //for 3 analog inputs
int[] sensorValues = new int[numberOfSensors];
// graphs
int distanceX = 110;
int distanceBottom = 40;
int graphWidth = 40;
color graphColor = color(255,255,255);

void setup() {
  // size of visualising window
  size(800, 600);
  
  textAlign(CENTER);
  stroke(100);
  textSize(12);

  // print all available serial ports in console window of processing
  println(Serial.list());
  // init connection to arduino
  port = new Serial(this, Serial.list()[0], 57600);
}

void draw() {

  // clear background
  background(0);

  // draw bars with values of analog inputs
  for(int i=0; i<numberOfSensors; i++){
    fill(graphColor); //define color of geometric objects
    rect(i*distanceX+distanceX,height-distanceBottom,graphWidth,-sensorValues[i]/2); //draws rectangular bars
    text(sensorValues[i], i*distanceX+distanceX, height-distanceBottom+20); //draw text
  }
  delay(100); //to give the controller and PC time for a smooth communication
  sendCommand(); // function defined below to send commands via processing to the arduino
}

// serial event
void serialEvent(Serial p){

  // get message till line break (ASCII > 13)
  message = port.readStringUntil(13);
  // just if there is data
  if (message != null) {
    // try catch function because of possible garbage in received data
    try {
      elements = splitTokens(message); //This is important to differentiate between different sensors
      // loop through sensor values
      for (int i =0; i < elements.length && i < numberOfSensors; i++ ) {
        sensorValues[i] = int(elements[i]);
        print(sensorValues[i]);
        print(" ");
      }
      println();
    }
    catch (Exception e){
    }
  }

}

//Here one can send commands to the arduino by pressing keys
void keyReleased() {
  if(key=='b'){ port.write("on\n"); }
  else{ port.write("off\n"); }
}