• 3D Printed Right-Angle Friction Drive Using Cam and Follower

    In this project we explore a simple but powerful mechanical idea:
    how a rotating cam and a disc-type follower can be used to create a right-angle friction drive — without gears, belts, or electronics.

    This entire mechanism is 3D printed and demonstrates how motion can be transferred purely through geometry and contact.


    📹 Project Video

    FreeCAD Rendering: 3D Printed Right-Angle Friction Drive

    https://youtube.com/shorts/w_zL9D7RV9Q


    🔧 What is a Right-Angle Friction Drive?

    A right-angle friction drive transfers rotation between two shafts that are oriented at 90 degrees to each other using surface contact instead of teeth.

    Instead of gears:

    • One rotating surface presses against another
    • Friction forces transfer motion
    • The driven part rotates because of rolling contact

    This principle is used in:

    • Record players
    • Paper feeders
    • Conveyors
    • Machine tools
    • Old mechanical clocks

    ⚙️ How This Mechanism Works

    This design uses:

    • A cam disc (rotating plate)
    • A flat roller follower (disc on a shaft)
    • A guided vertical shaft
    • A printed frame that holds everything in alignment

    When the cam rotates:

    • It rubs against the flat follower disc
    • The disc rolls along the cam surface
    • That rolling causes the follower shaft to rotate
    • The top plate rotates smoothly as a result

    Even though the axes are at right angles, rotation is transferred cleanly.

    This is not gear action — it is rolling friction drive.


    🧠 Why the Disc Rotates

    The follower disc is mounted on a pin and is free to spin.

    When the cam touches it:

    • The cam’s surface has tangential velocity
    • That velocity forces the disc to roll
    • Rolling motion turns into shaft rotation

    This eliminates sliding friction and allows smooth motion.

    In engineering, this disc is called a:

    Roller follower


    🛠 Why Use Friction Instead of Gears?

    Friction drives have unique advantages:

    FeatureBenefit
    SmoothNo noise, no vibration
    SafeSlips instead of breaking
    SimpleNo teeth or alignment needed
    Shock-proofOverload protection built-in

    This is why friction drives are used in printers, CNC feeders, and audio equipment.


    🧩 Mechanical Insight

    By changing only the cam shape, this same rig can be converted into:

    • A rotary drive (as shown here)
    • A lifting cam
    • A pump
    • A stamping mechanism
    • A timing controller

    The cam profile is mechanical programming.

    Rotation in → Motion out.


    🧪 Why 3D Printing is Perfect for This

    3D printing allows:

    • Fast experimentation
    • Custom cam profiles
    • Swappable parts
    • Learning through real motion

    This project shows that even with plastic parts, you can explore real kinematic systems used in industry.


    📦 Applications of This Concept

    This exact principle is used in:

    • Turntable drives
    • Conveyor rollers
    • Filament feeders in 3D printers
    • Mechanical automation systems
    • Educational models

    🧠 Final Thought

    This project shows that:

    Motion does not need electronics — geometry is enough.

    A rotating shape can drive, lift, pause, and spin simply by touching another shape.

    That is the beauty of mechanical engineering.

  • Smart City Mini Project Using Arduino UNO

    (Street Light Automation, Smart Gate & Air Quality Alert)

    Smart cities are built by combining automation, sensing, and decision-making.
    In this project, a Smart City model was developed using an Arduino UNO and commonly available sensors to demonstrate how embedded systems can be used for urban automation.

    This project focuses on real-world logic, not just blinking LEDs.


    📌 Project Demonstration Video

    🎥 Watch the complete working demonstration here:

    👉 The video shows the automatic street lights, smart gate operation, and air quality alert system working in real time.


    Project Overview

    The model demonstrates four smart city subsystems working together:

    1. Automatic Street Light System (LDR based)
    2. Smart Entry Gate / Traffic Control (Ultrasonic + Servo)
    3. Air Quality Monitoring System (MQ135 sensor)
    4. Alert System (Buzzer for pollution warning)

    Each subsystem works independently but is controlled by a single Arduino UNO, simulating how real smart-city nodes operate.


    Components Used

    • Arduino UNO
    • LDR (Light Dependent Resistor – discrete, not module)
    • Ultrasonic Sensor (HC-SR04)
    • Servo Motor (gate control)
    • MQ135 Air Quality Sensor
    • Buzzer
    • LEDs (street lights)
    • 330 Ω resistors (current limiting)
    • Breadboard, jumper wires, external LED wiring

    🔌 Circuit Diagram

    🧩 Complete circuit diagram for this project:

    Open circuit Open circuit

    The circuit includes:

    • LDR voltage divider connected to an analog input
    • Ultrasonic sensor connected to digital pins
    • Servo motor connected to a PWM pin
    • MQ135 sensor connected to an analog input
    • Buzzer connected to a digital output
    • LED street lights driven through resistors

    Street Light Implementation (Important Design Detail)

    To simulate street lights, multiple LEDs were used.

    Instead of driving LEDs directly from the Arduino pin, the following safe current-limiting method was implemented:

    • Two GPIO pins were used for street lighting
    • Each GPIO pin was connected through a 330 Ω resistor
    • The other end of each resistor was connected to 4–5 LEDs in parallel

    Why this method was used

    • The resistor limits the current drawn from the GPIO pin
    • Using two GPIOs distributes the load instead of stressing a single pin
    • Parallel LEDs represent multiple street lights connected to one junction

    This approach keeps the circuit safe for the Arduino while still allowing multiple LEDs to turn ON together during night conditions.


    Automatic Street Light Logic (LDR)

    • The LDR continuously measures ambient light
    • During daytime:
      • LDR value is high
      • Street LEDs remain OFF
    • During night:
      • LDR value drops below a threshold
      • Street LEDs turn ON automatically

    This demonstrates energy conservation, a core principle of smart cities.


    Smart Gate / Traffic Control System

    An ultrasonic sensor is placed near the entry point of the model.

    • When a vehicle or object comes within a fixed distance:
      • The ultrasonic sensor detects it
      • The servo motor rotates
      • The gate opens automatically
    • When the object moves away:
      • The gate closes again

    This simulates automatic toll gates, parking entry systems, and traffic barriers.


    Air Quality Monitoring (MQ135 Sensor)

    To introduce environmental monitoring, an MQ135 air quality sensor was added.

    • The sensor measures pollution levels in the surrounding air
    • When the pollution value crosses a preset threshold:
      • The buzzer turns ON
      • This acts as an air pollution warning

    This models how pollution monitoring stations work in smart cities.


    Alert System (Buzzer)

    The buzzer is used as a city alert mechanism.

    • OFF during normal air conditions
    • ON when pollution exceeds safe limits

    This introduces the concept of public warning systems and real-time environmental alerts.


    💻 Firmware Upload (Arduino Code)

    Flash the firmware directly to Arduino UNO:

    👉 This allows users to upload the tested firmware without opening the Arduino IDE.

    #include <Servo.h>
    
    #define TRIG_PIN 9
    #define ECHO_PIN 8
    #define LED_PIN  3
    #define LED_PIN1 5
    #define LDR_PIN  A0
    #define MQ135_PIN A1
    #define BUZZER_PIN 7
    #define SERVO_PIN 6
    
    Servo gateServo;
    
    long duration;
    int distance;
    int ldrValue;
    int airValue;
    
    int LDR_THRESHOLD = 500;     // adjust after testing
    int DIST_THRESHOLD = 15;     // cm
    int AIR_THRESHOLD  = 400;    // MQ135 threshold (adjust)
    
    void setup() {
      pinMode(TRIG_PIN, OUTPUT);
      pinMode(ECHO_PIN, INPUT);
      pinMode(LED_PIN, OUTPUT);
      pinMode(LED_PIN1, OUTPUT);
      pinMode(BUZZER_PIN, OUTPUT);
    
      gateServo.attach(SERVO_PIN);
      gateServo.write(90);   // gate closed
    
      Serial.begin(9600);
      Serial.println("Smart City System Starting...");
    }
    
    void loop() {
    
      /* ---------- LDR STREET LIGHT ---------- */
      ldrValue = analogRead(LDR_PIN);
    
      if (ldrValue < LDR_THRESHOLD) {
        analogWrite(LED_PIN, 255);     // street light ON
        digitalWrite(LED_PIN1, HIGH);
      } else {
        digitalWrite(LED_PIN, LOW);    // street light OFF
        digitalWrite(LED_PIN1, LOW);
      }
    
      /* ---------- ULTRASONIC SENSOR ---------- */
      digitalWrite(TRIG_PIN, LOW);
      delayMicroseconds(2);
      digitalWrite(TRIG_PIN, HIGH);
      delayMicroseconds(10);
      digitalWrite(TRIG_PIN, LOW);
    
      duration = pulseIn(ECHO_PIN, HIGH, 30000);
      distance = duration * 0.034 / 2;
    
      /* ---------- SERVO GATE CONTROL ---------- */
      if (distance > 0 && distance < DIST_THRESHOLD) {
        gateServo.write(0);    // open gate
      } else {
        gateServo.write(90);   // close gate
      }
    
      /* ---------- MQ135 AIR QUALITY ---------- */
      airValue = analogRead(MQ135_PIN);
    
      if (airValue > AIR_THRESHOLD) {
        digitalWrite(BUZZER_PIN, HIGH);   // pollution alert
      } else {
        digitalWrite(BUZZER_PIN, LOW);
      }
    
      /* ---------- SERIAL MONITOR ---------- */
      Serial.print("LDR: ");
      Serial.print(ldrValue);
      Serial.print(" | Distance: ");
      Serial.print(distance);
      Serial.print(" cm | Air: ");
      Serial.println(airValue);
    
      delay(1000);
    }

    Software Logic Summary

    The Arduino program continuously performs:

    • Ambient light measurement (LDR)
    • Distance measurement (Ultrasonic)
    • Air quality measurement (MQ135)
    • Decision-making based on thresholds
    • Actuator control (LEDs, servo, buzzer)

    All logic runs in a loop, similar to how embedded systems operate in real infrastructure.


    Educational Value

    This project helps learners understand:

    • GPIO usage and current limiting
    • Sensor interfacing and calibration
    • Real-world automation logic
    • Embedded decision-making
    • Power and safety considerations
    • Smart city concepts beyond theory

    Unlike ready-made kits, this setup uses discrete components, encouraging deeper understanding and troubleshooting skills.


    Conclusion

    This Smart City project demonstrates how simple electronics and embedded programming can be combined to address urban automation challenges such as energy efficiency, traffic control, and pollution monitoring.

    It serves as a reference implementation for students and educators exploring smart-city concepts using Arduino.

  • Arduino Uno Dot Matrix Display Using MAX7219 (Scrolling Text)

    In this project, we interface an 8×8 Dot Matrix Display (MAX7219) with Arduino Uno to display scrolling text using the MD_Parola library.

    This setup is ideal for learning:

    • SPI communication
    • External display control
    • Library-based programming
    • Real-time visual output from code

    All components, wiring, code, and flashing are available on a single page for smooth lab execution.


    Circuit Diagram (Arduino Uno + MAX7219)

    The circuit below shows the exact wiring required between the Arduino Uno and the dot matrix module.

    👉 Open this on the board or laptop and follow the connections directly.

    Open circuit Open circuit

    Pin Connections

    MAX7219 ModuleArduino Uno
    VCC5V
    GNDGND
    DIND11
    CS / LOADD10
    CLKD13

    Output Preview

    The following video shows the expected output after successful wiring and code upload.

    📺 Demo Video
    https://youtube.com/shorts/sZoBYKpf11I


    Required Libraries

    This project uses the following Arduino libraries:

    • MD_MAX72XX
    • MD_Parola

    How to Install Libraries

    1. Open Arduino IDE
    2. Go to Sketch → Include Library → Manage Libraries
    3. Search and install:
      • MD_MAX72XX
      • MD_Parola
    4. Restart Arduino IDE after installation

    If libraries are missing, the code will not compile.


    Arduino Uno Code (Scrolling Text)

    Copy and paste the following code into Arduino IDE:

    #include <MD_Parola.h>
    #include <MD_MAX72XX.h>
    #include <SPI.h>
    
    #define HARDWARE_TYPE MD_MAX72XX::FC16_HW
    #define MAX_DEVICES 1   // Number of dot matrix modules
    #define CS_PIN 10       // CS (LOAD) pin
    
    MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
    
    void setup() {
      P.begin();
      P.displayText("HELLO!", PA_CENTER, 70, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
    }
    
    void loop() {
      if (P.displayAnimate()) {
        P.displayReset();
      }
    }
    

    Uploading Code to Arduino Uno

    1. Connect Arduino Uno using USB cable
    2. Select:
      • Board: Arduino Uno
      • Port: Correct COM port
    3. Click Upload

    One-Click Arduino Flash (Recommended)

    To avoid IDE and driver issues, use the flash button below to upload firmware directly.


    Common Issues and Fixes

    • No display output
      • Check VCC and GND
      • Verify CS pin is set to 10 in code
    • Compilation error
      • Confirm both libraries are installed
    • Display orientation incorrect
      • Ensure FC16_HW hardware type is selected

    Next Steps

    You can extend this project by:

    • Adding a joystick to control text movement
    • Changing text dynamically
    • Using multiple dot matrix modules
    • Creating interactive animations

    This project forms a strong foundation for input + output based embedded systems.

  • AI Robot Head Tracking Using Browser Vision (No Training, No Server)

    Turn your head left, right, up, and down.
    Open circuit Open circuit

    Download FreeCAD project and STL files

    Introduction

    Most “AI robot face” demos rely on heavy machine-learning models, cloud APIs, or large datasets.
    This project explores a different approach:

    Using simple geometry and browser-based vision to create an expressive robot head that reacts to human movement in real time.

    The robot head tracks left, right, up, and down head motion and mirrors it using animated eyes displayed on a small OLED screen — all controlled directly from a web browser.

    No dataset.
    No model training.
    No server.

    What This Project Does

    • Detects a human face using the browser camera
    • Estimates head orientation (yaw & pitch)
    • Sends motion data to an Arduino using Web Serial
    • Animates eye movement on a 0.96″ OLED display
    • Allows direction inversion (mirror correction) at runtime

    The result is a small robot head that feels responsive and alive.

    System Architecture

    Browser Camera
          ↓
    Face Geometry (MediaPipe)
          ↓
    Yaw & Pitch Calculation
          ↓
    Web Serial (USB)
          ↓
    Arduino UNO
          ↓
    OLED Eye Animation
    

    All computation happens locally in the browser.

    Hardware Used

    • Arduino UNO
    • 0.96″ OLED (SSD1306, I2C)
    • USB cable
    • 3D-printed enclosure

    Software Stack

    • HTML + JavaScript
    • MediaPipe Face Mesh
    • Web Serial API
    • Arduino (C++)

    Key Design Decisions

    1. Pupils Move, Not Eyeballs

    Moving only the pupils inside fixed eyeballs makes the face feel more natural and expressive.

    2. Face-Relative Geometry

    Head motion is measured relative to facial landmarks, not camera pixels.
    This makes movement symmetric and stable.

    3. Runtime Direction Flip

    A toggle button allows instant correction for mirrored cameras without changing code.


    Educational Value

    This project can be used to teach:

    • Coordinate systems
    • Geometry-based tracking
    • Browser ↔ hardware communication
    • Human-centered design

    It is suitable for classrooms, labs, and exhibitions.


    Conclusion

    This robot head demonstrates that intelligence is not just about models, but about understanding interaction.

    By combining browser vision, simple math, and embedded hardware, we can build systems that feel responsive, expressive, and intuitive — without complexity.


    Try It Live

    Allow camera access, connect the Arduino, and move your head left, right, up, and down.

  • RGB LED with Arduino UNO/Nano

    What is an RGB LED and What Are We Building Here?

    An RGB LED is a special type of LED that contains three LEDs inside one packageRed, Green, and Blue.
    Using these three colours, the Arduino can blend them at different brightness levels to produce hundreds of colours like yellow, cyan, purple, pink, white, sky-blue, etc.

    In this example, we are using a Common-Cathode RGB LED, which means:

    • All three LEDs share one common negative (–) pin
    • The individual colour pins (R, G, B) must be connected through 220Ω resistors
    • The Arduino controls brightness using PWM pins
      • Red → D3
      • Green → D5
      • Blue → D6

    This forms the basis for colour-mixing projects used in IoT, indicators, robots, and UI feedback systems.

    Below, you can see the circuit wiring diagram, the mBlock representation, and the equivalent Arduino IDE code.
    Finally, you can flash the firmware directly from this page using ExaSub’s online uploader — no Arduino IDE installation required.

    Open circuit Open circuit

    Arduino IDE CODE

    // RGB LED with Arduino Nano
    // Common Cathode RGB LED
    // R -> D3, G -> D5, B -> D6
    
    int redPin = 3;
    int greenPin = 5;
    int bluePin = 6;
    
    void setup() {
      pinMode(redPin, OUTPUT);
      pinMode(greenPin, OUTPUT);
      pinMode(bluePin, OUTPUT);
    }
    
    void loop() {
      setColor(255, 0, 0);   // Red
      delay(800);
    
      setColor(0, 255, 0);   // Green
      delay(800);
    
      setColor(0, 0, 255);   // Blue
      delay(800);
    
      setColor(255, 255, 0); // Yellow (Red + Green)
      delay(800);
    
      setColor(80, 0, 255);  // Purple
      delay(800);
    
      setColor(0, 255, 255); // Cyan (Green + Blue)
      delay(800);
    
      setColor(255, 255, 255); // White
      delay(800);
    
      setColor(0, 0, 0);     // Off
      delay(800);
    }
    
    // Function to mix RGB
    void setColor(int r, int g, int b) {
      analogWrite(redPin, 255 - r);    // common cathode → invert logic
      analogWrite(greenPin, 255 - g);
      analogWrite(bluePin, 255 - b);
    }
    

    Mblock Code

    Flash Arduino UNO/Nano Directly From Browser Click on Button

    Note: Nano with old bootloader is not supported. Use the code with the arduino IDE for the Nano with old bootloader.

  • 3D printer setting for shiny prints

    I made a Cylindrical box for storing my leftover spices. So i made it, sliced it and let it to print. It was a H: 100mm , R: 60mm.

    On roughly about 20mm i changed the speed of the printer to just 25%.

    I found out that at 25% of the speed the print lines are shiny and when i resumed the print after few mm i got that dull look.

    So if you want to prints to come out shiny use low speeds. under 40mm/s for outer shell.

    But there is a catch since it is running slowly the more material will come out of the nozzle and you have to adjust the flow rate for it.

  • Make a Joystick-Controlled Car with ESP32 and NodeMCU

    Are you interested in making a remote-controlled car using ESP32 and NodeMCU? In this project, we will use a joystick module to control a car wirelessly. This is a fun and simple way to explore ESP-NOW communication and motor control!


    What You Need

    To build this joystick-controlled car, you will need:

    • ESP32 (for the remote controller)
    • NodeMCU (ESP8266) (for the car)
    • Joystick module
    • L298N motor driver
    • Two DC motors (500 RPM Johnson motors)
    • Two wheels (70mm diameter, 20mm width)
    • LM2596 voltage regulator (to power NodeMCU)
    • Power source (3S battery or similar)
    • Jumper wires

    How It Works

    • The ESP32 reads joystick movements and sends commands wirelessly using ESP-NOW.
    • The NodeMCU receives these commands and controls the motors accordingly.
    • The car moves forward, backward, left, and right based on joystick input.

    Wiring Connections

    Remote (ESP32 + Joystick Module)

    • Joystick VCCESP32 3.3V
    • Joystick GNDESP32 GND
    • Joystick X-axisESP32 GPIO 34
    • Joystick Y-axisESP32 GPIO 35

    Car (NodeMCU + L298N Motor Driver + Motors)

    • Motor 1 IN1NodeMCU D1
    • Motor 1 IN2NodeMCU D2
    • Motor 2 IN1NodeMCU D3
    • Motor 2 IN2NodeMCU D4
    • Motor 1 ENANodeMCU D5
    • Motor 2 ENBNodeMCU D6
    • LM2596 Output (3.3V/5V)NodeMCU Vin
    • LM2596 GroundNodeMCU GND

    ESP32 Code for the Remote

    #include <esp_now.h>
    #include <WiFi.h>
    
    // Define DEBUG to enable or disable serial debug statements
    //#define DEBUG  // Comment this line to disable debug statements
    
    const int xPin = 34;  // X-axis connected to GPIO 34
    const int yPin = 35;  // Y-axis connected to GPIO 35
    
    // Define thresholds for dead zone (adjust as needed)
    const float DEAD_ZONE_THRESHOLD = 0.2;  // Joystick values within ±0.2V are considered centered
    
    uint8_t broadcastAddress[] = {0xCC, 0x50, 0xE3, 0x0D, 0x15, 0x09};
    
    typedef struct struct_message {
      char command[32];
      int b;
    } struct_message;
    
    struct_message myData;
    esp_now_peer_info_t peerInfo;
    
    void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
      #ifdef DEBUG
      Serial.print("\r\nLast Packet Send Status:\t");
      Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
      #endif
    }
    
    void setup() {
        #ifdef DEBUG
        Serial.begin(115200);
        #endif
    
        WiFi.mode(WIFI_STA);
    
        if (esp_now_init() != ESP_OK) {
            #ifdef DEBUG
            Serial.println("Error initializing ESP-NOW");
            #endif
            return;
        }
    
        esp_now_register_send_cb(OnDataSent);
        memcpy(peerInfo.peer_addr, broadcastAddress, 6);
        peerInfo.channel = 0;
        peerInfo.encrypt = false;
        if (esp_now_add_peer(&peerInfo) != ESP_OK) {
            #ifdef DEBUG
            Serial.println("Failed to add peer");
            #endif
            return;
        }
    }
    
    void loop() {
        int xValue = analogRead(xPin);  // Read X-axis value
        int yValue = analogRead(yPin);  // Read Y-axis value
    
        float xVoltage = (xValue * 3.3) / 4095;  // Convert to voltage (0-3.3V)
        float yVoltage = (yValue * 3.3) / 4095;  // Convert to voltage (0-3.3V)
    
        #ifdef DEBUG
        Serial.print("X Voltage: "); Serial.print(xVoltage);
        Serial.print(" | Y Voltage: "); Serial.println(yVoltage);
        #endif
    
        // Check if the joystick is within the dead zone (centered)
        if (abs(xVoltage - 1.65) < DEAD_ZONE_THRESHOLD && abs(yVoltage - 1.65) < DEAD_ZONE_THRESHOLD) {
            strcpy(myData.command, "S"); // Stop (centered)
            myData.b = 0;  // No movement
        }
        // Check for movement outside the dead zone
        else if (xVoltage > (1.65 + DEAD_ZONE_THRESHOLD)) {
            strcpy(myData.command, "F"); // Forward
            myData.b = xVoltage;
        } else if (xVoltage < (1.65 - DEAD_ZONE_THRESHOLD)) {
            strcpy(myData.command, "B"); // Backward
            myData.b = xVoltage;
        } else if (yVoltage > (1.65 + DEAD_ZONE_THRESHOLD)) {
            strcpy(myData.command, "L"); // Left
            myData.b = yVoltage;
        } else if (yVoltage < (1.65 - DEAD_ZONE_THRESHOLD)) {
            strcpy(myData.command, "R"); // Right
            myData.b = yVoltage;
        }
    
        // Send the command via ESP-NOW
        esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
        #ifdef DEBUG
        if (result == ESP_OK) {
            Serial.println("Sent with success");
        } else {
            Serial.println("Error sending the data");
        }
        #endif
        
        delay(20);  // Small delay to make output readable
    }

    NodeMCU Code for the Car

    #include <ESP8266WiFi.h>
    #include <espnow.h>
    
    // Structure to receive data
    typedef struct struct_message {
      char a[32];
      int b;
      float c;
      bool d;
    } struct_message;
    
    struct_message myData;
    
    // Pin definitions
    #define LED_PIN 2  // Onboard LED pin (D4 on ESP8266)
    #define M1_ENA D5   // Motor 1 PWM (Speed)
    #define M2_ENB D6   // Motor 1 PWM (Speed)
    #define M1_IN1 D1  // Motor 1 input 1
    #define M1_IN2 D2  // Motor 1 input 2
    #define M2_IN1 D3  // Motor 2 input 1
    #define M2_IN2 D4  // Motor 2 input 2
    
    // Default speeds (adjust these values experimentally)
    int speedLeft = 800;   // 0-1023 (80% speed)
    int speedRight = 700;  // Right motor slightly slower
    
    // Callback function when data is received
    void OnDataRecv(uint8_t *mac, uint8_t *incomingData, uint8_t len) {
      memcpy(&myData, incomingData, sizeof(myData));
      Serial.print("Bytes received: ");
      Serial.println(len);
      Serial.print("Data received: ");
      Serial.println(myData.a);
      Serial.print("value received: ");
      Serial.println(myData.b);
    
      // Control motors based on received character
      if (strcmp(myData.a, "F") == 0) {
        // Move forward
        analogWrite(M1_ENA, speedLeft);
        analogWrite(M2_ENB, speedRight);
        digitalWrite(M1_IN1, HIGH); digitalWrite(M1_IN2, LOW);
        digitalWrite(M2_IN1, HIGH); digitalWrite(M2_IN2, LOW);
        digitalWrite(LED_PIN, LOW);  // Turn on LED (inverted logic on ESP8266)
      } else if (strcmp(myData.a, "B") == 0) {
        // Move backward
        analogWrite(M1_ENA, speedLeft);
        analogWrite(M2_ENB, speedRight);
        digitalWrite(M1_IN1, LOW); digitalWrite(M1_IN2, HIGH);
        digitalWrite(M2_IN1, LOW); digitalWrite(M2_IN2, HIGH);
        digitalWrite(LED_PIN, HIGH);  // Turn off LED (inverted logic on ESP8266)
      } else if (strcmp(myData.a, "L") == 0) {
        // Turn left
        analogWrite(M1_ENA, speedLeft);
        analogWrite(M2_ENB, speedRight);
        digitalWrite(M1_IN1, LOW); digitalWrite(M1_IN2, HIGH);
        digitalWrite(M2_IN1, HIGH); digitalWrite(M2_IN2, LOW);
      } else if (strcmp(myData.a, "R") == 0) {
        // Turn right
        analogWrite(M1_ENA, speedLeft);
        analogWrite(M2_ENB, speedRight);
        digitalWrite(M1_IN1, HIGH); digitalWrite(M1_IN2, LOW);
        digitalWrite(M2_IN1, LOW); digitalWrite(M2_IN2, HIGH);
      }
      else if (strcmp(myData.a, "S") == 0) {
        // Turn right
        analogWrite(M1_ENA, 0);
        analogWrite(M2_ENB, 0);
        digitalWrite(M1_IN1, HIGH); digitalWrite(M1_IN2, LOW);
        digitalWrite(M2_IN1, LOW); digitalWrite(M2_IN2, HIGH);
      } else {
        // Stop motors
        analogWrite(M1_ENA, 0);
        analogWrite(M2_ENB, 0);
        //   digitalWrite(M1_IN1, LOW); digitalWrite(M1_IN2, LOW);
        //   digitalWrite(M2_IN1, LOW); digitalWrite(M2_IN2, LOW);
      }
    }
    
    void setup() {
      // Initialize Serial Monitor
      Serial.begin(115200);
    
      // Initialize pins
      pinMode(LED_PIN, OUTPUT);
      pinMode(M1_IN1, OUTPUT);
      pinMode(M1_IN2, OUTPUT);
      pinMode(M2_IN1, OUTPUT);
      pinMode(M2_IN2, OUTPUT);
    
      // Ensure motors and LED are off initially
      digitalWrite(LED_PIN, HIGH);  // LED off (inverted logic on ESP8266)
      digitalWrite(M1_IN1, LOW); digitalWrite(M1_IN2, LOW);
      digitalWrite(M2_IN1, LOW); digitalWrite(M2_IN2, LOW);
    
      // Set device as a Wi-Fi Station
      WiFi.mode(WIFI_STA);
    
      // Initialize ESP-NOW
      if (esp_now_init() != 0) {
        Serial.println("Error initializing ESP-NOW");
        return;
      }
    
      // Register the receive callback
      esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
      esp_now_register_recv_cb(OnDataRecv);
    }
    
    void loop() {
      // Nothing to do here
    }

    How to Upload the Code

    1. Upload the remote code to your ESP32.
    2. Upload the car code to your NodeMCU.
    3. Power up both devices and check serial monitor outputs for debugging.

    Testing the Car

    1. Move the joystick forward → The car moves forward.
    2. Move the joystick backward → The car moves backward.
    3. Move the joystick left → The car turns left.
    4. Move the joystick right → The car turns right.
    5. Release the joystick (center position) → The car stops.

    3d Printed parts

    Since when i made this car. I had Johnson motors of 500RPM. But i did not had any bracket so i designed the brackets in FreeCAD and printed on Creality ender 3 v3 KE printer.

  • CREALITY Ender-3 V3 KE

    I bought the printer from wol3d’s New Delhi office.
    I am a electronics guy but i have inclination towards the 3d printing world. The feeling that you can design and make something in front of you. It’s a slow process but this printer comes with a slicer software which is fast.

    Build Volume : 220 x 220 x 240 mm

    The best thing is the auto bed leveling on this printer. I do not have to adjust the four corner bolts and rub a paper under the nozzle. It is done automatically done.


    Till now the results are amazing.

    I have noticed that the prints depends upon a lot of things:

    • Filament Quality :
      I have used a few filaments samples i got my hand on they were old and new. The old one which are above one year old open packet are just brittle they clog the printer every now and then. and one time it was so break while in the extruder which set my heart racing as i don’t want new printer to clog and change its nozzle. Thankfully the nozzle clogged removed when i inserted the fresh PLA and forced it into the extruder.
      So yes always use new filament. And also some filament are bad weather they are new or old.
    • Bed adhesion
    • Print Temp
    • Slicer Setting
  • German Vocabulary 4 – Kartoffeln Bockshornkleeblätter Rezept

    DeutschEnglish

    Kartoffeln Bockshornkleeblätter Rezept auf Deutsch


    Zutaten:

    • Kartoffeln (Aloo) – 3 mittelgroße, geschält und in kleine Würfel geschnitten
    • Bockshornkleeblätter (Methi) – 2 Tassen, frisch und gehackt
    • Öl – 2-3 Esslöffel
    • Kreuzkümmelsamen (Jeera) – 1 Teelöffel
    • Asafoetida (Hing) – eine Prise (optional)
    • Grüne Chilis – 2, fein gehackt (je nach Geschmack anpassen)
    • Knoblauch – 3-4 Zehen, gehackt (optional, aber geschmackvoll)
    • Korianderpulver (Dhaniya) – 1 Teelöffel
    • Salz – nach Geschmack

    Anleitung:

    1. Bockshornkleeblätter vorbereiten:
      Die Bockshornkleeblätter gründlich waschen, um Schmutz zu entfernen, und fein hacken. Beiseitestellen.
    2. Öl erhitzen:
      Öl in einer Pfanne oder einem Topf bei mittlerer Hitze erhitzen.
    3. Gewürze hinzufügen:
      Kreuzkümmelsamen in das heiße Öl geben und anbraten, bis sie anfangen zu knistern. Optional Asafoetida hinzufügen.
    4. Knoblauch und Chilis anbraten:
      Gehackten Knoblauch und grüne Chilis dazugeben. Anbraten, bis der Knoblauch goldbraun wird.
    5. Kartoffeln kochen:
      Die gewürfelten Kartoffeln hinzufügen. Gut vermischen und mit Korianderpulver würzen. Alles gleichmäßig vermengen.
    6. Abdecken und kochen:
      Die Pfanne abdecken und die Kartoffeln bei niedriger bis mittlerer Hitze etwa 7-10 Minuten kochen lassen. Gelegentlich umrühren, damit nichts anbrennt.
    7. Bockshornkleeblätter hinzufügen:
      Sobald die Kartoffeln halb gar sind, die gehackten Bockshornkleeblätter hinzufügen. Gut vermischen.
    8. Zusammen kochen:
      Wieder abdecken und weitere 5-7 Minuten kochen lassen, dabei gelegentlich umrühren, bis die Kartoffeln weich sind und die Bockshornkleeblätter gut eingearbeitet sind.
    9. Abschmecken:
      Mit Salz abschmecken und gut vermischen. Noch eine Minute kochen lassen.
    10. Servieren:
      Vom Herd nehmen und heiß mit Roti, Paratha oder Reis servieren.

    Guten Appetit! 😊

    Ingredients:

    • Potatoes (Aloo) – 3 medium-sized, peeled and diced into small cubes
    • Fenugreek Leaves (Methi) – 2 cups, fresh and chopped
    • Oil – 2-3 tablespoons
    • Cumin Seeds (Jeera) – 1 teaspoon
    • Asafoetida (Hing) – a pinch (optional)
    • Green Chilies – 2, finely chopped (adjust to taste)
    • Garlic – 3-4 cloves, minced (optional but adds flavor)
    • Coriander Powder (Dhaniya) – 1 teaspoon
    • Salt – to taste

    Instructions:

    1. Prepare Fenugreek Leaves:
      Wash the methi leaves thoroughly to remove dirt and chop them finely. Set aside.
    2. Heat Oil:
      Heat oil in a pan or kadai on medium heat.
    3. Add Aromatics:
      Add cumin seeds and let them splutter. Add a pinch of asafoetida if using.
    4. Sauté Garlic and Chilies:
      Add the minced garlic and green chilies. Sauté until the garlic turns golden.
    5. Cook Potatoes:
      Add the diced potatoes to the pan. Mix well and add coriander powder. Stir everything to coat the potatoes evenly with spices.
    6. Cover and Cook:
      Cover the pan and let the potatoes cook on low-medium heat for about 7-10 minutes, stirring occasionally to prevent sticking.
    7. Add Fenugreek Leaves:
      Once the potatoes are partially cooked, add the chopped methi leaves. Mix well.
    8. Cook Together:
      Cover and cook for another 5-7 minutes, stirring occasionally, until the potatoes are fully cooked and the methi leaves are well incorporated.
    9. Season:
      Add salt and mix well. Cook for another minute.
    10. Serve:
      Remove from heat and serve hot with roti, paratha, or rice.

    Enjoy your flavorful and simplified Aloo Methi! 😊

  • How to blink the onboard LED on the ESP32 Devkit V1

    The onboard LED is connected to GPIO 2

    code

    #define led 2
    void setup() {
      // put your setup code here, to run once:
    pinMode(2, OUTPUT);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    digitalWrite(led, 1);
    delay(1000);
    digitalWrite(led, 0);
    delay(200);
    }