Random and undefined Serial Output from Gauge

Hi everyone,
I am currently in the process of programming a Aruino Uno to collect data from a Gauge (https://www.idealvac.com/files/brochures/Pfeiffer_Single_Gauge_TPG261.pdf) and printing it on a OLED (SSD1315) as well as checking the position of 2 valves. In the future I want to send the data via ethernet port but I'm not there yet because I am running into a lot of issues regarding the serial communication.

I theory I should get well defined responses from my Gauge depending on the kind of request I'm making. In my code im only asking for the pressure on channel 1 and im expecting to get the status code 5 and a devault value since so sensor is currently connected to my Gauge. The code is right now in a state where I get exactly those results. If I however do minor (seemingly irrelevant) changes like adding or removing a Serial.print() command where I print an arbitrary String or variable, changing what is printed on the display etc. The Output I am getting from the gauge changes into something random and undefined.

For communcation I am currecntly using the RX and Tx pins of my port. In the past I tired using digital ones(10,11) in combination with SoftwareSerial but didnt have any luck with that either.

I would be very grateful if someone can help me find the source of my inconsistent outputs and will gladly elaborate on any not yet specified details.

Here is my Code:

#include <Arduino.h>
#include <U8g2lib.h> 
#include <Wire.h>
#include <SoftwareSerial.h>
#include <ArduinoJson.h>

 
// #ifdef U8X8_HAVE_HW_SPI
// #include <SPI.h>
// #endif
// #ifdef U8X8_HAVE_HW_I2C
// #include <Wire.h>
// #endif
 
// U8G2_SSD1306_128X64_ALT0_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, SCL,SDA); // SSD1306 and SSD1308Z are compatible
 
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);    //Low speed I2C

void setup(void) {

  u8g2.begin();
  Serial.begin(9600);
  u8g2.setFont(u8g2_font_ncenB08_tr);
  pinMode(0,INPUT);
  pinMode(1,OUTPUT);
}
int get_voltage(float *pin0,float *pin1){ //Sets pin0 and pin0 to a value between 1 and 1023 and V0, V1 to the corresponding voltage
  char buffer[10];                                //which is then printed on the display
  float V0, V1;
  *pin0=analogRead(A0);
  *pin1=analogRead(A1);
  V0=*pin0*5/1023;
  V1=*pin1*5/1023;
  dtostrf(V0, 6, 1, buffer);
  u8g2.drawStr(15, 10, buffer);
  dtostrf(V1, 6, 1, buffer);
  u8g2.drawStr(15, 20, buffer);
  
  return 0;
}

int valve_status(float pin0, float pin1){
  if(pin0<1000&&pin1>=1000){  //constellation for valve open
    u8g2.drawStr(55,15,"Valve closed");
  }
  else if(pin0>=1000&&pin1<1000){  //constellation for valve close
    u8g2.drawStr(55,15,"Valve open");
  }
  else{                           //if none of the conditions above are fullfilled the valve poistion is incorrect
    u8g2.drawStr(60,15,"Error!");
  }
  u8g2.sendBuffer();
  return 0;
}

void valve(){                         //Evaluates and outputs the valve position
  float pin0, pin1;
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB08_tr);
  u8g2.drawStr(0,10,"A0:");
  u8g2.drawStr(40,10,"V");
  u8g2.drawStr(0,20,"A1:");
  u8g2.drawStr(40,20,"V");
  u8g2.sendBuffer();
  get_voltage(&pin0, &pin1);
  valve_status(pin0, pin1);
}

void send_command(){
Serial.write("PR1");  // send command to request pressure reading
Serial.write(char(13));
Serial.write(char(10));
delay(1000);  // wait for response
Serial.write(char(5));
}

String get_data(){
  String data;
  int i=0;
  if (Serial.available()) {
    while (Serial.available()) {  // if data is available on the serial port
      data=Serial.readStringUntil(char(13));
      Serial.print(data);
      
       i++;
        if(i>30){
          Serial.print("Too much output\n");
          return "NULL";
        }
    }
  }
  else{
    Serial.print("No Data\n");
    u8g2.drawStr(85,35,"No data");
    u8g2.sendBuffer(); 
    }
  return data;
}

int display_data(const String& data){
  int status=data[1];
  u8g2.drawStr(0,35,"Status:");
  u8g2.sendBuffer();
  switch (status) {
    case 48:
      u8g2.drawStr(55, 35, "Measurement data okay");
      u8g2.drawStr(0, 50, "Pressure");
      u8g2.sendBuffer();
      Serial.print("Measurement data okay");
      for(int j=4;j<14;j++){
        char charac=char(data[j]);
        u8g2.setCursor(55+(j-4)*6, 50);
        u8g2.print(charac);
      }
      u8g2.sendBuffer();
      break;
    case 49:
      u8g2.drawStr(55, 35, "Underrange");
      u8g2.sendBuffer();
      break;
  case 50:
      u8g2.drawStr(55, 35, "Overrrange");
      u8g2.sendBuffer();
      break;
  case 51:
      u8g2.drawStr(55, 35, "Underrange");
      u8g2.sendBuffer();
  break;
    case 52:
      u8g2.drawStr(55, 35, "Sensor off");
      u8g2.sendBuffer();
      break;
    case 53:                            //53=5 in ascii
      u8g2.drawStr(55, 35, "No sensor");
      u8g2.drawStr(0, 50, "Pressure");
      u8g2.sendBuffer();
      for(int j=4;j<14;j++){
        char charac=char(data[j]);
        u8g2.setCursor(55+(j-4)*6, 50);
        u8g2.print(charac);
      }
      u8g2.sendBuffer();
      break;
    case 54:
      u8g2.drawStr(55, 35, "Identification error");
      u8g2.sendBuffer();
      break;
  }
  return 0;
}

float get_pressure(const String& data){   //trying to read the pressure encoded in the String data into a float--
  float p;                                //printing the float p changes the read from the gauge into something invalid
  for(int j=4;j<10;j++){                  //correct response contains NAK ACK and then the data String(5, 2.0000E-02)
    Serial.print(data);                   //printing p changes the response to alternate between AcK ACK and NAK 0001
    if(j==4){                             //even though data is given to this fuction as const String it is deleted/becomes empty    
      p+=char(data[j])-'0';               //after the first iteration of the loop
      //Serial.print(p);
    }
    else if(j>5){
        Serial.print(data);
        char charac=char(data[j]);
        p+=(charac-'0')*pow(10,j-5);
    }
  return p;
  }
}

int write_json_data(float V0, float V1){
  StaticJsonDocument<200> doc;
  JsonArray voltages = doc.createNestedArray("Voltages");
  voltages.add(V0);
  voltages.add(V1);
  //doc["Status"] = data[1];
  doc["pressure"] = 1351824120;
  serializeJson(doc, Serial);
  return 0;
}

void loop(){
  String data;
  float V0,V1;
  V0=analogRead(A0)/1023;
  V1=analogRead(A1)/1023;
  u8g2.clearBuffer();
  valve();  
  send_command(); 
  data=get_data();  
  display_data(data);  
  float press=get_pressure(data);
  //Serial.print(press);
  write_json_data(V0,V1);    
  delay(2000);
  u8g2.clearBuffer();
}

analogRead returns an int, not a float.

sp. "1024".
Are you certain that the reference voltage is 5V?

Welcome to the forum

The PDF that you linked to seems to indicate the the serial interface of the gauge uses an RS232 interface

Are you using anything to convert the RS232 level signals from the gauge to the TTL level signals that the Uno uses ? Note too that pins 0 and 1 of the Uno are used by the hardware Serial interface with the PC

A schematic of your project would show how the two are connected

Yes I forgot to mention I am using a RS232 to TTL converter.
Is it in general advisable to not use pins 0 and 1 for serial communication because for communication with the PC?

The best advice that I can give is simply not to use pins 0 and 1 of the Uno dies to their use by the hardware Serial interface

If you do want to use the serial pins that way, you have to give up comms with the USB, and it's also best to omit the bootloader and program the board via the ICSP. Or, get yourself a board that has multiple hardware serial ports.

I really thought this thread was going to be about Radon gas.

I´ve modified the head line.

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