Problemlösungen

Arduino Trimmrad zur Einstellung der Flugzeug-Trimmung (Teil 5)

Grundlagen


Arduino Mikrocontroller mit Ein- und Ausgabekomponenten
In dieser Artikel-Serie ging es ursprünglich um den Nachbau eines Trimmrades für Flugsimulatoren auf Basis eines Arduino-Controllers. In Kombination mit PCF8574-Erweiterungsplatinen ermögliht der Kontroller den Anschluss von sehr viel mehr Drehreglern, Knöpfen und Leuchtdioden. Deshalb ist geplant, das Projekt auszuweiten und zusätzliche Bedienelemente zu integrieren.

Die Grundlagen können in vorhergehenden Artikeln nachgelesen werden.

Arduino Trimmrad zur Einstellung der Flugzeug-Trimmung (Teil 1)

Arduino Trimmrad zur Einstellung der Flugzeug-Trimmung (Teil 2)

Arduino Trimmrad zur Einstellung der Flugzeug-Trimmung (Teil 3)

Arduino Trimmrad zur Einstellung der Flugzeug-Trimmung (Teil 4)

Arduino Trimmrad zur Einstellung der Flugzeug-Trimmung (Teil 5)

Quelltext überarbeitet und viel mehr Funktionalität implementiert


Der Controller hat nun viele zusätzliche Buttons, Drehregler und Kippschalter erhalten, die im Flugsimulator frei belegt werden können. Mangels Zeit kann ich vorerst leider nicht näher auf die Details und Probleme beim Bau des Prototypen eingehen oder die Eigenheiten der Belegung für Elevator-Trim, Aileron-Tri, Rudder-Trim und weitere Einstellungen genauer beschreiben. Nachfolgend vorerst also nur der weitgehend unkommentierte Quelltext.

Wichtig ist, dass die Funktion digitalRead() beim Lesen von Pins an den PCF8574A I/O Expander über den I2C-Bus mit “true” als zweiten Parameter aufgerufen werden müssen:

pcf8574_0.digitalRead(P6, true)
Die Funktion wird also etwas anders aufgerufen, als beim Auslesen von Pins direkt am Arduino-Board. Ohne diesen Parameter wird es zu unerwünschten Effekten beim Auslesen der Zustände kommen, die an fehlende Pullup- oder Pulldown-Widersände erinnern.

Im Prinzip läuft der Controller recht gut. Aufgrund des etwas wacklingen Aufbaus mit Steckverbindungen über Breadboards ohne feste Verlötung ist jedoch bei diesem Prototpen noch mit Wackelkontakten zu rechnen.

/*
 * Arduino HID Trim Wheel
 *
 * Author	Jan Wischniowski <jan.wischniowski@metanox.de>
 * URL		https://www.metanox.de/
 * Version	0.9.0
 * License	GNU GENERAL PUBLIC LICENSE Version 3
*/
 
#include "Arduino.h"
#include "HID-Project.h"
#include "PCF8574.h"
 
#define pcf8574_0_INTERRUPTED_PIN P7
#define pcf8574_1_INTERRUPTED_PIN P7
#define pcf8574_2_INTERRUPTED_PIN P7
#define pcf8574_3_INTERRUPTED_PIN P7
#define pcf8574_4_INTERRUPTED_PIN P7
#define pcf8574_5_INTERRUPTED_PIN P7
 
// Initialize library
//PCF8574 pcf8574_0(0x20, pcf8574_0_INTERRUPTED_PIN, rotary_0);
PCF8574 pcf8574_0(0x20);
PCF8574 pcf8574_1(0x21);
PCF8574 pcf8574_2(0x22);
PCF8574 pcf8574_3(0x23);
PCF8574 pcf8574_4(0x24);
PCF8574 pcf8574_5(0x25);
PCF8574 pcf8574_6(0x27);
 
// Arduino
const int arduino_led_1			= LED_BUILTIN;
 
// Rotary 0 / LED 0
const int rotary_0_switch		= P0;	// Pin 0 to SW (switch pin) on rotary encoder.
const int rotary_0_data			= P1;	// Pin 1 to DT (data) on rotary encoder.
const int rotary_0_clock		= P2;	// Pin 2 to CLK (clock) on rotary encoder.
const int led_0_red				= P3;
const int led_0_green			= P4;
const int led_0_blue			= P5;
volatile long rotary_0_value	= 1;	// Die Funktion readEncoderValue() liefert beim Start it 0 als ersten Wert -1. Also mit 1 Starten. Dann ist der erste Wert 0.
int rotary_0_rx_axis			= 0;
bool rotary_0_button			= LOW;
bool rotary_0_changed			= false;
 
// Rotary 1 / LED 1
const int rotary_1_switch		= P0;	// Pin 0 to SW (switch pin) on rotary encoder.
const int rotary_1_data			= P1;	// Pin 1 to DT (data) on rotary encoder.
const int rotary_1_clock		= P2;	// Pin 2 to CLK (clock) on rotary encoder.
const int led_1_red				= P3;
const int led_1_green			= P4;
const int led_1_blue			= P5;
volatile long rotary_1_value	= 1;	// Die Funktion readEncoderValue() liefert beim Start it 0 als ersten Wert -1. Also mit 1 Starten. Dann ist der erste Wert 0.
int rotary_1_ry_axis			= 0;
bool rotary_1_button			= LOW;
bool rotary_1_changed			= false;
 
// Rotary 2 / LED 2
const int rotary_2_switch		= P0;	// Pin 0 to SW (switch pin) on rotary encoder.
const int rotary_2_data			= P1;	// Pin 1 to DT (data) on rotary encoder.
const int rotary_2_clock		= P2;	// Pin 2 to CLK (clock) on rotary encoder.
const int led_2_red				= P3;
const int led_2_green			= P4;
const int led_2_blue			= P5;
volatile long rotary_2_value	= 1;	// Die Funktion readEncoderValue() liefert beim Start it 0 als ersten Wert -1. Also mit 1 Starten. Dann ist der erste Wert 0.
int rotary_2_rz_axis			= 0;
bool rotary_2_button			= LOW;
bool rotary_2_changed			= false;
 
// Rotary 3
const int rotary_3_switch		= P0;	// Pin 3 to SW (switch pin) on rotary encoder.
const int rotary_3_data			= P1;	// Pin 4 to DT (data) on rotary encoder.
const int rotary_3_clock		= P2;	// Pin 5 to CLK (clock) on rotary encoder.
const int led_3_red				= P3;
const int led_3_green			= P4;
const int led_3_blue			= P5;
volatile long rotary_3_value	= 1;	// Die Funktion readEncoderValue() liefert beim Start it 0 als ersten Wert -1. Also mit 1 Starten. Dann ist der erste Wert 0.
int rotary_3_x_axis				= 0;
bool rotary_3_button			= LOW;
bool rotary_3_changed			= false;
 
// Rotary 4
const int rotary_4_switch		= P0;	// Pin 3 to SW (switch pin) on rotary encoder.
const int rotary_4_data			= P1;	// Pin 4 to DT (data) on rotary encoder.
const int rotary_4_clock		= P2;	// Pin 5 to CLK (clock) on rotary encoder.
const int led_4_red				= P3;
const int led_4_green			= P4;
const int led_4_blue			= P5;
volatile long rotary_4_value	= 1;	// Die Funktion readEncoderValue() liefert beim Start it 0 als ersten Wert -1. Also mit 1 Starten. Dann ist der erste Wert 0.
int rotary_4_y_axis				= 0;
bool rotary_4_button			= LOW;
bool rotary_4_changed			= false;
 
// Rotary 5
const int rotary_5_switch		= P0;	// Pin 3 to SW (switch pin) on rotary encoder.
const int rotary_5_data			= P1;	// Pin 4 to DT (data) on rotary encoder.
const int rotary_5_clock		= P2;	// Pin 5 to CLK (clock) on rotary encoder.
const int led_5_red				= P3;
const int led_5_green			= P4;
const int led_5_blue			= P5;
volatile long rotary_5_value	= 1;	// Die Funktion readEncoderValue() liefert beim Start it 0 als ersten Wert -1. Also mit 1 Starten. Dann ist der erste Wert 0.
int rotary_5_z_axis				= 0;
bool rotary_5_button			= LOW;
bool rotary_5_changed			= false;
 
 
void setup()
{
	unsigned long time_start = millis();
	const long timeout_serial = 1000; 
 
	Serial.begin(9600);
 
	// Warten bis der der Serial Stream geöffnet ist.
	// "while (!Serial)" endet bei einem USB-Reconnect oder einem Reset nicht. Aus diesem Grund soll die Schleife nach einem ausreichend langen Timeout abgebrochen werden.
	// https://forum.arduino.cc/index.php?topic=171889.0
	while (!Serial) { if (millis() - time_start >= timeout_serial) { break; } }
 
	Serial.println("SERIAL OK :)");
 
	pinMode(arduino_led_1, OUTPUT);
 
	pinMode(4, INPUT_PULLUP);
	pinMode(5, INPUT_PULLUP);
	pinMode(6, INPUT_PULLUP); // Führt beim Verbinden mit Masse (Knopf gedrückt) zum Crash.
	pinMode(7, INPUT_PULLUP); // Führt beim Verbinden mit Masse (Knopf gedrückt) zum Crash.
	pinMode(8, INPUT_PULLUP);
	pinMode(9, INPUT_PULLUP);
	pinMode(10, INPUT_PULLUP);
	pinMode(11, INPUT_PULLUP);
 
	pcf8574_0.pinMode(led_0_red, OUTPUT);
	pcf8574_0.pinMode(led_0_green, OUTPUT);
	pcf8574_0.pinMode(led_0_blue, OUTPUT);
	pcf8574_0.encoder(rotary_0_data, rotary_0_clock); // Rotary 0 Pins
	pcf8574_0.pinMode(rotary_0_switch, INPUT_PULLUP); // Rotary 0 Button
	pcf8574_0.pinMode(P6, INPUT_PULLUP);
	pcf8574_0.pinMode(P7, INPUT_PULLUP);
 
	pcf8574_1.pinMode(led_1_red, OUTPUT);
	pcf8574_1.pinMode(led_1_green, OUTPUT);
	pcf8574_1.pinMode(led_1_blue, OUTPUT);
	pcf8574_1.encoder(rotary_1_data, rotary_1_clock); // Rotary 1 Pins
	pcf8574_1.pinMode(rotary_1_switch, INPUT_PULLUP); // Rotary 1 Button
	pcf8574_1.pinMode(P6, INPUT_PULLUP);
	pcf8574_1.pinMode(P7, INPUT_PULLUP);
 
	pcf8574_2.pinMode(led_2_red, OUTPUT);
	pcf8574_2.pinMode(led_2_green, OUTPUT);
	pcf8574_2.pinMode(led_2_blue, OUTPUT);
	pcf8574_2.encoder(rotary_2_data, rotary_2_clock); // Rotary 2 Pins
	pcf8574_2.pinMode(rotary_2_switch, INPUT_PULLUP); // Rotary 2 Button
	pcf8574_2.pinMode(P6, INPUT_PULLUP);
	pcf8574_2.pinMode(P7, INPUT_PULLUP);
 
	pcf8574_3.encoder(rotary_3_data, rotary_3_clock); // Rotary 3 Pins
	pcf8574_3.pinMode(rotary_3_switch, INPUT_PULLUP); // Rotary 3 Button
	pcf8574_3.pinMode(P3, INPUT_PULLUP);
	pcf8574_3.pinMode(P4, INPUT_PULLUP);
	pcf8574_3.pinMode(P5, INPUT_PULLUP);
	pcf8574_3.pinMode(P6, INPUT_PULLUP);
	pcf8574_3.pinMode(P7, INPUT_PULLUP);
 
	pcf8574_4.encoder(rotary_4_data, rotary_4_clock); // Rotary 3 Pins
	pcf8574_4.pinMode(rotary_4_switch, INPUT_PULLUP); // Rotary 3 Button
	pcf8574_4.pinMode(P3, INPUT_PULLUP);
	pcf8574_4.pinMode(P4, INPUT_PULLUP);
	pcf8574_4.pinMode(P5, INPUT_PULLUP);
	pcf8574_4.pinMode(P6, INPUT_PULLUP);
	pcf8574_4.pinMode(P7, INPUT_PULLUP);
 
	pcf8574_5.encoder(rotary_5_data, rotary_5_clock); // Rotary 3 Pins
	pcf8574_5.pinMode(rotary_5_switch, INPUT_PULLUP); // Rotary 3 Button
	pcf8574_5.pinMode(P3, INPUT_PULLUP);
	pcf8574_5.pinMode(P4, INPUT_PULLUP);
	pcf8574_5.pinMode(P5, INPUT_PULLUP);
	pcf8574_5.pinMode(P6, INPUT_PULLUP);
	pcf8574_5.pinMode(P7, INPUT_PULLUP);
 
	pcf8574_0.begin();
	pcf8574_1.begin();
	pcf8574_2.begin();
	pcf8574_3.begin();
	pcf8574_4.begin();
	pcf8574_5.begin();
	//pcf8574_6.begin();
 
	Gamepad.begin();
 
	if (pcf8574_6.begin())
	{
		Serial.println("PCF8574 OK :)");
	}
	else
	{
		Serial.println("PCF8574 KO :(");
	}
 
	// Reset
 
	pcf8574_0.digitalWrite(led_0_red, LOW);
	pcf8574_0.digitalWrite(led_0_green, LOW);
	pcf8574_0.digitalWrite(led_0_blue, LOW);
 
	pcf8574_1.digitalWrite(led_1_red, LOW);
	pcf8574_1.digitalWrite(led_1_green, LOW);
	pcf8574_1.digitalWrite(led_1_blue, LOW);
 
	pcf8574_2.digitalWrite(led_2_red, LOW);
	pcf8574_2.digitalWrite(led_2_green, LOW);
	pcf8574_2.digitalWrite(led_2_blue, LOW);
}
 
 
void loop()
{
	buttons();
	switches();
	rotary_0();
	rotary_1();
	rotary_2();
	rotary_3();
	rotary_4();
	rotary_5();
 
	Gamepad.write();
}
 
void buttons()
{
	// pcf8574_0
 
	if (!pcf8574_0.digitalRead(P6, true))
	{
		Serial.println("BUTTON 1 PRSSED!");
		Gamepad.press(1);
	}
	else
	{
		Gamepad.release(1);
	}
 
	if (!pcf8574_0.digitalRead(P7, true))
	{
		Serial.println("BUTTON 2 PRSSED!");
		Gamepad.press(2);
	}
	else
	{
		Gamepad.release(2);
	}
 
 
	// pcf8574_1
 
	if (!pcf8574_1.digitalRead(P6, true))
	{
		Serial.println("BUTTON 3 PRSSED!");
		Gamepad.press(3);
	}
	else
	{
		Gamepad.release(3);
	}
 
	if (!pcf8574_1.digitalRead(P7, true))
	{
		Serial.println("BUTTON 4 PRSSED!");
		Gamepad.press(4);
	}
	else
	{
		Gamepad.release(4);
	}
 
 
	//pcf8574_2
 
	if (!pcf8574_2.digitalRead(P6, true))
	{
		Serial.println("BUTTON 5 PRSSED!");
		Gamepad.press(5);
	}
	else
	{
		Gamepad.release(5);
	}
 
	if (!pcf8574_2.digitalRead(P7, true))
	{
		Serial.println("BUTTON 6 PRSSED!");
		Gamepad.press(6);
	}
	else
	{
		Gamepad.release(6);
	}
 
	// pcf8574_3
 
	if (!pcf8574_3.digitalRead(P3, true)) // Der 2. Parameter (Force Read Now) "true" ist wichtig!
	{
		Serial.println("BUTTON 7 PRSSED!");
		Gamepad.press(7);
	}
	else
	{
		//Serial.println("BUTTON 3-3 NOT PRSSED!");
		Gamepad.release(7);
	}
 
	if (!pcf8574_3.digitalRead(P4, true))
	{
		Serial.println("BUTTON 8 PRSSED!");
		Gamepad.press(8);
	}
	else
	{
		Gamepad.release(8);
	}
 
	if (!pcf8574_3.digitalRead(P5, true))
	{
		Serial.println("BUTTON 9 PRSSED!");
		Gamepad.press(9);
	}
	else
	{
		Gamepad.release(9);
	}
 
	if (!pcf8574_3.digitalRead(P6, true))
	{
		Serial.println("BUTTON 10 PRSSED!");
		Gamepad.press(10);
	}
	else
	{
		Gamepad.release(10);
	}
 
	if (!pcf8574_3.digitalRead(P7, true))
	{
		Serial.println("BUTTON 11 PRSSED!");
		Gamepad.press(11);
	}
	else
	{
		Gamepad.release(11);
	}
 
 
	// pcf8574_4
 
	if (!pcf8574_4.digitalRead(P3, true)) // Der 2. Parameter (Force Read Now) "true" ist wichtig!
	{
		Serial.println("BUTTON 12 PRSSED!");
		Gamepad.press(12);
	}
	else
	{
		//Serial.println("BUTTON 3-3 NOT PRSSED!");
		Gamepad.release(12);
	}
 
	if (!pcf8574_4.digitalRead(P4, true))
	{
		Serial.println("BUTTON 13 PRSSED!");
		Gamepad.press(13);
	}
	else
	{
		Gamepad.release(13);
	}
 
	if (!pcf8574_4.digitalRead(P5, true))
	{
		Serial.println("BUTTON 14 PRSSED!");
		Gamepad.press(14);
	}
	else
	{
		Gamepad.release(14);
	}
 
	if (!pcf8574_4.digitalRead(P6, true))
	{
		Serial.println("BUTTON 15 PRSSED!");
		Gamepad.press(15);
	}
	else
	{
		Gamepad.release(15);
	}
 
	if (!pcf8574_4.digitalRead(P7, true))
	{
		Serial.println("BUTTON 16 PRSSED!");
		Gamepad.press(16);
	}
	else
	{
		Gamepad.release(16);
	}
 
	// pcf8574_5
 
	if (!pcf8574_5.digitalRead(P3, true)) // Der 2. Parameter (Force Read Now) "true" ist wichtig!
	{
		Serial.println("BUTTON 17 PRSSED!");
		Gamepad.press(17);
	}
	else
	{
		//Serial.println("BUTTON 3-3 NOT PRSSED!");
		Gamepad.release(17);
	}
 
	if (!pcf8574_5.digitalRead(P4, true))
	{
		Serial.println("BUTTON 18 PRSSED!");
		Gamepad.press(18);
	}
	else
	{
		Gamepad.release(18);
	}
 
	if (!pcf8574_5.digitalRead(P5, true))
	{
		Serial.println("BUTTON 19 PRSSED!");
		Gamepad.press(19);
	}
	else
	{
		Gamepad.release(19);
	}
 
	if (!pcf8574_5.digitalRead(P6, true))
	{
		Serial.println("BUTTON 20 PRSSED!");
		Gamepad.press(20);
	}
	else
	{
		Gamepad.release(20);
	}
 
	if (!pcf8574_5.digitalRead(P7, true))
	{
		Serial.println("BUTTON 21 PRSSED!");
		Gamepad.press(21);
	}
	else
	{
		Gamepad.release(21);
	}
}
 
void switches()
{
	if (!digitalRead(4))
	{
		Gamepad.press(22);
		Gamepad.release(23);
//		Serial.println("TEST BUTTON 1 a PRESSED!");
	}
	else
	{
		//Serial.println("TEST BUTTON 1 a NOT PRESSED!");
	}
 
	if (!digitalRead(5))
	{
		Gamepad.press(23);
		Gamepad.release(22);
//		Serial.println("TEST BUTTON 1 b PRESSED!");
	}
	else
	{
		//Serial.println("TEST BUTTON 1 b NOT PRESSED!");
	}
 
	if (!digitalRead(6)) // Führt beim Verbinden mit Masse (Knopf gedrückt) zum Crash.
	//if (!digitalRead(8))
	{
		Gamepad.press(24);
		Gamepad.release(25);
//		Serial.println("TEST BUTTON 2 a PRESSED!");
	}
	else
	{
		//Serial.println("TEST BUTTON 2 a  NOT PRESSED!");
	}
 
	if (!digitalRead(7)) // Führt beim Verbinden mit Masse (Knopf gedrückt) zum Crash.
	//if (!digitalRead(9))
	{
		Gamepad.press(25);
		Gamepad.release(24);
//		Serial.println("TEST BUTTON 2 b PRESSED!");
	}
	else
	{
		//Serial.println("TEST BUTTON 2 b NOT PRESSED!");
	}
 
	if (!digitalRead(8))
	{
		Gamepad.press(26);
		Gamepad.release(27);
//		Serial.println("TEST BUTTON 3 a PRESSED!");
	}
	else
	{
		//Serial.println("TEST BUTTON 3 a NOT PRESSED!");
	}
 
	if (!digitalRead(9))
	{
		Gamepad.press(27);
		Gamepad.release(26);
//		Serial.println("TEST BUTTON 3 b PRESSED!");
	}
	else
	{
		//Serial.println("TEST BUTTON NOT PRESSED!");
	}
 
	if (!digitalRead(10))
	{
		Gamepad.press(28);
		Gamepad.release(29);
//		Serial.println("TEST BUTTON 4 a PRESSED!");
	}
	else
	{
		//Serial.println("TEST BUTTON NOT PRESSED!");
	}
 
	if (!digitalRead(11))
	{
		Gamepad.press(29);
		Gamepad.release(28);
//		Serial.println("TEST BUTTON 4 b PRESSED!");
	}
	else
	{
		//Serial.println("TEST BUTTON NOT PRESSED!");
	}
}
 
 
void rotary_0()
{
	rotary_0_changed = pcf8574_0.readEncoderValue(rotary_0_data, rotary_0_clock, &rotary_0_value);
 
	bool rotary_0_switch_value = pcf8574_0.digitalRead(rotary_0_switch);
	rotary_0_switch_value = !rotary_0_switch_value;
 
	if (rotary_0_switch_value!=rotary_0_button)
	{
		rotary_0_changed = true;
		rotary_0_button = rotary_0_switch_value;
 
		if (rotary_0_button)
		{
			digitalWrite(arduino_led_1, HIGH);
 
			// Button 1 gedrückt. X-Achse auf 0 zurücksetzen.
			//Gamepad.press(1);
 
			rotary_0_value = rotary_0_rx_axis = 0;
 
			pcf8574_0.digitalWrite(led_0_red, LOW);
			pcf8574_0.digitalWrite(led_0_green, LOW);
			pcf8574_0.digitalWrite(led_0_blue, HIGH);
		}
		else
		{
			digitalWrite(arduino_led_1, LOW);
 
			//Gamepad.release(1);
 
			pcf8574_0.digitalWrite(led_0_red, LOW);
			pcf8574_0.digitalWrite(led_0_green, LOW);
			pcf8574_0.digitalWrite(led_0_blue, LOW);
		}
	}
 
	if (rotary_0_changed)
	{
		rotary_0_rx_axis = -rotary_0_value*500;
 
		if (32767<rotary_0_rx_axis)
		{
			rotary_0_rx_axis = 32767;
		}
		if (-32768>rotary_0_rx_axis)
		{
			rotary_0_rx_axis = -32768;
		}
 
		if (0>rotary_0_rx_axis)
		{
			pcf8574_0.digitalWrite(led_0_red, HIGH);
			pcf8574_0.digitalWrite(led_0_green, LOW);
		}
		else if (0<rotary_0_rx_axis)
		{
			pcf8574_0.digitalWrite(led_0_red, LOW);
			pcf8574_0.digitalWrite(led_0_green, HIGH);
		}
		else
		{
			pcf8574_0.digitalWrite(led_0_red, LOW);
			pcf8574_0.digitalWrite(led_0_green, LOW);
			//pcf8574_0.digitalWrite(led_0_blue, LOW);
		}
 
		Serial.print("ENCODER 0 ENCODER VALUE: ");
		Serial.println(rotary_0_value);
		Serial.print("ENCODER 0 ENCODER BUTTON: ");
		Serial.println(rotary_0_button?"HIGH":"LOW");
		Serial.print("ENCODER 0 VAR rotary_0_rx_axis: ");
		Serial.println(rotary_0_rx_axis);
 
		rotary_0_changed = false;
 
		Gamepad.rxAxis(rotary_0_rx_axis);
	}
}
 
void rotary_1()
{
	rotary_1_changed = pcf8574_1.readEncoderValue(rotary_1_data, rotary_1_clock, &rotary_1_value);
 
	bool rotary_1_switch_value = pcf8574_1.digitalRead(rotary_1_switch);
	rotary_1_switch_value = !rotary_1_switch_value;
 
	if (rotary_1_switch_value!=rotary_1_button)
	{
		rotary_1_changed = true;
		rotary_1_button = rotary_1_switch_value;
 
		if (rotary_1_button)
		{
			digitalWrite(arduino_led_1, HIGH);
 
			// Button 2 gedrückt. Y-Achse auf 0 zurücksetzen.
			//Gamepad.press(2);
 
			rotary_1_value = rotary_1_ry_axis = 0;
 
			//Serial.println ("Rotary 1 Button: Pressed");
 
			pcf8574_1.digitalWrite(led_1_red, LOW);
			pcf8574_1.digitalWrite(led_1_green, LOW);
			pcf8574_1.digitalWrite(led_1_blue, HIGH);
		}
		else
		{
			digitalWrite(arduino_led_1, LOW);
 
			//Gamepad.release(2);
 
			pcf8574_1.digitalWrite(led_1_red, LOW);
			pcf8574_1.digitalWrite(led_1_green, LOW);
			pcf8574_1.digitalWrite(led_1_blue, LOW);
		}
	}
 
	if (rotary_1_changed)
	{
		rotary_1_ry_axis = -rotary_1_value*500;
 
		if (32767<rotary_1_ry_axis)
		{
			rotary_1_ry_axis = 32767;
		}
		if (-32768>rotary_1_ry_axis)
		{
			rotary_1_ry_axis = -32768;
		}
 
		if (0>rotary_1_ry_axis)
		{
			pcf8574_1.digitalWrite(led_1_red, HIGH);
			pcf8574_1.digitalWrite(led_1_green, LOW);
		}
		else if (0<rotary_1_ry_axis)
		{
			pcf8574_1.digitalWrite(led_1_red, LOW);
			pcf8574_1.digitalWrite(led_1_green, HIGH);
		}
		else
		{
			pcf8574_1.digitalWrite(led_1_red, LOW);
			pcf8574_1.digitalWrite(led_1_green, LOW);
			//pcf8574_1.digitalWrite(led_1_blue, LOW);
		}
 
		Serial.print("ENCODER 1 VALUE: ");
		Serial.println(rotary_1_value);
		Serial.print("ENCODER 1 BUTTON: ");
		Serial.println(rotary_1_button?"HIGH":"LOW");
		Serial.print("ENCODER 1 VAR rotary_1_ry_axis: ");
		Serial.println(rotary_1_ry_axis);
 
		rotary_1_changed = false;
 
		Gamepad.ryAxis(rotary_1_ry_axis);
	}
}
 
void rotary_2()
{
	rotary_2_changed = pcf8574_2.readEncoderValue(rotary_2_data, rotary_2_clock, &rotary_2_value);
 
	bool rotary_2_switch_value = pcf8574_2.digitalRead(rotary_2_switch);
	rotary_2_switch_value = !rotary_2_switch_value;
 
	if (rotary_2_switch_value!=rotary_2_button)
	{
		rotary_2_changed = true;
		rotary_2_button = rotary_2_switch_value;
 
		if (rotary_2_button)
		{
			digitalWrite(arduino_led_1, HIGH);
 
			// Button 2 gedrückt. Z-Achse auf 0 zurücksetzen.
			//Gamepad.press(3);
 
			rotary_2_value = rotary_2_rz_axis = 0;
 
			//Serial.println ("Rotary 2 Button: Pressed");
 
			pcf8574_2.digitalWrite(led_2_red, LOW);
			pcf8574_2.digitalWrite(led_2_green, LOW);
			pcf8574_2.digitalWrite(led_2_blue, HIGH);
		}
		else
		{
			digitalWrite(arduino_led_1, LOW);
 
			//Gamepad.release(3);
 
			pcf8574_2.digitalWrite(led_2_red, LOW);
			pcf8574_2.digitalWrite(led_2_green, LOW);
			pcf8574_2.digitalWrite(led_2_blue, LOW);
		}
	}
 
	if (rotary_2_changed)
	{
		rotary_2_rz_axis = rotary_2_value*1;
 
		if (127<rotary_2_rz_axis)
		{
			rotary_2_rz_axis = 127;
		}
		if (-128>rotary_2_rz_axis)
		{
			rotary_2_rz_axis = -128;
		}
 
		if (0>rotary_2_rz_axis)
		{
			pcf8574_2.digitalWrite(led_2_red, HIGH);
			pcf8574_2.digitalWrite(led_2_green, LOW);
		}
		else if (0<rotary_2_rz_axis)
		{
			pcf8574_2.digitalWrite(led_2_red, LOW);
			pcf8574_2.digitalWrite(led_2_green, HIGH);
		}
		else
		{
			pcf8574_2.digitalWrite(led_2_red, LOW);
			pcf8574_2.digitalWrite(led_2_green, LOW);
			//pcf8574_2.digitalWrite(led_2_blue, LOW);
		}
 
		Serial.print("ENCODER 2 VALUE: ");
		Serial.println(rotary_2_value);
		Serial.print("ENCODER 2 BUTTON: ");
		Serial.println(rotary_2_button?"HIGH":"LOW");
		Serial.print("ENCODER 2 VAR rotary_2_rz_axis: ");
		Serial.println(rotary_2_rz_axis);
 
		rotary_2_changed = false;
 
		Gamepad.rzAxis(rotary_2_rz_axis);
	}
}
 
void rotary_3()
{
	rotary_3_changed = pcf8574_3.readEncoderValue(rotary_3_data, rotary_3_clock, &rotary_3_value);
 
	bool rotary_3_switch_value = pcf8574_3.digitalRead(rotary_3_switch);
	rotary_3_switch_value = !rotary_3_switch_value;
 
	if (rotary_3_switch_value!=rotary_3_button)
	{
		rotary_3_changed = true;
		rotary_3_button = rotary_3_switch_value;
 
		if (rotary_3_button)
		{
			digitalWrite(arduino_led_1, HIGH);
 
			// Button 2 gedrückt. Z-Achse auf 0 zurücksetzen.
			//Gamepad.press(3);
 
			rotary_3_value = rotary_3_x_axis = 0;
 
			//Serial.println ("Rotary 2 Button: Pressed");
 
			pcf8574_3.digitalWrite(led_3_red, LOW);
			pcf8574_3.digitalWrite(led_3_green, LOW);
			pcf8574_3.digitalWrite(led_3_blue, HIGH);
		}
		else
		{
			digitalWrite(arduino_led_1, LOW);
 
			//Gamepad.release(3);
 
			pcf8574_3.digitalWrite(led_3_red, LOW);
			pcf8574_3.digitalWrite(led_3_green, LOW);
			pcf8574_3.digitalWrite(led_3_blue, LOW);
		}
	}
 
	if (rotary_3_changed)
	{
		rotary_3_x_axis = -rotary_3_value*500;
 
		if (32767<rotary_3_x_axis)
		{
			rotary_3_x_axis = 32767;
		}
		if (-32768>rotary_3_x_axis)
		{
			rotary_3_x_axis = -32768;
		}
 
		if (0>rotary_3_x_axis)
		{
			pcf8574_3.digitalWrite(led_3_red, HIGH);
			pcf8574_3.digitalWrite(led_3_green, LOW);
		}
		else if (0<rotary_3_x_axis)
		{
			pcf8574_3.digitalWrite(led_3_red, LOW);
			pcf8574_3.digitalWrite(led_3_green, HIGH);
		}
		else
		{
			pcf8574_3.digitalWrite(led_3_red, LOW);
			pcf8574_3.digitalWrite(led_3_green, LOW);
			//pcf8574_3.digitalWrite(led_3_blue, LOW);
		}
 
		Serial.print("ENCODER 3 VALUE: ");
		Serial.println(rotary_3_value);
		Serial.print("ENCODER 3 BUTTON: ");
		Serial.println(rotary_3_button?"HIGH":"LOW");
		Serial.print("ENCODER 3 VAR rotary_3_x_axis: ");
		Serial.println(rotary_3_x_axis);
 
		rotary_3_changed = false;
 
		Gamepad.xAxis(rotary_3_x_axis);
	}
}
 
void rotary_4()
{
	rotary_4_changed = pcf8574_4.readEncoderValue(rotary_4_data, rotary_4_clock, &rotary_4_value);
 
	bool rotary_4_switch_value = pcf8574_4.digitalRead(rotary_4_switch);
	rotary_4_switch_value = !rotary_4_switch_value;
 
	if (rotary_4_switch_value!=rotary_4_button)
	{
		rotary_4_changed = true;
		rotary_4_button = rotary_4_switch_value;
 
		if (rotary_4_button)
		{
			digitalWrite(arduino_led_1, HIGH);
 
			// Button 2 gedrückt. Z-Achse auf 0 zurücksetzen.
			//Gamepad.press(3);
 
			rotary_4_value = rotary_4_y_axis = 0;
 
			//Serial.println ("Rotary 2 Button: Pressed");
 
			pcf8574_4.digitalWrite(led_4_red, LOW);
			pcf8574_4.digitalWrite(led_4_green, LOW);
			pcf8574_4.digitalWrite(led_4_blue, HIGH);
		}
		else
		{
			digitalWrite(arduino_led_1, LOW);
 
			//Gamepad.release(3);
 
			pcf8574_4.digitalWrite(led_4_red, LOW);
			pcf8574_4.digitalWrite(led_4_green, LOW);
			pcf8574_4.digitalWrite(led_4_blue, LOW);
		}
	}
 
	if (rotary_4_changed)
	{
		rotary_4_y_axis = -rotary_4_value*500;
 
		if (32767<rotary_4_y_axis)
		{
			rotary_4_y_axis = 32767;
		}
		if (-32768>rotary_4_y_axis)
		{
			rotary_4_y_axis = -32768;
		}
 
		if (0>rotary_4_y_axis)
		{
			pcf8574_4.digitalWrite(led_4_red, HIGH);
			pcf8574_4.digitalWrite(led_4_green, LOW);
		}
		else if (0<rotary_4_y_axis)
		{
			pcf8574_4.digitalWrite(led_4_red, LOW);
			pcf8574_4.digitalWrite(led_4_green, HIGH);
		}
		else
		{
			pcf8574_4.digitalWrite(led_4_red, LOW);
			pcf8574_4.digitalWrite(led_4_green, LOW);
			//pcf8574_4.digitalWrite(led_4_blue, LOW);
		}
 
		Serial.print("ENCODER 4 VALUE: ");
		Serial.println(rotary_4_value);
		Serial.print("ENCODER 4 BUTTON: ");
		Serial.println(rotary_4_button?"HIGH":"LOW");
		Serial.print("ENCODER 4 VAR rotary_4_y_axis: ");
		Serial.println(rotary_4_y_axis);
 
		rotary_4_changed = false;
 
		Gamepad.yAxis(rotary_4_y_axis);
	}
}
 
void rotary_5()
{
	rotary_5_changed = pcf8574_5.readEncoderValue(rotary_5_data, rotary_5_clock, &rotary_5_value);
 
	bool rotary_5_switch_value = pcf8574_5.digitalRead(rotary_5_switch);
	rotary_5_switch_value = !rotary_5_switch_value;
 
	if (rotary_5_switch_value!=rotary_5_button)
	{
		rotary_5_changed = true;
		rotary_5_button = rotary_5_switch_value;
 
		if (rotary_5_button)
		{
			digitalWrite(arduino_led_1, HIGH);
 
			// Button 2 gedrückt. Z-Achse auf 0 zurücksetzen.
			//Gamepad.press(3);
 
			rotary_5_value = rotary_5_z_axis = 0;
 
			//Serial.println ("Rotary 2 Button: Pressed");
 
			pcf8574_5.digitalWrite(led_5_red, LOW);
			pcf8574_5.digitalWrite(led_5_green, LOW);
			pcf8574_5.digitalWrite(led_5_blue, HIGH);
		}
		else
		{
			digitalWrite(arduino_led_1, LOW);
 
			//Gamepad.release(3);
 
			pcf8574_5.digitalWrite(led_5_red, LOW);
			pcf8574_5.digitalWrite(led_5_green, LOW);
			pcf8574_5.digitalWrite(led_5_blue, LOW);
		}
	}
 
	if (rotary_5_changed)
	{
		rotary_5_z_axis = -rotary_5_value*1;
 
		if (127<rotary_5_z_axis)
		{
			rotary_5_z_axis = 127;
		}
		if (-128>rotary_5_z_axis)
		{
			rotary_5_z_axis = -128;
		}
 
		if (0>rotary_5_z_axis)
		{
			pcf8574_5.digitalWrite(led_5_red, HIGH);
			pcf8574_5.digitalWrite(led_5_green, LOW);
		}
		else if (0<rotary_5_z_axis)
		{
			pcf8574_5.digitalWrite(led_5_red, LOW);
			pcf8574_5.digitalWrite(led_5_green, HIGH);
		}
		else
		{
			pcf8574_5.digitalWrite(led_5_red, LOW);
			pcf8574_5.digitalWrite(led_5_green, LOW);
			//pcf8574_5.digitalWrite(led_5_blue, LOW);
		}
 
		Serial.print("ENCODER 5 VALUE: ");
		Serial.println(rotary_5_value);
		Serial.print("ENCODER 5 BUTTON: ");
		Serial.println(rotary_5_button?"HIGH":"LOW");
		Serial.print("ENCODER 5 VAR rotary_5_z_axis: ");
		Serial.println(rotary_5_z_axis);
 
		rotary_5_changed = false;
 
		Gamepad.zAxis(rotary_5_z_axis);
	}
}