Нужна помощь

Vanya_87
Offline
Зарегистрирован: 31.03.2015

всем привет. новая тема. 

вообщем ситуация такая: на аналоговый пин приходят импульсы,

1) нужно посчитать их кол-во и вывести в значение что бы можно было потом в формулу вбить - это сделано!

2) при отсутствие этих самых импульсов что бы значение становилось равным нулю.

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

написал вот такой вот код:

1   if (millis() - previousMillis > 5)
2 {
3      previousMillis = millis();
4   if (analogRead(SPEED_PIN) == 1)
5      {speed_1;}
6  else if (analogRead(SPEED_PIN) == 1)
7     {speed_1 = 0;}}

надеюсь на Вашу помощь.

Vanya_87
Offline
Зарегистрирован: 31.03.2015

код мой не делает speed_1 = 0 :(

speed_1 - это и есть количество импульсов

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

уже спросил же - это обработка сигналов датчика скорости ( он же датчик Холла ) ?
на стоячей машине сигнал SPEED_PIN может быть и 0 , и 1 .....
speed_1 = 0; надо делать когда импульсы отсутствуют , а не проверкой положения шторки в датчике Холла

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011
SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

точное определение скорости - это замер длительности импульсов с датчика, это использование счётчиков МК и прерываний - сложнова-то....

сделай блок кода подсчёта импульсов за 200 mS , перед выполнением кода обнули переменную колва импульсов , после выполнения кода будешь иметь - колвоИмпульсовЗа200mS и время 200 mS - из этого получить скорость в км/час , аршинов/мин и др. - просто

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

SPEED_PIN  повесь на пин 2 , в обработчике прерывания делаем приращение колва импульсов ( n++ )

измерять скорость за секунду - для ардуины это почти простой....
нужно оценить/измерить сколько импульсов даёт датчик скорости , нпример на скорости 60 км/час за 100 mS - а потом выбирать оптимальное значение длительности строба измерения скорости

Vanya_87
Offline
Зарегистрирован: 31.03.2015

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

Vanya_87
Offline
Зарегистрирован: 31.03.2015

а вот на счет блока кода на 200 mS - можно поподробнее)))

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

ну на сколько я знаю, импульсы с датчика скорости начинают поступать в тот момент когда начинается движение автомобиля
да, но с задержкой на угол поворота датчика ( щас это неважно )
и количество импульсов напрямую зависит от скорости авто
нет ! не колво , а скорость их появления или частота ( в ЭБУ используется длительность этих импульсов, что позволяет измерять скорость более чем ...... пусть 1000 раз в секунду )
то бишь на аналоговый выход
не нужен здесь АНАЛОГОВЫЙ вход ( не выход ) !
приходит +5в при каждом импульсе. автомобиль остановился +5в падает до 0в
или до +5в - датчик может выдать или +5 или 0 , нам не ведомо где он остановился :(
и так продолжается до тех пор пока авто не тронится с места. 
нет ! смотри выше через строку :)

X-Dron
Offline
Зарегистрирован: 24.01.2015
SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Vanya_87 пишет:

а вот на счет блока кода на 200 mS - можно поподробнее)))

попозже, ещё рано...

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

X-Dron пишет:

:) - чтобы сообщение было корочеееееее

...пусть сам поймёт и напишет сам :)

Vanya_87
Offline
Зарегистрирован: 31.03.2015

нашел в инете, кол-во импульсов за 60 мсек = текущей скорости. как это можно кодом выразить?

у меня уже 2 часа ночи, башка уже кипит и не варит ничего))))

 

ладно, писать буду уже завтра, вернее сегодня только днём)))

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

напрямую !
1И за 60 mS = 1 км/час
78И за 60 mS = 78 км/час
.............
280И за 60 mS = 280 км/час :)

но это с учётом что тырнет говорит про вашу машинку !

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

может быть у автопроизводителей есть стандарт ? независимо от КПП, главного дифференциала и др. - всё равно на выходе такая пропорциональность ? надо будет поизучать....

Vanya_87
Offline
Зарегистрирован: 31.03.2015

на этот счет думаю подойдет умножение на n-коофицент который по умолчанию сделаю равным 1, и потом можно будет кооректировать уже скорость этим коофицентом. 

это я понял на счет 1и за 60 ms= 1 км/ч, 78и за 60 ms = 78 км/ч. буду думать как код писать. от подсказки не откажусь. 

 

у меня есть импульсы = speed_1.

мне нужно значение speed_1 за 60 ms))))

 

что то типо такого: 

time = millis(60); - это не подходит)))
 
SPEED = speed_1 ЗА time
 
delay(1000);
вопросы:
какой код написать вместо ЗА ?
как задать величину равной 60 ms ?
Vanya_87
Offline
Зарегистрирован: 31.03.2015

и ещё такой вопрос:

можно ли выставить таймер на чтение порта 940 ms а снизу прописать delay(1000)??

т.е. получается будет считываться порт 60 ms в секунду, потом это значение вывести как то в число.

 

либо импульсы "speed_1" так же на них ввести таймер 940 ms и прописать delay(1000) и полученной величиной и будет моя скорость.

так можно?

Vanya_87
Offline
Зарегистрирован: 31.03.2015

написал вот такой вод код: значение показывает всегда ноль, где ошибка?

const int speedPin = 8;
unsigned long currentTime;
unsigned long loopTime;
unsigned char encoder_speed;
unsigned char encoder_speed_prev=0;
unsigned char speed1;

  
   pinMode(speedPin, INPUT);
  currentTime = millis();
  loopTime = currentTime; 
  
  
  currentTime = millis();
    if(currentTime >= (loopTime + 60))
  {   
    encoder_speed = digitalRead(speedPin);
     if((!encoder_speed) && (encoder_speed_prev))   // если состояние изменилось с положительного к нулю
      if (encoder_speed) {speed1++;}
      else {(speed1 < 1); speed1 = 0;}
  
  encoder_speed_prev = encoder_speed;
  
  loopTime = currentTime;
  }
  
  unsigned int speed2 = speed1 * 1;
  
   lcd.setCursor(0,0); 
   lcd.print("                ");
   lcd.setCursor(0,1);
   lcd.print(" sp: ");
   lcd.setCursor(5,1);
   lcd.print(speed2);

 

vvadim
Offline
Зарегистрирован: 23.05.2012

сам же написал 

else {(speed1 < 1); speed1 = 0;

Vanya_87
Offline
Зарегистрирован: 31.03.2015

ну, 0<1 значит скорость = 0

или я чего то не так понимаю?

Vanya_87
Offline
Зарегистрирован: 31.03.2015

щас исправил на >, тоже ноль))) но думаю правильнее был мой вариант)))

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

 else {(speed1 < 1); speed1 = 0;}  

А что это за конструкция такая ? Может я не знаю чего ? Вот это действие (speed1 < 1) оно ЧТО делает в данном месте ?

У вас строки 18-20 полный сюр. Дали нервно курить в сторонке. Ваш speed1 в данном бреде всегда обязан быть нулем.

Vanya_87
Offline
Зарегистрирован: 31.03.2015

http://nnm.me/blogs/e-troll/arduino-uno-urok-6-enkoder/ - вот здесь я эту конструкцию кода взял, только переделал под свои имена)))

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

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

Vanya_87
Offline
Зарегистрирован: 31.03.2015

убрал 20 строку speed1 стал единицей

Vanya_87
Offline
Зарегистрирован: 31.03.2015

помогите.

таймер на считывания цифрового входа я выставил,

currentTime = millis();
    if(currentTime >= (loopTime + 60))
  {    

    encoder_speed = digitalRead(speedPin);

 

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

 

таймер равен 60 ms

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Без прерываний тут делать нечего.  

Чувствую себя алисой в стране чудес.... не смогу помочь, терпения не хватит у меня , извините. А то тут еще клоуны какие то минусы лепят... Кто бы это мог быть...

Vanya_87
Offline
Зарегистрирован: 31.03.2015

не знаю кто... ну не я уж точно!

внизу этого таймера поставить delay(1000) , забыл просто)))

Vanya_87
Offline
Зарегистрирован: 31.03.2015

если это упростит тебе задачу, нужно так написать:

1 импульс за 60 mS = 1 км/час
78 импульс за 60 mS = 78 км/час
.............
280 импульс за 60 mS = 280 км/час :)

Vanya_87
Offline
Зарегистрирован: 31.03.2015

прописал всё как у вас, показываются только целые числа первая строчка 1000 и вторая строчка 60000. дальше не могу дотумкать что писать и исправлять надо.

датчик скорости посажен на пин D2

можете помочь? пожалуйста!

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

brokly пишет:

Чувствую себя алисой в стране чудес.... не смогу помочь, терпения не хватит у меня , извините. А то тут еще клоуны какие то минусы лепят... Кто бы это мог быть...

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

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Lа не, это я так :) Совсем не расстраиваюсь ! Говорю же сказочный лес :) Попытался помочь и понял, что человек не опечатался, а просто не понимает как работает. Это не плохо, просто у меня на такую помощь сейчас сил нет :(

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да и забей))

Vanya_87
Offline
Зарегистрирован: 31.03.2015

объясняю почему я не понимаю

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

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

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

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
volatile byte nSpeed;            // колво импульсов, если не будете гонять более 255 км/час
//volatile int nSpeed;           // колво импульсов, если    будете гонять более 255 км/час
#define speedPin 2               // для UNO
unsigned long speedMillisOld;    // "секундомер" для замера скорости
const byte speedMillisDelta=60;  // время измерения скорости - 60 mS
boolean getSpeed;
//=========================================================================
void setup()
{
  Serial.begin(9600);
  pinMode(speedPin,INPUT);
  digitalWrite(speedPin,HIGH);
  attachInterrupt(0,speedInterrupt,CHANGE);
  getSpeed=1;
  speedMillisOld=millis();
}
//=========================================================================
void speedInterrupt()
{
  nSpeed++;
}
//=========================================================================
void loop()
{
  if(getSpeed)
  {
    nSpeed=0;
    speedMillisOld=millis();
  }
  else
  {
    if((millis()-speedMillisOld)>speedMillisDelta)
    {
      getSpeed=1;
      Serial.print(" Speed = "); Serial.print(nSpeed); Serial.println(" km / h");
      delay(500);
    }
  }
}
//=========================================================================
// маленький кулер запитайте от VCC-GND , выход датчика Холла кулера подайте на пин 2
// притормаживайте-отпускайте крыльчатку кулера, смотрите в сериал

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

забыл.... надо Serial.print(nSpeed/2) , потому что attachInterrupt(0,speedInterrupt,CHANGE) -  CHANGE.....

Vanya_87
Offline
Зарегистрирован: 31.03.2015

огромнейшее спасибо. я код не много изменил вывода на дисплей:

      lcd.setCursor(0,0);
      lcd.print(" Speed:   ");
      lcd.setCursor(0,1);
      lcd.print("  ");
      lcd.setCursor(2,1);
      lcd.print(nSpeed/2*1);
      lcd.setCursor(4,1);
      lcd.print(" kmh   ");
       delay(500);     
 
у меня почему то Serial.print(...) не работает. уже несколько раз сталкивался, пока построчно не введёшь, не отобразится на дисплее ничего.
SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

lcd.print(nSpeed/2*1);

зачем умножать что-то на 1 ? почему не делить на 1 ? почему не прибавить или не отнять 0 ?
в Мониторе проверьте-выберите скорость как в коде

вставляйте крайнюю свёрнутую версию кода.... 

Vanya_87
Offline
Зарегистрирован: 31.03.2015

а на 1 - это коофицент. проверю скорость и если будет всё правильно показывать то убиру умножить на 1))))

при нажатие на кнопку, когда должен высветиться второй экран у меня вместо него загарается диод на плате "ТХ" и мегает, при этом на экране первая программа, ещё одно нажатие переходит на третий экран... вот так вот, я уже привык, буду так. только не удобно иногда так иногда, символы с пред. экрана остаются)))

если вбиваешь перед вторым экранов lcd.clear();, то экран вообще чистый на второй программе, а если его вбить перед кодом, то экран моргает

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

код-то дай !
....lcd.clear() применяй перед выводом, если новая строка короче - она затрёт часть старой, а хвост от старой строки останется

Vanya_87
Offline
Зарегистрирован: 31.03.2015

вот код, вернее его часть))) при таком коде второй экран мелькает.

void loop() {
  buttonState = digitalRead(buttonPin);
  if (millis() - previousMillis > 300) {
     //Запоминаем время первого срабатывания
     previousMillis = millis();
  if (buttonState == 0)
     {disp++;}}
 else if (disp > 3)
    {disp = 1;} 


switch (disp)
{
case 1: {firstcode(); break;}
case 2: {secondcode(); break;}
case 3: {dcode(); break;}
}
}

void speedInterrupt()
{
  nSpeed++;
}
  
int firstcode()
{
  boolean injector_state = analogRead(INJECTOR_PIN) > 500;
  boolean speed_state = analogRead(SPEED_PIN) > 500;
  unsigned long new_t = micros();
  
  // Вычисление мгновенных значений
    if (injector_state != last_injector_state) {
    if (injector_state) {
      dur = new_t - dur_t;
      if (dur) dur += DURATION_CORR; // Поправочка
      total_duration += dur;
    } else {
      dur_t = new_t;
      dur = 0;
    }
    
    last_injector_state = injector_state;
  }
  
  if (speed_state != last_speed_state) {
    total_ticks++;
    
    last_speed_state = speed_state;
  }
  
  // Действия, которые выполняются раз в секунду
  
  if (new_t >= t) {
    if (!dur) {
      dur = new_t - dur_t;
      if (dur) dur += DURATION_CORR; // Поправочка
      total_duration += dur;
    }
    
    // Отладочная установка значений
    
//    if (period_counter2 < AVG_LENGTH * AVG_REFRESH_PERIODS) {
//      total_duration = 100000;
//      total_ticks = 56;
//    } else if (period_counter2 < 2 * AVG_LENGTH * AVG_REFRESH_PERIODS) {
//      total_duration = 20000;
//      total_ticks = 1;
//    } else {
//      total_duration = 100000;
//      total_ticks = 56;
//    }
    
    d_avg_duration += total_duration;
    d_avg_ticks += total_ticks;
    
    ++period_counter;
//    ++period_counter2;
    
    if (d_avg_ticks >= AVG_REFRESH_TICKS || period_counter >= AVG_REFRESH_PERIODS) {
      // Вычисление средних значений
      
      // total_avg_duration += d_avg_duration - data[avg_counter].duration;
      /// total_avg_ticks += d_avg_ticks - data[avg_counter].ticks;
      
      data[avg_counter].duration = d_avg_duration;
      data[avg_counter].ticks = d_avg_ticks;

      total_avg_duration = 0;
      total_avg_ticks = 0;
      
      for (int i=0; i < AVG_LENGTH; i++) {
        total_avg_duration += data[i].duration;
        total_avg_ticks += data[i].ticks;
      }
      
      period_counter = 0;
      d_avg_duration = 0;
      d_avg_ticks = 0;

      ++avg_counter;
      if (avg_counter >= AVG_LENGTH)
        avg_counter = 0;
    }
    
    // Конвертация значений в физические единицы и вывод на экран

    String s1, s2, s3;
    unsigned int consumption = 0;
    unsigned int avg_consumption = 0;
    
    if (total_ticks > TICKS_TRESHOLD) {
      consumption = 10.0 * CONSUMPTION_FACTOR * total_duration / total_ticks;
    }

    if (total_avg_ticks > TICKS_TRESHOLD) {
      avg_consumption = 10.0 * CONSUMPTION_FACTOR * total_avg_duration / total_avg_ticks;
    }
    
    unsigned int hour_consumption = 10.0 * FUEL_FACTOR * total_duration * HOUR_PERIODS;
    unsigned int spd = RANGE_FACTOR * total_ticks * HOUR_PERIODS;
    
    s1 = String(total_duration, DEC);

    if (total_ticks > TICKS_TRESHOLD) {
      s1 = STR_CUR + format(consumption);
      // s1 = format(consumption);
    } else {
      s1 = STR_CUR + STR_NA;
      // s1 = "n/a ";
    }

    if (total_avg_ticks > TICKS_TRESHOLD) {
      s2 = STR_AVG + format(avg_consumption);
      // s2 = format(avg_consumption);
    } else {
      s2 = STR_AVG + STR_NA;
      // s2 = "n/a ";
    }

    // s2 = "hr: " + format(hour_consumption);
    // s2 = format(hour_consumption);
    
    // s3 = "sp: " + String(spd, DEC);
    // s3 = String(spd, DEC);
    // s3 = String(total_ticks, DEC);
    
    // int iters = 3 - s3.length();
    // int iters = 8 - s3.length();
    
    // for(int i = 0; i < iters; ++i)
    //  s3 = " " + s3;
      
    // int iters2 = 8 - s1.length();
    
    // for(int i = 0; i < iters2; ++i)
    //  s1 = " " + s1;
    
    // s3 += STR_KMH;
    
    lcd.setCursor(0,0);
    lcd.print(s2);
    
    lcd.setCursor(0,1);
    lcd.print(s1);
    
    total_duration = 0;
    total_ticks = 0;
    t = new_t + PERIOD;
  }

 } 

    
int secondcode()
{
  pinMode(speedPin,INPUT);
  digitalWrite(speedPin,HIGH);
  attachInterrupt(0,speedInterrupt,CHANGE);
  getSpeed=1;
  speedMillisOld=millis();
  
    
  if(getSpeed)
  {
    nSpeed=0;
    speedMillisOld=millis();
  }
  else
  {
    if((millis()-speedMillisOld)>speedMillisDelta)
    {
      getSpeed=1;
      
      delay(500);
    }
  }
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(" Speed:   ");
      lcd.setCursor(0,1);
      lcd.print("  ");
      lcd.setCursor(2,1);
      lcd.print(nSpeed/2*1);
      lcd.setCursor(4,1);
      lcd.print(" kmh   ");
       delay(500);      
}

 

Vanya_87
Offline
Зарегистрирован: 31.03.2015

пытался ставить так:

case 1: {firstcode(); break;}
case 2: {lcd.clear(); secondcode(); break;}
case 3: {lcd.clear(); dcode(); break;}
в итоге  так же мелькание экрана(((
 
вот так тоже мелькание:
switch (disp)
{
case 1: {firstcode(); break;}
lcd.clear();
case 2: {secondcode(); break;}
lcd.clear();
case 3: {dcode(); break;}
}

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

боишься за противоправное использование твоего кода ? :) 
дай ВЕСЬ код ! обсуждение и вопросы - по номерам строк....

Vanya_87
Offline
Зарегистрирован: 31.03.2015

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

вот весь код:

#include <LiquidCrystal.h>

#define SPEED_PIN A6 // Номер ноги для датчика скорости
#define INJECTOR_PIN A7 // Номер ноги для форсунки
#define PERIOD 1000000 // Период усреднения текущего расхода и обновления дисплея (микросекунды) - пять секунд

#define IDLE_STROKE_DURATION 21000 // Суммарное время открытия форсунок (милисекунды) за период на холостом ходу
#define IDLE_STROKE_HOUR_CONSUMPTION 1.2 // Часовой расход топлива на холостом ходу (литры в час)
#define TEST_SPEED 60.0 // Контрольная скорость (километры в час) для расчёта коэффициента пробега
#define TEST_TICKS 74 // Число импульсов с датчика скорости за период на контрольной скорости

#define HOUR_PERIODS ( 3600000000.0 / PERIOD ) // Число периодов в часу
#define FUEL_FACTOR ( IDLE_STROKE_HOUR_CONSUMPTION / HOUR_PERIODS / IDLE_STROKE_DURATION ) // Коэффициент расхода топлива (литры) за период
#define RANGE_FACTOR ( TEST_SPEED / TEST_TICKS / HOUR_PERIODS ) // Коэффициент пробега (километры) за период
#define CONSUMPTION_FACTOR ( 100.0 * FUEL_FACTOR / RANGE_FACTOR ) // Коэффициент километрового расхода топлива (литры на 100 км)

#define TICKS_TRESHOLD 1 // Порог (импульсы датчика скорости) за период, выше которого можно считать километровый расход
#define DURATION_CORR 0 // Поправка при измерении длительности времени открытия одной форсунки (микросекунды)
#define AVG_LENGTH 10 // Число периодов для усреднения

#define AVG_REFRESH_TIME 1 // Время в часах, после которого сбрасывается усреднённый километровый расход, если не было сброса по расстоянию (1 час)
#define AVG_REFRESH_LENGTH 0.1 // Расстояние в километрах, после которого сбрасывается усреднённый километровый расход (100 м)
#define AVG_REFRESH_PERIODS ( AVG_REFRESH_TIME * HOUR_PERIODS ) // Число периодов между обновлениями среднего расхода
#define AVG_REFRESH_TICKS ( AVG_REFRESH_LENGTH / RANGE_FACTOR ) // Число импульсов датчика скорости между обновлениями среднего расхода

// Строковые константы
#define STR_AVG String(" Cp:")
#define STR_CUR String("Mgn:")
#define STR_NA String(" n/a")
#define STR_KMH String("\xBA\xBC/\xC0")

LiquidCrystal lcd(12, 10, 6, 5, 4, 3);

unsigned long dur;
unsigned long dur_t;
unsigned long t;

boolean last_injector_state;
boolean last_speed_state;

unsigned long total_duration;
unsigned long total_ticks;
unsigned long total_avg_duration;
unsigned long total_avg_ticks;
unsigned long d_avg_duration;
unsigned long d_avg_ticks;
int period_counter;
// int period_counter2;

// Структура, описывающая данные для усреднения
struct consumption_data {
  unsigned int duration;
  word ticks; 
};

struct consumption_data data[AVG_LENGTH];
int avg_counter;
const int buttonPin = 9;
int buttonState = 0;
int disp = 1;
long previousMillis = 0;


volatile byte nSpeed;            // колво импульсов, если не будете гонять более 255 км/час
//volatile int nSpeed;           // колво импульсов, если    будете гонять более 255 км/час
#define speedPin 2               // для UNO
unsigned long speedMillisOld;    // "секундомер" для замера скорости
const byte speedMillisDelta=60;  // время измерения скорости - 60 mS
boolean getSpeed;


void setup() {
  Serial.begin(9600);
  lcd.begin(8, 2);
 
  pinMode(buttonPin, INPUT);
  
  
  t = micros() + PERIOD;
  pinMode(INJECTOR_PIN, INPUT);
  pinMode(SPEED_PIN, INPUT);
   
  
  last_injector_state = analogRead(INJECTOR_PIN) > 500;
  last_speed_state = analogRead(SPEED_PIN) > 500;
  
  
  dur = 0;
  dur_t = micros();
  total_duration = 0;
  total_ticks = 0;
  total_avg_duration = total_duration;
  total_avg_ticks = total_ticks;
  d_avg_duration = total_duration;
  d_avg_ticks = total_ticks;
  
  // Инициализация данных для усреднения
  for (int i=0; i < AVG_LENGTH; ++i) {
    data[i].duration = 0;
    data[i].ticks = 0;
  }
  
  period_counter = 0;
//  period_counter2 = 0;
  avg_counter = 0;
}

void loop() {
  buttonState = digitalRead(buttonPin);
  if (millis() - previousMillis > 300) {
     //Запоминаем время первого срабатывания
     previousMillis = millis();
  if (buttonState == 0)
     {disp++;}}
 else if (disp > 3)
    {disp = 1;} 


switch (disp)
{
case 1: {firstcode(); break;}
case 2: {secondcode(); break;}
case 3: {dcode(); break;}
}
}

void speedInterrupt()
{
  nSpeed++;
}
  
int firstcode()
{
  boolean injector_state = analogRead(INJECTOR_PIN) > 500;
  boolean speed_state = analogRead(SPEED_PIN) > 500;
  unsigned long new_t = micros();
  
  // Вычисление мгновенных значений
    if (injector_state != last_injector_state) {
    if (injector_state) {
      dur = new_t - dur_t;
      if (dur) dur += DURATION_CORR; // Поправочка
      total_duration += dur;
    } else {
      dur_t = new_t;
      dur = 0;
    }
    
    last_injector_state = injector_state;
  }
  
  if (speed_state != last_speed_state) {
    total_ticks++;
    
    last_speed_state = speed_state;
  }
  
  // Действия, которые выполняются раз в секунду
  
  if (new_t >= t) {
    if (!dur) {
      dur = new_t - dur_t;
      if (dur) dur += DURATION_CORR; // Поправочка
      total_duration += dur;
    }
    
    // Отладочная установка значений
    
//    if (period_counter2 < AVG_LENGTH * AVG_REFRESH_PERIODS) {
//      total_duration = 100000;
//      total_ticks = 56;
//    } else if (period_counter2 < 2 * AVG_LENGTH * AVG_REFRESH_PERIODS) {
//      total_duration = 20000;
//      total_ticks = 1;
//    } else {
//      total_duration = 100000;
//      total_ticks = 56;
//    }
    
    d_avg_duration += total_duration;
    d_avg_ticks += total_ticks;
    
    ++period_counter;
//    ++period_counter2;
    
    if (d_avg_ticks >= AVG_REFRESH_TICKS || period_counter >= AVG_REFRESH_PERIODS) {
      // Вычисление средних значений
      
      // total_avg_duration += d_avg_duration - data[avg_counter].duration;
      /// total_avg_ticks += d_avg_ticks - data[avg_counter].ticks;
      
      data[avg_counter].duration = d_avg_duration;
      data[avg_counter].ticks = d_avg_ticks;

      total_avg_duration = 0;
      total_avg_ticks = 0;
      
      for (int i=0; i < AVG_LENGTH; i++) {
        total_avg_duration += data[i].duration;
        total_avg_ticks += data[i].ticks;
      }
      
      period_counter = 0;
      d_avg_duration = 0;
      d_avg_ticks = 0;

      ++avg_counter;
      if (avg_counter >= AVG_LENGTH)
        avg_counter = 0;
    }
    
    // Конвертация значений в физические единицы и вывод на экран

    String s1, s2, s3;
    unsigned int consumption = 0;
    unsigned int avg_consumption = 0;
    
    if (total_ticks > TICKS_TRESHOLD) {
      consumption = 10.0 * CONSUMPTION_FACTOR * total_duration / total_ticks;
    }

    if (total_avg_ticks > TICKS_TRESHOLD) {
      avg_consumption = 10.0 * CONSUMPTION_FACTOR * total_avg_duration / total_avg_ticks;
    }
    
    unsigned int hour_consumption = 10.0 * FUEL_FACTOR * total_duration * HOUR_PERIODS;
    unsigned int spd = RANGE_FACTOR * total_ticks * HOUR_PERIODS;
    
    s1 = String(total_duration, DEC);

    if (total_ticks > TICKS_TRESHOLD) {
      s1 = STR_CUR + format(consumption);
      // s1 = format(consumption);
    } else {
      s1 = STR_CUR + STR_NA;
      // s1 = "n/a ";
    }

    if (total_avg_ticks > TICKS_TRESHOLD) {
      s2 = STR_AVG + format(avg_consumption);
      // s2 = format(avg_consumption);
    } else {
      s2 = STR_AVG + STR_NA;
      // s2 = "n/a ";
    }

    // s2 = "hr: " + format(hour_consumption);
    // s2 = format(hour_consumption);
    
    // s3 = "sp: " + String(spd, DEC);
    // s3 = String(spd, DEC);
    // s3 = String(total_ticks, DEC);
    
    // int iters = 3 - s3.length();
    // int iters = 8 - s3.length();
    
    // for(int i = 0; i < iters; ++i)
    //  s3 = " " + s3;
      
    // int iters2 = 8 - s1.length();
    
    // for(int i = 0; i < iters2; ++i)
    //  s1 = " " + s1;
    
    // s3 += STR_KMH;
    
    lcd.setCursor(0,0);
    lcd.print(s2);
    
    lcd.setCursor(0,1);
    lcd.print(s1);
    
    total_duration = 0;
    total_ticks = 0;
    t = new_t + PERIOD;
  }

 } 

    
int secondcode()
{
  pinMode(speedPin,INPUT);
  digitalWrite(speedPin,HIGH);
  attachInterrupt(0,speedInterrupt,CHANGE);
  getSpeed=1;
  speedMillisOld=millis();
  
    
  if(getSpeed)
  {
    nSpeed=0;
    speedMillisOld=millis();
  }
  else
  {
    if((millis()-speedMillisOld)>speedMillisDelta)
    {
      getSpeed=1;
      
      delay(500);
    }
  }
      lcd.clear(); 
      lcd.setCursor(0,0);
      lcd.print(" Speed:   ");
      lcd.setCursor(0,1);
      lcd.print("  ");
      lcd.setCursor(2,1);
      lcd.print(nSpeed/2*1);
      lcd.setCursor(4,1);
      lcd.print(" kmh   ");
       delay(500);      
}



int dcode()
{
    lcd.setCursor(0,0);
    lcd.print("Hello   ");
    lcd.setCursor(0,1);
    lcd.print("Hello   ");
}

  String format(unsigned int dec) {
  if (dec > 1000) return String("##.#");
  
  unsigned int intPart = dec / 10;
  unsigned int fracPart = dec % 10;
  String result = String(intPart, DEC) + "," + String(fracPart, DEC);

  int iters = 4 - result.length();  
  for(int i = 0; i < iters; ++i)
    result = " " + result;

  return result;
}

 

Vanya_87
Offline
Зарегистрирован: 31.03.2015

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

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

каша :( , зачем за всё сразу взялись ? 
обрисуйте сначала задачи - обработка кнопки для смены отображения на дисплее , замер скорости , вывод трёх экранов - потом дальше пойдёте :)
...а функции объявляются отдельно ( не в лупе, не в сетапе )

щас поломаю вам код :)

Vanya_87
Offline
Зарегистрирован: 31.03.2015

для Вас может быть и каша, а для меня на первое время удобно))) каждому экрану соответсвует своя функция - главное что бы нормально работало)))

Vanya_87
Offline
Зарегистрирован: 31.03.2015

ты мне дай код который нужно вствить, а я уже сам посмтрю куда его вставлять)))

или вставляй, я потом посмотрю как он должен стоять и потом решу куда его вставлять)))

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

фигВам ! я не хочу ковыряться в каше :(
тибе решать как применять мои каракули :)-
...ещё минут через 10

Vanya_87
Offline
Зарегистрирован: 31.03.2015

ВОПРОС: можно ли подать напряжение на аналоговый вход от 0 до 6 вольт и что бы это показывалось на экране? интересут не код программы а именно возможность работы платы Ardruino Nano v3 обработки такого низкого напряжения?

Vanya_87
Offline
Зарегистрирован: 31.03.2015

SU-27-16 пишет:

фигВам ! я не хочу ковыряться в каше :(
тибе решать как применять мои каракули :)-
...ещё минут через 10

 

ок))))