Forum: Mikrocontroller und Digitale Elektronik Hilfe gegen Bares


von He G. (dare)


Lesenswert?

Hi!
Ich habe hier ein Bordcomputer-Projekt mit einem Atmega. Für sich 
funktioniert das alles schon. Am Netzteil sogar so, wies soll. Es gibt 
noch ein paar kleine Probleme, welche ich in den Griff bekommen muss.
Das Problem ist, dass ich extrem unter Zeitdruck stehe, da der Urlaub 
vor der Tür steht und ich das nicht nur für mich sondern auch für ein 
paar Bekannte entwickle, die ihre Bauteile und die Platine bezahlt haben 
und nun gespannt warten.
Ich suche jemanden, der den Quelltext und die Schaltpläne/das Layout 
(von der Platine gibts keinen Schaltplan) durchgeht und das ganze 
optimiert und in Ordnung bringt. Natürlich sollen die Probleme gelöst 
werden.
Themen sind der AC um bei Spannungsabfall ins EEPROM zu speichern und 
Frequenzmessung.
Ich suche niemanden, der sich des Projekts Tagelang annimmt (dafür ist 
auch gar kein Geld da) sondern jemanden, der weiß, was er tut und 
unproblematisch schnell ein paar Änderungen macht. Das Ganze läuft eher 
unter dem Aushängeschild "Hilfe gegen Aufwandsentschädigung" als 
"Ingenieurleistung gegen horrenden Stundensatz".
Ich bin grad echt in der Klemme. Wär cool, wenn sich jemand meldet.
dare_@gmx.de
Vielleicht noch kurz hier eine Nachricht, falls die Mail verloren geht.
Hat jemand Zeit und Lust?
Vielen, vielen Dank!
H.

von He G. (dare)


Lesenswert?

keiner? :(

von Schlurch (Gast)


Lesenswert?

>Ich bin grad echt in der Klemme.

Verschiebe Deinen Liefertermin auf Weihnachten und mache in Ruhe Deinen 
Urlaub.
Vielleicht lösen sich danach die "paar kleinen Probleme" von ganz 
alleine.

von He G. (dare)


Lesenswert?

lol, das war ein konstruktiver vorschlag ;)

von Schlurch (Gast)


Lesenswert?

lol hin - lol her. Das ist Lebenserfahrung :-)

von gast (Gast)


Lesenswert?

... Ich suche jemanden, der den Quelltext und die Schaltpläne/das Layout
(von der Platine gibts keinen Schaltplan) durchgeht...

Wie soll man dann die Hardware Debuggen ???

von He G. (dare)


Lesenswert?

Meine Lebenserfahrung sagt, dass man nach ner Weile projektblind wird 
und es immer jemanden gibt, der gut genug ist, die letzten Probleme 
rauszubügeln. Ich hab früher als Webentwickler gearbeitet und da wars an 
der Tagesordnung in der Nacht vor der Abgabe noch Gas zu geben. Geklappt 
hats immer.
Wenn jemand wie Falk oder so mir zwei,drei Stunden widmen würden, dann 
wäre das Ding sicher durch.
Bilex hat halt 5 Wochen gebraucht um zu liefern (scheiss Post in 
Bulgarien) und der Proto lief schon. Hab noch etliches umgestrickt. Mein 
Hauptproblem heisst ohnehin AC. Der Interrupt wird ständig ausgelöst, 
wenn das Ding samt Messschaltungen am Roller hängt. Ohne Messchaltungen 
geht das.
Der Rest ist nur noch ein wenig Entstörung (der INT0 Interrupt wird ab 
und an ausgelöst ohne das ein Tachosignal eingeht, ebenso die Taster).
Temperaturmessung läuft fehlerfrei, Menu, Distanzen, Warnfunktion etc. 
auch.
Den Code und die Schaltung kann man sicher noch optimieren aber das sind 
die Hauptprobleme. Am Netzteil läuft alles zu meiner Zufriedenheit.
Irgendwie sinkt der Vergleichswert am Roller aber offensichtlich ständig 
unter den Sollwert wenn die Messchaltungen dranhängen. Aber ich muss die 
Daten ja irgendwie speichern...
Irgendjemand mehr anzubieten als gute Ratschläge? Ein bisschen Schaltung 
durchsehen, ein paar Zeilen C-Code überarbeiten und vielleicht Dinge 
sinnvoller gestalten und mir was dazu sagen, wie ich die Probleme aus 
der Welt bekomme - mehr verlange ich ja gar nicht. Und über den Preis 
kann man ja reden...

von He G. (dare)


Lesenswert?

Die Hardware debuggen? Nun, das Platinen-layout ist nicht so ne 
riesen-Herausforderung. Ich lese sowas sogar lieber als Schaltpläne. 
Alles Pinkompatibel und so. Ist aber auch nur die Grundbeschaltung des 
Megas und ein paar Pfostenbuchsen. Der Rest ist als Schaltplan 
vorhanden. Das geht schon.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ein Erfahrungswert: in 10% der Zeit wird ein Projekt zu 90% fertig.
Für die restlichen 10% des Projekts werden 90% der Zeit gebraucht.

Das Fazit daraus: dein Projekt ist zu 90% fertig (Zitat: nur noch ein 
paar kleine Probleme) und du hast erst 10% der Gesamtzeit verbraucht...

Wenn du also seit 1 Monat daran sitzt, dann wirst du noch weitere 9 
Monate brauchen... ;-(


>Den Code und die Schaltung kann man sicher noch optimieren...
Wenn du in einer "verseuchten" Umgebung unterwegs bist, dann vergiss es, 
einfach so z.B. einen Interrupt zum Zählen zu nehmen, der Zählimpuls 
muss vorher noch entprellt werden (Tachosignal, ebenso die Taster). Am 
einfachsten geht das per Software (die Hardware ist eh schon fertig).

>Mein Hauptproblem heisst ohnehin AC.
Nur für den Fall, dass ich das nicht ganz kapiere: was ist dieses AC?
All Clear? Alternating Current? Absolutes Chaos?

von He G. (dare)


Lesenswert?

AC ist ein Analog Comparator. Er vergleicht zwei Spannungen. Dazu gibts 
hier schon nen Thread. Kurz: VCC-Diode-Ua(Verbraucher). VCC-Diode-dicker 
ElKo-Ub(Atmega & Quarz). Damit geht man an die Pins AIN0 und AIN1. Sinkt 
nun Ua an AIN1 unter Ub an AIN0, dann kann man einen Interrupt auslösen. 
Zweck der Maßnahme ist, bei Spannungswegfall Messdaten ins EEPROM zu 
schreiben. Geht halt am Netzteil total toll. Nur ohne diese schicke 
Spannungsversorgung bricht Ua alle Nase lang ein und der Interrupt wird 
ausgelöst. Ach, was hilfts lange drüber zu reden. Hab noch ein paar 
Idee, die Teste ich jetzt noch eben.
Grüße!

von spess53 (Gast)


Lesenswert?

Hi

>Am Netzteil läuft alles zu meiner Zufriedenheit.

Aber nicht im Auto. Dafür ist den Schaltung absolut ungeeignet. Oder 
glaubst du deine Stromversorgung kommt mit Transienten von +/- 100V 
zurecht.

MfG Spess

von He G. (dare)


Lesenswert?

Nun, immerhin tut sie das, soweit das den Atmega, das Display, die 
Temperaturauswertung und (mit kleinen Einschränkungen) Drehzahl- und 
Geschwindigkeitserfassung angeht.

von He G. (dare)


Lesenswert?

by the way... es gibt threads in denen meine probleme erörtert wurden. 
hier gehts darum, dass ich an meine grenzen stoße und keine zeit habe, 
sie in time zu erweitern. darum suche ich jemanden, der deutlich mehr 
kann (was nicht schwer ist) und das in die hand nimmt. wenn die 
schaltung der spannungsversorgung so daneben wäre, dann würde wohl kaum 
laufen was läuft.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>Analog Comparator
Ja, den kenne ich...

>dann würde wohl kaum laufen was läuft.
Dein Problem ist ja nicht das Laufen, sondern das Abschalten 
(Powerfail).

>Sinkt nun Ua an AIN1 unter Ub an AIN0,
>dann kann man einen Interrupt auslösen.
Diese Interrupt-Verwenderei bei Ereignissen, die im ms-Bereich 
interessant sind, macht eben mehr Aufwand. Wieso innerhalb von 
µs-Bruchteilen auf etwas reagieren, das sowieso erst in ein paar ms 
interessant wird ("dicker Elko"). Solche Signale gehören gepollt, dann 
sind sie auch leicht zu entprellen.

Hast du auch irgendwelche zeitlichen Vorstellungen
- wie lange stützt dein "dicker Kondensator" die Spannung?
- wieviele Bytes willst du dann noch schreiben, wie lange dauert das?
- kannst du nach dem Powerfail noch irgendwelche  Verbraucher
  abschalten, um Zeit zu gewinnen?
Daraus ergibt sich dann, wie lange du maximal warten kannst, bis du 
wirklich auf dein Powerfail-Signal vom AC reagierst und den 
Speichervorgang startest.

Die Fehler, die du beschreibst, können (großteils) mit Software 
"ausgebügelt" werden. Nur braucht man dazu eben das komplette System, 
also deine Schaltung und deine Umgebung.

@Spess
>Aber nicht im Auto...
Da wäre es ja noch einfach.
Hier geht es um einen Roller  ;-)

von Christian (Gast)


Lesenswert?

Poste doch erstmal den ganzen spaß, wenn sich einer was angucken soll, 
darfst du Ihn nicht im dunklen lassen.

von He G. (dare)


Angehängte Dateien:

Lesenswert?

Ok... Los gehts. Ist vom Rumprobieren noch ein bisschen Müll drin und so 
richtig der Hit ist das natürlich auch nicht.


main.c
1
#include "lcd.h"
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include "functions.h"
5
#include <avr/interrupt.h>
6
#include <avr/eeprom.h>
7
8
//global vars
9
  uint16_t EEMEM eeKM;
10
  uint16_t EEMEM eeM;
11
  uint16_t EEMEM eeDKM;
12
  uint16_t EEMEM eeMaxTemp;
13
  uint16_t EEMEM eeWarnTemp;
14
  uint16_t EEMEM eeRadUmfang;
15
  uint16_t EEMEM eeIgnitions;
16
    uint16_t iWarnTemp;
17
      uint16_t iKM;
18
    uint16_t icm;
19
    uint16_t iM;
20
    uint16_t iMaxTemp;
21
    uint16_t iDKM;
22
    uint16_t iRadUmfang;
23
    uint16_t iIgnitions;
24
  uint16_t iRPM=0;
25
  volatile uint16_t iV=0;
26
  uint16_t iTemp;
27
  volatile uint16_t speedvar=0;
28
  volatile uint16_t tachoold=0;
29
  volatile uint16_t tachonew=0;
30
  uint16_t dzmold=0;
31
  uint16_t dzmnew=0;
32
  uint16_t dzmvar=0;
33
  uint16_t tachosignale;
34
  char scenario;
35
  char dzmflag;
36
  char lcdon=0;
37
38
ISR(TIMER1_OVF_vect) 
39
{
40
  
41
}
42
43
ISR(TIMER0_OVF_vect) 
44
{  
45
  dzmflag=1;
46
  dzmnew=TCNT1/10;
47
  if(dzmold!=0)
48
  {
49
    if(dzmnew>dzmold)  dzmvar=dzmnew-dzmold;
50
    else dzmvar=6553-dzmold+dzmnew;
51
    iRPM=9830/(dzmvar/100); 
52
  }
53
  dzmold=dzmnew;
54
}
55
56
57
58
ISR(INT0_vect)
59
{
60
  tachosignale++;
61
  tachonew=TCNT1/10;
62
  if(tachoold!=0)
63
  {
64
    if(tachonew>tachoold)  speedvar=tachonew-tachoold;
65
    else speedvar=6553-tachoold+tachonew;
66
    iV=(iRadUmfang*59)/(speedvar); 
67
  }
68
  tachoold=tachonew;
69
}
70
71
72
ISR ( ANA_COMP_vect )
73
{
74
   eeprom_write_word(&eeKM, iKM);
75
  eeprom_write_word(&eeM, iM);
76
  eeprom_write_word(&eeDKM, iDKM);
77
  eeprom_write_word(&eeMaxTemp, iMaxTemp);
78
  lcd_bel(0);
79
  lcdon=0;
80
  lcd_clrscr();
81
  _delay_ms(5);
82
  lcd_puts("datasave");  
83
  lcd_bel(1);
84
  _delay_ms(2000);
85
  lcd_clrscr();
86
}
87
88
89
int main(void)
90
{
91
92
_delay_ms(1000);
93
94
//Portrichtungsregister setzen
95
  DDRA |= (1 << DDA1) | (1 << DDA2); //a0 data eingang, a1 cs ausg, a2 clk ausg 
96
  PORTA &= (1<<PA0); //internen pull up aktivieren
97
  DDRC |= (1<<PC7); //lcd bel pin
98
  DDRB  |= (1<<DDB0);// | (1<<DDB2) | (1<<DDB3);  //b0 als eingang für dzm, b2,3 für ac
99
  PORTB |= (1<<PB0) | (1<<PB2);    //internen pull up aktivieren
100
//  DDRD  |= (1<<DDD2);
101
  PORTD |= (1<<PD2);
102
  
103
104
//deactivate interrupts
105
  cli();
106
107
108
109
//load var from eeprom
110
    iKM = eeprom_read_word(&eeKM);
111
    iM = eeprom_read_word(&eeM);
112
  iMaxTemp = eeprom_read_word(&eeMaxTemp);
113
  iDKM= eeprom_read_word(&eeDKM);
114
  iRadUmfang=eeprom_read_word(&eeRadUmfang);
115
  iIgnitions=eeprom_read_word(&eeIgnitions);
116
  iWarnTemp=eeprom_read_word(&eeWarnTemp);
117
118
//check if var is bogus and set 0 then
119
  if(iKM==0xFFFF){iKM=0;eeprom_write_word(&eeKM,0);}
120
  if(iM==0xFFFF){iM=0;eeprom_write_word(&eeM,0);}
121
  if(iMaxTemp==0xFFFF){iMaxTemp=0;eeprom_write_word(&eeMaxTemp,0);}
122
  if(iDKM==0xFFFF){iDKM=0;eeprom_write_word(&eeDKM,0);}
123
  if(iRadUmfang==0xFFFF){iRadUmfang=50;eeprom_write_word(&eeRadUmfang,50);}
124
  if(iIgnitions==0xFFFF){iIgnitions=1;eeprom_write_word(&eeIgnitions,1);}
125
  if(iWarnTemp==0xFFFF){iWarnTemp=1500;eeprom_write_word(&eeWarnTemp,1500);}
126
127
128
129
130
131
//displaybeleuchtung an
132
  lcd_bel(1);lcdon=1;
133
//zeit fürs display aufzuwachen
134
  _delay_ms(50);
135
//lcd init
136
  _delay_ms(50);
137
  lcd_init(LCD_DISP_ON);
138
  _delay_ms(50);
139
  lcd_clrscr();
140
//welcome screen
141
  _delay_ms(50);    
142
  lcd_puts("   VesCom 1.0   ");
143
  _delay_ms(1000);
144
  lcd_gotoxy(0, 1);
145
  _delay_ms(5);
146
  lcd_puts("    by  dare");
147
  _delay_ms(3000);
148
  lcd_clrscr();  
149
150
151
//start timer for systemtime ( 16384 hz)
152
   TCCR1B = (1<< CS12);
153
//set interrupt for dzm timer
154
  TIMSK |= (1<<TOIE0);
155
//timer0 vorladen
156
  TCNT0=246;
157
158
//start timer for dzm
159
  TCCR0 |= (1<<CS02) | (1<<CS01);  
160
161
162
163
//steigende/fallende? flanke löst interrupt aus
164
  MCUCR |= (1<<ISC01);
165
//enable interrupt on int0
166
  GIMSK |= (1<<INT0);
167
168
169
//startscenario
170
  scenario=1;
171
172
//set ac for power loose interrupt
173
//  ACSR = (1 << ACIE) | (1 << ACIS1); 
174
175
176
//activate interrupts
177
  sei();
178
179
180
181
182
for(;;)
183
  {
184
185
  dzmflag=0;
186
//put temp in iTemp
187
  fReadTemp(&iTemp); 
188
//temp warning function
189
  if(iTemp>=iWarnTemp) 
190
  {
191
    if(lcdon==1)
192
    {
193
      lcd_bel(0); 
194
      lcdon=0;
195
    }else 
196
    {
197
      lcd_bel(1);
198
      lcdon=1;
199
    }
200
  } else lcd_bel(1);
201
202
  
203
//maxtemp
204
  if(iTemp>iMaxTemp){eeprom_write_word(&eeMaxTemp,iTemp);iMaxTemp=iTemp;}
205
206
//werte ausgeben
207
  fOutput(scenario,iV,iRPM,iTemp,iMaxTemp,iKM,iM,iDKM); 
208
209
  for(uint16_t i=0;i<40000;i++)
210
    {
211
      if (fdebounce(&PINA, PA4)==1) {if(scenario>5)scenario=1; else scenario++; lcd_clrscr();}
212
      if (fdebounce(&PINA, PA3)==1) 
213
      {   
214
        eeprom_write_word(&eeKM, iKM);
215
        eeprom_write_word(&eeM, iM);
216
        eeprom_write_word(&eeDKM, iDKM);
217
        eeprom_write_word(&eeMaxTemp, iMaxTemp);
218
        menu(&eeDKM,&eeMaxTemp,&eeIgnitions,&eeWarnTemp,&eeRadUmfang);
219
      }
220
    }
221
  
222
  icm+=tachosignale*iRadUmfang;
223
  if(tachosignale==0)iV=0;
224
  tachosignale=0;
225
  while(icm>=100){iM++;icm-=100;}
226
  if(iM>=1000){iKM++; iDKM++; iM-=1000;}
227
  if(dzmflag==0)iRPM=0;
228
229
  }
230
return 0;
231
}

functions.c
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include "lcd.h"
4
#include <stdlib.h>
5
#include <string.h>
6
#include <avr/eeprom.h>
7
#include "functions.h"
8
#include <avr/wdt.h>
9
#include <avr/interrupt.h>
10
11
void menu(uint16_t *eeDKM,uint16_t *eeMaxTemp,uint16_t *eeIgnitions,uint16_t *eeWarnTemp,uint16_t *eeRadUmfang)
12
{
13
  lcd_bel(1);
14
  _delay_ms(5);
15
  lcd_clrscr();
16
17
  char menu=0;
18
  uint8_t state=1;
19
  uint16_t radumfang= eeprom_read_word(eeRadUmfang);
20
  uint16_t warntemp=eeprom_read_word(eeWarnTemp);
21
  while(menu<1)
22
  {
23
24
      switch(state)
25
      {
26
        case 1:
27
            _delay_ms(5);
28
            lcd_gotoxy(0, 0);
29
            _delay_ms(5);
30
            lcd_puts("Menu:");
31
            _delay_ms(5);
32
            lcd_gotoxy(0, 1);
33
            _delay_ms(5);
34
            lcd_puts(" ->, X   ");
35
            while(state<2)
36
            {
37
              if (fdebounce(&PINA, PA4)==1) state=2;
38
              if (fdebounce(&PINA, PA3)==1) 
39
              {
40
                cli();wdt_enable (WDTO_15MS);while (1); //atmega abschiessen
41
              }
42
            }
43
        break;
44
45
        case 2:
46
          _delay_ms(5);
47
          lcd_gotoxy(0,1);
48
          _delay_ms(5);
49
          lcd_puts("Tag-Km=0");
50
          while(state<3)
51
          {
52
            if (fdebounce(&PINA, PA3)==1) eeprom_write_word(eeDKM, 0);
53
            if (fdebounce(&PINA, PA4)==1) state=3;
54
          }
55
        break;
56
57
        case 3:
58
          _delay_ms(5);
59
          lcd_gotoxy(0,1);
60
          _delay_ms(5);
61
          lcd_puts("MxTemp=0");
62
          while(state<4)
63
          {
64
            if (fdebounce(&PINA, PA3)==1) eeprom_write_word(eeMaxTemp, 0);
65
            if (fdebounce(&PINA, PA4)==1) state=4;
66
          }
67
        break;
68
69
        case 4:
70
          while(state<5)
71
          {
72
          int ign=eeprom_read_word(eeIgnitions);
73
          _delay_ms(5);
74
          lcd_gotoxy(0,1);
75
          _delay_ms(5);
76
77
            if(ign==1)lcd_puts("Znd/U: 1"); 
78
              else lcd_puts("Znd/U: 2");
79
            if (fdebounce(&PINA, PA3)==1) 
80
            {
81
              if(ign==1) eeprom_write_word(eeIgnitions, 2);
82
              else eeprom_write_word(eeIgnitions, 1);
83
            }
84
            if (fdebounce(&PINA, PA4)==1) state=5;
85
            _delay_ms(10);
86
          }
87
        break;
88
89
        case 5:
90
    
91
          while(state<6)
92
          {          
93
            _delay_ms(5);
94
            lcd_gotoxy(0,1);
95
            _delay_ms(5);
96
            char out1[3];
97
            itoa(radumfang,out1,10);
98
            char out2[8];
99
            strcpy(out2,"Umfa:");
100
            if(radumfang<100) strcat(out2," ");
101
            if(radumfang<10) strcat(out2," ");
102
            strcat(out2,out1);
103
            lcd_puts(out2);
104
            if (fdebounce(&PINA, PA3)==1) 
105
            {
106
              if(radumfang<200) radumfang++;
107
              else radumfang=1;
108
            }
109
                  
110
            if (fdebounce(&PINA, PA4)==1) 
111
            {
112
              state=6;
113
              eeprom_write_word(eeRadUmfang,radumfang);              
114
            }
115
            _delay_ms(10);
116
          }
117
        break;
118
119
        case 6:
120
          
121
          while(state<7)
122
          {
123
            _delay_ms(5);
124
            lcd_gotoxy(0,1);
125
            _delay_ms(5);
126
            char out1[4];
127
            itoa(warntemp,out1,10);
128
            char out2[9];
129
            strcpy(out2,"WTp:");
130
            if(warntemp<1000) strcat(out2," ");
131
            if(warntemp<100) strcat(out2, " ");
132
            if(warntemp<10) strcat(out2, " ");
133
            
134
            
135
            strcat(out2,out1);
136
            
137
            lcd_puts(out2);
138
            
139
            if (fdebounce(&PINA, PA3)==1) 
140
            {
141
              if(warntemp<1200) warntemp+=5;
142
              else warntemp=1;
143
            }
144
                  
145
            if (fdebounce(&PINA, PA4)==1) 
146
            {
147
              eeprom_write_word(eeWarnTemp, warntemp);
148
              state=7;
149
            }
150
              
151
            _delay_ms(10);
152
          }
153
        break;
154
155
        default:
156
          state=1;
157
        break;
158
      }
159
160
161
  }
162
}
163
164
165
166
167
uint8_t fdebounce(volatile uint8_t *port, uint8_t pin)
168
{
169
    if ( ! (*port & (1 << pin)) )
170
    {
171
      _delay_ms(50); 
172
        _delay_ms(50); 
173
        if ( *port & (1 << pin) )
174
        {
175
            _delay_ms(50);
176
            _delay_ms(50); 
177
            return 1;
178
        }
179
    }
180
    return 0;
181
}
182
183
184
void fOutput(char scenario,uint16_t iV,uint16_t iRpm,uint16_t iTemp,uint16_t iMaxTemp,uint16_t iKM,uint16_t iM, uint16_t iDKM)
185
{
186
  char sSpeed[8];
187
  char sRpm[8];
188
  char sTemp[8];
189
  char sMaxTemp[8];
190
  char sDKM[8];
191
  char sKM[8];
192
193
  uint8_t iStrLen;
194
  
195
//Speed
196
197
  iStrLen=0;
198
  char sV2[8];
199
  itoa(iV,sV2,10); //int to string
200
  iStrLen=5-strlen(sV2); //how many spaces to add?
201
202
  strcpy(sSpeed,"V:");
203
  while(iStrLen>0)
204
  {
205
    strcat(sSpeed," ");
206
    iStrLen=iStrLen-1;
207
  }
208
  strcat(sSpeed,sV2);
209
//  sSpeed[7]='\0';
210
211
212
213
//Rpm
214
  iStrLen=0;
215
  char sRPM2[8];
216
  itoa(iRpm,sRPM2,10); //int to string
217
  iStrLen=5-strlen(sRPM2); //how many spaces to add?
218
  
219
  strcpy(sRpm,"U:");
220
  while(iStrLen>0)
221
  {
222
    strcat(sRpm," ");
223
    iStrLen=iStrLen-1;
224
  }
225
  strcat(sRpm,sRPM2);
226
227
//Temp
228
  iStrLen=0;
229
  char sTemp2[8];
230
  itoa(iTemp,sTemp2,10); //int to string
231
  iStrLen=4-strlen(sTemp2); //how many spaces to add?
232
  strcpy(sTemp,"Tp:");
233
234
  while(iStrLen>0)
235
  {
236
    strcat(sTemp," ");
237
    iStrLen=iStrLen-1;
238
  }
239
  strcat(sTemp,sTemp2);
240
241
242
//MaxTemp
243
  iStrLen=0;
244
  char sMT2[8];
245
  itoa(iMaxTemp,sMT2,10); //int to string
246
  iStrLen=4-strlen(sMT2); //how many spaces to add?
247
  strcpy(sMaxTemp,"mT:");
248
249
  while(iStrLen>0)
250
  {
251
    strcat(sMaxTemp," ");
252
    iStrLen=iStrLen-1;
253
  }
254
  strcat(sMaxTemp,sMT2);
255
256
257
//Distance
258
  char sMeter[8];
259
  uint8_t iMeter=iM/100;
260
  itoa(iMeter,sMeter,10);
261
  char sKilom[8];
262
  itoa(iKM,sKilom,10);
263
  iStrLen=5-strlen(sKilom); //how many spaces to add?
264
  strcpy(sKM,"");
265
  while(iStrLen>0)
266
  {
267
    strcat(sKM," ");
268
    iStrLen=iStrLen-1;
269
  }
270
  strcat(sKM,sKilom);
271
  strcat(sKM,".");
272
  strcat(sKM,sMeter);
273
274
//Tageskilometer
275
  iStrLen=0;
276
  char sDKM2[8];
277
  itoa(iDKM,sDKM2,10); //int to string
278
  iStrLen=5-strlen(sDKM2); //how many spaces to add?
279
  strcpy(sDKM,"D:");
280
  while(iStrLen>0)
281
  {
282
    strcat(sDKM," ");
283
    iStrLen=iStrLen-1;
284
  }
285
  strcat(sDKM,sDKM2);
286
  
287
288
289
290
291
  char ol[7];
292
  char or[7];
293
  char ul[7];
294
  char ur[7];
295
296
  switch(scenario)
297
  {
298
299
    case 1:
300
      strcpy(ol,sSpeed);
301
      strcpy(or,sRpm);
302
      strcpy(ul,sKM);
303
      strcpy(ur,sTemp);
304
    break;
305
306
    case 2:
307
      strcpy(ol,sSpeed);
308
      strcpy(or,sRpm);
309
      strcpy(ul,sMaxTemp);
310
      strcpy(ur,sTemp);
311
    break;
312
313
    case 3:
314
      strcpy(ol,sSpeed);
315
      strcpy(or,sRpm);
316
      strcpy(ul,sKM);
317
      strcpy(ur,sDKM);
318
    break;
319
320
    case 4:
321
      strcpy(ol,sSpeed);
322
      strcpy(or,"       ");
323
      strcpy(ul,sRpm);
324
      strcpy(ur,"       ");
325
    break;
326
327
    default:
328
      strcpy(ol,sSpeed);
329
      strcpy(or,sRpm);
330
      strcpy(ul,sKM);
331
      strcpy(ur,sTemp);
332
    break;
333
  }
334
335
  lcd_gotoxy(0,0);
336
  _delay_ms(5);
337
  lcd_puts(ol);
338
  _delay_ms(5);
339
  lcd_gotoxy(7,0);
340
  _delay_ms(5);
341
  lcd_puts("  ");
342
  _delay_ms(5);
343
  lcd_gotoxy(9,0);
344
  _delay_ms(5);
345
  lcd_puts(or);
346
  _delay_ms(5);
347
  lcd_gotoxy(0,1);
348
  _delay_ms(5);
349
  lcd_puts(ul);
350
  lcd_gotoxy(7,1);
351
  _delay_ms(5);
352
  lcd_puts("  ");
353
  _delay_ms(5);
354
  _delay_ms(5);
355
  lcd_gotoxy(9,1);
356
  _delay_ms(5);
357
  lcd_puts(ur);
358
359
}
360
361
362
void lcd_bel(char opt)
363
{
364
  if(opt==0)   PORTC &= ~(1<<PA7); //beleuchtung aus
365
  else PORTC |= (1<<PA7); //beleuchtung an
366
}
367
368
void fReadTemp(uint16_t *iTemp)
369
{
370
  PORTA |= (1<<PA1); //cs high for measure
371
  PORTA &= ~(1<<PA2); //clk low but dontcare
372
  _delay_ms(1);
373
  PORTA &= ~(1<<PA1); //cs low for data
374
  _delay_ms(1);
375
  PORTA |= (1<<PA2); //clk high 
376
  _delay_ms(1);
377
  PORTA &= ~(1<<PA2); //clk low
378
  _delay_ms(1);
379
  if ( PINA & (1<<PINA0) ) *iTemp=512; else *iTemp=0;
380
  _delay_ms(1);
381
  PORTA |= (1<<PA2); //clk high 
382
  _delay_ms(1);
383
  PORTA &= ~(1<<PA2); //clk low
384
  _delay_ms(1);
385
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+256;
386
  _delay_ms(1);
387
  PORTA |= (1<<PA2); //clk high 
388
  _delay_ms(1);
389
  PORTA &= ~(1<<PA2); //clk low
390
  _delay_ms(1);
391
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+128;
392
  _delay_ms(1);
393
  PORTA |= (1<<PA2); //clk high 
394
  _delay_ms(1);
395
  PORTA &= ~(1<<PA2); //clk low
396
  _delay_ms(1);
397
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+64;
398
  _delay_ms(1);
399
  PORTA |= (1<<PA2); //clk high 
400
  _delay_ms(1);
401
  PORTA &= ~(1<<PA2); //clk low
402
  _delay_ms(1);
403
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+32;
404
  _delay_ms(1);
405
  PORTA |= (1<<PA2); //clk high 
406
  _delay_ms(1);
407
  PORTA &= ~(1<<PA2); //clk low
408
  _delay_ms(1);
409
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+16;
410
  _delay_ms(1);
411
  PORTA |= (1<<PA2); //clk high 
412
  _delay_ms(1);
413
  PORTA &= ~(1<<PA2); //clk low
414
  _delay_ms(1);
415
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+8;
416
  _delay_ms(1);
417
  PORTA |= (1<<PA2); //clk high 
418
  _delay_ms(1);
419
  PORTA &= ~(1<<PA2); //clk low
420
  _delay_ms(1);
421
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+4;
422
  _delay_ms(1);
423
  PORTA |= (1<<PA2); //clk high 
424
  _delay_ms(1);
425
  PORTA &= ~(1<<PA2); //clk low
426
  _delay_ms(1);
427
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+2;
428
  _delay_ms(1);
429
  PORTA |= (1<<PA2); //clk high 
430
  _delay_ms(1);
431
  PORTA &= ~(1<<PA2); //clk low
432
  _delay_ms(1);
433
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+1;
434
435
  PORTA &= ~(1<<PA2); //clk low
436
  PORTA |= (1<<PA1); //cs high for measure
437
  PORTA &= ~(1<<PA2); //clk low but dontcare  
438
}

von He G. (dare)


Angehängte Dateien:

Lesenswert?

Und hier ist die Hauptplatine. Das rote sind Drahtbrücken. Liegt daran, 
dass ich nach der Fertigung noch etwas ändern musste. INT1 ist 
inzwischen auch freigeschaufelt und das Display hängt an einem anderen 
Pin aber das ja egal. Erwähne es nur, weil das in den Quellen schon so 
genutzt wird.

von He G. (dare)


Angehängte Dateien:

Lesenswert?

Dem Display vorgeschaltet ist eine kleine Platine mit nem Poti für den 
Kontrast und einem Transistor zum Schalten der Beleuchtung.
Am Connector wird Spannung über 4k7 R´s auf die Pins der Taster gegeben. 
Die Taster ziehen diese auf Masse. Zusätzlich hängt zur Entstörung noch 
je 1 100n C gegen Masse. Dann sind halt die Messschaltungen mit den Pins 
verbunden.

von Falk B. (falk)


Lesenswert?

@  He Gr (dare)

>Ok... Los gehts. Ist vom Rumprobieren noch ein bisschen Müll drin und so
>richtig der Hit ist das natürlich auch nicht.

Kleiner Tipp. Solche langen Quelltexte gehören in den Anhang!

MfG
Falk

von He G. (dare)


Lesenswert?

Ok, Danke!

von Stefan Salewski (Gast)


Lesenswert?

Autor:  Falk Brunner (falk) schrieb:

>Kleiner Tipp. Solche langen Quelltexte gehören in den Anhang!

Und die Hinweise auf Bildformate hast Du aufgegeben?

Hat auch keinen Sinn, die Leute werden nie begreifen, dass JPEG für 
Fotos gedacht ist.

von He G. (dare)


Lesenswert?

Hmm... wenn das Projekt hinter mir liegt, dann werde ich mich auch mal 
mit Bildkompressionsverfahren beschäftigen. Oder aber auch nicht. Als 
tif ist das Ganze 1MB gross. Als png immer noch knapp 5 mal so groß. Als 
gif noch immer 1,5 mal so groß. Und erkennen kann man auch alles. Wenn 
ich nen Server betreibe, dann bin ich zumindest daran interessiert, dass 
gepostete Dateien möglichst klein sind. Aber ich hab jetzt auch echt 
keinen Kopf für sowas. Ich merks mir und machs nächstes Mal wie 
gewünscht.

von Stefan Salewski (Gast)


Lesenswert?

>Als png immer noch knapp 5 mal so groß

Glaube ich nicht wirklich.

Eine typische Platine, in gut lesbarer Qualität, ist in PNG typisch so 
um die 50 kByte groß.

Natürlich, wenn man eine JPEG-Grafik mit ihren durch die 
verlustbehaftete Kompression generierten Artefakten nochmals nach PNG 
wandelt wird das Resultat kaum brauchbar sein.

Man muss die Grafik (Liniengrafik bzw. einfarbige Flächen) direkt als 
PNG abspeichern. (Wenn man Farbverläufe hat kann JPEG tatsächlich 
deutlich kleiner sein, aber Farbverläufe sollten in Schaltplänen und 
Platinenlayouts eigentlich nicht vorkommen.)

von He G. (dare)


Lesenswert?

Wie gesagt.. Ich setze das nächsten Mal so um. Ich mache das eh mit copy 
& paste in Irfanview - da ist das Abspeichern als png oder gif kein Akt.
Ich denke, ich versteh schon. Es ist bei diesen Formaten wohl möglich 
eine geringere Auflösung zu wählen weil sie hochwertigere Ergebnisse 
garantieren?!
Danke für den Hinweis.

von He G. (dare)


Angehängte Dateien:

Lesenswert?

Hier der Projektordner

von Falk B. (falk)


Lesenswert?

Schön, aber sollen wir nun raten an welchen Pins deine Taster und 
Drehzahl/Tachopulse dranhängen? Ich hab im Moment auch wenig Bock auf 
Reengineering.

Literaturempfehlung: Forum-Fragenformulierung

MFG
Falk

von Seppel (Gast)


Lesenswert?

Hallo

Also dein Eingang ist nicht gut gefiltert, der dicke Elko reicht nicht.

Verpolungsschutzdiode, Supressor-Diode, Drosseln(2Stk), Dicker Elko, 
kleiner Kerko (100N), dann der Linearregler, Elko, Kerko(100N).

Und prüf mal was auf deinem Komaratoreingang los ist.

Vor allem im Auto gibts Groudshifts,.... das Bordnetz ist total 
verseucht.

Und immer schön Kondensatoren an die Spannungs-Pins, zweilagig würde ich 
sowieso arbeiten, oben Vcc unten GND, gibt nen schönen Kondensator.

Und prüf mal deinen Takt,... .

Seppel

von Seppel (Gast)


Lesenswert?

P.S.

Du brauchst irgendwas filterndes an den Eingängen vom uC, ohne wird das 
im Auto nix.

von He G. (dare)


Lesenswert?

Oh, verzeihung.
Also:

Taster hängen an...
1
if (fdebounce(&PINA, PA4)==1)

A4

und...
1
if (fdebounce(&PINA, PA3)==1)

A3

Die Schaltung für die Drehzahl hängt an B0 (T0)
Die Schaltung fürs Tacho hängt an D2 (INT0)
Die Kommunikation mit dem Max-IC für das Thermoelement Typ K läuft über 
A0 (SO),A1(CS),A2(CLK)

von He G. (dare)


Lesenswert?


von Torsten S. (tse)


Lesenswert?

Also nach meiner bescheidenen Meinung ist in der ISR(ANA_COMP_vect) ganz 
großer Murks drin. Da wird ins Eeprom gelesen/geschrieben, auf das LCD 
zugegriffen usw. Um daß ganze noch zu toppen:

_delay_ms(2000);

Das ist grober Unfug, vorsichtig ausgedrückt.

Hast Du das selbst geschrieben?

von He G. (dare)


Lesenswert?

Nun. Das ist einfach nur da drin gelandet um zu debuggen. Wenn der 
Interrupt ständig getriggert wird, dann sind die 10000 Schreibzyklen 
schnell verbraucht. Außerdem will ich wissen, wann er ausgelöst wird. 
Das war die einfachste Lösung & funktioniert. Erstens wird verhindert, 
dass die Interruptroutine x Mal ausgeführt wird und zweitens seh ichs 
gleich auf dem Display. Wenn der Interrupt gewollt auftritt, dann ist 
das sowieso schnuppe, weil dann der Saft längst weg ist. Tritt er 
ungewollt auf, so bekomm ich das mit...

von Kachel-Heinz (Gast)


Lesenswert?

> dann sind die 10000 Schreibzyklen
> schnell verbraucht.

Vor jedem Schreiben den EEP lesen und vergleichen. Dann nur schreiben, 
wenn der Wert anders ist. Das spart schonmal einige unsinnige 
Schreibzyklen während des Debuggens oder bei Fehlern.

Falls es geholfen haben sollte verzichte ich trotzdem auf das "Bare".

Zum Programm sage ich weiter nix, C ist nicht mein Ding.

KH

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

Nur für alle, die es interessiert, womit man es bei der Stromversorgung 
aus dem Bordnetz zu tun hat.

MfG Spess

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Die Versorgung über Verpolungsschutz- und Entkopplungs-Diode und 
Brückengleichrichter ist schon was wert. Ausser den GND deiner Schaltung 
um 0,7V gegenüber der Masse des Mopeds anzuheben tut die Brücke nichts 
sinnvolles. Zusammen mit der Zündimpulsauswertung wie von dir angegeben 
kann das schon unerwartete Ergebnisse bringen. Schmeiß die Brücke raus 
und mach stattdessen Brücken vom Diode nach Plus und von Fahrzeugmasse 
nach Minus. Dann hast du wenigstens auf dem uC das gleiche Potential wie 
auf dem Rest des Rollers.

470uF sind nicht viel...
Mit der Näherungsformel C*dU = I*dt und dU ca. 12V-6V=6V und einer 
Stromaufnahme des uC von z.B. 50mA komme ich auf
dt = (470uF * 6V) / 50mA = knapp 60ms
Mit Backlight ist das noch etwas weniger....

Ich würde das sowieso und ganz anders machen...
Aber weil du in den Urlaub willst hilft vielleicht sowas:
:
ISR ( ANA_COMP_vect )
{                             // Murks!!! aber evtl. urlaubsfördernd:
  _delay_ms(1);               // nach Interrupt erst mal warten
  if(noch immer Powerfail)  { // Komparatorflag nochmal direkt abfragen
     lcd_bel(0);  // Powerfail --> Backlight aus, Strom sparen
     lcdon=0;
     eeprom_write_word(&eeKM, iKM);
     eeprom_write_word(&eeM, iM);
     eeprom_write_word(&eeDKM, iDKM);
     eeprom_write_word(&eeMaxTemp, iMaxTemp);
     :
  }
}
:

Aber wie gesagt: eigentlich solltest du nicht so extrem auf einen evtl. 
kurzen Spannungseinbruch reagieren. Sondern z.B. nur in der 
for(;;)-Schleife dauernd das Flag abfragen, entprellen und dann ggf. 
darauf reagieren. Dazu bräuchtest du allerdings einen ganz anderen 
Programmierstil, das geht nämlich nur, wenn du auch in absehbarer Zeit 
wieder mal an der Abfrage vorbeikommst....

SPS-Programme sind so aufgebaut.
1) Eingänge einlesen
2) Bearbeiten
3) Ausgänge schreiben
4) weiter bei 1)
Und das Bearbeiten bestimmt die Zykluszeit. Bei meinen Programmen achte 
ich darauf, dass ich nach spätestens 2ms mit einem Zyklus durch bin. 
Wenn ich z.B. eine Rechenaufgabe zu erledigen habe, die länger dauert, 
dann muss die unterbrechbar aufgebaut und in kleinen Häppchen ausführbar 
sein. Dann wird auch z.B. in jedem Zyklus 1 Zeichen auf das Display 
ausgegeben usw. usf. Und mit dem Beschreiben des EEPROMs muss ich nicht 
beginnen, wenn die vorherige Aktion auf dem EEPROM noch nicht beendet 
ist. Also gleich weiter im Programm.

Wenn du deine Programmierung so umstellst kommst du aber nicht mehr 
rechtzeitig in den Urlaub.... ;-)

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Sooo, hier mal eine erste Aufräumaktion. Naja, wir haben alle mal 
angefangen.

cli() am Anfang von main ist sinnlos, dort sind garantiert alle 
Interrupts aus.

Deine Schleife mit 40000 Abfragen der Tasten sind absolut unsinning bis 
kontraproduktiv. Zumal dein Tastenabfrage per Polling sinnlose 200ms die 
CPU lahmlegt. Sowas macht man per Timer und Flag, siehe 
Interrupt. Ich hab es aber beim Polling erstmal belassen, aber 
wesentlich sinnvoller.

Grossartige Rechnungen haben in ISRs nichts zu suchen. Das amcht man im 
Main, und dort auch nur so oft, wie man es für die Anzeige braucht (10 
Hz max.).

Deine Rechungen sind bisweilen konfus.

Schon mal was von ner Schleife gehört? Z.B. zm Auslesen deines 
Temperatursensors?

MfG
Falk

von He G. (dare)


Lesenswert?

Mensch Falk, vielen Dank!
Da sind auf jeden Fall ein paar Lerneffekte gegeben ;)
Bei der Geschwindigkeit darf es nicht heissen iRPM, ist klar. Nur, falls 
jemand den Code verwenden will... [dann gibts noch das Problem, dass der 
Mega sich abschiesst. Vermutlich wegen Division durch Null bzw. quatsch, 
wenn keine Tacho und Drehzahlsignale eingegangen sind, das muss man noch 
abfangen]
Ich freu mich schon drauf, dass zu testen. Übrigens hat sich jemand 
gefunden, der die Schaltung mit mir von Grund auf neu strickt. Das wird 
wohl auch das Beste sein für eine Version 2. Ich denke fast, das 
Abfragen des Flags nach einem delay ist eine Spitzen-Idee. Da werd ich 
morgen noch mal ran. Die anderen Tipps werde ich auch überdenken und 
umsetzen. Das ist erst mal ausreichend Stoff um mich zu beschäftigen. 
Ich gebe dann bescheid, wies gelaufen ist.
VIELEN DANK!

von He G. (dare)


Lesenswert?

Sooo.. ich habe die Quellen mit meinen "gemerged" und es läuft. Dann 
habe ich mir noch ein paar Gedanken gemacht. Die Sollspannung habe ich 
mittels Spannungsteiler auf etwa 4V reduziert. Zusätzlich frage ich im 
Interrupt ein paar mal das Flag aus und schaue, ob die Spannung weg 
bleibt. Ich muss mal schauen, ob das (noch) funktioniert. In jedem Fall 
wird der Interrupt nicht mehr ungewollt ausgelöst. Dann habe ich mich 
auf die Suche gemacht und herausgefunden, dass die Schaltung zur 
Erfassung der Drehzahl die Wurzel allen Störübels ist. Hängt sie nicht 
dran, dann läuft das Ganze fast schon erschreckend stabil und 
Störungsfrei. Ich war mit dem Ansatz ohnehin nicht so glücklich und habe 
mich blos bequatschen lassen. Nun würde ich gern einen anderen 
verfolgen. Ich eröffne hierzu einen neuen Thread und hoffe, dass das im 
Sinne der Forenregeln ist.
Grüße!

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.