Go Down

Topic: eigenes PCB - Serial funktioniert nicht (Read 350 times) previous topic - next topic

audacity363

Hallo zusammen,

ich würde gerne meinen PFSense Router mit einem LCD Display versehen. Ein Prototyp war auch realtiv schnell zusammen gelötet und funktioniert auch wunderbar. Dies habe ich als Anregung gesehen mich mal an einer eigenen Leiterplatine zu versuchen. Den Schaltplan habe ich mal als Bild angehangen.

An sich funktioniert auch alles, nur bei der Seriellen Kommunikation scheine ich etwas falsch gemacht zu haben:

Sobald ich Serial.print aufrufe hängt sich der ATMega auf. An fehlendem Memory kann es nicht liegen, da es auch schon mit folgendem nicht funktioniert:

Code: [Select]
bool pinstate = true;

void setup() {
    pinMode(7, OUTPUT);
    Serial.begin(9600);
    digitalWrite(7, HIGH);
}

void loop() {
    Serial.print("Hello World");
    pinstate = !pinstate;
    digitalWrite(7, pinstate);
    delay(1000);
}


Jetzt wird es interessant:
Um meine Platine auszuschließen habe ich den Atmega328p einfach mal in einen Arduino Uno gesetzt und den LED Pin auf 13 geändert. Und siehe da auch dort stürtzt der Chip beim ersten Serial.print ab.

Also würde ich sagen, dass es an meiner Schaltung liegt?! Um sicher zu gehen das dies wirklich der Fall ist, habe ich noch folgendes versucht:
Den obrigen Sketch auf einen neuen ATMega (mit Arduino Bootloader) gespielt und es ausprobiert. Natürlich funktioniert alles. Wenn ich jetzt den selben Chip in meine Platine stecke bleibt er wieder hängen (Wie erwartet). Nun stecke ich den Atmega wieder zurück in den UNO und siehe da: Er bleibt auch hängen....


Ich habe leider keine Ahnung wo ich da anfangen könnte zu suchen. Hat jemand eine Idee woran es liegen könnte?

uxomm

#1
Jun 21, 2018, 08:13 pm Last Edit: Jun 21, 2018, 08:14 pm by uxomm
Laut Schaltplan gibt es keine Entkoppel-Kondensatoren (100nF) zwischen Vcc und GND.
Das kann zu schwer "ergründbarem Fehlverhalten" führen. Vielleicht bist du gerade auf ein solches gestoßen. :)

Und AREF würde ich nicht an Vcc hängen.
Sie dir doch den Schaltplan eines UNO oder eines MINI an.
Always decouple electronic circuitry.

HotSystems

#2
Jun 21, 2018, 08:18 pm Last Edit: Jun 21, 2018, 08:19 pm by HotSystems
Du hast keine Abblockkondensatoren (100nF) an den VCC-Anschlüssen des Atmega328.
Die musst du noch einsetzen.
Allerdings ist das wohl nicht die Ursache deines Problems.
Das kann ich aktuell noch nicht erkennen.
Aber warum hast du VCC und ARef miteinander verbunden ?

Edit:
uxomm war schneller.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

audacity363

Laut Schaltplan gibt es keine Entkoppel-Kondensatoren (100nF) zwischen Vcc und GND.
Diese gibt es auch in der "Realität" nicht :)
Dann werde ich mal mal einen hinzufügen.

Laut Schaltplan gibt es keine Entkoppel-Kondensatoren (100nF) zwischen Vcc und GND.
Und AREF würde ich nicht an Vcc hängen.
Sie dir doch den Schaltplan eines UNO oder eines MINI an.
An dem habe ich mich auch tatsächlich auch orientiert, allerdings nur am Reset Breich.....
Dann werde ich mal die Leiterbahn durchschneiden und noch einen 100nf Kondensator zwischen Aref und GND löten.

Aber warum hast du VCC und ARef miteinander verbunden ?
Das ist im nachhinein tatächlich eine sehr gute Frage...

Danke euch beiden für die Vorschläge. Werde mich dann morgen noch einmal melden, ob es geklappt hat.

HotSystems

#4
Jun 21, 2018, 08:31 pm Last Edit: Jun 21, 2018, 08:34 pm by HotSystems
Diese gibt es auch in der "Realität" nicht :)
Dann werde ich mal mal einen hinzufügen.

An dem habe ich mich auch tatsächlich auch orientiert, allerdings nur am Reset Breich.....
Dann werde ich mal die Leiterbahn durchschneiden und noch einen 100nf Kondensator zwischen Aref und GND löten.

Das ist im nachhinein tatächlich eine sehr gute Frage...

Danke euch beiden für die Vorschläge. Werde mich dann morgen noch einmal melden, ob es geklappt hat.
Du musst an jeden VCC-Anschluss einen 100 nF Keramikkondensator anschließen. Lieber mehr als zu wenig.
Und in der Realität bzw. Original ist der oder die immer vorhanden.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

audacity363

Und in der Realität bzw. Original ist der oder die immer vorhanden.

Ich meine mit Realität mein Board :)

Also ich habe mich gerade noch einmal ran gesetzt. Die Serielle Kommunikation funktioniert nun. Der fehler war ganz einfach: Tx und Rx war verdreht.... Ich hatte nicht auf das FTDI Breakout Modul geachtet und das die beiden dort bereits gedreht sind.
Dies ist zwar keine Bergündng, warum der AtMega abstürtzt, aber ein Anfang.

Ich habe den Schaltplan jetzt dahin geändert, dass ich an jedem Spannungsversorgungspunkt und an VCC und AVCC einen Kondensator mit 100nf hinzugefügt habe. Den aktuellen Schaltplan habe ich wieder als Bild angehangen. Was haltet ihr davon?

Wenn ich mein Board Layout den Änderungen des Schaltplans anpasse auf was muss ich da bei den Kondensatoren achten?
Soweit ich es gelesen habe, sollten diese nah an an den jeweiligen GND bzw. VCC Pins sein.

HotSystems

Ich meine mit Realität mein Board :)
OK, hatte ich anders verstanden.

Quote
Also ich habe mich gerade noch einmal ran gesetzt. Die Serielle Kommunikation funktioniert nun. Der fehler war ganz einfach: Tx und Rx war verdreht.... Ich hatte nicht auf das FTDI Breakout Modul geachtet und das die beiden dort bereits gedreht sind.
Dann wundert mich, dass du über FTDI flashen konntest.

Quote
Ich habe den Schaltplan jetzt dahin geändert, dass ich an jedem Spannungsversorgungspunkt und an VCC und AVCC einen Kondensator mit 100nf hinzugefügt habe. Den aktuellen Schaltplan habe ich wieder als Bild angehangen. Was haltet ihr davon?

Wenn ich mein Board Layout den Änderungen des Schaltplans anpasse auf was muss ich da bei den Kondensatoren achten?
Soweit ich es gelesen habe, sollten diese nah an an den jeweiligen GND bzw. VCC Pins sein.
Schaltplan ist jetzt ok.

Ja, die 100nF jeweils so dicht wie möglich am Pin anbringen.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

Whandall

IDer fehler war ganz einfach: Tx und Rx war verdreht.... Ich hatte nicht auf das FTDI Breakout Modul geachtet und das die beiden dort bereits gedreht sind.
Dies ist zwar keine Bergündng, warum der AtMega abstürtzt, aber ein Anfang.
Was du als Abstürzen bezeichnest, ist dein blockierender Serial.print() Aufruf gegen einen vollen Puffer,
der mangels Verbindung niemals geleert wird.

Warum sich der UNO nach Transplantation ähnlich verhält, hat wahrscheinlich einen anderen Grund.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

MicroBahner

Was du als Abstürzen bezeichnest, ist dein blockierender Serial.print() Aufruf gegen einen vollen Puffer,
der mangels Verbindung niemals geleert wird.
Mangels HW Handshake dürfte dem Serial ziemlich egal sein, ob eine Verbindung besteht, der sendet im Zweifelsfall einfach in die Wüste.
Was mir aber aufgefallen ist: sollte der RESET nicht mit dem DTR vom FTDI verbunden sein ( und nicht mit dem CTS )?
Gruß, Franz-Peter

audacity363

#9
Jun 22, 2018, 11:15 am Last Edit: Jun 22, 2018, 11:22 am by audacity363
Dann wundert mich, dass du über FTDI flashen konntest.
Habe bei meinen Tests für das Ansprechen des LCDs immer über einen ISP Programmer geuploaded.

Was du als Abstürzen bezeichnest, ist dein blockierender Serial.print() Aufruf gegen einen vollen Puffer,
der mangels Verbindung niemals geleert wird.
Ich hätte erwartet, dass er dann entweder -1 zurück gibt, oder den Anfang des Buffers überschreibt. Ein Blick in "HardwareSerial.cpp" zeigt tatsächlich sogar beides:

Code: [Select]

size_t HardwareSerial::write(uint8_t c)
{
  int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
 
  // If the output buffer is full, there's nothing for it other than to
  // wait for the interrupt handler to empty it a bit
  // ???: return 0 here instead?
  while (i == _tx_buffer->tail)
    ;
 
  _tx_buffer->buffer[_tx_buffer->head] = c;
  _tx_buffer->head = i;
 
  sbi(*_ucsrb, _udrie);
  // clear the TXC bit -- "can be cleared by writing a one to its bit location"
  transmitting = true;
  sbi(*_ucsra, TXC0);
 
  return 1;
}



Allerdings verstehe ich nicht wie bei meinem Bespiel Sketch der Buffer voll laufen kann. Ich sende 11 Bytes und der Buffer hat mindestends 16 Bytes, dem SourceCode zu folge. Auch sollte der Interrupt handler den Buffer "asyncron" leeren. Da der AtMega aber bereits beim ersten loop() durchlauf stehen bleibt kann der Buffer ja noch nicht voll sein.
Auch müsste er ja mit 9600Baud senden was 960 Bytes/Sec sind. Wenn ich mich nicht verrecht habe, müsste der Buffer also vier mal pro Sekunde geleert werden (wenn etwas im Buffer steht). Da ich aber vor dem nächsten senden eine Sekunde warte, sollte er bis dahhin bereits wieder leer sein.

Übersehe ich da etwas bzw. bin ich jetzt zu sehr in meiner Programmier Logik gefangen?

Edit:
Was mir aber aufgefallen ist: sollte der RESET nicht mit dem DTR vom FTDI verbunden sein ( und nicht mit dem CTS )?
Jop nach kurzem Googlen gebe ich dir Recht.

Whandall

Ich hätte erwartet, dass er dann entweder -1 zurück gibt, oder den Anfang des Buffers überschreibt. Ein Blick in "HardwareSerial.cpp" zeigt tatsächlich sogar beides:
Nö, meiner Ansicht nach zeigt er keins von beidem.
Er zeigt dass der Przessor dann blockiert bleibt (ausser für Interrupts).

Normalerweise würde der Buffer mit der Baudrate im Hintergrund geleert werden,
ich weiss aber nicht ob das auch funktioniert wenn man am TX Ausgang einen anderen Ausgang anschließt.

Wenn das Problem mit den korrigierten Pins verschwindet, besteht ja auch kein wirklicher Erklärungsbedarf.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Whandall

Was mir aber aufgefallen ist: sollte der RESET nicht mit dem DTR vom FTDI verbunden sein ( und nicht mit dem CTS )?
Er sollte.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Go Up