How to implement swipe up-down using sendxy?

There seems to be a bug in the way sendxy works.
After sendxy command is sent, the LCD will send Down an Lift events with X,Y locations.
The problem is the Lift event sends the same X,Y location as the Down event.
The Lift event should send the X,Y location where the touch is lifted. It does not!
Without the proper Lift location, i cannot implement on screen swipes.
Please help, anybody…

I can not understand why you would use sendxy, which always transmits the last touch (not release!) coordinates to implement swiping gesture control.

I could make work this using the following tutorial:

Quick question - are you trying to handle all swipe detection on the Nextion itself or do you intend to use an attached microcontroller?

In my application I handle all swipe interactions purely on the Nextion. Swipes are usually used as a way to transition between pages or elements so the Nextion handles the swipes and simply returns the requested navigation to the MCU (previous, next, drop down, close, change page, etc). For most of the other touch interactions I utilize the MCU with tch0-tch3 queries.

You basically have four different touch detection methods on the Nextion, some with overlapping use cases.
Ranked in terms of touch detection speed from fastest to slowest you have:

  • continuous polling of tch0-tch3 values in while/for loop
  • sendxy=1 (0x67 return data - X,Y, touch, release)
  • send component ID (0x65 return data)
  • press events (individual components)

I really prefer using the tch0-tch1 variables for touch detection but you could also combine it with sendxy if you’re application depends on the Nextion signalling the MCU of a touch event (rather than polling for touch on the MCU or handling everything on the Nextion).

For example,
declare some variables
start_x=0
start_y=0
end_x=0
end_y=0
current_x=0
current_y=0
touch_time=0
then send the following command to the Nextion to begin touch nofications - “sendxy=1”

Once the Nextion detects a touch event and returns sendxy 0x67 return data, first confirm that the return data indicates a PRESS event (not RELEASE) then store the returned x and y touch values into start_x and start_y and run something like the following:

touch_time=millis() // time of initial touch press detection
while(Serial.available()==0&&millis()<touch_time+500)
// wait for 0x67 return data indicating touch release
{
send “get tch0”, save returned value to current_x
send “get tch1”, save returned value to current_y
if(current_x==0) { goto PROCESS_TOUCH ​} //release
if(abs(start_x-current_x)>100) { return; } // NOT a vertical swipe
end_x=current_x
end_y=current_y
​}
​ return // no touch release detected after 500ms
PROCESS_TOUCH:;
if(abs(start_y-end_y)<150) { return; }
// swipe length less than 150, ignore
if(start_y>end_y) { **SWIPE UP DETECTED ** }
else { **SWIPE DOWN DETECTED ** }

Sorry for the confusing pseudo code

You could also implement something similar on the Nextion with a timer polling tch0, tch1

Hope this helps

Here is a collection of routines I use to simplify touch processing on the MCU. Thought they might be useful to you.

void GetTouch() {
//places current X,Y touch positions into touch_x and touch_y global variables
// int touch_x; // contains current X coord of touch position AFTER RUNNING GetTouch();
// int touch_y; // contains current Y coord of touch position AFTER RUNNING GetTouch();
//no touch = 0
touch_x = getVal(“tch0”);
touch_y = getVal(“tch1”);
}

byte TouchState() { // return 0 or 1 for current touch state
while(1) {
GetTouch();
if(touch_x>0&&touch_y>0) { return 1; }
if(touch_x==0&&touch_y==0) { return 0; }
}
}

void WaitForTouchRelease() { while(TouchState()!=0) {} }

byte WaitForTouch() { return WaitForTouch(0); }

byte WaitForTouch(int max_wait_ms) {
// return 0 for no touch, 1 for touch
// max_wait_ms = max time to wait for touch before returning (ms) - set to 0 to wait indefinitely
byte result=0;
elapsedMillis ms;
Touch(0); //disable page touch events
WaitForTouchRelease();
while(TouchState()==0) {
if(max_wait_ms>0&&ms>max_wait_ms) { goto WFT_done; }
}
result=1;
WFT_done:;
tft.clear();
Touch(1);
return result;
}

void WaitForTap() {
WaitForTouchRelease();
WaitForTouch();
WaitForTouchRelease();
}

void WaitForHold() {
WaitForTouchRelease();
WaitForTouch();
while(abs(getVal(“tch0”)-getVal(“tch2”))>2) { }
while(abs(getVal(“tch1”)-getVal(“tch3”))>2) { }
}

void Touch(byte on_off) {
// enables or disables all touch events on the CURRENT page (changing pages re-enables all touch events)
// - USAGE: Touch(0) = DISABLE Touch(1) = ENABLE
// sendxy() and WaitForTouch() still function even with touch turned off
tft.print(“tsw 255,”);
tft.print(on_off);
TFT_Comm_End();
}

void TFT_Comm_End() { tft.print(“\xFF\xFF\xFF”); }

void DrawBoxExample() {
// simple example showing how to use touch and drag to create a filled box/square on the Nextion over serial
// just touch anywhere on the screen and drag then release
long start_x, start_y, last_x, last_y;
WaitForHold();
GetTouch();
start_x=touch_x;
start_y=touch_y;
DrawBoxLoopPre:;
last_x=touch_x;
last_y=touch_y;
DrawBoxLoop:;
GetTouch();
if(touch_x==0||touch_y==0) { return; }
if(abs(last_x-touch_x)+abs(last_y-touch_y)<4) { goto DrawBoxLoop; }
tft.print(“fill “);
tft.print(min(start_x,touch_x));
tft.print(”,”);
tft.print(min(start_y,touch_y));
tft.print(“,”);
tft.print(abs(start_x-touch_x));
tft.print(“,”);
tft.print(abs(start_y-touch_y));
tft.print(“,0”);
TFT_Comm_End();
goto DrawBoxLoopPre;
}

@ratnin quick note: you can use a pair of ` characters to format text as code. If the code is multiline, use three of those to start and end the code block.

def this():
    return "is an example."

Alternatively, if you prefer BBcode style, use [code] [/code].

Kind regards,
May

Hi All,

Thanks for your kind replies. I am using the Basic 3.5" Nextion display.
I am using an external micro-controller to try detect the swipes.
I need to detect the swipes using external micro-controller for finer control.
As mentioned, the sendxy never gives the LIft location, the Lift event still gives the Down location.
I tried reading the system variables tch0, tch1, tch2, tch3 but they all contain the Down locations, not the Lift locations.
Do I need to upgrade to Enhanced or Intelligent series to get the Lift X, Y ?

Use “sendxy=1” to alert micro of a new touch press.
Send “sendxy=0” to prevent Nextion from alerting micro on touch release.
Begin a loop on micro that continuously retrieves tch0 and tch1 values to monitor changing touch position as user swipes across screen.
Continue saving the returned X,Y values from tch0, tch1 until they return a value of 0 which indicates touch released.
Now compare the start position of the initial touch press event that was returned in the “sendxy” data to the last non-zero X,Y touch position read from tch0,tch1 during the polling loop above. These are the start and end touch coordinates on your swipe. If the change in X position is small while the change in Y is large, you have detected a swipe up or down even. Compare the start and end Y positions to then determine if the swipe direction was up or down.

Maybe I can try to simply this for you. What components exist on the page requiring swipe up/down detection?

ratnin, You are a genius ! Never in my mind would i have guessed that we need to stop sendxy before we can get the correct tch0, tch1 values.
This knowledge you have is very deep.
Are you one of the developers of the Nextion firmware?

Happy to help out. Not affiliated with Nextion in any way but my company uses the 3.2" Enhanced screen in an updated model of one of our existing products which previous featured a simple 2x16 character display. I needed to make it fully backward compatible with our existing microcontroller design to allow for upgrading of older models. I spent a decent amount of development time ensuring the Nextion integrated seamlessly with the core microcontroller - sharing the workload and resources between the two systems and allowing them both to take turns “running the show” at different points instead of a traditional master/slave arrangement. I also had to lay out a common protocol between the two systems so they could operate as a single controller while still allowing me to make changes to them individually in the future. For example, if I add some new feature to the microcontroller firmware and it requires some sort of interface menu or on-screen component arrangement that isn’t in the existing LCD firmware then the details of this new page are included in the microcontroller firmware update which creates the missing LCD interface dynamically “on-the-fly” without having to also reprogram the Nextion to add the new asset. The LCD isn’t easily accessible for updates so I avoid this until it becomes absolutely necessary. At that point any missing assets are also added to the LCD and get removed from the microcontroller firmware.

No that everyone has become so used to Androids and iPhones the expectations for a device touchscreen device have risen. I think things like swipe navigation, smooth operation and responsiveness are now simply “must haves” and although the Nextion isn’t perfect you can typical work out some way to implement almost anything you’re looking for.

1 Like