I’m trying to send a serial command to a CPU using a timer and I cannot figure out why it’s not working. Here’s how it is supposed to work.
- A keypad is used to enter a set point value into a numeric display (n0.val).
- The value of n0.val is compared to a variable (va0.val). The va0.val is the set point value in the CPU
- If those two values don’t match, that means the set point has been updated, and the nextion will send a serial command with the value in n0.val to the CPU.
- Once received, the CPU will echo back the setpoint value into variable va0.val.
- Once the two values match, the serial command will no longer execute.
Steps 2 and 3 are executed by a timer. Every time the timer updates, it compares va0.val to n0.val. If they are not equal, the command as described in line 3 is sent.
What should happen is that once every 500 mS, I should see an output of BS65 (this is the command). But what happens is that the serial output just starts filling the buffer with the same command over and over again. My CPU sees is BS65BS65BS65BS65BS65BS65BS65BS65BS65BS65.
This is happening much faster than the timer. I know this because I set the timer to 5000 mS and the same thing happened.
FYI, if I make the code execute by pushbutton, it works fine. Even if I push the push button as fast as I can, the commands look like this
Any ideas of what’s going on, and how I can fix it?
I hadn’t posted my code because I thought, incorrectly, that the problem was obviously in the screen. I used the nextion editor and the problem did not seem to exist.
I finally figured out that the problem was on the CPU side. I had been using the serial command readline(). This command will read the entire serial buffer until it encounters an end statement. My custom commands were not sending an end statement, but there must have been one coming from the serial commands sent by nextion. Therefore, every now and then I would read the serial buffer and get a bunch of data all at once. I still don’t know why the same command worked just fine when sent by a button. The command is below. I want to point out that the command was being sent properly by the screen while using a button AND using a timer. It just wasn’t being recognized on the CPU side when I used the timer, depending on the update timer rate. The faster I updated the timer, the more errors I got.
on timer update…
if(BS.val!=VBS.val) // BS is user set point. VBS is the CPU verified set point
printh EE // Message start marker
prints “BS”,2 // address ‘BS’
prints TXT.txt,2 // set point value in BS
printh FF // end marker
After learning how readline() waits for an end marker, I changed the serial read command to read(6). This command reads 6 bytes out of the buffer and does not require a specific end marker. Because it always reads the same size, it completes in a predictable number of CPU cycles.
In the CPU I used,
response=read(6) # read 6 byes from buffer
if len(response)==6: # Verify data in bufffer and that buffer size matches message size
if response==238 and response ==255: # verify start and end markers are there
msg = response[3:5].decode(‘utf-8’)
send_command(‘page1.VBS.val=’ + msg) # echo value back to screen to variable.
This worked perfectly, and now I can run the nextion timer to run at 100 mS, which is plenty fast for this application.
Sorry I hadn’t posted the code earlier. I hope this explanation helps others who are running into similar problems.