Analog Input and Output
Sensors like buttons produce only two states, which is convenient for the digital pins on the Huzzah32, but there are plenty of examples of sensors that produce voltages proportional to signals that cannot be read digitally. For example, the potentiometer can be wired to produce a voltage proportional to the angle of the knob. Microcontrollers, including the Huzzah32, have an analog to digital converter (ADC), to read the voltage and turn it into a digital number.
Visualizing Analog Voltages
The potentiometer is a knob that can be used as an angle sensor, using the following circuit diagram:
The potentiometer in the kit rotates 270 degrees, and the output voltage is linearly proportional to the angle (there are also logarithmic potentiometers, used as volume knobs). The output voltage can be read by any of the A pins on the Huzzah32, using the function analogRead(). The number returned by analogRead() is an integer from 0 for 0V to 4095 for 3.3V (this is a 12bit ADC).
Open the example AnalogReadSerial in 01.Basics. This example will read the voltage on pin A0, and then print the value to the computer using serial communication (we’ll explore serial in the next section). Load the code onto the Huzzah32, go to Tools->Port and select the option with Huzzah32, and open the Serial Monitor (button in the top right of the IDE, looks like a magnifying glass).
You should see a single column of text with a number from 0 to 4095 in the Serial Monitor. Turn the pot to verify that the number changes according to the angle. If the number does not change when you move the pot, check that the pot has 0V and 3.3V connected. Note that the number printing to the computer updates at 1kHz due to the 1ms delay in the code.
Edit the code to slow the output down to 100Hz. This time, open the Serial Plotter in the Tools menu. In this mode, if the data printed to the computer is columns of numbers separated by spaces, the data is plotted on a rolling graph that auto scales. Note the noise level on the voltage when the pot value is constant, this is electrical noise in the circuit and ADC, and there are some techniques for reducing it with circuits or code if it becomes an issue. The Serial Monitor and Plotter are convenient ways to see the value of sensor data and variables.
Note that every time you upload new code to the Huzzah32 the port will briefly disappear. It is good practice to close the Serial Monitor or Plotter before uploading new code, to prevent some random crashing of the Arduino IDE.
Set the brightness of the LED based on the potentiometer
Most microcontrollers don’t have the ability to generate analog voltages, using an internal digital to analog converter (the Huzzah32 does have a DAC, but we won’t use it for this purpose). Instead, the microcontroller can digitally pulse a pin at high frequency while varying the ratio of on to off time so that the average value is an analog signal. On most Arduino, the function that does this is called analogWrite(), which is a horrible name because the output voltage isn't actually analog, it is square, and only certain pins are capable of outputting it (this functionality is more accurately called pulse width modulation, or PWM). The Huzzah32 uses a different function, slightly more complicated, and also with a name that isnt quite right, but does give more options. First, in setup(), a channel is made for the PWM with a channel number, frequency, and resolution, using ledcSetup(ledChannel, freq, resolution), where the ledCannel can be 0, the freq 5000 (Hz), and the resolution 8 (bits, so values of 0-255). Second, in setup(), initialize the pin you want to use, using ledcAttachPin(ledPin, ledChannel), where ledPin is the number of the pin and channel can be 0. Then, in loop(), whenever you want to set the duty cycle of the PWM, use ledcWrite(ledChannel, dutyCycle), where ledChannel is 0 and dutyCycle is 0-255, 0 for 0V and 255 for 3.3V.
Edit the analogReadSerial code to apply the value read from A0 to the LED. Remember that analogRead() returns a maximum of 4095 and ledcWrite() takes a maximum of 255, so do the math to divide the number down or funny things will happen. Load the code and watch the LED brightness level. Lots of other devices, like motors, can be driven like this, but usually need amplifiers because the microcontroller pin can only supply 3.3V and a few mA of current.
Build the microphone circuit
Another circuit that creates an analog voltage is a microphone. The microphone in the kit is an electret type, and comes on a breakout board with an amplifier that conditions the signal so that the mean voltage is 1.65V and the magnitude changes with sound level. The breakout board has a tiny potentiometer built in so you can increase or decrease the gain to change the sensitivity.
Build the circuit and edit the delay in the AnalogReadSerial code so that, in the Serial Plotter, the data fills across the plot in about 5 seconds. Speak, whistle or clap into the microphone to visualize the sound.
The frequency of a high whistle is in the kilohertz range. To see the sine wave at this frequency, the sample rate of the analogRead() should be at least twice, or event better ten times, the frequency of the sine wave. But, decreasing the delay in the code will flood the computer with too much data to plot, and it will stutter or crash. To visualize the data better, read the data into an array of 1000 values, then print the 1000 values, using two different for() loops.