Для обсуждения - игровой атрибут

at0mix
at0mix аватар
Offline
Зарегистрирован: 23.11.2015

Сделал проект игрового атрибута для страйкбола - но в принципе для любой командной игры более 2х (шахматы).

При старте атрибут ждет нажатие на любую кнопку.

После нажатия на кнопку команды (игрока) включается светодиод - индикация, и стартует счетчик времени.

В старшем разряде показан номер игрока/команды, далее число минут времени владения точкой.

При переключении на любую другую команду/игрока продолжается отсчет таймера игрока Н.

Скорость увеличена в целях тестирования.

пример

https://cloud.mail.ru/public/2G1u/b4zK949sN

Хотелось бы услышать предложения по оптимизации кода.

Alexino
Offline
Зарегистрирован: 29.12.2015

А где код, по которому ждёте предложений ? 

at0mix
at0mix аватар
Offline
Зарегистрирован: 23.11.2015

В проекте - там схема и скетч в формате протеус8

/*********************************************************************************************/
// Программа игрового таймера на 4+ стороны.
// Идея: при включении таймер в состоянии ожидания (в тестовом режиме считает время со старта)
// все светодиоды выключены, в старшем разряде индикатора 0
// после нажатия любой кнопки загорается соответствующий светодиод,
// на индикаторе в старшем разряде высвечен номер кнопки
// на остальных - время в минутах.
// При нажатии на любую другую кнопку время текущей команды останавливается и запоминается.
// считается время новой текущей команды.
// При нажатии на ранее имевшую отсчет времени кнопку продолается отсчет времени.
// для тестирования время ускорено ;)
/*********************************************************************************************/

// настройки для вывода на 4-разрядный 7-сегментный индикатор.
// в реале будет заменено на библиотеку TM1637
const int latchPin = 2;     //Пин "защелки" первого регистра подключен к ST_CP входу первого регистра отвечающего за сегменты
const int clockPin = 3;    //Пин подключен к SH_CP входу 74HC595
const int dataPin = 4;     //Пин подключен к DS входу 74HC595
const int TimeLight = 5;  //время для разогрева сегментов

byte SegDisplay; // переменная для вывода символов на индикаторе
byte RazrDisplay; // переменная для включения разрядов

// Настройка комбинации для отображения каждого номера на дисплее.
// Комбинация выбрана на основе таблицы отображаемого знака данным порта
// Соответственно { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , dp, - }
byte g_digits[12]={192,249,164,176,153,146,130,248,128,144,127,255}; //массив цифр, генерирующий из сегментов цифры
byte g_registerArray[4]={1,2,4,8}; //массив цифр, указывающий разряды

unsigned int disp = 0; //создаем переменную для вывода на экран
const int PinSD[] = {0,9,10,11,12}; // светодиоды 1-4

int PrevKey=0;
int NextKey=0;
// счетчики времени
unsigned int XTimer[5]={0,0,0,0,0};

int Z=0;

void setup() {
// обозначаем пины как выходы для индикатора
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
// настраиваем пины для светодиодов
byte k=0;
for (k=1;k<5;k++){
   pinMode(PinSD[k], OUTPUT);
   digitalWrite(PinSD[k], LOW);
   }
//Serial.begin(9600);
}



void loop() {

// читаем кнопки
byte k=0;
for (k=0;k<4;k++){
   long Z=digitalRead(k+14);
   if (Z){NextKey=k+1;}
}
// если кнопка изменилась
if (NextKey!=PrevKey){
   digitalWrite(PinSD[NextKey],HIGH);
   if (PrevKey>0){
      digitalWrite(PinSD[PrevKey],LOW); // зажигаем светодиод
   }
   PrevKey=NextKey;
}
XTimer[NextKey]++; //считаем время

disp=NextKey*1000+XTimer[NextKey]/10;    //показываем время
  
// Разбиваем цифру по разрядам индикатора
Indicate(0, disp / 1000);
Indicate(1, (disp % 1000) / 100);   
Indicate(2, (disp % 100) / 10);
Indicate(3, disp % 10);
}
	 
void Indicate(int r,int x)
{
SegDisplay=g_digits[x]; // получаем цифру и выводим символ, из массива цифр, соответствующий этой цифре.
RazrDisplay=g_registerArray[r];  // получаем цифру и выводим номер регистра, из массива цифр, соответствующий этой цифре.
  digitalWrite(latchPin, LOW);  // устанавливаем синхронизацию "защелки" на LOW
      shiftOut(dataPin, clockPin, MSBFIRST, RazrDisplay); // Записываем информацию для второго регистра (Номер разряда)
      shiftOut(dataPin, clockPin, MSBFIRST, SegDisplay);  // Записываем информацию для первого регистра (Номер символа)
  digitalWrite(latchPin, HIGH);  //"защелкиваем" регистр, тем самым устанавливая значения на выходах
	 
   delay(TimeLight); // пауза, чтобы сегменты "разгорелись"
}

Alexino
Offline
Зарегистрирован: 29.12.2015

Что касается оптимизации.
Все номера ПИНов нужно объявлять через define, чтобы не занимали память.
Все массивы констант - в область программной памяти, чтобы также не занимали ОЗУ. Ибо оно - самый драгоценный ресурс в МК.

Ещё





   long Z=digitalRead(k+14);
   if (Z){NextKey=k+1;

Вы хоть понимаете, что пишите ? Или мне одному кажется, что тут не всё в порядке ?

Тут:





// Разбиваем цифру по разрядам индикатора
Indicate(0, disp / 1000);
Indicate(1, (disp % 1000) / 100);   
Indicate(2, (disp % 100) / 10);
Indicate(3, disp % 10);

вообще кошмар. Поищите нормальные алгоритмы разбитя чисел на цифры.

В общем, над вашим кодом вам ещё работать и работать. Его нужно оптимизировать весь полностью.

И ещё. Кнопки правильнее подключать на минус, подтягивая сопротивлениями к плюсу, а не наоборот.

Кстати, а в каких "попугаях" у вас измеряется время ? Что показывают цифры на индикаторе ?