Подсчет оборотов.

Protez1999
Offline
Зарегистрирован: 08.07.2012

Есть программа показывающая время с начала включения и количество оборотов в минуту. Подскажите пожалуйста как мне еще сделать чтоб она показывала общий пройденый путь( количество всех импульсов счас они сбрасывается каждую секунду).  Никак не догоню как мне rpmcount сохранить

volatile byte rpmVse;
volatile byte rpmcount;
unsigned int rpm; // сохраняем обороты
unsigned long timeold; // сохраняем время старое
int mMin;

#include <LiquidCrystal.h> // библиотека экрана
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);



void setup()
 {
   Serial.begin(9600);
   lcd.begin(16, 2);  // инициализируем дисплей

   //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
   //Triggers on FALLING (change from HIGH to LOW)
   attachInterrupt(0, rpm_fun, FALLING);// функция прерывания только при смене значения с 1 на 0
   rpmVse = 0;
   rpmcount = 0;
   rpm = 0;
   timeold = 0;
 }

 void loop()
 {
   //Обновляем значения каждую секунду
   delay(1000);
   //Don't 
   detachInterrupt(0);  // порт 
   //Если прерывание будет происходить один раз за оборот тогда 60*1000/(millis() - timeold)*rpmcount
   //если количество пребываний больше, то просто делим количество секунд в минуте на количество
   //прерываний за один оборот.
      rpm = 60*1000/(millis() - timeold)*rpmcount;
   timeold = millis();
   rpmcount = 0;

   //Выводим результат на дисплей
   lcd.clear();
   lcd.print("RPM=");
   lcd.print(rpm);
 //rpm = mMin;
 mMin = rpm*3/100; // метры в минуту если на 60 
Serial.print(mMin);Serial.print("M/m");
   //Перезапустить процесс прерывания
   attachInterrupt(0, rpm_fun, FALLING);
  
  }
  
  void rpm_fun()
   {
   //обновляем счетчик
      rpmcount++;// прибавляем единицу к полученому
      }

 

Protez1999
Offline
Зарегистрирован: 08.07.2012

Извиняюсь скинул код без часов но это не так важно. 

maksim
Offline
Зарегистрирован: 12.02.2012

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

volatile unsigned int rpmcount = 0;// сохраняем обороты

#include <LiquidCrystal.h> // библиотека экрана
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);  // инициализируем дисплей
  attachInterrupt(0, rpm_fun, FALLING);// функция прерывания только при смене значения с 1 на 0
}

void loop()
{
  delay(1000); //Обновляем значения каждую секунду
  lcd.clear();
  lcd.print(rpmcount); //Выводим результат на дисплей
  Serial.print(rpmcount);

}

void rpm_fun()
{
  rpmcount++;// прибавляем единицу к полученому
}

 

Protez1999
Offline
Зарегистрирован: 08.07.2012

Ниче не понял. я хочу одновременно и замерять скорсоть и считать количество оборотов (растояние) 

maksim
Offline
Зарегистрирован: 12.02.2012

Пропустил слово "еще", тогда как то так:

volatile byte rpmVse;
volatile byte rpmcount;
unsigned int rpm; // сохраняем обороты
unsigned long timeold; // сохраняем время старое
int mMin;
volatile unsigned int dist, distantion = 0;


#include <LiquidCrystal.h> // библиотека экрана
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);



void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);  // инициализируем дисплей

  //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
  //Triggers on FALLING (change from HIGH to LOW)
  attachInterrupt(0, rpm_fun, FALLING);// функция прерывания только при смене значения с 1 на 0
  rpmVse = 0;
  rpmcount = 0;
  rpm = 0;
  timeold = 0;
}

void loop()
{
  //Обновляем значения каждую секунду
  delay(1000);

  rpm = 60*1000/(millis() - timeold)*rpmcount;
  timeold = millis();
  rpmcount = 0;
  
  //Выводим результат на дисплей
  lcd.clear();
  lcd.print("RPM=");
  lcd.print(rpm);
 
  mMin = rpm*3/100; // метры в минуту если на 60 
  Serial.print(mMin);
  Serial.print("M/m");
  Serial.print(" ");
  
  distantion = dist*12; // 12 это диаметр колеса при условии, что срабатывание происходит 1 раз за 1 оборот
  Serial.print("Distantion ");
  Serial.println(dist);
 
}

void rpm_fun()
{
  //обновляем счетчик
  rpmcount++;// прибавляем единицу к полученому
  dist++;
}

 

Protez1999
Offline
Зарегистрирован: 08.07.2012

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

unsigned long time;
volatile int rpmVse;
volatile byte rpmcount;
unsigned int rpm; // сохраняем обороты
unsigned long timeold; // сохраняем время старое
int mMin;

#include <LiquidCrystal.h> // библиотека экрана
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);



void setup()
 {
   Serial.begin(9600);
   lcd.begin(16, 2);  // инициализируем дисплей

   //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
   //Triggers on FALLING (change from HIGH to LOW)
   attachInterrupt(0, rpm_fun, FALLING);// функция прерывания только при смене значения с 1 на 0
   rpmVse = 0;
   rpmcount = 0;
   rpm = 0;
   timeold = 0;
 }

 void loop()
 {
   //Обновляем значения каждую секунду
   delay(1000);
   //Don't 
   ////////////
     time = millis();
 int sek = time/1000;  
 int minyt = (time/1000)/60;
 int cas = (minyt/60);
 int minyt2 = minyt;
  if(cas>0) minyt2 =(minyt-60*cas);
   if((time/1000)>60) sek =(sek-60*minyt);
   
   
   ///////////
   detachInterrupt(0);  // порт 
   //Если прерывание будет происходить один раз за оборот тогда 60*1000/(millis() - timeold)*rpmcount
   //если количество пребываний больше, то просто делим количество секунд в минуте на количество
   //прерываний за один оборот.
      rpm = 60*1000/(millis() - timeold)*rpmcount;
   timeold = millis();
   rpmcount = 0;

   //Выводим результат на дисплей
   lcd.clear();
   lcd.print("RPM=");
   lcd.print(rpm);
 //rpm = mMin;
 mMin = rpm*3/100; // метры в минуту если на 60 
   Serial.print(cas);Serial.print("c.");Serial.print(minyt2); 
  Serial.print("m:");Serial.print(sek);Serial.println("s:");
Serial.print(mMin);Serial.println("-m/m");
Serial.print(rpmVse*3/100);Serial.println("-metrov");
   //Перезапустить процесс прерывания
   attachInterrupt(0, rpm_fun, FALLING);
  
  }
  
  void rpm_fun()
   {
   //обновляем счетчик
      rpmcount++;// прибавляем единицу к полученому
      rpmVse++;
    // Serial.print(rpmVse*3/100);Serial.println("-metrov");
      }

 

maksim
Offline
Зарегистрирован: 12.02.2012

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

Protez1999
Offline
Зарегистрирован: 08.07.2012

Вы про 21 строку????

maksim
Offline
Зарегистрирован: 12.02.2012

Нет, про 44 

Protez1999
Offline
Зарегистрирован: 08.07.2012

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

maksim
Offline
Зарегистрирован: 12.02.2012

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

Protez1999
Offline
Зарегистрирован: 08.07.2012

Все убрал. Часть кода нашел в инете сидел вчера разбарался честно говоря думал что это совсем другое значение . Посмотрел в справочнике не пойму для чего это сделали. Спасибо за подсказку