Arduino Forum

Using Arduino => Displays => Topic started by: MaxTheDog73 on Jul 09, 2019, 04:49 pm

Title: OLED affecting analogue reading
Post by: MaxTheDog73 on Jul 09, 2019, 04:49 pm
I am reading the adc value from a temperature circuit I made. This value (0-1024) is converted into degrees. This works perfectly fine when the OLED isn't powered. Here the values hardly change. When I plug the OLED in, it varies between 608 and 616. This isn't good enough as that means the temperature varies by about 4 degrees. Is there anything I can do about this other than splice a USB cable to get the power lines and power the OLED separately?
Title: Re: OLED affecting analogue reading
Post by: septillion on Jul 09, 2019, 05:06 pm
Last probably isn't helping. Probably the supply voltage really is varying a bit. What is that "temperature circuit" you made? Can it be adjusted to output 1V1 max instead of 5V? If so, you can use the internal reference.
Title: Re: OLED affecting analogue reading
Post by: MaxTheDog73 on Jul 09, 2019, 05:32 pm
Circuit diagram attached. Its a LM355 based circuit. The voltage range when I plug the OLED in is around 40mv. This variation only occurs when the OLED is powered by the arduino (on both 3.3 and 5v rails). I have powered the display by an external power supply but that isn't available to me at home.

Last probably isn't helping.
What do you mean by this?

1V1 max
Also what does this mean?
Title: Re: OLED affecting analogue reading
Post by: septillion on Jul 10, 2019, 12:18 pm

1V1 is "shorthand" for 1,1V (or 1.1V for Americans). Just like you can write 4k7 for a 4,7kΩ = 4700Ω resistor.

The ADC is by default (on standard Arduino's) referenced at Vcc. If Vcc varies the ADC readings of a steady voltage will as well. When using a pot to Vcc as well this isn't a problem. Because the pot output (wiper) will vary the same amount (relative) as Vcc so it all compensates.

But you have a fixed (with fixed temperature) voltage. So or you need to keep Vcc steady (use a beter power supply or regulator, no idea what's powering the Arduino atm). Or switch the ADC to a more stable reference. And default Arduino's come with a 1V1 (aka 1,1V) reference which will not vary with Vcc (although isn't very precise aka you need to calibrate). But this means your input voltage may not be higher then 1V1 (anything more will just read full scale aka 1023). And because a LM335 is around the 3V mark at room temperature you need to scale that back.

You can use a voltage divider for that but in order to not load the circuit it has to be 1 or 2 order of magnitude higher impedance. I would go for the 100k range but the exact values depend on your desired temperature range. But this gives a bit of trouble with the ADC which expects <10k impedance. To compensate you can add a small (like 100nF) capacitor after the voltage divider.
Title: Re: OLED affecting analogue reading
Post by: david_prentice on Jul 10, 2019, 12:54 pm
Since the LM335 output is about 3V at room temperature it would seem wise to use AVCC as reference.
You are probably using USB cable to power your project i.e. 5V

You can measure the actual AVCC voltage by using the internal voltage reference.    It will vary slightly from PC to PC.

It is very unlikely that the OLED will affect the AVCC voltage.
But at least you can measure it with the AVR.

Please draw your schematic.    Pencil on paper is fine.   Post a photo.
Please post the full sketch you are using.    Either paste to the message or attach as a file.

Title: Re: OLED affecting analogue reading
Post by: MaxTheDog73 on Jul 11, 2019, 03:28 pm
Code: [Select]
int ReadTemp = 0;

#include "AXE133Y.h"
#define oledPin 7
AXE133Y OLED = AXE133Y(oledPin);

void setup() {
  pinMode(ReadTemp, INPUT);
int average = 1;
float temperatureavg1;
float temperatureavg2;
float temperatureavg3;
float temperatureavg4;
float temperatureavg5;
float temperatureavg;
void loop () {
  int rawadc = analogRead(ReadTemp);    //reads from the circuit
  float voltage = rawadc * 5;           // * supply voltage, divides by max reading
  voltage = voltage / 1024;

  float temperature = voltage * 100 - 273; //*100 gets it to kelvin, -273 gets to celsius

  if (average == 1) {         //Creates a time series average for the output. Reduces the effect of the OLED.
    temperatureavg1 = temperature;      //However this is probably not the most effiecient way of coding this - not sure how to make it better
  if (average == 2) {
    temperatureavg2 = temperature;
  if (average == 3) {
    temperatureavg3 = temperature;
  if (average == 4) {
    temperatureavg4 = temperature;
  if (average == 5) {
    temperatureavg5 = temperature;
  temperatureavg = (temperatureavg1 + temperatureavg2 + temperatureavg3 + temperatureavg4 + temperatureavg5) / 5;

  average++;            //Resets on 6
  if (average == 6) {
    average = 1;
  //Serial write
  Serial.print(voltage);    //voltage
  Serial.print("V ");
  Serial.print(rawadc);   //raw adc value
  Serial.print(temperature);     //temperature
  Serial.print(" degrees");
  Serial.print(temperatureavg);  //average temperature

  OLED.cursorHome(1);               //and the same to the OLED
  OLED.printFloat(voltage, 3, 2);
  OLED.print("V ");
  OLED.printFloat(rawadc, 4, 0);
  OLED.print("           ");
  OLED.printFloat(temperature, 3, 1);
  OLED.print(" degrees");
  //  OLED.print(temperatureavg, 3, 1);

That makes sense about the 1v1 thing. I have seen it before but only ever on zener diodes.
I couldn't get any code to work to read the avcc voltage.
I have implemented a time series average to steady the figure somewhat, but it isn't particularly effiecient, especially for using more values like 10 or 20. With the average and reducing the multiplier on the analogue in to 4.96 instead of 5 seems to work fairly well when the LCD is plugged in. However I would like to make the average use more values.

Image of the circuit is attached.