mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega328, Probleme mit Interrupt und Bluetooth


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.
Autor: Alexander Z. (alex_z)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin neu hier im Forum.
Ich möchte meinen Atmega328P programmieren: Pin change Interrupt auf Pin 
14(PB0) und ich möchte mein Adafruit Bluefruit Bluetooth Low Energy 
(https://www.adafruit.com/product/2479) benutzen.
Ich habe mal ein Teil programmiert und erhalte folgende Fehlermeldung:

(.text+0x0): multiple definition of `__vector_3'

C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_857522\sketch\Atmega3 
28_Interrupt.ino.cpp.o  (symbol from plugin):(.text+0x0): first defined 
here

collect2.exe: error: ld returned 1 exit status
exit status 1
Fehler beim Kompilieren für das Board Arduino/Genuino Uno.

Ich finde aber den Fehler nicht.
Im Anhang ist das Programm.

Kann mir jemand helfen?

Vielen Dank

Alex

Autor: Hmmm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Belegt evtl. die SoftwareSerial den PCINT0?

Autor: Alexander Z. (alex_z)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Ja genau das ist auch meine Frage.
Aber wenn ich andere Interruptpins nehmen tritt der selbe Fehler auf

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist nicht die ganze Logmeldung, oder?

Zwei Quelltext-Dateien definieren einen Interrupt-Handler für PCIN0. 
Welche beiden das sind, sollte aus der Ausgabe des Compilers hervor 
gehen. Vielleicht ist es nötig, die Einstellungen der IDE zu ändern, so 
dass alle Ausgaben angezeigt werden.

Autor: Alexander Z. (alex_z)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also das ist der letzte Teil des Logs. Der Rest davor ist nur Zeug wie: 
C:\Program Files (x86)\Arduino....




Linking everything together...
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-gcc" -w -Os 
-g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p  -o 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632/Atmega328_Int 
errupt.ino.elf" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\sketch\Atmega 
328_Interrupt.ino.cpp.o" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\libraries\SPI 
\SPI.cpp.o" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\libraries\Ada 
fruit_BluefruitLE_nRF51_master\Adafruit_ATParser.cpp.o" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\libraries\Ada 
fruit_BluefruitLE_nRF51_master\Adafruit_BLE.cpp.o" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\libraries\Ada 
fruit_BluefruitLE_nRF51_master\Adafruit_BLEBattery.cpp.o" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\libraries\Ada 
fruit_BluefruitLE_nRF51_master\Adafruit_BLEEddystone.cpp.o" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\libraries\Ada 
fruit_BluefruitLE_nRF51_master\Adafruit_BLEGatt.cpp.o" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\libraries\Ada 
fruit_BluefruitLE_nRF51_master\Adafruit_BLEMIDI.cpp.o" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\libraries\Ada 
fruit_BluefruitLE_nRF51_master\Adafruit_BluefruitLE_SPI.cpp.o" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\libraries\Ada 
fruit_BluefruitLE_nRF51_master\Adafruit_BluefruitLE_UART.cpp.o" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\libraries\Ada 
fruit_BluefruitLE_nRF51_master\utility\Adafruit_FIFO.cpp.o" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\libraries\Sof 
twareSerial\SoftwareSerial.cpp.o" 
"C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632/core\core.a" 
"-LC:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632" -lm
C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\libraries\Soft 
wareSerial\SoftwareSerial.cpp.o  (symbol from plugin): In function 
`SoftwareSerial::read()':

(.text+0x0): multiple definition of `__vector_3'

C:\Users\ALEXAN~1\AppData\Local\Temp\arduino_build_590632\sketch\Atmega3 
28_Interrupt.ino.cpp.o  (symbol from plugin):(.text+0x0): first defined 
here

collect2.exe: error: ld returned 1 exit status

Bibliothek SPI in Version 1.0 im Ordner: C:\Program Files 
(x86)\Arduino\hardware\arduino\avr\libraries\SPI  wird verwendet
Bibliothek Adafruit_BluefruitLE_nRF51_master in Version 1.9.5 im Ordner: 
C:\Users\Alexander\Documents\Arduino\libraries\Adafruit_BluefruitLE_nRF5 
1_master   wird verwendet
Bibliothek SoftwareSerial in Version 1.0 im Ordner: C:\Program Files 
(x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial  wird 
verwendet
exit status 1
Fehler beim Kompilieren für das Board Arduino/Genuino Uno.

Autor: c-hater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Z. schrieb:

> Ja genau das ist auch meine Frage.
> Aber wenn ich andere Interruptpins nehmen tritt der selbe Fehler auf

Du mußt dann einen nehmen, der auf einem anderen Port liegt!

Hintergrund: Es gibt für jeden (Byte-) Port nur einen PCINT-Interrupt, 
der kann zwar theoretisch von jedem Pin dieses Ports ausgelöst werden, 
aber praktisch ist es so, dass der PCINTx "weitgehend" unbrauchbar wird, 
sobald mehr als ein Pin ihn auslösen kann.

Die bekloppten Code-Module, die du verwendest, gehen nun (wohl zu Recht) 
davon aus, dass ein Arduidiot sowieso nicht in der Lage wäre, die Luft 
zwischen "weitgehend" und "vollständig" sinnvoll zu nutzen und 
aquirieren einfach für ihren einen Scheiß-Pin den kompletten Interrupt 
für (bis zu) acht Pins.

Damit wirst du schlicht leben müssen, wenn du weiter bei Arduino 
bleibst...

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daran kannst du deutlich den Konflikt zwischen zwei Dateien erkennen:

SoftwareSerial.cpp
Atmega328_Interrupt.ino

Du musst einen anderen Interrupt verwenden, der frei ist.

Autor: Alexander Z. (alex_z)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Stefanus,

aber welcher ist denn frei?
Wenn ich zum Beispiel statt PCINT0 den PCINT8 nehme, der auch schon im 
Register anders definiert wird, kommt die gleiche Meldung


@ c-hater:
Ich benutze nur die Arduino IDE und möchte einfach einen Atmega328 
programmieren

Autor: c-hater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Z. schrieb:

> @ c-hater:
> Ich benutze nur die Arduino IDE und möchte einfach einen Atmega328
> programmieren

Dann tue doch einfach, was ich dir vorgeschlagen habe...

Tsss...

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> aber welcher ist denn frei?

Frag nicht mich, schau in die Quelltexte der Arduino Libraries.

> Ich benutze nur die Arduino IDE und möchte einfach einen
> Atmega328 programmieren

Im Arduino System ist es aber nicht vorgesehen, dass du Interrupts (oder 
andere ähnlich Hardwarenahme Sachen) programmierst. Du sollst nur die 
vorgefertigten Funktionen des Frsmeworks benutzen. Wenn Dir das nicht 
genügt, solltest du dich besser vom Arduino Framework trennen.

Autor: Alexander Z. (alex_z)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@c-hater

Aber welcher Interruptpin liegt denn auf einem anderen Port?

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lies das mal:
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Es geht also wohl doch, aber nicht so, wie du es gemacht hast. Immer 
dran denken: benutze nur die Funktionen des Frameworks. Alles andere 
provoziert Probleme.

: Bearbeitet durch User
Autor: Reiner_Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Z. schrieb:
> Danke Stefanus,
>
> aber welcher ist denn frei?
> Wenn ich zum Beispiel statt PCINT0 den PCINT8 nehme, der auch schon im
> Register anders definiert wird, kommt die gleiche Meldung
>
> @ c-hater:
> Ich benutze nur die Arduino IDE und möchte einfach einen Atmega328
> programmieren

Hier hilft es sich ein bisschen von der simplen Arduino Umgebung zu 
lösen und mal einen Blick ins Datenblatt zu werfen: 
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf

Im speziellen die Kapitel zu den Interrupts.

Zwei Anmerkungen zu IRQ Routinen:
1.) So kurz wie möglich
2.) Mögliche Endlos-Schleifen vermeiden.

Schaue ich mir das bisschen ISR Code aus deinem Sketch an, dann sind 
beide Bedingungen bei weitem nicht erfüllt:
- delay(50000) => Echt jetzt??? Ohne Worte!
- while(input == 1){ ... } => Auch Mist.

Was du in deiner ISR machst ist nicht zeitkritisch und kann auch bequem 
in der loop() Funktion untergebracht werden. Dann würde sich dein 
Problem einfach in wohl gefallen auflösen...

Autor: Alexander Z. (alex_z)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als das delay(50000); sind in der Realität 500ms
mit attachInterrupt passiert garnichts mehr. Es kommen zwar keine 
Fehler, aber auf dem Steckbrett passiert nix.

Das Datenblatt liegt schon lange vor mir, aber ich werde daraus nicht 
schlauer.

Habe noch das hier gefunden:

https://playground.arduino.cc/Main/PinChangeInterrupt

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> So kurz wie möglich
> Mögliche Endlos-Schleifen vermeiden.

Dieser weise Tip steht übrigens auch in der Arduino Dokumentation.

Autor: Alexander Z. (alex_z)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das weis ich ja, aber es ist nunmal auch die einzige Lösung, um viel 
Strom zu sparen. Letzten Endes soll in der ISR eine Berechnung zu einem 
Sensorwert durchgeführt werden, aber eben nur wenn sich der Wert 
ändert(pinChange), sonst soll der Atmega schlafen

Autor: Reiner_Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Z. schrieb:
> Als das delay(50000); sind in der Realität 500ms
> mit attachInterrupt passiert garnichts mehr. Es kommen zwar keine
> Fehler, aber auf dem Steckbrett passiert nix.

Ein delay hat nichts in einer ISR verloren... Nie... Egal wie lange...

Wenn du schon in die Doku schaust wegen dem attachInterrupt, dann bitte 
auch an der richtigen Stelle: 
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Kleiner Hinweis: Schau mal nach, mit welchen Pins das funktioniert...

Vergiss das ganze mit der ISR wieder und versuche das in die loop/() 
Funktion einzubauen...

Autor: c-hater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Z. schrieb:
> @c-hater
>
> Aber welcher Interruptpin liegt denn auf einem anderen Port?

Woher soll ich das wissen? Das kannst nur du wissen! Denn du hast die 
Pin-Verwendung konfiguriert (und du hast uns nicht wissen lassen, welche 
genau du konfiguriert hast).

Und fang' jetzt nicht an, uns mit Arduino-Pin-Nummern vollzulabern. Die 
alleine helfen bei diesem Problem nicht weiter. Man muss das Mapping auf 
die real vorhandenen Pins kennen.

Also genau den Kram, den dieses Arduino-Machwerk vor dir möglichst 
verbergen will...

Autor: Reiner_Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Z. schrieb:
> Das weis ich ja, aber es ist nunmal auch die einzige Lösung, um viel
> Strom zu sparen. Letzten Endes soll in der ISR eine Berechnung zu einem
> Sensorwert durchgeführt werden, aber eben nur wenn sich der Wert
> ändert(pinChange), sonst soll der Atmega schlafen

Nur so als Hinweis... Wenn der ATMega aufwacht, macht er an der Stelle 
weiter, an der er vorher Schlafen gelegt wurde... Du bräuchtest dann 
eigentlich nur in der loop() Schleife zu prüfen, ob sich der Wert seit 
dem letzten Schlafen legen geändert hat... Eine ISR brauchts dazu nicht

Autor: Alexander Z. (alex_z)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok danke

ich werde mal ein wenig rumprobieren

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Eine ISR brauchts dazu nicht

Ohne ISR würde er beim Interrupt abstürzen. Ich empfehle eine leere ISR.

Wobei das eventuell vom Arduino Framework erledigt wird. So genau kenne 
ich mich mit Arduino nicht aus.

Autor: Reiner_Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
>> Eine ISR brauchts dazu nicht
>
> Ohne ISR würde er beim Interrupt abstürzen. Ich empfehle eine leere ISR.
>
> Wobei das eventuell vom Arduino Framework erledigt wird. So genau kenne
> ich mich mit Arduino nicht aus.

Naja... Wenn der Compiler meldet, dass die ISR schon definiert ist, dann 
nehme ich an, dass die SoftwareSerial lib die schon definiert und daher 
hier kein Absturz stattfinden sollte

Autor: Reiner_Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Z. schrieb:
> ich werde mal ein wenig rumprobieren

Versuche mal folgendes Konstrukt in der loop() Funktion zu definieren:
- Abfrage und speichern des aktuellen Status
- Wenn sich der vom letzten Wert unterscheidet, dann Berechnung 
durchführen
- Aktuellen Wert als letzten Wert abspeichern
- ATMega schlafen legen

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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