# CircuitPython Basics: Analog Inputs & Outputs

## Analog Signals

Primary: This guide is older. You'll want to refer to the guide CircuitPython Essentials which has an Analog IO pages and much more.

### CircuitPython Essentials - CircuitPython Analog In

[CircuitPython Essentials](https://learn.adafruit.com/circuitpython-essentials)
[CircuitPython Analog In](https://learn.adafruit.com/circuitpython-essentials/circuitpython-analog-in)
### CircuitPython Essentials - CircuitPython Analog Out

[CircuitPython Essentials](https://learn.adafruit.com/circuitpython-essentials)
[CircuitPython Analog Out](https://learn.adafruit.com/circuitpython-essentials/circuitpython-analog-out)
### CircuitPython Essentials - CircuitPython PWM

[CircuitPython Essentials](https://learn.adafruit.com/circuitpython-essentials)
[CircuitPython PWM](https://learn.adafruit.com/circuitpython-essentials/circuitpython-pwm)
https://www.youtube.com/watch?v=0pUBP0k5WD4

Analog inputs and outputs are important for interacting with many types of sensors and other devices. This guide will explore what an analog signal is and how it differs from digital signals, how to read analog signals, and how to output analog signals with CircuitPython.

# Analog Signals

Analog signals are different from digital signals in that they can be _any_ voltage and can vary continuously and smoothly between voltages. An analog signal is like a dimmer switch on a light, whereas a digital signal is like a simple on/off switch.&nbsp;

Digital signals only can ever have two states, they are either are **on** (high logic level voltage like 3.3V) or **off** (low logic level voltage like 0V / ground).

By contrast, analog signals can be any voltage in-between on and off, such as 1.8V or 0.001V or 2.98V and so on.

Analog signals are continuous values which means they can be an _infinite_ number of different voltages. Think of analog signals like a floating point or fractional number, they can smoothly transiting to _any_ in-between value like 1.8V, 1.81V, 1.801V, 1.8001V, 1.80001V and so forth to infinity.

Many devices use analog signals, in particular sensors typically output an analog signal or voltage that varies based on something being sensed like light, heat, humidity, etc. Some examples of sensors with analog outputs:

- [Microphones](https://www.adafruit.com/product/1063)
- [Photocells (light sensitive resistors)](https://www.adafruit.com/product/161)
- [Temperature sensors](https://www.adafruit.com/product/165)
- [Force-sensitive resistors](https://www.adafruit.com/product/166)
- [Flex sensors](https://www.adafruit.com/product/1070)
- [Thermistor (temperature sensitive resistor)](https://www.adafruit.com/product/372)
- [Ultraviolet light sensor](https://www.adafruit.com/product/1918)
- [Light sensors](https://www.adafruit.com/product/2748)
- [Distance sensor](https://www.adafruit.com/product/164)
- [Anemometer (wind speed sensor)](https://www.adafruit.com/product/1733)
- [Resistive touch screen](https://www.adafruit.com/product/333)
- [Ultrasonic distance sensor](https://www.adafruit.com/product/979)
- [Liquid level sensor](https://www.adafruit.com/product/464)
- [Potentiometer (variable resistor)](https://www.adafruit.com/product/356)

The are also some devices that can be controlled by analog signals or varying voltages:

- [Simple LEDs and other lights](https://www.adafruit.com/category/90)
- [Speakers](https://www.adafruit.com/product/1898)
- [Transistors (to amplify signals)](https://www.adafruit.com/product/756)

And there are some devices that are controlled by a special type of analog-like signal called a pulse-width modulated, or PWM, signal. You’ll learn more about PWM signals at the end of this guide, but some devices that can be driven by a PWM signal are:

- [Simple LEDs and other lights](https://www.adafruit.com/category/90)
- [Servo motors](https://www.adafruit.com/product/169)
- [DC motors](https://www.adafruit.com/product/711)

# CircuitPython Basics: Analog Inputs & Outputs

## Analog to Digital Converter (Inputs)

An analog to digital converter (or ADC) is a device that reads the voltage of an analog signal and converts it into a digital, or numeric, value. The microprocessor in your development board can’t deal with analog signals directly because they can be an _infinite_ range of values. However if the analog signal is converted into a numeric value then it can be processed and reasoned about by the microprocessor just like any other number. The ADC is the key to reading analog signals and voltages with a microprocessor.

Typically development boards have one or more built-in analog to digital converters. Check your board’s documentation for details on the number of ADCs and which pins are used as inputs for them (some boards like the Metro M0 Express, Circuit Playground Express, Trinket M0, and Gemma M0 note their analog inputs with names like A0, A1, etc.).

Along with the number of analog to digital converters your board’s documentation also might mention the resolution or ‘bits’ used by the ADC. The resolution of the ADC controls how accurately it can read a voltage. For example a 12-bit ADC can represent analog voltages with 12-bit values, i.e. 0 to 4095 (use the equation 2^12 - 1 to understand how the number of bits relates to the possible values). This means the 12-bit ADC can see 4096 different voltages (remember 0 is a unique value too). That’s a lot of voltages, but remember analog signals have an infinite range of values so there might be cases where two measurements aren’t different enough for the ADC to measure and will appear as the same numeric value!

To understand the accuracy of an ADC you also need to understand its range of possible input values. Again check your board’s documentation to see how it defines (or lets you define) its analog reference voltage. The reference voltage sets the range of possible input voltages the ADC can measure. When the ADC reads the voltage it will see where it falls within the range of input voltages and output a number that falls within the same range of its bit resolution.

For example if a 12-bit ADC has a reference voltage of 3.3 volts (a typical value for most ADCs built-in to microprocessors) and reads a 2.5 volt value you can calculate the value output by the ADC (try running this in an interactive Python REPL):

```auto
&gt;&gt;&gt; int(2.5 / 3.3 * 4095)
3102
```

This means the ADC would return a value of 3102 for an input of 2.5 volts! You can try other input voltages too, like 0.1 volt:

```auto
&gt;&gt;&gt; int(0.1 / 3.3 * 4095)
124
```

Notice it returns a much smaller value of 124. What if you ever so slightly increase the voltage to 0.1001 volts?

```auto
&gt;&gt;&gt; int(0.1001 / 3.3 * 4095)
124
```

Wow you get the same 124 value even though the input voltage is slightly higher! This highlights a constraint of analog to digital converters that their analog reference range and bit resolution dictate the accuracy of voltage measurements. If you want to read very small changes in voltage you need a higher bit ADC, like 24 or even 32 bits of range, or a much smaller and more constrained reference voltage range.

To demonstrate the analog to digital converter you can read the voltage output by a potentiometer. A potentiometer is a small variable resistor that you can twist a knob or shaft to change its resistance. By wiring the potetiometer to your board in a special way (called a voltage divider) you can turn the change in resistance into a change in voltage that your board’s analog to digital converter can read. You’ll need the following parts to try this:

- [A potentiometer.](https://www.adafruit.com/product/356) Almost any potentiometer will work as long as it has 3 pins. A potentiometer is like a resistor and classified by its resistance in ohms (typically 1, 10, 100, etc. kilo-ohms). By twisting the knob or shaft on the potentiometer you can change the resistance of the middle pin (called the wiper) to be anywhere inbetween the range of resistance of the potentiometer.
- A breadboard and wires to connect the components and board together.

Connect the components to your board as follows:

![](https://cdn-learn.adafruit.com/assets/assets/000/045/775/medium800/circuitpython_02_analog_io_figure_1.png?1503704883)

- One of the outer legs of the potentiometer to the board ground or GND pin.
- The opposite outer leg of the potentiometer to the board 3.3 volt output.
- The middle leg of the potentiometer to an analog input of the board, like A0.

Now at the REPL import the [`analogio`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/ __init__.html#module-analogio "analogio: Analog hardware support (SAMD21, ESP8266)") and [`board`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/board/ __init__.html#module-board "board: Board specific pin names (SAMD21)") module to create an instance of the [`analogio.AnalogIn`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/AnalogIn.html#analogio.AnalogIn "analogio.AnalogIn") class:

```auto
&gt;&gt;&gt; import board
&gt;&gt;&gt; import analogio
&gt;&gt;&gt; adc = analogio.AnalogIn(board.A0)
```

Notice the [`analogio.AnalogIn`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/AnalogIn.html#analogio.AnalogIn "analogio.AnalogIn") class initializer needs to be told which pin will be used as the analog input. In this case the board pin A0 is being used as the ADC input.

Once the analog input is initialized you’re ready to start reading from it with the [`analogio.AnalogOut.value`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/AnalogOut.html#analogio.AnalogOut.value "analogio.AnalogOut.value") property. Simply read the value property to see the numeric output of the ADC:

```auto
&gt;&gt;&gt; adc.value
32683
```

Try twisting the knob of the potentiometer and reading the value property again, for example twist the knob all the way towards the ground input:

```auto
&gt;&gt;&gt; adc.value
65
```

If you read the value a few times you might notice the value changes a bit but stays around a low value near zero. Remember analog signals can be an infinite range of values so even though the potentiometer knob hasn’t moved, the voltage read by the ADC might be very slightly changing based on heat, electrical interference, vibrations, etc. that can affect analog devices and signals.

If you twist the knob of the potentiometer all the way to the other extreme near 3.3 volts and read its value:

```auto
&gt;&gt;&gt; adc.value
65476
```

You should see a very high value near 65000. As the voltage to the analog input increased the ADC value increased too!

As an aside if you have a multimeter try using it to measure the voltage output from the potentiometer. Connect the positive lead of the probe to the center output pin of the potentiometer and the ground lead of the probe to the ground pin of your board or potentiometer. Set the meter to read DC voltage and watch how the voltage and ADC value change as you twist the potentiometer knob. Remember the ADC is just converting the voltage into a number so as the voltage measured by the meter increases you’ll also see the ADC value increase!

For ADC values in CircuitPython you’ll find they’re all put into the range of 16-bit unsigned values. This means the possible values you’ll read from the ADC fall within the range of 0 to 65535 (or 2^16 - 1). Remember when you twisted the potentiometer knob to be near ground you saw a value close to zero and when you twisted it to the other extreme near 3.3 volts you saw a value close to 65535–you’re seeing almost the full range of 16-bit values!

One important note about this 16-bit range is that it applies even if your board’s ADC has a different resolution (like 10 or 12 bits). Using 16-bits as a base resolution is handy to make code work across many different boards but be aware you might not actually be getting 16-bits of resolution from your ADC. Check your board’s documentation to see the true resolution of its ADC.

Finally there’s one more handy property of the [`analogio.AnalogIn`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/AnalogIn.html#analogio.AnalogIn "analogio.AnalogIn") class, the `analogio.AnalogIn.reference_voltage`. This property lets you read the reference voltage used by the ADC to convert voltages into numbers. This is useful to convert the number you read from the ADC into an actual voltage value. Try running this code to read the ADC value and convert it into voltage using the reference voltage:

```auto
&gt;&gt;&gt; adc.value / 65535 * adc.reference_voltage
3.2998
```

Twist the potentiometer knob and run the same line again to see how the voltage value changes!

You can also wrap the above equation into a Python function that's easy to call and convert ADC values into voltages:

```auto
&gt;&gt;&gt; def adc_to_voltage(val):
...    return val / 65535 * 3.3
&gt;&gt;&gt; adc_to_voltage(adc.value)
3.2998
```

# CircuitPython Basics: Analog Inputs & Outputs

## Digital to Analog Converters (Outputs)

A digital to analog converter (also called a DAC) is a piece of hardware that can take a numeric, or digital, value and turn it into a voltage, or analog value. This is useful for interfacing with devices that expect varying analog signals, like controlling the intensity of a LED or driving a speaker to play sounds. Not all boards and processors support a digital to analog converter so check your board’s documentation to see if it has such a feature.

Luckily the Atmel SAMD21 processor used in many CircuitPython boards like the Circuit Playground Express and Metro M0 express have a digital to analog converter built-in. **Note: Not all CircuitPython boards have a digital to analog converter.**

To demonstrate the digital to analog converter you can control the voltage output by a pin to brighten and dim a LED. You’ll need the following components:

- [A single color LED.](https://www.adafruit.com/product/777) You want a simple single color LED and not a fancier multi-color LED or NeoPixel. Look for a LED that has two legs, a short one and long one. Check out [the Adafruit LED guide](../../../../all-about-leds/overview) for more details on LEDs.
- [A resistor in the range of 300-1,000 ohms.](https://www.adafruit.com/product/2781) You _must_ use a resistor when wiring up a LED to your board or else you might damage the digital output on the board. The resistor limits the amount of current to the LED and prevents damage to the board or LED. The exact value of the resistor isn’t super important for this demonstration–pick any resistor in the 300-1,000 ohm range.
- A breadboard and wires to connect the components and board together.

Connect the components to your board as follows:

![](https://cdn-learn.adafruit.com/assets/assets/000/045/776/medium800/circuitpython_02_analog_io_figure_2.png?1503705158)

- The short leg (cathode) of the LED connects to one end of the resistor.
- The other end of the resistor connects to the ground or GND pin of the board.
- The long leg (anode) of the LED connects to a the digital to analog converter output of your board. You might need to check your board’s documentation to find this pin. On the Metro M0 Express and Circuit Playground Express look for the A0 pin with a squiggly line next to it (the squiggle indicates this pin is a DAC output).

Now at the REPL import the [`analogio`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/ __init__.html#module-analogio "analogio: Analog hardware support (SAMD21, ESP8266)") and [`board`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/board/ __init__.html#module-board "board: Board specific pin names (SAMD21)") module to create an instance of the [`analogio.AnalogOut`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/AnalogOut.html#analogio.AnalogOut "analogio.AnalogOut") class:

```auto
&gt;&gt;&gt; import board
&gt;&gt;&gt; import analogio
&gt;&gt;&gt; led = analogio.AnalogOut(board.A0)
```

Just like with an analog input the [`analogio.AnalogOut`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/AnalogOut.html#analogio.AnalogOut "analogio.AnalogOut") class initializer needs to be told which pin will be used as the output. In this case the board pin A0 is being used as the DAC output.

Once the AnalogOut class is created you’re ready to control its voltage. You can change the voltage by updating the [`analogio.AnalogOut.value`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/AnalogOut.html#analogio.AnalogOut.value "analogio.AnalogOut.value") attribute. Just like with an analog input the range of possible values go from 0 to 65535, or all 16-bit unsigned integer values. For example to set the value to 0, or ground, and turn off the LED:

```auto
&gt;&gt;&gt; led.value = 0
```

And to turn on the LED to maximum brightness with the highest possible voltage output value use the value 65535:

```auto
&gt;&gt;&gt; led.value = 65535
```

Notice the LED turns on very brightly! Now try changing the value to a slightly lower value, like 50000:

```auto
&gt;&gt;&gt; led.value = 50000
```

You should see the LED light up less bright. Try experimenting with setting different values in the range of 0 to 65535 and notice how the LED responds.

One thing you might see is if the value is set to a low number, like 10000, the LED turns off just like if the value was set to 0. The reason for this is that the LED has a minimum voltage before it turns on and starts emitting light. For most LEDs this voltage is around 1.8 to 2 volts and with a low enough value like 10000 the voltage output by the DAC is below the LED’s ‘turn on’ (or forward) voltage.

As a side note if you have a multimeter that measures DC voltage try hooking up the probes to measure the voltage output by the A0 pin. Put the positive probe on the A0 output or LED anode and the negative probe on the board ground, then measure the DC voltage. As you set the value see how voltage read by the multimeter changes!

![](https://cdn-learn.adafruit.com/assets/assets/000/045/826/medium800/circuitpython_02_analog_io_multimeter.jpg?1503969917)

Just like with an analog input the digital to analog converter converts its digital value (the number like 10000) to a voltage based on an internal analog reference voltage. For the Metro M0 Express and Circuit Playground Express this reference voltage is 3.3 volts, so a value of 65535 means a full 3.3 volt output and a value of 0 means a 0 volt output. An in-between value will set a proportionally in-between voltage.

So a value of 10000 with a 3.3 volt reference voltage means you should see a DAC output voltage of (try typing this equation in the Python REPL):

```auto
&gt;&gt;&gt; 10000 / 65535 * 3.3
0.5035477225909819
```

A voltage of ~0.5 volts is too far below the ~2 volt threshold to turn on the LED. What if you try a higher value like 50000, what voltage should you expect? Again you can compute it with the same equation:

```auto
&gt;&gt;&gt; 50000 / 65535 * 3.3
2.517738612954909
```

So a value of 50000 means the output voltage is about 2.5 volts. Enough to turn on the LED but not very brightly. Try setting the DAC value to other values above 50000 to see how an increase in the voltage increases the brightness of the LED!

Remember you can create a Python function to simplify setting the output value for a desired output voltage:

```auto
&gt;&gt;&gt; def dac_value(volts):
...    return int(volts / 3.3 * 65535)
&gt;&gt;&gt; led.value = dac_value(2.5)
```

# CircuitPython Basics: Analog Inputs & Outputs

## Pulse-width Modulation (Outputs)

Another way to generate analog signals is with a technique called pulse-width modulation (or PWM). Like using a digital to analog converter you can use PWM to control the voltage output by a pin. However PWM is actually using a very high speed digital signal (either on or off, _never_ in-between) to approximate an analog value. Not every device can work with or ‘see’ the varying voltages output with PWM, but many devices like LEDs and servos work great with PWM. The advantage of using PWM is that it typically doesn’t need special hardware from the microprocessor like with a digital to analog converter. In many cases you can use any digital output as a PWM output!

To explore PWM outputs we’ll use one to dim and brighten a LED, just like with using the digital to analog converter above. You’ll need the same components and setup as with the DAC:

- [A single color LED.](https://www.adafruit.com/product/777) You want a simple single color LED and not a fancier multi-color LED or NeoPixel. Look for a LED that has two legs, a short one and long one. Check out [the Adafruit LED guide](../../../../all-about-leds/overview) for more details on LEDs.
- [A resistor in the range of 300-1,000 ohms.](https://www.adafruit.com/product/2781) You _must_ use a resistor when wiring up a LED to your board or else you might damage the digital output on the board. The resistor limits the amount of current to the LED and prevents damage to the board or LED. The exact value of the resistor isn’t super important for this demonstration–pick any resistor in the 300-1,000 ohm range.
- A breadboard and wires to connect the components and board together.

Connect the components to your board as follows:

![](https://cdn-learn.adafruit.com/assets/assets/000/045/778/medium800/circuitpython_02_analog_io_figure_3.png?1503707338)

- The short leg (cathode) of the LED connects to one end of the resistor.
- The other end of the resistor connects to the ground or GND pin of the board.
- The long leg (anode) of the LED connects to a PWM output of your board. You might need to check your board’s documentation to find these pins, but typically any digital output capable pin will work. Note that on Circuit Playground Express and Metro M0 Express you _can’t_ use pin A0 and need to switch to pin A1!

Now at the REPL import the `pwmio` and [`board`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/board/ __init__.html#module-board "board: Board specific pin names (SAMD21)") module to create an instance of the [`pwmio.PWMOut`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/pulseio/PWMOut.html#pulseio.PWMOut "pulseio.PWMOut") class:

```auto
&gt;&gt;&gt; import board
&gt;&gt;&gt; import pwmio
&gt;&gt;&gt; led = pwmio.PWMOut(board.A1)
```

Just like with using analog inputs and outputs you need to specify the board pin as a parameter to the `pwmio.PWMOut` class initializer. However there are more optional parameters which you might later choose to specify:

`frequency`

> Specify the frequency of the PWM signal in hertz. The default is 500 hz, or 500 times a second.

`duty_cycle`

> Specify the duty cycle of the signal, or percent of time that it’s held at a high vs. low signal. The default is 0, or a completely low / off signal, and can be any 16-bit unsigned value. You’ll learn more about duty cycle values further below.

`variable_frequency`

> This boolean indicates if the frequency of the PWM output can be changed. By default this is false which means the frequency can’t be changed (but the duty cycle still can be changed). It doesn’t hurt to enable this boolean but there are a limited number of internal timers to support different variable frequency PWM outputs. If you’re not planning to change the frequency of the output leave this disabled.

For now stick with the defaults for frequency and duty cycle (500hz and 0% respectively)–these values will work great to control the brightness of a LED.

Before you control the PWM output you’ll want to understand how frequency and duty cycle affect the output signal. As mentioned earlier a PWM output isn’t actually an analog signal in the truest sense of the word–at _no_ point is a PWM output any voltage in-between fully on (~3.3V) or off (0V / ground). However a PWM output can appear to many devices to be an in-between voltage by very quickly turning itself on and off.

Imagine flicking a light switch on and off very quickly, like 30 times a second. The light bulb would be changing so quickly your eyes might not even see the change from on to off and back on again–it would appear to be solidly lit at a moderate brightness. Now imagine as you’re quickly turning the light on and off you hold it on slightly longer than you hold it off. The light would appear to be brighter because it’s turned on more often than it’s turned off! Likewise if you hold the switch off very slightly longer than on you would see the light grow dimmer. Your eyes are effectively ‘averaging out’ the fast changes and seeing the light’s overall brightness change. Remember at no point is the light actually in-between fully on or off–if your eyes were fast enough they would actually see the light as flickering on and off!

With a PWM output the frequency is the rate at which the signal turns on and off. Typically you set this to a high value that’s much faster than the device you’re connected to can see or measure. For a LED any value greater than about 60-100hz is enough to appear to the human eye as unchanging. For other devices like servos they might expect a very specific PWM frequency like 50hz.

Duty cycle is the percent of time that a part of the PWM signal is fully on vs. fully off. Think of duty cycle like a knob you can twist from 0 to 100%, where at 0% the signal is always turned off and never turns on, at 50% the signal is on for exactly as much time as it’s off, and at 100% it’s always turned on. You can adjust the duty cycle to any in-between value, like 33.33%, to have the signal turned on for 1/3 of the time and turned off for the remaining 2/3 of the time. By manipulating the duty cycle you have similar control as if you were adjusting the voltage output by the pin!

To further illustrate how PWM is different from true analog output, look at the image below which shows oscilloscope output of a PWM signal at different duty cycles (0%, 25%, 50%, 75%, and 100%). Notice how as the duty cycle increases the amount of time the signal is at a high logic level (3.3V) gets longer. At 50% duty cycle the signal is high for twice as long as at 25% duty cycle (compare how long the tops of each wave are to check for yourself). At the extremes of 0% and 100% you can also see the signal never changes and is always at a high or low level!

![](https://cdn-learn.adafruit.com/assets/assets/000/045/993/medium800/circuitpython_02_analog_io_pwm.png?1504220854)

Back to controlling the LED, you can change the duty cycle by modifying the[`pwmio.PWMOut.duty_cycle`](http://circuitpython.readthedocs.io/en/latest/shared-bindings/pulseio/PWMOut.html#pulseio.PWMOut.duty_cycle "pulseio.PWMOut.duty\_cycle") attribute. Try setting the duty cycle to a 100% or fully on value with:

```auto
&gt;&gt;&gt; led.duty_cycle = 65535
```

Notice the LED turns on fully bright! Now set the duty cycle to 0% or fully off with:

```auto
&gt;&gt;&gt; led.duty_cycle = 0
```

The LED turns off! Try an in-between value like:

```auto
&gt;&gt;&gt; led.duty_cycle = 32767
```

You should see the LED turn on at a moderate or half brightness. Experiment with setting different duty cycle values between 0% and 100% (or 0 and 65535 values) to see the LED brighten and dim.

The duty cycle value is a 16-bit unsigned number just like the value used by digital to analog and analog to digital converters in CircuitPython. You can convert from a percentage value, like 66%, to a 16-bit duty cycle value with an equation like:

```auto
&gt;&gt;&gt; int(66 / 100 * 65535)
43253
```

Notice you can set any value in-between 0 to 65535 for the duty cycle and the LED appears to brighten and dim, even all the way down to very low duty cycle values like 1000 or less. This is in contrast to the digital to analog converter output where you saw below a large threshold there wasn’t enough voltage to turn on the LED. Remember a PWM output is always either fully on or fully off, it’s never in-between. As a result the PWM output will always be able to light the LED, even at very low duty cycle values. It’s only the amount of time the LED is turned on vs. off that changes–the less the LED is turned on the less bright it appears to your eyes!

Try using a loop to go through all 0-100% duty cycle values and back:

```auto
&gt;&gt;&gt; import time
&gt;&gt;&gt; while True:
...    for i in range(100):
...        led.duty_cycle = int(i / 100 * 65535)
...        time.sleep(0.01)
...    for i in range(100, -1, -1):
...        led.duty_cycle = int(i / 100 * 65535)
...        time.sleep(0.01)
&gt;&gt;&gt;
```

You should see the LED fade from off to fully on and back down to off repeatedly. Press Ctrl-C to stop the loop and get back to the serial REPL.

And remember you can make a handy Python function to more easily set PWM duty cycle. For example given a value from 0.0 to 1.0 (0 to 100%) it can compute the necessary duty cycle value for you:

```auto
&gt;&gt;&gt; def duty_cycle_value(percent):
...     return int(percent * 65535)
&gt;&gt;&gt; led.duty_cycle = duty_cycle_value(0.5)  # Set 50% duty cycle!
```


## Featured Products

### Circuit Playground Express

[Circuit Playground Express](https://www.adafruit.com/product/3333)
 **Circuit Playground Express** is the next step towards a perfect introduction to electronics and programming. We've taken the original Circuit Playground Classic and made it even better! Not only did we pack even more sensors in, we also made it even easier to...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3333)
[Related Guides to the Product](https://learn.adafruit.com/products/3333/guides)
### Adafruit METRO M0 Express - designed for CircuitPython

[Adafruit METRO M0 Express - designed for CircuitPython](https://www.adafruit.com/product/3505)
Metro is our series of microcontroller boards for use with the Arduino IDE. This new **Metro M0 Express** board looks a whole lot like our&nbsp;[original Metro 328](https://www.adafruit.com/product/2488), but with a huge upgrade. Instead of the ATmega328, this Metro...

In Stock
[Buy Now](https://www.adafruit.com/product/3505)
[Related Guides to the Product](https://learn.adafruit.com/products/3505/guides)
### Adafruit Feather M0 Express

[Adafruit Feather M0 Express](https://www.adafruit.com/product/3403)
At the Feather M0's heart is an ATSAMD21G18 ARM Cortex M0+ processor, clocked at 48 MHz and at 3.3V logic, the same one used in the new&nbsp;[Arduino Zero](https://www.adafruit.com/products/2843). This chip has a whopping 256K of FLASH (8x more than the Atmega328 or 32u4) and...

In Stock
[Buy Now](https://www.adafruit.com/product/3403)
[Related Guides to the Product](https://learn.adafruit.com/products/3403/guides)
### Adafruit Feather M0 Basic Proto - ATSAMD21 Cortex M0

[Adafruit Feather M0 Basic Proto - ATSAMD21 Cortex M0](https://www.adafruit.com/product/2772)
Feather is the new development board from Adafruit, and like its namesake it is thin, light, and lets you fly! We designed Feather to be a new standard for portable microcontroller cores.

This is the&nbsp; **Feather M0 Basic Proto** ,&nbsp;it has a bunch of prototyping space...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2772)
[Related Guides to the Product](https://learn.adafruit.com/products/2772/guides)
### Adafruit GEMMA M0 - Miniature wearable electronic platform

[Adafruit GEMMA M0 - Miniature wearable electronic platform](https://www.adafruit.com/product/3501)
The **Adafruit Gemma M0** is a super small microcontroller board, with just enough built-in to create many simple projects. It may look small and cute: round, about the size of a quarter, with friendly alligator-clip sew pads. But do not be fooled! The Gemma M0 is incredibly...

In Stock
[Buy Now](https://www.adafruit.com/product/3501)
[Related Guides to the Product](https://learn.adafruit.com/products/3501/guides)
### Adafruit Trinket M0 - for use with CircuitPython & Arduino IDE

[Adafruit Trinket M0 - for use with CircuitPython & Arduino IDE](https://www.adafruit.com/product/3500)
The&nbsp;Adafruit Trinket M0 may be small, but do not be fooled by its size! It's a tiny microcontroller board, built around the Atmel ATSAMD21, a little chip with _a lot_ of power. We wanted to design a microcontroller board that was small enough to fit into any project, and low...

In Stock
[Buy Now](https://www.adafruit.com/product/3500)
[Related Guides to the Product](https://learn.adafruit.com/products/3500/guides)
### Super Bright Red 5mm LED (25 pack)

[Super Bright Red 5mm LED (25 pack)](https://www.adafruit.com/product/297)
Need some really bright LEDs? We are big fans of these clear red LEDs, in fact we use them exclusively in our kits. They are very bright and have about 20degree LED beam. They go easily into a breadboard and will add that extra zing to your project.

- Pack of 25 clear red...

In Stock
[Buy Now](https://www.adafruit.com/product/297)
[Related Guides to the Product](https://learn.adafruit.com/products/297/guides)
### Through-Hole Resistors - 470 ohm 5% 1/4W - Pack of 25

[Through-Hole Resistors - 470 ohm 5% 1/4W - Pack of 25](https://www.adafruit.com/product/2781)
ΩMG! You're not going to be able to resist these handy resistor packs!&nbsp;Well, axially, they&nbsp;do all of the resisting for you!

This is a **25 Pack of 470Ω Resistors.** More specifically, they are **carbon film** , through-hole...

In Stock
[Buy Now](https://www.adafruit.com/product/2781)
[Related Guides to the Product](https://learn.adafruit.com/products/2781/guides)

## Related Guides

- [Adafruit Feather M0 Express](https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython.md)
- [Adafruit Metro M0 Express](https://learn.adafruit.com/adafruit-metro-m0-express.md)
- [Adafruit Trinket M0](https://learn.adafruit.com/adafruit-trinket-m0-circuitpython-arduino.md)
- [Adafruit Circuit Playground Express](https://learn.adafruit.com/adafruit-circuit-playground-express.md)
- [Easy Sparkle Pocket T-Shirt](https://learn.adafruit.com/easy-sparkle-pocket-t-shirt.md)
- [Trinket / Gemma IR Control](https://learn.adafruit.com/trinket-gemma-ir-remote-control.md)
- [CircuitPython Hardware: Charlieplex LED Matrix](https://learn.adafruit.com/micropython-hardware-charlieplex-led-matrix.md)
- [CircuitPython Hardware: PCA9685 DC Motor & Stepper Driver](https://learn.adafruit.com/micropython-hardware-pca9685-dc-motor-and-stepper-driver.md)
- [Using MPL3115A2 with CircuitPython](https://learn.adafruit.com/using-mpl3115a2-with-circuitpython.md)
- [NeoPixel Ring Bangle Bracelet](https://learn.adafruit.com/neopixel-ring-bangle-bracelet.md)
- [Getting Started With Steven Universe](https://learn.adafruit.com/getting-started-with-steven-universe.md)
- [Desktop Dumpster Fire](https://learn.adafruit.com/desktop-dumpster-fire.md)
- [The MonkMakes Plant Monitor and CircuitPython](https://learn.adafruit.com/monkmakes-plant-monitor-and-circuitpython.md)
- [Fidget Spinner Tachometer](https://learn.adafruit.com/fidget-spinner-tachometer.md)
- [A NeoPixel Blinkendisc](https://learn.adafruit.com/a-neopixel-blinkendisc.md)
- [Space Face LED Galaxy Makeup](https://learn.adafruit.com/space-face-led-galaxy-makeup.md)
- [Halloween Monsters with CRICKIT and Circuit Playground Express](https://learn.adafruit.com/halloween-monsters-with-crickit.md)
- [Larson Scanner Shades (Trinket-Powered NeoPixel LED Strip Glasses)](https://learn.adafruit.com/larson-scanner-shades.md)
- [Crickit Carnival Bumper Bot](https://learn.adafruit.com/crickit-carnival-bumper-car-bot.md)
