Nextion Display will not display force sensor value URGENT

Hi all,

I am working on a project where I am using four sensors connected to an Arduino Mega. The first three sensors are thermocouple amplifiers and they connect to digital inputs on the Mega and are controlled via SPI. The amplifier is the Max31855. I have code written to output the amplifiers values to the Nextion display continuously and this works exactly how I want it to work.

The problem that I am having is getting the display to display the output from the force sensitive resistor. It just uses a simple voltage divider with a 10K resistor and one analog input.

I have written some code for it and Im thinking that it should output onto the screen like the thermocouples but it does not the value just stays at zero.

I am using a number variable for the force sensor and assigning fsrForce to "force.val="

If I look on the serial monitor I can see that the force.val= 2?? so I know that the arduino understands this and is trying to get it onto the display but for some reason it cannot.

Any help would be greatly appreciated I am on a strict schedule sadly however.

Thanks in advance.

Here is my code ignore all the other not so relevant stuff in it. It does have the code to communicate with the LCD for the thermocouples which works fine its the force part that Ive added thats the issue.

#include <SoftwareSerial.h>
#include <SPI.h>
#include <Adafruit_MAX31855.h>
#define Enable 31
#define dirPin 3
#define stepPin 4
#define DischargePB 46
#define DischargePB2 47
#define stepsPerRevolution 1600

#define MAXDO 30
#define MAXCS 27
#define MAXCLK 28

#define MAXCS2 34
#define MAXDO2 35

#define MAXCS3 38
#define MAXDO3 39

int switchstate1 = 0;
int switchstate2 = 0;
int fsrPin = 5; // the FSR and 10K pulldown are connected to a5
int fsrReading; // the analog reading from the FSR resistor divider
int fsrVoltage; // the analog reading converted to voltage
unsigned long fsrResistance; // The voltage converted to resistance
unsigned long fsrConductance;
int fsrForce; //the resistance converted to force

Adafruit_MAX31855 thermocouple(MAXCLK, MAXCS, MAXDO);// MAXCLK = Turns on the thermocouple amplifier chip MAXCS = Clock cycle all three thermocouple amplifiers, MAXDO = Output voltage from amplifier

Adafruit_MAX31855 thermocouple2(MAXCLK, MAXCS2, MAXDO2);

Adafruit_MAX31855 thermocouple3(MAXCLK, MAXCS3, MAXDO3);

void setup() {
pinMode(Enable, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(DischargePB, INPUT);
pinMode(DischargePB2, INPUT);

while (!Serial); // wait for Serial on Leonardo/Zero, etc

Serial.begin(9600);
}

void loop() {

switchstate1 = digitalRead(DischargePB);
switchstate2 = digitalRead(DischargePB2);

double temperature = thermocouple.readCelsius();
if (isnan(temperature)) {
Serial.println("Something wrong with thermocouple!"); // Error check checks to see if a wire has disconnected from the terminal block
} else {
String command = "temperature.txt=""+String(temperature,1 )+"""; // This is the code used to store the temperature and send to the display
Serial.print(command);
endNextionCommand();
}

double temperature2 = thermocouple2.readCelsius();
if (isnan(temperature2)) {
Serial.println("Something wrong with thermocouple!"); // Error check checks to see if a wire has disconnected from the terminal block
} else {
String command = "temperature2.txt=""+String(temperature2,1 )+"""; // This is the code used to store the temperature and send to the display
Serial.print(command);
endNextionCommand();
}

double temperature3 = thermocouple3.readCelsius();
if (isnan(temperature3)) {
Serial.println("Something wrong with thermocouple!"); // Error check checks to see if a wire has disconnected from the terminal block
} else {
String command = "temperature3.txt=""+String(temperature3,1 )+"""; // This is the code used to store the temperature and send to the display
Serial.print(command);
endNextionCommand();
}

fsrReading = analogRead(fsrPin);
Serial.print("Analog reading = ");
Serial.println(fsrReading);

// analog voltage reading ranges from about 0 to 1023 which maps to 0V to 5V (= 5000mV)
fsrVoltage = map(fsrReading, 0, 1023, 0, 5000);
Serial.print("Voltage reading in mV = ");
Serial.println(fsrVoltage);

fsrResistance = 5000 - fsrVoltage; // fsrVoltage is in millivolts so 5V = 5000mV
fsrResistance *= 10000; // 10K resistor
fsrResistance /= fsrVoltage;
Serial.print("FSR resistance in ohms = ");
Serial.println(fsrResistance);

fsrConductance = 1000000; // we measure in micromhos
fsrConductance /= fsrResistance;
Serial.print("Conductance in microMhos: ");
Serial.println(fsrConductance);

// Use the two FSR guide graphs to approximate the force
if (fsrConductance <= 1000) {
fsrForce = fsrConductance / 80;
Serial.print("force.val=");
Serial.print(fsrForce);
endNextionCommand();
}
else {
fsrForce = fsrConductance - 1000;
fsrForce /= 30;
Serial.print("force.val=");
Serial.print(fsrForce);
endNextionCommand();
}

digitalWrite (Enable, HIGH);

if (switchstate1 == LOW and switchstate2 == LOW)
{
subroutine1();
}
}

void endNextionCommand() // Subroutine used to send the data to the Nextion screen
{ delay(250);
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
}

void subroutine1(){
digitalWrite(Enable, LOW);
digitalWrite(dirPin, HIGH);
for (int i = 0; i < 0.58 * stepsPerRevolution; i++) {

digitalWrite(stepPin, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin, LOW);
delayMicroseconds(500);
}
delay(1000);

digitalWrite(dirPin, LOW);

for (int i = 0; i < 0.58 * stepsPerRevolution; i++) {

digitalWrite(stepPin, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin, LOW);
delayMicroseconds(500);
}
delay(1000);
} //dirPin HIGH = CW dirPin LOW = CCW

Hello Babycobh1,
Did you forget how to post code properly, in code tags?

URGENT

Did you forget that we are volunteers helping when we can and want to help? If your request is urgent please post in gigs and collaborations and indicate how much you are willing to pay. Putting URGENT here just annoys people and puts them off replying. Last night when I first saw your post I thought the only thing that's urgent is that I was tired and wanted to go to bed.

     while (!Serial); // wait for Serial on Leonardo/Zero, etc
     Serial.begin(9600);

What would be the point of waiting for the serial port before you have initialised it?

  { delay(250);
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff);
  }

What is the point of this delay? It does nothing other than stop anything from happening for a quarter of a second.

      String command = "temperature2.txt=\""+String(temperature2,1 )+"\""; // This is the code used to store the temperature and send to the display
      Serial.print(command);

There's no reason to concatenate everything into one String before sending to the Nextion, just print each part separately. For some reason you've done this in other places, but not here, why the difference?

Some of your prints are missing bits, compare the ones that work to the ones that don't. Also, read my tutorial using Nextion displays with Ardunio and apply what you learn to your project.

Sorry about that Perry I haven't used the forum very often. So I looked at your feedback and altered the code to just use the force sensors and nothing else. Even when doing this the value on the Nextion is still zero. So I dont think that the string that I am using for the temperature sensors is the problem. I think that I am sending the Analog value correctly by storing it in force.val. Since the number variable on the Screen is called force. I also viewed your previous posts about the Nextion.

Here is the simplified code and some images of what happened when I uploaded it. The three errors in the one photo are because I am not sending any temperature info to the Nextion.

Thank you for your help.

    int fsrPin = 5;     // the FSR and 10K pulldown are connected to a5
    int fsrReading;     // the analog reading from the FSR resistor divider
    int fsrVoltage;     // the analog reading converted to voltage
    unsigned long fsrResistance;  // The voltage converted to resistance, can be very big so make "long"
    unsigned long fsrConductance; 
    int fsrForce;       // Finally, the resistance converted to force
     
    void setup(void) {
      Serial.begin(9600);   
    }
     
    void loop(void) {
      
      fsrReading = analogRead(fsrPin);  
      Serial.print("Analog reading = ");
      Serial.println(fsrReading);
     
      // analog voltage reading ranges from about 0 to 1023 which maps to 0V to 5V (= 5000mV)
      fsrVoltage = map(fsrReading, 0, 1023, 0, 5000);
      Serial.print("Voltage reading in mV = ");
      Serial.println(fsrVoltage);  
        
        
        fsrResistance = 5000 - fsrVoltage;     // fsrVoltage is in millivolts so 5V = 5000mV
        fsrResistance *= 10000;                // 10K resistor
        fsrResistance /= fsrVoltage;
        Serial.print("FSR resistance in ohms = ");
        Serial.println(fsrResistance);
     
        fsrConductance = 1000000;           //  micromhos
        fsrConductance /= fsrResistance;
        Serial.print("Conductance in microMhos: ");
        Serial.println(fsrConductance);
     
        // Use the two FSR guide graphs to approximate the force
        if (fsrConductance <= 1000) {
          fsrForce = fsrConductance / 80;          
          Serial.print("force.val=");
          Serial.print(fsrForce);         
          endNextionCommand();         
          }
         else {
          fsrForce = fsrConductance - 1000;
          fsrForce /= 30;          
          Serial.print("force.val=");
          Serial.print(fsrForce);         
          endNextionCommand();       
        }
    }

   void endNextionCommand() // Subroutine used to send the data to the Nextion screen
  { 
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff); 
  }

Right, now I can read your code I've had a closer look.

Am I to understand that on the display you have a number box with objname = force, is that correct?

Your variable:

 int fsrForce;

Is an integer, but you have

fsrForce = fsrConductance / 80;

I don't know what range of values that produces but I am going to assume that it could be a decimal fraction, which will get rounded, possibly to 0. fsrForce should be a float.

Don't bother with number boxes to display numbers, use a text box. So, assuming you replace your number box with a text box with objname = force then this should work:

void HMI_display_force(float force) {
 Serial.print(F("force.txt=\""));
 Serial.print(force);
 Serial.print(F("\""));
 Serial.write(0xff);
 Serial.write(0xff);
 Serial.write(0xff);
}

Once you do it like that it becomes easy to add some text, for example:

void HMI_display_force(float force) {
 Serial.print(F("force.txt=\""));
 Serial.print(F("Force = "));
 Serial.print(force);
 Serial.print(F("\""));
 Serial.write(0xff);
 Serial.write(0xff);
 Serial.write(0xff);
}

Your code would be a lot easier to read, understand and debug if it were not all in loop() but split into functions, with each function performing a specific task. There's loads of tutorials on here that show how to do that, not least my own. It is very obvious that you have not studied my tutorial, if you want any more help then your next question will have to show evidence that you have studied it and are still getting stuck.

Enjoy.

So I know what you mean by make multiple functions. I was taught to make subroutines for complex functions that will be repeated constantly. I tried your code then made my own using the same code that I used before for the temperature sensors.

But of course that results in zero no matter what as well. I also tried yours word for word. I had yours set up so that whenever the if statement is entered the result is sent to HMI_display_force(); the same happens in the else statement depending on how much force is applied. Still get zero. I also changed from a number to a TEXT variable.

I dont understand what I am doing wrong I have gotten three thermopcouples to work without an issue with a string and this has now become a huge problem for some reason.

Trying to make a subroutine with HMI_display_force(float force) would not compile so what I did was call it

HMI_display_force();
float force;

I only changed it there would not display on the display but the serial monitor showed it being stored in force.txt.

    int fsrPin = 5;     // the FSR and 10K pulldown are connected to a5

    int fsrReading;     // the analog reading from the FSR resistor divider

    int fsrVoltage;     // the analog reading converted to voltage

    unsigned long fsrResistance;  

    unsigned long fsrConductance; 

    float fsrForce;       // Finally, the resistance converted to force
  
    void setup(void) 
    {
    Serial.begin(9600);   
    }
     
    void loop() {
      
      fsrReading = analogRead(fsrPin);  
      Serial.print("Analog reading = ");
      Serial.println(fsrReading);
     
      fsrVoltage = map(fsrReading, 0, 1023, 0, 5000);
              
      fsrResistance = 5000 - fsrVoltage;  // fsrVoltage is in millivolts so 5V = 5000mV
      fsrResistance *= 10000;             // 10K resistor
      fsrResistance /= fsrVoltage;
   
      fsrConductance = 1000000;           //  micromhos
      fsrConductance /= fsrResistance;
        
                                          // Use the two FSR guide graphs to approximate the force
        if (fsrConductance <= 1000) 
          {
          fsrForce = fsrConductance / 80;          
          HMI_display_force();         
          }
         else 
         {
          fsrForce = fsrConductance - 1000;
          fsrForce /= 30;          
          HMI_display_force();                        
         }
    }

    void HMI_display_force(){
     double force = fsrForce;
     String command = "force.txt=\""+String(force,1 )+"\"";
     Serial.print(command);
     Serial.write(0xff);
     Serial.write(0xff);
     Serial.write(0xff);
}

I was taught to make subroutines for complex functions that will be repeated constantly.

That's one reason, another is to make the code easier to follow as you give each different task it's own function*.

What do you think is the point of this:

     double force = fsrForce;

How have you got your Nextion connected? A Maga has 3 spare serial ports, your code suggests you have it connected serial port 0, the one used by the serial monitor.

I've given you enough pointers to work with. If you ask for more advice and it is clear that you are trying to use functions and that you are trying to make sense of my tutorial then I'll try to help, otherwise I won't.

*'subroutine' is so 1980's Star Trek, as well as not meaning the same thing, they are called functions.

Right, I've gone through your code line by line and added Serial.print at every point where you do some maths. Try this:

int fsrPin = 5;     // the FSR and 10K pulldown are connected to a5

int fsrReading;     // the analog reading from the FSR resistor divider

int fsrVoltage;     // the analog reading converted to voltage

unsigned long fsrResistance;

unsigned long fsrConductance;

float fsrForce;       // Finally, the resistance converted to force

void setup(void)
{
  Serial.begin(9600);
}

void loop() {
  delay(1000);                              // PB added to slow it down a bit (I hate using delay!!!)
  Serial.println(" ");                      //PB start on a new line


  fsrReading = analogRead(fsrPin);
  Serial.print("Analog reading = ");
  Serial.println(fsrReading);             // PB This works OK (range 0 to 743, limited by how I wired it up)
  Serial.println(" ");

  fsrVoltage = map(fsrReading, 0, 1023, 0, 5000);
  Serial.print("FSR reading = ");
  Serial.println(fsrVoltage);           // PB This works OK (range 0 to 3631, limited by how I wired it up)
  Serial.println(" ");

  fsrResistance = 5000 - fsrVoltage;  // fsrVoltage is in millivolts so 5V = 5000mV
  Serial.print("FSR resistance = ");
  Serial.println(fsrResistance);           // PB This works OK (range 5000 to 742, limited by how I wired it up)
  Serial.println(" ");

  fsrResistance *= 10000;             // 10K resistor
  Serial.print("FSR resistance*10000 = ");
  Serial.println(fsrResistance);           // PB 10000* 5000 = 500000000(range printed 50000000 to 13690000, more digits that Serial.print can handle)
  Serial.println(" ");

  fsrResistance /= fsrVoltage;
  Serial.print("FSR resistance*10000 / fsrVoltage = ");
  Serial.println(fsrResistance);           // PB range 4294967295 to 3751
  Serial.println(" ");

  fsrConductance = 1000000;           //  micromhos
  fsrConductance /= fsrResistance;
  Serial.print("fsrConductance = ");
  Serial.println(fsrConductance);           // PB range 0 to 266 (no idea if this is what you were expecting)
  Serial.println(" ");

  if (fsrConductance <= 1000)            // From the above this is always true
  {
    fsrForce = fsrConductance / 80;
    Serial.print("fsrForce = ");
    Serial.println(fsrForce);           // PB range 0.00 to 3.00 (no idea if this is what you were expecting)
    Serial.println(" ");


    HMI_display_force();
  }
  else
  {
    fsrForce = fsrConductance - 1000;
    fsrForce /= 30;
    HMI_display_force();
  }
}

void HMI_display_force() {
  float force = fsrForce;                                    // What is the point of this?
  String command = "force.txt=\"" + String(force, 1 ) + "\""; // Prints in the range force.txt="0.0"⸮⸮⸮ to force.txt="3.0"⸮⸮⸮
  Serial.print(command);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
}

You need to connect your Nextion to a different serial port, not the one the serial monitor uses then modify your code accordingly.