Нестандартное решение. Измерение температуры с помощью звуковой платы.

Материал для тех кто "дружит" с паяльником.

© 2003-2005 Альберт Мамедов (MagDelphi)

В настоящее время большинство компьютеров укомплектовано устройствами вывода-ввода звуковых сигналов (звуковыми картами). Если выход звуковых карт задействован, то входы большинство пользователей не используют. Чем можно занять свободные входы? Первое что пришло в голову – измерить температуру.

В звуковых картах нам потребуется:

Так как АЦП звуковых карт принимает только сигналы переменного тока, будем измерять сигнал полученный с выхода простейшего генератора частотой около 100 герц запитанный напряжением полученным с микрофонного входа предназначенным для питания микрофонов.

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

Так как уровень сигнала программно управляется микшером нам необходимо предусмотреть регулировку уровня линейного входа в зависимости от уровня входного сигнала и типа звуковой карты.

Как собственно измерить входной сигнал? Есть несколько способов.

Использование Фурье – анализа (вычисление уровня основной гармоники) из-за сложной формы (обилие гармоник) входного сигнала и недостаточного быстродействия, нецелесообразно.

Пойдём более простым путём, будем интегрировать положительные отсчёты, предварительно синхронизированного  сигнала отдельно для каждого канала. С этим связан и выбор небольшой частоты входного сигнала, как обеспечивающим более устойчивую синхронизацию.

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

Программа состоит из 5 модулей:

В дальнейшем работа программы основана на обработке сообщения MM_WIM_DATA  звуковой платы.

Точность показаний во многом зависит от синхронизации измеряемого сигнала - модуль SoundTemp.pas

Я измеряю количество байтов от начала измеряемого фрейма, до места в котором происходит переход фазы сигнала от + к -.

function faza():integer; //устраняет сдвиг фаз
  var
    i,ni:integer;
    label n1;
begin
  result:=0;
  for i:=400 to 4000 do begin
    s1:= dd[i*4+2];//младший байт
    if s1>$80
      then s1:=-($ff-s1)
      else s1:=0;
    s2:= dd[(i*4+3)];
    if s2 >$80
      then ss:=-(($ff-s2)*$ff)+s1
      else ss:=0;
    if ss=0 then
      begin
        for ni:=i to 2000 do begin //ждем переход на -
          s1:= dd[ni*4+2];//младший байт
          if s1>$80
            then s1:=-($ff-s1)
            else s1:=0;
          s2:= dd[(ni*4+3)];
          if s2 >$80
            then ss:=-(($ff-s2)*$ff)+s1
            else ss:=0;
          if ss<0 then begin // inrange(ss,-20,-2)
            result:=ni;
            goto n1;
          end;
        end;
      end;
    end;
  n1:
end;

Если применить другой алгоритм, то возможно точность улучшиться

Проверка программы на разных компьютерах показала точность измерения не хуже 0.05 градуса, которая зависела от формы сигнала и характеристик звуковой карты.

Прилагаю схему подключения (см. ниже) и исходники программы на Delphi (13.3K).

Вместо стабилитрона возможно применение двух светодиодов.

Возможности данного решения довольно широки: измерение температуры среды, пожарная сигнализация, медицинские измерения, измерение уровня освещенности ( при замене термо на фото резистор).

Буду благодарен исправлениям и изменениям программы улучшающих её характеристики, пишите.

Copyright© 2003-2005 Альберт Мамедов  Специально для Delphi Plus

Rambler's Top100