вторник, 28 августа 2012 г.

Проект на BlockDuino: Расчет времени работы механизма

Мне приходится зачастую учитывать наработку различных механизмов, например реф.компрессоров, кондиционеров,  и т.д. Для этого собрал такое устройство:
Состоит всего из двух блоков: BlockDuino и BlockLCD, и в качестве датчика фоторезистор, который крепится на индикатор работы устройства (лампочку или светодиод).
Алгоритм работы прост, в зависимости от показания датчика определяет работает механизм или стоит и суммирует время соответственно работы или простоя.
Далее выводит на экран последовательно:

  • Общее время контроля ("TotlTime")
  • Время работы ("Run Time")
  • Время простоя ("StopTime")
  • Текущее состояние ("State")
  • Расчетное время работы за сутки ("Runned")
  • Процентное соотношение работы и простоя ("Ratio")


Код:
/*
   Calculate runtime of machinery
   by Vasyl Yudin
   Dec 2011
*/
#include <Time.h>
#include <LiquidCrystal.h> 

int sensorPin = A5;    // select the input pin for the potentiometer
int ledPin = 13;      // select the pin for the LED
int sensorValue = 0;  // variable to store the value coming from the sensor
int threshold = 400;
float ratio = 0;

int disp;

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

time_t duration;
time_t prevTime;
time_t changeState;
time_t timeH = 0;
time_t timeL = 0;

boolean state = LOW;
boolean prevState = LOW;

void setup(void)
{ 
  
  lcd.begin(8, 2);

  lcd.print("  Demo  ");
  lcd.setCursor(0, 1);
  lcd.print("RunHours");
  // initialize serial communications at 9600 bps:
//  Serial.begin(9600); 
  delay(1000);
  
  prevTime = now();
}

void showTime(time_t t){
  // display the given time 
  printDigits(hour(t));  lcd.print(":");
  printDigits(minute(t));  lcd.print(":");
  printDigits(second(t));
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  if(digits < 10) lcd.print('0');
  lcd.print(digits);
}


void loop(void)
{ 
  sensorValue = analogRead(sensorPin);
  state = (sensorValue >= threshold);
  digitalWrite(ledPin, state);  
  
  if (state) timeH++; else timeL++;
  ratio = (float(timeH) / (float(timeH) + float(timeL)));    
  
  disp = second()/2 % 6;
  lcd.clear();
  switch (disp)
  {
    case 0:  //display total time of measuring
      lcd.print("TotlTime");lcd.setCursor(0, 1);
      showTime(now());break;
      
    case 1:  //display runned time during measuring
      lcd.print("Run Time");lcd.setCursor(0, 1);
      showTime(timeH);break;
      
    case 2:  //display stopped time during measuring
      lcd.print("StopTime");lcd.setCursor(0, 1);
      showTime(timeL);break;
      
    case 3:  //display current state
      lcd.print("State");lcd.setCursor(0, 1);
      if (state) lcd.print("  Runned"); else lcd.print(" Stopped");break;
      
    case 4:  //display aprox. runned time during day (24 hours)
      lcd.print("Runned");lcd.setCursor(0, 1);
      lcd.print(24*ratio, 1);lcd.print(" h/d");break;
      
    default:  //display ratio in percent Runned/Stopped
      lcd.print("Ratio");lcd.setCursor(1, 1);
      lcd.print(ratio*100, 0);lcd.print("%/");
      lcd.print((1-ratio)*100, 0);lcd.write('%');break;
  }

  delay(1000);
}