/* ***********************************************************************************************************************
Сигнальный провод с датчика скорости подключаем на пин D2. ВАЖНО, чтобы на этом проводе было не более 5 и не менее 3 вольт !!!
Сигнальный провод также нужно при помощи резистора 4.7 кОм "подтянуть" к пину 5V
Минусовой провод с датчика скорости подключаем на пин GND
Если ваш датчик скорости не 6-импульсный, тогда нужно указать нужное кол-во импульсов у переменной "sensorPulseNum"
Использовать дисплей OLED SSD1306
*********************************************************************************************************************** */
#include <GyverOLED.h>
#include <EncButton.h>
#include <Tachometer.h>
#define EB_DEB_TIME 50 // таймаут гашения дребезга кнопки (кнопка)
#define TACH_PIN 2 // пин датчика скорости (D2) /желательна внешняя подтяжка резистором 4.7K к пину 5V/. !!! НЕ БОЛЕЕ 5В !!!
Button btn(4); // Кнопка (D4)
Tachometer tacho; // Датчик скорости автомобиля
uint8_t sensorPulseNum = 6; // Количество импульсов вашего датчика скорости (импульсов на 1 оборот) /от 2 - до 64/
uint16_t sensorPulseCoef; // Коэффициент для расчета скорости и расстояния по кол-ву импульсов датчика
volatile int counterSpeedSensor = 0; // переменная-счётчик импульсов с датчика скорости (начальное значение присваивается в блоке "Setup")
GyverOLED<SSD1306_128x64, OLED_BUFFER> oled; // oled дисплей SSD1306 (бывают и 0,96", и 1,3") - с буфером
void isr() {
tacho.tick(); // Считаем импульсы с датчика скорости
counterSpeedSensor++;
}
void setup() {
pinMode(TACH_PIN, INPUT); // Сигнальный пин датчика скорости как "вход"
//tacho.setWindow(20); // установка количества тиков для счёта времени (по умолчанию 10)
//tacho.setTimeout(2000); // таймаут прерываний (мс), после которого считается что вращение датчика скорости прекратилось
attachInterrupt(0, isr, FALLING); // Подключаем прерывания для нормального подсчета импульсов с датчика скорости
sensorPulseCoef = round(100 * sensorPulseNum / 6); // Узнаем коэффициент для вашего датчика скорости
oled.init(); // Инициализация дисплея
oled.setContrast(100);
}
void loop () {
btn.tick(); // тикер кнопки
static uint32_t startTime; // Время начала замера
static uint32_t finishTime; // Время окончания замера
static float timeAcceleration; // Время разгона
static bool flagAcceleration = false; // Флаг
static uint32_t counter1 = 0; // Счетчик для начала замера
static uint32_t counter2 = 0; // Счетчик для окончания замера
static uint8_t maxSpeed = 0; // Макс скорость за всё время замера
static uint8_t speedLimit = 100; // До какой скорости считаем время разгона
static uint16_t curImpulseCount = counterSpeedSensor; // Текущее значение насчитанных импульсов с датчика скорости
if (btn.holding()) speedLimit += 1; // Удержанием кнопки увеличиваем скорость
if (btn.click()) { // Нажатием кнопки обнуляем предыдущие показания разгона и снова запоминаем текущее кол-во насчитанных импульсов с датчика скорости
counter1 = 0;
counter2 = 0;
curImpulseCount = counterSpeedSensor;
maxSpeed = 0;
startTime = 0;
finishTime = 0;
}
oled.clear();
if (tacho.getRPM() / sensorPulseCoef > maxSpeed) maxSpeed = tacho.getRPM() / sensorPulseCoef; // Постоянно заносим в переменную maxSpeed макс достигнутую скорость за время разгона
if (curImpulseCount != counterSpeedSensor) counter1 += 1; // ЗАПУСК СЕКУНДОМЕРА ПО ПЕРВОМУ ИМПУЛЬСУ ДАТЧИКА СКОРОСТИ
if (counter1 == 1) {
startTime = millis(); // когда импульс получен, заносим в переменную start время начала разгона...
flagAcceleration = true; // и поднимаем флаг
}
if (maxSpeed >= speedLimit and tacho.getRPM() / sensorPulseCoef >= speedLimit) { // если макс. скорость больше или равна лимиту скорости (т.е. достигли лимита) и текущая скорость больше или равна лимиту скорости (т.е. скорость пока ещё равна или больше лимита скорости),
counter2 += 1; // то активируем счетчик2...
if (counter2 == 1) { //
finishTime = millis(); // заносим в переменную finish время окончания разгона...
flagAcceleration = false; // и опускаем флаг
}
}
if (flagAcceleration) { // пока флаг поднят - пишем на экране слово "замер"
oled.setScale(1);
oled.setCursorXY(31, 30); // остальные показания убираем с экрана для уменьшения погрешности измерения
oled.print(F(" замер "));
}
if (!flagAcceleration) { // когда флаг опущен
timeAcceleration = (finishTime - startTime) / 1000.0; // Вычисляем время разгона
oled.line(0, 25, 127, 25); // и пишем на экране различную инфо
oled.line(0, 53, 127, 53);
oled.setScale(1);
oled.setCursorXY(0, 28);
oled.print(F("ВРЕМЯ"));
oled.setCursorXY(0, 36);
oled.print(F("РАЗГОНА"));
oled.setCursorXY(0, 44);
oled.print(F("0 -"));
oled.setCursorXY(24, 44);
oled.print(speedLimit);
oled.setScale(2);
oled.line(45, 26, 45, 52);
oled.setCursorXY(50, 33);
oled.print(timeAcceleration, 1);
oled.setScale(1);
oled.setCursorXY(110, 41);
oled.print(F("СЕК"));
oled.setScale(1);
oled.rect(77, 0, 127, 10, OLED_FILL);
oled.textMode(1);
oled.setCursorXY(79, 2);
oled.print(speedLimit);
oled.setCursorXY(103, 2);
oled.print(F("КМ/Ч"));
oled.textMode(0);
oled.textMode(0);
}
oled.setCursorXY(0, 0);
oled.setScale(3);
static uint32_t timerSpeedSensor;
if (millis() - timerSpeedSensor > 100) {
timerSpeedSensor = millis();
oled.print(tacho.getRPM() / sensorPulseCoef); // текущая скорость отображается всегда
}
oled.update();
}