Forum: Mikrocontroller und Digitale Elektronik Arduino Interrupt Drehzahlmessung Faulhaber Motor


von Maik H. (tyson)


Angehängte Dateien:

Lesenswert?

Guten Abend,

aktuell Versuche mit einem Arduino Uno den Encoder eines Faulhaber 
Motors auszulesen und daraus die Drehzahl zu bestimmt.

Der folgende Motor wird verwendet:  2342S012CR
und der folgende Encoder:           IE3-32

Das Signal wird über den Interrupt-Pin 2 ausgelesen, allerdings 
entspricht die angezeigte Drehzahl nicht der tatsächlichen, diese bewegt 
sich nur in einem kleinen nicht nachvollziehbaren Bereich.

Der Encoder hat drei Ausgangssignale, zwei um 90 Grad verschobene 
Rechtecksignale und einen Indeximpuls.
Bisher kam das Auslesen des Indexumpulses den tatsächlichen Werten am 
nächsten.
Der Wechsel des Interrupt-Modus hat auch keinen Erfolg gebracht.

Da ich noch Neuling bin habe ich mich an der folgenden Anleitung für die 
Messung der Drehzahl orientiert:
https://arduino-projekte.info/drehzahlmesser/

Das ist mein aktuelles Programm:
1
// Variablen
2
int MotorSpeed;          // Geschwindigkeit Motor
3
4
// Variablen Encoder
5
byte DZM_InputPin = 2;
6
volatile unsigned long RPM_T2, RPM_Count;
7
unsigned long RPM , RPM_T1;
8
9
10
// Eingaenge  
11
int Poti = A3;          // Analogwert fuer Drehzahlvorgabe durch Potentiometer 
12
13
// Ausgaenge Motor 
14
int Motor = 9;          // PWM-Signal fuer Motorgeschwindigkeit 
15
int in1 = 8;            // H-Brueckensteuersignal fuer Drehrichtung
16
int in2 = 7;            // H-Brueckensteuersignal fuer Drehrichtung
17
18
19
/********************************************************************************************************************************/
20
void setup() {
21
22
    // Allgemein 
23
    Serial.begin(9600);                               // Die Kommunikation mit dem seriellen Port wird gestartet fuer die Darstellung von Ergebnissen im seriellen Monitor 
24
25
    // Einstellungen Encoder 
26
    pinMode(DZM_InputPin, INPUT_PULLUP);              // Pin Encoder wird als Eingang gesetzt mit Pull-Down-Widerstand auf dem Arduino
27
    RPM_T1 = 0;                                       // Setzen der Zeitvariable T1
28
    RPM_T2 = 0;                                       // Setzen der Zeitvariable T2
29
    RPM_Count = 0;                                    // Setzen des Umdrehungsvariable 
30
    
31
    // Interrupt Einstellungen
32
    attachInterrupt(0, FunktionInterrupt, RISING);    // Encoder1 = Pin fuer Signal, FunktionInterrupt = aufzurufende Funktion bei Interrupt, RISING = Detektion der positiven Flanke
33
    
34
  
35
    // Einstellungen Motor
36
    pinMode(Motor, OUTPUT);                           // Pin Motor wird als Ausgang gesetzt
37
    pinMode(in1, OUTPUT);                             // Pin in1 wird als Ausgang gesetzt
38
    pinMode(in2, OUTPUT);                             // Pin in2 wird als Ausgang gesetzt
39
40
}
41
42
/**************************************************************************************************************************/
43
void loop() {
44
       
45
  // Motor ansteuern und Poti auslesen
46
  digitalWrite(in1, LOW);                           // Drehrichtung Motor festlegen (H-Bruecke)
47
  digitalWrite(in2, HIGH);                          // Drehrichtung Motor festlegen (H-Bruecke)
48
  MotorSpeed = analogRead(Poti);                    // Position des Potentiometers auslesen
49
  MotorSpeed = map(MotorSpeed, 0, 1023, 0, 255);    // 10 bit Potentiometerwert in 8 bit Wert umrechenen (Eingang = 10bit, Ausgang = 8bit)
50
  
51
  if (MotorSpeed < 8) MotorSpeed = 0;               // Abfangen von Summen des Motors bei zu geringen Drehzahlen 
52
  analogWrite(Motor, MotorSpeed);                   // PWM-Signal für Motorgeschwindigkeit ausgeben 
53
54
  // Encoder Drehzahlausgabe 
55
  if (RPM_T2 > RPM_T1) {
56
    RPM = (unsigned)(long)(60000 * RPM_Count / (RPM_T2 - RPM_T1));
57
    RPM_T1 = RPM_T2;
58
    RPM_Count = 0;
59
    }
60
  else {                                            // Abfangen von Drehzahl = 0 
61
      RPM = 0;
62
    }
63
  // Ausgabe der Drehzahl
64
  Serial.println(RPM);
65
}
66
67
// Funktion Interrupt 
68
void FunktionInterrupt() {
69
  
70
  RPM_Count++;                // Impuls wird um eins erhoeht
71
  RPM_T2 = millis();          // Zeit seit Start des Arduinos fuer Berechnung der Drehzahl
72
  
73
}

Vielleicht kann mir jemand weiterhelfen, sehe aktuell nicht den Fehler 
in dieser Umsetzung.
Vielen Dank

von Guest (Gast)


Lesenswert?

Wie schnell dreht denn dein Motor? Eventuell kommt dein Programm nicht 
nach. So einen Encoder wertet man idr. eher mit einem Timer aus.

von Maik H. (tyson)


Lesenswert?

Der Motor kann bis zu 6000 1/min drehen, wird allerdings im späteren 
Betrieb nicht schneller als 3000 1/min drehen.
Zu der Auswertung mit Timern hatte ich bisher noch nichts gelesen, die 
Interrupt-Variante erschien mir bisher schlüssig.

von Guest (Gast)


Lesenswert?

Die Frage ist halt ob deine Zeitmessung genau genug ist. Ich kenne mich 
beim Atmel nicht so mit den Interrupts und der Priorisierung aus aber 
ich meine millis gibt den Wert einer Variable zurück die ebenfalls in 
einem Interrupt hochgezählt wird (Bin mir nicht absolut sicher). Je nach 
Gitter von deinem Pin und Millis Interrupt kann es sein das die Messung 
zu ungenau ist. Für die Drehzahl zu messen sollte der Indeximpuls 
ausreichend sein über die verschobenen Rechtecke kannst du zusätzlich 
noch Richtung und Rotor Winkel bestimmen. Ich würde das Ganze mit einem 
Timer machen. Such mal nach Timer Input Capture.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Wie ist denn das in der Arduino IDE mit 'volatile'? Sonst sollte man 
Variablen, die in der ISR bearbeitet werden, so deklarieren.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

volatile nutzt er schon, haut hin. Nur liest er diese Werte in der loop 
ohne atomaren Zugriffsschutz aus und hat deswegen Datenverstümmelung.
Serial.print würde ich auch nur aller 1s machen.

von Maik H. (tyson)


Lesenswert?

Wie kann ich den "atomaren Zugriffsschutz" einbringen, mit der Funktion 
"noInterrupts()"?

Serial.print ist aktuelle nur ein Platzhalter für ein LCD Display, werde 
die Zeit auf eine Sekunde erhöhen.

von m.n. (Gast)


Lesenswert?

Maik H. schrieb:
> RPM_T2 = millis();

Die Zeitmessung erscheint mir doch ein wenig zu grob, und warum die Zeit 
im Interrupt gelesen wird, leuchtet mir nicht ein.

Der Encoder liefert bei 6000 UPM eine Ausgangsfrequenz von 3,2 kHz. 
Wieviele Werte werden den pro Sekunde benötigt? Die einfachste Messung 
(mit fester Torzeit) würde eine Sekunde warten und dann das Ergebnis aus 
RPM_Count ermitteln.
Aber bei potentiell auch niedrigen Drehzahlen wäre eine reziproke 
Messung doch wesentlich sinnvoller. Das läuft dann über Timer1 mit dem 
T1-Capture-Eingang, wodurch sich eine hohe Auflösung bei hoher Messrate 
ergibt.

Nur fürchte ich, daß man sich das nicht aus Arduino-LIBs zusammenklicken 
kann ;-)

von Veit D. (devil-elec)


Lesenswert?

Maik H. schrieb:
> Wie kann ich den "atomaren Zugriffsschutz" einbringen, mit der Funktion
> "noInterrupts()"?

Nein. atomic block RESTORE
https://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html

Und das mit der Zeitmessung überlegste dir auch nochmal. Wurde schon 
angesprochen. millis wäre auch zu ungenau, müßtest schon micros 
verwenden. Aber wie schon gesagt wurde ist diese Vorgehensweise nicht 
optimal, weil du nur von Puls zu Puls misst.

: Bearbeitet durch User
von Maik H. (tyson)


Lesenswert?

Die Umsetzung mit dem "T1-Capture-Eingang" ist mir nicht klar geworden, 
gibt es eventuell ein nachvollziehbares Beispiel?

Aktuell habe ich den Code nochmal verändert, dabei nutze ich micros und 
zähle eine Sekunde lang die Impulse, die dann der Drehzahlbestimmung 
dienen.
Dabei dient der Kanal A des Encoders als Signal, da der Indeximpuls 
keine vernünftigen Werte liefert .

Aktuell erhalte ich hiermit Werte im Bereich von  60 bis 4440 RPM.
Bei der Ansteuerung mit dem Potentiometer fällt auf, dass im oberen 
Stellbereich eine geringere Drehzahländerung vorhanden ist.
Sind das die folgende des nicht genutzten "T1 Caputere Eingangs"?
1
// Variablen
2
int MotorSpeed;          // Geschwindigkeit Motor
3
4
// Variablen Encoder
5
// Motorpulse pro Umdrehung 
6
#define ENC_COUNT_REV 1
7
// Encoder Input 
8
#define ENC_IN 2
9
// Pulse vom Encoder
10
volatile long encoderValue = 0;
11
// Intervall 1 Sekunde
12
int interval = 1000000;
13
// Zähler für Microsekunden 
14
long previousMicros = 0;
15
long currentMicros = 0;
16
// Umdrehungen pro Minute
17
int rpm = 0;
18
19
// Eingaenge  
20
int Poti = A3;          // Analogwert fuer Drehzahlvorgabe durch Potentiometer 
21
22
// Ausgaenge Motor 
23
int Motor = 9;          // PWM-Signal fuer Motorgeschwindigkeit 
24
int in1 = 8;            // H-Brueckensteuersignal fuer Drehrichtung
25
int in2 = 7;            // H-Brueckensteuersignal fuer Drehrichtung
26
27
28
/********************************************************************************************************************************/
29
void setup() {
30
31
    // Allgemein 
32
    Serial.begin(9600);                               // Die Kommunikation mit dem seriellen Port wird gestartet fuer die Darstellung von Ergebnissen im seriellen Monitor 
33
34
    // Einstellungen Encoder 
35
    // Encoder Pin als Input mit Pullup  
36
    pinMode(ENC_IN, INPUT_PULLUP); 
37
    // Interrupt  
38
    attachInterrupt(digitalPinToInterrupt(ENC_IN), updateEncoder, RISING);
39
    // Start Timer 
40
    previousMicros = micros();
41
    
42
    // Einstellungen Motor
43
    pinMode(Motor, OUTPUT);                           // Pin Motor wird als Ausgang gesetzt
44
    pinMode(in1, OUTPUT);                             // Pin in1 wird als Ausgang gesetzt
45
    pinMode(in2, OUTPUT);                             // Pin in2 wird als Ausgang gesetzt
46
47
}
48
49
/**************************************************************************************************************************/
50
void loop() {
51
       
52
  // Motor ansteuern und Poti auslesen
53
  digitalWrite(in1, LOW);                           // Drehrichtung Motor festlegen (H-Bruecke)
54
  digitalWrite(in2, HIGH);                          // Drehrichtung Motor festlegen (H-Bruecke)
55
  MotorSpeed = analogRead(Poti);                    // Position des Potentiometers auslesen
56
  MotorSpeed = map(MotorSpeed, 0, 1023, 0, 255);    // 10 bit Potentiometerwert in 8 bit Wert umrechenen (Eingang = 10bit, Ausgang = 8bit)
57
  
58
  if (MotorSpeed < 8) MotorSpeed = 0;               // Abfangen von Summen des Motors bei zu geringen Drehzahlen 
59
  analogWrite(Motor, MotorSpeed);                   // PWM-Signal für Motorgeschwindigkeit ausgeben 
60
61
  // Umdrehungen jede Sekunde aktualisieren
62
  currentMicros = micros();
63
   if (currentMicros - previousMicros > interval) {
64
     previousMicros = currentMicros;
65
 
66
     // Berechnung Drehzahl
67
     rpm = (float)(encoderValue * 60 / ENC_COUNT_REV);
68
 
69
     // Displayausgabe wenn Wert gelesen
70
     if (rpm > 0) {
71
       Serial.print(rpm);
72
       Serial.println(" RPM");
73
    }
74
    encoderValue = 0;
75
   }
76
}
77
void updateEncoder()
78
{
79
  // Increment value for each pulse from encoder
80
  encoderValue++;
81
}

von Veit D. (devil-elec)


Lesenswert?

Hallo,

a) noch ohne atomic

b) Zeile 12
warning: overflow in conversion from 'long int' to 'int' changes value 
from '1000000' to '16960' [-Woverflow]
   12 | int interval = 1000000;

zusätzlich unsigned, damit der Vergleich später hinhaut, also unsigned 
long

c) previousMicros und currentMicros müssen unsigned long sein

von Veit D. (devil-elec)


Lesenswert?

Hallo,

wenn ich nichts übersehen habe, versuche mal dein Glück.
1
#include <util/atomic.h> 
2
3
// Variablen
4
unsigned int MotorSpeed;          // Geschwindigkeit Motor
5
6
// Variablen Encoder
7
// Motorpulse pro Umdrehung
8
const byte ENC_COUNT_REV = 1;
9
// Pulse vom Encoder
10
volatile unsigned long encoderValue;
11
// Intervall 1 Sekunde
12
const unsigned long interval = 1000000;
13
// Zähler für Microsekunden
14
unsigned long previousMicros;
15
unsigned long currentMicros;
16
// Umdrehungen pro Minute
17
int rpm;
18
19
// Eingaenge
20
const byte pinEncoder = 2;            // Encoder Input
21
const byte pinPoti = A3;          // Analogwert fuer Drehzahlvorgabe durch Potentiometer
22
23
// Ausgaenge Motor
24
const byte pinMotor = 9;          // PWM-Signal fuer Motorgeschwindigkeit
25
const byte pinIN1 = 8;            // H-Brueckensteuersignal fuer Drehrichtung
26
const byte pinIN2 = 7;            // H-Brueckensteuersignal fuer Drehrichtung
27
28
29
/********************************************************************************************************************************/
30
void setup() {
31
32
  // Allgemein
33
  Serial.begin(9600);                               // Die Kommunikation mit dem seriellen Port wird gestartet fuer die Darstellung von Ergebnissen im seriellen Monitor
34
35
  // Einstellungen Encoder
36
  // Encoder Pin als Input mit Pullup
37
  pinMode(pinEncoder, INPUT_PULLUP);
38
  // Interrupt
39
  attachInterrupt(digitalPinToInterrupt(pinEncoder), updateEncoder, RISING);
40
  // Start Timer
41
  previousMicros = micros();
42
43
  // Einstellungen Motor
44
  pinMode(pinMotor, OUTPUT);                           // Pin Motor wird als Ausgang gesetzt
45
  pinMode(pinIN1, OUTPUT);                             // Pin in1 wird als Ausgang gesetzt
46
  pinMode(pinIN2, OUTPUT);                             // Pin in2 wird als Ausgang gesetzt
47
48
}
49
50
/**************************************************************************************************************************/
51
void loop() {
52
53
  // Motor ansteuern und Poti auslesen
54
  digitalWrite(pinIN1, LOW);                // Drehrichtung Motor festlegen (H-Bruecke)
55
  digitalWrite(pinIN2, HIGH);               // Drehrichtung Motor festlegen (H-Bruecke)
56
  MotorSpeed = analogRead(pinPoti)/4;       // Position des Potentiometers auslesen und umrechen
57
                                            // 10 bit Potentiometerwert in 8 bit Wert umrechenen (Eingang = 10bit, Ausgang = 8bit)
58
59
  if (MotorSpeed < 8)
60
  {
61
    MotorSpeed = 0;               // Abfangen von Summen des Motors bei zu geringen Drehzahlen
62
  }
63
  
64
  analogWrite(pinMotor, MotorSpeed);                   // PWM-Signal für Motorgeschwindigkeit ausgeben
65
66
  // Umdrehungen jede Sekunde aktualisieren
67
  currentMicros = micros();
68
  if (currentMicros - previousMicros > interval)
69
  {
70
    previousMicros = currentMicros;
71
72
    // Berechnung Drehzahl
73
    unsigned long tempEncoderValue = 0;
74
    ATOMIC_BLOCK (ATOMIC_RESTORESTATE)          // cli()+sei() mit SREG Sicherung
75
    {  
76
      tempEncoderValue = encoderValue ; 
77
    }
78
    rpm = (int)(tempEncoderValue * 60.0 / ENC_COUNT_REV);  // Ergebnis landet in 'int'
79
80
    // Displayausgabe wenn Wert gelesen
81
    if (rpm > 0) {
82
      Serial.print(rpm);
83
      Serial.println(" RPM");
84
    }
85
    
86
  }
87
}
88
void updateEncoder()
89
{
90
  // Increment value for each pulse from encoder
91
  encoderValue++;
92
}

von Veit D. (devil-elec)


Lesenswert?

Hallo,

kleine Korrektur.
1
ATOMIC_BLOCK (ATOMIC_RESTORESTATE)        
2
{  
3
   tempEncoderValue = encoderValue;
4
   encoderValue = 0;
5
}

von Einer K. (Gast)


Angehängte Dateien:

Lesenswert?

Maik H. schrieb:
> Die Umsetzung mit dem "T1-Capture-Eingang" ist mir nicht klar geworden,
> gibt es eventuell ein nachvollziehbares Beispiel?

Durchaus!
Aber ob Nachvollziehbar?
Das liegt mehr an dir, als am Beispiel.


Hier mal ein Ereigniszähler für einen Arduino mit ATMega328p
Man kann damit Ereignisse bis in den MHz Bereich zählen lassen.
Den Interval Code lasse ich mal weg, der sorgt nur dafür, dass jede 
Sekunde eine Anzeige kommt.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

den Trick mit dem union finde ich nett. Spart das shiften bzw. 
multiplizieren. Mußte das erstmal binär nachbauen und schauen ob das 
wirklich so funktioniert wie ich dachte. :-)  Jetzt habe ich dadurch 2 
Fragen.

a) Warum ist das union/struct AVR only?
b) Ist der Vorteil wenn der "Timer Source T1" zählt der, dass dadurch 
beim zählen keine zusätzlichen Interrupts erzeugt werden?  Im Vergleich 
wenn ein "normaler" Interrupteingang jeden Puls zählen müßte.

von Einer K. (Gast)


Lesenswert?

a)
Eigentlich ist das Verhalten laut C++ undefiniert.
Der Gcc garantiert allerdings, dass das so funktioniert.
Bei anderen µC haben haben die Daten evtl. einen anderen Fußabdruck im 
Speicher, dann wird das so erstmal nix.
Wenns universell werden soll, dann eben schieben oder multiplizieren.

b)
Ja.
Wenn für jede Flanke ein Interrupt feuert, ist bei wenigen kHz Ende im 
Gelände. So geht selbst bei 1MHz kaum Rechenzeit drauf.

von m.n. (Gast)


Lesenswert?

Veit D. schrieb:
> den Trick mit dem union finde ich nett. Spart das shiften bzw.
> multiplizieren.

Der Compiler wird den Code ohne Multiplikation schon selber hinbekommen.

Veit D. schrieb:
> Ist der Vorteil, wenn der "Timer Source T1" zählt der, dass dadurch
> beim Zählen keine zusätzlichen Interrupts erzeugt werden?

Das ist ein normaler torzeitgesteuerter Zähler, die Auflösung bei 
niedrigen Frequenzen bleibt daher relativ gering. Bei 1 Hz schwankt die 
Anzeige zwischen 0 und 1. T1-Capture wird hier garnicht verwendet.

Arduino Fanboy D. schrieb:
> Wenn für jede Flanke ein Interrupt feuert, ist bei wenigen kHz Ende im
> Gelände.

>= 100 kHz sind kein Problem: 10 µs sind schon eine lange Zeit. In Assembler 
programmiert geht es bis 1 MHz Eingangsfrequenz.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

alles klar, habe verstanden. Danke. Jetzt hoffen wir das der TO aus 
alledem auch einen Nutzen ziehen kann.

von Einer K. (Gast)


Lesenswert?

m.n. schrieb:
> >= 100 kHz sind kein Problem: 10 µs sind schon eine lange Zeit. In Assembler
> programmiert geht es bis 1 MHz Eingangsfrequenz.
16 Takte für Call, iret Pus Pop und 32Bit Zähler hochsetzen?
Sportlich!
Sehr sportlich.

Wenn dann noch mehr ISR ihr Unwesen treiben, kann es so schnell mal ein 
Ereignis "übersehen".

Hach...
Assembler steht hier, glaube ich, erstmal nicht zu Debatte.

Der TE verwendet attachInterrupt().
Das ist einerseits recht bequem, erfordert andererseits einen Call in 
der ISR und führt so zu langen Push Pop Kaskaden.
Ja, lass die 100kHz die Grenze sein.... (nicht getestet), welche dann 
den armen kleinen 328p zur Vollbeschäftigung treibt.

Während er bei meinem Vorschlag noch reichlich "Luft" hat. Und eher kein 
Ereignis übersehen wird.

von m.n. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Ja, lass die 100kHz die Grenze sein.... (nicht getestet)

Das habe ich schon getestet.

Arduino Fanboy D. schrieb:
> Während er bei meinem Vorschlag noch reichlich "Luft" hat. Und eher kein
> Ereignis übersehen wird.

Der TO braucht Luft nach unten ;-)

von Maik H. (tyson)


Lesenswert?

Vielen Dank für die informativen Antworten und besonderen Dank an Veit 
D. für den angepassten Code.

Die Bibliothek #include <util/atomic.h> habe ich bisher nicht in den 
Bibliotheken für den Arduino in dieser Form gefunden.

Nach dem folgenden Link habe ich nun die Bibliothek #include 
<SimplyAtomic.h> eingefügt und im Code einen Teil angepasst.

https://github.com/wizard97/SimplyAtomic
1
ATOMIC()                         // neuer Befehl für den Aufruf
2
{  
3
 tempEncoderValue = encoderValue ; 
4
 encoderValue = 0;
5
}

Spricht etwas gegen diese Bibliothek oder wird diese die gleiche 
Funktionalität beinhalten?

von Einer K. (Gast)


Lesenswert?

Maik H. schrieb:
> Die Bibliothek #include <util/atomic.h> habe ich bisher nicht in den
> Bibliotheken für den Arduino in dieser Form gefunden.

Was auch kein Wunder ist, gehört sie doch zum Lieferumfang des GCC für 
AVR.
Natürlich darfst du den lieferumfang des Gcc ausblenden, bzw. unbeachtet 
lassen. Aber dann geht dir einiges/viel nützliches durch die Lappen.

Maik H. schrieb:
> Spricht etwas gegen diese Bibliothek oder wird diese die gleiche
> Funktionalität beinhalten?
Beide liegen im Quellcode vor!
Du könntest da rein schauen, und selber vergleichen.

Aber Vorsicht!
Auf die Art könnten sich ein Erkenntnisgewinn einstellen.
(hoffentlich kannst du damit umgehen)

von Veit D. (devil-elec)


Lesenswert?

Hallo,

> Die Bibliothek #include <util/atomic.h> habe ich bisher nicht in den
> Bibliotheken für den Arduino in dieser Form gefunden.

also ich kompiliere immer erst und schaue ob was fehlt

> Spricht etwas gegen diese Bibliothek oder wird diese die gleiche
> Funktionalität beinhalten?

Muss leider mit einer Gegenfrage antworten. Warum eine fremde Lib 
verwenden wenn man das Original hat? Die Frage müßte zugleich die 
Antwort sein.

Ich denke jedoch die Idee mit der fremden Lib beruht auf dem 
Missverständnis das obige Lib angeblich fehlen würde.

"util/atomic.h" ist nur der letzte Teil vom Suchpfad und Suchinfo für 
den Compiler. Du siehst daran nur das die Headerdatei atomic.h in einem 
Verzeichnis namens util liegt. Wenn man jetzt einfach auf C: nach 
atomic.h suchen würde, dann erscheinen unzählige Angaben, je nachdem was 
alles an Programmiersoftware installiert ist. Deswegen gehe in den 
Arduino Installationspfad und starte dort die Suche nach atomic.h, 
sollte nur einmal vorkommen.

Welche du verwenden solltest sollte damit klar sein.

Wegen dem Sketch. Kein Problem, so lang war der nicht.
Die Lösung von ArduinoFanboy solltest du dir allerdings auch anschauen. 
Sind paar tolle Features drin. Man kann immer wieder von anderen lernen. 
Am Ende muss man das nutzen was man versteht und lesen kann und das noch 
nicht verstandene aber versuchen im Hinterkopf zubehalten. Irgendwann 
versteht man es und wird so Stück für Stück immer schlauer.

von Maik H. (tyson)


Lesenswert?

Ja, es ist ein Missverständnis meinerseits. Bisher bin ich davon 
ausgegangen, dass alle Lib´s in "libaries" abgelegt sein müssen.
Die Antwort erweitert mein Verständnis dazu.


Die Datei habe ich im folgenden Pfad gefunden.
C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include\util

Mehrere Versuche diesen nun in für "until" in #include <util/atomic.h> 
einzusetzen schlugen fehl.

Wie sollte dieser Pfad-Aufruf aufgebaut sein?

#include <???/atomic.h>

Die Antworten von ArduinoFanboy sind bestimmt gut, allerdings kann ich 
aktuell wirklich nicht die Inhalte lesen und verstehen.
Leider fehlt mir aktuell die Zeit um dies in der Form nachzuvollziehen 
wie ich es gerne würde, vielleicht kann ich das nochmal nachholen.

von Einer K. (Gast)


Lesenswert?

Maik H. schrieb:
> Wie sollte dieser Pfad-Aufruf aufgebaut sein?
So wie es in meinem Programm steht!
Auch der Veit D hats vollkommen korrekt in seinem Programm.

Selbst auf der Dokuseite zu atomic.h  findet sich das so.

von Maik H. (tyson)


Lesenswert?

Der Fehler ist behoben.

Durch das Einbinden der der #include <SimplyAtomic.h> Bibliothek wurde 
die  <util/atomic.h> Bibliothek blockiert und konnte nicht eingebunden 
werden. Durch entfernen von SimplyAtomic.h, die dann nicht mehr benötigt 
wird, ist das Einbinden nun möglich.

Mein Gedanke war, dass ich die Bibliothek die nicht in dem libaries 
Verzeichnis liegt über den zugehörigen Pfad einbinden muss, damit es 
funktioniert.

Vielen Dank für die Mühe von euch in diesem Forum :-)

von Einer K. (Gast)


Lesenswert?

Maik H. schrieb:
> Mein Gedanke war, dass ich die Bibliothek die nicht in dem libaries
> Verzeichnis liegt über den zugehörigen Pfad einbinden muss, damit es
> funktioniert.

Diese Methode wird verwendet: 
https://www.rapidtables.com/code/linux/gcc/gcc-i.html

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.