/* * main.c / Tankanzeige2 * * Created: 1/9/2023 8:09:52 PM - Feb. 2023 * Author: Wulf D. */ #include #include #include #include #define Tank 0 // PWM Ausgang fuer die analoge Tankuhr #define UbTaster 4 // Doppelfunktion: Betriebsspannung messen (KL15 aus) und Tasterabfrage, ADC-Eingang #define Druck 2 // ADC-Eingang Drucksensor #define Luft 3 // Schaltausgang Luftpumpe #define LED_leer 1 // Schaltausgang LED, Tankwarnung #define ADCMUX_Druck 1 #define ADCMUX_UbTaster 1 #define ADCTRIGGER 30 /* ADC-Einheiten fuer Ereignis */ #define KEYSHORTTIME 50 /* Timerticks, je ca 12ms, eines kurzen Tastendrucks */ #define ADCSUM 8*ADCTRIGGER /* Ereignissumme */ #define ABGVEKTORDIM 20 /* Max Zahl der Stuetzstellen der Tankfuellung */ #define DRMITTELDIM 16 /* Stuetzstellenzahl Mittelwertbildung */ #define TIMEIRQ 8 /* Multiplikator Timerticks bis 1/10s */ /* key task Byte */ #define keypressed 0 #define keyshort 1 #define keylong 2 #define abgleichDa 3 #define abgleichImGang 4 #define pumpeImGang 5 #define messungStehtAn 6 #define initerror 7 /* task Byte */ #define adctst 0 #define UbEinbruch 1 #define pwmupdate 2 #define pumpcycle 3 #define mittelwert 4 /* OCR0A Wert der PWM mit Zeigerreaktion 64 erste Zeigerreaktion 76 0 - Linie Diff 12 84 1/8 8 92 1/4 8 98 3/8 6 104 1/2 6 111 5/8 9 120 3/4 11 132 7/8 12 161 voll 29 190 zeigerstrichbreit über voll */ const uint8_t anzArray[] PROGMEM={64,76,84,92,98,104,111,120,132,161,190}; void timer_setup(void); void adc_setup(void); void adctest(void); void tstkeyrelease(void); void pumpe(void); void pumpezyk(void); void messung(void); void mittelwertbildung(void); int16_t tankkurve (uint8_t druck); uint8_t anzeigekurve (int16_t tankwert); uint16_t ticker,sec=0,zeitstempel,keytime,pumpenzeit; int16_t test16; /* bildet den berechneten PWM-Wert für die Stromquelle des Anzeigeinstruments ab */ uint8_t intr_count=0,intr_c10=0, pumpzyklus, blinkzyklus; uint8_t adcDruck; /* gemittelter Druckwert vom ADC */ uint8_t adcUbtast,adcTrigger,adcUbtasta[8],TastVeri,UbLowVeri,adcindex; uint8_t key, task; /* Task-Bytes */ uint8_t indexdr=DRMITTELDIM-1; uint8_t indexab, abgvektor[ABGVEKTORDIM],drmittel[DRMITTELDIM]; /*RAM-Schatten des eeabpara, ADC-Druckmittelwerte*/ uint8_t eeabzahl EEMEM; /* Zahl der Tank-Kallibrierungs-Stuetzstellen */ uint8_t eeabpara[ABGVEKTORDIM] EEMEM; /* Tankstuetzstellen im EEPROM der Kallibrierung */ int main(void) { DDRB |= (1<ABGVEKTORDIM || indexab<3) {indexab=ABGVEKTORDIM; key |= (1 << initerror); DDRB &= ~(1<adcUbtasta[i-1])stetig=0; } if (sum<5) { key |= (1 << keypressed); keytime=ticker; } else if (stetig) { task |= (1 << UbEinbruch); key &= ~(1 << keypressed)|(1<400) task &= ~(1 << adctst); } /* ADC wird sowohl fuer die Druckmessung, der Unterspannungserkennung als auch zur Taster-Erkennung genutzt. Die Doppelbelegung Taster vs Unterspannung liegt auf dem selben Eingang und muss durch Verhalten unterschieden werden. Das erfolgt hauptsaechlich in Funktion adctest */ ISR (ADC_vect) /* ADC Conversion ready */ { if (ADMUX==0xA1) { adcUbtast = ADCH; ADMUX=0xA2; // Aufzeichnung bei starkem ADC-Abfall, um Tastendruck bzw KL15-aus. if ((ADCH=ADCTRIGGER) adcTrigger=0; } else { drmittel[indexdr]=ADCH; if (!indexdr) {indexdr=DRMITTELDIM; task |= (1<1024 Werte sind möglich. */ int16_t tankkurve (uint8_t druck) { uint8_t i; int16_t z, n, q, scale; for (i=0; i=indexab) i=indexab-1; scale=1152/(indexab-1); z=druck-abgvektor[i-1]; n=abgvektor[i]-abgvektor[i-1]; q = (z*scale)/n; q = q+scale*(i-1); return q; } /* Bildet den linearisierten Fuellstand des Tanks auf den Wertebereich der PWM der Tankuhr-Ansteuerung ab. Die Eichkurve anzArray der Anzeige wurde optisch in 8 Fuellständen von 0 bis F, plus zwei Staenden Zeiger bewegt sich gerade und Zeiger ein Strich ueber voll, optisch ermittelt und im Programmspeicher statisch abgelegt. Abschnittsweise linearisiert, da die PWM-Ansteuerung mit Stromquelle sowohl Offset hat als auch nach oben hin deutlich nichtlinear ist. Auf "optische Reserve" ausgelegt, d.h. ganz leer ist Linksanschlag <0. */ uint8_t anzeigekurve (int16_t tankwert) { int8_t i; int16_t rest,z,q; if ( (key & (1<9) i=9; z=anzArray[i+1]-anzArray[i]; q=z*rest/128; q=q+anzArray[i]; return (uint8_t)q; } void mittelwertbildung (void) { uint16_t sum=0; task &= ~(1< 50) // magic number! { // Taste geloest if (ticker-keytime2 ) { eeprom_write_byte (&eeabzahl, indexab); eeprom_write_block (abgvektor, eeabpara, indexab); key &= ~(1 << initerror); } } else { PORTB|=(1<pumpenzeit) { key &= ~((1<pumpenzeit) { task &= ~(1<pumpenzeit) { if ( key & (1<111) task &= ~(1<