секундомер помогите разобраться
- Войдите на сайт для отправки комментариев
Прошу помощи знатоков.
Для старта машинок на время, все как на трассах автогонок. Ардуино уно + lcd2004 (20,4) + 2 кнопки (Старт и Стоп, потом можно заменить на датчики) + 3 светодиода. Смысл такой:
- при нажатии кнопки "Старт",поочередно, с задержкой, включаются 3 светодиода и включается таймер (гонка началась);
- работа таймера отображается в верхней строчке
-при пересечении финиша 1 машинки срабатывает кнопка "Стоп" (потом можно и сенсор поставить) и во второй строке появляется время 1 машинки
-тоже происходит при пересечении финиша 2 и 3 машинок, результаты отображаются на экране 3 и 4 строке соответсвенно.
Просмотрел в инете что нибудь подобное, пока получилось вот так:
[code]
int Blink1=8;
int Blink2=9;
int Blink3=10;
int StartPin=2;
int StopPin=3;
int h,m,s; // переменные для минут, секунд, милисекунд
boolean z; // переменная для отображения точки
// подключаем библиотеку индикатора
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // Для экрана 20х4 (четырехстрочный)
//LiquidCrystal_I2C lcd(0x27, 16, 2); // Для экрана 16х2 (двухстрочный
// Variables will change :
int ledState = LOW; // ledState used to set the LED
unsigned long previousMillis = 0; // will store last time LED was updated
const long interval = 5; // interval at which to blink (milliseconds)
void setup() {
//нужно настроить порты на чтение, читаем как использовать кнопки, как настраивать порты.
pinMode(StartPin, INPUT);
digitalWrite(StartPin, HIGH);
pinMode(StopPin, INPUT);
digitalWrite(StopPin, HIGH);
lcd.begin();
delay(2000);
digitalWrite(Blink1,HIGH);
delay(1500);
digitalWrite(Blink2,HIGH);
delay(2000);
digitalWrite(Blink3,HIGH);
}
void loop()
{
if(digitalRead(StartPin)==HIGH) {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
s++;
if (s>59)
{
s=0; // присваиваем значение 0 переменной s
m++; // добавляем 1 к переменной m отвечающей за секунды
}
// секция подсчета секунд
if (m>59) // если значение m больше 59
{
m=0; // присваиваем значение 0 переменной m
h++; // добавляем 1 к переменной h отвечающей за минуты
}
// секция подсчета минут
if (h>23) // если значение h больше 23
{
h=0; // присваиваем значение 0 переменной h
}
// секция вывода информации
// вывод милисекунд
if (s<10) //если милисекунд меньше 10
{
lcd.setCursor(13, 0); // курсор в 6 позицию 0 строки
lcd.print(0); //печатаем 0
lcd.setCursor(14, 0); //курсор в 7 позицию 0 строки
lcd.print(s); //печатаем значение переменной s
}
else
{
lcd.setCursor(13, 0); //иначе курсор в 6 позицию 0 строки
lcd.print(s); // печатаем значение переменной s
}
lcd.setCursor(12, 0); // курсор в 5 позицию 0 строки
lcd.print(":"); // печатаем разделитель между милисекундами и секундами
// вывод секунд
if (m<10)
{
lcd.setCursor(10, 0);
lcd.print(0);
lcd.setCursor(11, 0);
lcd.print(m);
}
else
{
lcd.setCursor(10, 0);
lcd.print(m);
}
lcd.setCursor(9, 0); // курсор в 2 позицию 0 строки
lcd.print(":"); // печатаем разделитель между секундами и минутами
// вывод минут
if (h<10)
{
lcd.setCursor(7, 0);
lcd.print(0);
lcd.setCursor(8, 0);
lcd.print(h);
Пробовал еще вот так (в одной из тем было)
[code]
int Blink1=8;
int Blink2=9;
int Blink3=10;
int h,m,s; // переменные для минут, секунд, милисекунд
boolean z; // переменная для отображения точки
// подключаем библиотеку индикатора
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // Для экрана 20х4 (четырехстрочный)
volatile unsigned long start = 0; //переменная для хранения начального значения millis
volatile unsigned long stop = 0; //переменная для хранения полученного промежутка времени
volatile int once = 0; //переменная для игнорирования повторного нажатия кнопки
unsigned long prev_ms = 0; //переменная для создания отрезков, чтобы не использовать delay
volatile int state = HIGH;
void setup() {
//нужно настроить порты на чтение, читаем как использовать кнопки, как настраивать порты.
pinMode(2, INPUT);
digitalWrite(2, HIGH);
pinMode(3, INPUT);
digitalWrite(3, HIGH);
attachInterrupt(0, begin, LOW);
attachInterrupt(1, end, LOW);
lcd.begin();
delay(2000);
digitalWrite(Blink1,HIGH);
delay(1500);
digitalWrite(Blink2,HIGH);
delay(2000);
digitalWrite(Blink3,HIGH);
}
void loop() {
if ((millis() - prev_ms) > 10) { //вывод данных каждые 500мс
prev_ms = millis();
s++;
if (s>59)
{
s=0; // присваиваем значение 0 переменной s
m++; // добавляем 1 к переменной m отвечающей за секунды
}
// секция подсчета секунд
if (m>59) // если значение m больше 59
{
m=0; // присваиваем значение 0 переменной m
h++; // добавляем 1 к переменной h отвечающей за минуты
}
// секция подсчета минут
if (h>59) // если значение h больше 23
{
h=0; // присваиваем значение 0 переменной h
}
// секция вывода информации
// вывод милисекунд
if (s<10) //если милисекунд меньше 10
{
lcd.setCursor(13, 0); // курсор в 6 позицию 0 строки
lcd.print(0); //печатаем 0
lcd.setCursor(14, 0); //курсор в 7 позицию 0 строки
lcd.print(s); //печатаем значение переменной s
}
else
{
lcd.setCursor(13, 0); //иначе курсор в 6 позицию 0 строки
lcd.print(s); // печатаем значение переменной s
}
lcd.setCursor(12, 0); // курсор в 5 позицию 0 строки
lcd.print(":"); // печатаем разделитель между милисекундами и секундами
// вывод секунд
if (m<10)
{
lcd.setCursor(10, 0);
lcd.print(0);
lcd.setCursor(11, 0);
lcd.print(m);
}
else
{
lcd.setCursor(10, 0);
lcd.print(m);
}
lcd.setCursor(9, 0); // курсор в 2 позицию 0 строки
lcd.print(":"); // печатаем разделитель между секундами и минутами
// вывод минут
if (h<10)
{
lcd.setCursor(7, 0);
lcd.print(0);
lcd.setCursor(8, 0);
lcd.print(h);
}
else
{
lcd.setCursor(7, 0);
lcd.print(h);
}
}
}
void begin() {
if (once == 0) { //проверяем, нажималась ли уже кнопка старт
start = millis(); //получаем текущее значение millis
once = 1; //ставим метку "старт был нажат"
stop = 0; //обнуляем предыдущий замер, а можно и не обнулять :)
}
}
void end() {
if (once == 1) { //проверяем, нажималась ли кнопка старт
stop = millis() - start; //вычисляем промежуток
once = 0; //убираем метку
}
}
[/code]
В итоге таймер работает и отображается на 1 строке экрана. Кнопки стоп и старт при нажатии останавливают таймер (пока держишь, потом дальше идет счет).
Как вытащить данные при замыкании кнопки стоп для статичного отображения на 2 строке экрана. Пробовал повторять в loopе отображать одновременно таймер сразу в 2-х и более строках, что бы потом как то тормозить отображение таймера построчно (2,3,4), но видимо из-за этого замедляется процесс в loope и секунда становятся удлиняется (т.е. отображение одной секунды сравнимо с 3 -4 секундами).
В общем, первая проба сделать скейтч для ардуино. Help Me Please!!!
Я предлагаю свой код
/* //#1 светодиоды красный -> 8 (red_pin) 0 горит/ 1 нет желтый -> 9 (yellow_pin) 0 горит/ 1 нет зеленый -> 10 (green_pin) 0 горит/ 1 нет //#2 кнопки Старт -> 2 (start_pin) 0 нажата/ 1 нет GND -> GND Стоп -> 3 (stop_pin) 0 нажата/ 1 нет GND -> GND //#3 I2C LCD1602 GND -> GND +5V -> +5V SDA -> A4(SDA) SCL -> A5(SCL) */ //#0 uint32_t timer=0; uint8_t plus=0; //#1 const int red_pin=8; // светодиод красный uint8_t red; const int yellow_pin=9; // светодиод желтый uint8_t yellow; const int green_pin=10; // светодиод зеленый uint8_t green; const uint16_t interval=1000;// с каким периодом зажигаются светодиоды //#2 const int start_pin=2; // нога кнопки старт const int stop_pin=3; // нога кнопки стоп uint8_t start_btn,start_old_btn; uint8_t stop_btn,stop_old_btn; //#3 #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,16,2); // Устанавливаем дисплей void setup() { //#1 pinMode(red_pin, OUTPUT); // гасим красный светодиод digitalWrite(red_pin,red=1); pinMode(yellow_pin, OUTPUT);// гасим желтый светодиод digitalWrite(yellow_pin,yellow=1); pinMode(green_pin, OUTPUT);// гасим зеленый светодиод digitalWrite(green_pin,green=1); //#2 pinMode(start_pin, INPUT_PULLUP);// подключаем кнопку Старт start_btn =digitalRead(start_pin); pinMode(stop_pin, INPUT_PULLUP);// подключаем кнопку Стоп stop_btn =digitalRead(stop_pin); //#3 lcd.init() ; lcd.backlight() ; // Включаем подсветку дисплея } void loop() { static uint32_t MILLIS ; MILLIS = millis() ; //#0 10 миллисек поток таймера static uint32_t future0 = 0 ; if (MILLIS >=future0){ future0=future0+10; timer=timer+plus; } //#1 непрерывно управляем светодиодами static uint32_t future1 = 0 ; if (!green&&(MILLIS >=future1)) { // гасим зеленый digitalWrite(green_pin,green=1); } if (!yellow&&(MILLIS >=future1)) { // гасим желтый и включ зеленый и включ таймер digitalWrite(yellow_pin,yellow=1); future1=MILLIS+interval; digitalWrite(green_pin,green=0); plus=1; timer=0; } if (!red&&(MILLIS >=future1)) { // гасим красный и включ желтый digitalWrite(red_pin,red=1); future1=MILLIS+interval; digitalWrite(yellow_pin,yellow=0); } //#2 непрерывно опрашиваем кнопки start_old_btn=start_btn; start_btn =digitalRead(start_pin); if (!start_btn && start_old_btn) { // если нажата кнопка старт future1=MILLIS+interval; digitalWrite(red_pin,red=0); // вкл красный } stop_old_btn=stop_btn; stop_btn =digitalRead(stop_pin); if (!stop_btn && stop_old_btn) { // если нажата кнопка стоп plus=0; // остановить таймер } //#3 0,5 секунд обновление экрана static uint32_t future3 = 0 ; if (MILLIS >=future3){ future3=future3+500; lcd.clear(); lcd.print(timer); } }Спасибо, попробую разобраться.
А как сделать нормальное отображение таймера на экране минуты:секунды:милисекунды. Сейчас на экране получается просто меняющийся набор цифр по мере работы таймера. Может как то включается?
Еще
48lcd.init()пришлось заменить
на lcd.begin() , а то ругается при компиляции и экран поправить с
LiquidCrystal_I2C lcd(0x27,16,2) наLiquidCrystal_I2C lcd(0x27,20,4)может не правильно что то сделал? или библиотеку какую надо подключать?
Интересно, подключил другую библиотеку LiquidCrystal_I2C lcd - теперь lcd.init() принимает.
Обнаружил у себя таймер DS3231, буду на нем колдовать с уно.