Не могу заставить работать более одного датчика газа 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)));
  }
}

, 👍0

Обсуждение

Используя ваш объединенный код, но комментируя вызовы всех датчиков, кроме одного (за раз), каждый из них будет работать правильно?, @JRobert


1 ответ


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