Forum: Mikrocontroller und Digitale Elektronik Abblitzer / Zündzeitpunkt


von Nick S. (kolbi)


Lesenswert?

Hallo,

Ich möchte mir irgendwann mal eine programmierbare Zündung bauen, und 
bin gerade dabei die Basics zu lernen.

Daher habe ich mir (mit viel Hilfe vom Forum) einen Drehzahlmesser mit 
Arduino Nano und 2x16 LCD gebaut, inkusive Lichtschranken und kleiner 
Lochscheibe wo man einfach per Hand mal andreht und die Drehzahl ablesen 
kann.

In weiterer Folge soll eine bzw mehrere LEDs aufblitzen wenn der Impuls 
vom LiSchra kommt. Wenn man einen Strich auf die Lochscheibe malt, kann 
man den dann wie beim Zündung abblitzen beobachten. Je nach Drehzahl und 
Verzögerung müsste man den Strich wandern sehen.

Jetzt möchte ich den Blitzzeitpunkt, passend zur Drehzahl nach Belieben 
verstellen können...aber da haperts gewaltig an Verständnis :(

Wie würdet ihr das lösen?



Hier der Link zum Drehzahlmesser-Sketch:

Beitrag "Re: Arduino Drehzahlmesser"


Mfg

von Nick S. (kolbi)


Angehängte Dateien:

Lesenswert?

Eine Zündverstellung nach "spät" hab ich schonmal hinbekommen, hier der 
Code:

1
#include <LiquidCrystal.h>
2
LiquidCrystal lcd(12, 11, 5, 4, 3, 13);
3
4
volatile float Zeit = 0;
5
volatile float Vorherige_Zeit = 0;
6
7
void setup()
8
{
9
  //Led bzw Transistor
10
  pinMode(10, OUTPUT);
11
  
12
  //Digital Pin 2 als Interrupt konfigurieren, reagiert auf fallende Flanken
13
 attachInterrupt(0, Sensor_Interrupt, FALLING);
14
15
  // 2x16 LCD Display einrichten
16
  lcd.begin(16, 2);
17
  // Drehzahl auf dem LCD Ausgeben
18
  lcd.print("Umdrehungen/Min");
19
}
20
21
//Hauptschleife zum Berechnen der Drehzahl und LCD Displayupdate
22
void loop()
23
{
24
  int upm = 0;
25
  
26
  while(1){    
27
28
     //Displayupdates verzögern
29
    delay(200);
30
  
31
  //Letzte Reihe löschen
32
  lcd.setCursor(0, 1);
33
  lcd.print("                ");   
34
  
35
  //Drehzahl ausgeben
36
  lcd.setCursor(0, 1);
37
  lcd.print(upm);   
38
39
40
  //Drehzahlberechnung, Zeit*n für die Anzahl der Impulse (Lochscheibe, Lüfterflügel,...)
41
  if(Zeit > 0)
42
  {
43
        upm = 60*(1000000/Zeit);
44
  }
45
 
46
 }
47
}
48
49
//Interrrupt Capture
50
void Sensor_Interrupt()
51
{
52
   Zeit = (micros() - Vorherige_Zeit); 
53
   Vorherige_Zeit = micros();
54
55
   delayMicroseconds(2000); //LED Verzögerung   
56
57
58
   digitalWrite(10, HIGH);
59
   delayMicroseconds(5);
60
   digitalWrite(10, LOW);
61
}


Schaut ganz lustig aus den Strich auf dem Drehrad zu verfolgen, jetzt 
wärs halt schön je nach Drehzahl beliebige Verzögerungswserte zu haben.

Kann man zB die Drehzahl durch 100 Teilen, und dann die Drehzahl als 
Index in einem Array benutzen, wo ich meine Verzögerungswerte je 100 
Umdrehungen drin habe?

Lg!

von Thomas (kosmos)


Lesenswert?

ich habe das bisher immer so gemacht Zeit einer Umdrehung messen, durch 
360 bzw. 3600 Teilen je nach gewünschter Auflösung, dieser Wert 
entspricht dann halt 1° bzw. 0,1° und das dann mit dem Wert 
Multiplizieren wann gezündet werden soll abzügl. der Schließzeit.

Angenommen ich möchte dann 10° vor OT Zünden eine Umdrehung dauert 4000 
Takte

4000/3600=1,111...
1,111...x100=111,111....
4000-111,111=3888,888...= Zündzeitpunkt und dann musst du noch 
ausrechnen wann du die Zündspule bestromst damit du zum ZZP abschalten 
kannst.

Das ganze kann man dann über die Compare Match Funktion des Timers 
machen. Man übergibt also nur die beiden Werte wann die Spule ein und 
ausgeschaltet werden soll.

Wenn man nur Blitzen will reicht ja einfach der eine Wert eine 10Watt 
LED ist dafür ausreichend, wenn man sie kurz und stark pulst

von Nick S. (kolbi)


Lesenswert?

Ich habs mittlerweile hinbekommen, jetzt wärs interessant den Code zu 
optimieren. Ideen?
1
#include <LiquidCrystal.h>
2
LiquidCrystal lcd(12, 11, 5, 4, 3, 13);
3
4
volatile float Zeit = 0;  // float
5
volatile float Vorherige_Zeit = 0;  // float
6
volatile int upm = 0;
7
volatile int Gradzeit;
8
volatile int Pickupposition = 30;  //Pickupposition in °KW vor OT
9
volatile int Vorzuendung[] = {0,
10
11
5,5,5,5,5,9,9,9,9,9,        //100-1000upm
12
13
19,19,19,19,19,14,14,14,14,14,    //1100-2000upm
14
15
5,5,5,5,5,1,1,1,1,1,       //2100-3000upm
16
17
0,0,0,0,0,0,0,0,0,0,      //3100-4000upm
18
19
0,0,0,0,0,0,0,0,0,0};    //4100-5000upm
20
21
22
23
void setup()
24
{
25
  //Led bzw Transistor
26
  pinMode(10, OUTPUT);
27
  
28
  //Digital Pin 2 als Interrupt konfigurieren, reagiert auf fallende Flanken
29
 attachInterrupt(0, Sensor_Interrupt, FALLING);
30
31
  // 2x16 LCD Display einrichten
32
  lcd.begin(16, 2);
33
  // Drehzahl auf dem LCD Ausgeben
34
  lcd.print("Umdrehungen/Min");
35
}
36
37
//Hauptschleife
38
void loop()
39
{
40
//  int upm = 0;
41
  
42
  while(1){    
43
44
     //Displayupdates verzögern
45
    delay(200);
46
  
47
  //Letzte Reihe löschen
48
  lcd.setCursor(0, 1);
49
  lcd.print("                ");   
50
  
51
  //Drehzahl ausgeben
52
  lcd.setCursor(0, 1);
53
  lcd.print(upm);   
54
 
55
 }
56
}
57
58
//Interrrupt Capture
59
void Sensor_Interrupt()
60
{
61
   Zeit = (micros() - Vorherige_Zeit); 
62
   Vorherige_Zeit = micros();
63
64
   upm = 60*(1000000/Zeit);
65
66
   Gradzeit = Zeit/360;   // Zeit für 1°KW 
67
 
68
69
   delayMicroseconds(((Pickupposition-Vorzuendung[(upm/100)])*Gradzeit)); // Verzögerung   
70
71
72
   digitalWrite(10, HIGH);
73
   delayMicroseconds(10);
74
   digitalWrite(10, LOW);
75
}

lg

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.