БК автомобиля

beautiful mind
Offline
Зарегистрирован: 06.09.2012

Здравствуйте. Занялся я тут написанием простенького бортового компьютера для своего таза 2108, а то там даже вольтметра нет) И так как на arduino я пока ничего серьезного не писал (светодиодами только моргал:)) и дабы избежать каких-нибудь грубых ошибок, решил выложить здесь код, чтобы вы его покритиковали. Особенно интересуют всякие программные хитрости, чтобы более приятно было наблюдать за экранчиком. Например, вот обороты пробовал снимать, и прыгали они постоянно, было не очень, и я попробовал округлять их по 50, но пока не проверял, как это будет смотреться. Проект сейчас на начальной стадии, работает только датчик напряжения и оборотов. С нетерпением жду ваших замечаний :)

P.S.: LCD 16х2 подвешен на сдвиговый регистр 74hc595. Их там 2 стоит. Возможно, будет и 74hc165

// include the library code:
#include <math.h>

#include <LiquidCrystalExt.h>

#include <LineDriver.h>

#include <SPI_Bus.h>

#include <SPI.h>

SPI_Bus shreg(_16bit,8);

LiquidCrystal lcd(6, 5, 4, 3, 2, 1, &shreg); //LCD экран 16х2

// Пины датчиков
const int sensVolt = A1;  //датчик напряжения
const int ledLCD = 6;  //освещение LCD
const int sensFuel = A2;  //датчик топлива в баке
const int sensRPM = 2;  //датчик оборотов
const int sensSpeedCar = 4;  //датчик скорости(расстояния)
const int sensLight = 7; //габариты

//переменные
unsigned long thisSec = 0;  //временная переменная секунды
unsigned long thisSec2 = 0;
unsigned long ledLcdSec = 0;  //временная переменная времени подсветки дисплея

float volt = 0;  //напряжение
float tVolt = 0;  //времменая переменная напряжения
float volt2 = 0;  //напряжение прошлое, для сравнения
float voltPorog = 4;  //порог напряжения

int RPM = 0;  //обороты
int RPM2 = 0;  //обороты прошлые, для сравнения
int tRPM = 0;  //времменая переменная оборотов

float speedCar = 0;  //скорость
float speedCar2 = 0;  //скорость прошлая, для сравнения
int tSpeedCar = 0;  //времменая переменная скорости

float fastDist = 0;  //мгновенное расстояние
float fastDistAll = 0;

float dist = 0; //оставшееся расстояния на баке
float dist2 = 0; //расстояние прошлое, для сравнения
float tDist = 0; //

float rasFuel = 0;
float rasFuelFast = 0;

float fuel = 0;  //кол-во топлива в баке
float tFuel = 0;  //времменая переменная кол-ва топлива

float r = 0.0003; //радиус колеса
int ledPorog = 120;  //порог яркости LCD
int cyl = 4;  //количество цилиндров
int i = 0;
boolean j = LOW;
boolean k = LOW;

void setup() {
  noInterrupts();
  
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  
  // Print a message to the LCD.
  lcd.print("Beautiful mind");
  
  pinMode(ledLCD, OUTPUT);

  pinMode(sensRPM, INPUT);

  pinMode(sensSpeedCar, INPUT);
  
  pinMode(sensLight, INPUT);

  analogWrite(ledLCD, 255);
  
  digitalWrite(sensRPM, HIGH);

  interrupts();

  delay(1000);
  
  // чистка LCD
  lcd.clear();

  millisRPM = millis();

  refreshLCD();

  lastRPM = digitalRead(sensRPM);

  lastSpeedCar = digitalRead(sensSpeedCar);

  //Serial.begin(9600);
}

void loop() {  
  thisSec = millis();
  
  //цикл для опроса приоритетных датчиков
  while(millis() - thisSec < 601)
  {
    //считывание с датчика напряжения
    tVolt = tVolt + analogRead(sensVolt)*5.0001/1023;
    i++;

    //подсчет оборотов, считывание данных
    if(lastRPM != digitalRead(sensRPM))
    {
      if(lastRPM == LOW && digitalRead(sensRPM) == HIGH)
        tRPM++;
      lastRPM = digitalRead(sensRPM);
    }
    
    //подсчет скорости, считывание данных
    if(lastSpeedCar != digitalRead(sensSpeedCar))
    {
      if(lastSpeedCar == LOW && digitalRead(sensSpeedCar) == HIGH)
        tSpeedCar++;
      lastSpeedCar = digitalRead(sensSpeedCar);
    }
  }
  thisSec2 = millis();
  
  //подсчет оборотов
  RPM = round(1200.0*(float)tRPM/((float)(thisSec2-thisSec)*(float)cyl))*50;
  tRPM = 0;
  
  //подсчет мгновенного растояния
  fastDist = (float)tSpeedCar*2.0*M_PI*r;
  fastDistAll = fastDistAll + fastDist;
  
  //вычисление расхода топлива
  if (fastDistAll > 1000)
  {
    rashFuel = rashFuelFast / fastDistAll;
    fastDistAll = 0;
  }
  
  //подсчет скорости
  speedCar = 3600.0*fastDist/((float)(thisSec2-thisSec)/1000);
  tSpeedCar = 0;
  
  dist = thisSec2-thisSec;
  
  volt = round(100.0*tVolt/(i+1))/100.0;
  i = 0;
  tVolt = 0;
  
  //Уменьшение яркости дисплея
  if(digitalRead(sensLight)) analogWrite(ledLCD, ledPorog);
  else analogWrite(ledLCD, 255);
  
  if(volt2 != volt)
  {
    printVoltLCD();
    volt2 = volt;
  }
  if(RPM2 != RPM)
  {
    printRPMLCD();
    RPM2 = RPM;
  }
  if(speedCar2 != speedCar)
  {
    printSpeedCarLCD();
    speedCar2 = speedCar;
  }
  if(dist2 != dist)
  {
    printDistLCD();
    dist2 = dist;
  }
}

void printVoltLCD()
{
  //вывод напряжения бортовой сети на экран
  lcd.setCursor(2, 0);
  lcd.print("     ");
  if (volt < 10)
    lcd.setCursor(3, 0);
  else if (volt < 100)
    lcd.setCursor(2, 0);
  lcd.print(volt);
}

void printRPMLCD()
{
  //вывод оборотов на экран
  lcd.setCursor(12, 0);
  lcd.print("    ");
  if (RPM < 10)
    lcd.setCursor(15, 0);
  else if (RPM < 100)
    lcd.setCursor(14, 0);
  else if (RPM < 1000)
    lcd.setCursor(13, 0);
  else
    lcd.setCursor(12, 0);
  lcd.print(RPM);
}

void printSpeedCarLCD()
{
  //вывод расхода на экран
  lcd.setCursor(0, 1);
  lcd.print("     ");
  lcd.setCursor(0, 1);
  lcd.print(rashFuel);
  lcd.setCursor(5, 1);
  lcd.print("l/km");
}

void printDistLCD()
{
  //вывод оставшегося пути на с учетом расхода на экран
  lcd.setCursor(10, 1);
  lcd.print("    ");
  if (dist < 10)
    lcd.setCursor(13, 1);
  else if (dist < 100)
    lcd.setCursor(12, 1);
  else if (dist < 1000)
    lcd.setCursor(11, 1);
  else if (dist < 10000)
    lcd.setCursor(10, 1);
  else
    lcd.setCursor(9, 1);
  lcd.print(dist);
  lcd.setCursor(14, 1);
  lcd.print("km");
}

void refreshLCD()
{
  //вывод напряжения бортовой сети на экран
  lcd.setCursor(0, 0);
  lcd.print("V:");
  lcd.print("     ");
  if (volt < 10)
    lcd.setCursor(3, 0);
  else if (volt < 100)
    lcd.setCursor(2, 0);
  lcd.print(volt);

  //вывод оборотов на экран
  lcd.setCursor(8, 0);
  lcd.print("RPM:");
  lcd.print("    ");
  if (RPM < 10)
    lcd.setCursor(15, 0);
  else if (RPM < 100)
    lcd.setCursor(14, 0);
  else if (RPM < 1000)
    lcd.setCursor(13, 0);
  else
    lcd.setCursor(12, 0);
  lcd.print(RPM);

  //вывод расхода на экран
  lcd.setCursor(0, 1);
  lcd.print("     ");
  lcd.setCursor(0, 1);
  lcd.print(speedCar);
  lcd.setCursor(5, 1);
  lcd.print("l/km");

  //вывод оставшегося пути на с учетом расхода на экран
  lcd.setCursor(10, 1);
  lcd.print("    ");
  if (dist < 10)
    lcd.setCursor(13, 1);
  else if (dist < 100)
    lcd.setCursor(12, 1);
  else if (dist < 1000)
    lcd.setCursor(11, 1);
  else
    lcd.setCursor(10, 1);
  lcd.print(dist);
  lcd.setCursor(14, 1);
  lcd.print("km");
}

 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

beautiful mind пишет:

  LCD 16х2 подвешен на сдвиговый регистр 74hc595. Их там 2 стоит

а почему для LCD поставили 2а регистра сдвига?

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

const int PIN_LCD_STROBE         =  5;  // Out: LCD IC4094 shift-register strobe
const int PIN_LCD_DATA           =  6;  // Out: LCD IC4094 shift-register data
const int PIN_LCD_CLOCK          =  4;  // Out: LCD IC4094 shift-register clock
//const int PIN_LCD_BACKLIGHT      =  5;  // Out: LCD backlight (PWM)

// srdata / srclock / strobe
LiquidCrystal_SR_LCD3 lcd(PIN_LCD_DATA, PIN_LCD_CLOCK, PIN_LCD_STROBE);