Hallo,
bin absoluter Neuling und hab mich ab Dezember erstmals mit der Materie (Elektronik und C++) befasst.
Zum Ansteuern von Injektoren und berechnen der Signalzeit benötige ich die aktuelle Drehzahl.
Hab von Timer Interrupt :: Meine Arduino-Projekte
Inspirationen geholt.
Allerdings wird der Timer Interrupt scheinbar nicht ausgelöst.
Nachfolgend der Code.
Der Code ist insgesamt noch unvollständig,
meine Frage bezieht sich lediglich auf den Timer zum Ermitteln der Drehzahl U/min.
Ich verwende einen Nano.
Ich würde mich über Tips sehr freuen.
#define hauptschalter_PIN A2 // Pin Nummer des Lenkerschalters zum EIN und Ausschalten der Einspritzung
#define injektor2_schalter A3 // Pin Nummer des Lenkerschalters zum EIN und Ausschalten des zweiten Injektors
#define injektor3_schalter A4 // Pin Nummer des Lenkerschalters zum EIN und Ausschalten des zweiten Injektors
#define injektor_pin_1 7 //PIN Nummer Injektorausgang 1
#define injektor_pin_2 8 //PIN Nummer Injektorausgang 2
#define injektor_pin_3 9 //PIN Nummer Injektorausgang 3
#define pumpe_pin 3 //PIN Nummer Pumpe Ausgang
#define pickup_signal_2 2 // PIN Nummer PickupSignal2 Eingang (2.Pickup am Ansaugbeginn)PIN 2+3 sind die PINs an welchen die "interrupt"-Funktion funktioniert
// Die Potiometer Drehzahl und TPS dienen dazu die errechnete Einspritzzeit aus (drehzahl_einspritzwert_prozent [] )und (tps_einspritzwert_prozent [] )zu beeinflussen.
// Die Potis sind während der Fahrt zu bedienen um die Grundeinstellung zu ermitteln. Die Werte der beiden Potis werden auf dem LCD Display angezeigt.
#define poti_drehzahl_parameter_pin A0 //PIN Nummer Analog, Potentiometer,Poti um die Parameter aus dem errechneten ms Einpritzwert aus (drehzahl_einspritzwert_prozent [] )zu verändern
#define poti_tps_parameter_pin A1 //PIN Nummer Potentiometer,Poti um die Parameter aus dem errechneten ms Einpritzwert aus (tps_einspritzwert_prozent [] )zu verändern
#define tps_pin A5 //PIN Nummer Potentiometer,Poti um die Parameter aus dem errechneten ms Einpritzwert aus (tps_einspritzwert_prozent [] )zu verändern
// #define injektionszeit_max 2300 // maximale Einpritzdauer in Microsekunden bei 13000U/min(Entspricht einer Überschneidung der Signale vom Pickup pro Zylinder bei 13000 U/Min)
volatile unsigned int drehzahl_pumpe_an; //Variable in welcher die Drehzahl angegeben wird, ab welcher die Pumpe angeschaltet ist
volatile unsigned int pumpe_an; // Variable 0 oder 1, welche für die Anweisung verwendet wird. Pumpe an = 1 . Berechnet aus (drehzahl_aktuell > drehzahl_pumpe_an)
volatile unsigned long systemzeit; // Variable Speicher für Systemzeit Microsekunden.
//Formel zur Berechnung der Einspritzdauer in microsekunden ("drehzahl_einspritzwert []" multipliziert mal "tps_einpsritzfaktor []")
volatile unsigned int drehzahl_schaltpunkte [12] = {50,100,200,300,400,500,600,700,800,5000,6000,13000}; // Array mit 12 Werten zur Angabe der Drehzahlen,TEST
//volatile unsigned int drehzahl_schaltpunkte [12] = {6000,7000,7500,8000,8500,9000,9500,10000,10500,11000,11500,13000}; // Array mit 12 Werten zur Angabe der Drehzahlen, welche als Schaltpunkte verwendet werden, um die Einspritzdauer zu errechnen
volatile unsigned int drehzahl_einspritzwert [12] = {0,350,330,310,295,280,265,250,240,230,214,214}; // Array mit 12 Werten zur Angabe der (Einspritzdauer in Microsekunden geteilt durch 10) in Abhängigkeit von der Drehzahl aus (drehzahl_schaltpunkte [])
volatile unsigned int drehzahl_einspritzwert_tmp;
volatile unsigned long drehzahl_aktuell; //aktuelle Drehzahl des Motors
volatile unsigned int pickupsignalzaehler; //summe der hochgezählten Pickupsignale während der definierten Zeitspanne zur berechnung der aktuellen Drehzahl
// Potiometer Werte TPS :::::::::: noch nicht ganz sicher, ob ich Prozentwerte oder digitalwerte nehme
volatile unsigned int tps_auslesung;
volatile unsigned int tps_stellung;
volatile unsigned int tps_wert_tmp;
volatile unsigned int tps_schaltpunkte [11] = {10,15,20,30,40,50,60,70,80,90,100}; // Array mit 11 Werten zur Angabe der TPS Prozentwerte TEST
//volatile unsigned int tps_schaltpunkte [11] = {0,10,20,30,40,50,60,70,80,90,100}; // Array mit 11 Werten zur Angabe der TPS Prozentwerte, welche als Schaltpunkte verwendet werden, um die Einspritzdauer zu errechnen
volatile unsigned int tps_einpsritzfaktor [11] = {1,1,2,3,4,5,6,7,9,10}; // Array mit 11 Werten des Multiplikationsfaktors in Abhängigkeit von TPS Potiometerwerte aus (tps_schaltpunkte [])
//Die Einpritzzeit in Microsekunden errechnet sich aus tps_einpsritzfaktor MAL drehzahl_einspritzwert
volatile unsigned long einspritzzeit_micros; // errechnete Einspritzzeit in Microsekunden
volatile unsigned long anschaltszeit_einspritzung_micros; // Zeitstempel zu Beginn des Einspritzzeitpunktes in Microsekunden
volatile unsigned long ausschaltzeit_einspritzung_micros; // Zeitstempel zu Beginn des Einspritzzeitpunktes PLUS berechnete Einpritzzeit in Microsekunden (int einspritzzeit_micros;)GLEICH Endwert micros zum Stop des Injektorsignals
volatile unsigned int injektor_status; //Anweisung ob Injektor an sein soll oder aus , wenn Injektor AN (int injektor_pin = HIGH;)Wert=1, wenn Injektor AUS (int injektor_pin = LOW;)Wert=0
volatile unsigned int hauptschalter_status; // Lenkerschalter AN/AUS, Hauptschalter für das Ein- und Ausschalten der Einspritzung , Ein=HIGH - aus=LOW
volatile unsigned int injektor2_schalter_status; // Lenkerschalter AN/AUS für die Verwendung des zweiten Injektors, Ein=HIGH - aus=LOW
volatile unsigned int injektor3_schalter_status; // Lenkerschalter AN/AUS für die Verwendung des zweiten Injektors, Ein=HIGH - aus=LOW
//volatile unsigned int pickupsignal; //
volatile unsigned int index_tps; //=Ergenis, ist der Indexwert bzw. die Position des breakepoints im array-Index des tps_schaltpunkte breakpoints ermitteln um mit diesem den tps_einpsritzfaktor aus dem array zu finden
volatile unsigned int index_drehzahl; //=Ergenis, ist der Indexwert bzw. die Position des breakepoints im array Index des Drehzahlbreakpoints ermitteln um mit diesem den drehzahl_einspritzwert aus dem array zu finden
void setup() {
Serial.begin(9600); // serielle Schnittstelle konfigurieren mit 9600 Baud
pinMode(injektor_pin_1, OUTPUT); // Definition, dass das injektor_pin_1 ein Ausgang ist.
pinMode(injektor_pin_2, OUTPUT); // Definition, dass das injektor_pin_2 ein Ausgang ist.
pinMode(injektor_pin_3, OUTPUT); // Definition, dass das injektor_pin_3 ein Ausgang ist.
pinMode(pumpe_pin, OUTPUT); // Definition, dass das pumpe_pin ein Ausgang ist.
pinMode(tps_pin, INPUT); // Definition, dass potiometer_drehzahl_parameter_pin ein Eingang ist.
pinMode(poti_drehzahl_parameter_pin, INPUT); // Definition, dass potiometer_drehzahl_parameter_pin ein Eingang ist.
pinMode(poti_tps_parameter_pin, INPUT); // Definition, dass poti_tps_parameter_pin ein Eingang ist.
pinMode(injektor2_schalter, INPUT); // Definition, dass injektor2_schalter ein Eingang ist.
pinMode(injektor3_schalter, INPUT); // Definition, dass injektor2_schalter ein Eingang ist.
pinMode(pickup_signal_2,INPUT_PULLUP); // Definition, dass pickup_signal2 ein Eingang ist.
//attachInterrupt(digitalPinToInterrupt(pickup_signal_2), pickupsignal, RISING); // Signal vom Pickup erkennen
attachInterrupt(digitalPinToInterrupt(pickup_signal_2), pickupsignal, FALLING); // Signal vom Pickup erkennen - Änderung 0.2.0 zu 0.2.1 Bleibt vorerst bei RISING und NICHT FALLING
//injektor_status = 0;
//pickupsignalzaehler = 0;
drehzahl_pumpe_an = 100; // Angabe der Voreinstellung der Drehzahl, ab welcher die Pumpe an ist TEST
//drehzahl_pumpe_an = 6000; // Angabe der Voreinstellung der Drehzahl, ab welcher die Pumpe an ist
//START TIMER SETUP -------------------------------------------------------------------------------------------------START TIMER SETUP
//TIMER SETUP for highly preceise timed measurements TIMER SETUP für hochpräzise zeitgesteuerte Messungen
cli();//stop all interrupts
// turn on CTC mode
TCCR1A = 0;// set entire TCCR1A register to 0 das gesamte TCCR1A-Register auf 0 setzen
TCCR1B = 0;// same for TCCR1B
TCCR1B |= (1 << WGM12); //Setze CTC-Mode (Waveform Generation Mode)
// Set prescaler
TCCR1B |= (1 << CS11); //Setze CS11 (Clock Select) für prescaler 8
// Verschiedene settings
//TCCR1B |= (1 << CS12) | (1 << CS10); //Setze CS10 und CS12 (Clock Select) für prescaler 1024
//TCCR1B |= (1 << CS12); //Setze CS12 (Clock Select) für prescaler 256
TCCR1B |= (1 << CS11) | (1 << CS10); //Setze CS11 und CS10 (Clock Select) für prescaler 64 // Prescaler 64 hier verwendet
//TCCR1B |= (1 << CS11); //Setze CS11 (Clock Select) für prescaler 8
//initialize counter value to 0;
TCNT1 = 0;
// Timerzählung für 20Hz-Schritte einstellen =50Millisekunden. Der Wert des Registers OCR1A ist abhängig von der gewünschten Interruptfrequenz und dem gewählten Vorteiler. Es gilt die folgende Formel:
// (CPU Frequenz (Hier =16000000)/(Prescaler64*gewünschte Interruptfrequenz20HZ))-1
OCR1A = 12499; // Wert für 20Hz und prescaler 64
// enable timer compare interrupt Timer-Vergleichsinterrupt aktivieren
TIMSK1 |= (1 << OCIE1A); //Bit Output Compare A Match Interrupt Enable setzen
sei();//allow interrupts //Setze globales Interrupt-Enable-Bit
//END TIMER SETUP--------------------------------------------------------------------------------------------------END TIMER SETUP
} // setup Ende
// Funktion welche ausgeführt werden soll wenn das Pickupsignal den attachInterrupt auslöst . Anfang
// Wenn injektor aus ist, wird der injektor_status auf 1 gesetzt und die Systemzeit in der Variable anschaltszeit_einspritzung_micros gespeichert
void pickupsignal() {
pickupsignalzaehler++; // Erhöht die Variable "pickupsignalzaehler" pro Pickupsignal jeweils jeweils um 1
if (injektor_status == 0) {
injektor_status = 1; // Injektorstatus auf 1 setzen Der Injektorstatus ist die Anweisung, dass der Injektor an oder ausgeschaltet sein soll
anschaltszeit_einspritzung_micros = micros(); // Zeit zum Beginn der Einspritzung
ausschaltzeit_einspritzung_micros = anschaltszeit_einspritzung_micros + einspritzzeit_micros;
}
}
// Funktion welche ausgeführt werden soll wenn das Pickupsignal den attachInterrupt auslöst . Ende
void loop() {
// Ermitteln, ob die Pumpe angeschaltet werden soll oder nicht und setzten der Variable pumpe_an ANFANG
if (drehzahl_aktuell >= drehzahl_pumpe_an) {
pumpe_an = 1;
}
else {
pumpe_an = 0;
}
// Ermitteln, ob die Pumpe angeschaltet werden soll oder nicht und setzten der Variable pumpe_an ENDE
// Index des Drehzahlbreakpoints ermitteln um mit diesem den drehzahl_einspritzwert aus dem array zu finden ANFANG
//int index_drehzahl; //=Ergenis, ist der Indexwert bzw. die Position des breakepoints im array
for (int i=0; i<12; i++) { // i<12; Auszulesender array hat 12 Einträge/Länge
if (drehzahl_aktuell <= drehzahl_schaltpunkte[i]) {
index_drehzahl = i-1;
break;
}
}
// Index des Drehzahlbreakpoints ermitteln um mit diesem den drehzahl_einspritzwert aus dem array zu finden ENDE
// Einspritzwert aus array: drehzahl_einspritzwert ermitteln um mit diesem den drehzahl_einspritzwert aus dem array zu finden ANFANG
drehzahl_einspritzwert_tmp = drehzahl_einspritzwert [index_drehzahl];
// Einspritzwert aus array: drehzahl_einspritzwert ermitteln um mit diesem den drehzahl_einspritzwert aus dem array zu finden ENDE
// Index des tps_schaltpunkte breakpoints ermitteln um mit diesem den tps_einpsritzfaktor aus dem array zu finden ANFANG
//Umwandeln des TPS Signals in 0 bis 100 ANFANG
tps_auslesung = analogRead(tps_pin); //TPS Eingang Pin auslesen
tps_stellung = map(tps_auslesung, 0, 1023, 0, 100); // Auslesewert umwandeln in 0 bis 100
//Umwandeln des TPS Signals in 0 bis 100 ENDE
//int index_tps; //=Ergenis, ist der Indexwert bzw. die Position des breakepoints im array
for (int i=0; i<11; i++) { // i<11; Auszulesender array hat 11 Einträge/Länge
if (tps_stellung <= tps_schaltpunkte[i]) {
index_tps = i-1;
break;
}
}
// Index des tps_schaltpunkte breakpoints ermitteln um mit diesem den tps_einpsritzfaktor aus dem array zu finden ENDE
tps_wert_tmp = tps_einpsritzfaktor [index_tps]; // TPS Multiplikator ermitteln zum Errechnen der Einspritzzeit
einspritzzeit_micros = tps_wert_tmp * drehzahl_einspritzwert_tmp; //Einpritzzeit DAUER errechnen
// Funktion welche ausgeführt werden soll wenn der Lenkerschalterfür den Injektor2 auf EIN geschaltet ist und somit der 2. Injektor zusätzlich verwendet werden soll
if (digitalRead(injektor2_schalter)== HIGH) {
// injektor2_schalter_status auf 1 setzen
injektor2_schalter_status = 1;
}
// Funktion welche ausgeführt werden soll wenn der Lenkerschalterfür den Injektor3 auf EIN geschaltet ist und somit der 3. Injektor zusätzlich verwendet werden soll
if (digitalRead(injektor3_schalter)== HIGH) {
// injektor3_schalter_status auf 1 setzen
injektor3_schalter_status = 1;
}
// Funktion welche ausgeführt werden soll wenn der Lenkerschalter/Hauptschalter auf EIN geschaltet ist und somit die Einspritzung eingeschaltet ist
// if (digitalRead(hauptschalter_PIN)== HIGH) { // TEST IMMER AN
// hauptschalter_status auf 1 setzen
hauptschalter_status = 1;
// } // TEST IMMER AN
// Pumpe einschalten oder ausschalten ANFANG
if (hauptschalter_status == 1)
{
if (pumpe_an == 1)
{
digitalWrite(pumpe_pin, HIGH); // Pumpe Ein
}
else
digitalWrite(pumpe_pin, LOW); // Pumpe Aus
}
// Pumpe einschalten oder ausschalten ENDE
//
//Ausführung des Einpritzsignal
//injektor_pin = LOW; //Injektor Aus
if (hauptschalter_status == 1)
Serial.print("hauptschalter_status: ");
Serial.println(hauptschalter_status);
{
if (injektor_status == 1)
Serial.print("injektor_status: ");
Serial.println(injektor_status);
{
//Ausführung des Einpritzsignal wenn Hauptschalter EIN und Injektorstatus =1 Anfang
// anschaltszeit_einspritzung_micros = micros(); //Zeit speichern zu Beginn der Einpritzung
//ausschaltzeit_einspritzung_micros = einspritzzeit_micros + anschaltszeit_einspritzung_micros;
Serial.print("micros zum zeitpunkt Ausführung code: ");
Serial.println(micros());
if (micros()< ausschaltzeit_einspritzung_micros )
{
digitalWrite(injektor_pin_1, HIGH); // Injektor 1 Ein
Serial.print("Injektor1 Ein: ");
if (injektor2_schalter_status == 1){
digitalWrite(injektor_pin_2, HIGH); // Injektor 2 Ein
}
if (injektor3_schalter_status == 1){
digitalWrite(injektor_pin_3, HIGH); // Injektor 3 Ein
}
}
}
if (micros()> ausschaltzeit_einspritzung_micros )
{
digitalWrite(injektor_pin_1, LOW); // Injektor 1 Aus
digitalWrite(injektor_pin_2, LOW); // Injektor 2 Aus
digitalWrite(injektor_pin_3, LOW); // Injektor 3 Aus
injektor_status = 0; // Injektorstatus auf 0 setzen Der Injektorstatus ist die Anweisung, dass der Injektor angeschaltet sein soll
} //Ausführung des Einpritzsignal wenn Hauptschalter EIN und Injektorstatus =1 ENDE
}
} // Ende loop
//Funktion welche Ausgeführt wird, wenn das Timer interrupt ausgelöst wird-----------------------------Anfang
ISR(TIMER1_COMPA_vect) { //Interrupt at frequency of 20 Hz =50Millisekunden
//Drehzahlberechnung anhand der Variablen pickupsignalzaehler (Summe der Pickupsignale während der Zeitdauer von Timer interrupt zu Timer interrupt (HIER =50Millisekunden)
// Anzahl der Signale pro Umdrehung =2 , 50 Millisekunden pro Messung wie im Timersetup festgelegt, 60000 für Millisekuden in Minuten (pickupsignalzaehler / 50 / 2)*60000
Serial.print("pickupsignalzaehler: "); //zum Testen
Serial.println(pickupsignalzaehler); //zum Testen
drehzahl_aktuell= (((pickupsignalzaehler / 50)/2)*60000);
pickupsignalzaehler = 0; // PickupZähler für neue Messung zurücksetzen
}
//Funktion welche Ausgeführt wird, wenn das Timer interrupt ausgelöst wird-----------------------------Ende