Input, Output, and Hardware Integration
This is where code and hardware truly come together. You will learn the difference between digital and analog signals, when to use each, and how pulse width modulation lets a digital pin fake an analog output. Along the way you will control an RGB LED, dim an LED smoothly with a potentiometer using the map function, and ramp a DC motor's speed up and down through a transistor.
Digital input and output: on or off
Digital I/O works with exactly two states, HIGH and LOW, which you can also read as one and zero, on and off. Three functions cover it. pinMode(pin, mode) sets a pin as INPUT or OUTPUT. digitalRead(pin) reports whether a digital input is HIGH or LOW. digitalWrite(pin, value) sets an output pin to HIGH or LOW. Because it is digital, there is no in-between; a pin driven this way is fully on or fully off. That is perfect for a button, which is either pressed or not, or an LED you only need to switch.
Why an RGB LED on digital signals is limited
An RGB LED has separate red, green, and blue elements. Driven with digitalWrite, each color is only fully on or fully off, so you can make the primary colors and simple combinations but not the millions of shades the LED is capable of. To get a smooth spectrum, where red might be at 30 percent and blue at 70 percent, you need a way to send values between fully off and fully on. That is analog output.
Analog input and output: a range of values
Analog I/O works with a whole range instead of two states. analogRead(pin) returns a value from 0 to 1023 that represents an input voltage, which is ideal for components whose value varies continuously: a potentiometer's position, a temperature sensor's reading, a photoresistor's light level. analogWrite(pin, value) sends a value from 0 to 255 to an output. Note the different ranges: reads go up to 1023 and writes up to 255, because they use different resolutions. There is no analog version of pinMode, because a pin is still simply an input or an output.
The map function: matching two ranges
A common problem is that your input range and output range do not match. A potentiometer read gives 0 to 1023, but an LED brightness write takes 0 to 255. The map function converts a value from one range to the equivalent point in another: map(potValue, 0, 1023, 0, 255) takes the potentiometer reading and scales it into the brightness range. A mid-position reading of about 511 maps to roughly 127, the middle of 0 to 255. Without map, writing 1023 to an LED would exceed its 0 to 255 range.
Pulse width modulation
Here is a surprise: the pins marked with a tilde symbol are not true analog outputs. They are digital pins using pulse width modulation, which simulates an analog level by switching the pin on and off very rapidly. By spending more of each cycle on, the pin behaves like a higher analog value; more of each cycle off behaves like a lower one. Your eyes and a motor both average it out. This is how analogWrite dims an LED or sets a motor's speed. Only PWM-capable pins, the ones with the tilde, support analogWrite output.
Working through it
Cycle an RGB LED with digital output. Wire red, green, and blue to pins 9, 10, and 11 through resistors, set them as outputs, and use digitalWrite to flash each color on and off in turn. This shows the on-or-off limit of digital control before moving to analog.
Wire a potentiometer and an LED for dimming. Connect the potentiometer to A0, 5V, and ground; connect an LED to PWM pin 9 through a 220 ohm resistor. The potentiometer will be an analog input and the LED a PWM output.
Read, map, and write brightness. In loop, read the potentiometer with analogRead into potValue, convert it with int brightness = map(potValue, 0, 1023, 0, 255), and send it with analogWrite(ledPin, brightness). Using digitalRead here by mistake would only ever report on or off, which is why matching the function to the device matters.
Wire the DC motor through a transistor. A board pin cannot supply enough current for a motor, so a transistor acts as a switch. Connect the transistor's collector to the motor, its emitter to ground, and its base to PWM pin 9 through a 1k ohm resistor; connect the motor's other terminal to 5V. The pin controls the base, and the transistor handles the motor's current.
Ramp the motor speed up and down. In loop, use a for loop that raises speed from 0 to 255 in steps of five, calling analogWrite(motorPin, speed) with a short delay, then a second loop that lowers it from 255 back to 0. The motor accelerates smoothly, then decelerates.