Start a new topic

Digital and Analog Voltmeter with 32u4 on 2.4 inch Display

This is a repost from here

The attached files draw a voltmeter with an analog scale and a numeric display on a 2.4" Nextion module. The 32u4 (Arduino Leoardo, Pro Micro or similar) calculates two coordinates and a voltage value from an analog input signal and sends them to the Nextion display.



Since the "gauge" object can't have its center near the bottom of the screen, I used three lines to form the needle. A timer redraws the needle by overwriting its old position with a crop image (picq) every 50ms (only if the input value has changed), then sets the digits of the numerical display and paints the needle on top. There is barely any flickering noticeable, it runs very fast and smoothly.

I did not use any library for the communication between the 32u4 and the display because there are only three short and easy commands for each cycle. Instead you will find a little helper function for sending commands in the attached .ino that might also be useful for other projects since it uses a simple sprintf syntax to form commands.

On the Nextion display, the undocumented modulo operator "%" came in very handy to separate the digits. Just have a look. All the Nextion code is in the timer tm0, the comments in the .ino file explain what happens there.


3 people like this idea

very good, all my respect ... and it shows again, it can be done ... great work ...


1 person likes this
Here is a stand-alone version of the above meter application. It runs without an external MCU for demonstration purposes but the voltage value can of course be set via UART. I tried a somewhat awkward sine approximation for the arc calulations but it works fine.

With a little bit of math and the drawing functions there's not much you can not do with these displays imho.




Although there is little written on the modulo operator

  (some math understanding required before use)

  (not much written about + or += either)

The modulo operator was introduced in v0.33 of the Nextion Editor.

 "with your permission ..."

Of course, fine.

"(not much written about + or += either)"

I observed some interesting phenomenons here that might be worth to discuss. It is not clear to me how and if division and multiplication is carried out before addition and subtraction in longer statements since brackets are not part of the syntax. It seems that the calculation is done strictly from left to right but that is not true in all cases. I might show some examples in a new thread if it has not been a topic.

I see it has, somehow:

Indeed the user event code is interpretive, integer math and simplex

 - requires some old school thinking, or assembly language thought

left to right is indeed in the strict sense always left to right, always.


is equivalent to  (((va0.val+15)*16)+va1.val)




Full evaluation occurs on value after operator from left to right.

There is no order of operation (other than left to right)

simplex statements (as above n0.val=n0.val+15) supported

- longer with more than 1 operator is already complex

so by bending the rules (using complex), we can save a line or two

   but potentially exceed range and fail with only a partial.

but remember it is still simplex full evaluation on value after operator.

Now imagine a progress bar - left to right full eval on value after operator.

j0.val=16*16/16  ( = 16)

equivalent of

j0.val=16*16  j0 is now 256 and value is illegal, assignment doesn't occur

j0.val=j0.val/16  - will not occur, line was canceled with j0.val exceeded 100

final value of j0.val is what it was before the line of code.

 - But Nextion informed with Return Data 0x1C assignment failed

Consider again the same progress bar

j0.val=1*2*3*4*5/20   ( = 6)

equivalent to

j0.val=1*2  j0 is now 2

j0.val=j0.val*3  j0 is now 6

j0.val=j0.val*4  j0 is now 24

j0.val=j0.val*5  j0 is now 120, fails 101 and above, j0 is 24

j0.val=j0.val/25 is never executed, j0 is 24

 - But Nextion informed with Return Data 0x1C assignment failed


  sys0=1*2*3*4*5/20   ( = 6)


equivalent to

  sys0=1*2   sys0 is 2

  sys0=sys0*3   sys0 is 6

  sys0=sys0*4   sys0 is 24

  sys0=sys0*5   sys0 is 120

  sys0=sys0/20  sys0 is 6

  j0.val=sys0    j0 is 6

evaluations did not overflow and exceed limits.

such occurs on gauges as well when value exceeds 360

or waveforms when value exceeds 255

numbers are signed 32-bit, but order left to right can indeed overflow.

division is integer math, so value is truncated


va0.val=60000/20001*4/8*5  ( = 7.499625)

equivalent to

va0.val=60000/20001  va0 is 2

va0.val=va0.val*4  va0 is 8

va0.val=va0.val/8  va0 is 1

va0.val=va0.val*5  va0.val is 5

the same

va0.val=60000*4*5/8/20001 ( = 7.499625)

equivalent to

va0.val=60000*4   va0 is 240000

va0.val=va0.val*5  va0 is 1200000
va0.val=va0.val/8   va0 is 150000
va0.val=va0.val/20001 va0 is 7

so reduction is best where possible to avoid overflows

using tmp.val variable or sys0 etc can help.

2 people like this
Thank you for the detailed explanation. That should be part of the manual.


As a simplex integer based device, the behaviour is normal.



We are told it is simplex, and integer math no float support.

Yet it is we that still want to bend the rules

   to make complex multi-operator statements

We get away with some and nailed for others

   but it was we who wanted to bend the rules ... =)

Note there is no problem with assignments


    numA operator numB stored in leftside

The problem only arises when we add more than two

numbers and additional operators to the same line of code.

- this makes it complex, and we were told simplex.

most questions come out because of "not reading" already written ... I don't see the big improve in writing more when people neither read the existing nor even search for existing ... :-)

Login or Signup to post a comment