Serial-Streik

Hallo zusammen,

da das mit dem Display erst mal ne Weile dauern kann, wollte ich mit der Seriellen Kommunikation weiter machen und damit zum Test nur mal zwischen PC und IC.

Vorgehensweisen:

  1. Folgenden Sketch mit ISP hochgeladen:

int inByte = 0;
int blink = 0;
int ledState = LOW;
long previousMillis = 0;
long interval = 50;

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

pinMode(9, OUTPUT);
}

void loop()
{
if (Serial.available() > 0)
{
Serial.print("Hallo ");
Serial.println("Arduino-Nachbau");
}
}

  1. Im IDE Seriellen Port auf COM 7 (USB-Konverter) ausgewählt.

  2. Seriellen Monitor geöffnet.

  3. Vergebens auf Nachrichten gewartet.

  4. Vorgehensweise:

  5. Bootleader mit ISP auf IC geladen.

  6. USB-Konverter mit IC wegen RX/TX (ja, USB-TX auf IC-RX und USB-RX auf IC-TX) verbunden.

  7. Oben genannten Sektch hochgeladen.

  8. Keine Antwort vom IC.
    (Ja, bootleader laut IDE erfolgreich hochgeladen.)

Was hab ich hier wieder falsch gemacht?

LG

Fipsi

Hast Du dei Masse USB Converter - IC verbunden?
Versuch mal ob Du nicht TX-TX bzw RX-RX zusammenschalten mußt. Das weil die Senderichtung verschieden interpretiert werden kann.
Grüße Uwe

uwefed:
Hast Du dei Masse USB Converter - IC verbunden?

Ja, die Stromversorgung hab ich eh über den USB-Konverter, da dieser eine stabiliere Spannung liefert.

uwefed:
Versuch mal ob Du nicht TX-TX bzw RX-RX zusammenschalten mußt. Das weil die Senderichtung verschieden interpretiert werden kann.

Schon probiert, dann geht am USB-Konverter eine LED aus.

LG

Fipsi

Edit:
So, mein PC gerade abgestürzt, dachte mir, gut, spiel ich den Sketch einfach nochmal auf und siehe da: die LED am USB-Konverter blinkt im Takt der Datensendung, allerdings bekomm ich den Seriellen Monitor nicht auf, steht dauernt da, der Port wird bereits verwendet.

So, ein wenig fühl ich mich jetzt verarscht.

Davon abgesehen, dass sich der IDE öfter weigert den Seriellen Monitor zu öffnen, weil angeblich der Port besetzt ist, funktioniert jetzt alles.

LG

Fipsi

Edit:
Das einzige, was mich wundert, ist, dass ich dem Seriellen erst einen "schupser" geben muss. Heißt, erst, wenn ich was an den IC geschickt hab, macht er was.

Fipsi:
Das einzige, was mich wundert, ist, dass ich dem Seriellen erst einen "schupser" geben muss. Heißt, erst, wenn ich was an den IC geschickt hab, macht er was.

Der Sketch schickt erst dann Daten wenn er irgendwas auf der seriellen Schnittstelle bekommt und dann kontinuirlich bei jedem loop() Durchgang weil Du den seriellen Buffer nicht mittels serial.Read() leerst .

if (Serial.available() > 0)
  {
    Serial.print("Hallo ");

Grüße Uwe

Dass er andauernd sendet, ist jetzt noch eher weniger das Problem.

Jetzt kommt mir aber die Frage:
Wenn er erst Daten schickt, nachdem er was bekommen hat, wie kann ich dann die Kommunikation zwischen zwei Boards herstellen?

LG

Fipsi

hi,

er schickt deshalb erst dann, wenn er was bekommen hat, weil du ihm das so gesagt hast. mit

if (Serial.available() > 0)

wartet er, bis er was bekommt. dann mach ein Serial.read, um die daten zu lesen (und den puffer zu leeren).

wenn du kein if (Serial.available() > 0) reinschreibst, sonder gleich Serial println, schreibt er von beginn an.

gruß stefan

Du hast wohl nur das Wort "available" falsch interpretiert. Es heisst nicht, dass die Gegenstelle bereit ist etwas zu empfangen, sodern dass sie was gesendet hat

Fipsi:
Jetzt kommt mir aber die Frage:
Wenn er erst Daten schickt, nachdem er was bekommen hat, wie kann ich dann die Kommunikation zwischen zwei Boards herstellen?

Hängt von deiner Kommunikation ab.

Oft ist es gut, wenn einer ein Master ( oder Client ) ist und der andere ein Slave ( oder Server ).
Der erste ist aktiv und der andere reagiert. Daten gehen in beide Richtungen.
Der Master/Client sendet und fragt, der dienende hört es und antwortet ( ggfls mit seinen Daten ).
Macht oft mehr Sinn, wenn mehr als 2 Teilnehmer da sind:
entweder 1 Master - viele Slaves,
oder viele Clients - 1 Server

Alternative:
Beide melden einfach, was sie zu sagen haben, und fertig. ( Was sollen sie anders machen ob es gehört wird oder nicht ?)

Ob die jeweilige Gegenstelle bereit ist, kriegst du übrigens nicht raus mit Rx/Tx/GND ( ausser du vertraust darauf, dass Rx = HIGH nur von einer aktiven Gegenstelle kommen kann)

Auch einfach:
Beide senden regelmässig Lebenszeichen.

Eisebaer:
hi,

er schickt deshalb erst dann, wenn er was bekommen hat, weil du ihm das so gesagt hast. mit

if (Serial.available() > 0)

wartet er, bis er was bekommt. dann mach ein Serial.read, um die daten zu lesen (und den puffer zu leeren).

wenn du kein if (Serial.available() > 0) reinschreibst, sonder gleich Serial println, schreibt er von beginn an.

Ahhhh, super, danke. Damit ist das Problem gelöst :slight_smile:

michael_x:
Du hast wohl nur das Wort "available" falsch interpretiert. Es heisst nicht, dass die Gegenstelle bereit ist etwas zu empfangen, sodern dass sie was gesendet hat

Ja. Ich dachte, das available bedeutet, ob überhaupt eine Verbindung hergestellt werden konnte.

michael_x:

Fipsi:
Jetzt kommt mir aber die Frage:
Wenn er erst Daten schickt, nachdem er was bekommen hat, wie kann ich dann die Kommunikation zwischen zwei Boards herstellen?

Hängt von deiner Kommunikation ab.

Oft ist es gut, wenn einer ein Master ( oder Client ) ist und der andere ein Slave ( oder Server ).
Der erste ist aktiv und der andere reagiert. Daten gehen in beide Richtungen.
Der Master/Client sendet und fragt, der dienende hört es und antwortet ( ggfls mit seinen Daten ).
Macht oft mehr Sinn, wenn mehr als 2 Teilnehmer da sind:
entweder 1 Master - viele Slaves,
oder viele Clients - 1 Server

Alternative:
Beide melden einfach, was sie zu sagen haben, und fertig. ( Was sollen sie anders machen ob es gehört wird oder nicht ?)

Ob die jeweilige Gegenstelle bereit ist, kriegst du übrigens nicht raus mit Rx/Tx/GND ( ausser du vertraust darauf, dass Rx = HIGH nur von einer aktiven Gegenstelle kommen kann)

Auch einfach:
Beide senden regelmässig Lebenszeichen.

Ich hab einen Master und viele Slaves. Die Kommunikation selbst läuft dann nicht über die RX/TX selber, sondern über MAX 487-IC's.

LG

Fipsi

Ich hab einen Master und viele Slaves. Die Kommunikation selbst läuft dann nicht über die RX/TX selber, sondern über MAX 487-IC's.

Na dann ist ja alles klar :wink: Das geht eh nur halbduplex: Der Master sendet was und evtl. antwortet danach der adressierte Slave.
Ein Slave hat die wichtige Aufgabe, nichts zu sagen, wenn er nicht gefragt wurde.

Und was hast du jetzt mit dem PC - IC Test vorgehabt ?
Ist der PC ein Slave oder der Master ?

michael_x:
Und was hast du jetzt mit dem PC - IC Test vorgehabt ?
Ist der PC ein Slave oder der Master ?

Ich wollte schauen, ob ich's auf die Reihe krieg :smiley:

Und später wird er als Server fungieren, werde aber auch die vorgehensweise dann ändern (Ethernet oder Prozessing).

LG

Fipsi

So, das Problem ist doch noch nicht ganz erledigt.

Ich hab jetzt folgenden Code ausprobiert:

int inByte = 0;
int blink = 0;
int ledState = LOW;
long previousMillis = 0;
long interval = 50;

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

pinMode(9, OUTPUT);

pinMode(8, INPUT);
delay(10000);
}

void loop()
{
if (digitalRead(8) == HIGH))
{
Serial.print("Taste gedrückt!");
}

if (Serial.available())
{
inByte = Serial.read();

if (inByte == 1)
{
Serial.print("Hallo ");
Serial.println("Arduino-Nachbau");

digitalWrite(9, HIGH);
delay(500);
digitalWrite(9, LOW);
delay(500);
}
}
}

An Pin 8 befindet sich ein Taster.
Das seltsame an der ganzen Sache ist jetzt, auch wenn ich den taster nicht mehr drücke, bekomm ich etwa 2 bis 3 Sekunden noch Serial-nachrichten an den PC geschickt.
Und um den ganzen jetzt noch was aufzusetzen:
Wenn ich den Taster NUR am IC anstecke - also nicht an der Spannungsquelle, selbst dann werden Daten geschickt.

Was läuft denn da schief?

LG

Fipsi

Die serielle Übertragung dauert bei 9600 Baud ca. 1 ms pro Zeichen! Das heißt die Übertragung dauert viel länger als der Durchlauf von loop(). Du schreibst da schon wieder Zeug in den Sendepuffer obwohl die erste Nachricht noch gar nicht übertragen wurde.

Setze mal die Baudrate auf das Maximum. Und selbst dann ist das noch relativ langsam im Vergleich zur Prozessor-Geschwindigkeit.

Okay, gerade mal den Teil ein wenig verändert:

 if ((digitalRead(8) == HIGH) && (digitalRead(8) != LOW))
  {
    delay(200);
    if (digitalRead(8) == HIGH)
    {
      Serial.print("Taste gedrückt!");
      delay(500);
    }
  }

Aber das einzige, was sich dann am verhalten ändert, ist, dass die nicht mehr so schnell gesendet werden (was am delay(500) liegen sollte).
Die anderen Probleme sind noch vorhanden.

LG

Fipsi

(digitalRead(8 ) == HIGH) && (digitalRead(8) != LOW)
das filtert nur die ganz schnellen Preller ( < 1 µs für digitalRead( 8 ) ) und ist sonst Quatsch.

Während du die Taste gedrückt hast, kommt alle 0.7 sec ein Text wegen der 2 delays von 200 + 500 ms

Wenn nicht, vermutlich auch, weil der Taster in der Luft hängt ? --> PullDown oder PullUp

Fipsi:
So, das Problem ist doch noch nicht ganz erledigt.
...
An Pin 8 befindet sich ein Taster.
Das seltsame an der ganzen Sache ist jetzt, auch wenn ich den taster nicht mehr drücke, bekomm ich etwa 2 bis 3 Sekunden noch Serial-nachrichten an den PC geschickt.
Und um den ganzen jetzt noch was aufzusetzen:
Wenn ich den Taster NUR am IC anstecke - also nicht an der Spannungsquelle, selbst dann werden Daten geschickt.

Was läuft denn da schief?

Du hat keinen Pullup oder Pulldown Widerstand an den Eingang gehängt und auch den internen Pullup Widerstand nicht aktiviert.
Der eingang fängt Stöhrungen ein die er als gedrückten Taster interpretiert.
Grüße Uwe

Sorry, aber jetzt muss mir nochmal jemand das Phänomen eines PullDown/-Up-Widerstands erklärn.
Was für Widerstände muss ich da nehmen?

LG

Fipsi

Fipsi:
Sorry, aber jetzt muss mir nochmal jemand das Phänomen eines PullDown/-Up-Widerstands erklärn.
Was für Widerstände muss ich da nehmen?

LG

Fipsi

Du brauchst nicht zwingend Widerstände zusätzlich verwenden
http://arduino.cc/en/Tutorial/DigitalPins#.UyHv-_l5P54
Zwischen Ground und Pin einfach den Schalter und den Code wie folgend in die setup-Funktion

pinMode(pin, INPUT);           // set pin to input
digitalWrite(pin, HIGH);       // turn on pullup resistors

Des weiteren wäre Entprellen hilfreich. Achtung, du fragst den Pin dann nicht mehr nach HIGH, sonder LOW ab. Invertierte Logik.

sschultewolter:

pinMode(pin, INPUT);           // set pin to input

digitalWrite(pin, HIGH);      // turn on pullup resistors




Des weiteren wäre Entprellen hilfreich. Achtung, du fragst den Pin dann nicht mehr nach HIGH, sonder LOW ab. Invertierte Logik.

Und jetzt bitte einmal für die blöden. Invertierte Logik?

LG

Fipsi

if (digitalRead(pin) == HIGH) { /* ... */ } // Schalter ungedrückt
if (digitalRead(pin) == LOW) { /* ... */ } // Schalter gedrückt!