Start a new topic

NEXTION LCD - variable value modification over UART on STM32

Hi,


I have a ST Nucleo-F413 board and the Nextion 2.4" HMI display.


I have initialised and connected the UART on the MCU to the Nextion LCD. However, I'm a bit confused as to how to modify variables in my GUI on the display via UART from the MCU.


I have managed to send commands through the Nextion Editor serial emulation successfully, for example n0.val=20 would update the number display n0 to a value of 20.


I wondered if anyone could provide me with some basic example code for how to do this from the MCU over UART?


I have so far considered something like this (I would call the function like: setValue((uint8_t) 20,( char*) "n0") :

void setValue(uint8_t number, char *object_name)
{
    char buf[10] = {0};

    itoa(number, buf, 10);
		
		char cmd[strlen(object_name) + 15];
		strcpy( cmd, object_name );
		strcat( cmd, ".val=" );
		strcat( cmd, buf );

		uint8_t end = 0xFF;
		
		HAL_UART_Transmit(&huart2, (uint8_t*) &cmd, sizeof(cmd), 10);
		HAL_UART_Transmit(&huart2, (uint8_t*) &end, sizeof(end), 10);
		HAL_UART_Transmit(&huart2, (uint8_t*) &end, sizeof(end), 10);
	  HAL_UART_Transmit(&huart2, (uint8_t*) &end, sizeof(end), 10);
}

 But when I run this function, the value does not change on the LCD. I believe it is an issue with my transmission or format of the command from the MCU.


Thanks in advance!



Which compiler used probably makes a difference.


commands sent in emulation need three byte 0xFF termination serially.

(transparent to user that this is being appended before sent)


How you want to push the text characters is up to user.


I think I am going to stop writing until people start reading what is written

Why are you sending your characters/bytes in base 10?

Only the number would need to be output in base 10.


Try to see what you have been actually sending over serial

My bet is it looks far far different from n0.val=20ÿÿÿ

Patrick, first off thanks for your reply.


I wonder, did you read the example code I have been working towards? Because you would see that I have indeed read the documentation and I am sending the 3 0xFF  termination bytes.


I am not sending my characters in base 10, they are sent as bytes...


In my function, I convert the number to ASCII because the documentation states the commands are sent in ASCII.


I then created the string of chars corresponding to the ASCII command.


Then I send this command over the UART.


I then send 3 x bytes of 0xFF.

Oh and as for the compiler I'm using the Keil IDE which I believe uses the MDK-ARM compiler.


Also I just want to point out, I'm not an expert in different encodings/formats, hence the reason for the question. I have read the documentation and looked at the Arduino example and the demo code. However, the documentation whilst better than many, is still lacking and the English is not perfect, so I couldn't find my answers there.

HAL_UART_Transmit(&huart2, (uint8_t*) &end, sizeof(end), 10);


Okay so this is your compiler ... and the 10 parameter in your function is?

(I am not a linguist of all computerese languages.  Mostly binary and pascal)

Oh sorry, I realise why you were confused now. The 10 value is just the transmission timeout value, the HAL_UART_Transmit function is from the STM HAL library, and requires a timeout parameter.

why don't you just first connect your Nucleo directly to your PC via serial, start a simple Terminal on PC change to HEX mode display and see what really arrive when send data?

This normally shows very quickly the issue ... and when it is correct on PC, it also should work for the Nextion ...

besides there is a hardware issue ...

make sure, that everything is wired correctly between your Nucleo and Nextion ...

- common GND
- RX-TX / TX-RX

 

Okay, so let's try to figure this out.


The Arduino C++ version of setText() takes a uint32_t param.

This shouldn't matter as it is converted and passed to sendCommand

where sendCommand adds the three byte terminator.

 

bool NexNumber::setValue(uint32_t number)
{
    char buf[10] = {0};
    String cmd;
    
    utoa(number, buf, 10);
    cmd += getObjName();
    cmd += ".val=";
    cmd += buf;

    sendCommand(cmd.c_str());
    return recvRetCommandFinished();
}

 

and is used in code as

// NexComponent variable = NexComponent(pageno,.id,".objname");
    NexNumber MCUSide_n0 = NexNumber(0,1,"n0");
    uint32_t number;
    number = 20;
    n0.setValue(number);
// where "n0" is page0 and has .id of 0 in the user HMI file.

The pageno and .id members of the object class are used inbound to
  capture incoming press/release events
The .objname member of the object class are used for outbound to
   parse the .val= to ... blah-blah-blah before sending out.

sendCommand() function is straight forward

 

void sendCommand(const char* cmd)
{
    while (nexSerial.available())
    {
        nexSerial.read();
    }
    
    nexSerial.print(cmd);
    nexSerial.write(0xFF);
    nexSerial.write(0xFF);
    nexSerial.write(0xFF);
}

 


So if yours is doing the same and you are certain that your function
is pushing out n0.val=20ÿÿÿ serially ...

It either boils down to
1) n0 is not on the HMI current page and hasn't been set as .vscope global in the HMI for which prepending the page before the n0
is needed as in page0.n0.val=20ÿÿÿ or
2) your error is beyond your function's code.

Keil's compiler is different than Arduino, is different from mikroC

(I prefer mikroPascal for the STMs which contains the UART lib for STM32 work)
   UART1_Write_Text('n0.val=');
   UART1_Write_Text(Inttostr(number));
   UART1_Write(255);
   UART1_Write(255);
   UART1_Write(255);

So you see that it is merely just pushing out the text three bytes terminated
- which you state you are certain that your's is doing

Have you confirmed it is indeed sending (Logic Analyzer, Terminal, etc)?


Okay so firstly I don't have USB Serial adapter with me right now, I will have it tomorrow, so I can't hook the MCU up to the PC to see the output until then.


The wiring is definitely correct (TX to RX, RX to TX, GND to GND).


My setValue function is definitely being called (I've used LED outputs to verify).


The n0 object is definitely present on the current page (I only have the one page for now btw).


I am not certain that I am sending the command in the correct format, hence why I was originally asking for some STM32 based example code for this - so I could cross compare. I posted my current attempt in the hope that someone may be able to verify it looks correct, and from your replies it seems so.


I believe the error will be in the formatting of the sent command/termination bytes, as this is the area I am least confident in. I think I will have to wait till tomorrow when I can check the output for sure using my PC.

Try ascii send byte by byte of char buffer


void setValue(uint8_t number, char *object_name) {

   char bufA[4] = {0};

   char bufB[10] = {0};

   char bufC[3] = {255,255,255};  

   byte i;

   itoa(number, bufA, 10);


   bufB[0] = 110;

   bufB[1] = 48;

   bufB[2] = 46;

   bufB[3] = 118;

   bufB[4] = 97;

   bufB[5] = 108;

   bufB[6] = 61;

   bufB[7] = 0;

   for(i=0;i<8; i++) {

     if(BufB[i] != 0) {

        HAL_UART_Transmit(bufB[i],1,10);

     }

   }

   for(i=0;i<4; i++) {

     if(bufA[i] != 0) {

        HAL_UART_Transmit(bufA[i],1,10);

     }

  }

  for(i=0;i<3; i++) {

     if(bufC[i] != 0) {

        HAL_UART_Transmit(bufC[i],1,10);

     }

  }

}

Error in my code, didn't include first parameter for uart module.

But hopefully you get the idea of what I am trying to suggest.


The other configuration issue that we don't see is baudrate.

Nextion's by default are shipped with baud set at 9600.

This can be changed with the bauds system variable.


But certainly mismatched baudrates would cause sending not being displayed.

Thanks for the code Patrick, and don't worry I understood the idea. I have changed the parameters of the transmit function and tried the code you suggested but I still do not see any change on the LCD.


With regards to the baudrate, this has been set at 9600 the whole time as I had noticed that this was the default value when I read the documentation. So this is not an issue.


Finally, I found a Bluetooth UART module lying around that I had used to send data to my phone for a previous project. So I hooked it up to the UART of the MCU and sent the same data I was sending to the Nextion LCD UART, in order to verify the data is being transmitted correctly. However, there is not output on the terminal suggesting that the transmit function is not working. This would obviously explain the issues I'm facing.


Anyway, I just wanted to update you. I will continue exploring this problem tomorrow and I will also have my USB UART adapter so that I can connect directly to my PC.

Double check baudrate on Nextion

put a text variable t0 (to not conflict with n0) on page

In postinitialize event put

  cov bauds,t0.txt,0


If baudrate is correct - N81 Settings?

Then of course there is always documentation

Ouch! your Reference Manual is 1284 Pages

pdf
Login or Signup to post a comment