-         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 16

Thema: Mathematisches Problem

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    32
    Beiträge
    795

    Mathematisches Problem

    Anzeige

    Hallo zusammen,

    Ich komm mal gleich zur Sache:

    Zunächst wird eine Hebelstellung per POTI über den ADC ausgelesen.

    Dieser Wert liegt zwischen 0 und 1023. = way_akt

    Ich nutze aber nicht den vollen weg des Potis, sondern nur
    zB von 100 bis 900.

    Diese Werte habe ich in way_min und way_max geschrieben.


    Ich benötige am scholuss eine 8Bit-breite Zahl.

    Also habe ich mir folgende umrechnung ausgedacht:

    Code:
    uint8_t way_rev;		// Reverse-Bits
    uint16_t way_min = 100;	// Reverenz Minimalwert
    uint16_t way_mid;	// Reverenz Mittelstellung
    uint16_t way_max = 900;	// Reverenz Maximalwert
    
    uint16_t way_akt;	// Rohe-Potistellung
    uint16_t way_neu;	// Aufbereitete Stellgröße
    
    
    
    
    
    	way_akt = ADC_wert(0);
    
    	if( way_akt < way_min ){ way_akt = way_min; }
    	if( way_akt > way_max ){ way_akt = way_max; }
    	
    	way_akt = way_akt - way_min;
    	
    	double factor;
    	double x;
    	
    	factor = 1023 / (way_max - way_min);
    	x = (way_akt / factor);
    	
    	way_neu = x;
    	way_neu = ((way_neu)>>2);
    	
    
    
    PORTC = way_neu;

    nunja, leider ist die berechnung nicht so genau.

    Deshalb erreiche ich nie meine vollen 255!

    Wie könnte ich das am dümmsten lösen? Ich habe schon sämtliche formeln und Co ausprobiert....

    Für eure Hilfe wäre ich euch mehr als Dankbar!
    Gruß,
    Franz

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.11.2004
    Beiträge
    1.693
    Ich habe keine Ahnung von C, aber es müsste im Prinzip ja so aussehen:
    100=0
    900=255
    255/800=0,318
    Wert=way_akt*0,318

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von Michael
    Registriert seit
    17.01.2004
    Ort
    Karlstadt
    Alter
    48
    Beiträge
    1.255
    Hallo Kaiser-F,
    Ich nutze aber nicht den vollen weg des Potis, sondern nur
    zB von 100 bis 900.

    Diese Werte habe ich in way_min und way_max geschrieben.
    Nimm also way_diff = way_max - way_min.
    Jetzt der Dreisatz:
    Way_diff/255 = Way_akt/x
    x = Way_akt * 255 / way_dif

    x ist der gesuchte 8Bit-Wert.

    Gruß, Michael

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    12.11.2004
    Ort
    München
    Alter
    30
    Beiträge
    447
    Hi,
    @Michael: ich bin mir nicht sicher ob das 100%ig geht, weil uint16 max 65535 sein kann. Also könnte es bei Werten von Way_akt > 257 Probleme geben...
    @Kaiser-F: was mir bei deinem code seltsam vorkommt ist
    factor = 1023 / (way_max - way_min);
    x = (way_akt / factor);
    probier das mal mit
    factor = 1023.0 / (double)(way_max - way_min);
    x = ((double)way_akt / factor);

    PS: einfache floats sollten da doch reichen oder?
    .... bin mir jetzt nicht sicher ob es das war, aber das könnte es gewesen sein...
    MfG Alex

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von Michael
    Registriert seit
    17.01.2004
    Ort
    Karlstadt
    Alter
    48
    Beiträge
    1.255
    Hallo PasstScho,
    ich bin mir nicht sicher ob das 100%ig geht,
    das passtscho, setz einfach mal Werte ein und rechne es aus.
    einfache floats sollten da doch reichen oder?
    Besser noch:
    Kaiser-F wollte nur 8 bit!
    Gruß, Michael

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    32
    Beiträge
    795
    Sorry, war gerade nen Happe essen,
    Und hab mir 2 Aspirin + C reingehaun.

    Evtl hilft mir das mit C



    @PasstScho:

    factor = 1023 / (way_max - way_min);

    (way_max - way_min) ist der "Nutzweg"

    durch diesen factor muss ich später teilen.

    Das ganze funktioniert wunderbar, nur bekomm ich das mit den Gleitpunktvariablen nicht so hin....

    der wert factor, und der spätere Quotient:

    way_akt /factor ist dann zu ungenau...

    Ich bin mir nicht genau sicher wie ich die Gleitpunktvariablen anwenden muss.

    Ich probier gleich mal eire Anregungen aus.

    Danke vorerst mal für die Superschnelle Hilfe!

    EDIT:

    Zitat Zitat von PasstScho
    @Michael: ich bin mir nicht sicher ob das 100%ig geht, weil uint16 max 65535 sein kann. Also könnte es bei Werten von Way_akt > 257 Probleme geben...
    der ADC liefert max. 1023. Da es ein 10Bit ADC ist, bin ich gezwungen
    ein uint16_t zu verwenden.
    Gruß,
    Franz

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    32
    Beiträge
    795
    Also;

    Merkwürdigerweise erhalte ich wenn ich es EINFACH so schreibe:

    Code:
    	uint8_t way_rev;      // Reverse-Bits 
    	uint16_t way_min = 100;   // Reverenz Minimalwert 
    	uint16_t way_mid;   // Reverenz Mittelstellung 
    	uint16_t way_max = 900;   // Reverenz Maximalwert 
    
    	uint16_t way_neu;   // Aufbereitete Stellgröße 
    
    	uint16_t way_akt;   // Rohe-Potistellung
    	uint16_t way_nutz;
    	uint16_t factor; 
    	uint16_t x; 
    
    
    
    	way_akt = ADC_wert(0); 
    
    	if( way_akt < way_min ){ way_akt = way_min; } 
    	if( way_akt > way_max ){ way_akt = way_max; } 
        
    	way_akt = way_akt - way_min; 
        
    	way_nutz = (way_max - way_min);
        
    
    	factor = 1023 / way_nutz; 
    	x = way_akt / factor;
    	
    	
    	way_neu = x; 
    	way_neu = ((way_neu)>>2); 
        
    
    
    	PORTC = way_neu;
    Das "genauste" Ergebnis: 200....

    wenn man rechnet: 1023/800 = 1,27875. mit uint16_t sind macht das: 1

    also.... für nix.....



    mit
    Code:
    	uint8_t way_rev;      // Reverse-Bits 
    	uint16_t way_min = 100;   // Reverenz Minimalwert 
    	uint16_t way_mid;   // Reverenz Mittelstellung 
    	uint16_t way_max = 900;   // Reverenz Maximalwert 
    
    	uint16_t way_neu;   // Aufbereitete Stellgröße 
    
    	uint16_t way_akt;   // Rohe-Potistellung
    	
    	uint16_t way_nutz;
    	
    	double factor; 
    	double x; 
    
    
    
    	way_akt = ADC_wert(0); 
    
    	if( way_akt < way_min ){ way_akt = way_min; } 
    	if( way_akt > way_max ){ way_akt = way_max; } 
        
    	way_akt = way_akt - way_min; 
        
    	way_nutz = (way_max - way_min);
        
    
    	factor = 1023.0000 / way_nutz; 
    	x = way_akt / factor;
    	
    	
    	way_neu = x; 
    	way_neu = ((way_neu)>>2); 
        
    
    
    	PORTC = way_neu;
    kommt raus: 156... ??
    Gruß,
    Franz

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    32
    Beiträge
    795
    au au au... das wird peinlich!

    156 war rechnerisch absolut richtig!

    Code:
    	uint8_t way_rev;      // Reverse-Bits 
    	uint16_t way_min = 100;   // Reverenz Minimalwert 
    	uint16_t way_mid;   // Reverenz Mittelstellung 
    	uint16_t way_max = 900;   // Reverenz Maximalwert 
    
    	uint16_t way_neu;   // Aufbereitete Stellgröße 
    
    	uint16_t way_akt;   // Rohe-Potistellung
    	
    	uint16_t way_nutz;
    	
    	double factor; 
    	double x; 
    
    
    
    	way_akt = ADC_wert(0); 
    
    	if( way_akt < way_min ){ way_akt = way_min; } 
    	if( way_akt > way_max ){ way_akt = way_max; } 
        
    	way_akt = way_akt - way_min; 
        
    	way_nutz = (way_max - way_min);
        
    
    	factor = way_nutz / 255.0000; 
    	x = way_akt / factor;
    	
    	
    	way_neu = x; 
        
    
    
    	PORTC = way_neu;
    der Fehler lag darin, dass der factor nicht 1023/way_nutz ist,
    sondern way_nutz/255.


    Danke an Michael, durch seinen Tipp "DREISATZ" bin ich draufgekommen.

    Vielen Danke nochmal an alle!
    Gruß,
    Franz

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    12.11.2004
    Ort
    München
    Alter
    30
    Beiträge
    447
    Hi,
    Genau das ist der Grund warum ich das zu (double) gecastet habe.
    In C oder C++ ist 1000/800 nicht das gleiche wie 1000.0/800.0 ... bei 1000/800 teilt dein Programm mit Zahlen ohne Komma!
    Wenn du 1000.0/800.0 machst, sieht er das .0 und erkennt, dass du mit Komma rechnen willst.
    Du musst in deinem Programmen also richtig zwischen int und float unterscheiden.
    Ich prüfe mal grad die andere Lösung von Michael .... theoretisch könnte sie funktionieren, aber auch nicht so wirklich...

    MfG Alex

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    32
    Beiträge
    795
    Hi auch,

    @ Passtscho: Du hast vololkommen Recht!

    Wenn ich schreibe: (way_max[ch] - way_min[ch]) / 255; ist das Ergebnis ungenau!

    Wenn ich aber schreibe: (way_max[ch] - way_min[ch]) / 255.0000;
    dann erhalte ich das Richtige ergebnis. wobei 255.0000 etwas übertrieben wirkt

    Hier alles in Kurzform in einer Funktion:

    ( mit globalen Arrays )

    Code:
    void WAY_PROP ( uint8_t ch ){
    	
    	if( way_akt[ch] < way_min[ch] ){ way_akt[ch] = way_min[ch]; } 
    	if( way_akt[ch] > way_max[ch] ){ way_akt[ch] = way_max[ch]; } 
    	way_akt[ch] = way_akt[ch] - way_min[ch];
    	
    	double factor = (way_max[ch] - way_min[ch]) / 255.0000;
    	way_end[ch] = way_akt[ch] / factor;
    
    }
    Gruß,
    Franz

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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