  ## How to get started with microcontrollers - Part 2

Interfacing with a computer, controlling motors, servos etc.

 Author: Aki Korhonen Published: 06.05.2009 In English Suomeksi

### Example 2.3 - Reading the value of a potentiometer

Thing to learn: using PWM and ADC (Analog to Digital Converter)

Lets add some control to the fading and use the internal A/D-converter to read the value from a potentiometer. This time there are two code examples for the same circuit.

Parts:
• ATiny45
• 100 nF capacitor
• Red led
• 270 ohm resistor, current limiting resistor for the led (use LedCalc to calculate the right resistor for different leds)
• 100k ohm resistor
• 10k ohm (or bigger) potentiometer Example 2.3 Example 2.3

This first code example is a microcontroller version of Metku's old ColorFade. There is some difference in the fading method also as ColorFade is based on an analog circuit where the fading depends on the values of some parts and in this version everything is done digitally in software.

```
/**
* MetkuMods - http://metku.net/
* How to get started with AVR microcontrollers, part 2
* Example 2.3.1 - Reading the value of a potentiometer
*
* Author: Aki Korhonen
* Date: 2009-04-29
*/

// If clock speed isn't set in the project settings then it is set here
#ifndef F_CPU
#define F_CPU 1000000UL // 1 MHz
#endif

#include <avr/io.h>
#include <inttypes.h>

#include <util/delay.h>

// Led at PB0, (OCR0A)
#define LED 0

// Potentiometer slide at PB2, (ADC1)
#define POT 2

// Min and max values for the PWM
// You can fine tune how bright and dim the led goes
// Minimum for MIN is 0 and maximum for MAX is 255
#define PWM_MIN 0
#define PWM_MAX 128

int main(void)
{
// PB2 in, others out
DDRB = 0b11011;
PORTB = 0x00;

// Value for the register
// "value" equals brightness of the led
// 0 = off | 255 = full brightness
uint8_t value = 0;
uint8_t step = 1;
uint16_t delay = 10;
uint16_t i = 0;

// -------------------------
// Initialize PWM

// 8-bit PWM, Phase correct
// 8 bits give us 256 levels of brightness
TCCR0A |= (1<<WGM00);

// Clear OC0A/OC0B on Compare Match
// Set OC0A/OC0B at BOTTOM (non-inverting mode)
TCCR0A |= (1<<COM0A1);

// Set prescaler to 8
// 1 MHz / 8*256 = ~490 Hz PWM frequency
TCCR0B |= (1<<CS01);

// -------------------------
// Initialize ADC

// Enable ADC
ADCSRA = (1<<ADEN);

// Select ADC1
ADMUX |= (1<<MUX0);

// Use Vcc as voltage reference
ADMUX &= ~(1<<REFS1) | ~(1<<REFS0);

// Select divider factor 8, so we get 1 MHz/8 = 125 kHz ADC clock
ADCSRA |= (1<<ADPS1) | (1<<ADPS0);

// -------------------------

// The program reads the ADC value from the potentiometer slide
// all the time and calculates a delay between the steps.
while(1)
{
// Write the value to the Output Compare Register A
OCR0A = value;

// Increment the value by step
value += step;

// If we reach the maximum value, invert the direction and vice versa
if(value >= PWM_MAX)
step *= -1;
else if(value <= PWM_MIN)
step = 1;

// Start ADC conversion
ADCSRA |= (1<<ADSC);

// Wait until the conversion is ready
loop_until_bit_is_set(ADCSRA, ADSC);

// Calculate the delay between steps
// Min: 20 ms
// Max: 127 ms
delay = 20 + ((ADCW/8)-20);

// Wait for the calculated time.
// For-loop here because _delay_ms didn't
// like a variable as a parameter.
for(i=0 ; i<delay ; i++)
_delay_ms(1);
}

return 0;
}

```

In this second example the circuit is still the same but the potentiometer controls the brightness of the led instead of the speed of fading.

Tip: If you replace the led part of the circuit in this example with the motor part from the first example, you could then control the speed of the motor with the potentiometer.

```
/**
* MetkuMods - http://metku.net/
* How to get started with AVR microcontrollers, part 2
* Example 2.3.2 - Reading the value of a potentiometer
*
* Author: Aki Korhonen
* Date: 2009-04-29
*/

// If clock speed isn't set in the project settings then it is set here
#ifndef F_CPU
#define F_CPU 1000000UL // 1 MHz
#endif

#include <avr/io.h>
#include <inttypes.h>

#include <util/delay.h>

// Led at PB0, (OCR0A)
#define LED 0

// Potentiometer slide at PB2, (ADC1)
#define POT 2

int main(void)
{
// PB2 in, others out
DDRB = 0b11011;
PORTB = 0x00;

// Value for the register
// "value" equals brightness of the led
// 0 = off | 255 = full brightness
uint8_t value = 0;

// -------------------------
// Initialize PWM

// 8-bit PWM, Phase correct
// 8 bits give us 256 levels of brightness
TCCR0A |= (1<<WGM00);

// Clear OC0A/OC0B on Compare Match
// Set OC0A/OC0B at BOTTOM (non-inverting mode)
TCCR0A |= (1<<COM0A1);

// Set prescaler to 8
// 1 MHz / 8*256 = ~490 Hz PWM frequency
TCCR0B |= (1<<CS01);

// -------------------------
// Initialize ADC

// Enable ADC
ADCSRA = (1<<ADEN);

// Select ADC1
ADMUX |= (1<<MUX0);

// Use Vcc as voltage reference
ADMUX &= ~(1<<REFS1) | ~(1<<REFS0);

// Select divider factor 8, so we get 1 MHz/8 = 125 kHz ADC clock
ADCSRA |= (1<<ADPS1) | (1<<ADPS0);

// -------------------------

// The program reads the ADC value from the potentiometer slide
// all the time and updates the PWM register with that value so
// the led brightness is controlled with the potentiometer.
while(1)
{
// Start ADC conversion
ADCSRA |= (1<<ADSC);

// Wait until the conversion is ready
loop_until_bit_is_set(ADCSRA, ADSC);

// Read the ADC value and scale it to 8-bit value
// because the ADC is 10-bit (1024 values) and the
// PWM register is only 8-bit (256 values), 1024/256 = 4
value = (uint8_t)(ADCW/4);

// Write the value to the Output Compare Register A
OCR0A = value;

// Wait for 2 ms
_delay_ms(2);
}

return 0;
}

``` Pages:  1 2 3 4 5 6  .:Back to top Bandwidth by Copyright © Metku.net, All Rights Reserved. All content and graphics in MetkuMods are sole property of Jani Pönkkö and may not be reproduced or copied in any manner without written permission from him. All brand names, trademarks and copyrights are the property of their respective owners.Privacy Policy