ADC measurement

Hello,

I'm using an MQ sensor and i want to measure the output voltage and use it to calculate resistance.

i use this code :

float ADC_measure (int adc_m)
{
  return ((float) (ADCH / 256.0 * VCC)); //convert to voltage 
}

thank you for reply.

Some more detail, like your whole program, would help.

UKHeliBob:
Some more detail, like your whole program, would help.

As well as a description of the problem you are having, or an actual question that can be answered.

Well to biguine with, if you are using the analogue input of the Arduino, this:

  return ((float) (ADCH / 256.0 * VCC)); //convert to voltage

Should be that:

  return ((float) (ADCH / 1024.0 * VCC)); //convert to voltage

Cause it's base on 10 bits not 8

And as they say, seeing the whole code could help

Frédéric_Plante:
Should be that:

Almost...

return ((float) (ADC / 1024.0 * VCC)); //convert to voltage

Well I almost found the answer with almost nothing :wink:

Is ADC a variable, a function, we got nothing to verify but one thing is for sure there are 1024 level of potentiel différence and not 256 on the analog port of the Arduino. :slight_smile:

See Coding Badly you are much more fun and positive then the other guy as Admin. And that make the difference.

there are 1024 level of current

{ cough } voltage {cough }

Is ADC a variable, a function,

Neither; usually it's a macro.

thanks for reply,

i'm using mq3 sensor, and i want to calculate the voltage of the sensor output in order to calculate the Sensor resistance for my alcohol online sensor.

this is my code :

include "arduino.h"
#include <LiquidCrystal.h>


#define RO_CLEAN_AIR_FACTOR 50.0  //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO,//which is derived from the chart in datasheet
#define VCC 4.86
#define Rl 1000 // Load resistance 1 kohm



using namespace std;

float concentration(float x) {
  const float A[] = { 
    2.71494E+02, -3.10999E+02, 6.85051E+02, -3.47587E+02, 7.47499E+01            }; 
  float result;
  float B[4];
  B[0] = x*x;
  B[1] = B[0]*x;  
  B[2] = B[1]*x;
  B[3] = B[2]*x;

  result = A[0]*x+A[1]*B[0]+A[2]*B[1]+A[3]*B[2]+A[4]*B[3];
  return result;
}

char messages[5][16] = {
  "Heating sensor", "64 seconds", "Autozero", "Ready!", "ppm"};

int Ledalert=7;
float x;
float y;
float x0[5]={0};
float x_initial;


LiquidCrystal lcd(12, 11,5, 4, 3, 2); // Wiring microcontroller - LCD:

const int pushbutton = 8; // Pushbutton (normally open). Stops initial heating time when it is pressed. .
const int MQ3_analogPin = A0; // Reads sensor voltage.


void text_screen( char messages[],  int colum, int row) {
  lcd.setCursor( colum, row);
  lcd.print(messages);
}



void setup() {
  
  pinMode(Ledalert, OUTPUT);
  lcd.begin(16,2);
  Serial.begin(9600);
  
  lcd.clear(); 
  text_screen(messages[0], 0, 0);
  text_screen(messages[1], 0, 1);
  delay(2000);
  Serial.print("Heating ...");
  Serial.print("   ");
  Serial.print("  \n");
 
  for (int j = 0; j<4; j++)
  {
    lcd.clear();  // Heating sensor 4x16 = 64 seconds
    text_screen(messages[0], 0, 0);


    for (int i = 0; i<16; i++){  
      if (pushbutton == 1){   // Pressing pushbutton stops initial heating and enters in measuring mode.
        break;
      }

      lcd.setCursor(i, 1);
      lcd.write(62);
      delay(1000);
    }
  }


  lcd.clear();
  text_screen(messages[2], 0, 0);
  delay(1000);

   
   for (int i=0; i<5; i++)
  {
    
  x0[i]= analogRead(MQ3_analogPin);
  
   Serial.print(x0[i]);
   Serial.print("\n");
   delay(2000);

  }
 
 x_initial = (x0[0]+x0[1]+x0[2]+x0[3]+x0[4])/5; // Autozero. Average of 5 initial measures.

Serial.print("x_initial= ");
Serial.print(x_initial);
Serial.print("   ");
Serial.print("\n");

  lcd.clear();
  text_screen(messages[3], 0, 0);
  delay(2000);

  
}

void loop()  {
  
x = analogRead(MQ3_analogPin);

y =  ADC_measure (analogRead(MQ3_analogPin));

 
 Serial.print ("ADC= ");
 Serial.print (y);
 Serial.print("\n");
  Serial.print("analogRead = ");
  Serial.print(x);
  Serial.print("   ");
  Serial.print("\n");
  
x = (x-x_initial)*4.9; // Calculate real voltage. 
 
//Serial.print("x-x_initial= ");
//Serial.println(x);
//Serial.print("   ");


if(x<0.0)
x= 0.0;

Serial.print("x-x_initial= ");
Serial.println(x);
Serial.print("   ");
Serial.print("\n");


delayMicroseconds(100);



if (x < 0.30){
     digitalWrite(Ledalert, HIGH);
    }

    else {
      digitalWrite(Ledalert, LOW);
    }
float x1;
x = concentration(x/100000.0);

Serial.print("concentration de x = "); 
Serial.print(x);
Serial.print("   ");
Serial.print("\n");

float val = 0.0;
  for (int i = 0; i<32; i++){ 
  
    val += concentration (x);
    delay(32);
    
    val = val/ 32;
    val = val/RO_CLEAN_AIR_FACTOR; 
  }
Serial.print("val= ");
Serial.print(val);
Serial.print("  ");
Serial.print("\n");

  // Float to string conversion.
char buffer[16];      // you need some space 

dtostrf(val,16,2, buffer);

  
  lcd.clear();

  for (int i=0; i<strlen(buffer); i+=1)
 {
   
   lcd.setCursor(i,1);
   lcd.write(buffer[i]);  
   
   text_screen(messages[4], 10, 0); 
    
 }
  
  delay(1000);
  
}

float ADC_measure (int adc_m)
{
  return ((float) (ADCH / 256.0 * VCC)); //convert to voltage 
}

i need help to finish my code and than convert response to a percent of alcohol (%)

Thanks

Frédéric_Plante:
Is ADC a variable, a function...

It's a macro provided by AVR Libc that reduces to an I/O register access. AVR Libc provides macros for all the AVR I/O registers and all the I/O register bits. The macros allow manipulating the hardware (liking reading the ADC register pair) with the simplicity of manipulating a variable.

...we got nothing to verify...

The datasheet for the processor includes example snippets of code.

See Coding Badly you are much more fun and positive then the other guy as Admin. And that make the difference.

Don't pick on AWOL. He's a fun and positive guy, too. In his own way.

thanks Coding Badly for reply

it's ok.

float ADC_measure (int adc_m)
{
  return ((float) (ADCH / 256.0 * VCC)); //convert to voltage 
}

The parameter (adc_m) has the analog-to-digital converter reading but you don't use it. Instead you are re-reading the high byte of the value. Doing that is not very useful and I doubt it's what you want.

thanks Coding Badly for reply,

i need to return the value of the voltage i use the code :

float ADC_measure (int adc_m)
{
  return ((float) (ADC / 1024.0 * VCC)); //convert to voltage 
}

i can repleace int adc_m by a new variable like float ADC_measure (int voltage)

i can repleace int adc_m by a new variable like float ADC_measure (int voltage)

But the argument isn't used in the function, so supplying it is completely pointless.

ok,

what's the right way for to write the function ???

thanks

One way would be

float ADC_measure (int adc_reading)
{
  return  ((float) adc_reading * (float) VCC) / 1024.0;
}

Ok,

Thanks for advice,

i recall the function using the code :

y =  ADC_measure (analogRead(MQ3_analogPin));

it's true ????

thanks

i recall the function using the code :
Code:

y = ADC_measure (analogRead(MQ3_analogPin));

it's true ????

I don't know - it's your recollection.

Thanks for reply,

for the adc_measurement it's ok i receive the voltage.

just i have to convert using the mq3 chart the concnetration to % of alcohol

thanks for help

oui