Помогите написать алгоритм для кнопки.

Kaster308
Offline
Зарегистрирован: 25.12.2017

Задача такая:

При нажатии кнопки (например на 8 пине) необходимо выдать на пин (например 9) напряжение в течении 5 секунд после чего убрать напряжение. Алгоритм без использования delay.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

#18

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

задача понятная, так чем помочь то ? сделать за вас ?

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

qwone пишет:

#18

ща у чела инфаркт будет ))

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

xDriver пишет:
ща у чела инфаркт будет ))
А что делать. Не я такой,а жизнь такая.Программирование Ардуины требует здорового сердца, а потенциальные инфарктники пусть покупают готовые изделия.

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

Kaster308 пишет:

Задача такая:

При нажатии кнопки (например на 8 пине) необходимо выдать на пин (например 9) напряжение в течении 5 секунд после чего убрать напряжение. Алгоритм без использования delay.

я сам новичек, но вот какраз только щас и закончил с кнопками

для вашей задачи всё просто

1) при нажатии кнопки
а) подаете на 9й пин напряжение )
б) запускаете таймер на основе millis()

2) как только он натикал 5 секунд (5000мс) - снимаете с 9й пин напряжение )

Kaster308
Offline
Зарегистрирован: 25.12.2017

ELITE, еслм не сложно можно пример для ознакомления

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

#define button 8 // пин кнопки
#define led 13 // пин выхода напряжения по таймеру

bool lastbutton = 1;     //для считывания кнопки
bool currentbutton =0;   //для считывания кнопки

unsigned long timer = 0; //для таймера 
bool timerenabled = 0;   //для таймера 

void setup() {

pinMode (led, OUTPUT);   
pinMode (button, INPUT); digitalWrite (button, 1); // кнопка замыкает GND


}

void loop() {
 
   currentbutton = debounce (lastbutton);      //для считывания кнопки
  
   

if (timerenabled){ if (millis()-timer>5000) {  //если таймер был включен и он кончился
  timerenabled = 0;                            // выключаем таймер
  digitalWrite (led, 0);                       // выключаем свет
                                            }}

else if (!currentbutton && lastbutton) {  // иначе если таймер не включен и если кнопка нажата
    digitalWrite (led, 1);                        // включаем свет
    timer = millis();                             // нулим таймер
    timerenabled = 1;                             // включаем таймер
                                               }                                         

                                               
   lastbutton = currentbutton;                 //для считывания кнопки    
   
            }

// всё что ниже - для считывания кнопки

bool debounce (bool last){
bool current = digitalRead (button);
if (last != current) {delay (40); current = digitalRead (button);}
return current; }
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

qwone пишет:

#18

Человек же ясно написал - 5 секунд! А Вы даёте пример на 2 секунды! Он что, переделывать должен? Совсем, блин, гуру распустились! :)

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

лучше (ИМХО) параллельно кнопке поставить конденсатор на 100-500нф - никакого дребезга не будет, и никаких усложнений кода //я себе именно так и сделал

также ЗАБУДЬТЕ вы о дефайнах!! - это зло дебага!

ну и мой вариант кода

const int button=8; // пин кнопки
const int led=13; // пин выхода напряжения по таймеру

unsigned long tm = 0; //для таймера 

bool stb=0;	//защита от множественного срабатывания

void setup() {

pinMode (led, OUTPUT);   
pinMode (button, INPUT); digitalWrite (button, 1); // кнопка замыкает GND

}

void loop() {
bool btn = 0;	//"виртуальная" кнопка - сюда пишется факт нажатия кнопки

if(!digitalRead(button)){ if(!stb){stb=1; btn=1; }; }else{ stb=0; }; // фиксирует нажатие кнопки и заносим его в btn
 
if(btn) { tm = millis(); digitalWrite (led, 1); }// если кнопка нажата (btn = екгу) запоминаем текущее время и включаем свет         
  if(tm < millis()-5000 ){ digitalWrite (led, 0); }//время истекло - свет выключаем  
          
}

делает тоже самое, и весит поменьше:

Скетч использует 1042 байт (3%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 14 байт (0%) динамической памяти, оставляя 2034 байт для локальных переменных. Максимум: 2048 байт.
 
а ваш
Скетч использует 1268 байт (4%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 17 байт (0%) динамической памяти, оставляя 2031 байт для локальных переменных. Максимум: 2048 байт.
 
b707
Offline
Зарегистрирован: 26.05.2017

ELITE пишет:

также ЗАБУДЬТЕ вы о дефайнах!! - это зло дебага!

а можно поподробнее о вреде дефайнов?
 
Про код - "защита от множественного срабатывания" не сработает, а остальное, вроде, сойдет. Для теоретика неплохо :)
ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

define - фактически автозамена текста в коде

что будет есть например написать #define setup 12345 ??

правильно - ошибка, при этом компилатор не укажет место ошибки

а если будет код на пару тысяч строк и гдето случайно будет использована переменная по имени совпавшая с дефайном?? - так можно очень легко получить огромную головную боль в поиске этой ошибки!

а если это не критическая для компиляции ошибка? - то она может вылезти в процессе работы устройства, при этом не сразу и рандомно

ну и самое важное - использовать дефайн никак не выгоднее констунты - расурсы они занимают одинаково, размер кода не меняется, нагрузка тоже

но вот только конструнта, как и другие переменные, в случае ошибок - компилятор сразу укажет где и что не так!

----------

по коду - защита от множественного срабатывания - это имеется ввиду, что при нажатой кнопке будет зафиксированно единственное нажатие, не зависимо от кол-ва циклов проверки состояния её - тоесть зафиксирован факт нажатия

а защита от дребезга - как уже сказал - конденсатор || кнопке решает всё лучше всякого кода

100нф дают примерно 5-10мс задержку, что полностью избавляет от всех эффектов дребезга контактов, но при этом вполне позволяет фиксироваю даже очень быстрые повторные нажатия (человеком) - порядка 100 нажатий в секунду - это весьма большой запас!

b707
Offline
Зарегистрирован: 26.05.2017

ELITE пишет:

а если будет код на пару тысяч строк и гдето случайно будет использована переменная по имени совпавшая с дефайном?? - так можно очень легко получить огромную головную боль в поиске этой ошибки!

Для предотвращения этого есть простые правила - хорошим тоном является использовать в именах дефайнов только прописные (большие) буквы, а в переменных, именах функций и тп - строчные(маленькие) или смесь из прописных и строчных.

ELITE пишет:
ну и самое важное - использовать дефайн никак не выгоднее констунты - расурсы они занимают одинаково, размер кода не меняется, нагрузка тоже

А вот тут вы резко ошибаетесь. Дефайн, как вы верно отметили - макроподстановка. поэтому не занимает места в оперативной памяти.

ELITE пишет:

по коду - защита от множественного срабатывания - это имеется ввиду, что при нажатой кнопке будет зафиксированно единственное нажатие, не зависимо от кол-ва циклов проверки состояния её

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

 

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

b707 пишет:

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

я в этом коде подразумеваю, что при проверке кнопки , если она остается нажата (а мк успеет проверить это много десятков раз даже при коротком нажатии) - будет воспринято что было единственное нажатие, а не нажатие кнопки при каждом проходе цикла - это актуально, если надо считать число нажатий например - хотя в задачи ТС это изличше и можно тоже удалить, код станет еще меньше

ну тоже есть часть сути - но тут надо ТС, дабы он ответил, надо ему дожидаться окончания и выключения или нужна возможность продления до окончания таймера....

да и это решается просто перестановкой местами условий, даже код не меняется )

	if(tm-5000 > millis()){ digitalWrite (led, 0); 
		if(btn) { tm = millis(); digitalWrite (led, 1); }	
      }

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

b707 пишет:

ELITE пишет:
ну и самое важное - использовать дефайн никак не выгоднее констунты - расурсы они занимают одинаково, размер кода не меняется, нагрузка тоже

А вот тут вы резко ошибаетесь. Дефайн, как вы верно отметили - макроподстановка. поэтому не занимает места в оперативной памяти.

Если в дефайне строка и он использован в нескольких местах, то в них будет совершенно справедливо откопированна эта строка. Если же используется переменная, то можно обойтись расходом памяти в размере указателя. Ну, и когда константы в переменных, компилятор хотя бы их тип проверяет.

Но я не против дефайнов. Для условной компиляции они - единственное спасение.

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

b707, всё хорошо в меру.  Я вот тоже с дефайнами ужиться не могу,

http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-pamyat-1-chto-i-kak-ne-nado-delat?page=3#comment-336280

предпочитаю static const или просто const.  Компилятор, зачастую, оптимизирует эту const до простой подстановки.  А всё зло дефайнов можно только для условной компиляции использовать.  В остальном - нуихнах... 

ПыСы.  Вот. и sadman то же говорит. 

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

DetSimen пишет:
  Компилятор, зачастую, оптимизирует эту const до простой подстановки. 

кстати да, в примерах и описании именно для ардуины - компилятор так и делает, поэтому и нет лишнего расхода памяти на константы по сравнению с дефайнами

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

по дефайнам и константам

простой пример (часть кода) - далее в коде программы они вызываются также 4 раза (по 1 разу каждая)

#define interval1 100 // таймер 1 - счетчик для секундомера
#define interval2 50 // таймер 2 - обновление экрана
#define interval3 500 // таймер 3 - для тахометра
#define interval4 100 // таймер 4 - таймер кнопок
Скетч использует 7292 байт (23%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 394 байт (19%) динамической памяти, оставляя 1654 байт для локальных переменных. Максимум: 2048 байт.
 
меняю на 
const int interval1 = 100; // таймер 1 - счетчик для секундомера
const int interval2 = 50; // таймер 2 - обновление экрана
const int interval3 = 500; // таймер 3 - для тахометра
const int interval4 = 100; // таймер 4 - таймер кнопок
Скетч использует 7292 байт (23%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 394 байт (19%) динамической памяти, оставляя 1654 байт для локальных переменных. Максимум: 2048 байт.
 
как говорится: "найдите 5 отличий"©....
 
более того - меняю тип переменной
const long interval1 = 100; // таймер 1 - счетчик для секундомера
const long interval2 = 50; // таймер 2 - обновление экрана
const long interval3 = 500; // таймер 3 - для тахометра
const long interval4 = 100; // таймер 4 - таймер кнопок
Скетч использует 7292 байт (23%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 394 байт (19%) динамической памяти, оставляя 1654 байт для локальных переменных. Максимум: 2048 байт.
 
... и как удивительно, но что дефайн что константа инт (1 байт) что лонг (4 байта) - никак не отличаются в итоге....
 
 
b707
Offline
Зарегистрирован: 26.05.2017

Ну хорошо, по расходу оперативки вы меня убедили.  Однако я продолжу (с вашего позволения :) использовать дефайны в своих программах.

Дефайны удобны не только для условной компиляции, но и для замены длинных конструкций короткими, типа

#define PGM_CHR     (const __FlashStringHelper *)

На мой взгляд, и константы удобнее использовать в виде дефайнов - читабельность кода увеливается.

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ELITE пишет:

... и как удивительно, но что дефайн что константа инт (1 байт) что лонг (4 байта) - никак не отличаются в итоге....

Надо же, даже размер кода не увеличивается.... Тут уж без комментариев. 

sadman41
Offline
Зарегистрирован: 19.10.2016

А ежели ему сунуть #pragma GCC optimize ("O0") ?

 
b707
Offline
Зарегистрирован: 26.05.2017

DetSimen пишет:

Надо же, даже размер кода не увеличивается.... Тут уж без комментариев. 

ну ежели компилятор подставляет в код вместо константы ее значение, то это, по сути, дефайн и есть.  Так что выходит, использовать константы или дефайны - дело вкуса.

На стороне констант - проверка типа переменной и варнинги о потенциальных ошибках. На стороне дефайна - лучшая структурированность и читабельность кода, поскольку дефайны не сливаются с прочими константами и переменными, что позволяет выделить в коде важные для работы настройки.

MaksVV
Offline
Зарегистрирован: 06.08.2015

дефайны не дефайны, щас ТС испугается и убежит от таких страшных слов. ЗЫ. Зато в моем коде конденсатор не нужен на кнопку)

b707
Offline
Зарегистрирован: 26.05.2017

MaksVV пишет:

щас ТС испугается и убежит

"Слушай, говорит, кто он такой этот потерпевший? Куда он пошел? Я его, говорит, первый раз вижу." (с)

Logik
Offline
Зарегистрирован: 05.08.2014

Kaster308 пишет:

Задача такая:

При нажатии кнопки (например на 8 пине) необходимо выдать на пин (например 9) напряжение в течении 5 секунд после чего убрать напряжение. Алгоритм без использования delay.

Отчего же не помочь. Тем более в этом году еще не помогал.

#define PIN_BTN 8
#define PIN_OUT 9
#define DIVER100 100
#define TIME 5
#define TIME_DIVER (TIME*1000/DIVER100)
#define KEY digitalRead(PIN_BTN)


void setup() 
{
  // put your setup code here, to run once:
  pinMode(PIN_BTN, INPUT_PULLUP);
  pinMode(PIN_OUT, OUTPUT);
  Serial.begin(9600);
}

byte TimerProcess(byte t, byte (*pFn)(void))
{
 static byte m=0;
 static byte c=0;

 if((byte)(t-m)<DIVER100)
  return 0;

 m=t;

 if(c)
 {
  if(c<TIME_DIVER)
  {
    c++;
    return 1;
  }
  c=0;
  return 2;
 }
 
 if(pFn())
  return 3;
 c++;
 return 4; 
}

void loop() 
{
  switch (TimerProcess(millis(),[]()->byte{KEY;}))
  {
   case 2: digitalWrite(PIN_OUT, LOW);break;
   case 4: digitalWrite(PIN_OUT, HIGH);break; 
  }
}

Удачно сдать как Си выучите не зазнавайтесь, на форум заглядывайте, тоже уому поможете.

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

MaksVV пишет:

Зато в моем коде конденсатор не нужен на кнопку)

аппаратные решения всегда надежнее программных

и да, у вас есть убиственная delay! еще до кучи

 

Logik
Offline
Зарегистрирован: 05.08.2014

ELITE пишет:

MaksVV пишет:

Зато в моем коде конденсатор не нужен на кнопку)

аппаратные решения всегда надежнее программных

Да ну! Ща перепаяю вот высохший электролит, и пойду высохший код искать.

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

Logik пишет:

ELITE пишет:

MaksVV пишет:

Зато в моем коде конденсатор не нужен на кнопку)

аппаратные решения всегда надежнее программных

Да ну! Ща перепаяю вот высохший электролит, и пойду высохший код искать.

какие электролиты?! - кнопке нужен (и достаточен) обычный керамический кондер размером со спичечную головку... а они практически вечные, даже если он начнет терять емкость лет через 15 - он будет работать не хуже .... а лет через 50-70 маловероятно, что изделие еще будет актуально и работоспособно..., кнопки явно сотрутся в пыль за такой срок... а вот кондер наверняка будет спокойно жить...

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Logik пишет:

Удачно сдать

Садист! :)

Logik
Offline
Зарегистрирован: 05.08.2014

Вы же писали "всегда надежнее" вот и обсуждаю что хочу. Код надежность не теряет. Потому представления из категории "механика надежней электроники" оставте в прошлом веке им там самое место.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

b707 пишет:

DetSimen пишет:

Надо же, даже размер кода не увеличивается.... Тут уж без комментариев. 

ну ежели компилятор подставляет в код вместо константы ее значение, то это, по сути, дефайн и есть.  Так что выходит, использовать константы или дефайны - дело вкуса.

 

Этот коммент не Вам, а Илите.  У него, что с int, что с long код одного размера, что говорит о том, что компилятор потёр всё ненужное.  Иначе с long кода бы было больше, грузить в регистры int несколько короче чем long. 

 

Я вот про это говорил.

1 const int interval1 = 100; // таймер 1 - счетчик для секундомера
2 const int interval2 = 50; // таймер 2 - обновление экрана
3 const int interval3 = 500; // таймер 3 - для тахометра
4 const int interval4 = 100; // таймер 4 - таймер кнопок
Скетч использует 7292 байт (23%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 394 байт (19%) динамической памяти, оставляя 1654 байт для локальных переменных. Максимум: 2048 байт.
 
как говорится: "найдите 5 отличий"©....
 
более того - меняю тип переменной
1 const long interval1 = 100; // таймер 1 - счетчик для секундомера
2 const long interval2 = 50; // таймер 2 - обновление экрана
3 const long interval3 = 500; // таймер 3 - для тахометра
4 const long interval4 = 100; // таймер 4 - таймер кнопок
Скетч использует 7292 байт (23%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 394 байт (19%) динамической памяти, оставляя 1654 байт для локальных переменных. Максимум: 2048 байт.
 
Logik
Offline
Зарегистрирован: 05.08.2014

Ворота пишет:

Logik пишет:

Удачно сдать

Садист! :)

))) Ни одно доброе дело не останится безнаказаным!

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

ELITE пишет:

аппаратные решения всегда надежнее программных

Да, неужели? Так-таки и всегда?

MaksVV
Offline
Зарегистрирован: 06.08.2015

ELITE пишет:
аппаратные решения всегда надежнее программных

и да, у вас есть убиственная delay! еще до кучи

все правда, только ТСу я думаю это не помешает. А проверить легче. Нужна только дуня. 

b707
Offline
Зарегистрирован: 26.05.2017

DetSimen пишет:

Этот коммент не Вам, а Илите.  У него, что с int, что с long код одного размера, что говорит о том, что компилятор потёр всё ненужное.  Иначе с long кода бы было больше, грузить в регистры int несколько короче чем long.

 

 

все понятно. Константы обьявлены, но в коде, видимо, не используются. Подтасовочка :)

У кого Ардуино под рукой - проверьте код Илиты с реальным использованием констант...

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

Ворота пишет:

ELITE пишет:

аппаратные решения всегда надежнее программных

Да, неужели? Так-таки и всегда?

что будет, если гипотетически рядом с устройством взорвать атомную бомбу, которая не уничтожит его материально (сключаем температуру и ударное воздействие)

кнопку как была включена - так и останется включена

а вот программа может и словить сбой изза жесткого излучения и мощных магнитных полей - ведь всё крутится в памяти - а достаточно протону пробить ячейки - неизвестно что в ней останется при считывании - а значит и надежность ниже

Да, программно можно сделать коррекцию ошибок и обход аппаратных поломок, но это уже иные системы, а прямоаналогичные аппаратные будут всегда надежней прогреммнях

//и да, давайте не будем топить урановый лом в ванне с ртутью ®

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

вот весь код моей поделки (ну что на сегодня навоял)

/* модуль вывода на экран*/
/*http://arduino.on.kg/rabotaem-s-bibliotekoy-LedControl---razbor-funkciy-i-primery-primeneniya
*/
#include "LedControl.h"

/*
 * Подключаем библиотеку LedControl.h
 * и создаём объект класса LedControl
 * при этом, 7-ми сегметный дисплей с драйвером MAX72xx
 * должен быть подключен к плате Arduino следующим образом:
 * Arduino[Pin 5V] -> Display Module MAX72xx[VCC]
 * Arduino[PinGND] -> Display Module MAX72xx[GND]
 * Arduino[Pin 12] -> Display Module MAX72xx[DIN]
 * Arduino[Pin 11] -> Display Module MAX72xx[CLK]
 * Arduino[Pin 10] -> Display Module MAX72xx[LOAD/CS]
 * 
 */
LedControl lc = LedControl(12, 11, 10, 1);
   const byte ByteTable[10]   = { 
//      0         1         2         3        4           5        6          7         8       9                                               
    B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000,B01111111,B01111011 }  ;
//      
      

 
const long interval1 = 100; // таймер 1 - счетчик для секундомера
const long interval2 = 50; // таймер 2 - обновление экрана
const long interval3 = 500; // таймер 3 - для тахометра
const long interval4 = 100; // таймер 4 - таймер кнопок

int BTN[7] = {3,2,4,5,6,8,13};/* -, + , сброс, +-100,  , запись, датчик*/
bool btn_b[7]={0,0,0,0,0,0,0};
bool stb[7] = {0,0,0,0,0,0,0};
int btn_timer[7] = {0,0,0,0,0,0,0}; /*время нажатия кнопки*/

void setup() {
/* l дисплей*/ 
  lc.shutdown(0, false); //Устройство(7-ми сегментный дисплей) выводим из спящего режима
  lc.setIntensity(0,8);//Установить яркость дисплея на 8 (0..15)  
  lc.clearDisplay(0);//Очистить дисплей

/*кнопки*/
 for (int i = 0; i < 7; i++) {pinMode(BTN[i], INPUT); digitalWrite(BTN[i], HIGH);} 
  Serial.begin(9600);
}


unsigned long tm=0, timer1=0, timer2=0, timer3=0, timer4=0;
int tm1=0, tm2=0, tm3=0, tm4=0;

int tm_st = 0;   //режим работы

float count_odometr = 0;// счетчик одометра

long count_impuls = 0;  // счетчик импульсов
long odometr_0 = 0;     // счетчик пути (общий)
long odometr_1 = 0;     // счетчик пути 1

unsigned long count_tahometr=0,tahomert=0;      // счетчик тахометра

unsigned long count_secundomer=0;    // счетчик секундомера
      int m_sec = 0, sm_sec = 0, sm_min = 0, sm_hom = 0; //разложение минут/с
//---------------------------------------------------------------------------------------------------------------
void loop() {
bool button[11] = {0,0,0,0,0,0,0,0,0,0}; //признак нажатия кнопок

  tm = millis(); //текущий таймер
//  Serial.println(tm);
  tm1 = tm-timer1; /*время таймера 1*/ /*  if(tm1>interval1)  {        Serial.println(tm1);    timer1=tm;  }*/
  tm2 = tm-timer2; /*время таймера 2*/
  tm3 = tm-timer3;
  tm4 = tm-timer4;

/*--------------------- опрос состояния кнопок ---------------------*/
for (int i = 0; i < 7; i++) {  btn_b[i]=!digitalRead(BTN[i]);   }
/*фиксация состояния*/
/*кнопки с фиксацией нажатия (вкл/выкл)*/
if(btn_b[0]){button[0]=1;}else{button[0]=0;};   // +++
if(btn_b[1]){button[1]=1;}else{button[1]=0;};   // ---
if(btn_b[5]){button[5]=1;}else{button[5]=0;};   // калибровка (запись)
/*кнопки без фиксации (факт нажатия)*/

if(btn_b[4]){ if(!stb[4]){stb[4]=1; button[4]=1; }; }else{ stb[4]=0; };    // выбор режима отображения
if(btn_b[6]){ if(!stb[6]){stb[6]=1; button[6]=1; }; }else{ stb[6]=0; };    // датчик оборотов
/*таймерные кнопки*/
if(btn_b[2]){ if(!stb[2]){stb[2]=1; button[2]=1; }; }else{ stb[2]=0; btn_timer[2]=0; };    // СБРОС
if(btn_b[3]){ if(!stb[3]){stb[3]=1; button[3]=1; }; }else{ stb[3]=0; btn_timer[3]=0; };    // +-1 накрутка

if(tm4 > interval4) {  timer4=tm; /*таймер кнопок 10ms*/
  if(btn_b[2]){btn_timer[2]++;  
                if(btn_timer[2]>=30){button[10]=1;btn_timer[2]=30;}else{button[10]=0;};       // полный сброс
               };
  if(btn_b[3]){btn_timer[3]++;  
                if(btn_timer[3]<30&&btn_timer[3]>=10){button[8]=1;}else{button[8]=0;};       // +-10 накрутка
                if(btn_timer[3]>=30){button[9]=1;btn_timer[3]=30;}else{button[9]=0;};        // +-100 накрутка
               };
               
}
 Serial.println(btn_timer[2]);
/*--------------------- обработка событий ----------------------------------*/ 
     /* переключатель режима  */ 
  if( button[4]) {  if(tm_st==5) {tm_st=0;}else{tm_st++;};   } ; 
    
    /*события счетчика датчика*/
  if( button[5]) { /* калибровка */
       if(button[0]) { /*счет + */  
          if(button[6]) { count_impuls++; };   
          if(button[3]) { count_impuls+=1; };   
          if(button[8]) { count_impuls+=10; };   
          if(button[9]) { count_impuls+=100; };   
       }
       if(button[1]) { /*счет -*/
          if(button[6]) { count_impuls--; };      
          if(button[3]) { count_impuls-=1; };   
          if(button[8]) { count_impuls-=10; };   
          if(button[9]) { count_impuls-=100; };  
       }
          
    if(tm_st==0||tm_st==1){/*одометры*/   count_odometr = count_impuls;      }  //вывод на экран
    
  }else{ //обычный режим
          if(button[0]) { /*счет + */
            if(button[6]) { odometr_0++; odometr_1++; };   
            if(button[3]) { odometr_0+=1; odometr_1+=1; };   
            if(button[8]) { odometr_0+=10; odometr_1+=10; };   
            if(button[9]) { odometr_0+=100; odometr_1+=100; }; 
          }   
          if(button[1]) { /*счет -*/
            if(button[6]) { odometr_0--; odometr_1--; };      
            if(button[3]) { odometr_0-=1; odometr_1-=1; };   
            if(button[8]) { odometr_0-=10; odometr_1-=10; };   
            if(button[9]) { odometr_0-=100; odometr_1-=100; };     
          }   
     /*одометры - вывод на экран*/      
    if(tm_st==0){  if (count_impuls==0){count_odometr==0;} else { count_odometr = (odometr_0)*(1000/float(count_impuls));}; } /*общий*/
    if(tm_st==1){  if (count_impuls==0){count_odometr==0;} else { count_odometr = (odometr_1)*(1000/float(count_impuls));}; } /*участой*/
  }

    /* таймер (секундомер */   
      if(tm1 > interval1) {  timer1=tm;  /*Serial.println(tm_c);*/  
        count_secundomer++; m_sec=count_secundomer; if(count_secundomer>=10){count_secundomer=0;};      
        if(m_sec>=10) {m_sec=0;sm_sec++;};
        if(sm_sec>=60) {sm_sec=0;sm_min++;};
        if(sm_min>=60) {sm_min=0;sm_hom++;};
      }  /*таймер*/ 
      if(tm_st==2){/*таймер показ*/   
      //  sm_sec = 0, sm_min = 0, sm_hom = 0;

      //Serial.println(count_secundomer);Serial.println(sm_sec);Serial.println(sm_min);Serial.println(sm_hom);
    }

    /*Тахометр*/

    if(button[6]) count_tahometr++;
    if(tm3>interval3)  { timer3=tm; 
      tahomert = count_tahometr*120;
      count_tahometr = 0;
    //Serial.println(tahomert);
    }
      
      
   /*----------- сбросы!--------*/  
    if(button[2]) {
    if(tm_st==0){ if( button[5]){count_impuls = 0; }  else {odometr_0 = 0;}  };  //режим одометра общий
    if(tm_st==1){ if( button[5]){count_impuls = 0; }  else {odometr_1 = 0;}  };  //режим одометра участок
    if(tm_st==2){ count_secundomer=m_sec=sm_sec=sm_min=sm_hom=0;  };             //режим таймера   
    }
if(button[10]) {/*ПОЛНЫЙ сброс (кроме колибровки)*/
     odometr_0 = odometr_1 = 0;
     count_secundomer=m_sec=sm_sec=sm_min=sm_hom=0;
}
//Serial.println(count_odometr);   
  
/*--------------------------- Обработка и формирование данных для вывода на экран ---------------------------*/
//count_odometr = 15710.05624;

  if(tm2 > interval2) {    timer2=tm;  /*делаю 5 обновлений экрана в секунду (чаще нет смысла*/
  
  byte celoe[8]={0,0,0,0,0,0,0,0}; // 8 байт для вывода на экран
  int count_c=0; // число знаков целой части
  /*--------------------- Одометр ---------------------------*/
    if(tm_st==0||tm_st==1){/*одометры*/      
      int count_c=0; // число знаков целой части
      long disp_c = abs(count_odometr);          // целая часть числа            
      long j=disp_c;         
      for (int i=1; i<=8; i=i+1){  if (j<10){count_c=i; break;} else {  j = j/10;  } } //count_c = длинне целой части числа
      for (int i=0; i<count_c; i++) {
            celoe[i] = ByteTable[(disp_c % 10)];
            if(i==3) celoe[i]|=B10000000; //точка через 3 знака
            disp_c /= 10;   
          }  
         if (count_odometr<0){celoe[count_c]=B00000001;count_c++;} //знак - для отрицательного числа              
    }
  /*--------------------- Тахометр ---------------------------*/
    if(tm_st==3){/*tahomert*/
      int count_c=0; // число знаков целой части
      long j=tahomert;         
      for (int i=1; i<=8; i=i+1){  if (j<10){count_c=i; break;} else {  j = j/10;  } } //count_c = длинне целой части числа  
           j=tahomert;
      for (int i=0; i<count_c; i++) {
            celoe[i] = ByteTable[(j % 10)];
            if(i==3) celoe[i]|=B10000000; //точка через 3 знака
            j /= 10;   
          }       
    }
  /*--------------------- Таймер-Секундомер ---------------------------*/
    if(tm_st==2){/*tahomert*/
      int disp_c = m_sec;
       celoe[0]=ByteTable[(disp_c)];
        disp_c = sm_sec;
       celoe[1]=ByteTable[(disp_c % 10)]; disp_c /= 10;     
       celoe[1]|=B10000000;    
       celoe[2]=ByteTable[(disp_c % 10)]; 
        disp_c = sm_min;
       celoe[3]=ByteTable[(disp_c % 10)]; disp_c /= 10;     
       celoe[3]|=B10000000;    
       celoe[4]=ByteTable[(disp_c % 10)];      
        disp_c = sm_hom;
       celoe[5]=ByteTable[(disp_c % 10)]; disp_c /= 10;     
       celoe[5]|=B10000000;    
       celoe[6]=ByteTable[(disp_c % 10)];      
          
    }


  
  /*--------------------------- вывод на экран ---------------------------*/   
    // lc.clearDisplay(0);

    if (button[5])  celoe[6]=B01100111;    // вывод в левый 8 регистр "P"
                    celoe[7]=ByteTable[tm_st];            // вывод в левый 7 регистр статуса
      for (int i=0; i<8; i++){ /* Serial.print(i);Serial.print('=');Serial.print(celoe[i],BIN);Serial.print("\n\r");*/
      lc.setByte(0, i, (celoe[i]), 0);
           }



  }




}

и да, у меня библиотека изменена немного

LedControl.cpp

/*
 *    LedControl.cpp - A library for controling Leds with a MAX7219/MAX7221
 *    Copyright (c) 2007 Eberhard Fahle
 * 
 *    Permission is hereby granted, free of charge, to any person
 *    obtaining a copy of this software and associated documentation
 *    files (the "Software"), to deal in the Software without
 *    restriction, including without limitation the rights to use,
 *    copy, modify, merge, publish, distribute, sublicense, and/or sell
 *    copies of the Software, and to permit persons to whom the
 *    Software is furnished to do so, subject to the following
 *    conditions:
 * 
 *    This permission notice shall be included in all copies or 
 *    substantial portions of the Software.
 * 
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *    OTHER DEALINGS IN THE SOFTWARE.
 */


#include "LedControl.h"

//the opcodes for the MAX7221 and MAX7219
#define OP_NOOP   0
#define OP_DIGIT0 1
#define OP_DIGIT1 2
#define OP_DIGIT2 3
#define OP_DIGIT3 4
#define OP_DIGIT4 5
#define OP_DIGIT5 6
#define OP_DIGIT6 7
#define OP_DIGIT7 8
#define OP_DECODEMODE  9
#define OP_INTENSITY   10
#define OP_SCANLIMIT   11
#define OP_SHUTDOWN    12
#define OP_DISPLAYTEST 15

LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) {
    SPI_MOSI=dataPin;
    SPI_CLK=clkPin;
    SPI_CS=csPin;
    if(numDevices<=0 || numDevices>8 ) numDevices=8;
    maxDevices=numDevices;
    pinMode(SPI_MOSI,OUTPUT);
    pinMode(SPI_CLK,OUTPUT);
    pinMode(SPI_CS,OUTPUT);
    digitalWrite(SPI_CS,HIGH);
    SPI_MOSI=dataPin;
    for(int i=0;i<64;i++) 
        status[i]=0x00;
    for(int i=0;i<maxDevices;i++) {
        spiTransfer(i,OP_DISPLAYTEST,0);
        //при запуске scanlimit имеет значение max
        setScanLimit(i,7);
        //декодирование выполняется в исходном коде
        spiTransfer(i,OP_DECODEMODE,0);
        clearDisplay(i);
        //переходим в shutdown-режим при запуске
        shutdown(i,true);
    }
}

int LedControl::getDeviceCount() {
    return maxDevices;
}

void LedControl::shutdown(int addr, bool b) {
    if(addr<0 || addr>=maxDevices)
        return;
    if(b)
        spiTransfer(addr, OP_SHUTDOWN,0);
    else
        spiTransfer(addr, OP_SHUTDOWN,1);
}

void LedControl::setScanLimit(int addr, int limit) {
    if(addr<0 || addr>=maxDevices)
        return;
    if(limit>=0 && limit<8)
        spiTransfer(addr, OP_SCANLIMIT,limit);
}

void LedControl::setIntensity(int addr, int intensity) {
    if(addr<0 || addr>=maxDevices)
        return;
    if(intensity>=0 && intensity<16)	
        spiTransfer(addr, OP_INTENSITY,intensity);
}

void LedControl::clearDisplay(int addr) {
    int offset;

    if(addr<0 || addr>=maxDevices)
        return;
    offset=addr*8;
    for(int i=0;i<8;i++) {
        status[offset+i]=0;
        spiTransfer(addr, i+1,status[offset+i]);
    }
}

void LedControl::setLed(int addr, int row, int column, boolean state) {
    int offset;
    byte val=0x00;

    if(addr<0 || addr>=maxDevices)
        return;
    if(row<0 || row>7 || column<0 || column>7)
        return;
    offset=addr*8;
    val=B10000000 >> column;
    if(state)
        status[offset+row]=status[offset+row]|val;
    else {
        val=~val;
        status[offset+row]=status[offset+row]&val;
    }
    spiTransfer(addr, row+1,status[offset+row]);
}

void LedControl::setRow(int addr, int row, byte value) {
    int offset;
    if(addr<0 || addr>=maxDevices)
        return;
    if(row<0 || row>7)
        return;
    offset=addr*8;
    status[offset+row]=value;
    spiTransfer(addr, row+1,status[offset+row]);
}

void LedControl::setColumn(int addr, int col, byte value) {
    byte val;

    if(addr<0 || addr>=maxDevices)
        return;
    if(col<0 || col>7) 
        return;
    for(int row=0;row<8;row++) {
        val=value >> (7-row);
        val=val & 0x01;
        setLed(addr,row,col,val);
    }
}
void LedControl::setByte(int addr, int digit, byte value, boolean dp) {
    int offset;
 
    if(addr<0 || addr>=maxDevices)
        return;
    if(digit<0 || digit>7 )
        return;
    offset=addr*8;
    if(dp) value|=B10000000;
    status[offset+digit]=value;
    spiTransfer(addr, digit+1,value);
}

void LedControl::setDigit(int addr, int digit, byte value, boolean dp) {
    int offset;
    byte v;

    if(addr<0 || addr>=maxDevices)
        return;
    if(digit<0 || digit>7 || value>15)
        return;
    offset=addr*8;
    v=pgm_read_byte_near(charTable + value); 
    if(dp)
        v|=B10000000;
    status[offset+digit]=v;
    spiTransfer(addr, digit+1,v);
}

void LedControl::setChar(int addr, int digit, char value, boolean dp) {
    int offset;
    byte index,v;

    if(addr<0 || addr>=maxDevices)
        return;
    if(digit<0 || digit>7)
        return;
    offset=addr*8;
    index=(byte)value;
    if(index >127) {
        //no defined beyond index 127, so we use the space char
        index=32;
    }
    v=pgm_read_byte_near(charTable + index); 
    if(dp)
        v|=B10000000;
    status[offset+digit]=v;
    spiTransfer(addr, digit+1,v);
}

void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data) {
    //Create an array with the data to shift out
    int offset=addr*2;
    int maxbytes=maxDevices*2;

    for(int i=0;i<maxbytes;i++)
        spidata[i]=(byte)0;
    //put our device data into the array
    spidata[offset+1]=opcode;
    spidata[offset]=data;
    //enable the line 
    digitalWrite(SPI_CS,LOW);
    //Now shift out the data 
    for(int i=maxbytes;i>0;i--)
        shiftOut(SPI_MOSI,SPI_CLK,MSBFIRST,spidata[i-1]);
    //latch the data onto the display
    digitalWrite(SPI_CS,HIGH);
}    


LedControl.h

/*
 *    LedControl.h - A library for controling Leds with a MAX7219/MAX7221
 *    Copyright (c) 2007 Eberhard Fahle
 * 
 *    Permission is hereby granted, free of charge, to any person
 *    obtaining a copy of this software and associated documentation
 *    files (the "Software"), to deal in the Software without
 *    restriction, including without limitation the rights to use,
 *    copy, modify, merge, publish, distribute, sublicense, and/or sell
 *    copies of the Software, and to permit persons to whom the
 *    Software is furnished to do so, subject to the following
 *    conditions:
 * 
 *    This permission notice shall be included in all copies or 
 *    substantial portions of the Software.
 * 
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *    OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef LedControl_h
#define LedControl_h

#include <avr/pgmspace.h>

#if (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

/*
 * Segments to be switched on for characters and digits on
 * 7-Segment Displays
 */
const static byte charTable [] PROGMEM  = { 
//      0         1         2		   3		4		  5			6		 7                                               
    B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000,	//8
// 		8		  9			A		  b         c         d         e         f 
    B01111111,B01111011,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,	//16
//		g		  h      	i		 j			k		 L			m		 n	
    B00000000,B00000000,B00010000,B00111100,B00000000,B00001110,B00000000,B00010101,	//24
//	    o		  p	 		q		  r         s         t		    u		  v		  
    B01111110,B01100111,B01110011,B00000101,B00000000,B00000000,B00011100,B00000000,	//32
//      w         x        y         z                                                            	
    B00000000,B00000000,B00111011,B00000000,B00000000,B00000000,B00000000,B00000000,	//40
//                                                        -                           	
    B00000000,B00000000,B00000000,B00000000,B10000000,B00000001,B10000000,B00000000,	//48
//      0         1         2         3         4         5         6         7              	
    B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000,
//      8         9                                                                     	
    B01111111,B01111011,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
//                A          b         c         d        e         f        g              	
    B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000,
//      H         I         J         K          L         M         N        O               	
    B00110111,B00000000,B00111100,B00000000,B00001110,B00000000,B00000000,B01111110,
//      P         Q          R        S        T          U         V        W                       	
    B01100111,B00000000,B00000101,B01011011,B00000000,B00111110,B00000000,B00000000,
//      X          Y         Z                                                                     	
    B00000000,B00111011,B00000000,B00000000,B00000000,B00000000,B00000000,B00001000,
//                           b         c         d         e        f         g             	
    B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000,
//      H          i         j        k        L          m         n        o         	
    B00110111,B00010000,B00000000,B00000000,B00001110,B00000000,B00010101,B00011101,
//      p          q         r        s	      t		    u		  v		    w                    	
    B01100111,B01110011,B00000101,B00000000,B00000000,B00000000,B00000000,B00000000,
//      x         y          z                                                                   	
    B00000000,B00111011,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000
};

class LedControl {
    private :
        /*Массив для переноса данных на устройства / The array for shifting the data to the devices */
        byte spidata[16];
        /* Отправка одной команды на устройство / Send out a single command to the device */
        void spiTransfer(int addr, byte opcode, byte data);

        /* We keep track of the led-status for all 8 devices in this array */
		/* Мы следим водить-состояния для всех 8 приборов в этом массиве */    
		byte status[64];
        /* Data is shifted out of this pin*/
		/* Данные перемещаются из этого pin-кода*/
        int SPI_MOSI;
        /* The clock is signaled on this pin */
		/* Часы сигнал на этом выводе */
        int SPI_CLK;
        /* This one is driven LOW for chip selectzion */
		/* Это одно управляется низким уровнем для selectzion обломока */
        int SPI_CS;
        /* The maximum number of devices we use */
		/* Максимальное количество устройств, которые мы используем */
        int maxDevices;

    public:
        /* 
         * Создание нового контроллера 
		* Параметры :
		* dataPin пин на Arduino, где получает данные перенесены из
		* clockPin пин для часов
		* pin cspin для выбирать прибор 
		* numdevices максимальное количество устройств, которые можно контролировать
         */
        LedControl(int dataPin, int clkPin, int csPin, int numDevices=1);

        /*
		 * Получает количество устройств, подключенных к этому LedControl.
		 * Возвращать :
		 * int количество устройств на этом LedControl         */
        int getDeviceCount();

        /* 
		* Установите режим выключения (энергосбережения) для устройства
		 * Параметры :
		 * addr адрес дисплея, котор нужно контролировать
		 * состояние при значении true устройство переходит в режим выключения питания. Задать значение false
		 * для нормальной работы.
		 */
		void shutdown(int addr, bool status);

		/* 
		 * Установите количество цифр (или строк) для отображения.
		 * Смотрите даташит на побочные эффекты от scanlimit на яркость
		 * дисплея.
		 * Параметры :
		 * адрес addr дисплея, котор нужно контролировать
		 * ограничить количество отображаемых цифр (1..Восемь)
		 */
        void setScanLimit(int addr, int limit);

		/* 
		 * Установите яркость дисплея.
		 * Параметры:
		 * addr адрес дисплея, котор нужно контролировать
		 * интенсивность яркость дисплея. (0..15)
		 */   
		 void setIntensity(int addr, int intensity);
		/* 
		 * Выключите все светодиоды на дисплее. 
		 * Параметры:
		 * адрес addr дисплея, котор нужно контролировать
		 */
        void clearDisplay(int addr);

/* 
 * Установите состояние одного светодиода.
 * Параметры :
 * адрес addr дисплея 
 * строка строки светодиода (0..Семь)
 * соедините колонку светодиода (0..Семь)
 * государство, если справедливо включения светодиода, 
 * при значении false она выключена
 */
        void setLed(int addr, int row, int col, boolean state);

/* 
 * Установите все 8 светодиодов подряд в новое состояние
 * Параметры:
 * адрес addr дисплея
 * строка строки, которая должна быть установлена (0..Семь)
 * значение каждого бита 1 будет загораться
 * соответствуя Сид.
 */
        void setRow(int addr, int row, byte value);

/* 
 * Установите все 8 светодиодов в столбце в новое состояние
 * Параметры:
 * адрес addr дисплея
 * столбец col, который должен быть установлен (0..Семь)
 * значение каждого бита 1 будет загораться
 * соответствуя Сид.
 */
        void setColumn(int addr, int col, byte value);

/* 
 * Отображение байта на 7-Сегментном дисплее
 * Параметры:
 * адрес addr дисплея
 * цифра положение цифры на дисплее (0..Семь)
 * значение отображаемое значение. (0x00000000..0x11111111)
 * ДП устанавливает десятичной точки.
 */        void setByte(int addr, int digit, byte value, boolean dp);
/* 
 * Отображение шестнадцатеричной цифры на 7-Сегментном дисплее
 * Параметры:
 * адрес addr дисплея
 * цифра положение цифры на дисплее (0..Семь)
 * значение отображаемое значение. (0x00..0x0F)
 * ДП устанавливает десятичной точки.
 */        void setDigit(int addr, int digit, byte value, boolean dp);

/* 
 * Отображение символа на 7-Сегментном дисплее.
 * Есть только несколько символов, которые имеют смысл здесь :
 * 	'0','1','2','3','4','5','6','7','8','9','0',
 *  'A','b','c','d','E','F','H','L','P',
 * ' .','-','_',' ' 
 * Параметры:
 * адрес addr дисплея
 * обозначьте положение символа на дисплее (0..Семь)
 * значение отображаемого символа. 
 * ДП устанавливает десятичной точки.
 */
        void setChar(int addr, int digit, char value, boolean dp);
};

#endif	//LedControl.h



 

Logik
Offline
Зарегистрирован: 05.08.2014

ELITE пишет:

если гипотетически рядом с устройством взорвать атомную бомбу, которая не уничтожит его материально (сключаем температуру и ударное воздействие)

простой, доступный, повседневный пример :)

Хватит демагогию разводить. Как кондеры из строя выходят без ядерного взрыва хороше известно, если ума не хватает без довесок код писать - Ваша проблема.

b707
Offline
Зарегистрирован: 26.05.2017

ELITE пишет:

вот весь код моей поделки (ну что на сегодня навоял)

позвольте вас спросить, как художник художника :) чем отличаются эти строки? (123 -124)

if(button[6]) { odometr_0++; odometr_1++; };  
if(button[3]) { odometr_0+=1; odometr_1+=1; };  

 

Судя по строчкам 205-220, пользоваться циклами вы так и не научились...

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

b707 пишет:

ELITE пишет:

вот весь код моей поделки (ну что на сегодня навоял)

позвольте вас спросить, как художник художника :) чем отличаются эти строки? (123 -124)

if(button[6]) { odometr_0++; odometr_1++; };  
if(button[3]) { odometr_0+=1; odometr_1+=1; };  

 

Судя по строчкам 205-220, пользоваться циклами вы так и не научились...

по 123 -124 - это для наглядности, код в процессе написания и нет четкого ТЗ - поэтому меняется по 5 раз на дню... 

как будет боле-менее законченый алгоритм работы устройства - тогда буду уже оптимизировать 

а по 205-220 - я чтото не придумал как сюда запихать цикл с учетом изменений на некоторых итерациях

размер кода с циклом будет практически идентичен текущему (немного меньше) - но для наглядности пока разрабатываю мне было удобнее без цикла это оставить

---

а вообще у меня пока нет вопросов по моему коду - давайте не отклонятся всёже от темы ТС :)

а свой код я выложу позже с просьбой оценить и подсказать по оптимизации, когда он будет близок к релизной версии

arduinec
Offline
Зарегистрирован: 01.09.2015

ELITE пишет:

и как удивительно, но что дефайн что константа инт (1 байт) что лонг (4 байта) - никак не отличаются в итоге

int занимает 2 байта (char размером в 1 байт).

Большое количество дефайнов в скетче можно посмотреть здесь: http://arduino.ru/forum/proekty/transistor-tester-arduino

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

да по дефейнаи много статей - но на цвет... как говорится...

arduinec
Offline
Зарегистрирован: 01.09.2015

ELITE пишет:

что будет, если гипотетически рядом с устройством взорвать атомную бомбу, которая не уничтожит его материально (сключаем температуру и ударное воздействие)

кнопку как была включена - так и останется включена

а вот программа может и словить сбой изза жесткого излучения и мощных магнитных полей - ведь всё крутится в памяти - а достаточно протону пробить ячейки - неизвестно что в ней останется при считывании - а значит и надежность ниже

И какой толк в нажатой кнопке, если программа это нажатие не сможет обработать?

P.S. (юмор) Инструкция-приказ: солдат, попавший в эпицентр ядерного взрыва, должен держать автомат на вытянутых руках, чтобы расплавленный металл не капал на казённые сапоги.

arduinec
Offline
Зарегистрирован: 01.09.2015

ELITE пишет:

аппаратные решения всегда надежнее программных

Арифмометр и счёты возможно надёжнее, но присутствующие на данном форуме почему-то предпочитают компьютеры с программным обеспечением.

arduinec
Offline
Зарегистрирован: 01.09.2015

ELITE пишет:

также ЗАБУДЬТЕ вы о дефайнах!! - это зло дебага!

Похоже на предупреждение ребёнку: "Не трогай нож - порежешься!"

Каждый инструмент (define в частности) требует правильного применения. При безграмотном программировании можно и с константами накуролесить.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ELITE пишет:
достаточно протону пробить ячейки

В то время, как космические корабли бороздят просторы большого театра ....

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ELITE пишет:

а вот программа может и словить сбой изза жесткого излучения и мощных магнитных полей - ведь всё крутится в памяти - а достаточно протону пробить ячейки - неизвестно что в ней останется при считывании - а значит и надежность ниже

Жесткое излучение - воздействие на аппаратуру, а не на программу. И, кстати, для защитты тоже применяются аппаратные средства, а не программные.

Кстати, если бы Вы употребляли полные термины (аппаратный сбой) вместо кратких (сбой), это было бы понятно с самого начала.

Logik
Offline
Зарегистрирован: 05.08.2014

Конечно было бы понятно, но так зафлудить тему бы не получилось.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Сегодня коллега попросил подсказать ему как примерно такой же код набросать.
Получилось так.
boolean LastState=0;
boolean knopka= 0;
boolean led=0;
int x=0;
unsigned long LastTime=0;
void setup(){
Serial.begin(9600);
pinMode(3,0x2);
pinMode(13,0x1);
}
void loop(){
knopka=!digitalRead(3);
if(knopka!=LastState&&knopka==1){delay(10);led=!led;x++;
LastState=knopka;
}
if(knopka!=LastState&&knopka==0){delay(10);LastState=0;}
digitalWrite(13,led);
if(digitalRead(3)==0){if(millis()-LastTime>=3000){Serial.println(x);LastTime=millis();}}
else{LastTime=millis();}

}

Включаем и выключаем диод одной кнопкой, при удерживании кнопки долее 3 секунд выводим в монитор количество нажатий.

Logik
Offline
Зарегистрирован: 05.08.2014

Шото у препода фантазии никакой.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Kakmyc пишет:
Получилось так.
А что, нормально вставлять код Вы так и не научились?