Table of Contents

Potentiometer

Notwendiges Wissen: [HW] Sensors Module, [HW] User Interface Module, [ELC] Voltage Divider, [AVR] Analog-to-digital Converter, [LIB] Analog to Digital Converter, [LIB] 7-segment LED Display

Theorie

elektrisches Symbol eines Potentiometers

Ein Potentiometer ist ein elektronisches Widerstandsbauelement mit drei Anschlüssen. Zwischen den beiden Seitenkontakten ist der Widerstand fix, zwischen Seiten- und Mittelkontakt ist er variabel. Im Grunde ist ein Potentiometer ein Spannungsteiler, dessen Widerstand zwischen den Seiten- und Mittelkontakten hergestellt wird.

einfaches Drehpotentiometer

Ein typisches Potentiometer besteht aus einem Widerstand mit einer leitenden Oberfläche und einem Schiebekontakt (slider). Je näher der Schiebekontakt am Rand des Widerstandes angebracht ist, desto geringer ist der Widerstand zwischen Slider und Ecke des Widerstands und umgekehrt. Ein Material mit hohem Widerstand oder einer Spule aus Widerstandsdraht kann als Widerstand fungieren. Bei einigen Potentiometern sind die Beziehungen zwischen Widerstand und Sliderposition linear oder logarithmisch. Potentiometer sind normalerweise einfache Drehpotentiometer (siehe Bild), es gibt aber auch Schiebepotentiometer. Ein spezieller Typ von Potentiometer sind digitale Potentiometer, bei denen die Regulation des Widerstands intern über Signale geschieht.

Übung

Am HomeLab Modul befindet sich ein 4,7 kΩ Drehpotentiometer. Das Potentiometer ist mit der Masse und dem +5 V Potential angeschlossen, und der Schiebekontakt ist am Kanal 3 des analog-digital Konverters angeschlossen. So kann der Spannungsoutput des Potentiometers zwischen 0 und 5 V reguliert werden. Der digitale Wert der Potentiometeroutputspannung kann gemessen werden indem die Vergleichsspannung vom AVR digital-analog Konverter vom AVCC Pin genommen wird. die Folgende Funktionen für den ACR ADC sind in der HomeLab Bibliothek enthalten.

//
// Data types for adjustment
//
typedef enum
{
	ADC_REF_AREF = 0x00,
	ADC_REF_AVCC = 0x01,
	ADC_REF_2V56 = 0x03
}
adc_reference;
 
typedef enum
{
	ADC_PRESCALE_2   = 0x01,
	ADC_PRESCALE_4   = 0x02,
	ADC_PRESCALE_8   = 0x03,
	ADC_PRESCALE_16  = 0x04,
	ADC_PRESCALE_32  = 0x05,
	ADC_PRESCALE_64  = 0x06,
	ADC_PRESCALE_128 = 0x07
}
adc_prescale;
 
//
// Starting the ADC
//
void adc_init(adc_reference reference, adc_prescale prescale)
{
	// Allowing ADC to operate, selecting the frequency divider
	ADCSRA = bit_mask(ADEN) | (prescale & 0x07);
 
	// Selecting comparison voltage 
	ADMUX = (reference & 0x03) << REFS0;
}
 
//
// Converting the values of selected channel
//
unsigned short adc_get_value(unsigned char channel)
{	
	// Setting the channel
	ADMUX = (ADMUX & 0xF0) | (channel & 0x0F);
 
	// Starting the conversion
	bit_set(ADCSRA, ADSC);
 
	// Waiting the end of the conversion
	while (bit_is_set(ADCSRA, ADSC))
	{
		asm volatile ("nop");
  	}
 
	// Returning the results
	return ADCW;
}

Die Funktion adc_init muss zu Beginn des Programms ausgeführt werden. Sie sorgt dafür, dass der ADC funktioniert. Die Vergleichsspannung muss entweder vom AREF oder AVCC Pin kommen, oder es muss die eingestellte interne Spannung von 2,56 V ausgewählt werden. Dazu muss der Taktzyklus des Konverters mit einem Vorzähler gesetzt werden (Faktor des Frequenzteilers), welcher den Taktzyklus des Controllers teilt. Die Umsetzung ist schneller, wenn höhere Taktzyklen verwendet werden, jedoch kann die Genauigkeit drunter leiden. Die Funktion adc_get_value dient zur Messung. Es kann der Kanal gewählt werden und sie gibt 10-Bit Ergebnisse als ganze 16-Bit Zahlen aus. Die Funktion zur Messung wartet bis die Konversion beendet ist und gibt das Ergebnis erst dann aus.

In den zuvor erklärten Beispielprogrammen werden die Bibliotheken des ADC und des 7-Segment-Zifferanzeige genutzt. Der 10-Bit Wert des ADC wird mit 10 multipliziert und durch 1024 dividiert um einen Wert zwischen 0 und 9 zu erhalten. Der Wert 10 kann nicht erreicht werden, weil in C nur ganzzahligewerte berechnet werden und keine gerundeten Ergebnisse. Um die Genauigkeit des Ergebnisses zu erhöhen, wird eine Funktion zur Berechnung des Durchschnitts der Ergebnisse des ACSs genutzt. Daraus abgeleitet gibt das Programm auf der Anzeige einen Wert von 0 bis 9 aus, welcher der Position des Potentiometers entspricht.

//
// Beispielprogramm für das Potentiometer des Sensormoduls
// Die Position des Potentiometers wird auf der 7-Segmentanzeige dargestellt
//
#include <homelab/adc.h>
#include <homelab/module/segment_display.h>
 
//
// Auswahl des Kanals
//
//  1 = Photoresistor
//  2 = Thermistor
//  3 = Potentiometer
//
#define ADC_CHANNEL 3
 
//
// Hauptprogramm
//
int main(void)
{
	int value;
 
	// Anpassung der 7-Segmentanzeige
	segment_display_init();
 
	// Anpassung des ADC
	adc_init(ADC_REF_AVCC, ADC_PRESCALE_8);
 
	// Endlosschleife
	while (true)
	{
		// Liest viermal gerundete Werte aus dem Kanal
		value = adc_get_average_value(ADC_CHANNEL, 4);
 
		// Zeigt Hunderter des angezeigten Wertes an
		segment_display_write(value * 10 / 1024);
	}
}