9. INPUT DEVICES
Task for this week Input Devices
Group assignment:
Probe an input device(s)'s analog levels and digital signals Document your work on the group work page and reflect on your individual page what you learned
Individual assignment:
Measure something: add a sensor to a microcontroller board that you have designed and read it.
GROUP ASSIGNMENT
In the Week 9 group assignment, we explored how to probe and analyze signals from input devices using an oscilloscope. We worked with a digital microphone (INMP441 MEMS) and an analog joystick (PS2 Joystick Module), successfully visualizing their respective digital and analog signals. This involved learning oscilloscope calibration, adjusting voltage/time scales, zooming into waveforms, and analyzing real-time signals. Additionally, we understood the differences between digital and analog signals, proper power supply setup, and efficient probing techniques. This hands-on experience enhanced our understanding of signal characteristics and oscilloscope usage.
Rotary Encoder
I have decided to use Rotary encoder as my input device . I Read some basic datasheet to understand the working of the Rotary encoder .
I understood how the A, B and C button plays an important role in the clockwise and anticlockwise rotationary movement .
A rotary encoder works by having a disk with evenly spaced contact zones connected to a common pin and two output pins (A and B). As the disk rotates, pins A and B alternately make contact with the common pin, generating two square wave signals that are 90 degrees out of phase. By counting the pulses from these signals, you can determine how much the shaft has rotated, and by comparing the timing between A and B, you can also detect the direction of rotation
DESIGNING THE PCB
Then i searched in Snepeda to find the Schematic and footprint of the rotary encoder . then i have added it to the kicad library . For that you could refer week 2 documentation .
ESP WROOM 32
DATASHEET From the Espressif site .
You could go through the below link to understand the basic pinout and its functions .
then i Refered The Data sheet to Get Some Understanding Since We are not using the Module . We are only using the chip
Before designing as my instructor told . we referred to Neils Circuit design to get an overview . The circuit was a good help in the design process of my circuit board .
FREE ROUTER ADJUSTMENT
For Routing the pcb , i used the free router plugin that is available on kicad . The below are the settings that i changed on the free router to set the size of traces .
The below image is my schematic design .
Schematic Explanation
- Rotary Encoder:
- The rotary encoder (S1: WS-ENTV_4820XX514001) is connected to GPIO pins of the ESP32 for detecting rotation direction and button presses.
- Pull-up resistors (R1, R2, R3: 10kΩ) ensure proper signal levels for CLK, DT, and SW pins.
- ESP32 Microcontroller:
- The ESP32-WROOM-32 module serves as the central processing unit.
- Essential pins like EN (enable) and RX/TX are connected for programming and debugging.
- Voltage Regulator:
- A linear voltage regulator steps down 5V to 3.3V to power the ESP32.
- Capacitors (C1: 10µF, C3: 1µF) are placed on the input and output sides of the regulator for stability.
- Decoupling Capacitors:
- A 0.1µF capacitor (C2) is placed near the ESP32 power pins to filter high-frequency noise.
- Boot and Enable Switches:
- Tactile switches (SW1, SW3: Omron B3SN) are used for boot mode selection and resetting the microcontroller.
- Pull-up resistors (R4, R5: 10kΩ) ensure stable operation.
- Programmable LED:
- An LED (D1: LED_1206) is connected to a GPIO pin via a current-limiting resistor (R6: 100Ω).
- RX/TX Header:
- A pin header (J5: FTDI-compatible) provides external communication for programming/debugging.
- Pin Headers:
- Additional pin headers (J1, J2) are included for modularity and future expansion.
Design Considerations
- Pull-Up Resistors: Ensure stable HIGH logic levels for input pins.
- Decoupling Capacitors: Filter out noise and stabilize voltage during high-current events.
- Voltage Regulation: Protects the ESP32 by providing a steady 3.3V supply.
Then i have arranged the the pcb board by keeping the components on different sides . so i could route it good .
Then i used the free router as mentioned . I used the extension below .
I Refered Some Videos and Circuits
This is what i got after Free routing .
On DRC checking . i got 78 errors . i have to rectify those errors .
Many of the Errors was because of Padding Issues . So that i needed to adjust the Pads width .And it solved those
For that Right Click On the Pads > Properties
Change The Pad Properties as shown below .
Rather than manually applying the pad properties to all pads, you can automate the task by following these steps:
Right-click on the pad > Push Pad Properties to other pads > Change Pads on current footprint .
Adjusting VIA holes Padding to Fix the error
There was some issues with the via holes too . I was not aware about the what an annular Ring is . so I referred Google And the below Image would help you understand what an annular ring is .
Then i have downloaded the gerber file and used in the Gerber2Png Website to get the the PNG files .
Turn On the Double side Button If its Double side .
HOW TO MILL A DOUBLE SIDE PCB
TO MILL A DOUBLE SIDE PCB . YOU SHOULD DOWNLOAD THE TWO LAYER PNG FILE USING THE GERBER2PNG SITE
Then follow the order of the generated file . ie from 0 - 4 . As in my case 5 file was generated .
Refer the wiki from Gerber2PNG page To get the details on how to mill double side PCB .
Mill the Pcb in the order format of the numbers .
Then i Traced the Front layer and then i have cut the Front Plane Out .
Then i placed gum on the side that i have milled as shown below . The edges are getting cut in a different shape in the two layer PCB .
Then i have kept the PCB back to Milling machine so that i am ready to mill the second layer .
IMPT Note : remember to place the side correctly or you may end up getting milled on the wrong direction .
This is the Pcb that i got milled . The Depth was high so the copper on the outside layer is getting removed . and i was not able to use the via .
This is the BOM .
Then i have requested the components from the fab inventory .
The components that i have procured from our lab is shown below .
This is the PCB what i Made .
The Next Part is the testing the PCB for That i first installed the esp32 library to the arduino ide .
For That i asked the Perplexity and this was the result and i followed it and i was able to install it .
To add the ESP32 library to your Arduino IDE, follow these steps:
Step-by-Step Installation
- Install Arduino IDE:
- Ensure you have the latest version of Arduino IDE installed on your computer. You can download it from the official Arduino website.
- Open Preferences:
- Launch Arduino IDE and go to File > Preferences.
-
Add ESP32 Board URL:
-
In the Additional Board Manager URLs field, enter the following URL:
texthttps://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
-
If you already have other URLs (e.g., for ESP8266), separate them with a comma.
- Open Boards Manager:
- Navigate to Tools > Board > Boards Manager.
- Install ESP32 by Espressif Systems:
- In the Boards Manager search bar, type
ESP32
. - Locate the entry labeled "ESP32 by Espressif Systems" and click the Install button.
- Select Your ESP32 Board:
- After installation is complete, go to Tools > Board, and select your specific ESP32 model (e.g., DOIT ESP32 DEVKIT V1).
- Test the Installation:
- Connect your ESP32 board to your computer via USB.
- Select the appropriate COM port under Tools > Port.
- Load an example sketch (e.g., File > Examples > WiFi (ESP32) > WiFiScan) and upload it to your board.
- Open the Serial Monitor at 115200 baud rate to verify functionality.
-
Prompt Used In Perplexity : how to add esp32 library in my arduino ide
Testing My PCB
Then i tested the the Pcb By running a sample code to Blink the Led . It was working
Next i was ready to test my rotary encoder . and for that i referred sayanth s a previous fab alumini and i tried to replicate the code so that i can check the working .
But the code was not working . i tried using various codes across internet . but nothing was working . then i asked my instructor saheen and he helped me finding the missing connection . (or like a misplacement connection ) .
That time i knew that every thing that i have made so far has gone i realised that whether i should make a new microcontroller . and i was literally confused with like what to do .
Then saheen helped me with the external wiring so we could test the encoder and solve the issue as of now .
Below one is the mistake circuit .
CHANGED THE CIRCUIT TO THIS . (the mistake was i misplaced the switch ).
The below one is the PCB which is wired . ie the rotary encoder is connected externally in some connections .
after correcting i uploaded the same code and again it was not still working . so i moved to next task .
Later in next week i manufactured the same board with input and output device , the output i used was an oled display .
here i was able to make the encoder working . it too took some time in working , i think there is some issues with the encoder such as debouncing and i think you should have connected the roatary encoder pins to touch pad pins . these all may be the reason .
#include <Arduino.h>
#define ENCODER_B 14
#define ENCODER_A 27
#define BUTTON 39
volatile int counter = 0;
volatile bool aState, bState;
volatile int lastEncoded = 0;
volatile boolean TurnDetected;
volatile boolean up;
void IRAM_ATTR readEncoder() {
// aState = digitalRead(ENCODER_A);
// bState = digitalRead(ENCODER_B);
TurnDetected = true;
up = (digitalRead(ENCODER_A) == digitalRead(ENCODER_B));
// if (aState == bState) {
// counter++;
// } else {
// counter--;
// }
}
void setup() {
Serial.begin(115200);
pinMode(ENCODER_A, INPUT);
pinMode(ENCODER_B, INPUT);
pinMode(BUTTON, INPUT);
attachInterrupt(digitalPinToInterrupt(ENCODER_B), readEncoder, RISING);
// attachInterrupt(digitalPinToInterrupt(ENCODER_B), readEncoder, FALLING);
}
void loop() {
static int lastCounter = 0;
if (digitalRead(BUTTON) == LOW) {
counter = 0;
Serial.println("Counter Reset");
delay(200); // Debounce delay
}
if (TurnDetected) {
if(up)
{
counter++;
} else {
counter--;
}
Serial.print("Counter: ");
Serial.println(counter);
lastCounter = counter;
TurnDetected = false;
}
delay(10); // Small delay to avoid excessive CPU usage
}
After that i also tested it using oled and i was able to display the counter on the oled display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Define Rotary Encoder pins
#define CLK 14
#define DT 27
#define SW 39
// Define OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define I2C_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int counter = 0;
int lastCLK = LOW;
void setup() {
Serial.begin(9600);
// Setup rotary encoder pins
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
pinMode(SW, INPUT_PULLUP);
// Setup display
if (!display.begin(SSD1306_SWITCHCAPVCC, I2C_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
display.display();
}
void loop() {
readEncoder();
updateDisplay();
delay(5); // Small delay to debounce
}
void readEncoder() {
int currentCLK = digitalRead(CLK);
if (currentCLK != lastCLK && currentCLK == HIGH) {
if (digitalRead(DT) != currentCLK) {
counter++;
The OLED library you're using Adafruit_SH110X) might not be the correct one for your
display. Based on your previous messages, you're using an SSD1306 OLED display.
} else {
counter--;
}
}
lastCLK = currentCLK;
// Check for button press
if (digitalRead(SW) == LOW) {
counter = 0; // Reset counter when button is pressed
delay(250); // Debounce delay
}
}
void updateDisplay() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Counter:");
display.setCursor(0, 20);
display.println(counter);
display.display();
}
Setting Date and time in esp32
As my final Project is a Productivity timer . i wanted to incorporate date and time to my module . for that i asked my instructer how to do it . he told me to try with the Ntp server . So i could incorporate date and time .
I searched perplexity how to incorporate the thing .
Now i used ntp server to get date and time .
On first the time was not working . so i adjusted the gmt offset values to 19800 which equal gmt +5:30 🕠 .
i was able to generate the output correctly . the output is shown below .
This is the code that i used .
#include <WiFi.h>
#include "time.h"
const char* ssid = "Your wifiname ";
const char* password = "password";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 19800;
const int daylightOffset_sec = 0;
void printLocalTime()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
void setup()
{
Serial.begin(115200);
//connect to WiFi
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
//init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
//disconnect WiFi as it's no longer needed
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
}
void loop()
{
delay(1000);
printLocalTime();
}
Code parameters Explanation
-
gmtOffset_sec
: 19,800 seconds = 5.5 hours (IST offset)[^4][^8]daylightOffset_sec
: 0 for India (no daylight savings)ntpServer
: Global NTP pool for reliability[^4]``-
getLocalTime()` fetches current time from ESP32's RTC
- Format specifiers:
%A
: Full weekday name (e.g., "Wednesday")%B
: Full month name (e.g., "March")%d/%Y
: Day/Year in numbers%H:%M:%S
: 24-hour time format
CONCLUSION
For Week 9, I worked on designing and implementing input devices, focusing on a rotary encoder integrated with an ESP32 microcontroller. I created a detailed schematic in KiCad, ensuring proper connections for the rotary encoder, boot and enable switches, programmable LED, and RX/TX communication. The design included decoupling capacitors and a voltage regulator for stable operation. After resolving issues like pad sizing and routing errors, I generated Gerber files and milled a double-sided PCB. I programmed the ESP32 in Arduino IDE to test the rotary encoder functionality, troubleshooting initial wiring errors but it didnot worked out . Additionally, I incorporated NTP server functionality to display real-time data, aligning with my final project goals.