Не могу заставить работать более одного датчика газа Arduino одновременно.
Я выполняю школьный проект, в котором мне нужно отслеживать различные виды газов, проблема в том, что я не могу считывать данные с более чем одного датчика одновременно, я использую четыре датчика (mq5, mq7, mq8 и mq135), а код, который я использую, я объединил с помощью четырех разных кодов, найденных на github (https://github.com /mdsiraj1992/Gassensors). Когда у меня только один датчик, он работает нормально, но когда я использую код, который я объединил, значения полностью отключаются. В общем, я делаю что-то не так, но не знаю что. Пожалуйста, помогите мне, мне нужно доставить код на этой неделе.
#include <Adafruit_Sensor.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include <DHT.h>
#include <DHT_U.h>
/***Hardware Related Macros***/
#define MQ5PIN (2)
#define RL_VALUE_MQ5 (1)
#define RO_CLEAN_AIR_FACTOR_MQ5 (6.455)
#define MQ7PIN (3)
#define RL_VALUE_MQ7 (1)
#define RO_CLEAN_AIR_FACTOR_MQ7 (26.09)
#define MQ8PIN (1)
#define RL_VALUE_MQ8 (1)
#define RO_CLEAN_AIR_FACTOR_MQ8 (1)
#define MQ135PIN (5)
#define RL_VALUE_MQ135 (1)
#define RO_CLEAN_AIR_FACTOR_MQ135 (3.59)
/***Software Related Macros***/
#define CALIBARAION_SAMPLE_TIMES (50)
#define CALIBRATION_SAMPLE_INTERVAL (500)
#define READ_SAMPLE_INTERVAL (50)
#define READ_SAMPLE_TIMES (5)
/***Application Related Macros***/
#define GAS_LPG (1)
#define accuracy (0)
#define GAS_CARBON_MONOXIDE (3)
#define GAS_HYDROGEN (0)
#define GAS_METHANE (2)
#define GAS_CARBON_DIOXIDE (9)
#define GAS_AMMONIUM (10)
/***Globals***/
float Ro = 10;
void setup() {
Serial.begin(9600);
Serial.print("Calibrating...\n");
Ro = MQCalibration(MQ5PIN);
Serial.print("Calibration is done...\n");
Serial.print("Ro5=");
Serial.print(Ro);
Serial.print("kohm");
Serial.print("\n");
Ro = MQCalibration(MQ7PIN);
Serial.print("Calibration is done...\n");
Serial.print("Ro7=");
Serial.print(Ro);
Serial.print("kohm");
Serial.print("\n");
Ro = MQCalibration(MQ8PIN);
Serial.print("Calibration is done...\n");
Serial.print("Ro8=");
Serial.print(Ro);
Serial.print("kohm");
Serial.print("\n");
Ro = MQCalibration(MQ135PIN);
Serial.print("Calibration is done...\n");
Serial.print("Ro135=");
Serial.print(Ro);
Serial.print("kohm");
Serial.print("\n");
}
void loop() {
Serial.print("METHANE:");
Serial.print(MQGetGasPercentage(MQRead(MQ8PIN) / Ro, GAS_METHANE) );
Serial.print( "ppm" );
Serial.print(" ");
Serial.print("HYDROGEN:");
Serial.print(MQGetGasPercentage(MQRead(MQ8PIN) / Ro, GAS_HYDROGEN) );
Serial.print( "ppm" );
Serial.print(" ");
Serial.print("GLP:");
Serial.print(MQGetGasPercentage(MQRead(MQ5PIN) / Ro, GAS_LPG) );
Serial.print( "ppm" );
Serial.print(" ");
Serial.print("CARBON_MONOXIDE:");
Serial.print(MQGetGasPercentage(MQRead(MQ7PIN) / Ro, GAS_CARBON_MONOXIDE)
);
Serial.print( "ppm" );
Serial.print(" ");
Serial.print("CARBON_DIOXIDE:");
Serial.print(MQGetGasPercentage(MQRead(MQ135PIN) / Ro, GAS_CARBON_DIOXIDE)
);
Serial.print( "ppm" );
Serial.print(" ");
Serial.print("AMMONIUM:");
Serial.print(MQGetGasPercentage(MQRead(MQ135PIN) / Ro, GAS_AMMONIUM) );
Serial.print( "ppm" );
Serial.print("\n");
delay(200);
}
/***MQResistanceCalculation*****************************************
Input: raw_adc - raw value read from adc, which represents the
voltage
Output: the calculated sensor resistance
Remarks: The sensor and the load resistor forms a voltage divider.
Given the voltage
across the load resistor and its resistance, the resistance of the
sensor
could be derived.
*******************************************************************/
float MQResistanceCalculation(int raw_adc)
{
return ( ((float)RL_VALUE_MQ5 * (1023 - raw_adc) / raw_adc));
return ( ((float)RL_VALUE_MQ7 * (1023 - raw_adc) / raw_adc));
return ( ((float)RL_VALUE_MQ8 * (1023 - raw_adc) / raw_adc));
return ( ((float)RL_VALUE_MQ135 * (1023 - raw_adc) / raw_adc));
}
/*** MQCalibration*******************************************************
Input: mq_pin - analog channel
Output: Ro of the sensor
Remarks: This function assumes that the sensor is in clean air. It use
MQResistanceCalculation to calculates the sensor resistance in clean
air
and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is
about
10, which differs slightly between different sensors.
****************************************************************/
float MQCalibration(int mq_pin)
{
int i;
float RS_AIR_val = 0, r0;
for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
delay(CALIBRATION_SAMPLE_INTERVAL);
}
RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ5;
return r0;
for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
delay(CALIBRATION_SAMPLE_INTERVAL);
}
RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ7;
return r0;
for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
delay(CALIBRATION_SAMPLE_INTERVAL);
}
RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ8;
return r0;
for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
delay(CALIBRATION_SAMPLE_INTERVAL);
}
RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ135;
return r0;
}
/***************** MQRead *********************************
Input: mq_pin - analog channel
Output: Rs of the sensor
Remarks: This function use MQResistanceCalculation to caculate the
sensor resistenc (Rs).
The Rs changes as the sensor is in the different consentration of the
target
gas. The sample times and the time interval between samples could be
configured
by changing the definition of the macros.
********************************************************/
float MQRead(int mq_pin)
{
int i;
float rs = 0;
for (i = 0; i < READ_SAMPLE_TIMES; i++) {
rs += MQResistanceCalculation(analogRead(mq_pin));
delay(READ_SAMPLE_INTERVAL);
}
rs = rs / READ_SAMPLE_TIMES;
return rs;
}
/*********************** MQGetGasPercentage ****************************
Input: rs_ro_ratio - Rs divided by Ro
gas_id - target gas type
Output: ppm of the target gas
Remarks: This function uses different equations representing curves of
each gas to
calculate the ppm (parts per million) of the target gas.
******************************************************************/
int MQGetGasPercentage(float rs_ro_ratio, int gas_id)
{
if ( accuracy == 0 ) {
}
if ( gas_id == GAS_LPG ) {
return (pow(10, ((-2.513 * (log10(rs_ro_ratio))) + 1.878)));
}
else if ( gas_id == GAS_CARBON_MONOXIDE ) {
return (pow(10, ((-1.525 * (log10(rs_ro_ratio))) + 1.994)));
}
else if ( gas_id == GAS_HYDROGEN ) {
return (pow(10, ((-2.568 * (log10(rs_ro_ratio))) + 0.360)));
}
else if ( gas_id == GAS_METHANE ) {
return (pow(10, ((-16.16 * (log10(rs_ro_ratio))) + 1.093)));
}
else if ( gas_id == GAS_CARBON_DIOXIDE ) {
return (pow(10, ((-2.890 * (log10(rs_ro_ratio))) + 2.055)));
}
else if ( gas_id == GAS_AMMONIUM ) {
return (pow(10, ((-2.469 * (log10(rs_ro_ratio))) + 2.005)));
}
else if ( accuracy == 1 ) {
}
else if ( gas_id == GAS_LPG ) {
return (pow(10, ((-2.513 * (log10(rs_ro_ratio))) + 1.878)));
}
else if ( gas_id == GAS_CARBON_MONOXIDE ) {
return (pow(10, ((-1.525 * (log10(rs_ro_ratio))) + 1.994)));
}
else if ( gas_id == GAS_HYDROGEN ) {
return (pow(10, ((-2.568 * (log10(rs_ro_ratio))) + 0.360)));
}
else if ( gas_id == GAS_METHANE ) {
return (pow(10, (-281.3 * pow((log10(rs_ro_ratio)), 3) - 12.26 *
pow((log10(rs_ro_ratio)), 2) - 7.925 * (log10(rs_ro_ratio)) + 1.668)));
}
else if ( gas_id == GAS_CARBON_DIOXIDE ) {
return (pow(10, ((-2.890 * (log10(rs_ro_ratio))) + 2.055)));
}
else if ( gas_id == GAS_AMMONIUM ) {
return (pow(10, ((-2.469 * (log10(rs_ro_ratio))) + 2.005)));
}
}
@Bruno Moretti, 👍0
Обсуждение1 ответ
Прежде всего, вам нужно включить только один раз. Включать что-либо более одного раза бессмысленно и может быть вредно, если в заголовке нет защиты включения (у вас есть, но это все равно только усложняет чтение кода).
Давайте взглянем на функцию MQRes istanceCalculation
, ну... Она просто сломана.
float MQResistanceCalculation(int raw_adc)
{
return ( ((float)RL_VALUE_MQ5 * (1023 - raw_adc) / raw_adc));
return ( ((float)RL_VALUE_MQ7 * (1023 - raw_adc) / raw_adc));
return ( ((float)RL_VALUE_MQ8 * (1023 - raw_adc) / raw_adc));
return ( ((float)RL_VALUE_MQ135 * (1023 - raw_adc) / raw_adc));
}
Я не уверен, что вы ожидаете, но как только вы достигнете оператора возврата, этот блок кода останавливается и возвращается результат, поэтому по сути эта функция выполняет первый возврат, а затем останавливается. Вероятно, вы захотите передать тип датчика, а затем использовать переключатель, чтобы он возвращал значение MQ5, MQ7, MQ8 или MQ135, поскольку сейчас он возвращает только значение MQ5.
Тогда давайте взглянем на функцию MQCalibration
. Применяется то же самое, что и выше: пока вы достигаете возврата, функция останавливается. Ваша функция MQCalibration
в настоящее время делает только:
float MQCalibration(int mq_pin)
{
int i;
float RS_AIR_val = 0, r0;
for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {
RS_AIR_val += MQResistanceCalculation(analogRead(mq_pin));
delay(CALIBRATION_SAMPLE_INTERVAL);
}
RS_AIR_val = RS_AIR_val / CALIBARAION_SAMPLE_TIMES;
r0 = RS_AIR_val / RO_CLEAN_AIR_FACTOR_MQ5;
return r0;
}
А затем функцию MQGetGasPercentage
можно переписать с помощью операторов переключения, чтобы ее было легче читать и понимать. Да, и еще эта проверка accuracy == 0
тоже бессмысленна, в ней ничего нет.
Прочитав это, я вижу, что вы только что скопировали код, который не понимаете, и надеялись, что он сработает, но, как и ожидалось, этого не произошло. А копировать код, не имея хотя бы представления о том, что он делает, глупо. Так что просто прочитайте, поймите и напишите еще раз, но уже самостоятельно. В вашем коде много бессмысленных объявлений переменных, и он просто не очень хорошо «написан» (или, лучше сказать, скопирован).
Кроме того, я сам никогда не работал с этим датчиком, поэтому в основном рассматривал аспект кода, просто чтобы вы знали.
Теперь я понимаю и попробую написать новый код самостоятельно. Мне пришлось его скопировать и вставить из-за отсутствия знаний в Arduino, и у меня не было много времени на исследования, спасибо за помощь, я обязательно позабочусь чтобы сделать это правильно в следующий раз., @Bruno Moretti
- MAX30100 не работает
- Использование библиотеки емкостных датчиков с мультиплексором 74HC4067
- Проблема с сигналом датчика пульса
- Считывание значений с емкостного сенсорного датчика TTP229 на arduino
- Подключение двух Arduino через I2C, когда контакты I2C A4/A5 уже используются.
- Два датчика расхода, один ESP32, ЖК-дисплей и/или Arduino
- Arduino nano 33 ble vs ble sense. Потребляемая мощность и т.д.
- Проблема прерываний с датчиком потока
Используя ваш объединенный код, но комментируя вызовы всех датчиков, кроме одного (за раз), каждый из них будет работать правильно?, @JRobert