Arduino Project

Servo Control 4.0

Course Introduction

This project uses two touch sensors to control a servo motor. Press and hold a sensor to move the servo toward 0° or 180° in 5° steps. Both pressed = no movement. Initial angle: 90°.

Note

If this is your first time working with an Arduino project, we recommend downloading and reviewing the basic materials first.

1.1 Install Arduino IDE(Important)
1.2 Introduction of Arduino IDE

Required Components

In this project, we need the following components:

SN

COMPONENT INTRODUCTION

QUANTITY

PURCHASE LINK

1

Arduino UNO R4 WIFI

1

2

USB Type-C cable

1

×

3

Breadboard

1

BUY

4

Wires

Several

5

Touch Sensor Module

1

6

Rotary Encoder Module

1

Wiring

4.webp__PID:f307327a-4b6f-4a89-80dc-54756ca327b5

Common Connections:

Digital Servo Motor
Connect to breadboard’s positive power bus.
Connect to breadboard’s negative power bus.
Connect to 3 on the Arduino.

Touch Sensor Module 1
SIG:
Connect to 2 on the Arduino.
GND: Connect to breadboard’s negative power bus.
VCC: Connect to breadboard’s red power bus.

Touch Sensor Module 2
SIG:
Connect to 12 on the Arduino.
GND: Connect to breadboard’s negative power bus.
VCC: Connect to breadboard’s red power bus

Writing the Code

Note
You can copy this code into Arduino IDE.
Don’t forget to select the board(Arduino UNO R4 Minima/WIFI) and the correct port before clicking the Upload button.


/* Two Touch Sensors -> Servo (press-and-hold auto-repeat)
* Pins:
*   Touch #1 (toward 0°):  D2
*   Touch #2 (toward 180°): D12
*   Servo: D6
*
* Behavior:
*   - Initial angle = 90°
*   - On press: move immediately by 3°
*   - While holding: keep stepping every REPEAT_MS by 3°
*   - If both held: neutral (no move). You can change to priority if desired.
*
* Note:
*   Most capacitive touch modules output HIGH when touched.
*   If your module is ACTIVE-LOW, flip the read logic as commented below.
*/

#include 

const int PIN_TOUCH_01 = 2;     // toward 0°
const int PIN_TOUCH_02 = 12;    // toward 180°
const int PIN_SERVO    = 6;

const int  STEP_DEG       = 5;      // degrees per step
const unsigned long REPEAT_MS = 80;  // step interval while holding
const unsigned long FIRST_STEP_DELAY_MS = 0; // 0 = immediate first step

Servo servo;
int angleDeg = 90;  // start at 90°

enum Dir { STOP = 0, TO_0 = -1, TO_180 = +1 };

// state for auto-repeat
Dir currentDir = STOP;
unsigned long holdStartMs = 0;   // when the currentDir started
unsigned long lastStepMs  = 0;   // last time we stepped

void setup() {
  pinMode(PIN_TOUCH_01, INPUT);  // HIGH when touched (typical)
  pinMode(PIN_TOUCH_02, INPUT);
  // If ACTIVE-LOW modules, you can keep INPUT but invert reads below.

  servo.attach(PIN_SERVO);
  servo.write(angleDeg);

  Serial.begin(9600);
  Serial.println("Press-and-hold servo control ready.");
}

void loop() {
  unsigned long now = millis();

  // --- Read touch states ---
  bool t1 = (digitalRead(PIN_TOUCH_01) == HIGH);  // ACTIVE-HIGH typical
  bool t2 = (digitalRead(PIN_TOUCH_02) == HIGH);
  // If ACTIVE-LOW modules, use:
  // bool t1 = (digitalRead(PIN_TOUCH_01) == LOW);
  // bool t2 = (digitalRead(PIN_TOUCH_02) == LOW);

  // --- Decide direction ---
  Dir nextDir = STOP;
  if (t1 && !t2)      nextDir = TO_0;
  else if (!t1 && t2) nextDir = TO_180;
  else                nextDir = STOP;  // both idle or both pressed -> neutral

  // --- Handle dir changes (start/stop hold) ---
  if (nextDir != currentDir) {
    currentDir = nextDir;
    holdStartMs = now;
    lastStepMs  = 0;  // reset so we can apply FIRST_STEP_DELAY_MS cleanly
    // Immediate first step if requested
    if (currentDir != STOP && FIRST_STEP_DELAY_MS == 0) {
      stepOnce(currentDir);
      lastStepMs = now;
    }
  }

  // --- While holding, auto-repeat ---
  if (currentDir != STOP) {
    unsigned long wait = (lastStepMs == 0)
                        ? FIRST_STEP_DELAY_MS   // first step after a delay (if not immediate)
                        : REPEAT_MS;            // subsequent steps
    if (now - (lastStepMs == 0 ? holdStartMs : lastStepMs) >= wait) {
      stepOnce(currentDir);
      lastStepMs = now;
    }
  }

  // non-blocking loop keeps the system responsive
}

void stepOnce(Dir d) {
  int before = angleDeg;
  angleDeg += (d == TO_180 ? +STEP_DEG : -STEP_DEG);
  if (angleDeg < 0)   angleDeg = 0;
  if (angleDeg > 180) angleDeg = 180;

  if (angleDeg != before) {
    servo.write(angleDeg);
    Serial.print("Angle: ");
    Serial.println(angleDeg);
  }
}>