Объяснение кода, когда датчик pH подключен к Arduino

Мне нужно измерить значение pH для какого-то эксперимента. Я проверил различные коды, и все они включают среднее значение pH.

#define SensorPin 0          // Аналоговый выход pH-метра подключен к аналоговому выходу Arduino
unsigned long int avgValue;  //Сохраняем среднее значение обратной связи датчика
float b;
int buf[10],temp;
 
void setup()
{ 
  Serial.begin(9600);  
  Serial.println("Ready");    //Проверка последовательного монитора
}
void loop()
{
  for(int i=0;i<10;i++)       //Получить 10 значений от датчика для сглаживания значения
  { 
    buf[i]=analogRead(SensorPin);
    delay(10);
  }
  for(int i=0;i<9;i++)        //сортируем аналог от меньшего к большему
  {
    for(int j=i+1;j<10;j++)
    {
      if(buf[i]>buf[j])
      {
        temp=buf[i];
        buf[i]=buf[j];
        buf[j]=temp;
      }
    }
  }
  avgValue=0;
  for(int i=2;i<8;i++)                      //берем среднее значение 6-центровой выборки
  avgValue+=buf[i];
  float phValue=(float)avgValue*5.0/1024/6; // конвертируем аналог в милливольты
  phValue=3.5*phValue;                      //конвертируем милливольты в значение pH
  Serial.print("pH:");  
  Serial.println(phValue,2);
  delay(5000); 
} 

Пожалуйста, объясните значение этих двух строк. Зачем брать постоянные значения, выделенные жирным шрифтом (5/1024/6) и (3,5*pH)? Могу ли я использовать другое значение вместо этих?

float phValue=(float)avgValue*5.0/1024/6; // конвертируем аналог в милливольты
  phValue=3.5*phValue;                      //конвертируем милливольты в значение pH

, 👍1


1 ответ


1

Это прекрасный пример того, почему магические числа — это плохо. Всегда используйте символические константы.

Относительно первой строки:

  1. Программа "5.0" - опорное напряжение АЦП, по-видимому, 5,0 вольт.

  2. Код "1024" ширина диапазона значений, возвращаемых ADC.

  3. Кнопка "6" - это количество выборок, суммированное в двух предыдущих строках.

АЦП возвращает значения в диапазоне от 0 до 1023, что дает вам 1024 различных значения. Если он измеряет 0% своего опорного напряжения, он возвращает 0. Если он измеряет 100% своего опорного напряжения, он возвращает 1023. должно быть "1023", но с учетом точности это не имеет большого значения.

Если разделить измеренное значение на 1024, одно значение АЦП будет находиться в диапазоне от 0,0 (0%) до 0,999 (почти 100%).

Умножение на "5,0" дает напряжение, если предположить, что опорное напряжение равно 5,0 вольт.

Поскольку суммируются 6 выборок, для получения среднего необходимо еще одно деление на 6.

Вопреки комментарию, результатом первой строки является измеренное и усредненное напряжение в вольтах, а не в милливольтах.

Если бы автор использовал константы smybolic, комментарии не потребовались бы и, следовательно, не могли стать ошибочными.

Относительно второй строки:

По-видимому, это фактор датчика между напряжением и значением pH. Напряжение 0 В означает значение pH, равное 0, а напряжение 4 В – значение pH, равное 14. Примечание. Значение pH может находиться только в диапазоне от 0 до 14.

Поскольку вы не разместили ссылку на техпаспорт используемого датчика, мы не можем это проверить. Но вы можете.

Первый подход с символическими константами:

static const int FIRST_INDEX_FOR_AVERAGE = 2;
static const int NUMBER_OF_VALUES_TO_AVERAGE = 6;

static const float FULL_SCALE_IN_VOLTS = 5.0;
static const int ADC_MAXIMUM = 1023; // было 1024

static const float PH_PER_VOLT = 3.5; // или даже лучше 14.0/4.0

// ...

avgValue = 0;
for (int i = FIRST_INDEX_FOR_AVERAGE;
     i < FIRST_INDEX_FOR_AVERAGE + NUMBER_OF_VALUES_TO_AVERAGE;
     i++)
{
    avgValue += buf[i];
}

float phValue = avgValue * FULL_SCALE_IN_VOLTS / ADC_MAXIMUM / NUMBER_OF_VALUES_TO_AVERAGE;

phValue = phValue * PH_PER_VOLT;

Нет необходимости преобразовывать avgValue в float, так как FULL_SCALE_IN_VOLTS равно float, поэтому вычисления выполняются. с плавающей запятой.

,

Значения PH следуют линейному уравнению, y = mx + b, 3,5 — это наклон линейной линии. Обычно датчик PH необходимо откалибровать с помощью двух буферных растворов, например, при PH4, а другой при PH9 или PH7, затем можно провести линию и определить наклон., @hcheung

«Напряжение 0 вольт означает значение pH 0, а напряжение 4 вольта означает значение pH 14». Не совсем так, измерение значения PH обычно требуется усиливать через ОУ, а так как значение PH не может быть отрицательным значением, ОУ обычно "поднимает" опорное напряжение, скажем, до 2,5В, а затем откалибруйте датчик для операционного усилителя, чтобы выходное напряжение было равно 0, когда PH находится на уровне 7,0 (центр диапазона PH), поэтому значение PH колеблется в пределах +/-2,5 В., @hcheung

Как я уже писал, у нас нет информации, какой датчик и внешнюю схему использует ОП. Поэтому я просто объяснил фактор. В любом случае, ваши комментарии приветствуются как потенциальное издание моего ответа. Только сохраните смысл, пожалуйста., @the busybee

Относительно «_значение« 1024 »должно быть« 1023 »_»: теоретически оно должно быть 1024. Это [четко указано в техническом описании] (https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08 /ProductDocuments/DataSheets/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061B.pdf#G3.1738853) микроконтроллера: значение 1023 «представляет выбранное опорное напряжение минус один младший разряд». На практике вам придется калибровать АЦП, если вам нужен такой уровень точности. [Я измерил наклон ≈1026 на трех Arduinos](https://wiki.logre.eu/index.php/R%C3%A9ponse_de_l%27ADC_d%27un_Arduino/en)., @Edgar Bonet

@EdgarBonet Спасибо за это ценное понимание!, @the busybee