RC101–01 — The Foundations
I just thought to blog the entire learning i did to make the RC car using ESP32.
Learning the Required C++ for ESP-32
Firstly I didn’t want to copy paste the code and started learning the required C++ for coding the ESP-32. Although I might not code line by line I should be able to know what is responsible for what otherwise I don’t think i really worked on this.
These are some of the few concepts I covered in the Initial hours :
Most of the classical fundamentals of the programming language this is child’s game but i just wanted to be sure i didnt miss out on anything.
Arduino Sketches and Program Structure
An Arduino program is called a sketch.
setup()
Initialization instructions are put inside the setup
and this function runs once when the esp-32 restarts or starts
we could also configure stuff like motor drivers, starting wifi, initializing the oled display here, pinMode configuration is also done here
pinMode(pinNumber, Mode);
to configure a GPIO pin
Mode -> INPUT OUTPUT
void loop()
The function that runs indefinitely through the life time of the esp-32
loop()
As discussed above it keeps repeating itself after the running of setup
Libraries
Header files like Wifi, Wire, WebServer
Wire provides the I2C functionality
and WebServer provides the web-server funcitonality
Serial Communication and Serial Monitor
Serial.begin(115200)
this is the code we write to set the baud rate same for our clean communication.
SERIAL COMMUNICATION AND SERIAL MONITOR
Serial.begin(115200) here is the baud rate of the signal and also called as the communication speed here.
Serial.print()
prints information without moving to the next line.
Serial.println()
is the method to generally print the statements on the serial monitor in our laptop from the esp-32
Serial communication can do more than just display messages onto the screen and setting the baud rate.
We can have 2 way serial communication between ESP and Computer.
Serial.available();
checks whether some thing from the computer is there or not to arrive.
Serial.read();
used to read a character from the input serial buffer.
Digital Signals, GPIO, and Pull Resistors
Digital Signals have 2 logical states HIGH and LOW.
To receive signals from the GPIO pins but the pins may pickup electric noise and produce unpredictable HIGH and LOW signals and this is called floating input using a pull up and pull down resistors avoids this issue.
digitalWrite(pinNumber, Signal)
To send a signal through the GPIO pin we use digitalWrite().
To send HIGH(3.3v) or LOW(0v) signals we use the digitalWrite
digitalRead()
helps us read the digital signals from the sensors
Switching on an LED
In simple terms we keep pinMode(18,INPUT_PULLUP); and Pullup means the signal is always HIGH and when pressed the signal become connected to the GND hence we detect this low signal here and then on the led untill we are detecting the low signal actually when we turn off the switch the internal resistor is connected between the vcc and gpio pin so it actually is working like the setup of a PULLDown right why are we giving and naming it PULLUP so the main thing to understand here comes down the base state the pin is present when the button is not pressed for example
lets take a pullup setup, the name here suggests that the base state is the internal pin is connected to 3.3v through a resistor so that the general state here is HIGH and hence the switch must be connected to the GND and when the switch is pressed the circuit ends up as the GND 0v at the GPIO pin here.
Reading Sensors
Depending on the design of the sensing element the module can give out
- Digital Output
- Analog Output
- a combination of Digital and Analog Output
// READING INPUT FROM A SENSOR
int irPin = 19;
void setup(){
pinMode(irPin,INPUT);
Serial.begin(115200);
}
void loop(){
int val = digitalRead(irPin);
Serial.println(val);
delay(200);
}
/*the actual value of for the color white and black are determined only after the experimentation*/In simple terms the digital signals are like binary states either HIGH or LOW where as the analog signals are like varying voltages.
Individually they have their own use cases being digital helps us to know the occurrence of an event and analog signals tells how much of a value for a measurement we are measuring.
ADC
Sensors produces Analog voltages but esp-32 is a digital microcontroller.
So ADC converts the Analog value into a Digital number
Pasted image 20261101004936.png
Get Vinod Muddasu’s stories in your inbox
Join Medium for free to get updates from this writer.
So the approximate reading of the Analog sensor for the max scale are converted and approx values are mapped to the respective digital Signal here
GPIO 34–39 are input-only and do not have internal pull-up/pull-down circuitry.
Complete analog-reading code
void setup() {
Serial.begin(115200);
analogReadResolution(12);
analogSetPinAttenuation(POT_PIN, ADC_11db);
}void loop() {
int reading = analogRead(POT_PIN);
Serial.print("Potentiometer Reading: ");
Serial.println(reading);
delay(250);
}- What does Attenuation mean in the above code?
The ADC has a limited measurable voltage range. Attenuation adjusts the input range to accommodate higher voltages.
PWM
If we want to control the amount of light emitted by an led or else the speed at which motor rotates we use this concept.
for example lets say a motor rotates 100 rpm at maximum for a voltage provided 3.3v but if we want the motor to rotate 50 rpm but the microcontroller cannot provide half the voltage it can only send high or low signals that is where duty cycles comes in and since we want half the maximum percentage we send high signal half the time of a cycle hence achieving the desired output.
but we cannot decide the exact rpm here also it just gives a way to handle the speed here.
PWM frequency is the number of these cycles occurs in one second.
PWM RESOLUTION is the number of different possible duty values we can have in case of a 8 bit resolution we can have 0 - 255 different types of values.
LED Control Peripheral LEDC
ledcWrite(pin, duty);This is a sample LED PWM Configuration code
void setup(){
Serial.begin(115200);
bool status = ledcAttach(LED_PIN, 5000, 8);
if(status){
Serial.println("LED pin configured for PWM sucessfully");
}else{
Serial.println("LED pin configuration for PWM failed.");
}
}void loop(){
ledcWrite(LED_PIN,50);
Serial.println("50 is the duty currently.");
delay(2000);
ledcWrite(LED_PIN,255);
Serial.println("255 is the duty currently.");
delay(2000);
for(int i=1; i<=255; i++){
ledcWrite(LED_PIN,i);
delay(10);
} for(int i=255; i>=0; i--){
ledcWrite(LED_PIN,i);
delay(10);
}
}
Combining Analog Input with PWM Output
Here lets try to understand the map function since we are mapping values from 0 to 4095 onto 0 to 255 :
map(sensorValue, fromLow, fromHigh, toLow, toHigh);and this performs a linear conversion.
if we want the converted value within a range we can use constrain :
constrain(value, minimum, maximum);hence, minimum <= value <= maximum is the range.
int POT_PIN = 34;
void setup(){
Serial.begin(115200);
analogReadResolution(12);
analogSetPinAttenuation(POT_PIN,ADC_11db);
ledcAttach(LED_PIN,5000,8);
}void loop(){
int sensorValue = analogRead(POT_PIN);
int brightness = map(sensorValue,0,4095,0,255);
brightness = constrain(brightness,0,255);
ledcWrite(LED_PIN,brightness);
Serial.print("Sensor: ");
Serial.print(sensorValue);
Serial.print(" | Brightness: ");
Serial.print(brightness);
delay(100);
}Delay and Non-Blocking Timing with millis()
DELAY
delay(time in ms) stops the execution of the entire program for the time specified but this might be not the best approach when working with real time robots since we might miss out on the events.
the alternative we use
millis();this function returns the number of milliseconds elapsed since the start of the program.
we can use this to schedule some functions without stopping the execution of the entire program.
a sample program using millis to understand it in a better way.
const int interval = 1000;
int previousTime = 0;
bool ledState = false;
void setup(){
Serial.begin(115200);
pinMode(LED_PIN,OUTPUT);
}void loop(){
unsigned long currentTime = millis();
if(currentTime-previousTime >= interval){
previousTime = currentTime;
ledState = !ledState;
digitalWrite(LED_PIN,ledState);
}
}this switches the led state when the time gap reaches 1s without using any delay
ESP-32 Hardware and Pin Considerations
Some of the sensor modules like HC-SR04 ultrasonic sensor commonly operates at 5v and echos a 5v signal but the GPIO logic of the esp-32 board works at 3.3v helps we need to use a suitable voltage divider or logic level shifter before connecting to the pin directly.
the pins on the esp-32 are mostly configured for special purposes each hence refer a valid source before connecting any GPIO pin on the board.
ADC Pin Selection When Using Wi-Fi
On ESP-32 there are 2 groups of ADC pins ADC1 and ADC2 generally ADC2 impose restrictions when working along with wifi.
GPIO 34 is an ADC1 input on the classic ESP32.
Learning Map
| Component | Programming Concept | Arduino Function / Technique |
|---|---|---|
| ESP32 | Program execution | `setup()`, `loop()` |
| LED | Digital output | `pinMode()`, `digitalWrite()` |
| Push Button | Digital input | `digitalRead()` |
| Digital IR Sensor | Digital input | `digitalRead()` |
| Analog UV Sensor | Analog input | `analogRead()` |
| Motor Driver | PWM and digital output | `ledcAttach()`, `ledcWrite()`, `digitalWrite()` |
| OLED Display | Communication | `Wire.h` and display libraries |
| Wi-Fi Dashboard | Network communication | `WiFi.h`, `WebServer.h` |END NOTE
These are just some of the basics which are like the prerequisities for any electronic projects one might work on using micro — controllers.






