Sensor reading changes with added separate code

I'm trying to make a control board for a HPA compressor that reads multiple points of data and logs them. Currently I have temperature and pressure. I'm using an actual Arduino UNO r3 currently. I've tried the Elegoo Mega2560 r3.

I've got three different temperature sensors, a DHT11, a "MAX6675" probe, and the stock thermistor for the compressor. I have the code collected from various sources combined and they seem to function accurately.

The pressure transducer is also the stock three wire sensor that is on the unit. I've pulled and modified a few different pieces of code that allow it to read correctly by itself. The sensor output is from .5 volt to 4.5 volt reading with a dc voltmeter. By the numbers, it's either a 0-6000psi or 0-400 bar sensor.

The issue I have is when I run it all together, my AnalogRead raises by 50%. Say, from 100 to 150, 200 to 300, etc. It's keeping the same circuit layout, so that shouldn't be the issue. I've tested it with only USB, only external power supply, and both with nothing affected.

I got no hits asking various forms of this question to Google. I'd like to know if anyone spots the problem without me trying to rewrite and configure everything from the start. Sadly, though, I feel I might as well. I know I'll be adding more and it'll help me with learning my programming.

Please excuse the cludged stuff. I tried to keep each "group" of code labeled and separated so it was easier to find and mess with. My looped pressure stuff has a lot of //notes so I know where it started and what I've tried. The way it is right now makes the output correct...ish. I still need to tune it, but if I know my starting point is wrong, then I should start there.

//  DISPLAY stuff
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); 
//   TEMP AND HUMIDITY SENSOR STUFF
#include <DHT.h>
#include <DHT_U.h>
#define Type DHT11
int sensePin=2;
DHT HT(sensePin,Type);
float humidity;
float tempC;
float tempF;
int setTime=500;
//    THERMISTOR BOARD stuff
#include "max6675.h" // max6675.h file is part of the library that you should download from Robojax.com
int soPin = 4;// SO=Serial Out
int csPin = 5;// CS = chip select CS pin
int sckPin = 6;// SCK = Serial Clock pin
float probeC;
float probeF;
MAX6675 probe(sckPin, csPin, soPin);// create instance object of MAX6675
//    BARE THERMISTOR stuff
// which analog pin to connect
#define THERMISTORPIN A0         
// resistance at 25 degrees C
#define THERMISTORNOMINAL 9900      
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25   
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 5
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR 9940    
int samples[NUMSAMPLES];
//  pressure stuff
#include <Wire.h>
const int analogPin = A1;
float inputP1;
float conversionP1;
float outputP1;

void setup() {
Serial.begin(9600);
HT.begin();
delay(setTime);
//Display
 lcd.init();                      // initialize the lcd 
  lcd.init();
  lcd.backlight();
//  BARE THERMISTOR stuff
analogReference(EXTERNAL);
}
void loop() {
//  Pressure stuff
  inputP1 = analogRead(A1);
  //trial convert
  conversionP1 = ((float)inputP1*(.66));
  outputP1 = ((float)(conversionP1-101)*(6000/819));
  //ORIGINAL
    //outputP1 = ((float)(inputP1-98)*(6000/822));
  //2/3's.  Read 220 and accurate on bare code.  330 on full code.
  //outputP1 = ((float)((inputP1*(2/3))-98)*(6000/822));
  // Divide by 1024 for arduino input - multiply by 6000 as transducer reads 0 to 6000psi Was originally -102 and /818
  //  BARE THERMISTOR stuff
uint8_t i;
  float average;

  // take N samples in a row, with a slight delay
  for (i=0; i< NUMSAMPLES; i++) {
   samples[i] = analogRead(THERMISTORPIN);
   delay(10);
  } 
  // average all the samples out
  average = 0;
  for (i=0; i< NUMSAMPLES; i++) {
     average += samples[i];
  }
  average /= NUMSAMPLES;

  Serial.print("Average analog reading "); 
  Serial.println(average);
  
  // convert the value to resistance
  average = 1023 / average - 1;
  average = SERIESRESISTOR / average;
  Serial.print("Thermistor resistance "); 
  Serial.println(average);
  
  float steinhart;
  steinhart = average / THERMISTORNOMINAL;     // (R/Ro)
  steinhart = log(steinhart);                  // ln(R/Ro)
  steinhart /= BCOEFFICIENT;                   // 1/B * ln(R/Ro)
  steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
  steinhart = 1.0 / steinhart;                 // Invert
  steinhart -= 273.15;                         // convert absolute temp to C

  float steinhartF;
  steinhartF = average / THERMISTORNOMINAL;     // (R/Ro)
  steinhartF = log(steinhartF);                  // ln(R/Ro)
  steinhartF /= BCOEFFICIENT;                   // 1/B * ln(R/Ro)
  steinhartF += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
  steinhartF = 1.0 / steinhartF;                 // Invert
  steinhartF -= 273.15;                         // convert absolute temp to C
  steinhartF *= 1.8;                            // first step to F
  steinhartF +=32;                              //finally F
  
  Serial.print("T-Temperature "); 
  Serial.print(steinhart);
  Serial.print("tC ");
  Serial.print(steinhartF);
  Serial.println("tF");
  //DHT11 stuff
humidity=HT.readHumidity();
tempC=HT.readTemperature();
tempF=HT.readTemperature(true);
probeC=probe.readCelsius();
probeF=probe.readFahrenheit();
Serial.print("D-Temperature ");
Serial.print(tempC);
Serial.print("dC ");
Serial.print(tempF);
Serial.println("dF ");
   Serial.print("P-Temperature "); 
   Serial.print(probe.readCelsius());
   Serial.print("pC ");
   Serial.print(probe.readFahrenheit());
   Serial.println("pF ");
Serial.print("Humidity: ");
Serial.println(humidity);
Serial.print(outputP1);
Serial.println(" PSI");
Serial.print("Sensor reads ");
Serial.println(analogRead(A1));
lcd.clear();
lcd.setCursor(0,0);
lcd.print(outputP1);
lcd.print(" PSI");
lcd.setCursor(16,0);
lcd.print(analogRead(A1));
lcd.setCursor(0,1);
lcd.print(steinhart);
lcd.print("tC ");
lcd.print(steinhartF);
lcd.print("tF ");
//   DHT stuff
lcd.setCursor(0,2);
lcd.print(tempC);
lcd.print("dC ");
lcd.print(tempF);
lcd.print("dF ");
//   THERMISTOR BOARD STUFF
lcd.setCursor(0,3);
lcd.print(probeC);
lcd.print("pC ");
lcd.print(probeF);
lcd.print("pF ");

   delay(2000);
}

If I simply copy/paste the code verbatim, the sensor value, analogRead(A1) reads correctly. The roughly zero output is 101-103 due to noise. In the other code it's 153-156. It also seems more stable and accurate in the separate code, the displayed signal, not the output "PSI".

//  DISPLAY stuff
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); 
//  pressure stuff
#include <Wire.h>
const int analogPin = A1;
float inputP1;
float conversionP1;
float outputP1;
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
//Display
 lcd.init();                      // initialize the lcd 
  lcd.init();
  lcd.backlight();
  //  Pressure stuff
  inputP1 = analogRead(A1);
  //trial convert
  conversionP1 = ((float)inputP1*(.66));
  outputP1 = ((float)(conversionP1-101)*(6000/819));
  //ORIGINAL
    //outputP1 = ((float)(inputP1-98)*(6000/822));
  //2/3's.  Read 220 and accurate on bare code.  330 on full code.
  //outputP1 = ((float)((inputP1*(2/3))-98)*(6000/822));
  // Divide by 1024 for arduino input - multiply by 6000 as transducer reads 0 to 6000psi Was originally -102 and /818
}
void loop() {
  // put your main code here, to run repeatedly:
Serial.print(outputP1);
Serial.println(" PSI");
Serial.print("Sensor reads ");
Serial.println(analogRead(A1));
lcd.clear();
lcd.setCursor(0,0);
lcd.print(outputP1);
lcd.print(" PSI");
lcd.setCursor(16,0);
lcd.print(analogRead(A1));
delay(2000);
}

I've tried multiple analog pins just to make sure some background feature was confusing things. I was hoping I could sus this out myself, but to no avail. I was excited to start this project and make headway and learn things, then I hit this weird curveball.

Why buffer and then sum the readings?
You're not doing a rolling average, so the buffering is pointless; you may as well just sum the readings as you make them

That's an example of where my understanding stops. I wanted more accurate sensor readings for a thermistor and the examples were laid out like that. I copy/pasted it and check it across the other sensors and it seemed fine. I didn't like how much there was and how little of the bones I understood, but since it functioned I left it as is.

I'm wanting to learn to clean up the sensor noise. I know I'll need to on this transducer. My focus shifted from that prospect to this weird analogRead(A1) anomoly.

You seem to have too much code; you initialise the LCD twice, and if you've got a Celsius temperature (steinhart), it's very easy to convert that. (if you really must) to Fahrenheit (steinhartF), without going through all the log and reciprocal stuff.

You may find better operations by doing.

Serial.print("Sensor reads ");
analogRead(A1)); // discard reading
Serial.println(analogRead(A1));

Putting a 103 Ceramic cap into Aref and ground.

That is mixed data type math and does not always do as it seems it should

conversionP1 = ((float)inputP1*(.66));
  outputP1 = ((float)(conversionP1-101.0)*(6000.0/819.0));

is an int.

`inputP1 = float(analogRead(A1));`

makes a float.

Thank you for that. You've convinced me to wipe that code. The original code just output C. I tried converting it straight to Fahrenheit through the 9/5+32, but any way just gave me errors I didn't understand. I do like to have F around since it's what I'm naturally familiar with.

And thank you, Idahowalker. I'll have to get my components out and give that a shot. I've got the stock thermistor circuit ran through A-Ref. I'm really thinking I need a different coding method to use the thermistor. At least one I understand better.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display
const int analogPin = A1;
float inputP1;
float outputP1;
float inputP2;
//Averaging
const int numReadings = 10;
int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
int inputPin = A1;
void setup()
{
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  //Averaging
    // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
}}
void loop()
{
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = analogRead(inputPin);
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }
  // calculate the average:
  average = total / numReadings;
  //manual average pressure
int AverageRead;
    inputP2 = average;
  AverageRead = map(inputP2, 101, 921, 0, 5850);
  AverageRead = constrain(AverageRead, 0, 5850);
int PressureRead;
  inputP1 = analogRead(A1);
  PressureRead = map(inputP1, 101, 921, 0, 5850);
  PressureRead = constrain(PressureRead, 0, 5850);
  //inputP1 = analogRead(A1);
  //outputP1 = ((float)(inputP1-98)*(6000/822));
  // Divide by 1024 for arduino input-multiply by 6000 as transducer reads 0 to 6000psi(4 bar=5801psi) Was originally -102 and /818
  Serial.println(PressureRead);
  Serial.println(analogRead(A1));
  //averaging
    // send it to the computer as ASCII digits
  Serial.println(average);  
lcd.clear();
lcd.setCursor(0,0);
lcd.print(PressureRead);
lcd.print(" PSI");
lcd.setCursor(16,0);
lcd.print(analogRead(A1));
lcd.setCursor(0,2);
lcd.print("Average Read ");
lcd.print(average);
lcd.setCursor(0,3);
lcd.print(AverageRead);
lcd.print(" PSI Average");
  delay (500);
}

This was another "bare pressure" set of code I've used and messed with. Again, in the same circuit it reads the analog signal where I expect it to be.

What does that mean?

They're already zero at that point

This is what I used to get the thermistor reading and circuit diagram.

I currently have the A-Ref and 3.3 volt ran to one leg of the thermistor and reference resistor as the diagram lays out.

And AWOL, that was confusing to me. I didn't know why they included it, but it's there.

The biggest thing I've learned so far is if I don't understand it, it's probably wrong or doesn't need to be there.

You may find that putting Aref to the thermistor is a cause of many of your A:D issues.

All the A:D readings are affected by Aref.

https://www.arduino.cc/en/Reference.AnalogReference

That was it, Idaho. Thank you. I was thinking it was the circuit causing feedback. I didn't know the in code reference would do it. Stripping out all the bare thermistor code now gives me accurate signal readings. Now I need to settle on a conversion code that's most accurate. Then, of course, get a thermistor code that doesn't skew results.

My end goal in this whole project is to automate the pump and record the data in case of failure and to help schedule preventative maintenance.

1 Like

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