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


von Alexander Z. (alex_z)


Angehängte Dateien:

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

von Hmmm (Gast)


Lesenswert?

Belegt evtl. die SoftwareSerial den PCINT0?

von Alexander Z. (alex_z)


Lesenswert?

Hi,

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

von Stefan F. (Gast)


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.

von Alexander Z. (alex_z)


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.

von c-hater (Gast)


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...

von Stefan F. (Gast)


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.

von Alexander Z. (alex_z)


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

von c-hater (Gast)


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...

von Stefan F. (Gast)


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.

von Alexander Z. (alex_z)


Lesenswert?

@c-hater

Aber welcher Interruptpin liegt denn auf einem anderen Port?

von Stefan F. (Gast)


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.

von Reiner_Gast (Gast)


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...

von Alexander Z. (alex_z)


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

von Stefan F. (Gast)


Lesenswert?

> So kurz wie möglich
> Mögliche Endlos-Schleifen vermeiden.

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

von Alexander Z. (alex_z)


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

von Reiner_Gast (Gast)


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...

von c-hater (Gast)


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...

von Reiner_Gast (Gast)


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

von Alexander Z. (alex_z)


Lesenswert?

Ok danke

ich werde mal ein wenig rumprobieren

von Stefan F. (Gast)


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.

von Reiner_Gast (Gast)


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

von Reiner_Gast (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.