logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[atmega88][c] Dokladosc obliczen

Toners 14 Lis 2010 20:48 1096 6
REKLAMA
  • #1 8744316
    Toners
    Poziom 11  
    Hej, piszac posta napotkalem kolejny problem :/, wiec chcialbym podzielic na 2 czesci:

    [1] mam pot. podpiety pod ADC0, wynikiem jest wartosc od 0-1024. Chcialem wyswietlic na LCD takze wartosc w % (0-1024 odpowiada 0-100.0%) z 1 cyfra po przecinku, aby to zrobic przeskalowywuje (innej metody nie znam) wartosc 0-1024 na 0-1000 i wyswietlam jako string przesuwajac przecinek w lewo o 1 pole. Niestety Kalkulujac:

    proc = pot*125/128 //wariant_1
    proc = (pot*25/128)*25 //wariant_2

    gubie po drodze dokladnosc (zwlaszcza wariant_1) :/ ...jak tego uniknac ? czy sa inne metody kalkulacji niz rozbijanie ulamka i kombinowanie (jak np w wariant_2)?

    [2] Nie wiem dlaczego zmienna "zm1" zachowuje sie jako signed int po przekroczeniu 32767 zaczyna od -32768, natomiast w poz (6,1) wartosc wyswietlana jest jako unsigned int (leci powyzej 32767).

    
    #include <util/delay.h>
    #include <stdlib.h>
    #include "ADC.h"
    #include "HD44780.h"
    //
    int main(void)
    {
    	char str[7];
    	char tmp[7];
    	int pot;
    	unsigned int zm1;
    	DDRD = 0xF0; 
    	DDRC = 0x00;
    	ADC_Init();
    	LCD_Init();  	
    				
    	do{
    		LCD_Clear();
    		pot = getADC(0);
    		LCD_GoTo(0,0);
    		LCD_WriteText(itoa(pot,str,10));
    
    		zm1=(pot*100);                      
    		LCD_GoTo(6,0);
    		LCD_WriteText(itoa(zm1,str,10));
    
    		LCD_GoTo(6,1);
    		dtostrf(zm1,1,1,tmp);
    		LCD_WriteText(tmp);
    		_delay_ms(100);
    	}
    	while(1);
    	return 0;
    }
    
  • REKLAMA
  • #2 8744367
    Bartusjusz
    Poziom 25  
    Nie rozumiem problemu:
    100/1024= 0,09765625 wg mojego kalkulatora...

    czyli
    0,09765625% to 1 próbka, mówiąc prościej liczba którą odczytuje Ci atmega z przetwornika razy to co wyliczyłem da Ci liczbę procent.

    Dokładność zawsze będzie ograniczona chyba że wyświetlisz 8 miejsc po przecinku...
  • REKLAMA
  • #3 8744435
    Toners
    Poziom 11  
    bartusjusz napisał:
    Nie rozumiem problemu:
    100/1024= 0,09765625 wg mojego kalkulatora...

    czyli
    0,09765625% to 1 próbka, mówiąc prościej liczba którą odczytuje Ci atmega z przetwornika razy to co wyliczyłem da Ci liczbę procent.

    Dokładność zawsze będzie ograniczona chyba że wyświetlisz 8 miejsc po przecinku...


    a w jakiej zmiennej chcesz trzymac ta wartosc ? chcialbym miec mozliwosc zmiany wyswietlania, w zaleznosci od ustawienia 0,09765625 (bez przecinka) i 0,9765625 (z 1 miejscem po przecinku)? To jest wartosc typu double.
  • Pomocny post
    #4 8744437
    defrag07
    Poziom 11  
    Co do zm1, ona się tak zachowuje bo ją traktujesz jak inta przez to itoa, powinieneś użyć utoa
  • REKLAMA
  • REKLAMA
  • #6 8744549
    Toners
    Poziom 11  
    tmf napisał:
    Oczywiście, że gubisz, 1024*125=128000, grubo poza zakresem uint. Zmień zmienną na long, i mnóż przez 125UL.


    Problem w tym ze moge uzyc max 16-bitow, tzn nawet jak zmienie zmienna na UL to i tak max jaki wyswietli to 65535, powyzej zaczyna od 0. Czy mozna uzywac (jakos) zmiennych 32-bitowych ?
  • Pomocny post
    #7 8744665
    tmf
    VIP Zasłużony dla elektroda
    Źle mnie zrozumiałeś. Wynik końcowy ma być na 16-bitach, bo więcej nie potrzebujesz. Chodzi tylko o to, aby pośrednie obliczenia były wykonywane na zmiennych o większych długościach.
REKLAMA