Altering string for a function

I am currently building a project around a nextion display. Things are going reasonbly well so far, but I thought that before I get too far into the coding side of things, it would be more space effective to have the send to display as a function.

This poses a problem with how the data is sent though. This is used for one page and 2 text boxes on that page. This works fine but by the time you have a few pages 4 lines of code could be a bit teduious.

        Serial1.print("t3.txt=\"");
        Serial1.print(String(sensor_width));
        Serial1.print("\"");
        nextion_stop();
        //make sure the sensor height is up to date on the displau
        Serial1.print("t4.txt=\"");
        Serial1.print(String(sensor_height));
        Serial1.print("\"");
        nextion_stop();

Another example having to convert the float to a string before sending

        temp_string = String(coc_value,3);
        Serial1.print("t2.txt=\"");
        Serial1.print(temp_string);
        Serial1.print("\"");
        nextion_stop();

My thinking was to be able to have the print of the component ID and the variable to needs to be sent trasferred in a function call simialr to:

send_text(component_id, var_send);

void send_text(string id, float send_var){
//do the sending stuff here
}

Other than this assumption, I don't really know where to go from here. I have no idea how to format things so that the nextion will understand

Enitre code:


//---Variables for recieved display data
byte first = 0;                     //the first of 4 byte send in big endian format
byte second = 0;                    //the second byte
byte third = 0;                     //the the third byte
byte fourth = 0;                    //the fourth byte
long compiled = 0;                  //hold the re-arranged bytes from the display - positive numbers only
bool rx_ended = false;              //has the transmission ended - this is a flag
byte rx_end_count = 0;              //end byte counter
word nextion_read_in = 0;           //used to count number of end byte from display
byte comp_id = 0;                   //store for component ID
byte comp_page = 0;                 //page data that comes with componenet ID
        
//---control variables
byte current_page = 0;            //page 0 is the first page when starting, so lets presume that the case.
float sensor_width = 23.60;       //page 5, object 6
float sensor_height = 15.70;      //page 5, object 7
bool mirror_up = 1;               //mirror lockup, true by default
byte settle_time = 4;             //the amount of time between either the rail stopping moving or mirror up action in seconds

byte f_counter = 8;
float f_stops [37] = {1, 1.1, 1.2, 1.4, 1.6, 1.8, 2, 2.2, 2.4, 2.8, 3.2, 3.5, 4, 4.5, 5, 5.6, 6.3, 7.1, 8, 10, 13, 14, 16, 18, 20, 22, 25, 28, 32, 35.9, 40, 45, 50, 57, 64, 71.8, 80};

const char *mirror_string [] = {"Standard", "Mirror Up"};
float coc_value = 0.020;
byte coc_inc = 0;
float coc_array [3] = {0.001, 0.100, 0.010};

//---Temporary Variable---
String temp_string;

#define debug                 //uncoment for debugging

void setup() {
  #ifdef debug
    Serial.begin(115200);       //this is for debuging
  #endif
  Serial1.begin(115200);        //this is to comunicate with the display
  //nextion.begin(921600);      //this is as fast as the display will go - still too slow for teensy
  //load data from eeprom before proceeding, don't forget to check it
  delay(50);
  //check for correct start up - this wont work if CPU is reseet
  Serial1.print("page 0");      //ensure first page is selected during testing
  nextion_stop();               //send end of transmission to display
  #ifdef debug
    Serial.println("Running");
  #endif
}

void loop() {
  if (Serial1.available()>0){
    //not trying to use serial interrupt may well be a fools errand.
    delay(5);
    //delayMicroseconds(500); //needed as teensy 4.0 outpaces the serial connection.
    Serial.println("Reading");
    nextion_read();         //read the variables in the buffer that the nextion sent.
    
    //now go to the correct page and do whats needed
    //switch case is faster and more affective thaan if...
    switch (current_page){
      case 0:
        #ifdef debug
          Serial.println("Page 0, main loop");
        #endif
        //this is the home page
      break;

      case 1:
        #ifdef debug
          Serial.println("Page 1, main loop");
        #endif
        //calibrate camera menu - link to other pages
      break;

      case 2:
        #ifdef debug
          Serial.println("Page 2, main loop");
        #endif
        //Calibrate rail - link to other pages
      break;

      case 3:
        #ifdef debug
          Serial.println("Page 3, main loop");
        #endif
        //lens - link to other pages
      break;

      case 4:
        #ifdef debug
          Serial.println("Page 4, main loop");
        #endif
        //shoot - link to other pages
      break;

      case 5:
        #ifdef debug
          Serial.println("Page 5, main loop");
        #endif
        //Sensor size
        //item 8 is dec width, 9 inc width
        if (comp_id == 8){
          sensor_width = sensor_width - 0.10;
        }
        if (comp_id == 9){
          sensor_width = sensor_width + 0.10;
        }
        //item 10 is dec height, 11 inc width
        if (comp_id == 10){
          sensor_height = sensor_height - 0.10;
        }
        if (comp_id == 11){
          sensor_height = sensor_height + 0.10;
        }
        if (comp_id == 12){
          //save the data
        }
        //make sure the sensor width is up to date on the displau
        Serial1.print("t3.txt=\"");
        Serial1.print(String(sensor_width));
        Serial1.print("\"");
        nextion_stop();
        //make sure the sensor height is up to date on the displau
        Serial1.print("t4.txt=\"");
        Serial1.print(String(sensor_height));
        Serial1.print("\"");
        nextion_stop();
        comp_id = 100;        //put the componenet id outside of rnage to stop repeating it one page reloading.
      break;

      case 6:
        #ifdef debug
          Serial.println("Page 6, main loop");
        #endif
      
      break;

      case 7:
        #ifdef debug
          Serial.println("Page 7, main loop");
        #endif
        //mirror action
        if (comp_id == 7){
          //component 7, btn to toggle mirror type
          mirror_up = !mirror_up;
        }
        //component 4, btn to decrease settle time
        //component 5, btn to increase settle time.
        //component - t4.txt
        //settle time is t2.txtx
        comp_id = 100;
      break;

      case 8:
        #ifdef debug
          Serial.println("Page 8, main loop");
        #endif
        //Circle of confusion
        if (comp_id == 8){          //if increment amount changed, move data from input loo, to here
          coc_inc = compiled;
        }
        if (comp_id == 4){          //component 5 increase
          coc_value = coc_value + coc_array[coc_inc];
          if (coc_value > 2){
            coc_value = 0;
          }
        }
        if (comp_id == 5){          //component 4 increase
          coc_value = coc_value - coc_array[coc_inc];
          if (coc_value < 0){
            coc_value = 2;
          }
        }
        //Serial.println(coc_value,3);
        temp_string = String(coc_value,3);
        Serial1.print("t2.txt=\"");
        Serial1.print(temp_string);
        Serial1.print("\"");
        nextion_stop();
        comp_id = 100;
      break;

      default:

      break;
    }
  }

}

//---Read Data from the display---
void nextion_read(){
  rx_end_count = 0;             //reset end count before checking input
  while (rx_end_count <3){
    nextion_read_in = Serial1.read();
    delayMicroseconds(500);     //wait for all data
    switch (nextion_read_in){
      //0x00 0x00 0x00 0xFF 0xFF 0xFF - for started.
      //0x88 0xFF 0xFF 0xFF - for ready to go.
      case 0x24:
        Serial.println("Serial Buffer Overflow");
        //panic, we have outpaced the nextion
      break;

      case 0x65:
        #ifdef debug
          Serial.println("touch event");
        #endif
        //discard first and last bytes
        comp_page = Serial1.read();   //read this as it can be used to check if we are on the same page
        comp_id = Serial1.read();   
        nextion_read_in = Serial1.read();    //discard this for the time being 0 for release 1 for press
        #endif debug
          Serial.print("Component page: ");
          Serial.println(comp_page);
          Serial.print("Component ID: ");
          Serial.println(comp_id);
        #endif
      break;

      case 0x66:
        Serial.print("page number: ");
        //0x66 is page number - byte number
        current_page = Serial1.read();
        Serial.println(current_page);
      break;

      case 0x67:
        Serial.println("touch co-ord awake");
        //if this happens - panic
      break;

      case 0x68:
        Serial.println("touch co-ord sleep");
        //if this happens - panic
      break;

      case 0x70:
        Serial.println("text");
        //we are going to avoid recieving text - panic
      break;

      case 0x71:
        //0x71 is value - long word/4 byte in big endian form
        #ifdef debug
          Serial.print("number: ");
        #endif
        //NUmber in little endian format, so reshuffle byte to correct
        first = Serial1.read();
        second = Serial1.read();
        third = Serial1.read();
        fourth = Serial1.read();
        compiled = fourth << 8;
        compiled = compiled | third << 8;
        compiled = compiled | second << 8;
        compiled = compiled | first;
        #ifdef debug
          Serial.print("Compiled: ");
          Serial.println(compiled);
        #endif
      break;

      case 0x88:
        Serial.println("Screen Ready");
      break;

      case 0x89:
        Serial.println("Nextion Reading Micrto SD");
        Serial.println("Watch for firmware update to display");
      break;

      case 0xff:
        //Serial.println("End");
      break;

      default:
        //just print this to the terminal for debugging
        Serial.println("Something else: ");
        Serial.println(nextion_read_in, HEX);  
      break;
    }
    
    if (nextion_read_in == 0xff){
      rx_end_count ++;
      //doing it this way allow for easier resetting of the end counter than in the select case statement
    } else {
      rx_end_count = 0;
    }
    /*
    if (nextion.available() == 0){    //this is a fail safe incase we don't get all end bytes
      Serial.println("Serial no longer available");
      rx_end_count = 3;
    }
    */
  }
}

//---stop bytes when sending to display---
void nextion_stop(){
  Serial1.write("\xff\xff\xff");
}

Using a function sounds like a good idea

Which Arduino board are you using ?

Currently testing with a teensy 4.0. There is going to be some fairly heavy floating point maths later in the project and would like the benefit of a dedicated FPU

Does the teensy support the Serial.printf() function ?

it supports everything that a normal arduino suports using a teensyduino.

The ESP32 is not an official Arduino board but it allows the use of the Serial.printf() function

A little research seems to indicate that so does the Teensy. If so then the complete print statement can be in a single statement as long as the correct data types are used. Note that Strings may not be used with Serial.printf() to the best of my knowledge

Never used Printf, do you know of any good places to read about it to learn.
A little better understanding from my side may reveal a work around.

It works the same way as the C printf() function so any site that explains how to format mixed text and data output using that function will give you a good start

https://www.google.com/search?q=C%2B%2B+printf

thank you both, I will have a read in the morning. It's getting a little late and I think a fresh mind would be best.

Off the top of my head (and untested), if you add this line somewhere up in your variable declarations:

const char NEXTION_STOP[] = {"\xff\xff\xff"};

then this

        Serial1.print("t3.txt=\"");
        Serial1.print(String(sensor_width));
        Serial1.print("\"");
        nextion_stop();
        //make sure the sensor height is up to date on the displau
        Serial1.print("t4.txt=\"");
        Serial1.print(String(sensor_height));
        Serial1.print("\"");
        nextion_stop();

can become

        Serial1.printf("t3.txt=\"%.1f\"%s", sensor_width, NEXTION_STOP);
        //make sure the sensor height is up to date on the displau
        Serial1.printf("t4.txt=\"%.1f\"%s", sensor_height, NEXTION_STOP);

and this

        temp_string = String(coc_value,3);
        Serial1.print("t2.txt=\"");
        Serial1.print(temp_string);
        Serial1.print("\"");
        nextion_stop();

can become this

        Serial1.printf("t2.txt=\"%.3f\"%s", coc_value, NEXTION_STOP);

That works perfectly, thanks.

I can have a few functions for each .txt and just pass the float to them as needed. This appears to be a much better solution that my original code.

Or, as the printing will be done in a single line of code, you could call the printf() function itself instead of your own function to do the printing

It seems silly to call a function that simply calls a function

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.