Hi all, I am currently building a scale with two stepper motors. Right now I am only trying to get the display and touch controls working, but I am struggling a lot today. I have a CNC shield on a Arduino Mega and I use the ELEGOO 2.8" Touch Screen but using ribbon cables. That's because I cannot attach two Shields on one Arduino.
The following code is working and the display shows some buttons and text. However, the touch input does not work yet. That's what I ask for your help with. I managed to find the right library and pinout, otherwise the displays would not be working. I asked ChatGPT a bunch for advise, but it is pretty useless with this. It keeps telling me to connect physical touch pins, but they don´t exist on my TFT. This Adafruit article gives some insights on those pins, but I don't get it. Touchscreen Paint Example | 2.8" TFT Touch Shield | Adafruit Learning System
Anyway the touchscreen worked, but only when it was connected as a shield. Not with ribbon cables. Any ideas what I am doing wrong?
#include <Adafruit_GFX.h>
#include <Adafruit_TFTLCD.h>
#include <TouchScreen.h>
#include <AccelStepper.h>
#include <HX711.h>
// Color definitions
#define BLACK 0x0000
#define WHITE 0xFFFF
#define RED 0xF800
#define GREEN 0x07E0
#define BLUE 0x001F
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
// ===================== Pin Mapping =====================
#define LCD_CS A8 // Chip Select
#define LCD_CD A9 // Command/Data
#define LCD_WR A10 // Write
#define LCD_RD A11 // Read
#define LCD_RESET A12 // Reset
// Data D0–D7 -> Mega pins 22..29
// Touchscreen (4-wire resistive) breakout wiring (paint example)
#define YP A2 // must be analog pin
#define XM A3 // must be analog pin
#define YM 9 // can be digital pin
#define XP 8 // can be digital pin
#define TS_MINX 120
#define TS_MAXX 900
#define TS_MINY 70
#define TS_MAXY 920
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
// Instantiate TFT TouchScreen(XP, YP, XM, YM, 300);
// Instantiate TFT
typedef uint16_t color_t;
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
// Steppers
#define stepPinX 2
#define dirPinX 5
#define EndstopX 9
AccelStepper stepperX(AccelStepper::DRIVER, stepPinX, dirPinX);
#define stepPinY 3
#define dirPinY 4
#define EndstopY 11
AccelStepper stepperY(AccelStepper::DRIVER, stepPinY, dirPinY);
// HX711 scale
#define DOUT 32
#define CLK 33
HX711 scale;
#define RelayPin 12
// UI state
String inputText = "";
int Wunschanzahl = 0;
float WunschgewichtTotal = 0;
float GewichtEineSchraube = 0;
bool runPressed = false;
bool stopPressed = false;
bool WeighingComplete = false;
// Generic button drawer
void drawButton(int x, int y, int w, int h, const char\* label, color_t bg, color_t fg) {
tft.fillRect(x, y, w, h, bg);
tft.drawRect(x, y, w, h, fg);
tft.setTextSize(2);
int16_t textW = 6 \* strlen(label) \* 2; // char width 6px \* size
int16_t textH = 8 \* 2; // char height 8px \* size
int16_t tx = x + (w - textW) / 2;
int16_t ty = y + (h - textH) / 2;
tft.setCursor(tx, ty);
tft.setTextColor(fg);
tft.print(label);
}
// Draw keypad & controls with adjusted sizes
void drawKeypad() {
tft.fillScreen(BLACK);
// Numeric keys: narrower
const int numW = 40, numH = 40, numSX = 45, numSY = 45;
static const char\* keys\[4\]\[3\] = {{"1","2","3"},{"4","5","6"},{"7","8","9"},{"Del","0","OK"}};
for(int r=0; r<4; r++) {
for(int c=0; c<3; c++) {
int x = c \* numSX;
int y = r \* numSY;
drawButton(x, y, numW, numH, keys\[r\]\[c\], BLACK, WHITE);
}
}
// Control keys: wider (moved left)
const int ctrlW = 70, ctrlH = 40;
const int ctrlX = 150; // moved left from 180
drawButton(ctrlX, 0, ctrlW, ctrlH, "Enter", BLACK, WHITE);
drawButton(ctrlX, 50, ctrlW, ctrlH, "Run", GREEN, BLACK);
drawButton(ctrlX, 100, ctrlW, ctrlH, "Stop", RED, BLACK);
drawButton(ctrlX, 150, ctrlW, ctrlH, "TARE", CYAN, BLACK);
}
// Update numeric displays
void updateDisplays() {
tft.fillRect(0, 200, 320, 60, BLACK);
tft.setTextSize(2);
tft.setCursor(0, 200);
tft.setTextColor(GREEN);
tft.print("Wunschzahl: "); tft.print(Wunschanzahl);
tft.setCursor(0, 220);
tft.setTextColor(CYAN);
tft.print("Eingabe: "); tft.print(inputText);
tft.setCursor(0, 240);
tft.setTextColor(YELLOW);
tft.print("g/Stk: "); tft.print(GewichtEineSchraube, 2);
}
// Live weight feedback
void updateWeightDisplay(float w) {
tft.fillRect(0, 280, 320, 20, BLACK);
tft.setTextSize(2);
tft.setCursor(0, 280);
float delta = abs(WunschgewichtTotal - w);
float tol = WunschgewichtTotal \* 0.01;
color_t col = (delta <= tol) ? GREEN : ((delta <= GewichtEineSchraube\*3) ? YELLOW : RED);
tft.setTextColor(col);
tft.print("Gewicht: "); tft.print(w, 2);
}
// Homing routines
void HomingX() {
stepperX.setMaxSpeed(500);
stepperX.setSpeed(-500);
while(digitalRead(EndstopX)==HIGH) stepperX.runSpeed();
stepperX.stop(); delay(200);
stepperX.setCurrentPosition(0);
}
void HomingY() {
stepperY.setMaxSpeed(500);
stepperY.setSpeed(-500);
while(digitalRead(EndstopY)==HIGH) stepperY.runSpeed();
stepperY.stop(); delay(200);
stepperY.setCurrentPosition(0);
}
// Button press handler
void handleKey(const char\* label) {
if(!strcmp(label,"Del") && inputText.length()) inputText.remove(inputText.length()-1);
else if(!strcmp(label,"OK")) { Wunschanzahl=inputText.toInt(); inputText=""; }
else if(!strcmp(label,"Enter")) { scale.tare(); delay(500); WunschgewichtTotal=scale.get_units(20); GewichtEineSchraube=WunschgewichtTotal/Wunschanzahl; }
else if(!strcmp(label,"TARE")) scale.tare();
else if(!strcmp(label,"Run")) { runPressed=true; stopPressed=false; }
else if(!strcmp(label,"Stop")) { stopPressed=true; runPressed=false; }
else inputText+=label;
updateDisplays();
}
// Run sequence
void checkRunSequence() {
if(runPressed && !WeighingComplete) {
HomingX();
while(!WeighingComplete && !stopPressed) {
stepperX.setMaxSpeed(2000);
stepperX.move(10000); while(stepperX.distanceToGo()) stepperX.run(); delay(300);
stepperX.move(-10000); while(stepperX.distanceToGo()) stepperX.run(); delay(1000);
float cw=scale.get_units(20); updateWeightDisplay(cw);
float rem=WunschgewichtTotal-cw;
if(rem<=GewichtEineSchraube\*3) {
stepperX.move(8000); while(stepperX.distanceToGo()) stepperX.run();
for(int i=0;i<4;i++){ stepperX.move(500); while(stepperX.distanceToGo()) stepperX.run(); delay(400); }
}
if(abs(cw-WunschgewichtTotal)<WunschgewichtTotal\*0.01) { WeighingComplete=true; HomingY(); }
}
runPressed=false;
}
}
void setup() {
Serial.begin(9600);
pinMode(RelayPin,OUTPUT);
pinMode(EndstopX,INPUT_PULLUP);
pinMode(EndstopY,INPUT_PULLUP);
stepperX.setAcceleration(9000); stepperX.setMaxSpeed(4500);
stepperY.setAcceleration(1000); stepperY.setMaxSpeed(3500);
tft.reset(); uint16_t id=tft.readID(); tft.begin(id); tft.setRotation(0);
drawKeypad(); updateDisplays();
scale.begin(DOUT,CLK); scale.set_scale(); scale.tare();
}
void loop() {
TSPoint p=ts.getPoint(); pinMode(XP,OUTPUT); pinMode(YP,OUTPUT);
if(p.z>MINPRESSURE&&p.z<MAXPRESSURE) {
int x=map(p.x,TS_MINX,TS_MAXX,0,tft.width());
int y=map(p.y,TS_MINY,TS_MAXY,0,tft.height());
static const char\* keys\[4\]\[3\]={{"1","2","3"},{"4","5","6"},{"7","8","9"},{"Del","0","OK"}};
for(int r=0;r<4;r++) for(int c=0;c<3;c++){
int bx=c\*45,by=r\*45;
if(x>bx&&x<bx+40&&y>by&&y<by+40){ handleKey(keys\[r\]\[c\]); delay(300); }
}
if(x>150 && x<150+70){
if(y<40) handleKey("Enter");
else if(y<90) handleKey("Run");
else if(y<140) handleKey("Stop");
else if(y<190) handleKey("TARE");
delay(300);
}
}
float lw=scale.get_units(10); updateWeightDisplay(lw); checkRunSequence(); delay(200);
}