Labortagebuch - Arduino - Raspberry Pi
03.01.2022 - Processing - Arduino
Altes Processing-Logo
Processing ist eine objektorientierte, stark typisierte Programmiersprache mit zugehöriger integrierter Entwicklungsumgebung. Die Programmiersprache ist auf die Einsatzbereiche Grafik, Simulation und Animation spezialisiert. Processing wird in einem quelloffenen Projekt entwickelt, das am Massachusetts Institute of Technology von Ben Fry (Broad Institute) und Casey Reas (UCLA Design|Media Arts) initiiert wurde. Processing hat den Charakter einer stark vereinfachten Version der Programmiersprache Java, ermöglicht Interaktionen und visuelle Elemente zu programmieren und richtet sich vorwiegend an Gestalter, Künstler und Programmieranfänger. Die Klassenbibliotheken der Programmiersprache zielen vor allem auf das Einsatzgebiet von Processing ab und berücksichtigen die Themen Video, Grafik, Grafikformate, Sound, Animation, Typographie, 3D, Simulation, Datenzugriff und -transfer, sowie Netzwerkprotokolle. Im Jahr 2005 wurde Processing mit einer Goldenen Nica des Prix Ars Electronica in der Kategorie Net Vision/Net Excellence ausgezeichnet.
(Quelle:https://de.wikipedia.org/wiki/Processing)

Entwicklung der Versionen
Version 1.0 im November 2008
Version 1.5 im April 2011 (Vereinfachte Entwicklungsumgebung für Android-Geräte
Version 2.0 im September 2021 (Große Überarbeitung der gesamten Sprache)
Version 2.1 im Oktober 2013
Version 3.0 im September 2015 (Große Überarbeitung (u.a. Rendering, Editor, Interface))
Zur Zeit (November 2021) liegt die Beta 2 Version 4.0 vor und zwar nur in der 64-bit Version für Windows, Linux und Mac OS X
Internetseite: https://processing.org/de/download/
Quelle: https://blogs.iad.zhdk.ch/physical-computing-hs-12/08-arduino-und-processing/index.html

Arduino - Processing
Da die Arduino IDE auf Processing basiert, eignen sich die beiden Programmierumgebungen auch perfekt, um Daten untereinander auszutauschen. Auf der Arduino-Seite nutzt man dazu die Funktion Serial.print(), um Daten an Processing zu schicken und Serial.read(), um Daten von Processing zu empfangen. Auf Processing-Seite nutzt man die Serial library, die schon in Processing integriert ist. Um Daten vom Arduino in Processing zu empfangen, nutzt man ebenfalls die read()- Funktion und um Daten an das Arduino zu schicken die write()-Funktion.
Neues Processing Logo
1. Daten(Text) von Arduino an Processing
Als erstes muss man wissen, an welchem Port der Arduino angeschlossen ist. In der Arduino IDE kann man das leicht ablesen. Benutzt man dagegen Processing, so kann man sich mit folgendem Programm die verfügbaren Ports anzeigen lassen und den benötigten Port einfügen.

import processing.serial.*;
Serial myPort; // Serielle Schnittstelle definieren
printArray(Serial.list());

Im ersten Beispiel wird ein Text vom Arduino über die Serielle Schnittstelle in Processing ausgegeben.
Arduino Code

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

void loop(){
Serial.println("Hello World");
delay(100);
}
Processing Code

import processing.serial.*;
Serial myPort;
String value;
void setup(){
String portName=Serial.list()[0];
println(portName);
myPort =new Serial(this,“/dev/ttyUSB0“,9600);}

void draw(){
background(255);
if (myPort.available()>0)
{value = myPort.readStringUntil('\n');}
println(value);
fill(0,0,255);
textSize(50);
text(value,50,100);}
2. Daten (Zahlen) von Arduino an Processing
In diesem Beispiel werden die Zahlen 60 bis 120 in Processing ausgegeben. Es sind jeweils 6 Zahlen, dann bleibt das Fenster für 2 Sekunden stehen und die nächsten 6 Zahlen werden ausgegeben.
Arduino Code

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

void loop(){
for (int i=60;i<120;i++){
Serial.println(i);
delay(100);
}
Processing Code

import processing.serial.*;
Serial myPort;
String value;
int ywert=150;
void setup(){
size(400,400);
background(255);
String portName=Serial.list()[0];
println(portName);
myPort =new Serial(this,“/dev/ttyUSB0“,9600);}

void draw(){
if (myPort.available()>0)
{value = myPort.readStringUntil('\n');}
println(value);
fill(0);
textSize(40);
text(value,120,ywert);
ywert=ywert+40;
if(ywert>300)
{delay(2000);ywert=0;background(255);}
}
3. Daten von der Processing-Oberfläche zur Arduino IDE - LED automatisch schalten
In diesem Beispiel wird die LED aus der Arduino IDE selbstständig an- und ausgeschaltet. Gleichzeitig ändert das Quadrat in Processing seine Farbe von rot nach grau usw. Die LED ist an Pin 11 und GND angeschlossen.
//Arduino Code

char val;
int ledPin = 11;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600); }
void loop(){
if (Serial.available())
{ val = Serial.read();
if (val == 'H')
{ digitalWrite(ledPin, HIGH);}
if (val == 'L')
{ digitalWrite(ledPin, LOW); }
} }
// Processing Code

import processing.serial.*;
boolean ledOn = false;
Serial myPort;
void setup() { size(200, 200);
println(Serial.list());
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600); }
void draw() {delay(1000);
background(150);
ledOn = !ledOn;
if (ledOn == true)
{ fill(250,250,0);// change color and
myPort.write('H');// send an H to serial
}
else {fill(150); // change color and
myPort.write('L'); // send an H to serial
}
rect(50, 50, 100, 100); // draw a square
}
4. Daten von der Processing-Oberfläche zur Arduino IDE, um eine LED mit der Maus zu schalten
In diesem Beispiel wird die LED aus dem Processing-Programm angeschaltet. Dazu führt man den Mauszeiger auf das graue Fenster und drückt die Maustaste. Solange diese gedrückt ist, leuchtet die LED. Die LED ist mit Pin 11 und GND verbunden.
//Arduino Code

char val;
int ledPin = 11;

void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600); }

void loop(){
if (Serial.available())
{ val = Serial.read();
if (val == '1')
{ digitalWrite(ledPin, HIGH);}
else
{digitalWrite(ledPin,LOW); }
} }
// Processing Code

import processing.serial.*;
Serial myPort;
void setup() { size(300, 300);
println(Serial.list());
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600); }

void draw() {
if (mousePressed==true)
{myPort.write('1');
println("1");
else
{myPort.write('0');}
}
5. LED aus der Processing-Oberfläche schalten - mit linker und rechter Maustaste
In diesem Beispiel wird die LED aus dem Processing-Programm an- und ausgeschaltet. Dazu führt man den Mauszeiger auf das farbige Fenster, drückt die linke oder rechte Maustaste. Bei linker Maustaste leuchtet die LED, beim Drücken der rechten Maustaste erlischt die LED. Mit dem Potentiometer kann die Farbe(im blauen Bereich) des Fensters verändert werden.
Dieses Beispiel findet man auch auf folgender Seite:
https://maker.pro/arduino/tutorial/how-to-make-arduino-and-processing-ide-communicate
Verkabelung
//Arduino Code

char state;
int led_Pin = 7;
int pot_pin = A0;
int pot_output;

void setup() {
pinMode(led_Pin, OUTPUT);
Serial.begin(9600); }

void loop(){
pot_output=analogRead(pot_pin);
int mapped_output=map(pot_output,0,1023,0,255);
Serial.println(mapped_output);
if (Serial.available()>0)
{ state = Serial.read();
if (val == '1')
{ digitalWrite(led_Pin, HIGH);}
if (val == '0')
{ digitalWrite(led_Pin, LOW);}
}delay(10); }
// Processing Code

import processing.serial.*;
Serial myPort;
float background_color;

void setup() { size(500, 500);
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
myPort.bufferUntil('\n'); }

void serialEvent(Serial myPort){
background_color= float(myPort.readStringUntil('n\');}

void draw() {
background(150,50,background_color);
if (mousePressed && (mouseButton==LEFT))
{myPort.write('1');}
if (mousePressed && (mouseButton==RIGHT))
{myPort.write('0');}

Die Oberfläche
6. LED - Helligkeit verändern über Processing mit einem Slider
Um Buttons, Sliders, RadioButtons, Checkboxes etc. in Processing ohne großen Aufwand in Processing einzufügen, gibt es die GUI-Library ControlP5. Dies Umgebung wurde von Andreas Schlegel entwickelt, das letzte Update datiert vom 30.07.2015 und kann von folgender Seite heruntergeladen werden (Version 2.2.5).
http://www.sojamo.de/libraries/controlP5/ bzw. von https://github.com/sojamo/controlp5
Installieren der Library: Viele Libraries sind schon mit Namen in einem Menüpunkt aufgelistet. Diese Liste ruft man auf mit Sketch -> Library importieren -> Library hinzufügen... . Dann öffnet sich das sog. Contribution Manager- Fenster. Hier findet man die verfügbaren Libraries alphabetisch geordnet. Man scrollt auf ControlP5 und klickt auf den Button Install. Dann wird diese Library installiert.

Mit dem Slider wird der Wert für die LED verändert. Dazu muss die LED mit einem digitalen Eingang verbunden werden, der Signale im sog. PWM (Pulsweitenmodus) aufnimmt. Mit Hilfe dieser Technik kann die Spannung variiert werden. Nähere Informationen darüber findet man auf z.B. https://www.exp-tech.de/blog/arduino-tutorial-pulsweitenmodulation-pwm
Beim Arduino sind dies die digitalen Eingänge, die eine Tilde in der Beschriftung haben.

Die Schaltung

//Arduino Code

#define ledPin = 10
//PWM-Eingang
int val=0;

void setup() {  
pinMode(ledPin, OUTPUT);  
Serial.begin(9600); }

void loop() {  
if (Serial.available())
{val = Serial.read();
digitalWrite(ledPin, val); }  
}
//Processing Code

import processing.serial.*;
import controlP5.*;
Serial myPort; 
ControlP5 cp5;
void setup() {size(300, 300);  
String portName = Serial.list()[0];
myPort = new Serial(this, „/dev/ttyUSB0“, 9600);
cp5 = new ControlP5(this);

cp5.addSlider(„led“)
.setPosition(25,125)
// x und y obere linke Ecke
.setSize(250,50) // (Breite, Höhe)
.setRange(0,255)
//Slider-Wert – Min -> Max
.setValue(125) // Start-Wert
.setColorBackground(color(0,0,255))
// Farbe des oberen Teils des Sliders
.setColorForeground(color(0,255,0))
// Farbe des unteren Teils des Sliders
.setColorValue(color(255,255,255))
// Val color r,gb
.setActive(color(255,0,0))
// Mouse over color
;}
void draw(){ background(0,0,0);}

void led(int led) { print(led);
myPort.write(led);}

Die Oberfläche
7. Servo - gesteuert über Processing mit einem Slider
Mit Hilfe eines Sliders wird ein Servo gesteuert. Das Programm aus Processing, um die LED zu steuern, kann ohne Änderungen übernommen werden.

Die Schaltung

//Arduino Code

#include <Servo.h>
int val=0;
Servo servo1;

void setup() {  
servo1.attach(9);  
Serial.begin(9600); }

void loop() {  
if (Serial.available())
{val = Serial.read();
servo1.write(val);}}
//Processing Code

import processing.serial.*;
import controlP5.*;
Serial myPort; 
ControlP5 cp5;
#include <Servo.h>
void setup() {size(300, 300);  
String portName = Serial.list()[0];
myPort = new Serial(this, „/dev/ttyUSB0“, 9600);
cp5 = new ControlP5(this);

cp5.addSlider(„led“)
.setPosition(25,125)
// x und y obere linke Ecke
.setSize(250,50) // (Breite, Höhe)
.setRange(0,255)
//Slider-Wert – Min -> Max
.setValue(125) // Start-Wert
.setColorBackground(color(0,0,255))
// Farbe des oberen Teils des Sliders
.setColorForeground(color(0,255,0))
// Farbe des unteren Teils des Sliders
.setColorValue(color(255,255,255))
// Val color r,gb
.setActive(color(255,0,0))
// Mouse over color
;}
void draw(){ background(0,0,0);}

void led(int led) { print(led);
myPort.write(led);}

Die Oberfläche
8. LED wird über Processing mit 2 Buttons ein- und ausgeschaltet
Mit Hilfe von zwei Buttons in Processing wird eine LED ein- bzw. ausgeschaltet. Dazu muss ebenfalls wie schon oben beschrieben die Library ControlP5 installiert sein.

Die Schaltung

//Arduino Code

int ledPin=10;

void setup() {
pinMode(ledPin, OUTPUT);
//set pin as output , red led
Serial.begin(9600);
}

void loop(){
if(Serial.available()){
//if data available
int val = Serial.read();
if(val == 1){
//if 1 received
digitalWrite(ledPin, HIGH);
//einschalten
}
if(val == 2){
//if 2 received
digitalWrite(ledPin, LOW);
//ausschalten
} } }
//Processing Code

import controlP5.*; //library
import processing.serial.*; //library
Serial port; //do not change
ControlP5 cp5; //create ControlP5 object

void setup() {size(300, 300);
//window size, (width, height)
port = new Serial(this, "/dev/ttyUSB0", 9600);
//connected arduino port
cp5 = new ControlP5(this); //do not change
cp5.addButton("ON") //name of button
.setPosition(95, 50)
//x and y upper left corner of button
.setSize(120, 70) //(width, height)
..setColorBackground(color(255, 0, 0))
//background r,g,b
.setColorForeground(color(0, 255, 0))
//mouse over color r,g,b
.setColorLabel(color(255,255,255))
//text color r,g,b
;
cp5.addButton("OFF")
.setPosition(95, 150)<
.setSize(120, 70)
.setColorBackground(color(255, 0, 0))
.setColorForeground(color(0, 255, 0))
.setColorLabel(color(255,255, 255))
;
}
void draw() {
background(255,255,255);
// background color of window (r, g, b);
}
void ON() {port.write(1);}
void OFF() {port.write(2);}

Die Oberfläche
9. Die Werte zweier Potis werden als variable Säulendiagramme angezeigt
Zwei Potentiometer werden an den Arduino angeschlossen. Die Werte werden in der Processing-Umgebung als variables Säulendiagramm angezeigt. Dieses Beispiel stammt von der folgenden Seite:
https://www.codeiseverywhere.com/post/reading-analog-input-in-processing-from-arduino

Die Schaltung

//Arduino Code

const int analogInPinLeft = A0;
const int analogInPinRight = A1;
int sensorValueLeft = 0; // Wert für das linke Poti
int sensorValueRight = 0; // Wert für das rechte Poti
void setup() {
Serial.begin(9600);}
void loop() { // liest die analogenen Werte der Potis
sensorValueLeft = analogRead(analogInPinLeft);
sensorValueRight = analogRead(analogInPinRight); // Schreibt die Werte in den seriellen Monitor
Serial.print(sensorValueLeft);
Serial.print(":"); // Trennzeichen der Werte
Serial.print(sensorValueRight);
Serial.println(); delay(2); }
// Processing Code - Teil 1

import processing.serial.*;
Serial myPort;
String data="";
int horizontal, vertical;

void setup() {
size (600, 600);
String portName = Serial.list()[1];
myPort = new Serial(this, "/dev/ttyUSB0", 9600);
myPort.bufferUntil('\n');
background(128, 128, 128); }

void draw() {
background(178, 178, 178);
// Title Text
textSize(45); textAlign(CENTER); fill(0, 0, 0);
text("Werte zweier Potis", width / 2.0, 80);
// Left Rectangle
fill(80,32,240); stroke(202,18,18); rectMode(CENTER);
rect(width / 3.5, (height - ((horizontal * 0.40) / 2) - 75), width / 4, horizontal * 0.40, 20);
textSize(40); textAlign(CENTER); fill(0, 0, 0);
text("Poti 1 "+String.valueOf(horizontal), width / 3.5, height - 10);
// Processing Code - Teil 2

// Right Rectangle
fill(0,255,0); stroke(0,18,18); rectMode(CENTER);
rect(width / 1.5, (height - ((vertical * 0.40) / 2) - 75) , width / 4,vertical * 0.40, 20);
textSize(40); textAlign(CENTER); fill(0, 0, 0);
text("Poti 2 "+String.valueOf(vertical), width / 1.5, height - 10);
}

void serialEvent (Serial myPort) {
// reads the data from the Serial Port
data = myPort.readStringUntil('\n');
// if you got any bytes other than the linefeed:
if (data != null) {
data = trim(data);
// split the string at ":"
String items[] = split(data, ':');
if (items.length > 1) {
//--- Roll,Pitch in degrees
horizontal = int(items[0]);
vertical = int(items[1]);
} } }

Die Oberfläche
10. Die Werte von Temperatur und Luftfeuchtigkeit werden als variable Säulendiagramme angezeigt (DHT11)
Die Werte für Temperatur und Luftfeuchtigkeit (DHT11) werden als Säulendiagramm in der Processing-Umgebung variabel angezeigt. Der Code für die Processing-Umgebung kann fast genau so wie beim Potentiometer-Code übernommen werden. Lediglich der Text muss entsprechend geändert werden. Zusätzlich wurde die Erstellung der Säulendiagramme verändert. Diese Lösung sieht einfacher aus als bei der Potentiometerwerte-Darstellung aus.

Die Schaltung

//Arduino Code

#include "Adafruit_Sensor.h"
#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN,DHTTYPE);

void setup() {
Serial.begin(9600);
dht.begin();}

void loop() {
float Luftfeuchtigkeit=dht.readHumidity();
float Temperatur=dht.readTemperature();
// Zeigt die Werte im seriellen Monitor
Serial.print(Luftfeuchtigkeit);
Serial.print(":");
Serial.print(Temperatur);
Serial.println();
delay(2);}
// Processing Code - Teil 1

import processing.serial.*;
Serial myPort;
String data="";
int horizontal, vertical;

void setup() {
size (600, 600);
String portName = Serial.list()[1];
myPort = new Serial(this, "/dev/ttyUSB0", 9600);
myPort.bufferUntil('\n');
background(128, 128, 128); }

void draw() {
background(178, 178, 178);
// Title Text
textSize(45); fill(0, 0, 0);
text("Luftfeuchtigkeit - Temperatur",50, 80);
// Linkes Rechteck
fill(80,32,240); stroke(202,18,18); strokeWeight(4);
stroke(100,100,1008);strokeWeight(4);
line(0,500,width,500);
fill(80,32,240); stroke(202,18,18);strokeWeight(4);
textSize(30); fill(0, 0, 0);
text("Hydro "+String.valueOf(horizontal), 100,550);
// Processing Code - Teil 2

// Rechtes Rechteck
fill(0,255,0); stroke(0,18,18);
strokeWeight(4); rect(350,500,150,-vertical*4);
textSize(30); fill(0, 0, 0);
text("Temp "+String.valueOf(vertical), 350,550); }
void serialEvent (Serial myPort) {
data = myPort.readStringUntil('\n');
if (data != null) {
data = trim(data);
// split the string at ":"
String items[] = split(data, ':');
if (items.length > 1) {
horizontal = int(items[0]); vertical = int(items[1]);
println(horizontal); println(vertical);
} } }

Der Temperatursensor DHT11

Die Oberfläche