Множитель импульсов от датчика скорости автомобиля

kirnfs
Offline
Зарегистрирован: 22.07.2020

Всем привет!

Что делает программа:

Считывает с 5 пина входной сигнал частоты в диапазоне 1-300 Герц, переделывает его x3 и выводит новый преобразованный сигнал на 9 пин . Сигнал имеет скважность 50%.

int highTime;
int lowTime;
float period;
int freq;
unsigned int newFreq;

void setup() {
  pinMode(5, INPUT_PULLUP);
  pinMode(9, OUTPUT);
}

void loop() {
  highTime = pulseIn(5, HIGH);
  lowTime = pulseIn(5, LOW);
delay(50);

  period = highTime + lowTime;

  if (period != 0)
  {    
    freq = 1000000 / period;

    Serial.print("FrequencyInput=");
    Serial.println(freq);
    
    if (freq <= 40 || freq> 315)
    {
      goto outt;
    }
    else
    {
    digitalWrite(LED_BUILTIN, HIGH);

    newFreq = freq * 3;

    tone(9, newFreq); 
                    
    digitalWrite(LED_BUILTIN, LOW);   
    }
  }
  else
  {
    outt:
    noTone(9);
  }
}

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

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Ну начнем с того , что tone() ниже 31Гц не умеет.
Этого достаточно ?

b707
Offline
Зарегистрирован: 26.05.2017

строка 15 убивает всю идею

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

kirnfs пишет:
Хочу выслушать замечания

Вы хотите или Вы просите их высказать? А то вон Кикабидзе тоже Ларису Ивановну хотел.

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

Я не знаю такого свойства частоты как "плавность", потому не понимаю о чём это, но если хотите - делайте. Если кто спросит, скажете, что я разрешил.

kirnfs пишет:

Что делает программа:

Считывает с 5 пина входной сигнал частоты в диапазоне 1-300 Герц, переделывает его x3 и выводит новый преобразованный сигнал на 9 пин .

Она этого не делает и делать не может. Задержка в строке №15 пропускает сразу пятнадцать периодов частоты 300Гц в течение которых программа ни на что не реагирует. Это не говоря уже о том, что tone не умеет выдавать меандры меньше 31Гц .

kirnfs пишет:
Сигнал имеет скважность 50%.

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

Ну, и ещё одно замечание: этот раздел предназначен для описания готовых проектов. Решительно непонятно, что делает в нём Ваш пост.

-NMi-
Offline
Зарегистрирован: 20.08.2018

Kakmyc пишет:
Ну начнем с того , что tone() ниже 31Гц не умеет. Этого достаточно ?

Нет конечно.

Бетон вот в зависимости от способа заливки набирает минимальную конструкционную прочность за ~35 суток. Но с бетоном можно "дагавариццо" и бетон может застыть да хоть за час... Так-шо в этой стране tone() может не только ниже 31Гц, а даже -31Гц.

b707
Offline
Зарегистрирован: 26.05.2017

ЕвгенийП пишет:

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

позвольте с Вами поспорить :)

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

Вполне подходит для выражения отношения длины импульса к длине полного периода :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:

позвольте с Вами поспорить :)

Спорьте. Скважность меандра назовите, пожалуйста. Просто числом. А потом спорьте.

kirnfs
Offline
Зарегистрирован: 22.07.2020

Пока конструктива никакого не увидел. Поясню. Строка 15, действительно может быть лишней, но на отвал круиз контроля она никак не повлияла. Думаю ее потом либо убрать совсем, либо уменьшить до 10.

Ну начнем с того , что tone() ниже 31Гц не умеет. Это я знаю, смысл программы в том, что меньше 40 тут и не нужно ничего делать.

Код:

if (freq <= 40 || freq> 315)

27     {
28       goto outt;
29     }

Поясню смысл программы: Она была написана для круиз контроля опель омега, для шевроле Лачетти. У лачетти 6 импульсов датчика скорости на метр, у омеги 18. Поэтому была написана данная программа. Частоту ниже 40 герц мы исключили.

 

 

b707
Offline
Зарегистрирован: 26.05.2017

kirnfs пишет:

Пока конструктива никакого не увидел.

какого конструктива вы ждете при таком подходе? -

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

То, что написано у вас - это не серьезно. Это даже "оптимизировать" нет смысла, ибо в программе практически нет правильного кода. Но если вас устраивает - то дело ваше, не понятно только, каких советов вы тогда ждете.

 

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

kirnfs пишет:
в диапазоне 1-300 Герц

...

Частоту ниже 40 герц мы исключили.

Ты, уж определись, родной. А то плюрализм в одной голове - это шизофрения.

kirnfs
Offline
Зарегистрирован: 22.07.2020

b707 пишет:

kirnfs пишет:

Пока конструктива никакого не увидел.

какого конструктива вы ждете при таком подходе? -

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

То, что написано у вас - это не серьезно. Это даже "оптимизировать" нет смысла, ибо в программе практически нет правильного кода. Но если вас устраивает - то дело ваше, не понятно только, каких советов вы тогда ждете.

Можно примеры? Ссылки? Я с ардуино неделю, выложил то, что работает. Поэтому и обратился сюда, чтобы узнать, есть ли более лучшее решение.

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

kirnfs пишет:
Поэтому и обратился сюда, чтобы узнать, есть ли более лучшее решение.
Себя-то не обманывай. Ты обратился, чтобы тебя погладили по головке и сказали какой ты молодец. Любая другая реакция на твой пост - это "никакого конструктива".

В общем, молодец, всё здорово делаешь!

(это ведь конструктив, пральна?)

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Ещё конструктива:

period = highTime + lowTime;

highTime и lowTime это время в мкс.

Вопрос за каким МПХ понадобился float period ?

kirnfs
Offline
Зарегистрирован: 22.07.2020

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

kirnfs
Offline
Зарегистрирован: 22.07.2020

Ворота пишет:

kirnfs пишет:
Поэтому и обратился сюда, чтобы узнать, есть ли более лучшее решение.
Себя-то не обманывай. Ты обратился, чтобы тебя погладили по головке и сказали какой ты молодец. Любая другая реакция на твой пост - это "никакого конструктива".

В общем, молодец, всё здорово делаешь!

(это ведь конструктив, пральна?)

Сюда обратился, чтобы узнать все ли нормально сделано. Понимаю, что пока нет. Это мне и нужно было узнать, далее буду копать тему и улучшать. Торопился, делал пока именно то, что будет хотя бы работать. Немного подсказали куда смотреть, спасибо.

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Нифига ты не понял, смотреть нужно в сторону:"переписать все полностью"

kirnfs
Offline
Зарегистрирован: 22.07.2020

Kakmyc пишет:
Нифига ты не понял, смотреть нужно в сторону:"переписать все полностью"

Это и подразумевается) Набираю сейчас инфу для этого.

b707
Offline
Зарегистрирован: 26.05.2017

вот, к примеру, в этой теме можно найти примеры, как померить частоту через прерывания:

http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/chtenie-shim-5-kgts

kirnfs
Offline
Зарегистрирован: 22.07.2020

Почитал про аппаратное прерывание.

Вот такой вариант:

volatile int inputFreq = 0;
volatile bool inputFreqFlag = false;
int newFreq = 0;

void setup() {
  pinMode(3, INPUT_PULLUP);
  pinMode(9, OUTPUT);
  attachInterrupt(1, calcInputFreq, CHANGE); //3 digit пин ардуино
  //Serial.begin(9600);
}

void loop() {
  if (inputFreqFlag)
  {
    inputFreqFlag = false;
    digitalWrite(LED_BUILTIN, HIGH);
    newFreq = inputFreq * 3;
    tone(9, newFreq);
    digitalWrite(LED_BUILTIN, LOW);
  }
  noTone(9);
}


void calcInputFreq()
{
  int highTime = pulseIn(5, HIGH);
  int lowTime = pulseIn(5, LOW);
  int period = highTime + lowTime;

  if (period > 0)
  {
    inputFreq = 1000000 / period;
    if (inputFreq > 45 || inputFreq < 300)
    {
      inputFreqFlag = true;
    }
  }
}

Идея ПО следующая: Мне интересен только диапазон входной частоты от 50 до 300 герц.

Т.к. активация круиза происходит со 150 герц (т.е. 50*3).

Тут в одном цикле я проверяю флаг  и по прерыванию обрабатываю входную частоту  и умножаю на 3 с последующим выводом.

Подскажите какие проблемы могут возникнуть в этом примере?

b707
Offline
Зарегистрирован: 26.05.2017

kirnfs пишет:

Подскажите какие проблемы могут возникнуть в этом примере?

работать не будет :)

pulsIn() не работает в прерывании. насколько мне известно.

Кроме того, все переменные, изменяемые в прерывании - должны быть описаны как волатиле.  И еще - прерывание должно выполнятся как можно быстрее, поэтому все лищнее из него надо убирать. В вашем примере - в прерывании надо оставить только строчки 27 и 28, а все вычисления перенести в loop()

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

kirnfs
Offline
Зарегистрирован: 22.07.2020

b707 пишет:

kirnfs пишет:

Подскажите какие проблемы могут возникнуть в этом примере?

работать не будет :)

pulsIn() не работает в прерывании. насколько мне известно.

Кроме того, все переменные, изменяемые в прерывании - должны быть описаны как волатиле.  И еще - прерывание должно выполнятся как можно быстрее, поэтому все лищнее из него надо убирать. В вашем примере - в прерывании надо оставить только строчки 27 и 28, а все вычисления перенести в loop()

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

Замечания понял, попробую доработать. Да, примеры смотрел, учусь)

 

 

kirnfs
Offline
Зарегистрирован: 22.07.2020

Такой пример промежуточный.

Буду думать как заменить pulsein

Придется на  micros переходить)

Kakmyc
Offline
Зарегистрирован: 15.01.2018

kirnfs пишет:

Такой пример промежуточный.

Буду думать как заменить pulsein

Придется на  micros переходить)

Тебе же ссылку дали, читай. Там есть уже практически готовый код

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

kirnfs пишет:

Буду думать как заменить pulsein

Зачем? Вам же сказали, просто вынесите его из прерывания.

Правда в том виде, как у Вас написано, Вам ничто не поможет. Есть три вопроса для размышления:

1. Сколько раз успеет сработать прерывание за время выполнения строчек №№27 и 28?
2. Как изменится работа программы, при срабатывании прерывания по переходам 1->0 и 0->1 ?
3. Например, переменная period оказалась равной 19608 (в строке 29). Частота при этом получается 1000000 / 19608 = 50,999592. А у Вас она округлится до 51 или до 50?