Как посчитать количество импульсов на цифровом порту

elbugs
Offline
Зарегистрирован: 02.09.2016

Добрый день.

Делаю контроллер двигателя (дизельного) от рефрежератора. (на микрухе Atmega 328 boot уже залил в нее)

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

Подскажите как организавать подсчет скорости вращения коленвала програмно???

Нужно написать функцию при вызове которой на цифровом порту считались бы импульсы (от датчика хола или геркона).  которая бы возвращала 1- если двигатель уже завелся  и 0 - если еще не завелся.

Т.е. если столько то импульсов в секунду значит двигатель работает и нужно выключать стартер - вернуть 1

      а если меньше то возращаем 0 т.е. крутим стартером дальше.

Ребят помогите уже всю голову сломал. Я не программист великий поэтому не могу понять как это сделать.

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

Заранее благодарен,

Александр

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Поиск по форуму, в правом верхнем углу, волшебные слова - "подсчёт количества оборотов".

elbugs
Offline
Зарегистрирован: 02.09.2016

Все что нашел это подсчет через прерывания. (не хочется их использовать)

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

elbugs пишет:

Все что нашел это подсчет через прерывания. (не хочется их использовать)

Не используйте, раз не хочется. Хотя странно - почему вдруг не хочется, особенно если учесть, что это практически единственный расово верный подход? Впрочем, настаивать не буду, не хочется - не используйте.

elbugs
Offline
Зарегистрирован: 02.09.2016

DIYMan пишет:

elbugs пишет:

Все что нашел это подсчет через прерывания. (не хочется их использовать)

Не используйте, раз не хочется. Хотя странно - почему вдруг не хочется, особенно если учесть, что это практически единственный расово верный подход? Впрочем, настаивать не буду, не хочется - не используйте.

        Мне впринципе точно знать не нужно. Нужно просто посчитать импульсы и если они больше какого то значения выключить стартер.

elbugs
Offline
Зарегистрирован: 02.09.2016

Вот нашел что то не можите закоментить. а то не все понятно

01 const int tachPIN=2;
02 const unsigned long sampleTime=1000;
03 const int maxRPM = 10200;
04  
05 void setup()
06     {
07     pinMode(tachPIN, INPUT);
08     digitalWrite(tachPIN, HIGH); //Turns on pullup resistor on pin.   
09     Serial.begin(9600);
10     }
11  
12 void loop()
13  
14 {
15     int rpm=getRPM();
16     Serial.print("RPM: ");
17     Serial.print(rpm);
18     Serial.print("\n");
19 }
20  
21 int getRPM()
22  
23 {
24   // sample for sampleTime in millisecs
25   int kount=0;
26   boolean kflag=LOW;
27   unsigned long currentTime=0;
28   unsigned long startTime=millis();
29   while (currentTime<=sampleTime)
30 {
31  
32 if (digitalRead(tachPINPin)==HIGH)
33     {
34      kflag=HIGH;
35     }
36  
37 if (digitalRead(tachPINPin)==LOW && kflag==HIGH)
38     {
39     kount++;
40     kflag=LOW;
41     }
42  
43 currentTime=millis()-startTime;
44 }
45  
46 int kount2rpm = int(60000./float(sampleTime))*kount;
47 return kount2rpm;
48  
49 }

 

di_mot
Offline
Зарегистрирован: 12.08.2016

DIYMan пишет:

... особенно если учесть, что это практически единственный расово верный подход?

А кто-то или что-то запрещает использовть внутренний таймер в режиме "счета" с внешнего входа?

Обыденное дело для "частотомера".

 

di_mot
Offline
Зарегистрирован: 12.08.2016

elbugs пишет:

        Мне впринципе точно знать не нужно. Нужно просто посчитать импульсы и если они больше какого то значения выключить стартер.

10 (или 100) импульсов - это много или мало?

За год, месяц, день, час - разница как бы не слабая.

Так что само кол-во импульсов - ни чего не говорит.

А если импульсы за какое-то определенное время, то это уже тахометр. :-)

Вариантов - множество программых и меньше аппаратных реализаций "тахометра" на МК.

elbugs
Offline
Зарегистрирован: 02.09.2016

di_mot пишет:

elbugs пишет:

        Мне впринципе точно знать не нужно. Нужно просто посчитать импульсы и если они больше какого то значения выключить стартер.

10 (или 100) импульсов - это много или мало?

За год, месяц, день, час - разница как бы не слабая.

Так что само кол-во импульсов - ни чего не говорит.

А если импульсы за какое-то определенное время, то это уже тахометр. :-)

Вариантов - множество программых и меньше аппаратных реализаций "тахометра" на МК.

За секунду.

Я там вроде нашел примерчик пока разбираюсь как он работает.  (выкладывал выше)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну скорее всего вам надо, что бы при достижении нужного количества оборотов на одной ноге Uno появилась 1.

Так что в основом потоке идет подсчет оборотов вала. Скорее всего подсчет переходов от 0 в 1 . Разумеется с учетом дребезга на датчике. Второй вычислительный поток (Прерывание или millis()) просто сбрасывает счетчик оборотов при достижении какого-то периода времени. (1 секунда, 0.1 секунда). Если мотор набрал нужные обороты, счетчик импульсов досчитал до установленого числа, то на ногу выставляется 1.

Алгоритм готов. А дальше надо узнать с какой скоростью вращается завевшийся двигатель. На это Uno ответить не может.

elbugs
Offline
Зарегистрирован: 02.09.2016

qwone пишет:

Ну скорее всего вам надо, что бы при достижении нужного количества оборотов на одной ноге Uno появилась 1.

Так что в основом потоке идет подсчет оборотов вала. Скорее всего подсчет переходов от 0 в 1 . Разумеется с учетом дребезга на датчике. Второй вычислительный поток (Прерывание или millis()) просто сбрасывает счетчик оборотов при достижении какого-то периода времени. (1 секунда, 0.1 секунда). Если мотор набрал нужные обороты, счетчик импульсов досчитал до установленого числа, то на ногу выставляется 1.

Алгоритм готов. А дальше надо узнать с какой скоростью вращается завевшийся двигатель. На это Uno ответить не может.

Не совсем так. на ноге мне не нужна еденица.

Мне нужна функция проверки завелся ли двигатель. Она будет использована для выключения стартера и для определения нужно ли заводить двигатель если такая команда поступит от другого контроллера.

Считать нужно не постоянно а только при вызове функции из других участков кода. и она должна выдать 1 если двигатель работает (завелся) или 0 если не работает не завелся

Выложил бы схемму контроллера но не знаю как.

 

elbugs
Offline
Зарегистрирован: 02.09.2016

 

elbugs
Offline
Зарегистрирован: 02.09.2016

как картинку сделать больше не знаю

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

di_mot пишет:

DIYMan пишет:

... особенно если учесть, что это практически единственный расово верный подход?

А кто-то или что-то запрещает использовть внутренний таймер в режиме "счета" с внешнего входа?

Обыденное дело для "частотомера".

Читаем внимательно, а не бросаемся сразу с голой ж. на ежа: я написал "практически единственный". Вы предлагаете ТС щас в таймеры сунуться, если он ни в зуб даже с той простейшей реализацией подсчёта по прерываниям, что так любезно вытащено наружу и выставлено, что та проститутка на Ленинградке? Если что - я про attachInterrupt.

Именно поэтому и написал "практически единственный". Да в любом случае, как ни крути - "практически единственный" != "единственный". Давайте не будем придираться к частностям.

elbugs
Offline
Зарегистрирован: 02.09.2016

Пытался через форум выложить он жмет картинку до 23кб

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вы не великий программист. А я к сожелению, или к счастью, не великий учитель невеликих программистов. Если вы хотите вычислять через функцию. То у вас уже три вычислительных потока наклевывается. Один - это ваша система. 2 счетчик оборотов, 3 сбос счетчика в нужное время. То что 2 и 3 потоки надо выключать этого не меняет.  Так что вам то что вы намечтали не по зубам. А мне объяснить вам,что надо нанимать человека в месте где вы живете для решения ваших желаний.

elbugs
Offline
Зарегистрирован: 02.09.2016

пока скетч моего контроллера так выглядит

#include <Wire.h>               //Библиотека для работы с I2C
#include <LiquidCrystal_I2C.h>  //Библиотека для работы с экраном
                // Присваиваем портам имена 
#define ERROR_IGNOR_BAT    0    //Кнопка игнорирования (квитирования) аварии
#define MAN_AVTOM_BAT      1    //Кнопка выбора режима (ручной автоматический)
#define HEAT_BAT           2    //Кнопка предпускового прогрева
#define STARTER_BAT        3    //Кнопка стартера
#define T_SENS             4    //Датчик перегрева двигателя
#define HI_SPEED_COMMAND   5    //Вход сигнал команда Акселератора (команда нажать на газ)
#define START_COMMAND      6    //Вход сигнал команда завести двигатель
#define P_OIL_SENS         7    //Датчик аварийного давления масла
#define TOSOL_LEVEL_SENS   8    //Датчик уровня тосола
#define STARTER_RELAY      9    //Реле стартера
#define HEAT_RELAY         10   //Реле предпускового подогрева
#define FUIL_RELAY         11   //Реле клапана топлива и возбуждение генератора
#define HI_SPEED_RELAY     12   //Реле Акселератора (нажать на газ)
#define P_REF_SENS         13   //Датчик аварийного давления фреона
#define RPM_SENS           14   //Датчик оборотов двигателя
#define AMPER_SENS         A1   //Датчик зарядки аккумулятора
#define ALT_SENS           A2   //Датчик напряжения на генераторе
               //Присваеваем значения переменным которые нужно будет подбирать опытным путем
#define RPM                300  //Кнстанта числа оборотов по которой проверяется завелся ли двигатель                          
 
 
void setup() 
{
  // Определяем режим работы портов
   pinMode(ERROR_IGNOR_BAT, INPUT); 
   pinMode(MAN_AVTOM_BAT, INPUT);
   pinMode(HEAT_BAT, INPUT);
   pinMode(STARTER_BAT, INPUT);
   pinMode(T_SENS, INPUT);
   pinMode(HI_SPEED_COMMAND, INPUT);
   pinMode(START_COMMAND, INPUT);
   pinMode(P_OIL_SENS, INPUT);
   pinMode(TOSOL_LEVEL_SENS, INPUT);
   pinMode(STARTER_RELAY, OUTPUT);
   pinMode(HEAT_RELAY, OUTPUT);
   pinMode(FUIL_RELAY, OUTPUT);
   pinMode(HI_SPEED_RELAY, OUTPUT);
   pinMode(P_REF_SENS, INPUT);
   pinMode(RPM_SENS, INPUT);
}
 
void loop() 
{
int mode = checkMode(); //Проверяем в каком режиме работать
if (mode == 0){manModeWithAlarm();}     // Если получаем 0 то запускаем функ ручного режима с контролем параметров
if (mode == 1){manModNoAlarm();}        //Если получаем 1 то запускаем функ ручного режима без контроля параметров
if (mode == 2){autoModeWithAlarm();}    //Если получаем 2 то запускаем функ автомат режима с контролем параметров
if (mode == 3){autoModNoAlarm();}       //Если получаем 3 то запускаем функ автом режима без контроля параметров
}
 
//ПИШЕМ РАЗЛИЧНЫЕ ФУНКЦИИ
// Функция проверки режима работы 
int checkMode()
{
  if (digitalRead(MAN_AVTOM_BAT)==LOW && digitalRead(ERROR_IGNOR_BAT)==LOW)  //Если кнопки режима автомата и квитирования ошибки не нажаты
  {
    return 0;                                                                //Возвращаем режим 0 - это ручной режим работы с контролем парамметров
  }
  else if (digitalRead(MAN_AVTOM_BAT)==LOW && digitalRead(ERROR_IGNOR_BAT)==HIGH)  //Если кнопка режима автомата не нажата а кнопка квитирования ошибки нажата
  {
    return 1;                                                                //Возвращаем режим 1 - это ручной режим работы без контроля парамметров
  }
  else if (digitalRead(MAN_AVTOM_BAT)==HIGH && digitalRead(ERROR_IGNOR_BAT)==LOW)  //Если кнопка режима автомата  нажата а кнопка квитирования ошибки не нажата
  {
    return 2;                                                                //Возвращаем режим 2 - это автоматический режим работы с контролем парамметров
  }
 
  else if (digitalRead(MAN_AVTOM_BAT)==HIGH && digitalRead(ERROR_IGNOR_BAT)==HIGH)  //Если кнопки режима автомата и кнопка квитирования ошибки нажаты
  {
    return 3;                                                                //Возвращаем режим 3 - это автоматический режим работы без контроля парамметров
  }
}
 
//Функция ручного режима работы без контроля аварий 
void manModNoAlarm()
 {
  digitalWrite(FUIL_RELAY, HIGH);            // Включаем подачу топлива и возбуждение генератора
  if (digitalRead(HEAT_BAT)==HIGH)           // Если кнопка подогрева нажата
     {
      digitalWrite(HEAT_RELAY, HIGH);        //Включаем реле подогрева
     }
     else                                    // Если не нажата
     {
      digitalWrite(HEAT_RELAY, LOW);         //Выключаем подогрев
     }
     
  if (digitalRead(STARTER_BAT)==HIGH)        // Если кнопка стартера нажата
     {
      digitalWrite(STARTER_RELAY, HIGH);     //Включаем реле стартера
     }
     else                                    // Если не нажата
     {
      digitalWrite(STARTER_RELAY, LOW);      //Выключаем реле стартера
     }
  acselerator();                       //Запуск функции акселератора
 }   
 
// Функция ручного режима работы с контролем аварий 
 
void manModeWithAlarm()
{
 digitalWrite(FUIL_RELAY, HIGH);            // Включаем подачу топлива и возбуждение генератора
  if (digitalRead(HEAT_BAT)==HIGH)           // Если кнопка подогрева нажата
     {
      digitalWrite(HEAT_RELAY, HIGH);        //Включаем реле подогрева
     }
     else                                    // Если не нажата
     {
      digitalWrite(HEAT_RELAY, LOW);         //Выключаем подогрев
     }
     
  if (digitalRead(STARTER_BAT)==HIGH)        // Если кнопка стартера нажата
     {
      digitalWrite(STARTER_RELAY, HIGH);     //Включаем реле стартера
     }
     else                                    // Если не нажата
     {
      digitalWrite(STARTER_RELAY, LOW);      //Выключаем реле стартера
     }
  acselerator();                           //Запуск подпрограммы акселератора
  int mode=checkEngine();                  //Проверяем завелся ли двигатель
  if (mode==1)
    {
      delay(3000);                         //Ждем 3 сек пока вырастит давление масла
      int error=totalAlarmControl();       //Запускаем функцию контроля критических параметров
       if (error>0) 
          {
           digitalWrite(FUIL_RELAY, LOW);  //Глушим двигатель
           printTotalError(error);         //Выводим на экран что случилось
           return;                         //Если авария выходим из функции  (ВОЗМОЖНО НУЖНО ДОПИСАТЬ ВЫХОД СО ЗНАЧЕНИЕМ ЧТОБЫ НЕЛЬЗЯ БЫЛО ЗАПУСТИТЬ БЕЗ УСТРАНЕНИЯ ОШИБКИ)
          }
       return; //Если двигатель не запустился выходим из функции и она исполнится снова
    }       
       
}
 
// Функция автоматического режима с контролем аварий
 
void autoModeWithAlarm()
{
  if ((digitalRead(START_COMMAND)==HIGH) && (checkEngine()==1)) //Если есть сигнал на старт и двигатель запущен
  
    {
                       acselerator();                       //Запуск функции акселератора
                       int error=totalAlarmControl();       //Запускаем функцию контроля критических параметров
                       if (error>0) 
                         {
                          digitalWrite(FUIL_RELAY, LOW);  //Глушим двигатель
                          printTotalError(error);         //Выводим на экран что случилось
                          return;                         //Если авария выходим из функции  (ВОЗМОЖНО НУЖНО ДОПИСАТЬ ВЫХОД СО ЗНАЧЕНИЕМ ЧТОБЫ НЕЛЬЗЯ БЫЛО ЗАПУСТИТЬ БЕЗ УСТРАНЕНИЯ ОШИБКИ)
                         }
     }
  else if (digitalRead(START_COMMAND)==LOW) //Если команды на старт нет 
         {
          digitalWrite(FUIL_RELAY, LOW);    //Глушим двигатель
          return;
         }
 else if ((digitalRead(START_COMMAND)==HIGH) && (checkEngine()==0) && (prestartTest()==1)) //Если команда на запуск есть и двигатель не запущен и он может быть запущен
        {
         startEngine();                        //Запускаем двигатель
         acselerator();                       //Запуск функции акселератора
              int error=totalAlarmControl();       //Запускаем функцию контроля критических параметров
              if (error>0) 
                {
                 digitalWrite(FUIL_RELAY, LOW);  //Глушим двигатель
                 printTotalError(error);         //Выводим на экран что случилось
                 return;                         //Если авария выходим из функции  (ВОЗМОЖНО НУЖНО ДОПИСАТЬ ВЫХОД СО ЗНАЧЕНИЕМ ЧТОБЫ НЕЛЬЗЯ БЫЛО ЗАПУСТИТЬ БЕЗ УСТРАНЕНИЯ ОШИБКИ)
                 }          
        } 
}
 
// Функция автоматического режима без контроля аварий
 
int autoModNoAlarm()
{
      // Пока не написана
}
 
// Функция контроля критически важных для двигателя параметров (температура двигателя, давление масла, давление фреона) возвращает код сработки 1-3
int totalAlarmControl()
{
   // Пока не написана
}
 
// Функция контроля параметров (не критических - уровень тосола, зарядка аккумулятора, напряжение в сети) 
int alarmControl()
{
   // Пока не написана
}
 
// Функция проверки запущен ли двигатель. Возвращает 1 если да и 0 если нет 
int checkEngine()
{
   // Пока не написана
}
 
// Функция запуска двигателя
int startEngine()
{
   // Пока не написана
}
 
// Функция вывода на экран ошибки по номеру ошибки
void printTotalError(int errNum)
{
   // Пока не написана планирую использовать свич кейс
}
 
// Функция акселератора (добавить газу)
void acselerator()
{
   if (digitalRead(HI_SPEED_COMMAND)==HIGH)   // Если поступила команда нажать на газ
     {
      digitalWrite(HI_SPEED_RELAY, HIGH);    //Включаем реле акселератора
     }
   else                                    // Если нет команды
     {
      digitalWrite(HI_SPEED_RELAY, LOW);     //Выключаем реле акселератора
     }
}
 
// Функция проверки возможности запуска двигтеля
int prestartTest()
{
   // Пока не написана 
}
arduino328
Offline
Зарегистрирован: 01.09.2016

elbugs пишет:

Мне нужна функция проверки завелся ли двигатель. Она будет использована для выключения стартера и для определения нужно ли заводить двигатель если такая команда поступит от другого контроллера.

Считать нужно не постоянно а только при вызове функции из других участков кода. и она должна выдать 1 если двигатель работает (завелся) или 0 если не работает не завелся

Вызываете функцию, получаете два импульса, меряете между ними время, вычисляете обороты.

Если же использовать прерывания, то время и обороты можно вычислять в самой функции прерывания, а в основном скетче полученные значения нужно будет лишь сравнить с нужными.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

С какой частотой вращается двигатель?

elbugs
Offline
Зарегистрирован: 02.09.2016

qwone пишет:

С какой частотой вращается двигатель?

    либо 900 если газ не нажат 

    либо 1300 если газ нажат.

в качестве газа электромагнит

но импульсы помоему по зубам маховика считаются. 

завтра посмотрю

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Надо сначало узнать с какой скоростью идут импульсы. А потом уже думать про реализацию.

elbugs
Offline
Зарегистрирован: 02.09.2016

Завтра постараюсь раздобыть осцилограф и померяю.

Я его другу просто отдал.

di_mot
Offline
Зарегистрирован: 12.08.2016

elbugs пишет:

    либо 900 если газ не нажат 

    либо 1300 если газ нажат.

Ели стартер от аккамулятора, то:

1. Еще нужно знать кол-во оборотов когда стартер крутит коленвал, а запуск двига не произошел.

2. Контролировать время "пуска". Что бы не насиловать акк непрерывным "Пуском".

3. Контролировать напряжение на батарейке. Перед "Пуском" (пускать или в акке фига-с-малой) и во время запуска (под нагрузкой), что бы не угробить акк в ноль.

4. Вопить "Алярмы" в случае неисправностей и прочего. ;-)

Из личного и горького опыта. :-)

elbugs
Offline
Зарегистрирован: 02.09.2016

Вот подключил осцилограф к датчику. Причем все провода от него отключены. Он (датчик) сам вырабатывает импульсы. Предполагаю, что он не зубъя считает а прохождение магнита.

фото с осцилографа ниже.  Это двигатель работает на холостых оборотах. 

Только я не пойму показания частоты. пока осцилограф не подключен показывает 0.000Hz  а когда начинаю мерить сигнал, показывает 2.300 КС на холостых и 3.000КС на полных оборотах.

 Не пойму что это за еденица измерения такая КС. (осцилограф DSO 203)

http://saveimg.ru/show-image.php?id=ee386bb858ad0fd5c96a8d8e65dca55e

http://saveimg.ru/show-image.php?id=e1a6d88623b7fbf129169f7cae554159

Сам датчик

http://saveimg.ru/show-image.php?id=57a82612cc4c4bdfbb389d302b135238

Видео замера

  https://youtu.be/FkHMbOvFMlE аналоговый вход осцилографа

  https://youtu.be/7fR62NfTmEA цифровой вход правда случайно делитель включил.

Когда провода от родного контролера были подключины сигнал показывал +-5Вольт

Ну и схемка будующего контроллера

http://saveimg.ru/show-image.php?id=047a0210610728640982892846341b85

elbugs
Offline
Зарегистрирован: 02.09.2016

все таки присматриваюсь к прерываниям. 

ребят прокоментируйте картинки выше....

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну вот, наверно , надо сделать тестовую программу. Ну у которой дисплей и на которые выводится частота импульсов с датчиков. А потом подсоединить к датчику и включить машину в режиме работы стартера и двигателя. Без этого ну ни как.

ВН
Offline
Зарегистрирован: 25.02.2016

elbugs пишет:
    либо 900 если газ не нажат     либо 1300 если газ нажат. 

elbugs пишет:
   ...когда начинаю мерить сигнал, показывает 2.300 КС на холостых и 3.000КС на полных оборотах. 

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

 

elbugs пишет:
Вот подключил осцилограф к датчику. Причем все провода от него отключены. Он (датчик) сам вырабатывает импульсы. Предполагаю, что он не зубъя считает а прохождение магнита.

Мало похоже на магнит, а на зубья - похоже.

900 об/мин это 15 об/сек, а на осциле, по меньшей мере, видна цена клетки 500мкс и периеод синуса в нее, клетку, примерно укладывается. Т.е. 2.300КС похожи таки на килогерцы и 2300/15 дает 153 зуба на один оборот.

Дальше можно прикинуть диаметр маховика и получить вполне вменяемые значения . 

evgta
Offline
Зарегистрирован: 02.09.2016

elbugs пишет:

все таки присматриваюсь к прерываниям. 

ребят прокоментируйте картинки выше....

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

Для контроля исправности генератора и работы двигателя использовать датчик давления масла.

elbugs
Offline
Зарегистрирован: 02.09.2016

 

[/quote]

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

Для контроля исправности генератора и работы двигателя использовать датчик давления масла.

[/quote]

 

Пока двигатель выйдет на стабильные обороты стартер будет крутить. ( а это не есть хорошо)

по датчику давления то же

Все датчики (кроме давления масла)  при нормально режиме  работы замкнуты. При наступлении аварии размыкаются. Датчик масл наоборот замыкается. С написанием этого кода проблем не будет. 

elbugs
Offline
Зарегистрирован: 02.09.2016

qwone пишет:

Ну вот, наверно , надо сделать тестовую программу. Ну у которой дисплей и на которые выводится частота импульсов с датчиков. А потом подсоединить к датчику и включить машину в режиме работы стартера и двигателя. Без этого ну ни как.

   Я так и планирую сделать.

elbugs
Offline
Зарегистрирован: 02.09.2016

ВН пишет:

elbugs пишет:
    либо 900 если газ не нажат     либо 1300 если газ нажат. 

elbugs пишет:
   ...когда начинаю мерить сигнал, показывает 2.300 КС на холостых и 3.000КС на полных оборотах. 

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

 

elbugs пишет:
Вот подключил осцилограф к датчику. Причем все провода от него отключены. Он (датчик) сам вырабатывает импульсы. Предполагаю, что он не зубъя считает а прохождение магнита.

Мало похоже на магнит, а на зубья - похоже.

900 об/мин это 15 об/сек, а на осциле, по меньшей мере, видна цена клетки 500мкс и периеод синуса в нее, клетку, примерно укладывается. Т.е. 2.300КС похожи таки на килогерцы и 2300/15 дает 153 зуба на один оборот.

Дальше можно прикинуть диаметр маховика и получить вполне вменяемые значения . 

 

   Не согласен. Если датчик это катушка (предполагаю т.к. от него отключены все провода а он дает импульсы +-8Вольт) то либо весь венец маховика это магнит, либо есть несколько магнитов. Сегодня разберу посмотрю.

  Диаметр впринципе не обязательно прикидывать. надо зубья посчитать и если счетчик насчитает 153 зуба то это 1 оборот.

Показывал картинки на других форумах все говорят что КС - это килоциклы что равно килогерцы

Я правельно понимаю.

 

evgta
Offline
Зарегистрирован: 02.09.2016

elbugs пишет:

Пока двигатель выйдет на стабильные обороты стартер будет крутить. ( а это не есть хорошо)

по датчику давления то же.

стабильные имеется ввмду что двигатель уже работает сам без стартера и это около 400 об/мин

а давление масла для контроля за двигателем (его всеравно надо использовать), т.е условия:

1) если после 5 сек после запуска непоявилось давление масла или пропало во время работы - двигатель заглушить, 

2) если давление есть а на генераторе минус - стартер не включать, неисправен генератор или датчик давления масла.

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

evgta
Offline
Зарегистрирован: 02.09.2016

elbugs пишет:

   Не согласен. Если датчик это катушка (предполагаю т.к. от него отключены все провода а он дает импульсы +-8Вольт) то либо весь венец маховика это магнит, либо есть несколько магнитов. Сегодня разберу посмотрю.

 

Магнитные (индуктивного типа). Датчики коленвала этого типа не требуют для себя отдельного источника питания. Для сигнала ЭБУ напряжение индуцируется в тот момент, когда зуб синхронизации проходит сквозь магнитное поле, образованное вокруг датчика. Помимо контроля за оборотами коленвала, датчик коленвала используется и как датчик скорости.

те магнит на самом датчике и при прохождении зуба меняется магнитное датчика и соответственно индуцируется эдс

elbugs
Offline
Зарегистрирован: 02.09.2016

evgta пишет:

Магнитные (индуктивного типа). Датчики коленвала этого типа не требуют для себя отдельного источника питания. Для сигнала ЭБУ напряжение индуцируется в тот момент, когда зуб синхронизации проходит сквозь магнитное поле, образованное вокруг датчика. Помимо контроля за оборотами коленвала, датчик коленвала используется и как датчик скорости.

те магнит на самом датчике и при прохождении зуба меняется магнитное датчика и соответственно индуцируется эдс

        Снял датчик. Действительно в самом датчике есть магнит (ключ к нему прилипает) и считает он действительно зубья коленвала.

Итак по результатам измерения имеем следующие данные:

1. Количество зубов на маховике 108 шт

2. Частота сигнала при вращении стартера (двигатель не заведен) 393 Гц

    Это получается 393/108=3,63 об/сек (помоему это как то не реально)

3. Частота сигнала на холостых оборотах 2,3 кГц

    это 2300/108=21,29 об/сек если умножить на 60 = 1277 об/мин (тоже крутовато для дизеля)

Может я чего не правельно считаю???

evgta
Offline
Зарегистрирован: 02.09.2016

elbugs пишет:

Может я чего не правельно считаю???

Я так понял что это стационарный двигатель, для них нормальное условие работать с постоянными оборотами, при увеличении нагрузки обороты не меняются.  обзем дизеля то какой? на слабофорсировнных дизелях обычно рабочие обороты 1500-2000

ВН
Offline
Зарегистрирован: 25.02.2016

elbugs пишет:
Может я чего не правельно считаю??? 

ну если тока еще раз зубья маховика пересчитать  

 

elbugs
Offline
Зарегистрирован: 02.09.2016

evgta пишет:

Я так понял что это стационарный двигатель, для них нормальное условие работать с постоянными оборотами, при увеличении нагрузки обороты не меняются.  обзем дизеля то какой? на слабофорсировнных дизелях обычно рабочие обороты 1500-2000

[/quote]

        Это дизель 2,2 литра объемом. Холодильная установка Thermoking SBIII.

Я просто уверен что стартер не может крутить двигатель со скоростью 3,6 об/сек. это видно невооружонным глазом

elbugs
Offline
Зарегистрирован: 02.09.2016

ВН пишет:

elbugs пишет:
Может я чего не правельно считаю??? 

ну если тока еще раз зубья маховика пересчитать  

 

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

elbugs
Offline
Зарегистрирован: 02.09.2016

А не может датчик давать несколько импульсов на 1 зуб??

evgta
Offline
Зарегистрирован: 02.09.2016

elbugs пишет:

А не может датчик давать несколько импульсов на 1 зуб??

вот читайте http://diagramas.diagramasde.com/otros/Manual%20de%20Mantenimiento%20SB%20III%2030%20y%2050.pdf

1425-1475 низкие обороты(мин обороты)

2175-2225 высокие обороты(максимальные обороты)

elbugs
Offline
Зарегистрирован: 02.09.2016

evgta пишет:

elbugs пишет:

А не может датчик давать несколько импульсов на 1 зуб??

вот читайте http://diagramas.diagramasde.com/otros/Manual%20de%20Mantenimiento%20SB%20III%2030%20y%2050.pdf

1425-1475 низкие обороты(мин обороты)

2175-2225 высокие обороты(максимальные обороты)

 

За книжку огромное спасибо.

У меня получается обороты примерно 1333 даже меньше чем положено. Значит датчик считает верно.

Тепер о программной реализации. Вот скетч счетчика оборотов по прерываниям. Правельно ли я закоментил каждую строку??? (если я его правельно понимаю то буду его как то изменять под свои нужды)

#define RPMpin 2 // Опдеделяем порт с которого будем считать импульсы
volatile unsigned long microsold = 0;// Присваеваем переменной времяни последнего вызова прерывания значение 0
volatile int rpm = 0; //Присваеваем переменной значения оборотов в минуту значение 0

void setup() { 
  Serial.begin(9600); //запускаем сириал монитор
  digitalWrite(RPMpin, 1); // ??? как на порт ввода можно подать сигнал +5V ??? и зачем 
  attachInterrupt(0, RPM, FALLING);//запускаем прерывания ловим переход от 1 к 0 (помоему нужно ловить плюсы иначе прийдется ограничивать ток резистором)??????
}

void loop() {
  Serial.println(rpm, DEC); // Выводим на экран значение об/мин  
}
void RPM (){                                    // объявляем функц прерывания
  rpm = (1000000.0/(micros() - microsold))*60;  // 1 секунду делим на (разницу между времянем включения ардуины и времянем последнего вызова прерывания) умнож на 60 
  microsold = micros();// присваиваем последнему времяни сработки прерывания знчение времяни с момента запуска ардуины. ??? эта переменная поидеи когда то должна переполниться????
}

 

evgta
Offline
Зарегистрирован: 02.09.2016

 

micros() раз в 70 минут

ну тут на случай неверного отсчета надо делать выборку из 10-20 значений из них отбрасывать 4 верхних и 4 нижних а по оставшимся делать усреднение.

также не помешает при переходе к функции прерывания отключать прерывание и потом включать прерывание по выходу из функции

elbugs
Offline
Зарегистрирован: 02.09.2016

evgta пишет:

 

micros() раз в 70 минут

ну тут на случай неверного отсчета надо делать выборку из 10-20 значений из них отбрасывать 4 верхних и 4 нижних а по оставшимся делать усреднение.

также не помешает при переходе к функции прерывания отключать прерывание и потом включать прерывание по выходу из функции

    Чего то я совсем запутался. 

Получается, что время работы моего контроллера будет ограничено 70-ю минутами после чего он сдохнет???

Мне впринципе точные значения не нужны.

Мне достаточно если частота импульсов выше 500Гц (у меня когда стартер крутит осцил показывает 383Гц) нужно сообщить программе 1 т.е. двигатель завелся. или 0 если не завелся.

Это нужно чтобы знать когда выключать стартер и нужно ли его включать если пришла команда с другого контроллера завести двигатель.

 

 

evgta
Offline
Зарегистрирован: 02.09.2016

как-то так обороты определяются, а лучше всетаки снимать с контрольного провода генератора плюс и не мучать себе голову с считыванием оборотов

 
#define RPMpin 2 // Опдеделяем порт с которого будем считать импульсы
 
unsigned long xxx = 0;
 
unsigned long yyy = 0; 
unsigned long zzz=0;
unsigned long fff=0; 
 
void setup() {
 
  Serial.begin(9600); //запускаем сириал монитор
  attachInterrupt(0, RPM, FALLING);//запускаем прерывания ловим переход от 1 к 0 (помоему нужно ловить плюсы иначе прийдется ограничивать ток резистором)??????
 
}
 
 
 
void loop() {
 
  Serial.println(fff, DEC); // Выводим на экран значение об/мин 
zzz=0;
 
attachInterrupt(0, RPM, FALLING);
xxx=micros();
while(1)
{
yyy=micros()-xxx;
if (yyy>100000){break;}
}
detachInterrupt(0);
fff=(zzz*600)/108;
 
}
 
void RPM (){                                   
zzz++;
}
 
elbugs
Offline
Зарегистрирован: 02.09.2016

evgta пишет:

как-то так обороты определяются, а лучше всетаки снимать с контрольного провода генератора плюс и не мучать себе голову с считыванием оборотов

 
#define RPMpin 2 // Опдеделяем порт с которого будем считать импульсы
 
unsigned long xxx = 0;
 
unsigned long yyy = 0; 
unsigned long zzz=0;
unsigned long fff=0; 
 
void setup() {
 
  Serial.begin(9600); //запускаем сириал монитор
  attachInterrupt(0, RPM, FALLING);//запускаем прерывания ловим переход от 1 к 0 (помоему нужно ловить плюсы иначе прийдется ограничивать ток резистором)??????
 
}
 
 
 
void loop() {
detachInterrupt(0);
  Serial.println(fff, DEC); // Выводим на экран значение об/мин 
zzz=0;
 
attachInterrupt(0, RPM, FALLING);
xxx=micros();
while(1)
{
yyy=micros()-xxx;
if (yyy>100000){break;}
}
detachInterrupt(0);
fff=(zzz*600)/108;
 
}
 
void RPM (){                                   
zzz++;
}
 

Спасибо. Чейчас попытаюсь разобраться что Вы написали.

evgta
Offline
Зарегистрирован: 02.09.2016

вот оно же, но под другим соусом,тоже должно работать

 
 
unsigned long xxx = 0;
unsigned long yyy = 0; 
unsigned long zzz=0;
 
 
void setup() {
pinMode(2, INPUT);
 Serial.begin(9600); 
 detachInterrupt(0);
}
 
 
 
void loop() 
{
Serial.println(zzz);
   attachInterrupt(0, RPM, FALLING);
     zzz=0;
     for(xxx=micros(); yyy<100000; yyy=micros()-xxx){  }
   detachInterrupt(0);
zzz=(zzz*600)/108; 
}
 
void RPM ()
{                                   
zzz++;
}

 

 

evgta
Offline
Зарегистрирован: 02.09.2016

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

с выборкой 20 результатов и усреднением по ним

ну тут надо в живую смотреть и возможно поправки (+ или -) в pulseIn до расчетов вносить

long yyy = 0;
long zzz = 0; 
int xxx;
void setup() 
{
 pinMode(8, INPUT);
 Serial.begin(9600); 
}
void loop() 
{   
     zzz=0;
    for(xxx=0; xxx<20; xxx++)
    {
    yyy = pulseIn(2, LOW);
     yyy=yyy*2;
     yyy=1000000/yyy;
     yyy=yyy*60;
     yyy=yyy/108; 
    zzz =zzz+yyy;
    }
   zzz=zzz/20;
   Serial.println(zzz);
} 

 

elbugs
Offline
Зарегистрирован: 02.09.2016

Спасибо огромное evgta.

Сейчас лег в больницу на 3 дня для плановой операции. Как выпишусь буду пробовать. 

О результатах отпишусь.

  

elbugs
Offline
Зарегистрирован: 02.09.2016

evgta пишет:

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

с выборкой 20 результатов и усреднением по ним

ну тут надо в живую смотреть и возможно поправки (+ или -) в pulseIn до расчетов вносить

long yyy = 0;
long zzz = 0; 
int xxx;
void setup() 
{
 pinMode(8, INPUT);
 Serial.begin(9600); 
}
void loop() 
{   
     zzz=0;
    for(xxx=0; xxx<20; xxx++)
    {
    yyy = pulseIn(2, LOW);
     yyy=yyy*2;
     yyy=1000000/yyy;
     yyy=yyy*60;
     yyy=yyy/108; 
    zzz =zzz+yyy;
    }
   zzz=zzz/20;
   Serial.println(zzz);
} 

 

В 14 стороке помоему порт не тот указан??? Поидее 8-й порт будет.

elbugs
Offline
Зарегистрирован: 02.09.2016

А можно напрямую на порт ардуины сигнал от датчика оборотов +8Вольт??? Или лучще через оптопару

pc817 Завязать???

 

evgta
Offline
Зарегистрирован: 02.09.2016

напрямую думаю лучше не стоит, я бы подсоединил последовательно керамический конденсатор и между конденсатором и ногой МК защитный диод 4,7в(односторонний) или стабилитрон одной ногой а другой к массе , и второй контакт датчика тоже посадил бы на массу.

Но это мои предположения, может кто и получше знает как делать