Wert eines 'char' abfragen

Hallo zusammen,

stehe grad vollkommen auf dem Schlauch…
Ich empfange über altSerial einen Wert zwischen 1000 und 1111 (je nach Zustand der dortigen Schalter);
Nun soll am Empfängerbord ein Ausgang gesetzt werden, wenn alle Schalter da sind, und das klappt nicht.

Zur Kontrolle lass ich mir den Wert von c auf dem Seriellen Monitor anzeigen und der stimmt.
wenn nur 2 Schalter da sind zeigt er 1011, wenn nur einer da ist 1001 und wenn alle da sind 1111, nur die Abfrage klappt irgendwie nicht…

#include <AltSoftSerial.h>

AltSoftSerial altSerial;
char c;
int test = 13;

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for Arduino Serial Monitor to open
  altSerial.begin(9600);
  pinMode(test, OUTPUT);
}

void loop() {
    if (altSerial.available())
  {
    c = altSerial.read();
    if (c == '1111'){digitalWrite(test, HIGH);}
    if (c < '1111'){digitalWrite(test, LOW);}
    Serial.print(c); }
    
  
}

Was zeigt der Seriellen Monitor denn an, 1111 oder 15?

Warnungen: "character constant too long for its type", "comparison is always false due to limited range of data type"

Möglicherweise meinst du ja?    if (c == 0b1111)

agmue:
Was zeigt der Seriellen Monitor denn an, 1111 oder 15?

Warnungen: "character constant too long for its type", "comparison is always false due to limited range of data type"

Er zeigt mir im seriellen Monitor genau das an was der andere senden soll bzw. genau das was auch kommen sollen nämlich
1111
oder
1011
oder
1101
usw.....je nach Schalterstellung, also das stimmt wohl

Und wie druckst du das aus?

In BIN, HEX oder DEC?

ich drucke es in BIN aus....

Dann müsste das doch mit if (c == 0b1111)gehen. Oder mit if (c == 0xF)oder if (c == 15)ist ja alles funktional identisch.

NormanIGB:
ich drucke es in BIN aus....

So so...
Du verwendest also einen ganzzahligen Datentype, vergleichst aber Strings, bzw. Buchstaben.
Eine lustige Idee, ist aber leider so nicht zielführend.

Nein, Whandall, funktioniert nicht.
Das hab ich direkt nach deinem Tipp eben schon probiert und jetzt nochmal mit allen 3, keiner der 3 funktioniert

Ich empfange über altSerial einen Wert zwischen 1000 und 1111

Über Serial ( auch altSerial ) werden bytes übertragen. Die sind oft als Buchstaben lesbar.

Wenn du in deinem Code

void loop() {
    if (altSerial.available()) {
      char c = altSerial.read();
      Serial.print(c); 
    }
}

im SerialMonitor "1111" siehst, ist die Ausgabe nicht binär.

Um einen Text wie "1000" zu lesen, musst du vier mal read() aufrufen ...
Das passiert in deinem Sketch auch, in 4 oder mehr Umläufen.
Nur hat natürlich keines der 4 Zeichen den Wert '1111'. Das hat sogar schon der Compiler gemerkt, dass das nicht sein kann.

Woran erkennst du übrigens, dass der Text "1111" gekommen ist, bzw. woran erkennst du Anfang und Ende einer solchen Nachricht? Wie oft kommt denn was?

Irgendwann siehst du im SerialMonitor sowas wie 10111101110010111111 ... oder?
Wenn die 4 Zeichen nicht zu oft kommen, ist die Wahrscheinlichkeit recht gering, dass der Empfänger mitten in einer Sequenz startet, aber schön ist das nicht, finde ich.

Vier Schalter-Zustände könnte man natürlich auch kompakter darstellen, so dass alle zusammen bequem in einen einzigen Buchstaben (Byte) passen. Dann hättest du weder die Schwierigkeit, das Ergebnis zu erkennen, noch das Problem mit erstem oder letztem Zeichen.

michael_x:
Vier Schalter-Zustände könnte man natürlich auch kompakter darstellen, so dass alle zusammen bequem in einen einzigen Buchstaben (Byte) passen. Dann hättest du weder die Schwierigkeit, das Ergebnis zu erkennen, noch das Problem mit erstem oder letztem Zeichen.

Und wie mach ich das, Michael?

michael_x:
Woran erkennst du übrigens, dass der Text "1111" gekommen ist, bzw. woran erkennst du Anfang und Ende einer solchen Nachricht? Wie oft kommt denn was?

Irgendwann siehst du im SerialMonitor sowas wie 10111101110010111111 ... oder?

Nein, er zeigt mir die schön untereinander an, der Sender sendet nur bei Statuswechsel.

Aber du hast recht, wenn ich als Serial.println ausgebe stell ich fest, dass die 1111 z.b. in 4 verschiedenen Zeilen kommt.

Vielleicht hier noch mein Sender-Code zur besseren Übersicht:

void loop() 
{
  state = digitalRead(ws);
 
  if (state != lastState) 
  {
    if (state == HIGH) 
    {
      if (ledState == HIGH) 
      {
        ledState = LOW;
        bitWrite(bit1, 0, 0);
        Serial.println(bit1, BIN);
      }
      else
      {
        ledState = HIGH;
        bitWrite(bit1, 0, 1);
        Serial.println(bit1, BIN);
      }
    }
    lastState = state;
    
  }

  
 
  digitalWrite(blau, ledState);
  delay(10);

    state1 = digitalRead(og);
 
  if (state1 != lastState1) 
  {
    if (state1 == HIGH) 
    {
      if (ledState1 == HIGH) 
      {
        ledState1 = LOW; 
        bitWrite(bit1, 1, 0);
        Serial.println(bit1, BIN);
      }
      else
      {
        ledState1 = HIGH;
        bitWrite(bit1, 1, 1);
        Serial.println(bit1, BIN);
      }
    }
    lastState1 = state1;
  }
 
  digitalWrite(gruen, ledState1);
  delay(10);

    state2 = digitalRead(rd);
 
  if (state2 != lastState2) 
  {
    if (state2 == HIGH) 
    {
      if (ledState2 == HIGH) 
      {
        ledState2 = LOW;
        bitWrite(bit1, 2, 0);
        Serial.println(bit1, BIN);
      }
      else
      {
        ledState2 = HIGH; 
        bitWrite(bit1, 2, 1);
        Serial.println(bit1, BIN);
      }
    }
    lastState2 = state2;
  }

agmue:
Warnungen: "character constant too long for its type", "comparison is always false due to limited range of data type"

Kommt daher, weil char Literale int sind (nicht char wie man vielleicht denkt!). Daher geht maximal '11' wenn man das missbrauchen wollte

mein Sender-Code zur besseren Übersicht

Serial.println(bit1, BIN);

Erwischt! Du versuchst uns zu verwirren.
Die erste (geheime) 1 die du sendest, dient dazu dass immer 4 Buchstaben kommen.
Du sendest noch einen Zeilenende-Buchstaben hinterher, der im Empfänger für Struktur sorgt.

Wenn du statt der geheimen Vorbelegung 0x08 eine 0x40 nimmst, und
Serial.write(bit1); verwendest, kommt
statt "1111\n" ein einzelnes 'G' (0x47)
statt "1000\n" ein '@'
usw, alles auch menschen-lesbare Zeichen.

Wenn nicht, ist deine Definition der geheimen Variablenbit1falsch.

michael_x:
Erwischt! Du versuchst uns zu verwirren.
Die erste (geheime) 1 die du sendest, dient dazu dass immer 4 Buchstaben kommen.
Du sendest noch einen Zeilenende-Buchstaben hinterher, der im Empfänger für Struktur sorgt.

Wenn du statt der geheimen Vorbelegung 0x08 eine 0x40 nimmst, und
Serial.write(bit1); verwendest, kommt
statt "1111\n" ein einzelnes 'G' (0x47)
statt "1000\n" ein '@'
usw, alles auch menschen-lesbare Zeichen.

Wenn nicht, ist deine Definition der geheimen Variablenbit1falsch.

Sorry, bin raus......mit der Erklärung komm ich nicht klar.....

Ich will einfach ein Byte versenden, dass je nach Schalterzustand 1001 oder 1011 oder 1000 usw. versendet....und der Empfänger soll dieses so empfangen

NormanIGB:
Sorry, bin raus......

Also gedanklich bin ich raus, nicht aus dem Forum :wink:
Will heißen, kann der Erklärung nicht folgen.....

Ich will einfach ein Byte versenden

Dann mach das doch.

 Serial.write(bit1); // versendet 1 byte

Dass du in bit1 noch andere Bits setzt (z.Zt. die 8 ) kannst du machen wie du willst.

Der Vorschlag mit 0x40 statt 8 hätte dir nur ein einfacher lesbares Zeichen geliefert.
Aber du kannst auch die Test-Ausgabe im Empfänger auf Serial.println(c, BIN); umstellen
und, wie Whandall schon vorgeschlagen hat, auf  if (c == 0b1111)  abfragen.

michael_x:
Wenn du statt der geheimen Vorbelegung 0x08 eine 0x40 nimmst, und
Serial.write(bit1); verwendest, kommt
statt "1111\n" ein einzelnes 'G' (0x47)
statt "1000\n" ein '@'
usw, alles auch menschen-lesbare Zeichen.

Wenn nicht, ist deine Definition der geheimen Variablenbit1falsch.

Michael, vielen Dank für den hinweis!!
Mit Serial.write(bit1) klappt es, danke....aber den Rest mit 0x08 und 0x40 hab ich immer noch nicht verstanden :wink:

Wenn du das wichtigste, die Variablendefinition, nicht ignorieren und geheimhalten würdest,
sondern dir anschaust, woher das erste Zeichen in 1111 kommt...

michael_x:
Wenn du das wichtigste, die Variablendefinition, nicht ignorieren und geheimhalten würdest,
sondern dir anschaust, woher das erste Zeichen in 1111 kommt…

Das erste Zeichen kommt, wenn der Sender online ist.

Okay, ich hab jetzt ein echtes Byte empfangen, aber wie kann ich das bitweise zelegen?

Hiermit:
https://www.arduino.cc/en/Reference/BitRead

Was übrigens nur ein einfaches Makro ist:

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)

Man schiebt das Bit das man will auf das niederwertigste Bit und setzt alle anderen Bits mit & auf Null. Dann hat man 0 oder 1 je nachdem ob das Bit 0 oder 1 war

Nur zur Erklärung was da abläuft. Die IDE hat es fertig implementiert.