Модернизация Контроллера охлаждения для ПК. Проблема с сигналом тахометра. Помогите новичку!

Stark43

✩✩✩✩✩✩✩
28 Мар 2021
6
0
Цель: Дублирование сигнала тахометра из сети в 12в на Ардуино чтобы определить момент остановки потока жидкости (пузырьки, ошибка остановки ротора.)

Необходимо одновременно получать сигнал с датчика потока материнской платой и Ардуино.

Фото 1.

Датчик подключается в 3Pin кулера материнской платы 12В. Ардуино получает 5 В по USB.

По сути датчик потока SLF-V3 работает как кулер, но без пина управления.

Подключая напрямую к Ардуино, и даже двум, всё работает через прерывание. Скетч могу привести. Фото2.

Подключая одновременно напрямую, через делитель напряжения, или через оптрон PC817 материнская плата перестаёт получать сигнал, срабатывает защита. Фото3. Последний вариант подсмотрел на форумах автомобилистов, но он тоже не работает. (Фото 4).

Я понимаю, что нужна какая-то гальваническая развязка из-за разностей в вольтажах сетей.

Между сигнальным и землёй при подключении только к 3 Pin материнки вольтаж колеблется от 7,5 до 9В в зависимости от текущих оборотов.

Цель.jpg
Работает.jpg
НЕ РАБОТАЕТ1.jpg
НЕ РАБОТАЕТ_2.jpg
сигнал_осцилограф.png

Заранее большое спасибо!
 

kostyamat

★★★★★★✩
29 Окт 2019
1,098
631
@Stark43, а кто вам сказал, что сигнал с тахометра имеет размах 12в? Если бы это было так, я думаю с ардуино вы бы уже попрощались. Там делитель наверное просто не нужен?
 

Stark43

✩✩✩✩✩✩✩
28 Мар 2021
6
0
@Stark43, а кто вам сказал, что сигнал с тахометра имеет размах 12в? Если бы это было так, я думаю с ардуино вы бы уже попрощались. Там делитель наверное просто не нужен?
до Как я написал выше, я замерял вольтаж между сигнальным проводом и минусом. На выходе было от 7 до 9 вольт. Подозреваю что это зависит от текущих оборотов.
 

kostyamat

★★★★★★✩
29 Окт 2019
1,098
631
@Stark43, ну ок, возможно краткий импульс не успевает убить ардуино. Тогда решение такое - поставить резистор килоома на два, и после него вход ардуино зашунтировать на землю стабилитроном (diod zener) на напряжение, 3.3-4.7 вольта. Ставить катодом (минусом) ко входу, анодом (плюсом) к земле. Зенер будет обрезать пики напряжения, которые выше напряжения собственного пробоя.
 

Stark43

✩✩✩✩✩✩✩
28 Мар 2021
6
0
@Stark43, ну ок, возможно краткий импульс не успевает убить ардуино. Тогда решение такое - поставить резистор килоома на два, и после него вход ардуино зашунтировать на землю стабилитроном (diod zener) на напряжение, 3.3-4.7 вольта. Ставить катодом (минусом) ко входу, анодом (плюсом) к земле. Зенер будет обрезать пики напряжения, которые выше напряжения собственного пробоя.
Спасибо за совет. Вы такую схему имели ввиду?
Работает Стабилитрон.jpg

К сожалению под рукой не оказалось ни одного стабилитрона с напряженим стабилизации ниже 9в. Потому пока не проверил.

Что вы думаете о делателе напряжения вместо оптрона рисунок 4 ? с двумя резисторами по 10K получаю по середине 4.6В. С доп резитсором в 1К к земле вроде всё работает. Но пугает что при ~7В в основной цепи получаю примерно 4.9 на ардуино. Сигнал идёт, только сбиваются характеристики примерно каждую третью секунды. (считаю через прерывание: attachInterrupt(digitalPinToInterrupt(Pulses), rpm, CHANGE);)
 

kostyamat

★★★★★★✩
29 Окт 2019
1,098
631
@Stark43, да, схема правильная, только резистор может быть великоват, открыть стабилитрон тока может не хватить. Думаю киллоома два самое то.
Делитель тоже нормально, расчитайте по большему напряжению, оно у вас 7-9в. Вот из этого исходите. Ардуино регистрирует нормально от 3.1в до 5.5в.

А вот прерывание - зачем вы считаете по обоим фронтам импульса? Там достаточно либо FALLING, либо RISING. У вас сейчас на каждый импульс два раза прерывание происходит. Зачем спамить бедный контроллер?
 

Stark43

✩✩✩✩✩✩✩
28 Мар 2021
6
0
@Stark43,

А вот прерывание - зачем вы считаете по обоим фронтам импульса? Там достаточно либо FALLING, либо RISING. У вас сейчас на каждый импульс два раза прерывание происходит. Зачем спамить бедный контроллер?
Спасибо за совет, честно не помню почему я выбрал изменение. Чтото было связано с результирующей точностью получаемой.

Сам блок встроен в переделанный скетч гайвера PCDisplay.


Обороты и расход потока:
[CODE=cpp]

void setup() {
    ....
  attachInterrupt(digitalPinToInterrupt(Pulses), rpm, CHANGE);  // считать изменение состояния датчика потока на пине Pulses - D3
  ...
}

void getFLOWdata()                             // Flow Sensor
{
  if (millis() - myTimer1 >= PERIOD)          // ищем разницу (500 мс)
  {
    // выполнить действие 1
    // 2 раза в секунду
    myTimer1 += PERIOD;

    // так как прерывание CHANGE, срабатывает два раза то и считываем каждые пол секунды.
    rpmCount = ((val*60)/2);  // количество импульсов на 60 секунд
   //   Serial.print(rpmCount);   //Debug
 
    // Количество литров за минуту = RPM / Калибровку
    l_minutes = (rpmCount / Calibration); // (Pulse frequency x 60 min) / 8.6Q = flowrate in L/hour

    // и делим на количество импульсов на оборот
 //   Serial.print(" Rpm / ");
 //   Serial.print(val);
 //   Serial.print(" val / ");
 //   Serial.print(l_minutes);
 //   Serial.println(" L/minute");

    val = 0; // сбрасываем счетчик и ждем.
  }
}

void rpm()
{
  val++;      //Increment the variable on every pulse
}
[/CODE]
 

PiratFox

★★★★★✩✩
13 Фев 2020
1,707
474
@Stark43, в качестве альтернативы. В С++ есть функция измерения длительности импульса, поступившего на вход МК pulseln(). Подробнее здесь.
 

kostyamat

★★★★★★✩
29 Окт 2019
1,098
631
Вот это совершенно не правильно. Вроде как бы логично, но таки не правильно. Подумайте почему. Подсказка- на обсчет и вывод в порт тоже тратится время, а millis()-myTimer1>=PERIOD не жесткое условие, и предполагает сдвиг относительно PERIOD. К тому же, при переполнении переменной myTimer1 у вас все это просто перестанет работать.
Так что,
myTimer1=millis():
Второй момент: перед обсчетом и выводом делайте детач прерывания, а потом снова атач, иначе прерывания будут продолжать вам накручивать счетчик, даже когда вы уже обсчитываете значения.
 
Изменено:

Stark43

✩✩✩✩✩✩✩
28 Мар 2021
6
0
Избыточное цитирование
Вот это совершенно не правильно. Вроде как бы логично, но таки не правильно. Подумайте почему. Подсказка- на обсчет и вывод в порт тоже тратится время, а millis()-myTimer1>=PERIOD не жесткое условие, и предполагает сдвиг относительно PERIOD. К тому же, при переполнении переменной myTimer1 у вас все это просто перестанет работать.
Так что,
myTimer1=millis():
Второй момент: перед обсчетом и выводом делайте детач прерывания, а потом снова атач, иначе прерывания будут продолжать вам накручивать счетчик, даже когда вы уже обсчитываете значения.
Про первое понятно, но если просто заменить в верхнем скетче
myTimer1 += PERIOD;
показания стали в 10 меньше, значения на экране меняются настолько быстро что трудно разлечить конкретное значение. Мой вариант работал но переполнение таймера действительно было (просто это было почти не заметно, ардуино довольно часто рестартует из-за работы по usb, питание по которому на 0.3 секунды пропадает при подключении чего либо к компу -ХЗ почему)

Сейчас с старым вариантом работает правлеьно, но ошибается на +-1, тоесть в таймер вместо 17 стандартных импульсов иногда попадает либо 16 либо 18. Но добавив среднее значение вроде практически удалось победить всплески (наверно надо больше число брать (sum / 10))

Я нашел у Алекса таймер с защитой от переполнения, отлично работает.
также я добавил в код detachInterrupt
C++:
// Пульсы тахометра
void rpm()
{
  val++;      //Increment the variable on every pulse
}

void getFLOWdata()                             // Flow Sensor
{
int val_avarrage;

  if (millis() - tahoTimer1 >= PERIOD2)          // ищем разницу (1000 мс)
  {
    // выполнить действие 1
    // 1 раза в секунду

    // отключаем прерывание  
    detachInterrupt(digitalPinToInterrupt(Pulses));

    // прерывание CHANGE срабатывает два раза, считывая каждую секунду делим на 4.
    // 86 IMP / L
    // For 1 liter per minute= 8.6* 1 liter * 60 seconds = 450 pulses  (8.6 *1 *60 = 516)

    // среднее значение из 2 прерываний
    val_avarrage = ((val + val_previous)/ 2);

    rpm_temp = ((val_avarrage*60)/4);        // количество импульсов на 60 секунд
    rpmCount = int(rpm_temp);                // количество импульсов на 60 секунд  
  
    // Количество литров за минуту = RPM / Калибровку
    l_minutes = (rpm_temp / Calibration);   // (Pulse frequency x 60 min) / 8.6Q = flowrate in L/hour

    val_previous = val;
    val = 0; // сбрасываем счетчик.

    // Включаем снова
    attachInterrupt(digitalPinToInterrupt(Pulses), rpm, CHANGE);

    do {
        tahoTimer1 += PERIOD2;
      if (tahoTimer1 < PERIOD2) break;  // переполнение uint32_t
    } while (tahoTimer1 < millis() - PERIOD2); // защита от пропуска шага
  }
}

Про детач прерывания это хорошая идлея, добавил в код, но на результаты это не повлияло..
 
Изменено:

Stark43

✩✩✩✩✩✩✩
28 Мар 2021
6
0
@Stark43, в качестве альтернативы. В С++ есть функция измерения длительности импульса, поступившего на вход МК pulseln(). Подробнее здесь.
Спасибо, я на неё уже смотрел, дело в том что сами импульсы одинаковы практически всегда (исключение, первые 3 секунды старта помпы). В остольное время меняется только количество импульсов.
 

vrangel3

✩✩✩✩✩✩✩
13 Май 2024
3
0
Всем привет, прохожу тот же путь, что и автор этого топика.
Кто-нибудь может объяснить, почему не работает схема 4 с оптроном?
Ардуино сигнал получает, но материнская плата его детектировать перестает.
Получается, включение диода в схему искажает изначальный сигнал?
 
Изменено:

Геннадий П

★★★★★★✩
14 Апр 2021
1,945
619
44
Кто-нибудь может объяснить, почему не работает схема 4 с оптроном?
Ардуино сигнал получает, но материнская плата его детектировать перестает.
Ответ тот же, почему и светодиод нельзя подключать напрямую.
 

vrangel3

✩✩✩✩✩✩✩
13 Май 2024
3
0
Ответ тот же, почему и светодиод нельзя подключать напрямую.
Геннадий, спасибо за ответ. Забыл написать, что ток на оптроне ограничивал резистором, конечно. Все, что справа от оптрона работает. Но вот внесение оптрона в схему, судя по всему, вносит какие-то изменения в параметры сигнала и устройство (motherboard на схеме) перестает их детектировать. Вот думаю, что же это может быть такое и как это устранить. Осцилографа нет, к сожалению, чтоб измерить.
 

poty

★★★★★★✩
19 Фев 2020
3,154
926
@vrangel3, без подробной схемы со всеми забытыми примочками ничего сказать невозможно.