Einen wunderschönen guten morgen liebes Forum
Ich habe mal wieder ein Projektchen, und bräuchte mal einen Denkanstoß, vielleicht habt ihr einen Gedanken für mich!
Konkret gehts um meinen Rasenmäher. Momentan hat der Motor eine Fliehkraftgesteuerte Drehzahlregelung. Das bedeutet: Mit dem Gaszug spanne ich nur eine Feder, die dann mit einer gewissen Kraft am Hebel der Drosselklappe zieht und diese somit ganz öffnet (vollgas). An die Kurbelwelle ist nun ein Fliehkraftregler gekoppelt, der mit steigender Drehzahl einen Hebel bewegt. Dieser Hebel drückt nun die Drosselklappe zurück richtung geschlossen. Wenn das alles gut justiert ist, pendelt sich die Drehzahl sauber ein auf einen Wert den ich am Gaszug einstellen kann, und reagiert somit auf Belastungen.
Und hier ist auch die Crux, das ganze ist dermaßen schlecht zu justieren, fehleranfällig und hakelig, ganz besonders weil der Motor mit der Regelung doch schon in die Jahre gekommen ist, und sich dadurch natürlich auch die Charakteristik ändert.
Nun hab ich mir in den Kopf gesetzt, den ganzen Klapperatismus durch einen Arduino, einen Hallgeber und einen Servo zu ersetzen.
Man könnte sich natürlich die Arbeit sparen und einfach einen neuen Rasenmäher kaufen, aber das wäre langweilig ^^
Nun zum eigentlichen Projekt:
Kernstück ist ein Arduino Nano mit einem Mega328p.
Die Drehzahl wird mit einem Hallgeber direkt an der Schwungscheibe abgenommen, in der ja schon ein Magnet integriert ist (für die Zündspule), es ergibt sich ein Impuls pro Umdrehung.
Es wird 2 Killswiches geben, einer der das ganze System ausschaltet, und einer der über ein einfaches Relais die Motorzündung abschaltet (bei Spannungsabfall lässt das Relais los -> Zündung unterbrochen -> Motor aus).
Mit 2 Tastern wird die Solldrehzahl in Schritten von 100 oder 200 upm eingestellt (Hier wäre auch ein Poti denkbar).
Als Display ist eine 7-Segmentanzeige vorgesehen, die mit einem MAX7219 angesteuert wird. Davon sollen 4 Digits die exakte Ist-Drehzahl anzeigen, 2 Digits zeigen die Eingestellte Soll-Drehzahl an, und die restlichen 2 Digits werden ausgelötet, dafür kommt ein Bargraph als Lastanzeige dran (der letzten Endes nur die Drosselklappenstellung widerspiegelt). Die Digits auf dem Display möchte ich alle 500ms aktualisieren, die Lastanzeige alle 100ms, mit dem Durchschnittswert aus der jeweiligen Zeitspanne.
Die Drosselklappe wird dann einfach direkt über ein kleines Servo angesteuert.
Folgendes ist schon realisiert:
Der Arduino liest den Hallgeber aus und zeigt die exakte Drehzahl auf dem Display an. Funktioniert bis 1000upm problemlos, mehr Drehzahl gibt mein Akkuschrauber leider nicht her, also werde ich das ganze bald in den Rasenmäher einbauen müssen
Die einzelnen Elemente an sich stellen kein Problem für mich dar, Errechnen der Drehzahl, Ansteuerung des Displays, sind gar kein Problem, und auch ein Servo steuern sollte unproblematisch sein (auch wenn ich das noch nie gemacht hab).
Meine Gedankenblockade liegt nun eher im Regelkreis, so ein Motor reagiert ja auch etwas verzögert, und nicht so exakt (wobei es ja auf 50 Umdrehungen hin oder her nicht ankommt)
Ich bin für jeden Gedankeninput dankbar, und wenn er noch so abwegig oder unausgegoren scheint!
Ein weiteres Problem befürchte ich im Timing: bei 4000upm (soviel muss auf jeden Fall messbar sein, das ist so die obere Grenze im normalen Mähbetrieb, allerdings kann der Motor auch locker mehr, was nach Möglichkeit auch noch gemessen werden sollte) dauert jede Umdrehung gerademal 15ms, wenn jetzt der Arduino recht beschäftigt ist und ständig Umdrehungen übersieht wäre das ungünstig... Vielleicht könnt ihr ja meine Sorgen diesbezüglich ein bisschen zerstreuen, oder habt auch Tipps um die Sache möglichst sicher zu gestalten.
So, das war jetzt viel Text, für so ein mickriges und vollkommen unnötiges Projekt, aber vielleicht ist noch Jemand bis hierhin gekommen und hat einen Denkanstoß für mich...!
Zum Abschluss hänge ich noch meinen bisherigen Code an, aber achtung: Das ist bisher nur ein ganz schnell zusammengesteckter Code zum testen der Funktionen, es ist viel copy&paste und miese variablennamen drin, das wird noch komplett neu geschrieben
#include "LedControl.h"
LedControl lc=LedControl(12,11,10,1);
unsigned long previousMillis = 0;
const long interval = 1000;
int i = 9;
int r = 0;
int c = 0;
boolean hall_state_changed = 0;
unsigned long millis_rev = 0;
unsigned long millis_last = 0;
unsigned long upm = 0;
int upm_0 = 0;
int upm_1 = 0;
int upm_2 = 0;
int upm_3 = 0;
const byte interruptPin = 2;
void isr()
{
hall_state_changed = 1;
}
void setup()
{
pinMode(interruptPin, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), isr, FALLING);
lc.shutdown(0,false);
lc.setIntensity(0,8); // (0-15)
lc.clearDisplay(0);
lc.setRow(0,3,B01011011);
lc.setRow(0,2,B01000110);
lc.setRow(0,1,B01111110);
lc.setRow(0,0,B11100111);
}
void loop()
{
if(hall_state_changed == 1)
{
hall_state_changed = 0;
millis_rev = millis() - millis_last;
millis_last = millis();
upm = 60000/millis_rev;
upm_3=(upm%10000)/1000;
upm_2=(upm%1000)/100;
upm_1=(upm%100)/10;
upm_0=upm%10;
lc.setDigit(0,3,upm_3,true);
lc.setDigit(0,2,upm_2,false);
lc.setDigit(0,1,upm_1,false);
lc.setDigit(0,0,upm_0,false);
}
if(millis() - millis_last >= 1000)
{
lc.setRow(0,3,B01011011);
lc.setRow(0,2,B01000110);
lc.setRow(0,1,B01111110);
lc.setRow(0,0,B11100111);
upm = 0;
}
if(millis() - previousMillis >= interval)
{
previousMillis = millis();
// Platz für alles mögliche
}
}