ITEAD Studio

How can we help you today?

Another look at Radio Buttons

i

indev2

started a topic
about 1 year ago

Hi,

First up, I'm not a programmer or computer expert, just a hobbyist with a project that involves a Nextion connected to an ESP8266.

On one of my Nextion pages I have a group of 10 selection buttons. For indication purposes, the selected choice should change color, much like a group of Radio buttons. I'm using ordinary buttons for this, as I don't need the sofistication of dual state or other refinements. All that is easy enough to do.

I'm posting this just in case others would like to use the idea, but also to ask which of the 2 methods (question for the MCU guru's) is the most efficient.

I actually have 3 methods, but one of them is a bit of code back on the ESP, similar to page 1 in the attached HMI. And that is the least efficient as we need to use the Serial lines.

So on page 0 we have the quick and dirty method, just a bunch of catch all writes.

Page 1 the refined method, but we have Variables, nested 'ifs', reads and writes.

Patrick Martin

Patrick Martin

In looking at the HMI and keeping in what you stated sending it over serial is least efficient

- efficiency has several meanings. You are hardly about to run out of resources in the K3.5".

So how do you want to measure the efficiency?

i

indev2

said
about 1 year ago

@Patrick

Indeed it was and thanks for that. But like others frustrated before the addition, I used a method that swapped out the colours back on the ESP.

This is my method, very simple

byte ter2 [3] = {0xff, 0xff, 0xff};//Terminating characters

void toggleButtonColor() {

NexSerial.print("b");

NexSerial.print(activeButton);
//Gives the button number

NexSerial.print(".bco=65248");

NexSerial.write(ter2, 3);

NexSerial.print("ref b");

NexSerial.print(activeButton);

NexSerial.write(ter2, 3);

NexSerial.print("b");

NexSerial.print(lastActiveButton);
Gives last button number

NexSerial.print(".bco=33800");

NexSerial.write(ter2, 3);

NexSerial.print("ref b");

NexSerial.print(lastActiveButton);

NexSerial.write(ter2, 3);

}

Later I was looking for the most efficient method on the Nextion with what we had at the time.

And BTW my app requires all off at default start.

The question was, which is most efficient

Page 0 or page 1 ?

i

indev2

said
about 1 year ago

Sorry Patrick crossed post,

Efficient processing, the best code for the job.

P

Patrick Martin

said
about 1 year ago

And I am interested to play here - so lets attempt a few things and see.

The most efficient is where neither the Nextion and the MCU are waiting on each other.

The serial is going to slow things down, but is the job for the MCU to flash options to the user as in the game Wack-A-Mole and the user plays to attempt to hit it while it is selected, or is the job to have the user select something and then inform the MCU for the MCU to respond.

Mostly you want to use the Nextion to pre-process what it can without the need of the MCU - then inform. You do not want to have to constantly poll, or be constantly receiving data so prints are used sparingly.

The difficulty in several buttons is as a radio button is having all the code in each button. When it comes time to update or find where an offending code is - there is a lot of "user code" to go through and find. If we can group this code in one spot - we save time when maintenance comes. (It also will consume less TFT file space as well).

The most efficient is to use the radio button and it indicates the user choice to the user

But for the sake of a button type example .. let me play. Now it does depend on what the button does (if it goes to another page - another approach is needed)

Patrick Martin

and have your MCU respond to the pin toggle cutting serial down even further.

Now Gerhard Kropf could probably come by and cut mine down even further.

i

indev2

said
about 1 year ago

Thank you so much Patrick,

As I'm only a coding student of 8 months standing (though somewhat older and longer of tooth ;) I'll need a little time to digest. What I wanted to learn was best coding practice, not just anything will do because we have acres of SRAM and faster cores these days.

So it's not a time critical application. I'm working on a 10 channel duplex wifi throttle and there are at least 5 mcu's in the loop if one includes the network router.

As you so rightly point out keeping the serial traffic to a minimum should be the goal.

I'll be back later

Thanks again,

Steve.

i

indev2

said
about 1 year ago

@Patrick,

Wow thank you Sir,

That's real neat, I had wondered if you could drop in a single routine like that.

In fact it would be very useful if it became an additional component to the Editor.

In much the same way as we have hidden Variables one could have methods that don't have to be part of the 'surface'. Then use something like a 'call' event rather than 'click'. We would then be moving toward a more traditional approach to programming. Guess someone like yourself has already requested.

All the same, that is a really cool workaround, thanks for enlightening me.

Kind Regards.

Steve.

P

Patrick Martin

said
about 1 year ago

Two points. It should matter not whether or not it is called "call" or "click", but rather that we note the behaviour is a simplistic user defined procedure. Second, with acres of SRAM and plenty of resources normally, there are limits in MCUs that are like no other. If the GD32 chip on the back of that Nextion has more than 96K of SRAM I would be surprised. So even though one could toss a 32GB microSD to expand their MCU, there are still limits that challenge - and that is where Good Practices comes in.

For fun I put together a 10 track slider expanding upon the last example.

In the theme of a ten track locomotive concept

Here each of the sliders have a value 0 to 100 and its Touch Release Event contains

sys2=10 // sys2=x where x is the component id

click m0,1

Beside each slider is a numeric value for the slider.

Each slider also shows which is the currently selected slider.

If there was to be ten locomotives in play at the same time, it may be tedious to adjust each locomotive jumping back and forth, so it is intuitive to add a +/- 5 value so that all increase or decrease at once. It would probably be prudent to have a kill switch.

The +5 contains a basic

click m1,0

The -5 contains a basic

click m1,1

For the kill switch we have a checkbox and a label, and to tap exactly on the checkbox - painful, so tapping the label also toggles the checkbox. It is here that it gets a bit more complex. If the kill switch is off - does the MCU need to be notified (probably not) - but if you are issuing the kill switch then the MCU certainly needs to know to kill the power to all the locomotives. Also, if the power is off, does it make sense to send the slider change? No. But it would be important to ensure the display represents this to the user by resetting the slider back to zero.

There are four procedures: hotspot m0 and m1 - Touch Pressed and Touch Release.

m0 touch -> adjust individual track

m0 release ->

m1 touch -> +5 for all

m1 release -> -5 for all

sys0 still allows for serial to be used or not - in this case hard to control locomotives if the speed isn't sent out of the nextion over serial, so sys0=1 is located in the page0 PostInitialize Event.

So what is Good Coding Practices?

It occurs when you have coded for and against all contingincies that could occur. Keeping the code simple to follow, clear to the user, clear for the machine (especially when maintenance time arrives) and code should be documented - and note that mine is not. (Not a good practice).

You might notice that rather than creating a new variable, sometimes I used one of the existing sysX variables as my temp and then reset it after borrowing it ... this again is probably NOT good practice.

However, the interface has a simple 4 byte communication system 0x42 0xAA 0xBB 0x00

The first byte is always 0x42 ... letting you know this is track controls coming in

The second byte 0xAA is for either track or system

When it is a track - the track number 1 (top) to 10 (bottom) is the second number

-- and the third byte 0xBB will be the speed from 0 to 100

When it is system - the byte is 0x00

-- If the third byte is 0x00 - the kill switch was pressed (MCU should turn each locomotive off)

-- If the third byte is 0x01 - the -5 was issued (MCU should decrease each locomotive by 5)

-- If the third byte is 0x02 - the +5 was issued (MCU should increase each locomotive by 5)

The fourth byte is always 0x00 zero.

Now as the user plays with the interface and is seeking a particular value, each release is sending the track command over the serial - so it could be improved by decreasing the serial traffic and allow the user to see the slider value without them having to release and try again - sending more data over serial before they are satisfied. So by adding another hotspot m2 and adding

sys2=2

click m2,1

into the Touch Move event for each slider, we can then have m2's hotspot code update a corresponding numeric component before the user lets go of the slider -- which triggers the serial. But only IF the kill switch is off. So now there are five user procedures.

Hope you find this example interesting and helpful.

BTW: Where did you find the reference to being able to call the components via the b[x] array?

"BTW: Where did you find the reference to being able to call the components via the b[x] array?"

Well as you've already found out and put to very good use, I was scratching my head thinking surely the syntax is a little more evolved than the very basic stuff that is documented.

And looking for a better way to code the method for the original topic of this thread, I just started playing around until something compiled. This was only yesterday I might add. So you could say I just dropped on it by being persistent.

Who knows what else is lurking under the hood ?

My suck it see approach comes from trying to learn Html/javscript and C/C++ all at the same time. Prior to February this year, I knew nothing other than memories of a few lines of Basic going back to my 1970's days at high school.

An Arduino running the blink sketch is a very recent development for me :)

On the off chance you're even remotely interested in what I'm up to, the whole project is pretty much open source, save for my current stuff that I'm working on right now.

This link goes to a shot of my first attempt at getting something to work with my brand new shiny Nextion back in July.

indev2

said
about 1 year ago

Hi Patrick,

Oh no, like me will you ever be able to put it down ?

What started as new hobby for me looking into the digital electronics of model railways (with a view to building something later - I don't own a layout either !) has become quite a time consuming passion this last eight months.

Call it the engineer in me - the logic is quite intriguing.

OK, you're on the right track (pun intended) but not the right project.

Another member, Mr. Dave Bodnar (trainelectronics.com), upon seeing the potential of the Nextion, shortly after I made the announcement that the above link relates, went off to write something is his own style. Let's call it something of a valid, but lesser device than mine. Still with me ?

Now let's not get tied up trying to reinvent the wheel.

Prior to Nextion displays, I'd already been down the WebApp route. I wrote a rather nice page that you can run on modern mobile devices, in an ordinary browser.

I never got to finalising the javascript, but to me anyway, it represents a valid solution and in the main it works quite well.

But, here's the caveat (and I can appreciate folks comments on this), an all touchscreen solution does't have that ergonomic twiddly control factor. So enter the Rotary Encoder.

Patrick Martin

said
about 1 year ago

Let's see. It was shortly after I built a model railway station as a child and my brother had us play "Wild-Wild-West" with his pellet gun - well let's say Dad never let us touch his train set. So I would need to just get a few confirmations

So let me see if I have some of this correct.

Connection goes to connect to the BASE Station (more than one?)

Up to ten trains on the tracks controlled via the BASE

The power switch there is your kill switch

<s> ?? not sure

Forward/Reverse and All Stop

If active then <T5 76 1> status line?

The 29 Functions are user add ins (a bell, light, switch, sensor) that can vary for every user?

The layout above

concept of every function quickly tapped - is very handy - so perhaps how to squeeze everything above into a Nexion most efficiently?

I would think that it would be cool if the F25 showed an icon for what it was for - and since you found the b component array and I found the indexed font structure, the two could merge to have a set of icons that changes color when on/off for each function slot (if my understanding of the 29 functions is correct)

i

indev2

said
about 1 year ago

Patrick,

"Connection goes to connect to the BASE Station (more than one?)"

Connect does set up a connection to Base Station. In this case it's a WebSocket connection, a fast duplex, always on used by Webpages mainly..

.

"Up to ten trains on the tracks controlled via the BASE"

Yes,the Base does the command interpretation of the throttles output strings.

.

"The power switch there is your kill switch"

That switch kills the whole layout

.

"<s> ?? not sure"

A request to send current running loco status and other stuff.

Great for testing the connection and synchronising the throttle, there can be more that one throttle instance at the same time.

.

"Forward/Reverse and All Stop"

Just applies to the currently selected loco.

.

"If active then <T5 76 1> status line?"

Return data from Base Station, either from this or other throttles. All must be stored and acted upon.

And constantly updated.

.

"The 29 Functions are user add ins (a bell, light, switch, sensor) that can vary for every user?"

Broadly speaking yes.

Functions are a rather secondary consideration, save for folks who have complex sound and other little niceties on their trains. The first group F0 - F4 is used quite often.

I have a current solution for function keys, did you catch the short video ?