- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 9 von 9

Thema: Widerstandswert ( Poti ) mit nur einem I/O Pin einlesen ?

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

    Widerstandswert ( Poti ) mit nur einem I/O Pin einlesen ?

    Anzeige

    Praxistest und DIY Projekte
    Hallo,

    Ich möchte gern meinen AVR dazu benutzen eine Regelung zu machen.

    Dazu muss ich mehrere Potis einlesen in nur einen µC.

    Ich hab mir das so vorgestellt:
    Code:
    Vcc
    |
    C1: 100nF 
    |
    +---(R2 220)---->µC
    |
    |
    Poti 10K
    |
    -
    GND
    Dazu muss der Pin am µC als Ausgang auf HING gesetzt werden.

    Dadurch dass an C1 nun an beiden Seiten +5V anliegen, wird dieser entladen.

    Schaltet man nun den Pin des µC als Eingang, so wird C1 über das Poti geladen.

    Nach einer bestmmten Zeit unterschreitet die Spannung am Pin des µC die "schwellspannung von ca. 2.2V und der µC hat ein LOW auf seinem Eingang.


    Diese Methode habe ich aus einer Anleitung herausgelesen und hoffentlich richtig interpretiert.

    Leider weiss ich nochnicht wie ich einen Pin des µC als Eingang und gleichzeitig als Ausgang benutzen kann.

    in der anleitung ging es mit dem Befehl "__mmio" (Memory mapped I/O)
    Das will der Compiler aber nicht, sagt immer error.

    hier mal mein Code (Verwendet wurde pin 0 von Port A):

    Code:
    #include <io.h>
    
    typedef unsigned short WORD;
    typedef unsigned char  BYTE;
    
    
    int main (void)
    
    {
        volatile WORD   x;
        register WORD   y;
    
        // Portpin auf Ausgang setzen. 
        __mmio (DDRA) = __mmio (DDRA) | (1 << 0);
    
        // Portpin auf HIGH setzen
        __mmio (PORTA) = __mmio (PORTA) | (1 << 0);
    
        // Kondensator entladen, indem der Ausgang auf HIGH (Vcc) gesetzt wird.
        for (x=0; x<50;) x++ /* Zaehlen */;
    
        y = 0;
    
        // Portpin auf Eingang schalten.
        __mmio (DDRA) = __mmio (DDRA) & ~(1 << 0);
    
    
        /* Zaehlschleife.
           Wir zaehlen y so lange hoch bis der Kondensator unter die
           Schwellwertspannung geladen ist. */
        while (__mmio (PINA) & (1 << 0) && y < 65535) y++;
    
        // Zählerwert zurückgeben
        return y;
    
    }
    Kann von euch jemand evtl den Fehler finden?
    Oder mir eine einfachere Programmvariante nennen?

    Ich hab schon das ganze Forum durchstöbert und konnte leider nichts treffendes finden.

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Hi, Ich find beim Winavr nur
    __MMIO_BYTE () u.
    __MMIO_WORD ()
    und die in <sfr_defs.h>
    Soll nix heißen, aber wenn keiner was besseres weiß, kannst du ja probieren. mfg

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    10.08.2004
    Ort
    Großbardorf
    Alter
    37
    Beiträge
    674
    könnte man das nicht auch mit dem AD-Converter des AVR machen, indem man eine Spannungsteilerschaltung (mit Poti und festem Widerstand) aufbaut, bei der der AVR zwischendrin die Spannung misst und in Poti-Wert umrechnet?

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Wie auch immer, der Trick is nicht schlecht, den verwendet im Prinzip LEGO Mindstorms für seine Sensoren. Alle (aktiven) Sensoren haben Graetz-Gleichrichter, mit dem sie den kurzen Out-Impuls in passenden Saft verwandeln. Man spart draht und kann anstecken, wie man will (is ja für Kinder). mfg robert

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    37
    Beiträge
    795
    Hallo,

    @ Pascal

    A/D Wandler wollt ich auch schon benutzen, aber die µC haben leider, so viel ich weiß, keine 5 Stück...





    Ich finde das Prinzip auch super,

    Vor allem weil man fast keine Komponenten braucht und jeden beliebigen Port-Pin verwenden kann.

    Im Prinzip bräuchte ich nur einen Befehl mit dem ich einen Pin als ausgang UND Eingang verwenden kann...

    Falls das nicht gehd muss ich halt nen zweiten Pin benutzen, und mit diesem immer wieder den Kondensator Entladen ( über Diode dazuschalten ):

    Code:
    Vcc+5V
    |
    |
    C1 100nF
    |
    |
    +--- ( |< Diode )---( 220R )---µC "entlade Pin "
    |
    +-----------------------µC "lesepin"
    |
    |
    Poti 10K
    |
    |
    _
    GND
    (Diode ist nötig, da ja sonst wenn der Ausgang auf LOW steht, GND am eingang anliegt und das ergebnis hinfällig macht....

    Der Programmablauf müsste im Grunde nur folgendermaßen aussehen:

    - Entlade C1: Ausgang auf HIGH ( zB 50ms lang, je nach Kondensatorgröße )
    - Umschalten auf Eingang (entladevorgang abschalten) und zählen bis LOW anliegt
    - Zählerwert ausgeben und zurücksetzen

    das Ganze ständig wiederholen.


    Wär halt cool wenn man dafür nur einen Pin bräuchte.

    Vielen Dank für eure Bemühungen!

    mfg

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Hi, also das Out-definieren mach ich beim Winavr direkt DDRx = 0x11
    Mit dem AD Wandler müßtest du dich noch auseinandersetzen, damit er inzwischen Ruhe gibt
    Vielleicht geht das auch überlappt, d.h wenn du einen PIN High setzt zum C-Laden, kann er ja derweil einen anderen Kanal digitalisieren, mfg

  7. #7
    Gast
    Hallo

    hier ein Link zum Thema

    http://www.atmel.com/dyn/resources/p...ts/DOC0942.PDF


    Dieter

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    10.08.2004
    Ort
    Großbardorf
    Alter
    37
    Beiträge
    674
    A/D Wandler wollt ich auch schon benutzen, aber die µC haben leider, so viel ich weiß, keine 5 Stück...
    die haben vielleicht keine 5 ADCs, aber dafür einen 6 oder 8 kanaligen ADC, du kannst also, je nach AVR, bis zu 8 analoge Signale einlesen(zeitlich versetzt)

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    37
    Beiträge
    795
    @ Pascal

    Muss ich ganz ehrlich zugeben, das mit den Kanälen hab ich nicht gewusst... Muss ich mich noch einlesen.

    @ Gast,

    Danke für den Link, werd ich mir demnächst mal vornehmen


    Ich hab in der zwischenzeit schon experimentiert und das Programm für die " 2-Pin-Variante" geschrieben. ist evtl. noch ein bisschen umständlich,

    muss noch optimiert werden:


    Code:
    #include <avr/io.h>
    
    
    typedef unsigned char  BYTE;
    typedef unsigned int   WORD;
    
    WORD	entladedauer;		// Variable für Entladungsdauer
    WORD	entladen_1;			// Variable zum zählen der Entladungsdaue
    WORD	poti_1;				// Variable zum zählen des Widerstandswertes
    
    
    
    
    
    int main(void)
    {
    
        outp (0x01,DDRA);	// PORT A:  PIN 0 als Ausgang, Rest Eingang
        outp (0xFF,DDRB);	// PORT B:  Ausgabe des ermittelten Wertes
    
    entladedauer = 500;		// hier wird die entladedauer festgelegt...
    entladen_1 = 0;			
    poti_1 = 0;				
    
    
        
        for(;;)
        {
    	
    	if( entladen_1 >= entladedauer ) {		// Wenn lange genug entladen
    		cbi (PORTA, 0); 						// entladung stoppen ( Pin0 auf LOW )
    		
    		if( !bit_is_clear (PINA, PIND1)) {		// solange der zählpin HIGH ist, zählen
    		poti_1++;
    		}
    		if( bit_is_clear (PINA, PIND1)) {		//wenn Zählpin LOW wird,
    		outp (poti_1, PORTB);						//Wert des Widerstands ausgeben
    		poti_1 = 0;									//Wert zurücksetzen für neue Messung
    		entladen_1 = 0;								//Wert zurücksetzten für neue Entladung
    		}
        }else{									// ansonsten wenn Kondensator nicht genügend entladen,
    		sbi (PORTA, 0); 					// entladen ( PIN0 auf HIGH )
    		entladen_1++;
    	}
    	
    	}
    }

    Bei einem Poti mit 10K und einem Kondensator mit 100nF
    Erhalte ich am Ausgangsport Werte zwischen 0 und 40.

    nicht gerade die beste Auflösung, aber ich werd mal mit den Kondensator und Potiwerten Experimentieren.


    Ansonsten Funktioniert es einwandfrei.


    Was meint ihr dazu?
    ist es umständlicher oder einfacher als über A/D wandler?

    (hier bin ich nicht pingebunden....)

Berechtigungen

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

12V Akku bauen