Datenübertragung zwischen Arduino und p5.js
Bedienung eines ›Breath-Pacers‹ mithilfe der Datenübertragung zwischen Arduino und p5.js.
Um Arduino als Eingabegerät für p5.js zu verweden, orientieren wir uns am Quellcode von Teil 1 und 2 dieses Tutorials. Anschließend modifizieren und ergänzen wir den Quellcode des Tutorials mit einem eigenen p5.js-Breathpacer (Atmungstimer).
Notwendige Downloads
Diese Software muss installiert bzw. heruntergeladen werden:
- Arduino IDE
- P5.serialcontrol App
- Code dieses Projektes herunterladen
Arduino-Board vorbereiten
Folgende Teile werden für das Projekt benötigt:
- Arduino Uno
- Breadboard
- eine LED
- Potentiometer/Poti/Drehwiderstand
- Schaltdrähte x 7
- 220Ω Widerstand (rot-rot-braun)
Arduino einrichten
Wir öffnen die Arduino IDE. Unter Werkzeuge > Port > ... den Port an dem der Arduino angeschlossen ist, auswählen.
Nun den folgenden Code in die IDE kopieren, überprüfen und hochladen.
const int led1Pin = 9; // Pin-Nummer für den LED-Output
const int sensorPin = 0; // Pin-Nummer um den Poti auszulesen
int brightness = 0; // Variable um anzugeben, wie hell die LED ist
void setup() {
pinMode(led1Pin, OUTPUT); // Festlegen des LED-Pins als Output:
}
void loop() {
int sensorValue;
sensorValue = analogRead(sensorPin); // vom Poti lesen
brightness = map(sensorValue, 0, 1023, 0, 255); // bildet den Wert des Poti (Bereich von 0 bis 1023) auf die Helligkeit (von 0 bis 255) ab
// Steuerung der Helligkeit ausgehend vom Sensor-Wert
if (sensorValue >= 0) {
analogWrite(led1Pin, brightness); // LED mit bestimmter Helligkeit einschalten
} else{
digitalWrite(led1Pin, LOW); // LED ausschalten
}
}
Zwischenergebnis: die Helligkeit der LED sollte sich mittels des Drehreglers steuern lassen.
Daten vom Arduino auslesen
Um mit der p5.js Web-App kommunizieren zu können, müssen noch folgende Änderungen im Code vorgenommen werden:
// Folgenden Code an das Ende der entsprechendes Funktionen des vorherigen Code-Schnispels kopieren
void setup() {
Serial.begin(9600); // initialisiert die serielle Schnittstelle für die Datenübertragung
}
void loop() {
Serial.write(brightness); // überträgt die Helligkeit zur seriellen Schnittstelle, damit p5.js den Wert auslesen kann
}
Im p5.js-Code muss der Port-Name geändert werden. Der Port-Name unseres Arduinos (z.B. COM3, etc.), den wir in der Arduino IDE ausgewählt haben, lässt sich auch mit der p5.serialcontrol-App ermitteln.
Mit Rescan Ports werden die aktuellen Ports angezeigt, anschließend unter Connect den Port des Arduino auswählen und auf Open klicken.
Der Variable portname in sketch.js den Name des seriellen Ports zuweisen:
var portName = 'COM3'; // <-- eigenen Port-Namen hier einfügen
Zwischenergebnis: Die Helligkeit einer Seite des Bildschirmes lässt sich nun mittels des Drehreglers verändern.
Breath-Pacer erstellen
In function draw()
setzen wir die Hintergrundfarbe auf weiß:
background(255);
Danach entfernen wir den geteilten Bildschirm:
// var leftBrightness = map(inData, 0, 255, 0, 255); // map input ...
var leftBrightness = 255; // Hintergrundfarbe auf weiß fixieren
fill(leftBrightness); // transfer the ...
rect(0,0,width,height); // width/2 --> width
In function setup()
legen wir fest, dass wir Winkel in Grad angeben. Der Grund hierfür wird im folgenden Code näher erläutert.
function setup() {
...
anglemode(DEGREES);
}
Den Code von „// right side setup…
“ bis „rect(width/2-0,5, 0, 1, height);
“ löschen, und an dessen Stelle den Code des Breath-Pacers einsetzen:
// Bewege Koordinatenursprung (0/0) zur Mitte des Canvas
translate(width /2, height /2);
// Segmentierung der Kreise
// Variable kontrolliert um wie viel j steigt in folgender For-Schleife
// wegen anglemode(DEGREES) bestimmt space die Entfernung der Linien in Grad / im Gradmaß, anstelle vom Bogenmaß
var space = 2;
// äußere und innere Kreis Linien
radiusInnerCircle = width*0.255;
radiusOuterCircle = width*0.445;
lineLength = 5;
for (var j = 0; j < 360; j += space) {
// fill (255, 255, 255, 50);
fill (0, 0, 0, 50);
rotate(space);
rect(radiusInnerCircle, 0, lineLength, 1);
// fill (255, 255, 255, 70);
fill (0, 0, 0, 70);
rect(radiusOuterCircle, 0, lineLength, 1);
}
// Geschwindigkeit der Atmung
var pace = map(inData, 0, 255, 1, 10);
// aktuellen Pace ausgeben
fill(textLColor);
textSize(12);
var paceTextOutput = 0 + pace;
text("PACE: " + paceTextOutput.toFixed(2), 30-width/2, 70-height/2); // Darstellung der Eingabe
// Breath-Pacer Kreisgröße
maxPacerSize = radiusOuterCircle-radiusInnerCircle+lineLength;
// Zeitausgabe
var minutes = minute();
var seconds = second();
var millisecond = millis();
//text('Session Time: \n' + minutes + ":" + seconds, -radiusOuterCircle, radiusOuterCircle+50);
text('Milliseconds \nrunning: \n' + millisecond, 30-width/2, 90-height/2);
// Farbe des Breath-Pacer Kreises
fill(50, 185, 215, 230);
// Breath-Pacer Kreis (eigentlicher, sichtbarer Kreis)
var radiusPacer = map(sin(millisecond/5/pace), -1, 1, (radiusInnerCircle*2+lineLength*2), (radiusOuterCircle*2));
ellipse(0, 0, radiusPacer, radiusPacer);
// ^ millisecond / 100 = alle 20 Sekunden
// millisesond / 50 = alle 10 Sekunden pro halbe Periode
// millisecond / 5 = jede Sekunde ein Ein- oder Ausatmen
// --> kann mit Drehregler genau eingestellt werden
// Kreisinneres „entfernen“
noStroke();
//fill(backgroundCol);
fill (leftBrightness);
ellipse(0, 0, radiusInnerCircle*2, radiusInnerCircle*2);
Der Rest in sketch.js bleibt bestehen!
So sollte das finale Ergebnis aussehen:
Quellcode
Sketch.js-Code inkl. Breath-Pacer.