PROJECT: Nap Spot Indicator
Step 1 - Build the Project
Use temperature, light, and sound sensors to measure the environment around you. Then use three LEDs as indicators. Each LED will be either off, half-on, or fully on depending on the sensor readings. When you've found somewhere that's dark, warm, and quiet, you've found a perfect nap spot!
Step 2 - Upload the Code
Step 3 - Read the Walkthrough
At the top of your code, create a 'float' type variable called averageNoise.
Next, create a 'long' type variable and name it timer. This timer allows you to take measurements at certain intervals without using the delay() command. Since delay() actually pauses the program, you can't do anything in that time period. The timer variable eliminates that.
In the setup() section of the code, make the center pin of the sound trigger an INPUT. Set the pinMode of the light sensor to INPUT_PULLUP, so it sends a signal close to 0 for brightness and close to 1000 for darkness. Now set the pinMode of your temperature sensor's center pin as an INPUT. Ensure that you have the outer legs plugged in the correct orientation to + and - or the sensor will get very hot.
Finally, set the LED pins as OUTPUTs in the code so they are receiving instructions from the code, not trying to send data in to the code.
Here you'll set the value of averageNoise equal to the analogRead of A4. You will add each reading of the sound to this average in the loop, so you want to start with a typical sound reading, not 0.
First in the loop you're going to update the value of the averageNoise variable. Look at the first half of the equation. When you see float(analogRead(A4)), that's called a cast. You're telling the code "for this calculation only, treat analogRead(A4) as a float variable". Doing that allows you to multiply analogRead(A4) by a decimal. Otherwise, an integer variable type will just cut decimals off the end of the value. Once you have cast analogRead(A4) as a float, you multiply it by 0.01.
In the second half of the equation, you multiply averageNoise (already a float) by 0.99. In effect, you are saying "The new value of averageNoise should be made up of 1% soundValue and 99% averageNoise.". You can change the impact of any new reading by changing the decimals attached to analogRead(A4) and averageNoise.
averageNoise is updated very quickly, once per loop. The rest of the loop sits inside an 'if' statement that runs only once per 500 milliseconds. How does this work? The 'if' statement compares the value of millis() and the value of the variable timer. If the difference between them is more than 500 milliseconds, the 'if' statement is true. Otherwise, the 'if' statement is false. Remember that millis() is a built-in timer in the Arduino software and it is always counting up, which is why you don't need to create it as a variable.
Inside the 'if' statement, you'll create an integer variable called tempF. The numbers in this equation are specific to this sensor, don't change those. However, you can see another variable cast in this line. You temporarily make analogRead(A3) a float variable so that you can multiply it by the decimals. On the very outside of the parentheses, though, you can see 'int'. That means that after your calculations are complete, you actually re-cast the value to an integer. tempF ends up as an integer.
Taking the light reading is much simpler. You simply create an integer variable called lightValue and set its value to analogRead(A2).
Once all of the readings are taken, you can check each value with a series of if-else statements. The first set of if-else statements checks the lightValue variable. If it's less than 300 (meaning it is very bright), the analogWrite() sends a brightness of 0 to the LED.
The else-if statement is only checked when the 'if' statement above is false. So only if the light value is not less than 300, the else-if statement is checked. If the light value is greater than 300 but less than 600, the light is turned on half brightness with analogWrite.
The else statement comes last. It's not checked unless both statements above it are false. In effect, this means that if the light value is greater than 600, the light is turned on all the way with analogWrite(255);
You can see that you can create priorities in the code with if-else if-else statements. If you rearrange the order of the if-else if-else statements, you will make some strange things happen in the code.
Next come two more sets of if-else if-else statements. They check the readings from the temperature variable and the noise variable and change their LED brightness based on that reading. You could repeat this pattern with other sensors and inputs, too.
Finally, you reset the value of the timer variable to the value of millis(). That way, the next time millis() and timer are compared, the difference between them is less than 500 and the if-else if- else statements are skipped, but a new noise reading is still taken.