Progressive Learning: Servo, Water Sensor, DC Motor & Integration
This tutorial teaches Arduino programming through progressive examples, starting with individual components and building up to a complete integrated system. Each example is standalone and ready to run.
Main microcontroller board
180° positioning servo
Analog liquid detector
Motor and driver module
For motor driver (1A min)
For prototyping
1Start with the simplest actuator - a servo motor. Learn positioning, sweeping, and angle control.
| Servo Pin | Arduino Pin | Wire Color |
|---|---|---|
| GND (Brown/Black) | GND | Black/Brown |
| VCC (Red) | 5V | Red |
| Signal (Orange/Yellow) | D9 | Orange/Yellow/White |
/*
* Example 1: Servo Motor Control
* Learn: Basic servo positioning and sweeping motion
*/
#include <Servo.h>
// Create servo object
Servo myServo;
// Pin definition
const int SERVO_PIN = 9;
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Attach servo to pin 9
myServo.attach(SERVO_PIN);
Serial.println("=== Servo Motor Test ===");
Serial.println("Starting sweep motion...");
}
void loop() {
// Sweep from 0 to 180 degrees
Serial.println("Sweeping 0° to 180°");
for (int angle = 0; angle <= 180; angle += 5) {
myServo.write(angle);
Serial.print("Position: ");
Serial.print(angle);
Serial.println("°");
delay(50); // Wait for servo to reach position
}
delay(500); // Pause at 180°
// Sweep back from 180 to 0 degrees
Serial.println("Sweeping 180° to 0°");
for (int angle = 180; angle >= 0; angle -= 5) {
myServo.write(angle);
Serial.print("Position: ");
Serial.print(angle);
Serial.println("°");
delay(50);
}
delay(500); // Pause at 0°
Serial.println("---");
}
The servo will continuously sweep from 0° to 180° and back, with position updates printed to Serial Monitor every 50ms.
2Learn analog input by reading a water level sensor. Understand ADC conversion and data mapping.
| Sensor Pin | Arduino Pin | Function |
|---|---|---|
| - (GND) | GND | Ground |
| + (VCC) | 5V | Power (5V) |
| S (Signal) | A0 | Analog output |
/*
* Example 2: Water Level Sensor
* Learn: Analog input, ADC conversion, data mapping
*/
// Pin definition
const int WATER_SENSOR_PIN = A0;
// Variables
int sensorValue = 0; // Raw ADC reading (0-1023)
int waterPercentage = 0; // Converted to percentage
// Calibration values (adjust for your sensor)
const int SENSOR_MIN = 0; // Value when sensor is dry
const int SENSOR_MAX = 700; // Value when fully submerged
void setup() {
// Initialize serial communication
Serial.begin(9600);
Serial.println("=== Water Level Sensor Test ===");
Serial.println("Reading sensor values...");
Serial.println();
}
void loop() {
// Read analog value from sensor (0-1023)
sensorValue = analogRead(WATER_SENSOR_PIN);
// Convert to percentage (0-100%)
waterPercentage = map(sensorValue, SENSOR_MIN, SENSOR_MAX, 0, 100);
// Constrain to valid range
waterPercentage = constrain(waterPercentage, 0, 100);
// Display results
Serial.print("Raw Value: ");
Serial.print(sensorValue);
Serial.print(" | Water Level: ");
Serial.print(waterPercentage);
Serial.print("% | ");
// Status indicator
if (waterPercentage < 20) {
Serial.println("Status: LOW ⬇️");
} else if (waterPercentage < 50) {
Serial.println("Status: MEDIUM ➡️");
} else if (waterPercentage < 80) {
Serial.println("Status: HIGH ⬆️");
} else {
Serial.println("Status: FULL ✓");
}
// Update every second
delay(1000);
}
3Control a DC motor using the L298N motor driver. Learn PWM speed control and direction changes.
| L298N Pin | Arduino Pin | Function |
|---|---|---|
| ENA | D5 | PWM speed control (0-255) |
| IN1 | D6 | Direction control 1 |
| IN2 | D7 | Direction control 2 |
| GND | GND | Common ground |
| +12V | External 12V supply | Motor power |
| GND (Power) | External supply GND | Power ground |
/*
* Example 3: DC Motor Control with L298N
* Learn: Motor driver operation, PWM speed control, direction changes
*/
// Pin definitions
const int MOTOR_ENA = 5; // PWM speed control pin
const int MOTOR_IN1 = 6; // Direction pin 1
const int MOTOR_IN2 = 7; // Direction pin 2
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Configure motor driver pins as outputs
pinMode(MOTOR_ENA, OUTPUT);
pinMode(MOTOR_IN1, OUTPUT);
pinMode(MOTOR_IN2, OUTPUT);
// Start with motor stopped
stopMotor();
Serial.println("=== DC Motor Control Test ===");
Serial.println("Testing speed and direction...");
Serial.println();
}
void loop() {
// Test 1: Forward at different speeds
Serial.println("Forward - Low Speed (100 PWM)");
runMotorForward(100);
delay(3000);
Serial.println("Forward - Medium Speed (180 PWM)");
runMotorForward(180);
delay(3000);
Serial.println("Forward - Full Speed (255 PWM)");
runMotorForward(255);
delay(3000);
// Stop
Serial.println("Stopping...");
stopMotor();
delay(2000);
// Test 2: Reverse at different speeds
Serial.println("Reverse - Low Speed (100 PWM)");
runMotorReverse(100);
delay(3000);
Serial.println("Reverse - Full Speed (255 PWM)");
runMotorReverse(255);
delay(3000);
// Stop
Serial.println("Stopping...");
stopMotor();
delay(2000);
Serial.println("--- Cycle Complete ---\n");
delay(1000);
}
// Function: Run motor forward at specified speed
void runMotorForward(int speed) {
// Set direction: IN1 = HIGH, IN2 = LOW
digitalWrite(MOTOR_IN1, HIGH);
digitalWrite(MOTOR_IN2, LOW);
// Set speed (0-255)
analogWrite(MOTOR_ENA, speed);
}
// Function: Run motor in reverse at specified speed
void runMotorReverse(int speed) {
// Set direction: IN1 = LOW, IN2 = HIGH
digitalWrite(MOTOR_IN1, LOW);
digitalWrite(MOTOR_IN2, HIGH);
// Set speed (0-255)
analogWrite(MOTOR_ENA, speed);
}
// Function: Stop motor
void stopMotor() {
// Set both direction pins LOW
digitalWrite(MOTOR_IN1, LOW);
digitalWrite(MOTOR_IN2, LOW);
// Set speed to 0
analogWrite(MOTOR_ENA, 0);
}
The motor will run through a test sequence: forward at increasing speeds, stop, reverse at different speeds, then repeat. Each step is announced via Serial Monitor.
4Combine all components into an intelligent water tank management system with automated pump control.
/*
* Example 4: Complete Water Tank Management System
* Integrates: Water Level Sensor + DC Motor Pump + Servo Valve
*
* System Logic:
* - Monitors water level continuously
* - Activates pump when level drops below 30%
* - Runs pump at reduced speed between 30-80%
* - Stops pump when level exceeds 80%
* - Servo indicates water level position (0° = empty, 180° = full)
*/
#include <Servo.h>
// ========== PIN DEFINITIONS ==========
// Water Level Sensor
const int WATER_SENSOR_PIN = A0;
// Servo Motor (Valve)
const int SERVO_PIN = 9;
// DC Motor (Pump) via L298N
const int MOTOR_ENA = 5; // PWM speed control
const int MOTOR_IN1 = 6; // Direction 1
const int MOTOR_IN2 = 7; // Direction 2
// ========== OBJECTS ==========
Servo valveServo;
// ========== VARIABLES ==========
int waterLevel = 0; // Raw sensor value (0-1023)
int waterPercentage = 0; // Water level percentage (0-100%)
int valvePosition = 0; // Servo angle (0-180°)
int pumpSpeed = 0; // Motor PWM (0-255)
bool pumpRunning = false; // Pump state
// ========== CONFIGURATION ==========
// Sensor calibration (adjust for your sensor)
const int SENSOR_MIN = 0; // Dry reading
const int SENSOR_MAX = 700; // Submerged reading
// Control thresholds
const int LEVEL_LOW = 30; // Start pump below 30%
const int LEVEL_HIGH = 80; // Stop pump above 80%
// Motor speeds
const int PUMP_SPEED_FULL = 255; // Maximum speed
const int PUMP_SPEED_LOW = 150; // Reduced speed
void setup() {
// Initialize serial for monitoring
Serial.begin(9600);
// Configure motor pins
pinMode(MOTOR_ENA, OUTPUT);
pinMode(MOTOR_IN1, OUTPUT);
pinMode(MOTOR_IN2, OUTPUT);
// Initialize servo
valveServo.attach(SERVO_PIN);
// Start with safe states
stopPump();
valveServo.write(0);
// Startup message
Serial.println("=========================================");
Serial.println(" WATER TANK MANAGEMENT SYSTEM v1.0 ");
Serial.println("=========================================");
Serial.println("System Status: ONLINE");
Serial.println("Monitoring water level...");
Serial.println();
delay(2000);
}
void loop() {
// ========== READ WATER LEVEL ==========
waterLevel = analogRead(WATER_SENSOR_PIN);
waterPercentage = map(waterLevel, SENSOR_MIN, SENSOR_MAX, 0, 100);
waterPercentage = constrain(waterPercentage, 0, 100);
// ========== AUTOMATIC PUMP CONTROL ==========
if (waterPercentage < LEVEL_LOW && !pumpRunning) {
// Water level is LOW - Start pump at FULL speed
startPump(PUMP_SPEED_FULL);
Serial.println("🔵 ACTION: Pump STARTED (Water LOW)");
}
else if (waterPercentage > LEVEL_HIGH && pumpRunning) {
// Water level is HIGH - Stop pump
stopPump();
Serial.println("🟢 ACTION: Pump STOPPED (Water HIGH)");
}
else if (waterPercentage >= LEVEL_LOW && waterPercentage <= LEVEL_HIGH && pumpRunning) {
// Water level in MIDDLE range - Reduce pump speed
startPump(PUMP_SPEED_LOW);
}
// ========== VALVE POSITION CONTROL ==========
// Map water level to servo angle (visual indicator)
valvePosition = map(waterPercentage, 0, 100, 0, 180);
valveServo.write(valvePosition);
// ========== DISPLAY STATUS ==========
Serial.print("📊 Raw: ");
Serial.print(waterLevel);
Serial.print(" | Level: ");
Serial.print(waterPercentage);
Serial.print("%");
Serial.print(" | Pump: ");
if (pumpRunning) {
Serial.print("ON (");
Serial.print(pumpSpeed);
Serial.print(" PWM)");
} else {
Serial.print("OFF");
}
Serial.print(" | Valve: ");
Serial.print(valvePosition);
Serial.println("°");
// Alert messages
if (waterPercentage < 20) {
Serial.println("⚠️ ALERT: Water level CRITICAL!");
} else if (waterPercentage > 90) {
Serial.println("⚠️ WARNING: Near maximum capacity!");
}
Serial.println("----------------------------------------");
// Update every second
delay(1000);
}
// ========== MOTOR CONTROL FUNCTIONS ==========
void startPump(int speed) {
// Set direction: Forward (IN1=HIGH, IN2=LOW)
digitalWrite(MOTOR_IN1, HIGH);
digitalWrite(MOTOR_IN2, LOW);
// Set speed via PWM
analogWrite(MOTOR_ENA, speed);
pumpSpeed = speed;
pumpRunning = true;
}
void stopPump() {
// Stop motor: Both direction pins LOW
digitalWrite(MOTOR_IN1, LOW);
digitalWrite(MOTOR_IN2, LOW);
// Set speed to 0
analogWrite(MOTOR_ENA, 0);
pumpSpeed = 0;
pumpRunning = false;
}
| Water Level | Pump Status | Pump Speed | Valve Position |
|---|---|---|---|
| 0-30% | ON (Starting) | 255 PWM (Full) | 0°-54° |
| 30-80% | ON (Filling) | 150 PWM (Reduced) | 54°-144° |
| 80-100% | OFF | 0 PWM (Stopped) | 144°-180° |