Dec2Bin

Ich bin gerade dabei, die Tasten des PS2 Kontrollers auszuwerte und weiterzuverarbeiten. Ich lasse immer 4 Tasten zusammen in ein Byte packen siehe Code-Schnipsel.

In der loop Frage ich ab, ob sich der Wert für sendByte geändert hat, wenn JA, werden die Daten über die Serielle Schnittstelle an den Mega geschickt. An diesem sind für jede Taste eine LED angeschlossen. Das geht soweit alles schon wunderbar.

Nun bekomme ich aber die Auswertung der Joysicks (Analoge Werte) nicht in ein Byte, da ich entsprechend codieren möchte. Nun würde ich gerne einmal die horizontale und vertikale Lage des Joystick erfassen (0....255). Ich gehe nun vor wie im Schnipsel. Wie kann ich dann den Wert (in diesem Falle dann ein Int) an die 4 bis 15.Stelle des Bytes schicken?

byte readRPB() {
    byte sendByte;

    //Codierung 3
    bitSet(sendByte, 0);    // 1
    bitSet(sendByte, 1);    // 1
    bitClear(sendByte, 2);  // 0
    bitClear(sendByte, 3);  // 0

    bitWrite(sendByte, 4, ps2x.Button(PSB_TRIANGLE));
    bitWrite(sendByte, 5, ps2x.Button(PSB_CIRCLE));
    bitWrite(sendByte, 6, ps2x.Button(PSB_CROSS));
    bitWrite(sendByte, 7, ps2x.Button(PSB_SQUARE));

    return sendByte;
}

sschultewolter: Wie kann ich dann den Wert (in diesem Falle dann ein Int) an die 4 bis 15.Stelle des Bytes schicken?

Ich glaube du solltest lieber ins Bett gehen ;)

Oder meinst du ein Byte in einen int verpacken? Mit Casten, Schieben und Verodern.

Ja, ich meine ein Byte in ein Int packen. Hier mal kurz die derzeiten Sketche. Es kommt mir ein bisschen so vor, als ob ich viel zu viel geschrieben habe und es deutlich kürzer und einfacher geht.

Ich habe zwischenzeitig irgendwo gelesen, könnte im Playground gewesen sein, dass diese Bitzuweisung nur bei Bytes geht. Im Buch, “C von A bis Z” sowie O’Reilays “Kochbuch” habe ich leider noch nicht die passenden Textpassagen gefunden.

Pro Mini 328 16MHz (Sender)

#include <AltSoftSerial.h>	// http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html <-- Nur Testzwecke
#include <PS2X_lib.h>		// http://www.billporter.info/2010/06/05/playstation-2-controller-arduino-library-v1-0/
#include <Streaming.h>		// http://arduiniana.org/libraries/streaming/

AltSoftSerial Serial2;

PS2X ps2x;
#define PSB_ANALOG A0
const byte PSB_ANALOG_LED = A1;

void setup(){
	Serial.begin(57600);
	Serial2.begin(57600);
	// Initialisiere Controller (Clock, Command, Attention, Data, Druck, Rumble)
	ps2x.config_gamepad(13, 11, 10, 12, true, false);

	pinMode(PSB_ANALOG, INPUT_PULLUP);
	pinMode(PSB_ANALOG_LED, OUTPUT);
}

byte readSB() {
	byte sendByte;

	//Codierung 1
	bitSet(sendByte, 0);	// 1
	bitClear(sendByte, 1);	// 0
	bitClear(sendByte, 2);	// 0
	bitClear(sendByte, 3);	// 0

	bitWrite(sendByte, 4, ps2x.Button(PSB_START));
	bitWrite(sendByte, 5, ps2x.Button(PSB_SELECT));
	bitWrite(sendByte, 6, digitalRead(PSB_ANALOG));

	return sendByte;
}

byte readLPB() {
	byte sendByte;

	//Codierung 2
	bitClear(sendByte, 0);	// 0
	bitSet(sendByte, 1);	// 1
	bitClear(sendByte, 2);	// 0
	bitClear(sendByte, 3);	// 0

	bitWrite(sendByte, 4, ps2x.Button(PSB_PAD_UP));
	bitWrite(sendByte, 5, ps2x.Button(PSB_PAD_RIGHT));
	bitWrite(sendByte, 6, ps2x.Button(PSB_PAD_DOWN));
	bitWrite(sendByte, 7, ps2x.Button(PSB_PAD_LEFT));

	return sendByte;
}

byte readRPB() {
	byte sendByte;

	//Codierung 3
	bitSet(sendByte, 0);	// 1
	bitSet(sendByte, 1);	// 1
	bitClear(sendByte, 2);	// 0
	bitClear(sendByte, 3);	// 0

	bitWrite(sendByte, 4, ps2x.Button(PSB_TRIANGLE));
	bitWrite(sendByte, 5, ps2x.Button(PSB_CIRCLE));
	bitWrite(sendByte, 6, ps2x.Button(PSB_CROSS));
	bitWrite(sendByte, 7, ps2x.Button(PSB_SQUARE));

	return sendByte;
}

byte readLJB() {
	byte sendByte;

	//Codierung 4
	bitClear(sendByte, 0);	// 0
	bitClear(sendByte, 1);	// 0
	bitSet(sendByte, 2);	// 1
	bitClear(sendByte, 3);	// 0

	bitWrite(sendByte, 4, ps2x.Button(PSB_L1));
	bitWrite(sendByte, 5, ps2x.Button(PSB_L2));
	bitWrite(sendByte, 6, ps2x.Button(PSB_L3));

	return sendByte;
}

byte readRJB() {
	byte sendByte;

	//Codierung 5
	bitSet(sendByte, 0);	// 1
	bitClear(sendByte, 1);	// 0
	bitSet(sendByte, 2);	// 1
	bitClear(sendByte, 3);	// 0

	bitWrite(sendByte, 4, ps2x.Button(PSB_R1));
	bitWrite(sendByte, 5, ps2x.Button(PSB_R2));
	bitWrite(sendByte, 6, ps2x.Button(PSB_R3));

	return sendByte;
}

int readLXJA() {
	int sendInt;

	// Codierung 6
	bitClear(sendInt, 0);	// 0
	bitSet(sendInt, 1);		// 1
	bitSet(sendInt, 2);		// 1
	bitClear(sendInt, 3);	// 0

	bitWrite(sendInt, 4, bitRead(ps2x.Button(PSS_LX), 0));
	bitWrite(sendInt, 5, bitRead(ps2x.Button(PSS_LX), 1));
	bitWrite(sendInt, 6, bitRead(ps2x.Button(PSS_LX), 2));
	bitWrite(sendInt, 7, bitRead(ps2x.Button(PSS_LX), 3));
	bitWrite(sendInt, 8, bitRead(ps2x.Button(PSS_LX), 4));
	bitWrite(sendInt, 9, bitRead(ps2x.Button(PSS_LX), 5));
	bitWrite(sendInt, 10, bitRead(ps2x.Button(PSS_LX), 6));
	bitWrite(sendInt, 11, bitRead(ps2x.Button(PSS_LX), 7));

	return sendInt;
}

int readLYJA() {
	int sendInt;

	// Codierung 7
	bitSet(sendInt, 0);		// 1
	bitSet(sendInt, 1);		// 1 
	bitSet(sendInt, 2);		// 1
	bitClear(sendInt, 3);	// 0

	bitWrite(sendInt, 4, bitRead(ps2x.Button(PSS_LY), 0));
	bitWrite(sendInt, 5, bitRead(ps2x.Button(PSS_LY), 1));
	bitWrite(sendInt, 6, bitRead(ps2x.Button(PSS_LY), 2));
	bitWrite(sendInt, 7, bitRead(ps2x.Button(PSS_LY), 3));
	bitWrite(sendInt, 8, bitRead(ps2x.Button(PSS_LY), 4));
	bitWrite(sendInt, 9, bitRead(ps2x.Button(PSS_LY), 5));
	bitWrite(sendInt, 10, bitRead(ps2x.Button(PSS_LY), 6));
	bitWrite(sendInt, 11, bitRead(ps2x.Button(PSS_LY), 7));

	return sendInt;
}

int readRXJA() {
	int sendInt;

	// Codierung 8
	bitClear(sendInt, 0);	// 0
	bitClear(sendInt, 1);	// 0
	bitClear(sendInt, 2);	// 0
	bitSet(sendInt, 3);		// 1

	bitWrite(sendInt, 4, bitRead(ps2x.Button(PSS_RX), 0));
	bitWrite(sendInt, 5, bitRead(ps2x.Button(PSS_RX), 1));
	bitWrite(sendInt, 6, bitRead(ps2x.Button(PSS_RX), 2));
	bitWrite(sendInt, 7, bitRead(ps2x.Button(PSS_RX), 3));
	bitWrite(sendInt, 8, bitRead(ps2x.Button(PSS_RX), 4));
	bitWrite(sendInt, 9, bitRead(ps2x.Button(PSS_RX), 5));
	bitWrite(sendInt, 10, bitRead(ps2x.Button(PSS_RX), 6));
	bitWrite(sendInt, 11, bitRead(ps2x.Button(PSS_RX), 7));

	return sendInt;
}

int readRYJA() {
	int sendInt;

	// Codierung 9
	bitSet(sendInt, 0);		// 1
	bitClear(sendInt, 1);	// 0 
	bitClear(sendInt, 2);	// 0
	bitSet(sendInt, 3);		// 1

	bitWrite(sendInt, 4, bitRead(ps2x.Button(PSS_RY), 0));
	bitWrite(sendInt, 5, bitRead(ps2x.Button(PSS_RY), 1));
	bitWrite(sendInt, 6, bitRead(ps2x.Button(PSS_RY), 2));
	bitWrite(sendInt, 7, bitRead(ps2x.Button(PSS_RY), 3));
	bitWrite(sendInt, 8, bitRead(ps2x.Button(PSS_RY), 4));
	bitWrite(sendInt, 9, bitRead(ps2x.Button(PSS_RY), 5));
	bitWrite(sendInt, 10, bitRead(ps2x.Button(PSS_RY), 6));
	bitWrite(sendInt, 11, bitRead(ps2x.Button(PSS_RY), 7));
	return sendInt;
}

void loop() {
	ps2x.read_gamepad();
	static byte oldReadSB, oldReadLPB, oldReadRPB, oldReadLJB, oldReadRJB;
	static int oldReadLXJA, oldReadLYJA, oldReadRXJA, oldReadRYJA;
	static byte TxLed;

	// System Buttons
	byte setSB = readSB();
	if (oldReadSB != setSB){
		oldReadSB = setSB;
		Serial2 << setSB << endl;
		Serial << setSB << endl;
	}

	// Linke Pad Buttons
	byte setLPB = readLPB();
	if (oldReadLPB != setLPB){
		oldReadLPB = setLPB;
		Serial2 << setLPB << endl;
		Serial << setLPB << endl;
	}

	// Rechte Pad Buttons
	byte setRPB = readRPB();
	if (oldReadRPB != setRPB){
		oldReadRPB = setRPB;
		Serial2 << setRPB << endl;
		Serial << setRPB << endl;
	}

	// Linker Joystick Buttons
	byte setLJB = readLJB();
	if (oldReadLJB != setLJB){
		oldReadLJB = setLJB;
		Serial2 << setLJB << endl;
		Serial << setLJB << endl;
	}

	// Rechter Joystick Buttons
	byte setRJB = readRJB();
	if (oldReadRJB != setRJB){
		oldReadRJB = setRJB;
		Serial2 << setRJB << endl;
		Serial << setRJB << endl;
	}

	// Linker Joystick Analog X-Achse
	int setLXJA = readLXJA();
	if (oldReadLXJA != setLXJA){
		oldReadLXJA = setLXJA;
		Serial2 << setLXJA << endl;
		Serial << setLXJA << endl;
	}

	// Linker Joystick Analog Y-Achse
	int setLYJA = readLYJA();
	if (oldReadLYJA != setLYJA){
		oldReadLYJA = setLYJA;
		Serial2 << setLYJA << endl;
		Serial << setLYJA << endl;
	}

	// Rechter Joystick Analog X-Achse
	int setRXJA = readRXJA();
	if (oldReadRXJA != setRXJA){
		oldReadRXJA = setRXJA;
		Serial2 << setRXJA << endl;
		Serial << setRXJA << endl;
	}

	// Rechter Joystick Analog Y-Achse
	int setRYJA = readRYJA();
	if (oldReadRYJA != setRYJA){
		oldReadRYJA = setRYJA;
		Serial2 << setRYJA << endl;
		Serial << setRYJA << endl;
	}

	digitalWrite(PSB_ANALOG_LED, bitRead(setSB, 6));
}

Mega 2560 (Empfänger)

#include <Streaming.h>

#define PSB_PAD_UP 22
#define PSB_PAD_RIGHT 24
#define PSB_PAD_DOWN 26
#define PSB_PAD_LEFT 28

#define PSB_TRIANGLE 34
#define PSB_CIRCLE 36
#define PSB_CROSS 38
#define PSB_SQUARE 40

#define PSB_START 7
#define PSB_SELECT 6
#define PSB_ANALOG 12

#define PSB_L1 30
#define PSB_L2 32
#define PSB_L3 50

#define PSB_R1 42
#define PSB_R2 44
#define PSB_R3 48

#define PSS_LX1 5
#define PSS_LX2 3
#define PSS_LY1 2
#define PSS_LY2 4

#define PSS_RX1 11
#define PSS_RX2 9
#define PSS_RY1 8
#define PSS_RY2 10

void setup() {
  pinMode(PSB_PAD_UP, OUTPUT);
  pinMode(PSB_PAD_RIGHT, OUTPUT);
  pinMode(PSB_PAD_DOWN, OUTPUT);
  pinMode(PSB_PAD_LEFT, OUTPUT);

  pinMode(PSB_TRIANGLE, OUTPUT);
  pinMode(PSB_CIRCLE, OUTPUT);
  pinMode(PSB_CROSS, OUTPUT);
  pinMode(PSB_SQUARE, OUTPUT);

  pinMode(PSB_START, OUTPUT);
  pinMode(PSB_SELECT, OUTPUT);
  pinMode(PSB_ANALOG, OUTPUT);

  pinMode(PSB_L1, OUTPUT);
  pinMode(PSB_L2, OUTPUT);
  pinMode(PSB_L3, OUTPUT);

  pinMode(PSB_R1, OUTPUT);
  pinMode(PSB_R2, OUTPUT);
  pinMode(PSB_R3, OUTPUT);

  pinMode(PSS_LX1, OUTPUT);
  pinMode(PSS_LX2, OUTPUT);
  pinMode(PSS_LY1, OUTPUT);
  pinMode(PSS_LY2, OUTPUT);

  pinMode(PSS_RX1, OUTPUT);
  pinMode(PSS_RX2, OUTPUT);
  pinMode(PSS_RY1, OUTPUT);
  pinMode(PSS_RY2, OUTPUT);
  Serial.begin(57600);
  Serial2.begin(57600);
}

void loop() {
  byte getValueLX, getValueLY, getValueRX, getValueRY;

  if (Serial2.available()> 0) {
    int incData = Serial2.parseInt();
    for(int i = 0; i < 16; i++) Serial << bitRead(incData, i) << endl;

    byte getSum;
    getSum += bitRead(incData, 0);
    getSum += 2*bitRead(incData, 1);
    getSum += 4*bitRead(incData, 2);
    getSum += 8*bitRead(incData, 3);

    switch(getSum) {
    case 1:
      digitalWrite(PSB_START, bitRead(incData,4));
      digitalWrite(PSB_SELECT, bitRead(incData, 5));
      digitalWrite(PSB_ANALOG, bitRead(incData, 6));
      break;

    case 2: 
      digitalWrite(PSB_PAD_UP, bitRead(incData,4));
      digitalWrite(PSB_PAD_RIGHT, bitRead(incData, 5));
      digitalWrite(PSB_PAD_DOWN, bitRead(incData, 6));
      digitalWrite(PSB_PAD_LEFT, bitRead(incData, 7));
      break;

    case 3:
      digitalWrite(PSB_TRIANGLE, bitRead(incData, 4));
      digitalWrite(PSB_CIRCLE, bitRead(incData, 5));
      digitalWrite(PSB_CROSS, bitRead(incData, 6));
      digitalWrite(PSB_SQUARE, bitRead(incData, 7));
      break;  

    case 4:
      digitalWrite(PSB_L1, bitRead(incData, 4));
      digitalWrite(PSB_L2, bitRead(incData, 5));
      digitalWrite(PSB_L3, bitRead(incData, 6));
      break;  

    case 5:
      digitalWrite(PSB_R1, bitRead(incData, 4));
      digitalWrite(PSB_R2, bitRead(incData, 5));
      digitalWrite(PSB_R3, bitRead(incData, 6));
      break;

    case 6:
      getValueLX += bitRead(incData, 4);
      getValueLX += 2*bitRead(incData, 5);
      getValueLX += 4*bitRead(incData, 6);
      getValueLX += 8*bitRead(incData, 7);
      getValueLX += 16*bitRead(incData, 8);
      getValueLX += 32*bitRead(incData, 9);
      getValueLX += 64*bitRead(incData, 10);
      getValueLX += 128*bitRead(incData, 11);
      break;

    case 7:
      getValueLY += bitRead(incData, 4);
      getValueLY += 2*bitRead(incData, 5);
      getValueLY += 4*bitRead(incData, 6);
      getValueLY += 8*bitRead(incData, 7);
      getValueLY += 16*bitRead(incData, 8);
      getValueLY += 32*bitRead(incData, 9);
      getValueLY += 64*bitRead(incData, 10);
      getValueLY += 128*bitRead(incData, 11);
      break;

    case 8:
      getValueRX += bitRead(incData, 4);
      getValueRX += 2*bitRead(incData, 5);
      getValueRX += 4*bitRead(incData, 6);
      getValueRX += 8*bitRead(incData, 7);
      getValueRX += 16*bitRead(incData, 8);
      getValueRX += 32*bitRead(incData, 9);
      getValueRX += 64*bitRead(incData, 10);
      getValueRX += 128*bitRead(incData, 11);
      break;

    case 9:
      getValueRY += bitRead(incData, 4);
      getValueRY += 2*bitRead(incData, 5);
      getValueRY += 4*bitRead(incData, 6);
      getValueRY += 8*bitRead(incData, 7);
      getValueRY += 16*bitRead(incData, 8);
      getValueRY += 32*bitRead(incData, 9);
      getValueRY += 64*bitRead(incData, 10);
      getValueRY += 128*bitRead(incData, 11);
      break;
    }
  }
/*
  if(getValueLX > 127) analogWrite(PSS_LX1, map(getValueLX, 127, 255, 0, 255));
  else analogWrite(PSS_LX2, map(getValueLX, 127, 0, 0, 255));

  if(getValueLY > 127) analogWrite(PSS_LY1, map(getValueLY, 127, 255, 0, 255));
  else analogWrite(PSS_LY2, map(getValueLY, 127, 0, 0, 255));

  if(getValueRX > 127) analogWrite(PSS_RX1, map(getValueRX, 127, 255, 0, 255));
  else analogWrite(PSS_RX2, map(getValueRX, 127, 0, 0, 255));

  if(getValueRY > 127) analogWrite(PSS_RY1, map(getValueRY, 127, 255, 0, 255));
  else analogWrite(PSS_RY2, map(getValueRY, 127, 0, 0, 255));
*/
}

Hier das Video vom derzeitgen Aufbau https://www.dropbox.com/s/dzc5ih9wijulxz0/2014-02-10%2000.45.36.mp4

Du kannst das machen:

int i = 0;
byte b = 0xFF;
i |= b << 4;

Das schiebt das Byte vier stellen nach links damit es auf Bits 4-11 landet.

Ich habs mal in Visual C++ getestet und ein Cast ist doch nicht nötig. Gehen keine Bits verloren :slight_smile:

Falls im Sketch zu erkennen,

ich setzte 2 Bytes zu einem Int zusammen. Verschicke diese über die Serielle Schnittstelle und diese werden dann beim Empfänger aufgesplittet. Die ersten 4 Zellen entscheiden, was mit den anderen bis zu 8 Stellen geschiet,

Ja sieht man hier:

    bitWrite(sendInt, 4, bitRead(ps2x.Button(PSS_RX), 0));
    bitWrite(sendInt, 5, bitRead(ps2x.Button(PSS_RX), 1));
    bitWrite(sendInt, 6, bitRead(ps2x.Button(PSS_RX), 2));
    bitWrite(sendInt, 7, bitRead(ps2x.Button(PSS_RX), 3));
    bitWrite(sendInt, 8, bitRead(ps2x.Button(PSS_RX), 4));
    bitWrite(sendInt, 9, bitRead(ps2x.Button(PSS_RX), 5));
    bitWrite(sendInt, 10, bitRead(ps2x.Button(PSS_RX), 6));
    bitWrite(sendInt, 11, bitRead(ps2x.Button(PSS_RX), 7));

Das kannst du definitiv mit Schieben und Oder machen. Du musst dazu aber sendInt auf 0 initialisieren, da es lokal ist! Damit kannst du dir auch das bitClear() sparen

Danke, ich werde mal sehen, sollte umzusetzen sein ;)

So, hab den Sketch mal ein bisschen bearbeitet, gefühlt sind es schon mal deutlich weniger Zeilen :wink:
Gibt es sonst noch etwas sinnvoll zu verbessern? Ich hab bei sendData noch eine Rückfrage eingebaut, ob die Daten auch erfolgreich gelesen wurden.

Die Abfrage muss nicht drin, weiß aber nicht, ob sonst immer alles geschickt wird, wenns zu schnell geht.

Sender

//#include <AltSoftSerial.h>	// http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html <-- Nur Testzwecke
//#include <SoftwareSerial.h>
#include <PS2X_lib.h>		// http://www.billporter.info/2010/06/05/playstation-2-controller-arduino-library-v1-0/
#include <Streaming.h>		// http://arduiniana.org/libraries/streaming/

//AltSoftSerial Serial2;
//SoftwareSerial Serial2(8, 9);

PS2X ps2x;
#define PSB_ANALOG A0
const byte PSB_ANALOG_LED = A1;

void setup(){
	Serial.begin(57600);
	//Serial2.begin(57600);

	// Initialisiere Controller (Clock, Command, Attention, Data, Druck, Rumble)
	ps2x.config_gamepad(13, 11, 10, 12, true, false);

	pinMode(PSB_ANALOG, INPUT_PULLUP);
	pinMode(PSB_ANALOG_LED, OUTPUT);
}

void readSB() {
	static int oldData;
	int data = 0x01;
	
	bitWrite(data, 4, ps2x.Button(PSB_START));
	bitWrite(data, 5, ps2x.Button(PSB_SELECT));
	bitWrite(data, 6, digitalRead(PSB_ANALOG));
	
	oldData = sendData(data, oldData);
}

void readLPB() {
	static int oldData;
	byte data = 0x02;

	bitWrite(data, 4, ps2x.Button(PSB_PAD_UP));
	bitWrite(data, 5, ps2x.Button(PSB_PAD_RIGHT));
	bitWrite(data, 6, ps2x.Button(PSB_PAD_DOWN));
	bitWrite(data, 7, ps2x.Button(PSB_PAD_LEFT));
	
	oldData = sendData(data, oldData);
}

void readRPB() {
	static int oldData;
	byte data = 0x03;

	bitWrite(data, 4, ps2x.Button(PSB_TRIANGLE));
	bitWrite(data, 5, ps2x.Button(PSB_CIRCLE));
	bitWrite(data, 6, ps2x.Button(PSB_CROSS));
	bitWrite(data, 7, ps2x.Button(PSB_SQUARE));

	oldData = sendData(data, oldData);
}

void readLJB() {
	static int oldData;
	byte data = 0x04;

	bitWrite(data, 4, ps2x.Button(PSB_L1));
	bitWrite(data, 5, ps2x.Button(PSB_L2));
	bitWrite(data, 6, ps2x.Button(PSB_L3));

	oldData = sendData(data, oldData);
}

void readRJB() {
	static int oldData;
	byte data = 0x05;

	bitWrite(data, 4, ps2x.Button(PSB_R1));
	bitWrite(data, 5, ps2x.Button(PSB_R2));
	bitWrite(data, 6, ps2x.Button(PSB_R3));

	oldData = sendData(data, oldData);
}

void readLXJA() {
	static int oldData;
	int data = 0x06;
	byte value = ps2x.Analog(PSS_LX);
	data |= value << 4;

	oldData = sendData(data, oldData);
}

void readLYJA() {
	static int oldData;
	int data = 0x07;
	byte value = ps2x.Analog(PSS_LY);
	data |= value << 4;

	oldData = sendData(data, oldData);
}

void readRXJA() {
	static int oldData;
	int data = 0x08;
	byte value = ps2x.Analog(PSS_RX);
	data |= value << 4;

	oldData = sendData(data, oldData);
}

void readRYJA() {
	static int oldData;
	int data = 0x09;
	byte value = ps2x.Analog(PSS_RY);
	data |= value << 4;

	oldData = sendData(data, oldData);
}

void blinkLed() {
	// Taste ANALOG abfragen
	digitalWrite(PSB_ANALOG_LED, digitalRead(PSB_ANALOG));
};

int sendData(int data, int oldData) {
	boolean sendOk = false;
	static unsigned long lastMicro;
	
	if (data != oldData) {
		oldData = data;
		// Senden an Empfaenger
		Serial << data << endl;

		lastMicro = micros();
		while (sendOk == false) {
			if (Serial.available() > 0) {
				byte getData = Serial.parseInt();
				//Serial << micros() - lastMicro << F("\t") << getData << endl;
				if (getData == 255) sendOk = true;
			}
		}
	}
	return oldData;
}


void loop() {
	// PS2B Kontroller abfragen
	ps2x.read_gamepad();
	readSB();		// START, SELECT, ANALOG
	readLPB();		// HOCH, RECHTS, UNTEN, LINKS
	readRPB();		// DREIECK, KREIS, KREUZ, QUADRAT
	readLJB();		// L1, L2, L3
	readRJB();		// R1, R2, R3
	readLXJA();		// Joystick Links X-Achse
	readLYJA();		// Joystick Links >-Achse
	readRXJA();		// Joystick Rechts X-Achse
	readRYJA();		// Joystick Rechts Y-Achse
	blinkLed();		// Led ANALOG
}

Empfänger

#include <Streaming.h>

#define PSB_PAD_UP 22
#define PSB_PAD_RIGHT 24
#define PSB_PAD_DOWN 26
#define PSB_PAD_LEFT 28

#define PSB_TRIANGLE 34
#define PSB_CIRCLE 36
#define PSB_CROSS 38
#define PSB_SQUARE 40

#define PSB_START 7
#define PSB_SELECT 6
#define PSB_ANALOG 12

#define PSB_L1 30
#define PSB_L2 32
#define PSB_L3 50

#define PSB_R1 42
#define PSB_R2 44
#define PSB_R3 48

#define PSS_LX1 5
#define PSS_LX2 3
#define PSS_LY1 2
#define PSS_LY2 4

#define PSS_RX1 11
#define PSS_RX2 9
#define PSS_RY1 8
#define PSS_RY2 10

void setup() {
  pinMode(PSB_PAD_UP, OUTPUT);
  pinMode(PSB_PAD_RIGHT, OUTPUT);
  pinMode(PSB_PAD_DOWN, OUTPUT);
  pinMode(PSB_PAD_LEFT, OUTPUT);

  pinMode(PSB_TRIANGLE, OUTPUT);
  pinMode(PSB_CIRCLE, OUTPUT);
  pinMode(PSB_CROSS, OUTPUT);
  pinMode(PSB_SQUARE, OUTPUT);

  pinMode(PSB_START, OUTPUT);
  pinMode(PSB_SELECT, OUTPUT);
  pinMode(PSB_ANALOG, OUTPUT);

  pinMode(PSB_L1, OUTPUT);
  pinMode(PSB_L2, OUTPUT);
  pinMode(PSB_L3, OUTPUT);

  pinMode(PSB_R1, OUTPUT);
  pinMode(PSB_R2, OUTPUT);
  pinMode(PSB_R3, OUTPUT);

  pinMode(PSS_LX1, OUTPUT);
  pinMode(PSS_LX2, OUTPUT);
  pinMode(PSS_LY1, OUTPUT);
  pinMode(PSS_LY2, OUTPUT);

  pinMode(PSS_RX1, OUTPUT);
  pinMode(PSS_RX2, OUTPUT);
  pinMode(PSS_RY1, OUTPUT);
  pinMode(PSS_RY2, OUTPUT);
  Serial.begin(57600);
  Serial2.begin(57600);
}

void loop() {
  static byte valueLX, valueLY, valueRX, valueRY;

  if (Serial2.available() > 0) {
    int getData = Serial2.parseInt();

    // Codierung auslesen
    byte decoding;
    decoding += 1 * bitRead(getData, 0);
    decoding += 2 * bitRead(getData, 1);
    decoding += 4 * bitRead(getData, 2);
    decoding += 8 * bitRead(getData, 3);
    getData = getData >> 4;


    switch (decoding) {
    case 1:
      digitalWrite(PSB_START, bitRead(getData, 0));
      digitalWrite(PSB_SELECT, bitRead(getData, 1));
      digitalWrite(PSB_ANALOG, bitRead(getData, 2));
      break;

    case 2:
      digitalWrite(PSB_PAD_UP, bitRead(getData, 0));
      digitalWrite(PSB_PAD_RIGHT, bitRead(getData, 1));
      digitalWrite(PSB_PAD_DOWN, bitRead(getData, 2));
      digitalWrite(PSB_PAD_LEFT, bitRead(getData, 3));
      break;

    case 3:
      digitalWrite(PSB_TRIANGLE, bitRead(getData, 0));
      digitalWrite(PSB_CIRCLE, bitRead(getData, 1));
      digitalWrite(PSB_CROSS, bitRead(getData, 2));
      digitalWrite(PSB_SQUARE, bitRead(getData, 3));
      break;

    case 4:
      digitalWrite(PSB_L1, bitRead(getData, 0));
      digitalWrite(PSB_L2, bitRead(getData, 1));
      digitalWrite(PSB_L3, bitRead(getData, 2));
      break;

    case 5:
      digitalWrite(PSB_R1, bitRead(getData, 0));
      digitalWrite(PSB_R2, bitRead(getData, 1));
      digitalWrite(PSB_R3, bitRead(getData, 2));
      break;

    case 6:
      valueLX = getData;
      break;

    case 7:
      valueLY = getData;
      break;

    case 8:
      valueRX = getData;
      break;

    case 9:
      valueRY = getData;
      break;
    }
    // Rueckmeldung Daten erhalten
    Serial2 << 255<< endl;
 
  }

  if(valueLX > 0 && valueLX < 100) {
    digitalWrite(PSS_LX1, 1);
    digitalWrite(PSS_LX2, 0);
  }
  else if(valueLX > 127) {
    digitalWrite(PSS_LX1, 0);
    digitalWrite(PSS_LX2, 1);
  }
  else {
    digitalWrite(PSS_LX1, 0);
    digitalWrite(PSS_LX2, 0);
  }

  if(valueLY > 0 && valueLY < 100) {
    digitalWrite(PSS_LY1, 1);
    digitalWrite(PSS_LY2, 0);
  }
  else if(valueLY > 150) {
    digitalWrite(PSS_LY1, 1);
    digitalWrite(PSS_LY2, 0);
  }
  else {
    digitalWrite(PSS_LY1, 0);
    digitalWrite(PSS_LY2, 0);
  }


  if(valueRX > 0 && valueRX < 100) {
    digitalWrite(PSS_RX1, 1);
    digitalWrite(PSS_RX2, 0);
  }
  else if(valueRX > 150) {
    digitalWrite(PSS_RX1, 0);
    digitalWrite(PSS_RX2, 1);
  }
  else {
    digitalWrite(PSS_RX1, 0);
    digitalWrite(PSS_RX2, 0);
  }


  if(valueRY > 0 && valueRY < 100) {
    digitalWrite(PSS_RY1, 1);
    digitalWrite(PSS_RY2, 0);
  }
  else if(valueRY > 150) {
    digitalWrite(PSS_RY1, 0);
    digitalWrite(PSS_RY2, 1);
  }
  else {
    digitalWrite(PSS_RY1, 0);
    digitalWrite(PSS_RY2, 0);
  }
}

Empfänger :
Wieso so:

    byte decoding;
    decoding += 1 * bitRead(getData, 0);
    decoding += 2 * bitRead(getData, 1);
    decoding += 4 * bitRead(getData, 2);
    decoding += 8 * bitRead(getData, 3);

anstatt

byte decoding = ((bitRead(getData, 0) << 0) | (bitRead(getData, 1) << 1) | (bitRead(getData, 2) << 2) | (bitRead(getData, 3) << 3));

Jomelo:

byte decoding = ((bitRead(getData, 0) << 0) | (bitRead(getData, 1) << 1) | (bitRead(getData, 0) << 2) | (bitRead(getData, 0) << 3));

Muss das nicht byte decoding = ((bitRead(getData, 0) << 0) | (bitRead(getData, 0) << 1) | (bitRead(getData, 0) << 2) | (bitRead(getData, 0) << 3)); heißen? Wieso so nicht, weil ich die Schreibweise noch nicht wahrgenommen habe. Hab mich mehr auf die anderen Parts mit dem Bitshifting konzentriert :wink:

Danke

Ja, das mit 0, 1 , 2, 3 hab ich nun oben korrigiert ;-) Immer dieses Copy&Paste

Edit: So wie bei dir alles mit 0 wäre falsch, da es ja immer das gleiche bit ist. Es sollen ja schon die 4 Bit ausgewertet werden.

Man soll ja auch Copy&Paste&Edit machen ;) Ist die Schreibweise beim Sender soweit in Ordnun vom Stil?

Aber lustig zu sehen, wie elegante Lösungen von der Arduino-Standardlösung abweichen - du bist auf dem besten Weg (wie die meisten, die mit dem Arduino angefangen haben) auf Plain AVR C zu wechseln :)

Bei mir war das ganz ähnlich. Ich bin noch weit entfernt, alles über C/C++ und auch den Arduino zu wissen - aber irgendwann kommt man an einen Punkt, wo fertige Lösungen nicht mehr greifen oder komfortabel sind. Und dann tastet man sich Schritt für Schritt weiter, bis man bei bare-metal und (in meinem Fall) auch den STM32 und den PICs landet. Ich benutz den Arduino inzwischen immer noch gerne zum prototyping von einigen Sachen - aber soetwas wie Shields hat der noch nie gesehen (bin aber auch eher bei den Mini / Nano / Micros). Das ganze ding wird dann auf eine eigene platine mit SMD-Chip geflasht und dann ist es eh egal, was der Unterbau ist. :)

sschultewolter: Hier das Video vom derzeitgen Aufbau https://www.dropbox.com/s/dzc5ih9wijulxz0/2014-02-10%2000.45.36.mp4

Hallo Marcus. Shields habe ich hier eigentlich garnicht im Einsatz. Fertige Shields habe ich sowie nie welche im Einsatz. Wenn dann sind es meist Prototyping Shields, wo nichts drauf ist.

Hauptsächlich nutze ich den Arduino Pro Mini. Wie auch in dem Video vielleicht zu sehen, ist dieser die Hauptsteuereinheit (unten auf dem Breadboard).

Im hinteren Bereich ist der Mega evtl. zu sehen, das ich den eingesetzt habe, hat auch nur einen Grund, ich brauchte die Pins. Wollte nicht unnötig noch auf dem Breadboard Shiftregister anbringen. Habe die LEDs alle soweit direkt über die Pins angesteuert. Ich weiß, der Ausgangsstrom für die Pins ist begrenzt, ist mir auch bewusst. Deshalb habe ich die Leds mit Hilfe des Widerstandes mit etwa ~5mA am leuchten. Üblich sind bei diesen Leds 20mA und dann kann man in die Led aufgrund der Helligkeit nicht mehr reinschauen. Das schalten aller Pins ist auch hardwaretechnisch nicht möglich (PS2 Kontroller Steuerkreuz links ist eine Wippe. Maximal 2 von 4 Pins können gleichzeitig betätigt werden. Das gleiche gilt für die Joysticks. Und für die anderen Tasten, soviele Finger habe ich nicht :)

Zum Ende des Projekts würde ich den Code gerne nicht in diesem Arduino C präsentieren. Ich würde mich gerne an das normale C, welches auch so in allen Büchern, die sich nicht um den Arduino ranken, beschrieben wird. Evtl auch C++ (Basics bekannt).

Den Pro Mini habe ich aber später auch weiter vor, zu nutzen. Der belegte Speicher durch den Bootloader ist beim Pro Mini im vergleich zum Pro Micro einiges geringer (~4%). Einen richtigen AVR Progger wurde bereits in der Bucht bestellt. Müsste dann nur sehen, wie ich das ganze löse, dass ich Sketche über ICSP übertrage, ohne die Hälfte der Schaltung vorab abzuklemmen. Aber dazu weiteres, wenn das Teil da ist.

Bücher für das "richtige C" habe ich 2, von denen ich denke, das beide nicht die schlechtesten sind. "Powerprojekte mit Arduino und C", sowie "C von A bis Z"(C Allgmein).

Netter Aufbau

sschultewolter:
Im hinteren Bereich ist der Mega evtl. zu sehen, das ich den eingesetzt habe, hat auch nur einen Grund, ich brauchte die Pins. Wollte nicht unnötig noch auf dem Breadboard Shiftregister anbringen. Habe die LEDs alle soweit direkt über die Pins angesteuert. Ich weiß, der Ausgangsstrom für die Pins ist begrenzt, ist mir auch bewusst. Deshalb habe ich die Leds mit Hilfe des Widerstandes mit etwa ~5mA am leuchten. Üblich sind bei diesen Leds 20mA und dann kann man in die Led aufgrund der Helligkeit nicht mehr reinschauen. Das schalten aller Pins ist auch hardwaretechnisch nicht möglich (PS2 Kontroller Steuerkreuz links ist eine Wippe. Maximal 2 von 4 Pins können gleichzeitig betätigt werden. Das gleiche gilt für die Joysticks. Und für die anderen Tasten, soviele Finger habe ich nicht :slight_smile:

Das ist ein Argument, dass ich absolut nicht nachvollziehen kann. Was spricht gegen einen Portexpander alla PCF85xx / PCF95XX etc? I2C x-beliebig viele Ports, cascadierbar, billig (knapp einen Euro). Ich geh allerdings immer von einem diskreten Aufbau auf einer individuellen Platine aus - und da wär mir der Aufwand den TQFP-100 vom Mega zu routen und die entsprechende Zusatzbeschaltung zu viel. Außerdem kostet ein kleine Mega, oder sogar ein Tiny plus die Expander oft weniger als ein 2560. Den 2560 benutz ich nur, wenn ich das Flash oder das RAM brauche, niemals aber wenn ich Pins brauche.

EDIT: Oder man baut sich seine 1²C-Port-Erweiterung mit ein paar Tinys, da hat man dann absolute kontrolle, was das Ding macht.

Man muss sich immer vor augen führen, dass die Bauteile, die wir benutzen nicht für Bastler entwickelt wurde - sie finden einsatz in der Industrie. Es gibt also durchaus auch gründe, die für den Einsatz dieser Teile sprechen, z.B. Single-Point-of-failure etc.

Das ist der Prototyp. Die Fernbedienung (PSController) ist soweit fertig, bis auf das fehlende XBee Modul. Ich wollte nur testen, ob der Sketch soweit das macht, was ich möchte. Vorallem ob die 57600 Baud ausreichen (was es mehr als tut!). Denn ich lasse nur neue Werte übertragen. Aber vom Joystick kommen eine ganze Menge an Daten wenn der mal sich bewegt ;)

Der Mega ist einfach nur dazu dau, die entsprechenden Tasten zu mappen. Verbunden nur über Rx/Tx. Das Teil wird morgen wieder auseinander gebaut, wenn die Teile da sind. PortExpander Shield habe ich nicht. Shiftregister schon. Hätte die TLC5916 einsetzen können. Hab davon genug für umsonst als DIP bekommen. TLC5940 hatte ich nicht genug und 74HC595 habe ich einen ganzen Haufen. Jedoch finde ich die Dinger einfach nur zum K*****. Da brauchste auch einen ganzen Haufen an extra Beschaltung (Widerstände). Welche ich mir mit dem TLC hätte ersparen könnte.

Es ging bei dem Aufbau auf dem Breadboard nur um zu testen, ob meine Serielles Protokoll damit klar kommt, wenn mehrere verschiedene Tasten gleichzeitig gedrückt werden.

Den Mega habe ich eigentlich nie im Einsatz. Habe den mir damals aus der Bucht direkt nach dem Uno geholt. Da waren Portexpander mir noch nicht bekannt. Aber wirklich gebraucht habe ich ihn nie. Lediglich, wenn ich mal mehrere Serielle stellen auswerten möchte. Denn NewSoftSerial/SoftSerial ist zu langsam und AltSoftSerial belegte mir mit dem Timer den Pin 10.

Eine Frage, was ist ein kleiner Mega? Ich habe im engl. Teil gesehen, dass einer ein BreakoutBoard für den Chip gemacht hat mit doppelten Pinreihen aussen rum. Sowas würde mich defenitiv auch noch interessieren für größere Projekte. Denn mich stört meist doch der kleine Speicher von den 328. Tritt aber nur auf, wenn ich GLCD einsetze. Wollte mich in naher Zukunft mit zusätzlichen Speichererweiterungen mal auseinander setzen. Bin aber nun erstmal dabei, "PowerProjekte Arduino und C" durch zu arbeiten. Hab seit meinem Begin mit den µC (zeitgleich mit der Anmeldung hier im Juli?) erst 1 oder 2 Kapitel Grundlagen abgearbeitet. Das Buch war in Verbindung mit dem SMD UNO sehr preiswert. Wobei, hätte ich das gewusst, hätte ich mir das Buch doch lieber einzeln geholt und irgendeinen DIP UNO aus der Bucht ;)