Verständnisproblem für Schreibweise einer Formel

Hallo Leute,

sitze in den Endzügen meines Projektes eines Tachoumbaus bei dem ich vor Allem Can-Bus Signale übersetzen musste.

Jetzt sitze ich an einem Problem, wo ich irgendwie nicht weiterkomme.

Beim alten Tacho gibt es digitale Signale, die dann in einem Can-Bus Signal ausgegeben werden. Diese Aufgabe muss nun das Arduino Due übernehmen.

Ich muss bei dem Byte6 eines Can-Bus Signals einen Wert ausgeben der sich aus mehreren Faktoren zusammensetzt. (Zahlen in Hex)
Tür-vorne links = 01
Tür-vorne rechts = 02
Tür-hinten links = 04
Tür-hinten rechts = 08
Heckklappe = 10

Wenn also z.B. die Tür vorne rechts, hinten links und die Heckklappe offen sind, muss über den Byte6 der Wert 16 (hex) ausgeben werden.

Für jedes der Signale gibt es jeweils einen digitalen input.

Wie gehe ich da am Besten mit Variablen und if-Abfragen ran?

Hier schonmal der Anfang von meinem Code:

void setup() {
  //start serial connection
  Serial.begin(9600);
  //configure pin 2 as an input and enable the internal pull-up resistor
  pinMode(4, INPUT_PULLUP); //Tür VO RE
  pinMode(5, INPUT_PULLUP); //Tür VO LI
  pinMode(6, INPUT_PULLUP); //Tür HI RE
  pinMode(7, INPUT_PULLUP); //Tür HI LI
  pinMode(8, INPUT_PULLUP); //Heckklappe
}

void loop() {
  //read the pushbutton value into a variable
  int TUERVR    = digitalRead(4);
  int TUERVL    = digitalRead(5);
  int TUERHR    = digitalRead(6);
  int TUERHL    = digitalRead(7);
  int HECK      = digitalRead(8);
}

Die Idee war meinerseits zu sagen die Variable z.B. TUERVR = 00 und wenn der taster gedrückt ist, dass die Variable dann auf 02 änder. Die Variablen dann in einer einfachen Addition addiere.
Ich weiß halt leider nur nicht wie ich die Variablen über eine if-Abfrage ändern kann.

struct door
{
  uint8_t pin;
  uint8_t maske;
};

Und dann ein "Range based loop" über einen Container aller Türen
(ok, das war jetzt die Kurzfassung)

Sie können Maskierung verwenden

// Masks
const byte turVorneLinks    = 0x1;
const byte turVorneRechts   = 0x2;
const byte turHintenLinks   = 0x4;
const byte turHintenRechts  = 0x8;
const byte Heckklappe       = 0x10;

// gefälschter Wert, normalerweise dynamisch erhalten
bool turVorneLinksOffen    = false;
bool turVorneRechtsOffen   = true;
bool turHintenLinksOffen   = true;
bool turHintenRechtsOffen  = false;
bool HeckklappeOffen       = true;

void setup() {
  Serial.begin(115200);
  byte byte6 = 0;
  // -------- Maskierung --------
  if (turVorneLinksOffen)   byte6 |= turVorneLinks;
  if (turVorneRechtsOffen)  byte6 |= turVorneRechts;
  if (turHintenLinksOffen)  byte6 |= turHintenLinks;
  if (turHintenRechtsOffen) byte6 |= turHintenRechts;
  if (HeckklappeOffen)      byte6 |= Heckklappe;
  // ------------------------
  Serial.print(F("\nByte6 = 0b"));
  Serial.println(byte6, BIN);
}

void loop() {}

gucke ich mir direkt mal an.

int TUERVR = digitalRead(4) * 2;
int TUERVL = digitalRead(5);
int TUERHR = digitalRead(6) * 8;
int TUERHL = digitalRead(7) * 4;
int HECK = digitalRead(8) * 16;

Dies ist eine Art Hack, es hängt von HIGH und LOW ab, um als 1 und 0 angesehen zu werden. Es wird funktionieren, aber es ist keine gute Codierungspraxis. Arduino könnte eines Tages entscheiden, HIGH und LOW in einen formalen Enum-Typ zu ändern, und Sie könnten in Schwierigkeiten geraten (der Compiler wird sich beschweren).

// Masks
const byte turVorneLinks    = 0x1;
...
byte6 |= (digitalRead(pinTurVorneLinks) == LOW) ? 0 : turVorneLinks;
...

Falls nicht fügt man noch einen Typecast hinzu.

BTW welchen Datentyp hat digitalRead()? Tatsächlich ist der Typ int, daran wird sich auch in Zukunft nichts mehr ändern. Da ist die Gefahr viel größer, daß LOW und HIGH einmal umdefiniert werden.

Funktioniert leider genau umgekehrt.

Wenn das Signal nicht kommt ist der Pin high. Der Anschluss des Signals ist wie hier erfolgt: https://www.arduino.cc/en/Tutorial/BuiltInExamples/InputPullupSerial

Ausgabe in Bin ist falsch.... aber selbst wenn ich auf HEX ändere kommen falsche Ergebnisse raus. Ab einem bestimmten Ergebnis scheint er nicht weiterzuzählen....

Beispiel...
const bool turVorneLinksOffen = false;
const bool turVorneRechtsOffen = false;
const bool turHintenLinksOffen = true;
const bool turHintenRechtsOffen = true;
const bool HeckklappeOffen = true;

wirft mir 28 raus. sollte aber 22 sein.

int

das scheint mir richtig zu sein

Dann eben
int TUERVR = !digitalRead(4) * 2;
oder
int TUERVR = !digitalRead(4) << 1;

Und zum Senden:
byte xx = TUERVR | TUERVL ...

Anscheinend ein Kommunikationsproblem :)....

Ich möchte ein Can-Bus Signal senden mit dem Datenpaket
00 00 00 00 00 00 xx 00

Anstatt xx soll ein entsprechender Wert übermittelt werden.

ja also xx ist byte6

// Masks
const byte turVorneLinks    = 0x1;
const byte turVorneRechts   = 0x2;
const byte turHintenLinks   = 0x4;
const byte turHintenRechts  = 0x8;
const byte Heckklappe       = 0x10;

// gefälschter Wert, normalerweise dynamisch erhalten
bool turVorneLinksOffen    = false;
bool turVorneRechtsOffen   = false;
bool turHintenLinksOffen   = true;
bool turHintenRechtsOffen  = true;
bool HeckklappeOffen       = true;

void setup() {
  Serial.begin(115200);
  byte byte6 = 0;
  // -------- Maskierung --------
  if (turVorneLinksOffen)   byte6 |= turVorneLinks;
  if (turVorneRechtsOffen)  byte6 |= turVorneRechts;
  if (turHintenLinksOffen)  byte6 |= turHintenLinks;
  if (turHintenRechtsOffen) byte6 |= turHintenRechts;
  if (HeckklappeOffen)      byte6 |= Heckklappe;
  // ------------------------
  Serial.print(F("\nByte6 = 0b"));
  Serial.println(byte6, BIN);
}

void loop() {}

Serial Monitor ➜ Byte6 = 0b11100

wirft mir 28 raus. sollte aber 22 sein

warum ? 0x10 + 0x8 + 0x4 = 0x1C = 28

es wurde diskutiert ➜ schau hier

typedef enum {
  LOW     = 0,
  HIGH    = 1,
  CHANGE  = 2,
  FALLING = 3,
  RISING  = 4,
} PinStatus;

typedef enum {
  INPUT           = 0x0,
  OUTPUT          = 0x1,
  INPUT_PULLUP    = 0x2,
  INPUT_PULLDOWN  = 0x3,
} PinMode;
...

void pinMode(pin_size_t pinNumber, PinMode pinMode);
void digitalWrite(pin_size_t pinNumber, PinStatus status);
PinStatus digitalRead(pin_size_t pinNumber);

kann es sein das du einfach

10+8+4 = 22

gerechnet hast?
das geht bei HEX leider nicht ganz so einfach.

die ursprünglichen informationen sind

dies ist eine oktale Notation und 08 macht keinen Sinn... Also nahm ich an, dass es hexadezimal war (und "Zahlen in Hex")

Tür-vorne links = 0x01 ➜ 1dec
Tür-vorne rechts = 0x02 ➜ 2dec
Tür-hinten links = 0x04 ➜ 4dec
Tür-hinten rechts = 0x08 ➜ 8dec
Heckklappe = 0x10 ➜ 16dec

Ich muss das jetzt selber nochmal kurz am Fahrzeug überprüfen...

Abgesehen davon, daß digitalRead() keinesfalls irgendwann einmal CHANGE usw. liefern sollte, und damit diese Definition absolut unprofessionell ist, um nicht zu sagen völlig bekloppt,

steht in meiner Arduino.h eindeutig
int digitalRead(uint8_t pin);

Aber ich merke schon, mit meinem Minimalismus bin ich wohl nicht mehr auf der Höhe der Zeit. Ich wurde noch nach Stunden bezahlt, nicht nach Anzahl Zeilen. Und ein guter Teil meiner Arbeit bestand darin, anderer Leute Code so zusammenzustreichen, daß er hinterher auch funktioniert hat.

Ja, die Idee hat viel Gegenwind bekommen