├── img └── USARTConfig.png ├── Nextion.h ├── README.md └── Nextion.c /img/USARTConfig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrdr23/Nextion_STM32_Library/HEAD/img/USARTConfig.png -------------------------------------------------------------------------------- /Nextion.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Nextion.h 3 | * 4 | * Created on: Aug 12, 2022 5 | * Author: Emre DUR 6 | * 7 | * 8 | * Configure UART RX and TX DMA streams and UART Global Interrupt to use this library. 9 | * This library also requires the function below included in the main code wihtout ANY changes. 10 | * 11 | * 12 | ---------------------------- 13 | void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 14 | { 15 | Nextion_Update(huart, &nextion); 16 | } 17 | ----------------------------- 18 | * 19 | * 20 | */ 21 | 22 | #ifndef INC_NEXTION_H_ 23 | #define INC_NEXTION_H_ 24 | 25 | //Include HAL Library from main header file :/ 26 | #include "main.h" 27 | 28 | //Include libraries 29 | #include "stdlib.h" 30 | #include "string.h" 31 | #include "stdio.h" 32 | 33 | /* 34 | * Defines 35 | */ 36 | //Reminder: To use more components or to receive more characters increase buffer or list counts! 37 | #define NEXTION_TIMEOUT 250 38 | #define NEXTION_MAX_BUFF_LEN 96 39 | #define NEXTION_TEXT_BUFF_LEN 64 40 | #define NEXTION_MAX_COMP_COUNT 32 41 | 42 | #define NEX_RET_CMD_FINISHED (0x01) 43 | #define NEX_RET_EVENT_LAUNCHED (0x88) 44 | #define NEX_RET_EVENT_UPGRADED (0x89) 45 | #define NEX_RET_EVENT_TOUCH_HEAD (0x65) 46 | #define NEX_RET_EVENT_POSITION_HEAD (0x67) 47 | #define NEX_RET_EVENT_SLEEP_POSITION_HEAD (0x68) 48 | #define NEX_RET_CURRENT_PAGE_ID_HEAD (0x66) 49 | #define NEX_RET_STRING_HEAD (0x70) 50 | #define NEX_RET_NUMBER_HEAD (0x71) 51 | #define NEX_RET_INVALID_CMD (0x00) 52 | #define NEX_RET_INVALID_COMPONENT_ID (0x02) 53 | #define NEX_RET_INVALID_PAGE_ID (0x03) 54 | #define NEX_RET_INVALID_PICTURE_ID (0x04) 55 | #define NEX_RET_INVALID_FONT_ID (0x05) 56 | #define NEX_RET_INVALID_BAUD (0x11) 57 | #define NEX_RET_INVALID_VARIABLE (0x1A) 58 | #define NEX_RET_INVALID_OPERATION (0x1B) 59 | #define NEX_EVENT_ON_PRESS (0x01) 60 | #define NEX_EVENT_ON_RELEASE (0x00) 61 | 62 | /* 63 | * NexComp Struct 64 | */ 65 | typedef struct 66 | { 67 | //Variables for storing page and ID for every component 68 | uint8_t _page, _id; 69 | 70 | //Function pointers for storing the callback functions 71 | void (*callbackOnPress)(); 72 | void (*callbackOnRelease)(); 73 | 74 | //Variable for storing object name 75 | char *objname; 76 | 77 | } NexComp; 78 | 79 | 80 | /* 81 | * Nextion Struct 82 | */ 83 | typedef struct 84 | { 85 | //Handle for the UART used with the Nextion display 86 | UART_HandleTypeDef *nextionUARTHandle; 87 | 88 | //Variables for parsing the received data 89 | uint8_t _RxDataArr[NEXTION_MAX_BUFF_LEN], _RxData, _arrCount, _pkgCount; 90 | 91 | //Variables for component list 92 | NexComp* _NexCompArr[NEXTION_MAX_COMP_COUNT]; 93 | uint8_t _NexCompCount; 94 | 95 | //Variables for receiving strings and numbers, 96 | uint8_t NexTextBuff[NEXTION_TEXT_BUFF_LEN], NextTextLen; 97 | int32_t NextNumBuff; 98 | 99 | } Nextion; 100 | 101 | 102 | /* 103 | * Library User functions 104 | */ 105 | 106 | uint8_t NextionAddComp(Nextion* nex, NexComp* _nexcomp, char* objectname, uint8_t __page, uint8_t __id, void (*callbackFuncOnPress)(), void (*callbackFuncOnRelease)()); 107 | uint8_t NextionUpdate(UART_HandleTypeDef *huart, Nextion *nex); 108 | uint8_t NextionInit(Nextion *nex, UART_HandleTypeDef *nextionUARTHandle); 109 | uint8_t NextionGetText(Nextion *nex, NexComp *comp, char *buf); 110 | uint8_t NextionSetText(Nextion *nex, NexComp *comp, char *usertext); 111 | uint8_t NextionGetVal(Nextion *nex, NexComp *comp, int *valBuf); 112 | uint8_t NextionSetVal(Nextion *nex, NexComp *comp, int userval); 113 | 114 | 115 | /* 116 | * Library Low Level Functions 117 | */ 118 | uint8_t NextionSendCommand(Nextion *nex, char *_command); 119 | uint8_t NextionEndCommand(Nextion *nex); 120 | uint8_t NextionRestartIT(Nextion *nex); 121 | uint8_t NextionStopIT(Nextion *nex); 122 | 123 | #endif /* INC_NEXTION_H_ */ 124 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nextion-STM32-Library 2 | Library for using Nextion HMI displays on STM32 MCUs with STM32Cube and HAL based projects. 3 | 4 | # Introduction 5 | This library is created for STM32Cube projects using HAL libraries and depends on the "main.h" file created by STM32Cube software. Inclusion of "main.h" file makes this library compatible for all STM32 microcontroller families as long as the project is created with STM32Cube with HAL libraries selected. 6 | 7 | # Configuration 8 | To properly use this library, a USART/UART peripheral of the MCU should be reserved to the Nextion display and configured in "Asynchronous" mode and the Global Interrupts should be activated in the STM32Cube IOC configuration as shown below; 9 | 10 | ![](img/USARTConfig.png) 11 | # Usage 12 | 13 | This library requires to be initialized in a few steps. Every code in this section is written in order, so you can follow this section as a step by step guide. 14 | 15 | Before getting started, don't forget to include the library in your project. 16 | ``` 17 | #include "Nextion.h" 18 | ``` 19 | 20 | 21 | First of all, the user should create a Nextion object. Then multiple objects for the components can be created. 22 | ``` 23 | //Object for the Nextion display 24 | Nextion nextion; 25 | 26 | //Objects for the components. Button1 is for example only. 27 | NexComp button1; 28 | ``` 29 | 30 | 31 | Then you could define the USART/UART Interrupt Callback function and including the NextionUpdate function. This enables the library to interpret the data without using proccessing power in the main loop. This part is copy pasteable and doesn't need any modifications, if you are using the same Nextion object name in your project. 32 | ``` 33 | void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 34 | { 35 | NextionUpdate(huart, &nextion); 36 | } 37 | ``` 38 | 39 | 40 | You can also declare and define a callback function for any Nextion components you want. This function will be attached to the component in the next step 41 | ``` 42 | void buttonCallback() 43 | { 44 | //Example function 45 | HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); 46 | } 47 | ``` 48 | 49 | 50 | In the next step you can initialise the Nextion and the components you want. 51 | ``` 52 | //Initialise Nextion with the configured UART handle 53 | NextionInit(&nextion, &huart2); 54 | 55 | //Register the component in the library with parameters: Nextion Object, Component Object, Object Name, Page, ID, Callback Function On Press, Callback Function On Release 56 | //If you don't want any callback function, pass NULL as the parameter 57 | NextionAddComp(&nextion, &button1, "b0", 0, 2, buttonCallback, NULL); 58 | ``` 59 | The code below shows a complete example if you want a component callback (Only the functions needed for this library are included); 60 | ``` 61 | #include "Nextion.h" 62 | 63 | Nextion nextion; 64 | NexComp button1; 65 | 66 | void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 67 | { 68 | NextionUpdate(huart, &nextion); 69 | } 70 | 71 | void buttonCallback() 72 | { 73 | //Example function 74 | HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); 75 | } 76 | 77 | int main() 78 | { 79 | NextionInit(&nextion, &huart2); 80 | NextionAddComp(&nextion, &button1, "b0", 0, 2, buttonCallback, NULL); 81 | 82 | while(1) 83 | { 84 | //Main loop 85 | } 86 | } 87 | ``` 88 | 89 | 90 | ## Component Functions 91 | 92 | This library has four functions which can be used with the corresponding Nextion components: 93 | 94 | ### NextionGetText(Nextion *nex, NexComp *comp, char *buf); 95 | 96 | This function gets the text data of a Nextion Text component. 97 | 98 | Example Usage; 99 | ``` 100 | NextionGetText(&nextion, &nexText1, mybuffer); 101 | ``` 102 | 103 | ### NextionSetText(Nextion *nex, NexComp *comp, char *usertext); 104 | 105 | This function gets the text data of a Nextion Text component. 106 | 107 | Example Usage; 108 | ``` 109 | NextionSetText(&nextion, &nexText1, "Hello!"); 110 | ``` 111 | 112 | ### NextionGetVal(Nextion *nex, NexComp *comp, int *valBuf); 113 | 114 | This function gets the text data of a Nextion Text component. 115 | 116 | Example Usage; 117 | ``` 118 | NextionGetVal(&nextion, &number0, &exampleVariable); 119 | ``` 120 | 121 | ### NextionSetVal(Nextion *nex, NexComp *comp, int userval); 122 | 123 | This function gets the text data of a Nextion Text component. 124 | 125 | Example Usage; 126 | ``` 127 | NextionSetVal(&nextion, &number1, 93); 128 | ``` 129 | 130 | 131 | 132 | # Thanks 133 | I want to thank the creators of the repositories below for the inspiration. 134 | 135 | - https://github.com/ITEAD-Thierry/NextionX 136 | - https://github.com/itead/ITEADLIB_Arduino_Nextion 137 | - https://github.com/guiguitz/STM32-Nextion-API 138 | -------------------------------------------------------------------------------- /Nextion.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Nextion.c 3 | * 4 | * Created on: Aug 12, 2022 5 | * Author: Emre DUR 6 | */ 7 | 8 | #include "Nextion.h" 9 | 10 | uint8_t NextionAddComp(Nextion* nex, NexComp* _nexcomp, char* objectname, uint8_t __page, uint8_t __id, void (*callbackFuncOnPress)(), void (*callbackFuncOnRelease)()) 11 | { 12 | //Make space before passing the object name to the nexcomp struct 13 | _nexcomp->objname = (char *) malloc((strlen(objectname)*sizeof(char)) + 1); 14 | //Pass the object name to the struct 15 | strcpy(_nexcomp->objname, objectname); 16 | 17 | //Pass the corresponding data from component to component struct 18 | _nexcomp->_id = __id; 19 | _nexcomp->_page = __page; 20 | 21 | //Add the component struct to the list on the Nextion Struct 22 | nex->_NexCompArr[nex->_NexCompCount] = _nexcomp; 23 | nex->_NexCompCount++; 24 | 25 | //Bind the correct callback functions together 26 | _nexcomp->callbackOnPress = callbackFuncOnPress; 27 | _nexcomp->callbackOnRelease = callbackFuncOnRelease; 28 | 29 | //Return OK 30 | return 0; 31 | } 32 | 33 | uint8_t NextionInit(Nextion *nex, UART_HandleTypeDef *nextionUARTHandle) 34 | { 35 | //Pass the used UART handle to the struct 36 | nex->nextionUARTHandle = nextionUARTHandle; 37 | 38 | //Start the parsing counters from zero 39 | nex->_arrCount = 0; 40 | nex->_pkgCount = 0; 41 | 42 | //Start UART transaction using DMA 43 | HAL_UART_Receive_IT(nex->nextionUARTHandle, (uint8_t *)&nex->_RxData, 1); 44 | 45 | //Start the component count variable from zero 46 | nex->_NexCompCount = 0; 47 | 48 | //Return OK 49 | return 0; 50 | } 51 | 52 | uint8_t NextionUpdate(UART_HandleTypeDef *huart, Nextion *nex) 53 | { 54 | if(huart->Instance == (nex->nextionUARTHandle->Instance)) 55 | { 56 | //Add the received byte to the array and increment the counter afterwards 57 | nex->_RxDataArr[nex->_arrCount] = nex->_RxData; 58 | nex->_arrCount++; 59 | 60 | //Count 0xFF 61 | if(nex->_RxData == 0xFF) 62 | nex->_pkgCount++; 63 | else 64 | nex->_pkgCount = 0; 65 | 66 | //Assume a package is received after three 0xFF commands, 67 | //and start processing the data 68 | if(nex->_pkgCount == 3) 69 | { 70 | //Determine the length (count) of the data 71 | uint8_t count = 0, FFCount = 0; 72 | for(uint8_t i = 0; FFCount < 3; i++) 73 | { 74 | count++; 75 | if(nex->_RxDataArr[i] == 0xFF) FFCount++; 76 | } 77 | 78 | //In case of a touch event call the callback function accordingly, 79 | if(nex->_RxDataArr[0] == NEX_RET_EVENT_TOUCH_HEAD) 80 | { 81 | //Loop through the component struct array, 82 | for(uint8_t i = 0; i < nex->_NexCompCount; i++) 83 | { 84 | //Detect the affected component by its Page and ID 85 | if( (nex->_RxDataArr[2] == (nex->_NexCompArr[i]->_id)) && (nex->_RxDataArr[1] == (nex->_NexCompArr[i]->_page)) ) 86 | { 87 | //Call the desired On Press or On Release callback function, 88 | if((nex->_RxDataArr[3] == NEX_EVENT_ON_PRESS) && (nex->_NexCompArr[i]->callbackOnPress != NULL)) 89 | nex->_NexCompArr[i]->callbackOnPress(); 90 | if((nex->_RxDataArr[3] == NEX_EVENT_ON_RELEASE) && (nex->_NexCompArr[i]->callbackOnRelease != NULL)) 91 | nex->_NexCompArr[i]->callbackOnRelease(); 92 | } 93 | } 94 | } 95 | 96 | //If the received package contains string data 97 | if(nex->_RxDataArr[0] == NEX_RET_STRING_HEAD) 98 | { 99 | nex->NextTextLen = 0; 100 | for(int i = 0; i < (count - 4); i++) 101 | { 102 | nex->NexTextBuff[i] = nex->_RxDataArr[i+1]; 103 | nex->NextTextLen++; 104 | } 105 | } 106 | 107 | //If the received package contains integer data 108 | if(nex->_RxDataArr[0] == NEX_RET_NUMBER_HEAD) 109 | { 110 | nex->NextNumBuff = ((uint32_t)nex->_RxDataArr[4]<<24)|((uint32_t)nex->_RxDataArr[3]<<16)|(nex->_RxDataArr[2]<<8)|(nex->_RxDataArr[1]); 111 | } 112 | 113 | //Reset the buffer counters 114 | nex->_pkgCount = 0; 115 | nex->_arrCount = 0; 116 | } 117 | 118 | HAL_UART_Receive_IT(nex->nextionUARTHandle, (uint8_t *)&nex->_RxData, 1); 119 | } 120 | 121 | //Return OK 122 | return 0; 123 | } 124 | 125 | uint8_t NextionGetText(Nextion *nex, NexComp *comp, char *buf) 126 | { 127 | //Allocate a static buffer for combining the transfer command string 128 | char transmitBuff[NEXTION_TEXT_BUFF_LEN] = {0}; 129 | 130 | //Combine required commands in a single string 131 | sprintf(transmitBuff, "get %s.txt", comp->objname); 132 | 133 | //Send the combined command to Nextion and wait for the received answer 134 | NextionSendCommand(nex, transmitBuff); 135 | HAL_Delay(10); 136 | 137 | //Copy the received string to the desired buffer (and add NULL character to the end), 138 | for(uint8_t i = 0; i < nex->NextTextLen; i++) 139 | { 140 | buf[i] = nex->NexTextBuff[i]; 141 | } 142 | buf[nex->NextTextLen] = '\0'; 143 | 144 | //Return OK 145 | return 0; 146 | } 147 | 148 | uint8_t NextionSetText(Nextion *nex, NexComp *comp, char *usertext) 149 | { 150 | //Allocate a static buffer for combining the transfer command string 151 | char transmitBuff[NEXTION_TEXT_BUFF_LEN] = {0}; 152 | 153 | //Combine required commands in a single string 154 | sprintf(transmitBuff, "%s.txt=\"%s\"", comp->objname, usertext); 155 | 156 | //Send the combined command to Nextion and wait for the received answer 157 | NextionSendCommand(nex, transmitBuff); 158 | 159 | //Return OK 160 | return 0; 161 | } 162 | 163 | uint8_t NextionGetVal(Nextion *nex, NexComp *comp, int *valBuf) 164 | { 165 | //Allocate a static buffer for combining the transfer command string 166 | char transmitBuff[NEXTION_TEXT_BUFF_LEN] = {0}; 167 | 168 | //Combine required commands in a single string 169 | sprintf(transmitBuff, "get %s.val", comp->objname); 170 | 171 | //Send the combined command to Nextion and wait for the received answer 172 | NextionSendCommand(nex, transmitBuff); 173 | 174 | //Wait for Nextion to send the command back; 175 | //This line blocks the code for a while and provides a crude ensurement 176 | HAL_Delay(50); 177 | 178 | //Get the received value from the buffer and pass it to the user variable 179 | *valBuf = nex->NextNumBuff; 180 | 181 | //Return OK 182 | return 0; 183 | } 184 | 185 | uint8_t NextionSetVal(Nextion *nex, NexComp *comp, int userval) 186 | { 187 | //Allocate a static buffer for combining the transfer command string 188 | char transmitBuff[NEXTION_TEXT_BUFF_LEN] = {0}; 189 | 190 | //Combine required commands in a single string 191 | sprintf(transmitBuff, "%s.val=%d", comp->objname, userval); 192 | 193 | //Send the combined command to Nextion and wait for the received answer 194 | NextionSendCommand(nex, transmitBuff); 195 | 196 | //Return OK 197 | return 0; 198 | } 199 | 200 | char ENDTERMS[]={255,255,255}; 201 | uint8_t NextionSendCommand(Nextion *nex, char *_command) 202 | { 203 | HAL_UART_Transmit(nex->nextionUARTHandle, (uint8_t *)_command, strlen((const char*)_command), NEXTION_TIMEOUT); 204 | NextionEndCommand(nex); 205 | 206 | //Return OK 207 | return 0; 208 | } 209 | 210 | uint8_t NextionEndCommand(Nextion *nex) 211 | { 212 | uint8_t EndCommand[3] = {255, 255, 255}; 213 | HAL_UART_Transmit(nex->nextionUARTHandle, EndCommand, 3, NEXTION_TIMEOUT); 214 | NextionRestartIT(nex); 215 | 216 | //Return OK 217 | return 0; 218 | } 219 | 220 | //Following two functions are not needed anymore and will be removed in the future, 221 | uint8_t NextionRestartIT(Nextion *nex) 222 | { 223 | HAL_UART_Receive_IT(nex->nextionUARTHandle, (uint8_t *)&nex->_RxData, 1); 224 | 225 | //Return OK 226 | return 0; 227 | } 228 | 229 | uint8_t NextionStopIT(Nextion *nex) 230 | { 231 | //Stop UART interrupts. Required for Nextion communication functions, 232 | HAL_UART_AbortReceive_IT(nex->nextionUARTHandle); 233 | 234 | //Return OK 235 | return 0; 236 | } 237 | --------------------------------------------------------------------------------