#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "button.h"
#include "graf.h"
#include "funcs.h"
#include <EEPROM.h>
// Для руссификации, нужно glcdfont.c поместить в C:\Users\USER\Documents\Arduino\libraries\Adafruit_GFX_Library. У вас путь до библиотеки может отличаться.
// Конвертор из UTF-8 в бинарную строку здесь: https://грибовы.рф/rusifikaciya-displeya-ssd1306/
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
button btn1(4); // указываем пин кнопки 1
button btn2(5); // указываем пин кнопки 2
#define piezoPin 3 // пин бипера
int LightPin = A2; // пин подсветки кнопок
// Вольтметр
int analogInput = A0; // Аналоговый порт куда подключается выход с делителя напряжения
double inaccuracy = 0.5;
float R1 = 10000.0; // Сопротивление R1 (10K) в ОМАХ
float R2 = 2000.0; // Сопротивление R2 (2K)в ОМАХ
float vout = 0.0;
float vin = 0.0;
int value = 0;
// моточасы по умолчанию
struct SavedData {
byte beeper=0; // 1 - звук кнопок есть, 0 - нет
byte light=0; // 1 - подсветка кнопок есть, 0 - нет
int motoclock_motor=13200; // замена масла двигателя
int motoclock_kpp=26000; // замена масла МКПП
long motoclock_most=132000; // замена масла мосты
long motoclock_grm=132000; // замена ремня грм
};
SavedData ee_data;
SavedData etalon;
long old_milis,old_milis_2;
byte layout=0; // текущий экран 0 - температура, 1 - моточасы
float celsius1,celsius2,celsius3;
int _lang=0;
void beep(){
if (ee_data.beeper==1) {
for (int i=0; i <= 100; i++){
digitalWrite(piezoPin, HIGH);
delay(1);
digitalWrite(piezoPin, LOW);
delay(1);
}
} else {
delay(500);
}
}
void setup() {
Serial.begin(9600);
// инициализирую дисплей
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.cp437(true);
display.clearDisplay();
display.drawBitmap(0, 0, fxf, 128, 64, WHITE);
display.display();
// инициализация ног
pinMode(piezoPin, OUTPUT);
pinMode(analogInput, INPUT);
pinMode(LightPin, OUTPUT);
ee_data.beeper=1;
beep(ee_data.beeper);delay(1000);beep(ee_data.beeper);
// читаем данные из энергонезависимой памяти
EEPROM.get(2,ee_data);
if (ee_data.beeper>0){
ee_data.beeper=1;
};
if ((ee_data.motoclock_motor<0) or (ee_data.motoclock_kpp<0) or (ee_data.motoclock_most<0) or (ee_data.motoclock_grm<0)){
ee_data=etalon;
};
if (ee_data.light==1){
digitalWrite(LightPin, HIGH);
} else {
digitalWrite(LightPin, LOW);
};
old_milis=millis(); // засекаем время начало работы адулины
old_milis_2=millis(); // засекаем время начало работы адулины
display.clearDisplay();
LayoutScreen(true,0);
}
void beep(byte is_beep){
if (ee_data.beeper==1) {
for (int i=0; i <= 100; i++){
digitalWrite(piezoPin, HIGH);
delay(1);
digitalWrite(piezoPin, LOW);
delay(1);
}
} else {
delay(500);
}
}
void PutMenu(int curpoz,int cnt,String mass[]){
display.cp437(true);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(1,1);
for (int i=0; i < cnt; i++){
if (curpoz==i){
display.print(("> "));
}
display.println(mass[i]);
};
display.display();
beep(ee_data.beeper);
}
int YesNoMenu(){
const String menuYN[] PROGMEM = {
"No",
"Yes"
};
int poz=0;int size=sizeof(menuYN) / sizeof(menuYN[0]);
PutMenu(poz,size,menuYN);
while(true){
if (btn1.click()) {
poz=poz+1;
if (poz>=size){
poz=0;
};
PutMenu(poz,size,menuYN);
};
if (btn2.click()) {
return poz;
};
};
return poz;
};
int CounterMenu(){
const String menuCounter[] PROGMEM = {
"Engine oil", // масло двигателя
"Trans oil", // масло в мостах
"Gear oil", // Масло в КПП
"Timing belt", // Ремни ГРМ
"Exit"
};
int poz=0;int size=sizeof(menuCounter) / sizeof(menuCounter[0]);
PutMenu(poz,size,menuCounter);
while(true){
if (btn1.click()) {
poz=poz+1;
if (poz>=size){
poz=0;
};
PutMenu(poz,size,menuCounter);
};
if (btn2.click()) {
return poz;
};
};
return poz;
};
int MainMenu(){
const String menuMain[] PROGMEM = {
"Moto clock",
"Clicks sound",
"Backlight",
"Exit"
};
int poz=0;int size=sizeof(menuMain) / sizeof(menuMain[0]);
PutMenu(poz,size,menuMain);
while(true){
if (btn1.click()) {
poz=poz+1;
if (poz>=size){
poz=0;
};
PutMenu(poz,size,menuMain);
};
if (btn2.click()) {
if (poz==0){ // настройка счетчика моточасов
int PozCounter=0;
// PozCounter=CounterMenu();
};
if (poz==1){ // звук нажатия
ee_data.beeper=YesNoMenu();
EEPROM.put(2,ee_data);
return 0;
};
if (poz==2){ // подсветка кнопок
ee_data.light=YesNoMenu();
//Serial.print("Y/N:");Serial.println(ee_data.light);
EEPROM.put(2,ee_data);
if (ee_data.light==0){
Serial.println("LED Off");
digitalWrite(LightPin, LOW);
} else {
Serial.println("LED ON");
digitalWrite(LightPin, HIGH);
};
return 0;
};
if (poz==3){ // выход из меню
return 0;
};
};
};
return 0;
}
// отобразить текущий экран
// refresh true/false - стереть всё предварительно
// lay - экран. 0 - температура, 1 - моточасы
void LayoutScreen(boolean refresh,byte lay){
display.setCursor(0,0);
if (lay==0){
if (refresh==true){
display.clearDisplay();
display.drawBitmap(65, 32, fxf3, 59, 32, WHITE);
};
display.setTextColor(WHITE, BLACK);
// улица
display.setCursor(20, 1);
display.print("Street:");
display.print(celsius1);display.print("c");
// салон
display.setCursor(20, 10);
display.print("Int:");
display.print(celsius2);display.print("c");
// двигатель
display.drawBitmap(1, 22, ico_dvig, 16, 16, WHITE);
display.setCursor(20, 26);
display.print(celsius3);display.print("c");
// батарея
display.drawBitmap(1, 42, ico_bat, 16, 16, WHITE);
display.setCursor(20, 46);
display.print(vin);display.print("v");
display.display();
} else {
if (refresh==true){
display.clearDisplay();
display.drawBitmap(65, 32, fxf3, 59, 32, WHITE);
};
display.setTextColor(WHITE, BLACK);
display.setCursor(1, 1);
display.print("Motoclock:");display.print(ee_data.motoclock_motor/60);display.print("h");
display.setCursor(1, 10);
display.print("Transmission:");display.print(ee_data.motoclock_kpp/60);display.print("h");
display.setCursor(1, 20);
display.print("Bridge:");display.print(ee_data.motoclock_most/60);display.print("h");
display.setCursor(1, 30);
display.print("GRM ribbon:");display.print(ee_data.motoclock_grm/60);display.print("h");
display.display();
};
}
void loop() {
if (millis()-old_milis_2>1000){ // раз в секунду читаем показания
// читаем показания датчиков температуры
sensors.requestTemperatures();
celsius1=sensors.getTempCByIndex(0); if (celsius1<-120){celsius1=0;};
celsius2=sensors.getTempCByIndex(1); if (celsius2<-120){celsius2=0;};
celsius3=sensors.getTempCByIndex(2); if (celsius3<-120){celsius3=0;};
// читаем показания вольтметра
value = analogRead(analogInput);
vout = (value * 5.0) / 1024.0;
vin = vout / (R2/(R1+R2))-inaccuracy;
old_milis_2=millis();
LayoutScreen(false,layout);
}
if (btn1.click()) {
MainMenu();
LayoutScreen(true,layout);
};
if (btn2.click()) {
layout=layout+1;
if (layout>1){layout=0;};
LayoutScreen(true,layout);
beep(ee_data.beeper);
}
}
Loading
ds18b20
ds18b20
Loading
ds18b20
ds18b20
Loading
ds18b20
ds18b20