- 12V Akku mit 280 Ah bauen         
Seite 3 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 21 bis 30 von 34

Thema: Pogramierschierigkeiten

  1. #21
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    Beiträge
    5.799
    Blog-Einträge
    8
    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo

    Code:
    #include "RP6RobotBaseLib.h"
    
    
    
    unsigned char brightOld = 0;
    unsigned char bright = 0;
    
    void light(void){
    
    
      if(adcLSR<400){
        bright = 1;
     }
     else if((adcLSR<=1000)&&(adcLSR>=400)){
        bright = 0;
     }
     else if (adcLSR>1000){
        bright = 2;
     }
    
     if(bright != brightOld){
        switch(bright){
           case 0:
              writeString_P("\nIch bin glücklich\n");
              break;
           case 1:
              writeString_P("\nMach das Licht an!\n");
              break;
           case 2:
              writeString_P("\nMir ist es hier zu hell!\n");
              break;
     }
    
     }
    
     brightOld = bright;
    
    }
    int main (void)
    {
       initRobotBase();
    
    
       while(true)
       {
         task_ADC();
         light();
       }
       return 0;
    }
    Das Problem war die lokale Variable bright die nicht initialisiert wurde. Bei jedem Aufruf von light() wurde sie neu angelegt und hatte dann den zufälligen Wert, der im Speicher stand.

    Für bright==0 habe ich noch eine Meldung eingefügt damit man merkt, wenn sich die Helligkeit ändert. Die Abfrage zum Setzen von bright=0 habe ich um <= bzw. >= erweitert.

    Mit dem adc-Task wird nur bei jedem 6sten Aufruf ein neuer Wert in adcLSR gespeichert:

    Code:
    void task_ADC(void)
    {
    	static uint8_t current_adc_channel = 0;
    	if(!(ADCSRA & (1<<ADSC))) {
    	//	ADCSRA |= (1<<ADIF);
    		switch(current_adc_channel) {
    			case 0: adcBat = ADC; startADC(ADC_MCURRENT_L); break;
    			case 1: adcMotorCurrentLeft = ADC; startADC(ADC_MCURRENT_R); break;
    			case 2: adcMotorCurrentRight = ADC; startADC(ADC_LS_L); break;
    			case 3: adcLSL = ADC; startADC(ADC_LS_R); break;
    			case 4: adcLSR = ADC; startADC(ADC_ADC0); break;
    			case 5: adc0 = ADC; startADC(ADC_ADC1); break;
    			case 6: adc1 = ADC; startADC(ADC_BAT); break;
    		}
    		if(current_adc_channel == 6)
    			current_adc_channel = 0;
    		else
    			current_adc_channel++;
    	}
    }
    Das könnte man berücksichtigen und in light() zuerst prüfen, ob sich adcLSR seit dem letzen Aufruf geändert hat.

    Übrigens hat der Mega32 reichlich Speicher, den könnt ihr mit den paar Programmzeilen nie füllen Nettes Programm..

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  2. #22
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    04.02.2005
    Ort
    Hannover
    Beiträge
    174
    Probier es mal so: (nicht getestet)

    Code:
    void light(void)
     {
    	#define LICHT_AN 0
    	#define LICHT_OK 1
    	#define LICHT_AUS 2
    	
    	static uint8_t old = 0;
     if(adcLSR<400 && old != LICHT_AN)
      {
        writeString_P("\nMach das Licht an!\n");
    	old = LICHT_AN;
      }
      else if((adcLSR<1000)&&(adcLSR>400)&&old != LICHT_OK)
      {
    	writeString_P("\nDie Lichtverhältnisse hier sind wirklich gut. So lässt es sich Leben:)!\n");
    	old = LICHT_OK;
      }
      else if(old != LICHT_AUS)
      {
    	writeString_P("\nMir ist es hier zu hell!\n");
    	old = LICHT_AUS;
      }
     }

  3. #23
    Neuer Benutzer Öfters hier
    Registriert seit
    05.03.2008
    Beiträge
    17
    So danke erstmal für eure ganzen Vorschläge...
    ich habe sie alle ausprobiert und habe mir daraus selber ein Prog geschreiben weil die alle so ihre Tücken hattenAls Vorlage habe ich mir das von zerush genommen, weil das eig. das einzige wa wo ich verstanden habe was er gemacht hat.
    So eine Tücke hat das aber noch, und zwar schreibt er am Anfang immer mir ist es zu dunkel...
    Also ich habe gesagt dass er mir aufschreiben soll wie das Licht ist und siehe da, im ersten durchganz wir immer 0 gemessen. Könnte man das vielleicht so machen, dass er im ersten Durchgang noch nicht aufschreibt???



    Code:
    #include "RP6RobotBaseLib.h" 
      
    
    unsigned char brightOld=0;
    unsigned char bright=0;
    
    void light(void){
     
     writeIntegerLength(brightOld, DEC, 1);
     writeIntegerLength(bright, DEC, 1);
     writeIntegerLength(adcLSR, DEC, 4);
    
      
      if(adcLSR<=400){
        bright = 1;
     }
     else if((adcLSR<1000)&&(adcLSR>400)){
        bright = 0;
     }
     else if (adcLSR>=1000){
        bright = 2;
     }
    
     if(bright != brightOld){
        switch(bright){
           case 0:
              break;
           case 1:
              writeString_P("\nMach das Licht an!\n");
    		  mSleep(1000);
              break;
           case 2:
              writeString_P("\nMir ist es hier zu hell!\n");
    		  mSleep(1000);
              break;
    		  
     }
     brightOld=bright;
     
    }
    
    }
    void main (void)
    {
       
       initRobotBase();
       
       
       while(true)
    	{
    	  task_ADC();
    	  light();
    	
    	} 
       return 0;
    }

  4. #24
    Benutzer Stammmitglied
    Registriert seit
    10.08.2007
    Beiträge
    47
    Hi,

    ich hab mit Absicht nicht alles haarklein beschrieben (oder sourcecode gepostet). Dann bleibt fuer Dich auch ein Aha-Erlebnis. Mit dem lernt man viel besser als fertigen code zu verwenden.
    Nun sieht es ja schon ganz ordentlich aus. Anstelle des "case 0" wuerde ich allerding "default" im switch verwenden.

    Als Ergaenzung: das hier gezeigte geht in Richtung FSM (finite state machine). So kann man z.B. auch Taster softwaretechnisch entprellen. Und natuerlich noch viele andere tolle Dinge tun...

  5. #25
    Neuer Benutzer Öfters hier
    Registriert seit
    05.03.2008
    Beiträge
    17
    was heißt den einen Taster softwaretechnisch entprellen...
    und zu meiner Frage hat da vielleicht noch wer ne idee??

  6. #26
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.11.2004
    Ort
    Aachen
    Alter
    39
    Beiträge
    246
    Wie radbruch ja festgestellt hat, aktualisiert die taskADC() Funktion den gewünschten Wert nur bei jedem 6ten Mal...

    Rufe doch einfach in einer for-Schleife die taskADC() 6 mal hintereinander auf.
    Das sollte den ersten dunklen Messwert eliminieren.

  7. #27
    Neuer Benutzer Öfters hier
    Registriert seit
    05.03.2008
    Beiträge
    17
    ne das geht nicht, aber ich habe mal Radbruches Variante versucht, versteh zwar net was er da macht aber egal....
    allerdings sagt der zur letzten Zeile_"expectet declaration or statement of the end of input"....ich weiß jetzt nicht genau was er da von mir will!!!

    Code:
    #include "RP6RobotBaseLib.h" 
      
    
    unsigned char brightOld=0;
    unsigned char bright=0;
    
    void light(void){
     
     writeIntegerLength(brightOld, DEC, 1);
     writeIntegerLength(bright, DEC, 1);
     writeIntegerLength(adcLSR, DEC, 4);
      
      if(adcLSR<=400){
        bright = 1;
     }
     else if((adcLSR<1000)&&(adcLSR>400)){
        bright = 0;
     }
     else if (adcLSR>=1000){
        bright = 2;
     }
    
     if(bright != brightOld){
        switch(bright){
           case 0:
    	      writeString_P("\nSchon bessa:)!!\n");
              break;
           case 1:
              writeString_P("\nMach das Licht an!\n");
    		  mSleep(1000);
              break;
           case 2:
              writeString_P("\nMir ist es hier zu hell!\n");
    		  mSleep(1000);
              break;
    		  
     }
     brightOld=bright;
     
    }
    
    }
    void task_ADC(void)
    {
       static uint8_t current_adc_channel = 0;
       if(!(ADCSRA & (1<<ADSC))) {
       //   ADCSRA |= (1<<ADIF);
          switch(current_adc_channel) {
             case 0: adcBat = ADC; startADC(ADC_MCURRENT_L); break;
             case 1: adcMotorCurrentLeft = ADC; startADC(ADC_MCURRENT_R); break;
             case 2: adcMotorCurrentRight = ADC; startADC(ADC_LS_L); break;
             case 3: adcLSL = ADC; startADC(ADC_LS_R); break;
             case 4: adcLSR = ADC; startADC(ADC_ADC0); break;
             case 5: adc0 = ADC; startADC(ADC_ADC1); break;
             case 6: adc1 = ADC; startADC(ADC_BAT); break;
          }
          if(current_adc_channel == 6)
             current_adc_channel = 0;
          else
             current_adc_channel++;
       } 
    void main (void)
    {
       
       initRobotBase();
      
       while(true)
    	{
    	  task_ADC();
          light();
    	 
    	} 
       return 0;
       }

  8. #28
    Neuer Benutzer Öfters hier
    Registriert seit
    05.03.2008
    Beiträge
    17
    ok das Problem habe ich gelöst, allerdings sagt er jetzt das "task ADC" zwei Bedeutungen hat.

  9. #29
    Neuer Benutzer Öfters hier
    Registriert seit
    05.03.2008
    Beiträge
    17
    ich mache Fortschritte
    habe ihn der Anleitung gelesen,dass man es jetzt auch anders machen kann...

    Code:
    #include "RP6RobotBaseLib.h" 
      
    
    unsigned char brightOld=0;
    unsigned char bright=0;
    
    void light(void){
     uint16_t LSR = readADC(ADC_LS_R);
     
      if(LSR<=400){
        bright = 1;
     }
     else if((LSR<1000)&&(adcLSR>400)){
        bright = 0;
     }
     else if (LSR>=1000){
        bright = 2;
     }
    
     if(bright != brightOld){
        switch(bright){
           case 0:
    	      writeString_P("\nSchon bessa:)!!\n");
              break;
           case 1:
              writeString_P("\nMach das Licht an!\n");
    		  mSleep(100);
              break;
           case 2:
              writeString_P("\nMir ist es hier zu hell!\n");
    		  mSleep(100);
              break;
    		  
     }
     brightOld=bright;
     
    }
    
    }
    
    
    
    void main (void)
    {
       
       initRobotBase();
      
       while(true)
    	{
          light();
    	 } 
       return 0;
       }
    aber auch da taucht ein Problem auf:
    und zwar wenn ich den Finger davorhalte, sagt er mir ist es zu dunkel.
    Aber wenn ich ihn wieder wegnehme sagt nichts.Eigentlich müsste er sagen schon bessa.
    Und wenn ich den Finger wieder vorhalte sagt er nicht.
    Ich muss erst wieder ne Lampe vorhalten und dann funktioniert das wieder mit dem Mir ist es zu dunkel.

  10. #30
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.11.2004
    Ort
    Aachen
    Alter
    39
    Beiträge
    246
    Hier ist der Fehler:

    else if((LSR<1000)&&(adcLSR>400)){

    aus adcLSR musst du auch hier LSR machen

Seite 3 von 4 ErsteErste 1234 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests