#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Wire.h>
#include <Adafruit_FT6206.h>
#include <Servo.h>
#include <Encoder.h>
// Define connections for ILI9341 display
#define TFT_CS 10 // Chip Select pin
#define TFT_DC 9 // Data/Command pin
// Initialize display, touch controller, servo, and encoder
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
Adafruit_FT6206 ctp = Adafruit_FT6206();
Servo myServo;
Encoder myEncoder(2, 3); // Rotary encoder pins (adjust as needed)
int servoPin = 5; // Servo motor control pin
int servoAngle = 90; // Initial servo angle
int lastServoAngle = -1; // For angle change detection
long encoderPosition = 0; // Track rotary encoder position
enum Mode { TOUCH, MANUAL, SWING };
Mode currentMode = TOUCH;
unsigned long swingDelay = 15; // Delay for servo swing speed (controls speed in Swing mode)
int swingDirection = 1; // Swing forward initially
unsigned long lastSwingUpdate = 0;
int stepSize = 1; // Step size for servo in Manual mode (controls precision)
void setup() {
Serial.begin(115200);
tft.begin();
tft.fillScreen(ILI9341_BLACK);
// Initialize the touchscreen
if (!ctp.begin(10)) {
Serial.println("Couldn't start FT6206 touchscreen controller");
while (1);
}
Serial.println("Capacitive touchscreen started");
// Initialize servo and set it to initial position
myServo.attach(servoPin);
myServo.write(servoAngle);
drawUI(); // Draw UI elements on screen
updateDisplay(); // Show initial angle and mode
}
void loop() {
// Touchscreen-based mode selection
if (ctp.touched()) {
TS_Point p = ctp.getPoint();
p.x = map(p.x, 0, 240, 240, 0);
p.y = map(p.y, 0, 320, 320, 0);
// Detect mode change based on touch location
if (p.y >= 20 && p.y <= 60) {
if (p.x >= 20 && p.x < 80) {
currentMode = TOUCH;
} else if (p.x >= 90 && p.x < 150) {
currentMode = MANUAL;
encoderPosition = servoAngle; // Sync encoder position with servo angle
myEncoder.write(encoderPosition * 4); // Adjust for encoder steps
} else if (p.x >= 160 && p.x <= 220) {
currentMode = SWING;
}
updateDisplay();
}
// Touch mode: control servo angle with slider
if (currentMode == TOUCH && p.y >= 200 && p.y <= 250) {
servoAngle = map(p.x, 20, 220, 0, 180);
if (servoAngle != lastServoAngle) {
myServo.write(servoAngle);
lastServoAngle = servoAngle;
updateDisplay();
}
}
// Swing mode: control speed with the slider
if (currentMode == SWING && p.y >= 200 && p.y <= 250) {
swingDelay = map(p.x, 20, 220, 5, 100); // Adjust delay based on slider position
updateDisplay();
}
// Manual mode: control step size with the slider
if (currentMode == MANUAL && p.y >= 200 && p.y <= 250) {
stepSize = map(p.x, 20, 220, 1, 10); // Adjust step size based on slider position
updateDisplay();
}
}
// Manual mode: control servo angle with rotary encoder
if (currentMode == MANUAL) {
long newEncoderPosition = myEncoder.read() / 4;
if (newEncoderPosition != encoderPosition) {
encoderPosition = newEncoderPosition;
servoAngle = constrain(encoderPosition * stepSize, 0, 180); // Apply step size to the movement
myServo.write(servoAngle);
updateDisplay();
}
}
// Swing mode: servo sweeps back and forth from 0 to 180
if (currentMode == SWING) {
if (millis() - lastSwingUpdate > swingDelay) {
lastSwingUpdate = millis();
servoAngle += swingDirection;
if (servoAngle >= 180 || servoAngle <= 0) {
swingDirection = -swingDirection; // Reverse direction
}
myServo.write(servoAngle);
updateDisplay();
}
}
}
void drawUI() {
// Draw mode selection buttons
tft.fillRect(20, 20, 60, 40, ILI9341_BLUE);
tft.fillRect(90, 20, 60, 40, ILI9341_GREEN);
tft.fillRect(160, 20, 60, 40, ILI9341_RED);
tft.setCursor(30, 30);
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
tft.print("Touch");
tft.setCursor(100, 30);
tft.print("Manual");
tft.setCursor(170, 30);
tft.print("Swing");
// Draw slider bar for touch mode
tft.fillRect(20, 220, 200, 20, ILI9341_WHITE);
tft.drawRect(20, 220, 200, 20, ILI9341_BLACK);
}
void updateDisplay() {
// Clear previous text area
tft.fillRect(20, 100, 200, 40, ILI9341_BLACK);
// Display current mode
tft.setCursor(20, 100);
tft.setTextColor(ILI9341_YELLOW);
tft.setTextSize(2);
tft.print("Mode: ");
if (currentMode == TOUCH) tft.print("Touch");
else if (currentMode == MANUAL) tft.print("Manual");
else if (currentMode == SWING) tft.print("Swing");
// Display current servo angle
tft.fillRect(20, 150, 200, 40, ILI9341_BLACK);
tft.setCursor(20, 150);
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(2);
tft.print("Angle: ");
tft.print(servoAngle);
// Update slider indicator if in touch mode
if (currentMode == TOUCH) {
drawUI(); // Redraw slider area
int sliderPosX = map(servoAngle, 0, 180, 20, 220);
tft.fillRect(sliderPosX - 5, 220, 10, 20, ILI9341_RED);
}
// Display swing speed or step size depending on mode
if (currentMode == SWING) {
tft.setCursor(20, 200);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(1);
tft.print("Speed: ");
tft.print(100 - swingDelay); // Show speed as 100 - swingDelay
}
if (currentMode == MANUAL) {
tft.setCursor(20, 200);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(1);
tft.print("Steps: ");
tft.print(stepSize); // Display step size in Manual mode
}
}
Loading
ili9341-cap-touch
ili9341-cap-touch