Display the value of MQ-3 sensor on SerLCD with Arduino Uno

Hello,

I need some help because my sketch it's not working properly. Maybe i did something wrong and somebody tells me how to fix it. In attachment you will find libraries what I used and pictures with connections.
My sketch:
/*

Breathalyzer with Arduino UNO and Serial LCD from SparkFun
I'm using a MQ-3 sensor
*/

#include <SoftwareSerial.h>
#include "serLCD.h"

// Set pin to the LCD's rxPin
int pin = 1;
int sensorValue;

serLCD lcd(pin);

void setup()
{
Serial.begin(9600);
}

void loop() {

sensorValue = analogRead(A0);
lcd.print("Alcohol is: ");
lcd.print(sensorValue);
delay(2000);

}

Thanks

serLCD.cpp (4.8 KB)

serLCD.h (2.72 KB)

To be more precise

I don't know why dosn't display the "Alcohol is: " to and it's displays only the value of the sensor, multiple times. Maybe I will connect a temp_sensor to and I want to diplay it on the second line but dosn't work. How I do that?
In the end I want to display on SerLCD the biggest readed value in an interval of 3 seconds and to display the temperature from another sensor. On first line: "Alcohol is: " and on the second line "Temperature is: ". Alcohol in mg/L and temperature in Celsius degrees.

Thank You very mouch

PS: sorry for my BAD english

I don't know why dosn't display the "Alcohol is: " to and it's displays only the value of the sensor, multiple times.

If you are able to display anything to the LCD, then you know the LCD is working. Perhaps there is a way to position the cursor so that the second statement doesn't overwrite the first one.

Purhaps, but where I found how sould I do this. If you dont know where maybe you know how ??? :~ Can you help me ?
Thanks

Purhaps, but where I found how sould I do this.

Look in the serKCD.h file, to see what all you can do with the LCD.

I think you should consider whether you have to do something with the integer value that you get from analogRead() before you send it to the LCD.

Hint: The LCD is expecting an ASCII code that represents the number that you are trying to display.

Don

Actually I'm gone create a math formula to display the acohol in aer in mg/L and I think it's gone work. With math will be pretty hard I think.... Somebody some sugestions???
Thanks for your advice

With math will be pretty hard I think.... Somebody some sugestions???

math is never hard, you just did not do that formula before;)

Do you have a link to the math ? datasheet ?

If you have a graph than you can allways use multiMap() to approximate the value - Arduino Playground - HomePage -
as easy as filling 2 arrays...

MQ-3 alcohol sensor.
"http://www.sparkfun.com/datasheets/Sensors/MQ-3.pdf"

Have you searched the forum allready? [upper right]

It gives a dozen or two threads about this sensor including some with code.

I read a few topics like you said but find elsewhere simple map() function an seems to work only on Serial Monitor. I can not display that value on serLCD.
Some ideas ?

/*

Breathalyzer with Arduino UNO and Serial LCD from SparkFun
I'm using a MQ-3 sensor
*/

#include <SoftwareSerial.h>
#include "serLCD.h"

// Set pin to the LCD's rxPin
int pin = 1;
int sensorValue = 0; // The sensor value
int sensorMin = 280; // Minimum sensor value
int sensorMax = 1008; // Maximum sensor value

serLCD lcd(pin);

void setup()
{
Serial.begin(9600);
}

void loop() {

sensorValue = analogRead(A0);
//0.05 it is the minimum value that sensor can read and max is 10 mg/L
sensorValue = map(sensorValue, sensorMin, sensorMax, 0.05, 10);
// keep the value in the desired range
sensorValue = constrain(sensorValue, 0.05, 10);
//lcd.selectLine(1);
//lcd.print("Alcohol is: ");
//lcd.selectLine(2);
lcd.print(sensorValue);
delay(2000);

}

please use the # button when posting code to get proper tagging. The code will look much better readable imho.

read - map() - Arduino Reference -
The map() function uses integer math so will not generate fractions, when the math might indicate that it should do so.

You should use an float variation of map see below

float fmap(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

OK, but aftere I do that, my value readet from the sensor it's "x" or ..., what should I display on LCD # lcd.print(x); # ???

I have done some changes. Toke another serial LCD librarie and try to implement your ideea but, a few errors. Maybe it's late and I should go to sleep.
Code:

/*

Breathalyzer with Arduino UNO and Serial LCD from SparkFun
I'm using a MQ-3 sensor
*/

#include <SoftwareSerial.h>
#include "SparkFunSerLCD.h"

// Set pin to the LCD's rxPin  
float sensorValue = 0;   // The sensor value
float sensorMin = 250;  // Minimum sensor value
float sensorMax = 1008;     // Maximum sensor value

SparkFunSerLCD lcd(1,2,16);

void setup()
{
  Serial.begin(9600);
}

void loop() {

  sensorValue = analogRead(A0); 
  //0.05 it is the minimum value that sensor can read and max is 10 mg/L
  sensorValue = map(sensorValue, sensorMin, sensorMax, float 0.05, float 10); 
    {
     return (sensorValue - sensorMin) * (10 - 0.05) / (sensorMax - sensorMin) + 0.05; 
    }
  // keep the value in the desired range
  sensorValue = constrain(sensorValue, 0.05, 10);
  lcd.print("Alcohol is: ");
  lcd.print(sensorValue);
  lcd.print(" mg/L");
  delay(2000);
 
}

What I don't understand the last 2 line from this code, who is in_min, in_max, out_min, out_max ????
Why should I map the sensorValue twice ?
Thanks

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  float sensorMin = 250.00;  // minimum value what sensor measure on analogRead
  float sensorMax = 1008.00; // max value measured on analogRead

  int x = analogRead(A0);

  float sensorValue = fmap(x, 0, 1023, sensorMin, sensorMax);
  Serial.println(sensorValue);

  float sensorValue2 = fmap(x, 0, 1023, 0.05, 10.00); /* 0.05 mg/L minimum acohol in pure aer what cand my sensor detect and max 10 mg/L*/

  Serial.println(sensorValue2);

  delay(1000);
}

float fmap(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

What I don't understand the last 2 line from this code, who is in_min, in_max, out_min, out_max ????

fmax is a function returning a float with five parameters called: x, in_min, in_max, out_min, out_max

These 5 parameters are used internally in the formula between the { }

Please read this book, chapter functions: - http://zanasi.chem.unisa.it/download/C.pdf - maybe you better buy it as it is worth it.

Why should I map the sensorValue twice ?

It just shows that you can call fmap with different parameters, nothing more && nothing less.

I solved some problems and now my code it's looking like this

/*

Breathalyzer with Arduino UNO using a MQ-3 alcohol sensor and Serial LCD from SparkFun

*/

#include <SoftwareSerial.h>
#include "serLCD.h"
#include "Button.h"

// Set pin to the LCD's rxPin
int pin = 2;  
int sensorValue = 0;   // The sensor value


serLCD lcd(pin);
// Set button pin
Button btn(7);


void setup()
{
  Serial.begin(9600);
  lcd.clear();
  lcd.print("Apasa-ti butonul");
  lcd.print("pentru a incepe!");
  btn.setup();            // setup & describe the button's normal state
  btn.normallyOpen();        // button closes circuit when pressed
    //btn.normallyClosed();    // button opens circuit when pressed
  btn.buttonCold();        // button shorts to sink
    //btn.buttonHot();        // button shorts to voltage

  bool isButtonPressed ( void ); // is the button in the opposite of normal state ?
  bool buttonMoved ( void ); // did the button change ?
}

#define skipCount 2
#define sampleCount 5

void loop() {

  btn.loop();
  sensorValue = analogRead(A0);

    // only while the button is pushed
    if (btn.isButtonPressed()) {
   
        // read the sensor X times and average the total, skipping the 1st Y readings
        for (int i=0; i< skipCount ; i++) analogRead(A0);
        for (int i=0; i< sampleCount ; i++) sensorValue += analogRead(A0);
        sensorValue /= sampleCount;
 
  
  //detection concentartion scope is between 0.05 to 10 mg/L
  //the minimum value readet from analog input is 260 and until BUTTON implementation the maximum was 1008 and now it's over 1200
  float mappedValue = map(sensorValue, 380, 1030, (0.05*100.00),(10.00*100.00))/100.00; 
  lcd.clear();
  
  lcd.print("Alcool: ");
  if (mappedValue >= 0.05)
    {
    lcd.print(mappedValue);
    }
    else 
    {
      lcd.print("0.00");
    }
  lcd.print("mg/L");
  
  lcd.print(sensorValue);
  Serial.println(sensorValue);
  
  delay(2000);
    }
}

My big problem right now is I don't understand why it's returns a very big value, over 1200 (the ADC from Arduino should return from 0 to 1023) when injected a large amount of alcohol. Normally schould return 1023. I tryed with constrain() but dosn't work.
Maybe it's from Button librarie (in attachment).

Somebody some ideeas?

Button.cpp (1.68 KB)

Button.h (734 Bytes)

serLCD.cpp (4.8 KB)

serLCD.h (2.72 KB)

  bool isButtonPressed ( void ); // is the button in the opposite of normal state ?
  bool buttonMoved ( void ); // did the button change ?

Why are these function prototypes in setup()?

  sensorValue = analogRead(A0);

        for (int i=0; i< sampleCount ; i++) sensorValue += analogRead(A0);
        sensorValue /= sampleCount;

If sampleCount is 3, you read 4 times. If it is 5, you read 6 times. That first statement should be

  sensorValue = 0;

My big problem right now is I don't understand why it's returns a very big value, over 1200 (the ADC from Arduino should return from 0 to 1023) when injected a large amount of alcohol.

My big problem is that I don't know what "it" is that is returning a very big value. If "it" is the sensor you are reading and averaging, incorrectly, then perhaps reading and averaging correctly will solve the problem.

I'm talking about sensorValue readet with analogRead(A0). The sensorValue it's over 1200 sometimes.

The Button prototypes are in setup() because who create the Button.h librarie told me to do it like that.

The SampleCount is 5, that means it's reading 6 times ? should read 5 times and eliminate the first and last and average the 3 values from middle. That's what I need, to average 3 values from 5 readings...

About sensorValue = 0. Shoulden't be initialized with 0 ?

Paul, do you have another option for the Button menu?
I want to start my aplication after I push the Button and before I want to print on LCD "push the Button to start" and only after that I want my code to read the analog value from alcohol sensor and print it on the LCD.
What I need more is to average more readings and after that to map it and print it to the LCD.
I created another program without the Button and my analog value is max 1012. That means I have a problem with the Button function (maybe librarie).
Thanks for fast answer