I'm new on here and have done a bit of programming but not a whole ton with inputs from sensors and what not. I am trying to hook up an MQ-8 hydrogen sensor from NCD to be able to tell if a furnace is leaking hydrogen for safety reasons. I have read that the A4 and A5 pins are for the SDA and SCL ports respectively. This is how I have connected the sensor. This sensor has a GRD SCL SDA and 5V pins. They sell a shield but I'd rather not have to order it to use them. I have got it to where it will give me a reading and when hydrogen passes over it it registers that there is hydrogen and there is a jump in the reading. I have several of them and would like to daisy chain them together seeing as that is how they are designed, but I'd like to be able to see the readings from each sensor. I am lost as to how to do this. Any information would be much appreciated!
void setup() {
pinMode(8, OUTPUT);
Serial.begin(9600);
}
// The loop routine runs over and over again forever
void loop() {
int sensorValue = analogRead(A4);
Serial.println(sensorValue);
delay(1000);
// if (sensorValue > 500) {
// digitalWrite(pin8, HIGH);
// }
// else {
// digitalWrite(pin8, LOW);
// }
Don't know if that imported my code correctly
Because when I used the Wire.write() I couldn't get it to output any information. So that was me trying different things until I got some sort of output out of the sensor. Honestly it's probably done wrong. I feel as though using the I2C controls with the wire library and having addresses to each sensor as some sort of slave is how I can get it to work the way I want, but I have no idea of how to go about that.
This is what I understood from what I have read on I2C
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
}
void loop() {
Wire.requestFrom(6, A4);
Serial.print(Wire.read());
delay(1000);
}
I must have had dyslexia kick in and read that backwards. So to clarify the address would be the pin that I'm using. For I2C it would be A4 for SDA and A5 for SCL? Or what 7-bit address is it talking about? And the bytes is how many bits per second are being transferred from the sensor?
The MQ-8 sensor itself is an analog device and needs to be read with an ADC.
Post a link to the exact module you are using.
Data sheet. Note that it detects several flammable gases, such as alcohols and methane, as well as hydrogen.
Who knows? The sensor module could have an I2C ADC on it!
I'm sorry if I wasted your time. Definitely wasn't my intention. I was just relaying the ports that it had on the sensor which are clearly labeled SDA and SCL. You were the one who said it was an I2C. So I took your word for it that it was. Like I said I have no experience with these sort of sensors or anything of the like. I posted the link to the actual sensor that it is in the very first post that I made. The data sheet I'm looking at also says that its I2C compatible.
https://store.ncd.io/product/mq-8-hydrogen-gas-sensor-adc121c-12-bit-adc-i2c-mini-module/ Module
https://media.ncd.io/sites/2/20170721134609/ADC121C-8.pdf Data sheet
I put it in there but it must not have posted I put them both in my last post just in case they didn't show up.
That module DOES have an ADC on it. And a pretty good one, too.
Careful study of the "NCD I2C" interface and connection diagram on this page is strongly recommended.
You need to make sure that I2C pullup resistors are present and activated, or it won't work at all.
In your opinion if I was to daisy chain the sensors together would it be better to use the ADC or set them up with an I2C configuration?
The "I2C configuration" talks to the ADC on the module. You really need to spend some time with the data sheets.
Get one sensor working before you worry about anything else. Don't forget the 24-48 hour sensor burn-in time.
I got one sensor working and that's why I'm wondering about the others. Would it be better to just plug the 5 sensors I have into each one of the analog ports and have a code similar to the one I already have working or do an I2C configuration?
Perhaps you are confusing analog inputs A4 and A5 with their alternative uses as SDA and SCL.
The sensors can be daisy chained as shown on the product page, but each sensor must have a different I2C address.
You are probably right. I'll keep reading more on I2C cause there are still aspects that aren't making sense to me. Maybe I can find some good youtube videos too. I feel it's easier to grasp it if I can see it being done or at least written down while I see it. I do thank you for your time! It is much appreciated. When I figure it all out I'll post updates for those like me who are still deep in the learning process. Thanks again.
I found out the address to the sensors I am using, and from the data sheet I believe it is required to send 12 bits. I have it connected and I believe that it should be taking a reading but I keep getting that the reading is 0. I have posted my code. Please let me know if there need to be amendments to it or if I am missing something. Thanks in advance for your time.
#include <Wire.h>
int sensor1 = 1010000;
void setup() {
Serial.begin(9600);
Wire.begin();
}
void loop() {
Wire.beginTransmission(sensor1);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(sensor1, 12);
while(Wire.available() == 0);
int one = Wire.read();
Serial.print("SENSOR 1: ");
Serial.println(one);
delay(5000);
}
Wire.requestFrom(sensor1, 12);
This requests 12 bytes, not 12 bits. Try "2" instead.
Is the ADC properly configured? Study the data sheet to learn what the initial value of the configuration register is, and what it should be for your purposes.
I've got it to work when I have one sensor hooked up to in and it works great so I thank you for all your help up to here! But when I hook up the 5 sensors it will give me the first one's reading and it says that all the other ones are reading -1. Which is the same reading as if nothing is connected. Do I have to change something in the code for it to read the other sensors? I was under the impression that it was just the address of the sensor. Any suggestions?
#include <Wire.h>
int sensor1 = 1010001;
int sensor2 = 1011001;
int sensor3 = 1010101;
int sensor4 = 1010100;
int sensor5 = 1010010;
void setup() {
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
Serial.begin(9600);
Wire.begin();
}
void loop() {
/*
* ******SENSOR ONE******
*/
Wire.beginTransmission(sensor1);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(sensor1, 2);
int one = Wire.read();
Serial.print("SENSOR 1: ");
Serial.println(one);
if(sensor1 >= 5){
tone(7, 261, 5000);
}
if(sensor1 >= 500){ //INITIATES LIGHT FOR SENSOR AT POSITION ONE
digitalWrite(2, HIGH);
}
else{
digitalWrite(2, LOW);
}
/*
* ******SENSOR TWO******
*/
Wire.beginTransmission(sensor2);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(sensor2, 2);
int two = Wire.read();
Serial.print(" SENSOR 2: ");
Serial.print(two);
if(sensor2 >= 5){
tone(7, 261, 5000);
}
if(sensor2 >= 500){ //INITIATES LIGHT FOR SENSOR AT POSITION TWO
digitalWrite(3, HIGH);
}
else{
digitalWrite(3, LOW);
}
/*
* ******SENSOR THREE******
*/
Wire.beginTransmission(sensor3);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(sensor3, 2);
int three = Wire.read();
Serial.print(" SENSOR 3: ");
Serial.print(three);
if(sensor3 >= 5){
tone(7, 261, 5000);
}
if(sensor3 >= 500){ //INITIATES LIGHT FOR SENSOR AT POSITION THREE
digitalWrite(4, HIGH);
}
else{
digitalWrite(4, LOW);
}
/*
* ******SENSOR FOUR******
*/
Wire.beginTransmission(sensor4);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(sensor4, 2);
int four = Wire.read();
Serial.print(" SENSOR 4: ");
Serial.print(four);
if(sensor4 >= 5){
tone(7, 261, 5000);
}
if(sensor4 >= 500){ //INITIATES LIGHT FOR SENSOR AT POSITION FOUR
digitalWrite(5, HIGH);
}
else{
digitalWrite(5, LOW);
}
/*
* ******SENSOR FIVE******
*/
Wire.beginTransmission(sensor5);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(sensor5, 2);
int five = Wire.read();
Serial.print(" SENSOR 5: ");
Serial.println(five);
if(sensor5){
tone(7, 261, 5000);
}
if(sensor5 >= 500){ //INITIATES LIGHT FOR SENSOR AT POSITION FIVE
digitalWrite(6, HIGH);
}
else{
digitalWrite(6, LOW);
}
delay(1000);
}
Try hooking up the individual sensors, one at a time, to verify that each one works individually.
Did you add/change the jumpers on the modules to the correct address values? The module photo on this page suggests that you can change only the lowest three address bits, but your code shows changes to the lowest four.
However, it isn't clear to me how the jumpers are supposed to work. You can always use the I2C_Scanner program to verify individual module addresses, after changing the jumper settings.
Finally, if modules are daisy chained, make sure that only one set of pullup resistors is activated.
The resistor was the problem. I had them on each sensor, didn't realize that it was only supposed to be on one. Sorry for all of the questions but I learn little by little haha. Now that I got them all sensing and outputting a reading, I wrote code to pass that reading into a PPM outcome. I had a little guidance from the internet especially with sandbox electronics. But when I run the code it seems to get bogged down on the setup portion where I do the calibration. If anyone would be willing to look it over and see if I have some bad logic in there because the code will compile. Thanks in advance for your time.
#include <Wire.h>
int sensor[5] = {0x51, 0x52, 0x54, 0x58, 0x50};
int calibration_interval = 50;
int calibration_iterations = 25;
int sensor_interval = 5;
int sensor_iterations = 50;
double rl_value = 10;
double ro_clean = 9.21;
double h2_curve[3] = {2.3, 0.93, -1.44};
void setup() {
Serial.begin(9600);
Serial.println("CALIBRATING... ");
for(int i = 0; i < 5; i++){
Wire.begin();
Wire.beginTransmission(sensor[i]);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(sensor[i], 2);
int ro[i] = {Wire.read()};
Serial.print("RO = ");
Serial.print(Calibration(ro[i]));
Serial.print("KΩ");
}
}
void loop() {
for(int i = 0; i < 5; i++){
Wire.begin();
Wire.beginTransmission(sensor[i]);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(sensor[i], 2);
int hydrogen[i] = {Wire.read()};
Serial.print("SENSOR ");
Serial.print(i + 1);
Serial.print(": ");
Serial.print(h2_ppm(Sensor(hydrogen[i]) / rl_value, h2_curve));
Serial.print(" PPM ");
if(i == 4){
Serial.print("\n");
}
delay(500);
}
}
double Resistance(int voltage){
return ((rl_value * (1023 - voltage) / voltage));
}
double Calibration(int sensor){
double calibrate = 0;
for(int i = 0; i < calibration_iterations; i++){
for(int *j = 0; j < 5; j++){
calibrate += Resistance(sensor[j]);
delay(calibration_interval);
}
}
calibrate = calibrate / calibration_iterations;
calibrate = calibrate / ro_clean;
return calibrate;
}
double Sensor(int sensor){
double rs = 0;
for(int i = 0; i < sensor_interval; i++){
for(int *j = 0; j < 5; j++){
rs += Resistance(sensor[j]);
delay(sensor_iterations);
}
}
rs = rs / sensor_interval;
return rs;
}
double h2_ppm(double rs_ro_ratio, double *h2_curve){
return (pow(10, ((log(rs_ro_ratio) - h2_curve[1] / h2_curve[2]) + h2_curve[0])));
}