Touchscreen only working when connected to laptop and not a 12V battery source

Hi, as I mentioned in the title I am trying to set up a simple little Arduino touch screen. I should also note that I am very new to Arduino and that I am currently using a 12V power source, a 4 relays shield and a slightly complicated board (I'll link them below). These devices are mainly because I want to expand on this project later on, but for now I am just trying to get my touchscreen to run a simple button program (I'll link this as well).
Currently my issue is that when I run the button program, whilst my board is connected to my laptop (via a USBC port) everything seems to be working just fine, but when I change the power source to the 12V, the screen will display but it won't register any touches.
I have also tried running a calibrate screen demo program (again I will link this), which does seem to work on both power sources, although I cannot figure out what the button program does differently.
Besides from that I've run a whole bunch of other small tests, and the only thing I've found so far that might be making a difference is that when my board is connected to the 12V power source, my board is getting about 5V. But when it's connected to my laptop it's getting about 3.3V, although the screen is supposed to be compatible with both.

Could someone please advise what I should do, or even just tell me whether this an electrical issue or a code issue? This is my first time using an Arduino touch screen so it's probably my code, but I tried my best to stay simple and similar to demo code that I found.
Also, (I don't know how important this is) but all of my equipment is pretty much new and I think my laptop has a 65W (20V and 3.25A) output.

Touchscreen: http://www.lcdwiki.com/2.8inch_Arduino_Display
4 Relays Shield: Arduino 4 Relays Shield — Arduino Official Store
Board (very similar to a mega): https://wiki.keyestudio.com/KS5014_Keyestudio_2560_WIFI_PLUS_Main_Board

Simple Button Code:

#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#include <TouchScreen.h>
#define MINPRESSURE 200
#define MAXPRESSURE 1000

// copy-paste results from the touchscreen calibration program
const int XP=8,XM=A2,YP=A3,YM=9; //240x320 ID=0x7575
const int TS_LEFT=933,TS_RT=101,TS_TOP=129,TS_BOT=913;

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

Adafruit_GFX_Button on_btn, off_btn;

int pixel_x, pixel_y;   
bool Touch_getXY(void)
{
    TSPoint p = ts.getPoint();
    pinMode(YP, OUTPUT);    
    pinMode(XM, OUTPUT);
    digitalWrite(YP, HIGH);  
    digitalWrite(XM, HIGH);
    bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
    if (pressed) {
        pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width());
        pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
    }
    return pressed;
}

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

void setup(void)
{
    Serial.begin(9600);
    uint16_t ID = tft.readID();
    Serial.print("TFT ID = 0x");
    Serial.println(ID, HEX);
    Serial.println("Calibrate for your Touch Panel");
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    tft.begin(ID);
    tft.setRotation(0);            //PORTRAIT
    tft.fillScreen(BLACK);
    on_btn.initButton(&tft,  60, 200, 100, 40, WHITE, CYAN, BLACK, "ON", 2);
    off_btn.initButton(&tft, 180, 200, 100, 40, WHITE, CYAN, BLACK, "OFF", 2);
    on_btn.drawButton(false);
    off_btn.drawButton(false);
    tft.fillRect(40, 80, 160, 80, RED);
}

void loop(void)
{
    bool down = Touch_getXY();

    Serial.print("Touch X: ");
    Serial.print(pixel_x);
    Serial.print(" Y: ");
    Serial.println(pixel_y);

    on_btn.press(down && on_btn.contains(pixel_x, pixel_y));
    off_btn.press(down && off_btn.contains(pixel_x, pixel_y));
    if (on_btn.justReleased())
        on_btn.drawButton();
    if (off_btn.justReleased())
        off_btn.drawButton();
    if (on_btn.justPressed()) {
        on_btn.drawButton(true);
        tft.fillRect(40, 80, 160, 80, GREEN);
    }
    if (off_btn.justPressed()) {
        off_btn.drawButton(true);
        tft.fillRect(40, 80, 160, 80, RED);
    }
}

Calibrate screen code (this is only a snippet):

#define PORTRAIT  0
#define LANDSCAPE 1
#define USE_XPT2046   0
#define USE_LOCAL_KBV 1

#define TOUCH_ORIENTATION  PORTRAIT

#if defined(USB_PID) && USB_PID == 0x804E // Arduino M0 Native
#define Serial SerialUSB
#endif

#define SWAP(x, y) { int t = x; x = y; y = t; }

#define TITLE "TouchScreen.h GFX Calibration"
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

// MCUFRIEND UNO shield shares pins with the TFT.
#if defined(ESP32)
int XP = 27, YP = 4, XM = 15, YM = 14;  //most common configuration
#else
//int XP = 6, YP = A1, XM = A2, YM = 7;  //most common configuration
int XP = 7, YP = A2, XM = A1, YM = 6;  //next common configuration
//int XP=PB7,XM=PA6,YP=PA7,YM=PB6; //BLUEPILL must have Analog for YP, XM
#endif
#if USE_LOCAL_KBV
#include "TouchScreen_kbv.h"         //my hacked version
#define TouchScreen TouchScreen_kbv
#define TSPoint     TSPoint_kbv
#else
#include <TouchScreen.h>         //Adafruit Library
#endif
TouchScreen ts(XP, YP, XM, YM, 300);   //re-initialised after diagnose
TSPoint tp;                            //global point

void readResistiveTouch(void)
{
    tp = ts.getPoint();
    pinMode(YP, OUTPUT);      //restore shared pins
    pinMode(XM, OUTPUT);
    //digitalWrite(YP, HIGH);  //because TFT control pins
    //digitalWrite(XM, HIGH);
    //    Serial.println("tp.x=" + String(tp.x) + ", tp.y=" + String(tp.y) + ", tp.z =" + String(tp.z));
}

uint16_t readID(void) {
    uint16_t ID = tft.readID();
    if (ID == 0xD3D3) ID = 0x9486;
    return ID;
}
#define TFT_BEGIN()  tft.begin(ID)

#define WHITE 0xFFFF
#define RED   0xF800
#define BLUE  0x001F
#define GREEN 0x07E0
#define BLACK 0x0000

//#define GRAY  0x2408        //un-highlighted cross-hair
#define GRAY      BLUE     //idle cross-hair colour
#define GRAY_DONE RED      //finished cross-hair

bool ISPRESSED(void)
{
    // .kbv this was too sensitive !!
    // now touch has to be stable for 50ms
    int count = 0;
    bool state, oldstate;
    while (count < 10) {
        readResistiveTouch();
        state = tp.z > 200;     //ADJUST THIS VALUE TO SUIT YOUR SCREEN e.g. 20 ... 250
        if (state == oldstate) count++;
        else count = 0;
        oldstate = state;
        delay(5);
    }
    return oldstate;
}
.
.
.
void startup()
{
    centertitle(TITLE);

    tft.println(F("#define NUMSAMPLES 3 in Library\n"));
    tft.println(F("Use a stylus or something"));
    tft.println(F("similar to touch as close"));
    tft.println(F("to the center of the WHITE"));
    tft.println(F("crosshair.  Keep holding"));
    tft.println(F("until crosshair turns RED."));
    tft.println(F("Repeat for all crosshairs.\n"));
    tft.println(F("Report can be pasted from Serial\n"));
    tft.println(F("Touch screen to continue"));

    while (ISPRESSED() == false) {}
    while (ISPRESSED() == true) {}
    //    waitForTouch();
}

I hope that's enough of the code to be useful. Thanks in advance :slight_smile:

It is not a matter of the code.

When you connect to a laptop you have a large area of metal to act as your reference ground. You loose that when you just have batteries.

The solution is to compensate for this by making a ground reference with respect to the batterer's ground.

You can do this by adding an area of ground by using self adhesive copper foil connected to your battery.

It is a bit trial and error as to how much foil you have to add.

Please show your schematic diagram. How your relay board is powered while you using 12v source?

Wait sorry, I don't really get what you mean,

, this is my 12V power supply. Where would I put the copper foil?

Ok, does this help at all?

It is not a schematic.

As far I understand, the 12v power cord is connected to DC in input of arduino board, and all other boards are powered from arduino?

In this case, all devices are powered through a linear voltage regulator on the Arduino board, which is not designed for such a load. Remember the important rule - the Arduino is not a power source.
You need an external power source for your relay modules. Or you can use a common 5V power source for all boards , in this case the regulator on the Arduino board will not be overloaded.

You put the foil around the touch connector, extending it out as a sort of surround to the display. Something like a bezel to the display.

Did you compare the TFT calibrate software's values between using 12V and the USB?

Your laptop is probably not supplying enough current

Ok, thanks I'll give that a go

Yeah, they're the same for all values.

So then should I try and adjust the 12V power source to lower its current?

Wait so I've tried removing the relay shield completely and the program still works with my laptop and not the 12V power source, is the touch screen itself also overloading the arduino? Or do I need to keep the relay shield and then also get a 5V power source for it? Also if the board is getting 5/3.3V doesn't that mean that it is regulating the power source correctly?
Sorry, I'm a little out of my depths here.

https://wiki.keyestudio.com/KS5014_Keyestudio_2560_WIFI_PLUS_Main_Board

Wait sorry, are you referring to the part in that table that says DC Power Interface DC6-9V? And if you are what does that mean? Am I overloading the touch screen?

Where are you measuring this voltage?

The digital pins right underneath the screen

Which digital pin would that be?

Run the diagnose_TFT_support.ino see if it finds any problems

I checked 10 to 1, and they were all pretty similar using the two different power sources

1 Like