Алкотестер своими руками

На сегодняшний день существует много различных разновидностей алкотестеров, для оценки количества спирта в крови человека по выдыхаемому человеком воздуху. Такие устройства используются в основном для контроля состояния водителя, так как нельзя садиться за руль автомобиля, другого автотранспортного средства или выполнять действия, сопряженные с опасностью для себя и других людей. 
Есть фабричные устройства, а также самодельные. Они относительно сложны или дороги и не всеми могут быть реализованы. Данный проект нацелен на создание простого в изготовлении алкодетектора, который может определить присутствие недопустимого содержания паров спирта в выдыхаемом воздухе. 

Экспериментальный стенд

Используемые компоненты

  • Датчик паров спирта MQ-3 в форме готового модуля
  • Батарея питания 9 В
  • Интегральный стабилизатор напряжения, выдающий не ниже 180 мА при напряжении 5 В Например, КР142ЕН5А (2А)
  • Конденсаторы по 22 мкФ
  • резистор 300 Ом
  • Светодиод
  • Выключатель

Схема соединений

Для тестирования датчика была собрана следующая схема:

Алкотестер своими руками

Так как модулю MQ-3 требуется стабильное питание 5 В, то был реализован понижающий стабилизатор напряжения.

датчик MQ-3 подключение
Подключение на макетной плате. Без выключателя.
датчик MQ-3 подключение
С другой стороны есть потенциометр для регулировки порога срабатывания.
датчик MQ-3 подключение
Вид сверху на соединения

Эксперименты

1. Время нагрева датчика

Первый эксперимент заключался в измерении параметров датчика MQ-3 в период нагрева. Контролироваловь выходное напряжение и температура датчика в зависимости от времени прошедшего с включения питания.

Эксперимент по нагреву датчика MQ-3 и тест на алкоголь

С результатами данного исследования можно ознакомиться в данной статье.

Результат исследования характеристик датчика MQ-3 при прогреве
Результат исследования характеристик датчика MQ-3 при прогреве

Здесь хорошо виден начальный этап нагрева, при котором напряжение вначале резко возрастает до 1 В, а затем начинает падать до уровня 0.7 В, а в последствии медленно расти до 0.8 В. Т.е. рабочий диапазон выходного напряжения здесь 0.7 … 0.8 В.

Вывод

Данный датчик не может быть использован сразу после включения, т.к. показания будут непредсказуемо изменяться в период нагрева, в тоже время держать его постоянно включенным не желательно при питании от батареи, т.к. он потребляет относительно большой ток на нагрев.
Если применять его для портативных устройств, то нужно выжидать время нагрева (не менее 400 с) и затем производить измерение. Альтернативным вариантом является мониторинг скорости изменения напряжения – если напряжение находится на уровне ниже 0.9 В и скорость его изменения меньше пороговой, то произвести измерение.
В любом случае стоит предусмотреть сохранение значения напряжения при отсутствии алкоголя и затем сравнить его с измеренным значением при неизвестным значением алкоголя. Так будет нивелироваться плавающее базовое значение напряжения.

2. Исследование линейности датчика MQ-3

Во втором эксперименте было произведено исследование датчика MQ-3 на линейность зависимости концентрации алкоголя и выходного напряжения. Это позволит определиться с процедурой калибровки.

С результатами данного исследования можно ознакомиться в данной статье.

Алкотестер своими руками
Результаты измерений разных концентраций алкогольных паров

Здесь видна линейность зависимости среднего значения напряжения в серии для каждой концентрации.

Алкотестер своими руками
Регрессионная линейная модель среднего значения напряжения датчика

Здесь показан результат построения линейной модели по полученным данным. Полученный коэффициент детерминации 0.97 позволяет подтвердить утверждение о линейности показаний.

Вывод

Результаты эксперимента дали подтверждение линейности показаний датчика MQ-3, что упрощает модель преобразования и процесс калибровки.
Также для повышения точности следует использовать базовое напряжение в отсутствии алкоголя в качестве нулевой точки и рассчитывать концентрацию уже по отношению к ней.

3. Калибровка

Изучая методы калибровки наткнулся на такой любопытный подход, описанный в книге Г.Виглеб Датчики. Устройство и применение. // пер. с нем. М.А. Хацернова, Москва, изд. “Мир”, 1989 г. :

Лучше всего проводить калибровку с использованием водки крепостью 40%. Для этого в восемь рюмок наливают точно по 20 мл. Затем одну из этих рюмок выпивают и выжидают примерно 1/4 ч, чтобы алкоголь мог перейти в кровь и в полости рта не оставалось бы следов алкоголя. После этого нужно подуть на датчик и убедиться, что показания все еще составляют 0 промилле, как и должно быть.

После второй рюмки также следует сделать паузу 1/4 ч. Показания должны составлять 0.2 промилле. Эта процедура продолжается далее, пока после восьмой дозы показания не достигнут 1 промилле.

Калибровка рассчитана на вес тела 75 кг и на проведение процедуры натощак. Жирная пища и большой вес снижают показания.

Учитывая, что функция преобразования датчика линейна, можно преобразовать данную методику. Для этого воспользуемся профессиональным калькулятором алкоголя в крови, применяемым судмедэкспертами. Вводя туда параметры испытуемого (пол, массу рост), процент содержания спирта в действующем веществе и его количество можно рассчитать максимальное количество промилле алкоголя в крови и динамику его повышения. По графику определить минимальное и максимальное время достижения максимума алкоголя в крови (синий и красный график). Это тот период, где следует ожидать максимум. Именно через такое время после приема действующего вещества нужно измерять показания прибора и использовать для калибровки максимальные показания.

Разработка Алкотестера RGB

Так как мы не претендуем на прецизионность показаний, то вполне уместно для сокращения расходов и упрощения конструкции использовать цветовое картирование результатов измерений. Грубо говоря, применить метод светофора. Малые значения концентрации алкоголя будут показываться зеленым цветом, значимые концентрации – красным, а высокие будут обладать синим оттенком. Причем будет реализована плавная смена цветов! Для этого можно использовать один RGB светодиод.

Электрическая схема алкотестера

Здесь показано соединение компонентов семы.

Алкотестер своими руками

Как видно, всего три ключевых компонента, схему может собрать даже школьник! За основу предлагается взять DigiSpark из-за его малых размеров. У него есть один важный для измерителей недостаток – нестабилизированный тактовый RC-генератор, но к счастью время измерения тут не так велико, да и постоянство периода дискретизации не требуется.

Для питания датчика можно использовать стабилизатор самого модуля, т.к. он может потянуть ток потребления датчика MQ-3 и RGB диода. Резисторы у диода необходимы, чтобы он не сгорел (ну или порт микроконтроллера). Чтобы изменить общую яркость диода можно ввести в схему еще резистор а разрез синего провода, ведущего от диода в “земле” GND. Но это считаю лишним.

Тестирование макета алкотестера

Программа для Digispark (Arduino IDE)

Разработанная программа (скетч) реализует все умные методы измерения, определенные в результате исследований: умный прогрев, компенсация внешних условий, калибровка, цветовое картирование. И все это полностью автоматически. Ни одной кнопки пользователю нажимать не придется! Вставляете в среду Ардуино, настроенную под DigiSpark. Есть даже готовые сборки. Если будут сложности с этим – выложу инстукцию.

// Alcotester RGB v.2 DigiSpark
// Контроль прогрева датчика, компенсация внешних условий, измерение алкоголя в крови и индикация цветом.
// Зеленый - норма, красный - 0.16 промилле (нельзя за руль), синий - 1 промилле, фиолетовый - критическое значение. 
// (c) Isakov Roman, 2020
// (c) LabData.ru
// Адрес проекта https://labdata.ru/project/prostejshij-alkotester-svoimi-rukami
//----------------

// Блок настроек
#define Red_pin 0
#define Green_pin 4
#define Blue_pin 1
#define Sensor_pin A1
#define max_grad 2
#define level_0 131
#define level_02 165
#define level_1 825
// Управление цветом
byte GetRed(float v)
{ byte R;
  if (v <= level_02)
  { byte k = map(v, level_0, level_02, 0, 255);
    R = k;
  } else if (v > level_02 && v <= level_1)
  { byte k = map(v, level_02, level_1, 0, 255);
    R = 255-k;
  } else if (v > level_1)
  { byte k = map(v, level_1, 1023, 0, 255);
    R = k;
  }
  return R;
}
byte GetGreen(float v)
{ byte G;
  if (v <= level_02)
  { byte k = map(v, level_0, level_02, 0, 255);
    G = 255-k;
  } else if (v > level_02 && v <= level_1)
  { byte k = map(v, level_02, level_1, 0, 255);
    G = 0;
  } else if (v > level_1)
  { byte k = map(v, level_1, 1023, 0, 255);
    G = 0;
  }
  return G;
}
byte GetBlue(float v)
{ byte B;
  if (v <= level_02)
  { byte k = map(v, level_0, level_02, 0, 255);
    B = 0;
  } else if (v > level_02 && v <= level_1)
  { byte k = map(v, level_02, level_1, 0, 255);
    B = k;
  } else if (v > level_1)
  { byte k = map(v, level_1, 1023, 0, 255);
    B = 255;
  }
  return B;
}
// Управление светодиодом
void SetLED(float v)
{
  analogWrite(Red_pin, GetRed(v));
  analogWrite(Blue_pin, GetBlue(v));
  analogWrite(Green_pin, GetGreen(v));
}
// Инициализация глобальных переменных
int Raw = 0;
int Raw_old = 1000;
int dRaw = 1000;
int zeroline = 0;
uint32_t ms_old = 0;
void SmartHeating(int period, int maxvolts, int maxgrad){
    uint32_t start = millis();
    while ((millis()-start)<600000){ // Если не выполнятся условия за 10 мин, прогрев закончится
        analogWrite(Red_pin, 255);
        analogWrite(Blue_pin, 0);
        analogWrite(Green_pin, 0);
      if (( millis() - ms_old) > period ){ //Установка периода дискретизации
        Raw = analogRead(Sensor_pin); // Получение данных с датчика
        ms_old = millis(); // Отмечаем время последнего измерения
          analogWrite(Red_pin, 0);
          analogWrite(Blue_pin, 255);
          analogWrite(Green_pin, 0);
          
        dRaw = Raw-Raw_old; // Вычисляем скорость измения напряжения (температуры)
        Raw_old = Raw; // Отмечаем последнее напряжение
        //Условия окончания умного прогрева
        if ((Raw < maxvolts)&&(abs(dRaw) < max_grad)){
          break;
        }
        delay(300);
      }
    }
}
void setup() {
  pinMode(Red_pin, OUTPUT); 
  pinMode(Green_pin, OUTPUT); 
  pinMode(Blue_pin, OUTPUT);
  // Heating
  analogWrite(Red_pin, 255);
  analogWrite(Blue_pin, 0);
  analogWrite(Green_pin, 0);
  delay(500);
  analogWrite(Red_pin, 50);
  analogWrite(Blue_pin, 0);
  analogWrite(Green_pin, 0);
  delay(1000);
  analogWrite(Red_pin, 0);
  analogWrite(Blue_pin, 255);
  analogWrite(Green_pin, 0);
  delay(500);
  analogWrite(Red_pin, 0);
  analogWrite(Blue_pin, 50);
  analogWrite(Green_pin, 0);
  delay(1000);
  analogWrite(Red_pin, 0);
  analogWrite(Blue_pin, 0);
  analogWrite(Green_pin, 255); 
  delay(500);
  analogWrite(Red_pin, 0);
  analogWrite(Blue_pin, 0);
  analogWrite(Green_pin, 50); 
  delay(1000); 
  ms_old = millis();
  SmartHeating(20000, 300, max_grad);
  
  zeroline = Raw; 
  ms_old = millis();
}

void loop() {
      if (( millis() - ms_old) > 2000 ){
        Raw = analogRead(Sensor_pin);
        ms_old = millis();
        dRaw = Raw - zeroline;
        if (dRaw < level_0){
          dRaw = level_0;
        }
        SetLED(dRaw);
       }
}

Корпус устройства

Описание программы, сборки и демонстрации устройства смотрите на видео.

Финальная демонстрация

Устройство получилось очень интересное, в этом направлении еще можно дальше работать. Если остались вопросы, что-то не получается – пишите сюда или в группу ВК!

(с) Роман Исаков

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *