Go Down

Topic: Attiny85 - Method to discart glitched ADC values? (Read 197 times) previous topic - next topic

St0RM53

Hello. I have a problem i need to solve so i will simply it as much as possible.

Basically there is a system with a micro-controller where it reads 2 sensors. These 2 sensors are of variable resistance type, aka their measuring value is output as different resistance. For example one is a pressure sensor where at 0psi the sensor has a value of 20ohms to ground, and for 100psi it has a value of 120ohms. The sensor is connected between ground and a fixed value resistor so the output acts like a voltage divider.

The micro-controller seems to be multiplexing by switching pull up between each 2 sensors (probably because using a single ADC), at random times (as the microcontroller performs other functions) but approx. every 80ms for each sensor, and about 40ms between each sensor. So at 0ms it reads one sensor, at 40ms the other sensor, and at 80ms back at the first sensor and so on. I have no idea why they haven't used a fixed pull-up, but the pull-up is only done when the controller wants to read the sensor for only about 120us.

I wanted to read these sensors to input to an ECU, without affecting the original device. Thus the easiest solution i could think off as the pull-up isn't always high to perform a read, was to add another microcontroller (in my case a Digispark based on the ATtiny85 running at 16.5MHZ). Alternatively i could open up the device and modify it to use a fixed pull-up but let's say i want to avoid this route. The digispark essentially reads both sensor outputs and when it sees a voltage above ground it outputs it to the ECU. I have since then updated the program to check the ADC values it reads so that it is between the nominal range of the sensor. And while this works there are times where the ADC will read a wrong value and output it to the ECU which looks as random spikes and dips in the data.

Look at my following code:
Code: [Select]

      const int oil_in = 0; //P5
      const int temp_in = 1; //P2
      const int oil_out = 1; //P1
      const int temp_out = 4; //P4
      int oil_value = 0;
      int oil_value_good = 0;
      int temp_value = 0;
      int temp_value_good = 0;
     
    // the setup routine runs once when you press reset:
    void setup() {               
      // initialize the digital pin as an output.
      pinMode(oil_out, OUTPUT);
      pinMode(temp_out, OUTPUT);
    }
   
    // the loop routine runs over and over again forever:
    void loop() {
      oil_value = analogRead(oil_in);
      if (oil_value > 106 && oil_value < 466)
      {
        oil_value_good=oil_value;
        analogWrite (oil_out, oil_value_good/4);
      }
   
        temp_value = analogRead(temp_in);
      if (temp_value > 113 && temp_value < 920)
     {
        temp_value_good=temp_value;
        analogWrite (temp_out, temp_value_good/4);
      }
    }


Each ADC pin has a range of acceptable values. These correspond to the MIN AND MAX nominal values for each sensor. However there are times where the ADC will read at the wrong time and it will output either a MIN or a MAX value depending on the condition. I can replicate this on the breadboard by having the input to the ADC reading a nominal value, and by shorting it to either ground or VCC (5V) i can sometimes trick the ADC to read a MIN or MAX value. And since the next measurement will be done after some time, the output will produce these spikes. Since there is no sync between the readings these error data can be sometimes be outputed for 1-1.5s.

I've tried thinking hard about this problem, but i am not sure for a certain solution that will eliminate this problem. ADC interrupts, changing ADC pre-scaler, filtering of data, problem the reading window is really small (100-120us).

Also nominal ADC input values for each sensors are between 0.56V-2.33V for one sensor, and 0.6V-4.68V for the other sensor. Not sure if the interrupt can even be activated at such low voltage.

How do you think i should proceed?

Kind regards

DrAzzy

temp_in and oil_out are the same pin...

What do you expect to happen when you're outputting pwm on the analog pin you are trying to read?
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

St0RM53

temp_in and oil_out are the same pin...

What do you expect to happen when you're outputting pwm on the analog pin you are trying to read?
It's not the same pin, when in analogread pin 1 corresponds to pin2 in digispark

DrAzzy

#3
Aug 10, 2017, 08:43 pm Last Edit: Aug 10, 2017, 08:43 pm by DrAzzy
So it's not a normal attiny85, but a digispark one? Okay...

That's not one of the pins used for USB or anything is it?
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

Smajdalf

Maybe you could use internal Analog Comparator to detect when pull-up is turned on and start (after a small delay) ADC measuring? This way you should get nearly fixed delay from pull-up turn on and ADC sampling. I think your glitches come from ADC sampling to soon after pull up turn on or soon after turn off.
On 8-bit (i.e. Uno) use "byte" instead of "int" if possible - it is faster and saves resources!

Go Up