Necessary knowledge : [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
Connaissances nécessaires : [HW] sensor, [HW] digi, [ELC] Diviseur de tension, [AVR] Convertisseur analogique - numérique, [LIB] Convertisseur analogique numérique, [LIB] segment_display
Le potentiomètre est une résistance à trois bornes, qui règle la résistivité entre ses deux contacts sur les bords et le contact central, tel une résistance variable. Le potentiomètre est un atténuateur (diviseur de tension), où la résistance est formée entre les contacts des bords et le contact central.
Un potentiomètre classique consiste en une résistance avec des surfaces conductrices d’électricité et d'un contact glissant appelé curseur. Plus le curseur est proche du bord de la résistance, plus petite est la résistance entre le curseur et ce bord et vice versa. Une matière qui a une haute résistivité ou une bobine de fil. Il y a les potentiomètres qui sont basés sur des relations linéaires ou logarithmiques entre la résistance et la position du curseur. Les potentiomètres sont principalement des potentiomètres rotatifs simples (exemple sur l'image), mais il existe aussi des potentiomètres glissants. Il existe un type spécifique de potentiomètres qui sont les potentiomètres numériques, avec lequel la variation de la résistance est réalisée selon les signaux dans le micro schéma.
Dans le module du HomeLab il y a un potentiomètre rotatif de 4.7 kΩ. Ce potentiomètre est connecté entre la terre et un potentiel de +5V puis le curseur est connecté à la voie 3 du convertisseur analogique-numérique. Connecté tel quel, la tension de sortie du potentiomètre peut varier entre 0 et 5V La valeur numérique de la tension de sortie du potentiomètre peut être mesuré dans sa plage entière si la tension de comparaison du convertisseur analogique-numérique est pris depuis la broche AVCC. Dans la librairie du HomeLab on retrouve les fonctions suivantes pour utiliser l’AVR ADC :
// // 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; }
La fonction adc_init
doit être appelée au début du programme, elle est utilisée pour initialiser l’ADC. La tension de référence doit être choisie entre la broche AREF ou la broche AVCC, il est tout de même possible de fixer une tension interne de 2,56V. De plus, il est nécessaire d’initialiser l’horloge du convertisseur en configurant le prescaler (facteur de division de fréquence), qui peut être utilisé pour diviser le cycle de l’horloge du contrôleur. La conversion est plus rapide lorsqu’on utilise un plus grand cycle de l’horloge mais dans ce cas la précision pourrait en souffrir. Afin de la mesurer on utilise la fonction adc_get_value
, qui permet de sélectionner la voie et retourne un résultat de 10 bits sous forme d’un entier de 16 bits. La fonction servant à mesurer est verrouillée, cela signifie qu’elle ne retourne un résultat qu’après la fin de toutes les mesures.
Dans cet exemple on a déjà expliqué le convertisseur analogique-numérique et on utilise la librairie concernant l’afficheur 7 segments. La valeur de 10 bits du convertisseur analogique-numérique est multipliée par 10 et divisée par 1024 afin d’obtenir une valeur entre 0 et 9. La valeur 10 est impossible parce que lorsqu’on divise en langage C seules les valeurs entières sont calculées, pas les résultats exacts. Pour avoir un résultat avec plus de précision on utilise la fonction de résultat moyen du calculateur. Comme résultat le programme indique le numéro entre 0 et 9 qui correspond à la position du potentiomètre sur l’indicateur.
// // Example program of potentiometer on the Sensor module // The position of the potentiometer is displayed on the 7-segment indicator // #include <homelab/adc.h> #include <homelab/module/segment_display.h> // // Selecting the channel // // 1 = photoresistor // 2 = thermistor // 3 = potentiometer // #define ADC_CHANNEL 3 // // Main program // int main(void) { int value; // Adjusting 7-segment indicator segment_display_init(); // Adjusting ADC adc_init(ADC_REF_AVCC, ADC_PRESCALE_8); // Endless loop while (true) { // Reading 4 times rounded values of the channel value = adc_get_average_value(ADC_CHANNEL, 4); // Displaying the hundreds of the indicated value segment_display_write(value * 10 / 1024); } }