Start a new topic

Creating a Tilt Box within Nextion Logic

For January 2017's tutorial, this thread will show how to create a Tilt Box within Nextion Logic without the need for an external microprocessor.  As we go through the process of creating this addictive little game, I will deal with a few techniques that may be useful in your projects.  You will see how to create some visual effects via the Nextion's gui commands.


This project will use the Nextion 3.5" Enhanced NX4832K035_011 <Order Here>

and optionally the Expansion Board for the Enhanced Nextions <Order Here>


image


Our component list begins very modestly

  • 1 page with 2 variables
  • 4 pictures, 1 subset font
  • 1 page with 5 hotspots, 9 radio buttons, 10 variables and a timer.

So download the blank tilt_43.HMI, and the 5 resources, let's get started.

HMI
(925 Bytes)
drain.png
(3.43 KB)
cup.png
(384 Bytes)
felt.png
(76.2 KB)
wood.png
(173 KB)
zi
(4.29 KB)

First, let's add in our resources


 - In the Picture pane, add the four pictures in the following order

     - felt.png, wood.png, cup.png and drain.png.

  - In the Font pane, add the numbers.zi font.

Now let's build the table.

Start with our wood frame we set the page background to our wood picture
- change page0 .sta attribute to image
- set page0 .pic attribute to 1
Now let's drop the green in by adding a line in page0 Postinitialize Event
   pic 40,20,0
If we were to run this as is, there's something missing, some depth?

So let's create some depth around the green above our pic command
- in a darker colour, 2 pixels wide let's shade the top and left
  fill 38,18,401,2,14624
  fill 38,18,2,281,14624
- in a lighter colour, 1 pixels wide let's shade the bottom and right
  fill 40,300,401,1,47878
  fill 440,20,1,280,47878
Great.  Now a bit of depth and our green is recessed.

Adding in the remaining table page0 Components


Now it is time to add in our 9 radio Components on the right side
 - set all radio .w attributes to 13
 - set all radio .h attributes to 13
 - for now, set all radio .val attributes to 0
 - for now, set all radio .pco attributes to 0
 - set all radio .x attributes to 454

With r0 set .bco to 1024, and .y to 26

With r1 set .bco to 63488, .pco to 16384, and .y to 62

With r2 set .bco to 2016, .pco to 512.y to 84, and .val to 1

With r3 set .bco to 47104, and .y to 171

With r4 set .bco to 47104, and .y to 193

With r5 set .bco to 48608, and .y to 214

With r6 set .bco to 48608, and .y to 236

With r7 set .bco to 1024, and .y to 258

With r8 set .bco to 1024.y to 279, and .val to 1


Lets add our 5 hotspots

set m0 .w to 20, .h to 20, .x to 460 and .y to 0

set m1 .objname to bu, .w to 40, .h to 20, .x to 0 and .y to 260

set m2 .objname to bl, .w to 20, .h to 20, .x to 0 and .y to 280

set m3 .objname to br, .w to 20, .h to 20, .x to 20 and .y to 280

set m4 .objname to bd, .w to 40, .h to 20, .x to 0 and .y to 300


Now toss 10 Numeric Variable Components and set their .objname to

tmp, hor, ver, bx, by, hx, hy, diff, over, and bounce

Finally, add in our Timer Component tm0 and set .tim attribute to 50

So what's these components for?

- Top right hotspot - reset

- Bottom Left four hotspots - tilt controls

- Top first radio r0 - game is on indicator

- Radio r1 and r2 - Bounce control on/off indicators

- Radio r3 to r8 - difficulty level, r3 being the worst, and r8 easiest

- Timer keeps our ball in motion

- hor, ver will track our motion direction

- bx, by track the center of our ball

- hx, hy track the center of our hole

- diff is our difficulty level


So let's get coding.

Doing some of the easiest first


Table Reset


In the m0 hotspot Touch release event add

  page 0


Tilt Controls


The tilt range for ver and hor is -6 to +6.


In the bu hotspot Touch Press Event - tilt up

   if(ver.val>-6)

   {

      ver.val=ver.val-1

   }


In the bl hotspot Touch Press Event  - tilt left

   if(hor.val>-6)

   {

      hor.val=hor.val-1

   }


In the br hotspot Touch Press Event  - tilt right

   if(hor.val<6)

   {

      hor.val=hor.val+1

   }


In the bd hotspot Touch Press Event  - tilt down

   if(ver.val<6)

   {

      ver.val=ver.val+1

   }


Bounce Controls


Here we clear the radio group with the b[.id] array, then set.


In the r1 Radio Touch Press Event - rail bounce off

  for(sys1=0;sys1<=1;sys1++)

  {

    b[2+sys1].val=0

  }

  r1.val=1

  bounce.val=0


In the r2 Radio Touch Press Event - rail bounce on

  for(sys1=0;sys1<=1;sys1++)

  {

    b[2+sys1].val=0

  }

  r2.val=1

  bounce.val=1


Difficulty Settings


Again we clear the radio group with the b[.id] array, then set.


In the r3 Radio Touch Press Event - needed precision 0

  for(sys1=0;sys1<=5;sys1++)

  {

     b[4+sys1].val=0

  }

  r3.val=1

  diff.val=0


In the r4 Radio Touch Press Event - needed precision 1

  for(sys1=0;sys1<=5;sys1++)

  {

     b[4+sys1].val=0

  }

  r4.val=1

  diff.val=1


In the r5 Radio Touch Press Event - needed precision 2

  for(sys1=0;sys1<=5;sys1++)

  {

     b[4+sys1].val=0

  }

  r5.val=1

  diff.val=2


In the r6 Radio Touch Press Event - needed precision 3

  for(sys1=0;sys1<=5;sys1++)

  {

     b[4+sys1].val=0

  }

  r6.val=1

  diff.val=3


In the r7 Radio Touch Press Event - needed precision 4

  for(sys1=0;sys1<=5;sys1++)

  {

     b[4+sys1].val=0

  }

  r7.val=1

  diff.val=4


In the r8 Radio Touch Press Event - needed precision 5

  for(sys1=0;sys1<=5;sys1++)

  {

     b[4+sys1].val=0

  }

  r8.val=1

  diff.val=5

So let's deal with a couple in initializations.  In page0 Preinitialization add

  bounce.val=1

  over.val=0

This will default our choice for bounce on and our game is not over.


In our PostInitialization Event, we need to need to initialize our ball and cup.

So lets place our cup and add

   hx.val=rand%370+50

   hy.val=rand%250+30

   pic hx.val-11,hy.val-11,2

This will randomly place our cup somewhere on our table.


Now we place our ball, I have made it always starting 155,78

   bx.val=155

   by.val=78

   cirs bx.val,by.val,9,16

   cirs bx.val+3,by.val+2,2,11482

But the ball will need some speed/direction to start off rolling in

   tmp.val=rand%7

   hor.val=tmp.val

   tmp.val=rand%7

   ver.val=0-tmp.val

And now that it is placed and set to roll, let's ensure to activate our timer

   tm0.en=1

What's in the Timer Event


Here we will clear the ball (it will be redrawn again later), reset the cup, then do our calculations for the ball movement, ensuring if the ball is to bounce we alter the directions and check if the ball is within range to drop into the cup based on the difficulty.  So a big chunk of code ... here we go


  xpic bx.val-9,by.val-9,19,19,bx.val-49,by.val-29,0

  pic hx.val-11,hy.val-11,2

  if(hor.val>0)

  {

     if(bx.val<430)

     {

       bx.val=bx.val+hor.val

       if(bx.val>=430)

       {

         if(bounce.val==1)

         {

           hor.val=0-hor.val

         }

         bx.val=430

       }

     }

  }

  if(hor.val<0)

  {

    if(bx.val>49)

    {

      bx.val=bx.val+hor.val

      if(bx.val<=49)

      {

        if(bounce.val==1)

        {

          hor.val=0-hor.val

        }

        bx.val=49

       }

     }

   }

   if(ver.val<0)

   {

     if(by.val>29)

     {

       by.val=by.val+ver.val

       if(by.val<=29)

       {

         if(bounce.val==1)

         {

           ver.val=0-ver.val

         }

         by.val=29

       }

     }

   }

   if(ver.val>0)

   {

     if(by.val<289)

     {

       by.val=by.val+ver.val

       if(by.val>=289)

       {

         if(bounce.val==1)

         {

            ver.val=0-ver.val

         }

         by.val=289

       }

     }

   }

   sys0=hx.val-diff.val

   if(bx.val>=sys0)

   {

     sys0=hx.val+diff.val

     if(bx.val<=sys0)

     {

        sys0=hy.val-diff.val

        if(by.val>=sys0)

        {

           sys0=hy.val+diff.val

           if(by.val<=sys0)

           {

              hor.val=0

              ver.val=0

              bx.val=hx.val

              by.val=hy.val

              cirs hx.val-1,hy.val-1,7,16

              cirs hx.val+1,hy.val,1,8748

              over.val=1-over.val

              tm0.en=0

              r0.bco=1024

              page 1

            }

          }

       }

    }

   if(over.val==0)

   {

      cirs bx.val,by.val,9,16

      cirs bx.val+3,by.val+2,2,11482

    }

At this point you have a moving ball that can be manipulated by your four hotspots.

So what happens when you finally get the ball into the cup?

I have a drain that takes the ball from the cup and drops it onto another green.


Let's build the Drain.


Add a new page to the HMI page1

- set page1 .sta to solid color and .bco to 0

Add two Variable components va0 and va1
- set va0 .vscope to global
- set va1 .sta to String, .txt to <empty>, and .txt_maxl to 3

Now we add a bit of code to page1 PostInitialization Event

- this will draw our drain pipe and display the levels completed

  bringing it top to bottom blind fashion and removing it the same way.

- then return to page0 to start the next round.  So here's the code.

  va0.val=va0.val+1

  cov va0.val,va1.txt,3

  xstr 15,230,84,56,1,512,0,0,0,1,va1.txt

  for(sys0=0;sys0<=319;sys0++)

  {

     xpic 100,sys0,380,1,100,sys0,3

     delay=2

   }

   for(sys0=0;sys0<=319;sys0++)

   {

      fill 1,sys0,480,1,0

      delay=2

   }

   page 0


And there we go, we have our functioning Tilt Box.

All in Nextion Logic without the need for an external MCU.

Using the optional Expansion Board for Enhanced Nextions


So we have a couple lines of code to add in to set this for the Expansion Board


Where the Expansion board is left of the Nextion Display

In page0 Preinitialize Event insert into the beginning lines

   cfgpio 1,1,m0    // Bind Enter IO1 to Reset page0

   cfgpio 2,1,bl      // Bind Right IO2 to Move left

   cfgpio 3,1,bu     // Bind Down IO3 to Move up

   cfgpio 4,1,bd     // Bind Up IO4 to Move down

   cfgpio 5,1,br      // Bind Left IO5 to Move right

   pio6=0                // Set pio6 so LED starts as off

   cfgpio 6,2,0        // Config pio6 to LED


Where the Expansion board is right of the Nextion Display

In page0 Preinitialize Event insert into the beginning lines

   cfgpio 1,1,m0    // Bind Enter IO1 to Reset page0  

   cfgpio 2,1,br      // Bind Right IO2 to Move right

   cfgpio 3,1,bd     // Bind Down IO3 to Move down

   cfgpio 4,1,bu     // Bind Up IO4 to Move up

   cfgpio 5,1,bl      // Bind Left IO5 to Move left

   pio6=0                // Set pio6 so LED starts as off

   cfgpio 6,2,0        // Config pio6 to LED


In page1 Postinitialize Event insert as the first line for LED on during the drain run

   pio6=1

add as the second last line, just before page 0 for LED off

   pio6=0


So now you have Nextion Tilt Box set for your Expansion Board.

I hope you have found this tutorial both entertaining and educational


Enjoy

Patrick GE Martin


PS: This tutorial may be expanded on in the future.

Idea 1) Create a series of mazes to navigate in order to reach the cup

Idea 2) Using FFC and connector, build a coin sled or series of tilt sensors

I apologize for the video quality



mp4
HMI
(1.12 MB)
Login or Signup to post a comment