Секундомер для спидкубинга
- Войдите на сайт для отправки комментариев
Сб, 11/01/2020 - 01:09
Приветствую всех.
Про секундомеры избитая тема.
Сын увлекся спидкубингом и я решил сделать для него секундомер. Суть в чем: есть две кнопки, на которые ложатся руки, при отпускании одной из них начинается отсчет. После сборки кубики нужно нажать на обе кнопки и счетчик останавливается. И есть третья кнопка для сброса в нули.
Вывожу все на экран 2004 большими цифрами. Но проблема в точности и в выводе миллисекунд. Не доходит, как вывести их до точности 0.01
#include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x3F,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display unsigned long time0 = 0, time1; byte ms, s, m, start1, stop1, go, blok, kn_start1, kn_start2, kn_reset; uint8_t LT[8] = {0b00111, 0b01111, 0b01111, 0b01111, 0b01111, 0b01111, 0b01111, 0b00111}; uint8_t UB[8] = {0b11111, 0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000}; uint8_t RT[8] = {0b11100, 0b11110, 0b11110, 0b11110, 0b11110, 0b11110, 0b11110, 0b11100}; uint8_t LL[8] = {0b01111, 0b00111, 0b00000, 0b00000, 0b00000, 0b00000, 0b00011, 0b00111}; uint8_t LB[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111}; uint8_t LR[8] = {0b11110, 0b11100, 0b00000, 0b00000, 0b00000, 0b00000, 0b11000, 0b11100}; uint8_t UMB[8] = {0b11111, 0b11111, 0b11111, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111}; uint8_t LMB[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00111, 0b01111}; void setup() { Serial.begin(115200); lcd.init(); lcd.backlight(); lcd.home(); pinMode(10, INPUT); pinMode(11, INPUT); pinMode(7, INPUT); pinMode(13, OUTPUT); lcd.createChar(0, LT); lcd.createChar(1, UB); lcd.createChar(2, RT); lcd.createChar(3, LL); lcd.createChar(4, LB); lcd.createChar(5, LR); lcd.createChar(6, UMB); lcd.createChar(7, LMB); lcd.clear(); digitsNumber(); } void custom0(int x) { // составим из блоков цифру 0 lcd.setCursor(x,0); lcd.write(0); lcd.write(1); lcd.write(2); lcd.setCursor(x, 1); lcd.write(0); lcd.write(4); lcd.write(2); } void custom1(int x) { // составим из блоков цифру 1 lcd.setCursor(x,0); lcd.write(32); lcd.write(32); lcd.write(2); lcd.setCursor(x, 1); lcd.write(32); lcd.write(32); lcd.write(2); } void custom2(int x) { // составим из блоков цифру 2 lcd.setCursor(x,0); lcd.write(3); lcd.write(6); lcd.write(2); lcd.setCursor(x, 1); lcd.write(0); lcd.write(4); lcd.write(4); } void custom3(int x) { // составим из блоков цифру 3 lcd.setCursor(x,0); lcd.write(3); lcd.write(6); lcd.write(2); lcd.setCursor(x, 1); lcd.write(7); lcd.write(4); lcd.write(2); } void custom4(int x) { // составим из блоков цифру 4 lcd.setCursor(x,0); lcd.write(0); lcd.write(4); lcd.write(2); lcd.setCursor(x, 1); lcd.write(32); lcd.write(32); lcd.write(2); } void custom5(int x) { // составим из блоков цифру 5 lcd.setCursor(x,0); lcd.write(0); lcd.write(6); lcd.write(5); lcd.setCursor(x, 1); lcd.write(7); lcd.write(4); lcd.write(2); } void custom6(int x) { // составим из блоков цифру 6 lcd.setCursor(x,0); lcd.write(0); lcd.write(6); lcd.write(5); lcd.setCursor(x, 1); lcd.write(0); lcd.write(4); lcd.write(2); } void custom7(int x) { // составим из блоков цифру 7 lcd.setCursor(x,0); lcd.write(1); lcd.write(1); lcd.write(2); lcd.setCursor(x, 1); lcd.write(32); lcd.write(0); lcd.write(32); } void custom8(int x) { // составим из блоков цифру 8 lcd.setCursor(x,0); lcd.write(0); lcd.write(6); lcd.write(2); lcd.setCursor(x, 1); lcd.write(0); lcd.write(4); lcd.write(2); } void custom9(int x) { // составим из блоков цифру 9 lcd.setCursor(x,0); lcd.write(0); lcd.write(6); lcd.write(2); lcd.setCursor(x, 1); lcd.write(32); lcd.write(4); lcd.write(2); } void digitsNumber() { // Вывод минут printDigits(m/10, 0); printDigits(m%10, 3); // Вывод секунд printDigits(s/10, 7); printDigits(s%10, 10); // Вывод миллисекунд printDigits(ms/10, 14); printDigits(ms%10, 17); // Моргание точек между минутами, секундами и миллисекундами (раз в секунду) if (s%10%2 == 0){ lcd.setCursor(6, 0); lcd.print("."); lcd.setCursor(6, 1); lcd.print("."); lcd.setCursor(13, 0); lcd.print("."); lcd.setCursor(13, 1); lcd.print("."); } else { lcd.setCursor(6, 0); lcd.print(" "); lcd.setCursor(6, 1); lcd.print(" "); lcd.setCursor(13, 0); lcd.print(" "); lcd.setCursor(13, 1); lcd.print(" "); } } void printDigits(int digits, int x){ switch (digits) { case 0: custom0(x); break; case 1: custom1(x); break; case 2: custom2(x); break; case 3: custom3(x); break; case 4: custom4(x); break; case 5: custom5(x); break; case 6: custom6(x); break; case 7: custom7(x); break; case 8: custom8(x); break; case 9: custom9(x); break; } } void loop() { kn_start1 = digitalRead(10); kn_start2 = digitalRead(11); // Нажали две сенсорные кнопки TTP223 if (kn_start1 == HIGH && kn_start2 == HIGH && blok == 0) { go = 1; } // Если отпустили хотя бы одну кнопку, то начался отсчет if ((kn_start1 == LOW || kn_start2 == LOW) && start1 == 0 && go == 1) { start1 = 1; stop1 = 1; } // Собрали кубик и должны нажать обе кнопки if ((kn_start1 == HIGH && kn_start2 == HIGH) && start1 == 1 && stop1 == 1) { start1 = 0; go = 0; blok = 1; } // Кнопка сброса счетчика в нули kn_reset = digitalRead(7); if (kn_reset == HIGH && start1 == 0 && stop1 == 1) { start1 = 0; stop1 = 0; blok = 0; ms = 0; s = 0; m = 0; digitsNumber(); } // Счетчик и вывод на экран if (start1 == 1) { if(millis() - time0 > 99){ time0 = millis(); ++ms; // отсчет 0,1 с if(ms > 6){ ms = 0; ++s; // отсчет 1 с } if(s > 59){ s = 0; ++m; // отсчет 1 мин } if(m > 59){ m = 0; } } digitsNumber(); } }
1. Пожалуйста, сформулируйте вопрос, на который можно было бы ответить. Фраза "Не доходит, как" - это не вопрос, а утверждение. Вопрос у Вас есть? Задавайте, не стесняйтесь.
2. Поясните подробнее,
А) что Вы сейчас выводите - что это за цифры на экране;
Б) чего хотите - поясните словами и нарисуйте как должен выглядеть экран;
В) в каком месте программы Вы пытались сделать (Б), и в чём именно Ваша проблема/затык.
Интересно, почему у вас в секунде только 6 десятых?
это я с чьего то секундомера "слизал", вот от сюда rcl-radio.ru/?p=42827 (но там стоит 9, а я подбирал, чтоб точность у секунд более менее была). Знаю, что это не правильно, поэтому и написал сюда.
1. Пожалуйста, сформулируйте вопрос, на который можно было бы ответить. Фраза "Не доходит, как" - это не вопрос, а утверждение. Вопрос у Вас есть? Задавайте, не стесняйтесь.
2. Поясните подробнее,
А) что Вы сейчас выводите - что это за цифры на экране;
Б) чего хотите - поясните словами и нарисуйте как должен выглядеть экран;
В) в каком месте программы Вы пытались сделать (Б), и в чём именно Ваша проблема/затык.
1. Вопрос в том, как правильно высчитать и минуты, секунды и миллисекунды.
2. А) на экран выводятся (должны) МИНУТЫ:СЕКУНДЫ:МИЛЛИСЕКУНДЫ
Б) смотрим А)
В)
И проблему, вроде, я решил. Перелопатил еще разных таймеров, секундомеров. И вместо кода, который чуть выше, вставил этот :
И заработало. За 2 минуты точность с секундомером на телефоне точь в точь
Ну, вот, видите. Пока на форум не обратились - не могли решить. а как обратились ... вот что форум животворящий делает!
вот что форум животворящий делает!
это точно, не первый раз такое происходит и по другим житейским вопросам
Вот что в итоге получилось. Правда пришлось переделать отображение миллисекунд, т.к. экран взял меньше.
(Ардуино Нано, две кнопки TTP223, одна без фиксации для сброса, LCD 1602. Корпус спроектировал и выпилил из экструдированного пенополистирола на станке с ЧПУ). Питается от сети.
А можно получить готовый код?
А можно получить готовый код?
конечно, в нулевом и третьем посте он весь
А мне нужен двух строчный а не 4
А мне нужен двух строчный а не 4
Ага. Тоись, тебе еще и код переделай.
Эмм.. Как бы в финальной версии на картинки двух строчный дисплей
На первых фотографиях тоже используются только две верхние строки. Так что никаких особых проблем с заменой 2004 на 2002 не возникнет. А вот если менять 2004 на 1602, то придётся чем-то жертвовать.
Вот что в итоге получилось. Правда пришлось переделать отображение миллисекунд, т.к. экран взял меньше.
(Ардуино Нано, две кнопки TTP223, одна без фиксации для сброса, LCD 1602. Корпус спроектировал и выпилил из экструдированного пенополистирола на станке с ЧПУ). Питается от сети.
На первых фотографиях тоже используются только две верхние строки. Так что никаких особых проблем с заменой 2004 на 2002 не возникнет. А вот если менять 2004 на 1602, то придётся чем-то жертвовать.
вот и пришлось пожертвовать выводом секунд большого формата.
Эмм.. Как бы в финальной версии на картинки двух строчный дисплей
на экране 2004 используется только две строчки (нулевая и первая) и на 1602 тоже самое (нулевая и первая) - ничего не изменилось
да но 2004 там 20 строк (запол. все) а 1602 только 16
да но 2004 там 20 строк (запол. все) а 1602 только 16
скорее 16 столбцов
вот поэтому и пришлось секунды вывести обычным способом вместо больших цифр.
подсказка: нужно найти строки, где выводятся минуты, секунды и доли, и там заменить вывод долей секунд (2 строчки, они даже подписаны) на стандартные 4 строчки.
Я особо в коде не бум-бум
я то нашёл но заменить не могу(не знаю как)
Я особо в коде не бум-бум
я до сих пор такой же
я то нашёл но заменить не могу(не знаю как)
а на это в помощь youtube и прочий интернет в помощь. сам там учусь и уже почти собрал на SIM800L сигналку для гаража.
Вам что сложно?
я смог сделать только десятые а сотые не получаються
Вам что сложно?
мне, нет
я смог сделать только десятые а сотые не получаються
Тут всегда рады помочь и направить. Вставляйте код, что у вас получилось и будем смотреть, разбираться вместе.
ну, во-первых, вы не изменили часть кода (строки 265-284) на другие из #3 сообщения.
во-вторых, где вывод миллисекунд, почему то сначала идет 15 столбик, а потом 14 (в принципе, особого значения не имеет, главное подставить нужные переменные в эти столбцы)
ну, и в-третьих, не точно переписаны переменные вывода миллисекунд (ms имеется виду), изначально чуть другое значение идет
Что мне нужно сделать?
http://prntscr.com/qpfphn
Что мне нужно сделать?
всего три действия
ну, во-первых, вы не изменили часть кода (строки 265-284) на другие из #3 сообщения.
во-вторых, где вывод миллисекунд, почему то сначала идет 15 столбик, а потом 14 (в принципе, особого значения не имеет, главное подставить нужные переменные в эти столбцы)
ну, и в-третьих, не точно переписаны переменные вывода миллисекунд (ms имеется виду), изначально чуть другое значение идет
какие переменые? я не понимаю
http://prntscr.com/qpfphn
видимо не хватает одной закрывающей }
какие переменые? я не понимаю
(ms имеется виду)
что в них не так?
как я понимаю первое ms а второе другое да?
что в них не так?
не точно переписаны
ну сравните, что было в первом посту, и что у вас в коду
170
printDigits(ms/10, 14);
171
printDigits(ms%10,
переменная идет до запятой
http://prntscr.com/qpfs66
170
printDigits(ms/10, 14);
здесь вывод printDigits(ПЕРЕМЕННАЯ, ПОЗИЦИЯ);
мне надо мельник цифры
мне надо мельник цифры
не важно, какие цифры будут выходить на экран, ПЕРЕМЕННАЯ остается в том же виде
http://prntscr.com/qpfuc0 так?
http://prntscr.com/qpfuc0 так?
НЕТ, блин, я больше не могу
вы не просто скопируйте, а хоть не много вникните.
хорошо но оно показывает только сотые, десятые нет
ну, во-первых, вы не изменили часть кода (строки 265-284) на другие из #3 сообщения.
а это сделано???
Ладно, спасибо вам за всю помощь и неудобство
Добавил комменты для наглядности
Код для двух кнопок посаженых на землю.
Код для двух кнопок посаженых на землю.
хммм, до такого еще далеко, с этим еще разбираться и разбираться, по крайней мере мне.
а можно строчки прокомментировать?