Have you ever considered making sounds with LDR and buzzer? I just had and will show you how to do just that in this post. We are going to be making sound whose oscillation frequency change depending on the amout of light received by a sensor.
The idea is to make use of the tone() function in Arduino to generate a frequency, then turning it on and off (alternatively) depending on the amount of light incident on a LDR light sensor. We will then map (using the, you guessed it, map() function of Arduino) the analog value of the sensor to a specific range of times in milisseconds.
For this project I am going to be using a SeeedStudio Xiao ESP32-C6, a WiFi chip (of which we will not use the WiFi). It has analog inputs which will read in 4096 steps (12bit) instead of the 1024 steps (10bit) of the Arduino UNO. All we have to do is declare it in the Arduino code that we want to use the full 12bit:
analogReadResolution(12);
Schematic diagram
You can see below how simple this experiment is, all we have is one LDR light sensor (pin A0, with a 10k resistor in series) and a buzzer connected directly to the ESP32-C6 pin D7.
Below you can see the assembly of the prototype. Notice that the LDR sensor is already soldered to the circut board, it is a feature of it.
Coding for it
As stated above, we are using Arduino and its IDE (version 2.3.3) to write, compile and download the code to the Xiao ESP32-C6. There is really not much to it, I basically create a function that is entered every interval of 25 to 800 milisseconds, depending on the LDR readings. Inside the function I essentially flip the state of an LED (pin 15, onboard Xiao ESP32-C6 LED) and the state (on or off) of the buzzer pin.
With the most amount of light we are having a 25ms interval, while with the least amout of light (essentially dark) we are having 800ms interval.
long oldtime;
int ldrvalueconverted;
#define led 15
#define buzzer D7
void setup() {
// put your setup code here, to run once:
analogReadResolution(12);
pinMode(led, OUTPUT);
pinMode(buzzer, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
ldrvalueconverted = map(analogRead(A0), 0, 4095, 800, 25);
if(millis() - oldtime > ldrvalueconverted){
oldtime= millis();
digitalWrite(led, !digitalRead(led));
if(digitalRead(led)){
tone(buzzer, 3000);
}else{
noTone(buzzer);
}
}
}
I choose the 3000Hz frequency in the tone() function because it sounded nice, nothing else. Notice that I made an IF statement dependent on the LED pin state, when it is HIGH I play the tone, when it is LOW I go noTone().
Closing thoughts
There is a video of the experiment below, enjoy. If you want to learn more about sensor here in the blog, click here.
Leave a Reply