mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Hilfe gegen Bares


Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
keiner? :(

Autor: Schlurch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lol, das war ein konstruktiver vorschlag ;)

Autor: Schlurch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lol hin - lol her. Das ist Lebenserfahrung :-)

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ???

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: He Gr (dare)
Datum:

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

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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  ;-)

Autor: Christian (Gast)
Datum:

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

Autor: He Gr (dare)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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
#include "lcd.h"
#include <avr/io.h>
#include <util/delay.h>
#include "functions.h"
#include <avr/interrupt.h>
#include <avr/eeprom.h>

//global vars
  uint16_t EEMEM eeKM;
  uint16_t EEMEM eeM;
  uint16_t EEMEM eeDKM;
  uint16_t EEMEM eeMaxTemp;
  uint16_t EEMEM eeWarnTemp;
  uint16_t EEMEM eeRadUmfang;
  uint16_t EEMEM eeIgnitions;
    uint16_t iWarnTemp;
      uint16_t iKM;
    uint16_t icm;
    uint16_t iM;
    uint16_t iMaxTemp;
    uint16_t iDKM;
    uint16_t iRadUmfang;
    uint16_t iIgnitions;
  uint16_t iRPM=0;
  volatile uint16_t iV=0;
  uint16_t iTemp;
  volatile uint16_t speedvar=0;
  volatile uint16_t tachoold=0;
  volatile uint16_t tachonew=0;
  uint16_t dzmold=0;
  uint16_t dzmnew=0;
  uint16_t dzmvar=0;
  uint16_t tachosignale;
  char scenario;
  char dzmflag;
  char lcdon=0;

ISR(TIMER1_OVF_vect) 
{
  
}

ISR(TIMER0_OVF_vect) 
{  
  dzmflag=1;
  dzmnew=TCNT1/10;
  if(dzmold!=0)
  {
    if(dzmnew>dzmold)  dzmvar=dzmnew-dzmold;
    else dzmvar=6553-dzmold+dzmnew;
    iRPM=9830/(dzmvar/100); 
  }
  dzmold=dzmnew;
}



ISR(INT0_vect)
{
  tachosignale++;
  tachonew=TCNT1/10;
  if(tachoold!=0)
  {
    if(tachonew>tachoold)  speedvar=tachonew-tachoold;
    else speedvar=6553-tachoold+tachonew;
    iV=(iRadUmfang*59)/(speedvar); 
  }
  tachoold=tachonew;
}


ISR ( ANA_COMP_vect )
{
   eeprom_write_word(&eeKM, iKM);
  eeprom_write_word(&eeM, iM);
  eeprom_write_word(&eeDKM, iDKM);
  eeprom_write_word(&eeMaxTemp, iMaxTemp);
  lcd_bel(0);
  lcdon=0;
  lcd_clrscr();
  _delay_ms(5);
  lcd_puts("datasave");  
  lcd_bel(1);
  _delay_ms(2000);
  lcd_clrscr();
}


int main(void)
{

_delay_ms(1000);

//Portrichtungsregister setzen
  DDRA |= (1 << DDA1) | (1 << DDA2); //a0 data eingang, a1 cs ausg, a2 clk ausg 
  PORTA &= (1<<PA0); //internen pull up aktivieren
  DDRC |= (1<<PC7); //lcd bel pin
  DDRB  |= (1<<DDB0);// | (1<<DDB2) | (1<<DDB3);  //b0 als eingang für dzm, b2,3 für ac
  PORTB |= (1<<PB0) | (1<<PB2);    //internen pull up aktivieren
//  DDRD  |= (1<<DDD2);
  PORTD |= (1<<PD2);
  

//deactivate interrupts
  cli();



//load var from eeprom
    iKM = eeprom_read_word(&eeKM);
    iM = eeprom_read_word(&eeM);
  iMaxTemp = eeprom_read_word(&eeMaxTemp);
  iDKM= eeprom_read_word(&eeDKM);
  iRadUmfang=eeprom_read_word(&eeRadUmfang);
  iIgnitions=eeprom_read_word(&eeIgnitions);
  iWarnTemp=eeprom_read_word(&eeWarnTemp);

//check if var is bogus and set 0 then
  if(iKM==0xFFFF){iKM=0;eeprom_write_word(&eeKM,0);}
  if(iM==0xFFFF){iM=0;eeprom_write_word(&eeM,0);}
  if(iMaxTemp==0xFFFF){iMaxTemp=0;eeprom_write_word(&eeMaxTemp,0);}
  if(iDKM==0xFFFF){iDKM=0;eeprom_write_word(&eeDKM,0);}
  if(iRadUmfang==0xFFFF){iRadUmfang=50;eeprom_write_word(&eeRadUmfang,50);}
  if(iIgnitions==0xFFFF){iIgnitions=1;eeprom_write_word(&eeIgnitions,1);}
  if(iWarnTemp==0xFFFF){iWarnTemp=1500;eeprom_write_word(&eeWarnTemp,1500);}





//displaybeleuchtung an
  lcd_bel(1);lcdon=1;
//zeit fürs display aufzuwachen
  _delay_ms(50);
//lcd init
  _delay_ms(50);
  lcd_init(LCD_DISP_ON);
  _delay_ms(50);
  lcd_clrscr();
//welcome screen
  _delay_ms(50);    
  lcd_puts("   VesCom 1.0   ");
  _delay_ms(1000);
  lcd_gotoxy(0, 1);
  _delay_ms(5);
  lcd_puts("    by  dare");
  _delay_ms(3000);
  lcd_clrscr();  


//start timer for systemtime ( 16384 hz)
   TCCR1B = (1<< CS12);
//set interrupt for dzm timer
  TIMSK |= (1<<TOIE0);
//timer0 vorladen
  TCNT0=246;

//start timer for dzm
  TCCR0 |= (1<<CS02) | (1<<CS01);  



//steigende/fallende? flanke löst interrupt aus
  MCUCR |= (1<<ISC01);
//enable interrupt on int0
  GIMSK |= (1<<INT0);


//startscenario
  scenario=1;

//set ac for power loose interrupt
//  ACSR = (1 << ACIE) | (1 << ACIS1); 


//activate interrupts
  sei();




for(;;)
  {

  dzmflag=0;
//put temp in iTemp
  fReadTemp(&iTemp); 
//temp warning function
  if(iTemp>=iWarnTemp) 
  {
    if(lcdon==1)
    {
      lcd_bel(0); 
      lcdon=0;
    }else 
    {
      lcd_bel(1);
      lcdon=1;
    }
  } else lcd_bel(1);

  
//maxtemp
  if(iTemp>iMaxTemp){eeprom_write_word(&eeMaxTemp,iTemp);iMaxTemp=iTemp;}

//werte ausgeben
  fOutput(scenario,iV,iRPM,iTemp,iMaxTemp,iKM,iM,iDKM); 

  for(uint16_t i=0;i<40000;i++)
    {
      if (fdebounce(&PINA, PA4)==1) {if(scenario>5)scenario=1; else scenario++; lcd_clrscr();}
      if (fdebounce(&PINA, PA3)==1) 
      {   
        eeprom_write_word(&eeKM, iKM);
        eeprom_write_word(&eeM, iM);
        eeprom_write_word(&eeDKM, iDKM);
        eeprom_write_word(&eeMaxTemp, iMaxTemp);
        menu(&eeDKM,&eeMaxTemp,&eeIgnitions,&eeWarnTemp,&eeRadUmfang);
      }
    }
  
  icm+=tachosignale*iRadUmfang;
  if(tachosignale==0)iV=0;
  tachosignale=0;
  while(icm>=100){iM++;icm-=100;}
  if(iM>=1000){iKM++; iDKM++; iM-=1000;}
  if(dzmflag==0)iRPM=0;

  }
return 0;
}


functions.c
#include <avr/io.h>
#include <util/delay.h>
#include "lcd.h"
#include <stdlib.h>
#include <string.h>
#include <avr/eeprom.h>
#include "functions.h"
#include <avr/wdt.h>
#include <avr/interrupt.h>

void menu(uint16_t *eeDKM,uint16_t *eeMaxTemp,uint16_t *eeIgnitions,uint16_t *eeWarnTemp,uint16_t *eeRadUmfang)
{
  lcd_bel(1);
  _delay_ms(5);
  lcd_clrscr();

  char menu=0;
  uint8_t state=1;
  uint16_t radumfang= eeprom_read_word(eeRadUmfang);
  uint16_t warntemp=eeprom_read_word(eeWarnTemp);
  while(menu<1)
  {

      switch(state)
      {
        case 1:
            _delay_ms(5);
            lcd_gotoxy(0, 0);
            _delay_ms(5);
            lcd_puts("Menu:");
            _delay_ms(5);
            lcd_gotoxy(0, 1);
            _delay_ms(5);
            lcd_puts(" ->, X   ");
            while(state<2)
            {
              if (fdebounce(&PINA, PA4)==1) state=2;
              if (fdebounce(&PINA, PA3)==1) 
              {
                cli();wdt_enable (WDTO_15MS);while (1); //atmega abschiessen
              }
            }
        break;

        case 2:
          _delay_ms(5);
          lcd_gotoxy(0,1);
          _delay_ms(5);
          lcd_puts("Tag-Km=0");
          while(state<3)
          {
            if (fdebounce(&PINA, PA3)==1) eeprom_write_word(eeDKM, 0);
            if (fdebounce(&PINA, PA4)==1) state=3;
          }
        break;

        case 3:
          _delay_ms(5);
          lcd_gotoxy(0,1);
          _delay_ms(5);
          lcd_puts("MxTemp=0");
          while(state<4)
          {
            if (fdebounce(&PINA, PA3)==1) eeprom_write_word(eeMaxTemp, 0);
            if (fdebounce(&PINA, PA4)==1) state=4;
          }
        break;

        case 4:
          while(state<5)
          {
          int ign=eeprom_read_word(eeIgnitions);
          _delay_ms(5);
          lcd_gotoxy(0,1);
          _delay_ms(5);

            if(ign==1)lcd_puts("Znd/U: 1"); 
              else lcd_puts("Znd/U: 2");
            if (fdebounce(&PINA, PA3)==1) 
            {
              if(ign==1) eeprom_write_word(eeIgnitions, 2);
              else eeprom_write_word(eeIgnitions, 1);
            }
            if (fdebounce(&PINA, PA4)==1) state=5;
            _delay_ms(10);
          }
        break;

        case 5:
    
          while(state<6)
          {          
            _delay_ms(5);
            lcd_gotoxy(0,1);
            _delay_ms(5);
            char out1[3];
            itoa(radumfang,out1,10);
            char out2[8];
            strcpy(out2,"Umfa:");
            if(radumfang<100) strcat(out2," ");
            if(radumfang<10) strcat(out2," ");
            strcat(out2,out1);
            lcd_puts(out2);
            if (fdebounce(&PINA, PA3)==1) 
            {
              if(radumfang<200) radumfang++;
              else radumfang=1;
            }
                  
            if (fdebounce(&PINA, PA4)==1) 
            {
              state=6;
              eeprom_write_word(eeRadUmfang,radumfang);              
            }
            _delay_ms(10);
          }
        break;

        case 6:
          
          while(state<7)
          {
            _delay_ms(5);
            lcd_gotoxy(0,1);
            _delay_ms(5);
            char out1[4];
            itoa(warntemp,out1,10);
            char out2[9];
            strcpy(out2,"WTp:");
            if(warntemp<1000) strcat(out2," ");
            if(warntemp<100) strcat(out2, " ");
            if(warntemp<10) strcat(out2, " ");
            
            
            strcat(out2,out1);
            
            lcd_puts(out2);
            
            if (fdebounce(&PINA, PA3)==1) 
            {
              if(warntemp<1200) warntemp+=5;
              else warntemp=1;
            }
                  
            if (fdebounce(&PINA, PA4)==1) 
            {
              eeprom_write_word(eeWarnTemp, warntemp);
              state=7;
            }
              
            _delay_ms(10);
          }
        break;

        default:
          state=1;
        break;
      }


  }
}




uint8_t fdebounce(volatile uint8_t *port, uint8_t pin)
{
    if ( ! (*port & (1 << pin)) )
    {
      _delay_ms(50); 
        _delay_ms(50); 
        if ( *port & (1 << pin) )
        {
            _delay_ms(50);
            _delay_ms(50); 
            return 1;
        }
    }
    return 0;
}


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)
{
  char sSpeed[8];
  char sRpm[8];
  char sTemp[8];
  char sMaxTemp[8];
  char sDKM[8];
  char sKM[8];

  uint8_t iStrLen;
  
//Speed

  iStrLen=0;
  char sV2[8];
  itoa(iV,sV2,10); //int to string
  iStrLen=5-strlen(sV2); //how many spaces to add?

  strcpy(sSpeed,"V:");
  while(iStrLen>0)
  {
    strcat(sSpeed," ");
    iStrLen=iStrLen-1;
  }
  strcat(sSpeed,sV2);
//  sSpeed[7]='\0';



//Rpm
  iStrLen=0;
  char sRPM2[8];
  itoa(iRpm,sRPM2,10); //int to string
  iStrLen=5-strlen(sRPM2); //how many spaces to add?
  
  strcpy(sRpm,"U:");
  while(iStrLen>0)
  {
    strcat(sRpm," ");
    iStrLen=iStrLen-1;
  }
  strcat(sRpm,sRPM2);

//Temp
  iStrLen=0;
  char sTemp2[8];
  itoa(iTemp,sTemp2,10); //int to string
  iStrLen=4-strlen(sTemp2); //how many spaces to add?
  strcpy(sTemp,"Tp:");

  while(iStrLen>0)
  {
    strcat(sTemp," ");
    iStrLen=iStrLen-1;
  }
  strcat(sTemp,sTemp2);


//MaxTemp
  iStrLen=0;
  char sMT2[8];
  itoa(iMaxTemp,sMT2,10); //int to string
  iStrLen=4-strlen(sMT2); //how many spaces to add?
  strcpy(sMaxTemp,"mT:");

  while(iStrLen>0)
  {
    strcat(sMaxTemp," ");
    iStrLen=iStrLen-1;
  }
  strcat(sMaxTemp,sMT2);


//Distance
  char sMeter[8];
  uint8_t iMeter=iM/100;
  itoa(iMeter,sMeter,10);
  char sKilom[8];
  itoa(iKM,sKilom,10);
  iStrLen=5-strlen(sKilom); //how many spaces to add?
  strcpy(sKM,"");
  while(iStrLen>0)
  {
    strcat(sKM," ");
    iStrLen=iStrLen-1;
  }
  strcat(sKM,sKilom);
  strcat(sKM,".");
  strcat(sKM,sMeter);

//Tageskilometer
  iStrLen=0;
  char sDKM2[8];
  itoa(iDKM,sDKM2,10); //int to string
  iStrLen=5-strlen(sDKM2); //how many spaces to add?
  strcpy(sDKM,"D:");
  while(iStrLen>0)
  {
    strcat(sDKM," ");
    iStrLen=iStrLen-1;
  }
  strcat(sDKM,sDKM2);
  




  char ol[7];
  char or[7];
  char ul[7];
  char ur[7];

  switch(scenario)
  {

    case 1:
      strcpy(ol,sSpeed);
      strcpy(or,sRpm);
      strcpy(ul,sKM);
      strcpy(ur,sTemp);
    break;

    case 2:
      strcpy(ol,sSpeed);
      strcpy(or,sRpm);
      strcpy(ul,sMaxTemp);
      strcpy(ur,sTemp);
    break;

    case 3:
      strcpy(ol,sSpeed);
      strcpy(or,sRpm);
      strcpy(ul,sKM);
      strcpy(ur,sDKM);
    break;

    case 4:
      strcpy(ol,sSpeed);
      strcpy(or,"       ");
      strcpy(ul,sRpm);
      strcpy(ur,"       ");
    break;

    default:
      strcpy(ol,sSpeed);
      strcpy(or,sRpm);
      strcpy(ul,sKM);
      strcpy(ur,sTemp);
    break;
  }

  lcd_gotoxy(0,0);
  _delay_ms(5);
  lcd_puts(ol);
  _delay_ms(5);
  lcd_gotoxy(7,0);
  _delay_ms(5);
  lcd_puts("  ");
  _delay_ms(5);
  lcd_gotoxy(9,0);
  _delay_ms(5);
  lcd_puts(or);
  _delay_ms(5);
  lcd_gotoxy(0,1);
  _delay_ms(5);
  lcd_puts(ul);
  lcd_gotoxy(7,1);
  _delay_ms(5);
  lcd_puts("  ");
  _delay_ms(5);
  _delay_ms(5);
  lcd_gotoxy(9,1);
  _delay_ms(5);
  lcd_puts(ur);

}


void lcd_bel(char opt)
{
  if(opt==0)   PORTC &= ~(1<<PA7); //beleuchtung aus
  else PORTC |= (1<<PA7); //beleuchtung an
}

void fReadTemp(uint16_t *iTemp)
{
  PORTA |= (1<<PA1); //cs high for measure
  PORTA &= ~(1<<PA2); //clk low but dontcare
  _delay_ms(1);
  PORTA &= ~(1<<PA1); //cs low for data
  _delay_ms(1);
  PORTA |= (1<<PA2); //clk high 
  _delay_ms(1);
  PORTA &= ~(1<<PA2); //clk low
  _delay_ms(1);
  if ( PINA & (1<<PINA0) ) *iTemp=512; else *iTemp=0;
  _delay_ms(1);
  PORTA |= (1<<PA2); //clk high 
  _delay_ms(1);
  PORTA &= ~(1<<PA2); //clk low
  _delay_ms(1);
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+256;
  _delay_ms(1);
  PORTA |= (1<<PA2); //clk high 
  _delay_ms(1);
  PORTA &= ~(1<<PA2); //clk low
  _delay_ms(1);
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+128;
  _delay_ms(1);
  PORTA |= (1<<PA2); //clk high 
  _delay_ms(1);
  PORTA &= ~(1<<PA2); //clk low
  _delay_ms(1);
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+64;
  _delay_ms(1);
  PORTA |= (1<<PA2); //clk high 
  _delay_ms(1);
  PORTA &= ~(1<<PA2); //clk low
  _delay_ms(1);
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+32;
  _delay_ms(1);
  PORTA |= (1<<PA2); //clk high 
  _delay_ms(1);
  PORTA &= ~(1<<PA2); //clk low
  _delay_ms(1);
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+16;
  _delay_ms(1);
  PORTA |= (1<<PA2); //clk high 
  _delay_ms(1);
  PORTA &= ~(1<<PA2); //clk low
  _delay_ms(1);
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+8;
  _delay_ms(1);
  PORTA |= (1<<PA2); //clk high 
  _delay_ms(1);
  PORTA &= ~(1<<PA2); //clk low
  _delay_ms(1);
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+4;
  _delay_ms(1);
  PORTA |= (1<<PA2); //clk high 
  _delay_ms(1);
  PORTA &= ~(1<<PA2); //clk low
  _delay_ms(1);
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+2;
  _delay_ms(1);
  PORTA |= (1<<PA2); //clk high 
  _delay_ms(1);
  PORTA &= ~(1<<PA2); //clk low
  _delay_ms(1);
  if ( PINA & (1<<PINA0) ) *iTemp=*iTemp+1;

  PORTA &= ~(1<<PA2); //clk low
  PORTA |= (1<<PA1); //cs high for measure
  PORTA &= ~(1<<PA2); //clk low but dontcare  
}




Autor: He Gr (dare)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: He Gr (dare)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, Danke!

Autor: Stefan Salewski (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Salewski (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.)

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: He Gr (dare)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier der Projektordner

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Seppel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Seppel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P.S.

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

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, verzeihung.
Also:

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

A4

und...
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)

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Torsten S. (tse)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Kachel-Heinz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi

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

MfG Spess

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.... ;-)

Autor: Falk Brunner (falk)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: He Gr (dare)
Datum:

Bewertung
0 lesenswert
nicht 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!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.