Unofficial Nextion/TJC User Forum

How to get ascii from char?

It’s ugly, but this code searches for a letter in a string and returns the next letter in a round-robbin fashion:

for(sys0=0;sys0<26;sys0++)
{
// get one letter and put it in va0.txt
substr "abcdefghijklmnopqrstuvwxyza",va0.txt,sys0,1
// check if t0.txt matches the letter
if(t0.txt==va0.txt)
{
// advance to the next letter
sys0++
// put the next letter in t1.txt
substr "abcdefghijklmnopqrstuvwxyz",t1.txt,sys0,1
}
}

sys0 contains the position number within the string. You can expand on this as needed.

3 Likes

Thank you. I meant to avoid cycles to reduce time.

Yes, i know, unfortunately

Thank you very much fvanroie,

Same question is there a way to get the ascii value of a text character

Ok I have worked it out save text character to eeprom read back location to number variable

… comes at the expense of 1 write cycle and those are finite (AFAIK around 100000 for Nextion).

Kind regards,
Max

1 Like

I have a page that loads ascii 32 to 126 characters into eeprom then it will search eeprom to find the character entered and give you its ascii value.
So why do this , well I have written the code that will do xmodem crc and nextion has no command to find ascii value of character.

So how to share this?

2 Likes

The Nextion editor allows exporting single pages from a project…

That is not a problem its only one page but where to upload it ?

Thanks for that info. We are using am OMRON programmable relay and a Nex screen as the HMI for a small project.
Communications to and from the OMRON is a combination of ascii bytes , Packet Format is
STX Ascii Readable block ETX BCC
BCC is Xor of Ascii Readable block ETX
Struggled to work out how to do this until I read your post.
Many Thanks

paulvk,

I would really like to get a copy of your page that searches eprom to give me the ascii value of a character. If you don’t mind, my em a il is kci at va x x ine d com

Thanks,
Dale

I have changed the code it no longer needs eeprom it uses a variable , the eeprom is limited because every value uses 4 bytes but in a text variable they only use one byte per character.
Here you can see the code indeed the whole project you can look at in the editor with many picture files as well it does animation , parsing with reparse mode , ascii value look up , simple maths , sliders for animation , xmodem CRC generation and more.
https://forums.aeva.asn.au/viewtopic.php?f=64&t=6788

Here in the Bascom forum
https://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=14531&start=45

With this I did away with a microcontroller between my solar inverters and the nextion now the nextion is a remote control and display for the inverters.
If you have more questions please ask here or in the AEVA forum.

t0.txt=”A” // set t0.txt variable to char
sya1=0 // ASCII value will be returned in sya1 (undocumented global)
wepo sya1,0 //zero out EEPROM bytes 0-3
wepo t1.txt,0 // write char to EEPROM address 0 (bytes 1-3 remain 0)
repo sya1,0 // copy EEPROM bytes 0-3 to sya1 (bytes 1-3 are still 0)
// sya1=returned ASCII value

@ratnin (and other readers) I wouldn‘t recommend this approach at all:

Max - That’s ridiculous.
Nextion uses a 24C08 to provide the 1024 bytes of EEPROM on the Enhanced series. That chip is rated at 1 MILLION write cycles and 100 YEARS of data retention. It also offers byte level read/writes instead of requiring entire pages or blocks to be erased during a write operation. This limits any wear to only the specific byte(s) being written.

You need to also consider the failure mode of cumulative wear from repetitive erase/write cycles at the byte level. That 1 million writes/100 year retention rating means that even after a MILLION erase/write cycles the EEPROM still offers 100 years of data retention. The result of excessive write cycles is shortened data retention. Most of the EEPROM stress/endurance tests you find online show no indication of failure even after repetitive erase/write cycles that are often 5-10X in excess of the rated write endurance. This is only because these test typically commit the new value to EEPROM, wait 4-5ms for the erase/write operation to complete then immediately read the value stored in that address and compare it to the written value as verification of a successful read/write operation. In reality this method of stress testing is a poor indicator of EEPROM wear because it doesn’t consider the more common failure modes where the stored data can no longer be reliably retrieved a few months or even a couple days later. A saw one particular EEPROM endurance test where the chip continued to return the correct bytes after several write/read cycles then after a delay was inserted between the write and read operations corrupted data began to show up when reading the EEPROM address just a few seconds after the write operation.

For the purposes of ASCII to CHAR conversion, these types of data retention failures are not likely to be any issue because the read operation takes place immediately after erase/write process is completed. The data just needs to be viable for a few milliseconds.

This process only requires 4 bytes of EEPROM but you could easily set aside a larger block of memory and implement some simple wear leveling with error correction. For example, set aside 40 bytes of EEPROM address space (eg. 100 to 139). On the initial setup, zero out this range (eg. sys0=0 ; wepo sys0,100 ; wepo sys0,104 ; wepo sys0,108 … wepo sys0,136 :wink: This is one erase write cycle for each of the reserved byte positions. Setup two global text variable with max_l of 1 (eg. char.txt and check.txt). To get an ASCII value, store the char to char.txt (eg. char.txt=“A”) then do a simple FOR loop to read the values in the 100-139 reserved address space into check.txt (FOR-sys0++ ; repo check.txt,sys0; ) and compare char.txt to check.txt in each byte position to see if the character was previous written to EEPROM. If a match is found then simply read the read the address position into a system variable, take modulus 256 to get the LSB and that’s your ASCII to CHAR conversion result (no EEPROM write cycle even required). If the scan doesn’t turn up a matching character already in EEPROM then go to the first address location with a byte value of 0 and write the character value to that position (ei. wepo char.txt,112) then read it out into a system variable and take mod 256 to get the corresponding ASCII value (repo sys0,112 ; sys0%=256 // sys0 now holds returned ASCII value). The EEPROM write operation appends a null /00 character on to text strings. If max_lengt of char.txt is set to 1 then any conversion will write two byte positions. The 0x00 byte value used to terminate the text EEPROM write then serves as a pointer to the EEPROM address for the next character conversion. With 40 bytes of address space reserved for ASCII conversion you have simple wear leveling for 40X the write cycle endurance. The vast majority of common readable ASCII characters have values between 32 and 127 and after adding in the common control characters (CR/LF,etc) you’re left with a set of only around 100 characters that would likely need to be converted. Since the last 40 character conversions will already exist in the EEPROM that cuts the number of conversions that will require an actual erase/write cycle nearly in half. That’s tens of millions of character conversions you could safely perform without any serious wear concerns and absolutely zero impact on the 96% of EEPROM memory locations outside of the 40 byte block set aside for ASCII conversion.

Using the on-chip EEPROM for this ASCII workaround is completely safe and it offers a simple way to implement a useful feature that is lacking from the factory.

10k, 100k or 1M writes?

24C08 is not 24C08

Stuff is a little more complicated. I know that the 24C08 from Microchip (Atmel) is specified for 1M writes. I also know that the version from STM is - under certain conditions - specified for 4M writes. One 24C08 version from a chinese manufacturer that I checked was specified for 1M again. I don’t own a screen with EEPROM so I’ve had to rely on online pictures. Based on those I could not determine the exact datasheet of this specific part. So I don’t know how this particular one is specified. There are EEPROMs (‘true’ EEPROMs!) that are only specified for 100k writes (Atmel 28C models f.ex; likely others, too).

Nextion spec and warranty

What I know is that Nextion specifies as little as 10k writes. I’m unsure why since that is really low; I originally thought they’d use some crappy flash chip as fake EEPROM but that’s not the case. I can only assume that they want to basically avoid any sort of EEPROM reclamations. I can’t see another reason why they’d put out such an understatement.

While their very low 10k spec does not matter for most it could very well matter if you’re responsible for dozens or hundreds of devices and count on warranty/… in case of issues.

Why even 1M writes don’t (always) save you

I don’t think that the proposed solution is always a bad idea but you should be aware that the lifetime is finite. If you’re using this trick f.ex. to do custom checksums for serial data even 1M is not that much. Assume you have an average of one message per second. Furthermore I assume an average size of 20 bytes per message (example: page0.n12.val=2605ÿÿÿ is 21 characters. If you look at the NSpanel serial protocol, that one uses much, much longer messages). That results in

20 bytes/message 
* 1 message/second 
* 3600 seconds/hour 
= 72k bytes/h

With 1M lifetime:

1M bytes / 72k bytes/h = 14 hours

Not days, not years. 14 hours. Multiply by 10 and it’s still not much at all. Multiply by 100 (!!) and it’s getting useful. Use an NSpanel like protocol and you can forget the idea entirely.

Again, there are scenarios where it can make sense but IMO it cannot be the general goto recommendation.

But what about enhancing the lifetime with cycling??

As for your “40-byte cycling” version (and pretty much all imaginable variations), I cannot see any advantage over the string lookup anymore. Neither in complexity nor in runtime. It only has the disadvantage of a finite (though very high) lifetime.
The basic EEPROM version is attractive because it is ‘elegant’ with only two short lines whereas the string lookup is 4 long-ish lines. So as soon as your EEPROM code exceeds 4 lines of code it more or less looses all of its advantages.

Kind regards,
Max

I’m not familiar with NSpanel. Why does it write serial messages to EEPROM? That seems like a really odd solution but I’m not familiar with the software or application so I’m not in a position to critique the setup. Does seem unusual thought.
The problem I see with the string lookup table is the RAM consumption. A table with all 256 possible values could be in a global variable but would reduce your available memory by 256 bytes on EVERY page. If you make the tables local then you take a 256 byte hit on RAM and program memory on any page using a ASCII->CHAR conversions. The simple version of the EEPROM method is 2 lines of code, a system variable (that already consumes RAM anyway) and 2-byte local or global string variable (“text”). I’m not sure about other users but I routinely run into RAM quantity issues on the Nextion and have to engineer some workaround that’s labor intensive and extremely inefficient. For me RAM is precise. Others might be fine taking the 256 byte hit. The amount of available EEPROM has not been any issue for me so the 2 line ASCII conversion method is a quick, efficient solution for a feature that is lacking.

To satisfy my curiosity, I wrote a simple EEPROM wear tester for the Nextion last week and it’s been running ever since on my desk.

The first line is the cycle number and current value being written to EEPROM at position 100. The 2nd line is the value read back from position 100. The third value is the cycle number of the first encountered read error. The 4th value is the number of total read errors. It writes the value, waits 25ms to allow some time for the EEPROM to settle or corrupt then reads the location. Every 1000 cycles it pauses an additional 10 seconds between write/read and every 10000 cycles it pauses 3 minute time between the write and subsequent read verification. As you can see in the attached image, the EEPROM in my test Nextion 3.2" Enhanced has now gone over 7.2 MILLION write/read cycles without corruption. This is 7.2M erase/writes over the same 4 bytes in the EEPROM. I think the results are pretty conclusive. You’ll have at least 3 minutes of data retention on bytes that are excessively write cycled using this method or anything similar. I believe I’m going to have it pause at 10M cycles and continuously check the stored value over the course of several days. If that checks out I’ll pull the power for a few week then check the data once more. I have hundreds of these LCD’s so I’m happy to test it until failure. I’ll just let it sit on the corner of my desk counting away for a few weeks (months, maybe?). It’s USB power is backed by a UPS battery backup so it shouldn’t be effected by intermittent power failures. If for some reason it has a prolonged power outage that exhausts the UPS it is programmed to retrieve the last cycle count from EEPROM and resume. Assuming this value isn’t corrupted during the power loss it should be able to run unassisted indefinitely. Those tortured EEPROM bytes have to fail at some point, right?

We can just agree to disagree on this issue if you like. I know you’re knowledgeable and I respect your opinion. I also don’t understand the Nextion 10,000 cycle statement. I wonder if at some point in the past they used different “EEPROM” storage, perhaps on-chip flash, utilized different write methods (like page erases rather than byte) or had some extreme use case that presented an issue (unstable supply voltages, strong EMI, etc). Certainly appears conservatively rated.

I’m using the Nextion in a production product so I’ve had to come up with quite a few workarounds to get the user interface I wanted. Things like a schematic image viewer (phone style interface - drag to navigate image, swipe left/right to change image, swipe down to close viewer, etc - smooth and seemless), having the Nextion code automatically detect if it’s running in the simulator or on an actual device (useful for debugging and branching), locking the compiled code to only our screens (allows for safe distribution of updates), adding a pass thru function to the microcontroller to allow programming the attached Nextion without access to the screen itself, scrolling text viewer with limited editing capability, automatic font sizing and scrolling on the keyboard input to allow longer entries, automatically generated menu screens (send the screen the page title, subtitle and names for any buttons then call the page and it auto populates the screen with your buttons arranged and all fonts sized/wrapped to fit in each button and header), etc. I’d be happy to share most of them. The Nextion screens seem a bit limited at first but if you break the problem down its surprising how many features you can implement. I would kill for a few low level commands though but I realize that nothing is ever perfect.

My issue right now is 3.2" Enhanced availability. I’m literally losing sleep over it.

I’m not familiar with NSpanel. Why does it write serial messages to EEPROM? That seems like a really odd solution but I’m not familiar with the software or application so I’m not in a position to critique the setup. Does seem unusual thought.

That‘s not what I meant to say; sorry if I haven‘t been clear. The NSpanel uses a JSON based protocol. Meaning the Nextion screen receives messages like this one {"HMI_ATCDevice":{"ctype":"device","id":"1001383218","outlet":0,"etype":"hot"}} (79 characters; don‘t ask me why it is the way it is; I don‘t know). Each message has an additional header and a CRC checksum at the end. The CRC is (likely) done using Nextions CRC commands. Long story short NSpanel itself has nothing to do with EEPROM. I only used it as a real-world example for a lengthy protocol used with Nextion screens. When I chose the example in my previous post I assumed that custom checksums - possibly with custom protocols - are a frequent reason for looking into string to ascii ordinal conversion. The NSpanel itself may not need such a conversion yet other, similarly long, custom protocols could need it.

The problem I see with the string lookup table is the RAM consumption. […]

Nope, nope, nope. I mean, you could put it in the RAM but you absolutely don‘t need to. Hardcoded strings (as in fvanroies example above) do not consume the „user“ RAM in Nextion. Assuming that one or two of the sys0, sys1, sys2 variables are available (usually yes), you don‘t consume any additional RAM. Believe me, I‘d have included it as disadvantage otherwise because I agree, it would be an important one.
Btw you wouldn‘t need to put the full 256 characters into ram because Nextion doesn‘t support most of the non-printable ones anyway.

As for Nextions poor EEPROM spec, I’ve seen a forum post (you too) that makes it clear that it‘s basically them saying „don‘t use it or don‘t ask for RMA“ (Source. Be warned, there‘re a lot of utterly useless replies in that thread). The chip itself seems to be indeed spec‘ed as 1M writes. Or in other words, they prefer giving their customers 100x (10k = 1M/100) worse specs than risking to provide more support for customers… :man_shrugging: Even if they would get returns; it‘s not hard to replace that one chip (and should even be worth the time compared to discarding the display).

As for your test it doesn‘t reveal anyhing new; or let‘s say, I‘d have been surprised if it had already failed. It is after all known that most EEPROM cells under normal conditions outperform their datasheet specs. I still stick with my point that - depending on your use case - you would need to rely on it to outperform its spec by a factor of 100. I guess many people would - rightfully - be fine with a factor of 10 but 100 seems like pushing it a bit too far IMO - even though some devices may exceed even that.

Since the lookup solution does not consume any RAM I wonder if you still consider it „inferior“. I for myself still tend to stay with my position that it may be an easy and appropriate solution for some cases but it shouldn’t be the default solution for all cases. Or in other words, people should at least estimate if they‘re in the 100k or 100M writes ballpark with their application before (mis)using the EEPROM for overcoming such a stupid language limitation (yes, more than anything else do I think that this topic shouldn‘t even exist).
I do wonder how both compare speedwise. I tend to bet on the EEPROM tbh. Interested in doing some benchmarks?

Regards,
Max

RE: Speed comparison

Since precision timing doesn’t really exist on the Nextions I resorted to counting the number of EEPROM based char/ASCII conversions over a 1 minute period (referencing the RTC)

Here’s the basic code:

cycles.val=0
ascii.val=31
sec.val=rtc5
while(rtc5==sec.val) // wait for RTC seconds value to change
{
}
while(sec.val!=rtc5) // continue loop for 60 seconds (RTC)
{
ascii.val++ // cycle ASCII value between 32 and 126
if(ascii.val==127)
{
ascii.val=32
}
wepo ascii.val,520 // write the ASCII value to EEPROM
repo char.txt,520 // read out the corresponding CHAR
cycles.val++ // increment cycle counter
}

The results on a 3.2" Enhanced worked out to 22.4ms per EEPROM conversion. Some of that is loop overhead and RTC timing checks but 20ms is a reasonable estimate.

I still prefer this method. It’s quick, efficient and simple. Any ASCII<>CHAR conversion accomplished with two lines of code.

Regardless, I think I’ve conclusively demonstrated that the EEPROM method I provided is safe and robust and that any
claim of “10K write cycles” presenting any issues are totally false. I’m currently over 8 million cycles without issue.


This forum is in no way affiliated with NEXTION®, ITEAD STUDIO®, TJC®, or anyone else really. All product names, logos, and brands are property of their respective owners. All company, product, and service names used in this website are for identification purposes only. Use of these names, logos, and brands does not imply endorsement from the respective rights holder(s).