- LiFePO4 Speicher Test         
Ergebnis 1 bis 5 von 5

Thema: adc wert auf die uart

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    09.04.2005
    Beiträge
    10

    adc wert auf die uart

    Anzeige

    Powerstation Test
    hallo,

    ich lauf wider einmal im kreis. ich versuche die werte des adc auf der RN-Control 1.4 auf die UART auszugeben . die UART funktioniert aber die wert vom adc sind irgendwie nicht richtig glaub ich zumindest?
    den Port c ist nur zur kontrolle ob der atmel läuft.
    Jetzt hat jemand eine ahnung wieso ich solche ergebnise bekomme wie: adcval 5c spannung 1f ? aber am PA6 1,7V sind?
    liegt es an der Konvertierung?
    sind die werte des ADC falsch?
    wenn ja wie sollte man den ADC auswerten?
    mit result = ADCH;
    oder result = ADCL + (ADCH << 8 );


    hier mein quellcode:


    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include <avr/signal.h>
    #include <string.h>
    #include "uart.h"
    
    #ifndef F_CPU
    #define F_CPU 16000000UL // 16MHz Taktfrequenz
    #endif
    
    /* 9600 baud */
    #define UART_BAUD_RATE      9600      
    #define CR \r\n
    
    
    #define	DELAY_LOOPS   50     // So viele Schleifendurchgaenge lang muss erledigt werden
    
    struct{
    	
    	uint8_t bPin:1 ;			// Aktuelles Signal am Pin (Taster)
    	uint8_t bStatus:1;			// Status des Tasters ob dieser beim voriegen durchlauf gedrückt war!
    
    
    } bportd;
    
    uint8_t nCounter;				// Zähler wie oft der Taster gedrückt war
    uint8_t nKeyPress;				// Schleifenzähler wie viele Schleifen der Taster schon gedrückt war!
    
    //Prototypen
    void init(void);
    uint16_t RADCC(uint8_t mux);
    
    int main (void){
    
    
    	// UART Initalisierung   
        uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
        
    	//Interrupt enable
    	sei();
    	// Initialisierung der Register
    	DDRA = 0x00;
    	PORTA = 0xff;
    	DDRC = 0xff; 
    	DDRD = 0x00; 
    	PORTD = 0x01;
    	
    	// Initialisierung der Varialblen 
    	char buffer[15];
    	
    	bportd.bPin =1;
    	bportd.bStatus =0;
    	nCounter =0;
    	uint16_t adcval ;
    	uint16_t spann;
    	
    	
    	uart_puts("\n\r Test Prog V1.0 RS232 Start\n\r");
    	for(;;){	
    	
    	if(bit_is_clear (PIND,PIND0)){		// wenn der knopf gedrückt ist logisch 0 
    		if(bportd.bPin){				// wenn der knopf nicht gedrückt war dann wird alles zurückgesetzt!
    		nCounter =0;
    		bportd.bPin =0;
    		bportd.bStatus =0;
    		}
    		else if(!bportd.bStatus){		// wenn der knopf immer noch gedrückt
    		
    			if(++nCounter > DELAY_LOOPS){
    			nKeyPress++;			//zähler erhöhen
    			PORTC = nKeyPress;		// ausgabe am Port c
    			
    			adcval = RADCC(6);	//
    			spann = (4,88*adcval)/255;
    			
    			itoa( adcval, buffer, 16);
    			uart_puts("\n\r adcval ");
    			uart_puts(buffer);
    			
    			itoa( spann, buffer, 16);
    			uart_puts("\n\r spannung ");
    			uart_puts(buffer);
    			
    			bportd.bStatus=1;		// status merken
    			}
    		}
    	
    	}
    	else
    	{
    	bportd.bPin = 1;
    	}
    }}
    
    
    
    uint16_t RADCC(uint8_t mux){
    	uint8_t i;
    	uint16_t  result =0; // Initialisierung wichtig
    	
    	ADCSRA = (1<<ADEN) | (1<<ADPS1)| (1<<ADPS2)| (1<<ADPS0); 	//Prescaler 128 & ADC aktivieren
    	ADMUX = mux; //Kanalwählen
    	ADMUX |= (1<<REFS1) |(1<<ADLAR); //VCC = Referenz
    	
    	ADCSRA |= (1<<ADSC); //adc wandlung
    	while(!ADCSRA & (1<<ADIF));//Warten 
    	
    	
    	for(i=0;i<4;i++)
    	{
    		ADCSRA |= (1<<ADSC); // adc wandlung
    		
    		while ( ADCSRA & (1<<ADSC) ); // Warten
    		
    		result += ADCH; // Wandlungsergebnisse addiern
    		//result += ADCW; //einspricht ADCL + (ADCH <<8);
    	}
    	
    		ADCSRA &= ~(1<<ADEN); // ADC deaktivieren 
    		
    		result /= 4; // arithm. Mittelwert
    		
    return result;
    }
    bestendank für eure mühe

    sg servusssss

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    -- es heisst nicht 4,88 sondern 4.88!
    -- die Multiplikation mit 4.88 wird so wohl nicht gehen. besser:
    Code:
        const uint16_t faktor = (double) 4.88/255 * (1L << 15);
        spann = (adcval*faktor) >> 15;
    Man erweitert also mit 2**15, um die Genauigkeit weiter zu verbesser.
    -- Wenn du die Zahlen als Dezimal willst, muss es heissen itoa (..., 10);
    Aber auch das ist wohl nicht das, was du willst? So bekommst du nämlich nur die Vorkommastellen...
    -- Wo ist/sind deine Interrupt-Routinen? Bzw warum machst du ein sei()?
    Disclaimer: none. Sue me.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    09.04.2005
    Beiträge
    10
    -das stimmt 4.88 ist ja c
    das "(double)" ist mir klar aber für was ist das " * (1L << 15);" und das >> 15; ist das für die genauigkeit hab ich das richtig verstanden??

    und ich hätte gerne das ich 1.7 raus kommt wie kann man das machen?!

    das sei(); ist von einem anderen programm wo ich befehle über die UART schicke, wollte nur die tasterabfrage kopieren hab ich übersehen beim löschen vom rest.

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Dein ADC liefert 4.88/255 V pro Inkrement. Die Spannung für den ADC-Wert adcwert ist also 4.88/255*adcwert. Der Faktor 4.88/255 ist kleiner als 1, was einem 2 Möglichkeiten lässe
    -1- Man nimm float-Arithmetik. Das funktioniert, ist aber teuer.
    -2- Man macht eine Fixpunkt-Rechnung mit int-Arithmetik.

    Für -2- erweitert man die entstehenden Ausdrücke mit 10000 (oben hatte ist 32768, ist aber nicht so toll wen man Dezimaldarstellung braucht).
    4.88/255*10000*adcwert ist dann die Gemessene Spannung in Einheiten von 1e-5V = 100µV = 0.1mV
    Code:
    const uint16_t faktor = (double) 4.88/255 * 10000L;
        uint16_t spann_100uV = faktor*adcval;
    Da faktor = 191 und adcval < 256 passt das in 16 Bit rein.
    Die Vorkommastelle deiner Spannung ist dann spann_100uV / 10000, die Nachkommastellen sind spann_100uV % 10000.

    Beachte, daß du für die Ausgabe der Nachkommastellen eine 1 als "0001" ausgeben musst, eine 33 als "0033", etc.
    Disclaimer: none. Sue me.

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    09.04.2005
    Beiträge
    10
    ich hab mich noch mit dem format problem beschäftigt :
    Beachte, daß du für die Ausgabe der Nachkommastellen eine 1 als "0001" ausgeben musst, eine 33 als "0033", etc.

    ich hab mir mal eine lösung zusammen gebastelt die auch funktioniert, aber wie ist das mit dem speicher wenn ich solche funktionen (strlen, strcat) nutze gut/schlecht?
    verbrauch ich da zuviel speicher?
    gibt es eine speicher sparendere lösung?
    hier mein code:

    Code:
    itoa(vork_spann, buffer, 10.0);
    			uart_puts("\n\r Spannung: ");
    			uart_puts(buffer);
    			uart_putc(',');
    			
    			
    			itoa( nachk_spann, buffer, 10.0);
    			char ausgabe[5] = "";
    			uint8_t charanz;
    			
    			if(strlen(buffer) <=4){ // fals ein ergebnis mit x,0032
    			for(charanz = strlen(buffer); charanz <=3 ;charanz ++){
    			strcat(ausgabe,"0");// mit nullen ergänzen auf 4 stellen
    			}
    			strcat(ausgabe,buffer);//wert anhängen
    			}
    			else{
    			strcat(ausgabe,buffer);//umleiten in den ausgabe string
    			}
    			uart_puts(ausgabe);
    besten dank

Berechtigungen

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

Labornetzteil AliExpress