Attiny1617, Hall Sensor mit Magnet Encoder ... Interrupt zählt nicht korrekt

Hallo,

ich sitze hier an einem I2C Motor Kontroller den ich hier in meinem YOutube kanal vorgestellt habe.

Nachdem nun alles bei mir angekommen ist und ich auch die Komponenten alle ausgetestet habe, versuche ich mich an meine ersten library. Das Problem, der Motor hat eine Übersetzung von 298:1 ... wenn ich das Encoder rad langsam eine volle Umdrehung drehe bekomm ich 6 Impulse. rechnet man das hoch, müsste sich der Getriebemotor eine volle umdrehung bei 298*6 = 1788 Schritten drehen ... leider dreht er sich bis 10 mal um die eigene Achse. In der magnetencoder scheibe sind 2 magneten die sich in 180° gegenüberstehen.

Hier der komplette Code bei github:
https://github.com/xpix/XMoto/blob/master/DRV8837_lib/drv8837/drv8837.cpp

Der Interrupt macht nichts anderes, als einfach den Counter hochzuzählen und ihn mit den übergebenen Steps zu vergleichen, wenn mehr Schritte im Counter als bei Steps wird der Motor gestoppt:

https://github.com/xpix/XMoto/blob/master/DRV8837_lib/drv8837/drv8837.cpp#L39


....
attachInterrupt(_HALL_pin, drv8837::_count, RISING);
}

static void drv8837::_count() {
_counter++;

if(_steps && _counter >= _steps){
_stop();
}
}

Leider funktioniert das nicht, erst nach einer ewigen zeit und mehrmaligen umdrehungen des motorgetriebes stoppt er.

Auch habe ich das ganze am Ausgang des hall sensors via Oszilloskop gemessen, die abstände zwischen den Signalen liegen bei 150ms, das sollte doch der Interrupt schaffen?

Den Attiny betreibe ich mit dem megaTinyCore, hier der Pinout von dem teil:
https://github.com/SpenceKonde/megaTinyCore/blob/master/megaavr/extras/ATtiny_x17.md

Ich hoffe auf Eure Hilfe, da ich langsam ratlos bin was ich noch machen kann. der Attiny1617 läuft übrigens intern mit 20MHz.

Gruß
Frank

Im Anhang ein Bild von dem Aufbau.

Das auslesen deines Counters muss atomar erfolgen

Hatten wir hier nicht letztens gerade eine Diskussion, dass man eine Methode nicht so einfach als ISR benutzen kann (wegen self?)

Gruß Tommy

combie:
Das auslesen deines Counters muss atomar erfolgen

Ok, und wie mache ich das am besten?

Tommy56:
Hatten wir hier nicht letztens gerade eine Diskussion, dass man eine Methode nicht so einfach als ISR benutzen kann (wegen self?)

Das geht nur durch das static. Statische Methoden haben keinen this-Zeiger. Ansonsten kompiliert das erst gar nicht

Die übliche falsche Verwendung von Interrupts (vor allem atomares Auslesen) kompiliert, aber läuft nicht richtig:

https://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html
Das sauberste ist ATOMIC_RESTORESTATE, obwohl man hier eigentlich davon ausgehen kann dass die Interrupts normalerweise aktiviert sind. Man kann aber auch die Interrupts per Hand aus- und anschalten und dazwischen den Wert kopieren

Danke, das static hatte ich übersehen.

Gruß Tommy

Hi

if(_steps && _counter >= _steps){
_stop();
}

Wie soll Da die Ver-UND-ung größer als einer der Werte werden?
Das Höchste der Gefühle ist die Gleichheit, wenn _steps==_counter ist - dann brauche ich aber keine logische UND-Verknüpfung zuvor, da reicht mir die simple Prüfung auf Gleichheit - sollte auch schneller sein (wenn Das der Kompiler nicht eh erkannt hat).

MfG

Ok, hat sich erledigt. Der HallSensor war der schuldige ... der konnte nur 45Hz ... war halt ein chinesisches Datasheet :slight_smile:

Vielen Dank an alle
Frank