mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Arduino Due - Serial AND Interrupt = FREEZE


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Tom (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Guten Tag.
Ich möchte mit dem Arduino Due ein 8-Bit breites Signal über den 
Serial-Port übertragen der über den Serial-Monitor in der Arduino-IDE 
empfangen wird. Dazu benutze ich an einem digitalen Eingang einen 
Interrupt der auf FALLING reagiert. Das ganze funktioniert auch nach ein 
paar übertragenen Bytes super. Dann allerdings kommt keine serielle 
Übertragung mehr zustande. Nach einem Reset des DUEs funktioniert es 
wieder für wenige Bytes. Dann ist wieder Schluss. Wer kann sich das 
erklären?

Lieben Gruß
Tom
const int Data_Bit_7 = 11;
const int Data_Bit_6 = 10;
const int Data_Bit_5 = 9;
const int Data_Bit_4 = 8;
const int Data_Bit_3 = 7;
const int Data_Bit_2 = 6;
const int Data_Bit_1 = 5;
const int Data_Bit_0 = 4;

const int Control_STROBE = 32;

byte data_register = 0;

void setup() {
  // put your setup code here, to run once:
  
  pinMode(Control_STROBE, INPUT_PULLUP);
  
  pinMode(Data_Bit_7, INPUT);
  pinMode(Data_Bit_6, INPUT);
  pinMode(Data_Bit_5, INPUT);
  pinMode(Data_Bit_4, INPUT);
  pinMode(Data_Bit_3, INPUT);
  pinMode(Data_Bit_2, INPUT);
  pinMode(Data_Bit_1, INPUT);
  pinMode(Data_Bit_0, INPUT);

  Serial.begin(19200);

  attachInterrupt(digitalPinToInterrupt(Control_STROBE), strobe_INT, FALLING);  
  
}

void loop() {
  
}

void strobe_INT() {    
    noInterrupts();
    
    incomming_Data();    
    Serial.print(data_register, HEX);
    Serial.print(' ');
    
    interrupts();
}

void incomming_Data() {  
  bitWrite(data_register, 0, digitalRead(Data_Bit_0));
  bitWrite(data_register, 1, digitalRead(Data_Bit_1));
  bitWrite(data_register, 2, digitalRead(Data_Bit_2));
  bitWrite(data_register, 3, digitalRead(Data_Bit_3));
  bitWrite(data_register, 4, digitalRead(Data_Bit_4));
  bitWrite(data_register, 5, digitalRead(Data_Bit_5));
  bitWrite(data_register, 6, digitalRead(Data_Bit_6));
  bitWrite(data_register, 7, digitalRead(Data_Bit_7));
}

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Tom schrieb:
> Serial.print(data_register, HEX);
>     Serial.print(' ');

Soetwas in der Interruptroutine ist nicht dein Ernst, oder?

von Arduino Fanboy D. (ufuf)


Bewertung
-1 lesenswert
nicht lesenswert
noInterrupts() und interrupts() benötigst du nicht, dass sollte der 
Arduino Rahmen für dich erledigen.

Serial wurde schon gesagt.


Und für byte data_register = 0; könnte volatile von Nutzen sein.

von Klaus (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Arduino Fanboy D. schrieb:
> noInterrupts() und interrupts() benötigst du nicht, dass sollte der
> Arduino Rahmen für dich erledigen.

Ab interrupts() bis zum wirklichen Ende des Interrupthandlers ist der 
Interrupt enabled. Da schlägt natürlich sofort der nächste zu, bis der 
Stack alle ist.

MfG Klaus

Beitrag #6059602 wurde von einem Moderator gelöscht.
Beitrag #6059609 wurde von einem Moderator gelöscht.
von Tom (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Vor dem Due hatte ich einen Uno. Der war auf jeden Fall langsam. Schon 
schade dass noInterrupts() hier nicht hilfreich ist.

Lg Tom

von Arduino Fanboy D. (ufuf)


Bewertung
0 lesenswert
nicht lesenswert
Tom schrieb:
> Schon schade dass noInterrupts() hier nicht hilfreich ist.
Ein Toaster und eine Gießkanne sind das in diesem Fall auch nicht.

: Bearbeitet durch User
von leo (Gast)


Bewertung
3 lesenswert
nicht lesenswert
Tom schrieb:
> Vor dem Due hatte ich einen Uno. Der war auf jeden Fall langsam.

Lass dich nicht verarschen re Arduino Speed.

> Schon
> schade dass noInterrupts() hier nicht hilfreich ist.

Interrupts sind sowieso disabled in einer ISR. Das Problem ist, dass 
Serial.print() selber Interrupts verwendet, um den Sendebuffer zu 
leeren. Da diese aber ausbleiben, haengt dein Programm.
S. auch e.g. https://forum.arduino.cc/index.php?topic=131801.0

Setze also in der ISR ein (volatile) Flag, dass was zu tun ist und 
verwende dieses in loop().

Als naechstes kannst du mal ueber den Vorteil von Schleifen nachdenken.

leo

von Tom (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Ach so. Okay.
Werde ich morgen als erstes ausprobieren.
Danke schön.

Lg Tom

von Arduino Fanboy D. (ufuf)


Bewertung
0 lesenswert
nicht lesenswert
leo schrieb:
> Als naechstes kannst du mal ueber den Vorteil von Schleifen nachdenken.

Oder über RingBuffer.

von leo (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Arduino Fanboy D. schrieb:
> Oder über RingBuffer

... der bei fixen 8 Bits genau was bringt?

leo

von Arduino Fanboy D. (ufuf)


Bewertung
-1 lesenswert
nicht lesenswert
leo schrieb:
> der bei fixen 8 Bits genau was bringt?

Och....

Manchmal kommen sie in Strömen, die Bytes....

Bytes rudeln ganz gerne.
Und dann hat ein RingBuffer als Zwischenhändler zwischen ISR und 
Hauptprogramm nicht nur Nachteile.

: Bearbeitet durch User
von leo (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Arduino Fanboy D. schrieb:
> Manchmal kommen sie in Strömen, die Bytes....

Ich denke der TO will zuerst mal ein Byte nach dem anderen ausgeben. Bis 
zu den Stroemen ist noch ein weiter Weg ;-)

leo

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Arduino Fanboy D. schrieb:
> Und dann hat ein RingBuffer als Zwischenhändler zwischen ISR und
> Hauptprogramm nicht nur Nachteile.

Ein Ringpuffer nützt allerdings auch nur, wenn sicher gestellt ist, dass 
die mittlere Datenrate nicht höher ist, als die 
Übertragungsgeschwindigkeit und der Puffer groß genug ist.

von Kaj (Gast)


Bewertung
0 lesenswert
nicht lesenswert
leo schrieb:
> Interrupts sind sowieso disabled in einer ISR.
Nope. Der Due ist ein Cortex-M3 und kein AVR.

von Klaus (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Kaj schrieb:
> Der Due ist ein Cortex-M3

Und auch der disabled mindestens den gleichen Interrupt im Handler. Da 
das Interrupt-Flag in SW zurückgesetzt werden muß, würde er sonst nie 
den ersten C-Befehl des Handlers erreichen. Er käme noch nicht mal dazu, 
ein paar Register zu retten.

MfG Klaus

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.