Необходимо включить насос через 3 минутыпосле того как одна из трех кнопок нажата(удерживается,сухой контакт) и отключить насос через 1 минутуесли ни одна кнопка не нажата.P.S. для теплого пола. 3 минуты задержки нужны для открытия сервопривода на коллекторе и 1 минута на закрытие
/*насос*/
unsigned long mill; // переменная под millis()
//-------кнопки---------------------
const byte Btn1Pin =/*пин*/2;
const byte Btn2Pin =/*пин*/3;
const byte Btn3Pin =/*пин*/4;
//-------насос---------------------
const byte pumpPin =/*пин*/13;
byte state = 0; /*0 выкл /1 вкл /2 собирается выкл/3 собирается вкл*/
const unsigned long timeON = 180000;
const unsigned long timeOFF = 60000;
unsigned long pastPump;
void stand(byte s) { /*установить в состояние*/
state = s;
pastPump = mill;
switch (s) {
case 0:/*0 выкл*/
digitalWrite(pumpPin, LOW);
break;
case 1:/*1 вкл*/
digitalWrite(pumpPin, HIGH);
break;
}
}
void initPump() { /* инициализация воткнуть в setup*/
pinMode(Btn1Pin, OUTPUT);
stand(0);
}
void runPump() { /*воткнуть в loop*/
if (state == 2 && mill - pastPump >= timeON ) stand(0);
if (state == 3 && mill - pastPump >= timeOFF) stand(1);
}
void ONtime() { /*вкл с задержкой*/
if (state == 1)return;
if (state == 3)return;
stand(3);
}
void OFFtime() { /*выкл с задержкой*/
if (state == 0)return;
if (state == 2)return;
stand(2);
}
//--------------main--------------
void setup() {
pinMode(Btn1Pin, INPUT_PULLUP);
pinMode(Btn2Pin, INPUT_PULLUP);
pinMode(Btn3Pin, INPUT_PULLUP);
initPump();
}
void loop() {
mill = millis();
bool Btn1 = digitalRead(Btn1Pin);
bool Btn2 = digitalRead(Btn2Pin);
bool Btn3 = digitalRead(Btn3Pin);
if (!Btn1 || !Btn2 || !Btn3) { /*если одна из кнопок нажата*/
ONtime(); /*то включить насос с задержкой 3 мин*/
}
if (Btn1 && Btn2 && Btn3) { /*если все кнопки отжаты */
OFFtime(); /*то отключить насос с задержкой 1 мин*/
}
runPump() ;
}
/*Скетч использует 1384 байт (4%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 18 байт (0%) динамической памяти, оставляя 2030 байт для локальных переменных. Максимум: 2048 байт.
*/
Так скетч Блинкер. Задаете программу и мигает по программе. Нажали кнопку включилось. еще раз нажали выключилось. Можно хоть на мигать различными ногами и по своей программе.
/**/
unsigned long mill;
typedef void (*pDo)() ;// тип -функция обработчик
//------------------------------------
typedef struct { /*формат записи программы*/
byte maxTick; // количество миганий
unsigned long OnTick; // сколько нужно светить
unsigned long OffTick; // сколько "держать паузу
} Tick_t;
enum {sStop = 0, sStart, sOnTick, sOffTick, sPause};
class Cl_Blinker {
protected:
byte pin;/*нога*/
Tick_t *prog;
unsigned long past, interval;
const unsigned long pause = 1000;/*длительность паузы между сериями*/
byte iTick, iPeriod, maxTick, maxPeriod;
byte state;
void stand(byte s) {
state = s;
past = mill;
switch (state) {
case sStop:
digitalWrite(pin, LOW);
break;
case sStart:
iTick = 0;
iPeriod = 0;
maxTick = prog[iPeriod].maxTick;
state = sOnTick;
case sOnTick:
interval = prog[iPeriod].OnTick;
digitalWrite(pin, HIGH);
break;
case sOffTick:
interval = prog[iPeriod].OffTick;
digitalWrite(pin, LOW);
break;
case sPause:
interval = pause;
break;
}
}
public:
Cl_Blinker(byte p, Tick_t *pr, byte s)
: pin(p), prog(pr), maxPeriod(s) {}
void init() {
pinMode(pin, OUTPUT);
stand(sStop);
}
void run() {
if (state == sOnTick && mill - past >= interval) stand(sOffTick);
if (state == sOffTick && mill - past >= interval) {
iTick++;
if (iTick >= maxTick) {
iPeriod++;
if (iPeriod >= maxPeriod) {
stand(sPause);
return;
}
else {
iTick = 0;
maxTick = prog[iPeriod].maxTick;
stand(sOnTick);
}
}
else stand(sOnTick);
}
if (state == sPause && mill - past >= interval) stand(sStart);
}
void start() {
stand(sStart);
}
void stop() {
stand(sStop);
}
};
//------Cl_Btn----------------------
// класс кнопка
class Cl_Btn {
protected:
const byte pin;
pDo Do1, Do2; //обработчик 1 и 2
bool bounce = 0;
bool btn = 1, oldBtn;
unsigned long past;
byte stand = 0;
void tick() {
if (stand == 0) {
stand = 1;
Do1();
}
else {
stand = 0;
Do2();
}
}
public:
/*конструктор*/
Cl_Btn(byte pin_, pDo D1, pDo D2)
: pin(pin_), Do1(D1), Do2(D2) {}
/*инициализация-вставить в setup()*/
void init() {
pinMode(pin, INPUT_PULLUP);
tick();
}
/*работа-вставить в loop()*/
void run() {
bool newBtn = digitalRead(pin);
if (!bounce && newBtn != btn) {
bounce = 1;
past = mill;
}
if (bounce && mill - past >= 10) {
bounce = 0 ;
oldBtn = btn;
btn = newBtn;
if (!btn && oldBtn) tick();
}
}
};
//------Компоновка-------------------------------
Tick_t prog[] = {
/* maxTick OnTick OffTick*/
{3, 100 , 100}, // 3 коротких
{3, 500 , 100}, // 3 длиных
{3, 100 , 100}, // 3 коротких
};
byte step = sizeof(prog) / sizeof(Tick_t); // вычисляем сколько у нас всего "комманд".
Cl_Blinker Blinker(/*пин*/13,/*программа*/prog,/*количество*/step);
void Do1Btn1() {
Blinker.start();
}
void Do2Btn1() {
Blinker.stop();
}
Cl_Btn Btn1(/*пин*/2,/*обработчик 1*/Do1Btn1,/*обработчик 2*/Do2Btn1);
//---------Main----------------------------
void setup() {
Blinker.init();
Btn1.init();
}
void loop() {
mill = millis();
Blinker.run();
Btn1.run();
}
/*Скетч использует 1910 байт (6%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 74 байт (3%) динамической памяти, оставляя 1974 байт для локальных переменных. Максимум: 2048 байт.
*/
Нипонял, а где мигание зеленого за 3сек до переключения на желтый и где одновременное горение желтого и красного перед переключением на зеленый?
По коду, voidstand(bytes) выполняет 5 действий (причем 2 из них совпадают) в зависимости от параметра, а два из этих действий обернуты в отдельный вызов в стр55-62. Это явно надумано. Делаем просто 4 функции voidstandOFF() voidstandRed() ..... и массив указателей на них, заполненный по порядку их включения. И паузы тоже в массив. В результате стр.50-53 приятно ужимаются почти в одну и их кол-во перестает зависить от числа режимов. И тогда любые хотелки типа мигания зеленого легко добавляются причем почти без правки кода, только добавлением в массив указателей на функции и массив пауз. А совсем уж по уму держать один массив структур.
Logik, здесь используется цифровой автомат. И решается через цифровой автомат. Если начать оптимизировать, то точно сведется к черному ящику и нефиг лезть туда, где и так все работает.
Logik пишет:
Нипонял, а где мигание зеленого за 3сек до переключения на желтый и где одновременное горение желтого и красного перед переключением на зеленый?
Это все можно организовать дополнительным классом. Просто расписав алгоритм работы и состояния системы. Как и частоту мигания . А так же вывод сколько секунд осталось до переключения.
Пух, ну вот КАК тебе удается нести херню, вроде бы, с виду правильными словами? Я вот когда несу, у меня слова неправильные, а у тебя дар. Я прям завидую.
Спасибо вам за тему! Очень полезная. Вы советовали книгу вначале темы. И там как мне показалось указано, что нельзя при создании класса присваивать значение переменным в этом классе. Строки 16 и 17. Однако ваш код работает.
class Cl_Btn {
13
byte pin; // номер ноги на кнопке
14
void (* Do)();// указатель на обработчик
15
bool btn, btn_old;
16
bool bounce = 0; // антидребезговый флаг
17
uint32_t past = 0 ;
18
public:
19
// конструктор класса
20
Cl_Btn( byte _pin, void (* _Do)()): pin(_pin), Do(_Do) {}
21
// метод setup()
22
void setup() {
23
pinMode(pin, INPUT_PULLUP);// подключить кнопку 1 с подтяжкой
24
btn = digitalRead(pin); // прочитать реальное значение на выводе};
25
}
26
// метод loop()
27
void loop() {
28
if (! bounce && btn != digitalRead(pin)) { // если прошел фронт изм на выводн
29
bounce = 1; // выставить флаг
30
past = millis(); // сделать временую засветку
31
}
32
else if ( bounce && millis() - past >= 5 ) { // если прошло антидребезговое время
33
bounce = 0; // то снять флаг
34
btn_old = btn ;
35
btn = digitalRead(pin) ; // прочитать реальное значение на выводе
36
if (btn_old && ! btn) Do();
37
}
38
}
39
};
freeman86, а вот здесь вылез факт о котором новички не догадываются. Они считают что Си/Си++ уже не развивается и не меняется. А последняя редакция Си произошла в 2017 году. А книга о Си написана еще до этих изменений.
нельзя при создании класса присваивать значение переменным в этом классе. Строки 16 и 17.
Без крайней нужды этого лучше не делать. А если делать, то точно знать что именно Вы делаете. Там очень много тонкостей, и очень многое может пойти не так. Инициализация в конструкторе - значительно проще и надёжнее.
вот тут по ссылке бит инверсии. Не понимаю, в чем преимущество такого варианты перед led = !led? И как понимать синтаксис led ^ inv, в таблице я оператор ^ не нашел, только ^=.
Теперь по программе. Есть реле (светодиоды и т д) . Некоторые срабатывают при HIGH, другие по LOW. Можно написать для них два класса. Но можно написать универсальный, где ввести в консруктор дополнитнльную переменную inv. Если inv - LOW , то это срабатывание при HIGH. И обратно. То есть использование оператора ^ упрощает и сокращает код. И в конце концов делает "универсальный класс".
В большинстве случаев, это неважно, там разница маленькая, но методологически это неправильно.
а так сойдёт?
void loop() {
if (uint32_t m = millis() - past > 100) {
*_pnt = map(analogRead(_pin), 0, 1023, 0, 31000);// 31 Ампер
past = m; //millis(); // Измеряем раз в 100 миллисекунд
}
}
Скажите пожалуйста, а как сделать так, чтоб этот код, описанный в посте #18, на выходе выдавал, скажем, 3 импульса по 2 секунды с интервалом между импульсами в 5 секунд?
Скажите пожалуйста, а как сделать так, чтоб этот код, описанный в посте #18, на выходе выдавал, скажем, 3 импульса по 2 секунды с интервалом между импульсами в 5 секунд?
Не нужно разбрасывать свой вопрос одновременно по нескольким темам.
А вот скетч
/**/ unsigned long mill; typedef void (*pDo)(); //------Cl_Display---------------------- // класс регулярный вывод на дисплей class Cl_Display { protected: pDo Do;//обработчик bool refreshON = 1; //сигнал обновить public: /*конструктор*/ Cl_Display(pDo D): Do(D) {} /*инициализация-вставить в setup()*/ void init() { } /*работа-вставить в loop()*/ void run() { if (refreshON) { refreshON = 0; Do(); } } void refresh() { refreshON = 1; } /*записать новый обработчик*/ void write( pDo D) { Do = D; } }; //------Cl_Btn---------------------- class Cl_Btn { /* класс кнопка*/ protected: const byte pin; pDo Do;//обработчик bool bounce = 0; bool btn = 1, oldBtn; unsigned long past; public: /*конструктор*/ Cl_Btn(byte p, pDo D): pin(p), Do(D) {} /*инициализация-вставить в setup()*/ void init() { pinMode(pin, INPUT_PULLUP); } /*работа-вставить в loop()*/ void run() { bool newBtn = digitalRead(pin); if (!bounce && newBtn != btn) { bounce = 1; past = mill; } if (bounce && mill - past >= 10) { bounce = 0 ; oldBtn = btn; btn = newBtn; past = mill; if (!btn && oldBtn) Do(); } } /*записать новый обработчик*/ void write( pDo D) { Do = D; } }; //------Cl_BtnR---------------------- class Cl_BtnR : public Cl_Btn { /* класс кнопка с повтором при удерж кнопки*/ protected: public: /*конструктор*/ Cl_BtnR(byte p, pDo D): Cl_Btn(p, D) {} /*работа-вставить в loop()*/ void run() { bool newBtn = digitalRead(pin); if (!bounce && newBtn != btn) { bounce = 1; past = mill; } if (bounce && mill - past >= 10) { bounce = 0 ; oldBtn = btn; btn = newBtn; past = mill; if (!btn && oldBtn) Do(); } if (!newBtn && !btn && mill - past >= 150) { past = mill; Do(); } } }; //-----Компоненты Меню------------------------- void ExitMenu() {}; int Value1, Value2, Value3, Value4, Value5, Value6, Value7, Value8, Value9; byte screen ; byte line ; bool fEdit; void initMenu( byte screen);/*предварительное объявление*/ //-----sItemMenu---------------- enum { ROOT, HOLDER, CONFIGINT }; struct sItemMenu { byte type; byte num; }; const sItemMenu dbItemMenu[] PROGMEM = { /*type,num*/ {ROOT, 0}, /*#0 ROOT[0] 1-3*/ {HOLDER, 0}, /*#1 HOLDER[0] 4-6*/ {HOLDER, 1}, /*#2 HOLDER[1] 7-9 */ {CONFIGINT, 0},/*#3 var 1 CONFGINT[0]*/ {HOLDER, 2}, /* #4 HOLDER[2] 10-12 */ {CONFIGINT, 1}, /* #5 var 2 CONFGINT[1] */ {CONFIGINT, 2}, /* #6 var 3 CONFGINT[2] */ {CONFIGINT, 3}, /* #7 var 4 CONFGINT[3] */ {CONFIGINT, 4}, /* #8 var 5 CONFGINT[4] */ {CONFIGINT, 5}, /* #9 var 6 CONFGINT[5] */ {CONFIGINT, 6}, /* #10 var 7 CONFGINT[6]*/ {CONFIGINT, 7}, /* #11 var 8 CONFGINT[7]*/ {CONFIGINT, 8} /* #12 var 9 CONFGINT[8]*/ }; void pgm_viev(char *name) {/*вывод из PROGMEM*/ char buffer[15]; strcpy_P(buffer, name); Serial.print(buffer); } //------sItemRoot------------------- struct sItemRoot { const byte top; const byte bottom; const pDo Do; }; const sItemRoot dbItemRoot[] PROGMEM = { {1, 3, ExitMenu} /*ROOT[0]*/ }; byte readTopItemRoot(byte the) { /* <- top[the] */ return pgm_read_byte(&dbItemRoot[the].top); } byte readBottomItemRoot(byte the) { /* <- top[the] */ return pgm_read_byte(&dbItemRoot[the].bottom); } void DoItemRoot(byte the) { /* Do[the] */ pDo Do = pgm_read_word(&dbItemRoot[the].Do); Do(); } //------sItemHolder------------------- struct sItemHolder { const byte father; const byte top; const byte bottom; const char *name; }; const char txtItemHolder0[] PROGMEM = "R0 HOLDER 1"; const char txtItemHolder1[] PROGMEM = "R0 HOLDER 2"; const char txtItemHolder2[] PROGMEM = "H0 HOLDER 3"; const sItemHolder dbItemHolder[] PROGMEM = { /*father,top,bottom,name*/ {0, 4, 6, txtItemHolder0}, /*#0 HOLDER[0]*/ {0, 7, 9, txtItemHolder1}, /*#1 HOLDER[1]*/ {1, 10, 12, txtItemHolder2} /*#2 HOLDER[2]*/ }; byte readFatherItemHolder(byte the) { /* <- father[the] */ return pgm_read_byte(&dbItemHolder[the].father); } byte readTopItemHolder(byte the) { /* <- top[the] */ return pgm_read_byte(&dbItemHolder[the].top); } byte readBottomItemHolder(byte the) { /* <- top[the] */ return pgm_read_byte(&dbItemHolder[the].bottom); } char * readItemHolderName(byte the) { /* <- name[the] */ return (char *)pgm_read_byte(&dbItemHolder[the].name); } //-------sItemConfigInt---------------- struct sItemConfigInt { int * pointer; byte addr; int maxValue; int minValue; int setValue; const char *name; }; const byte numItemConfigInt = 9; /*кол-во элементов ConfigInt */ const char txtItemConfigInt0[] PROGMEM = "R0 var 1="; const char txtItemConfigInt1[] PROGMEM = "H0 var 2="; const char txtItemConfigInt2[] PROGMEM = "H0 var 3="; const char txtItemConfigInt3[] PROGMEM = "H1 var 4="; const char txtItemConfigInt4[] PROGMEM = "H1 var 5="; const char txtItemConfigInt5[] PROGMEM = "H1 var 6="; const char txtItemConfigInt6[] PROGMEM = "H2 var 7="; const char txtItemConfigInt7[] PROGMEM = "H2 var 8="; const char txtItemConfigInt8[] PROGMEM = "H2 var 9="; const sItemConfigInt dbItemConfigInt[] PROGMEM = { /*pointer,addr,max,min,set,name*/ { &Value1, 0, 100, 10, 10, txtItemConfigInt0}, /*CONFGINT[0]*/ { &Value2, 2, 100, 10, 20, txtItemConfigInt1}, /*CONFGINT[1]*/ { &Value3, 4, 100, 10, 30, txtItemConfigInt2}, /*CONFGINT[2]*/ { &Value4, 6, 100, 10, 40, txtItemConfigInt3}, /*CONFGINT[3]*/ { &Value5, 8, 100, 10, 50, txtItemConfigInt4}, /*CONFGINT[4]*/ { &Value6, 10, 100, 10, 60, txtItemConfigInt5}, /*CONFGINT[5]*/ { &Value7, 12, 100, 10, 70, txtItemConfigInt6}, /*CONFGINT[6]*/ { &Value8, 14, 100, 10, 80, txtItemConfigInt7}, /*CONFGINT[7]*/ { &Value9, 16, 100, 10, 90, txtItemConfigInt8} /*CONFGINT[8]*/ }; int readItemConfigInt(byte the) { /*<-VAL[the]* ++ */ int * pointer = pgm_read_word(&dbItemConfigInt[the].pointer); return * pointer; } void readItemConfigIntfromPROGMEM(byte the) { /*VAL[the]<-PROGMEM[the] ++ */ int * pointer = pgm_read_word(&dbItemConfigInt[the].pointer); *pointer = pgm_read_word(&dbItemConfigInt[the].setValue); } void plusItemConfigInt(byte the) {/*if (VAL[the]<max[the]) ++VAL[the]*/ int * pointer = pgm_read_word(&dbItemConfigInt[the].pointer); byte maxValue = pgm_read_byte(&dbItemConfigInt[the].maxValue); if (* pointer < maxValue) *pointer += 1; } void minusItemConfigInt(byte the) {/*if (VAL[the]>min[the]) --VAL[the]*/ int * pointer = pgm_read_word(&dbItemConfigInt[the].pointer); byte minValue = pgm_read_byte(&dbItemConfigInt[the].minValue); if (* pointer > minValue ) *pointer -= 1; } char * readItemConfigIntName(byte the) { /* <- name[the] */ return (char *)pgm_read_byte(&dbItemConfigInt[the].name); } #include <EEPROM.h> void readItemConfigIntfromEEPROM(byte the) { /*VAL[the]<-EEPROM[the]*/ int * pointer = pgm_read_word(&dbItemConfigInt[the].pointer); byte addr = pgm_read_byte(&dbItemConfigInt[the].addr); EEPROM.get(addr, *pointer); } void writeItemConfigIntToEEPROM(byte the) { /*EEPROM[the]<-VAL[the]*/ int * pointer = pgm_read_word(&dbItemConfigInt[the].pointer); byte addr = pgm_read_byte(&dbItemConfigInt[the].addr); EEPROM.put(addr, *pointer); } void readAllItemConfigIntfromEEPROM() { /*VAL[All]<-EEPROM[All]*/ for (int i = 0; i < numItemConfigInt; ++i) { readItemConfigIntfromEEPROM(i); } } void AllItemConfigIntPROGMEMtoEEPROM() { /*EEPROM[All]<-PROGMEM[the][All]*/ for (int i = 0; i < numItemConfigInt; ++i) { int ConfigInt = pgm_read_word(&dbItemConfigInt[i].setValue); byte addr = pgm_read_byte(&dbItemConfigInt[i].addr); EEPROM.put(addr, ConfigInt); } } //------------------- void initMenu( byte scr) { screen = scr; byte type = pgm_read_byte(&dbItemMenu[screen].type); byte num = pgm_read_byte(&dbItemMenu[screen].num); if (type == ROOT) line = pgm_read_byte(&dbItemRoot[num].top); if (type == HOLDER) line = pgm_read_byte(&dbItemHolder[num].top); fEdit = 0; } //------------------- void VievMenu(byte screen, byte line, byte fEdit) { byte type = pgm_read_byte(&dbItemMenu[screen].type); byte num = pgm_read_byte(&dbItemMenu[screen].num); if (type == ROOT) { byte top = pgm_read_byte(&dbItemRoot[num].top); byte bottom = pgm_read_byte(&dbItemRoot[num].bottom); Serial.println(); for (int i = top; i <= bottom; ++i) { Serial.println(); if (i == line) { if (fEdit)Serial.print("*"); else Serial.print(">"); } else Serial.print(" "); byte t = pgm_read_byte(&dbItemMenu[i].type); byte n = pgm_read_byte(&dbItemMenu[i].num); if (t == CONFIGINT) { char * name = readItemConfigIntName(n); pgm_viev(name); int ItemValue = readItemConfigInt(n); Serial.print(ItemValue); } if (t == HOLDER) { char * name = readItemHolderName(n); pgm_viev(name); } } } if (type == HOLDER) { byte top = pgm_read_byte(&dbItemHolder[num].top); byte bottom = pgm_read_byte(&dbItemHolder[num].bottom); Serial.println(); for (int i = top; i <= bottom; ++i) { Serial.println(); if (i == line) { if (fEdit)Serial.print("*"); else Serial.print(">"); } else Serial.print(" "); byte t = pgm_read_byte(&dbItemMenu[i].type); byte n = pgm_read_byte(&dbItemMenu[i].num); if (t == HOLDER) { char * name = readItemHolderName(n); pgm_viev(name); } if (t == CONFIGINT) { char * name = readItemConfigIntName(n); pgm_viev(name); int ItemValue = readItemConfigInt(n); Serial.print(ItemValue); } } } } //-----Компоновка------------------------------ void DoViev() { VievMenu(screen, line, fEdit); } Cl_Display Display(/*обработчик*/DoViev); void DoBtn1() {/*-*/ Display.refresh(); if (fEdit) { /*реж редактирования*/ byte t = pgm_read_byte(&dbItemMenu[line].type); byte n = pgm_read_byte(&dbItemMenu[line].num); if (t == CONFIGINT) { minusItemConfigInt(n); } } else {/*реж передвиж*/ byte type = pgm_read_byte(&dbItemMenu[screen].type); byte num = pgm_read_byte(&dbItemMenu[screen].num); if (type == ROOT) { byte top = pgm_read_byte(&dbItemRoot[num].top); if (line > top ) --line; } if (type == HOLDER) { byte top = pgm_read_byte(&dbItemHolder[num].top); if (line > top ) --line; else if (line == top ) { screen = pgm_read_byte(&dbItemHolder[num].father); byte t = pgm_read_byte(&dbItemMenu[screen].type); byte n = pgm_read_byte(&dbItemMenu[screen].num); if (t == ROOT) line = pgm_read_byte(&dbItemRoot[n].top); else line = pgm_read_byte(&dbItemHolder[n].top); } } } } void DoBtn2() {/*+*/ Display.refresh(); if (fEdit) { /*реж редактирования*/ byte t = pgm_read_byte(&dbItemMenu[line].type); byte n = pgm_read_byte(&dbItemMenu[line].num); if (t == CONFIGINT) { plusItemConfigInt(n); } } else {/*реж передвиж*/ byte type = pgm_read_byte(&dbItemMenu[screen].type); byte num = pgm_read_byte(&dbItemMenu[screen].num); if (type == ROOT) { byte bottom = pgm_read_byte(&dbItemRoot[num].bottom); if (line < bottom ) ++line; } if (type == HOLDER) { byte bottom = pgm_read_byte(&dbItemHolder[num].bottom); if (line < bottom ) ++line; } } } void DoBtn3() {/*exe*/ Display.refresh(); byte t = pgm_read_byte(&dbItemMenu[line].type); byte n = pgm_read_byte(&dbItemMenu[line].num); if (fEdit) { /*реж редактирования*/ if (t == CONFIGINT) { writeItemConfigIntToEEPROM(n); fEdit = 0; } return; } else { /*реж передвиж*/ if (t == HOLDER ) initMenu(line); if (t == CONFIGINT) fEdit = 1; } } Cl_BtnR Btn1(/*пин*/2,/*обработчик*/DoBtn1);/*-*/ Cl_BtnR Btn2(/*пин*/3,/*обработчик*/DoBtn2);/*+*/ Cl_Btn Btn3(/*пин*/4,/*обработчик*/DoBtn3);/*exe*/ //--main()------------------- void setup() { Serial.begin(9600); //AllItemConfigIntPROGMEMtoEEPROM();/*первичная настройка EEPROM из PROGMEM*/ readAllItemConfigIntfromEEPROM(); /*прочитать из памяти*/ initMenu(0);/*установить меню в начало*/ Display.init(); Btn1.init(); Btn2.init(); Btn3.init(); } void loop() { mill = millis(); Display.run(); Btn1.run(); Btn2.run(); Btn3.run(); } /*Скетч использует 4380 байт (14%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 250 байт (12%) динамической памяти, оставляя 1798 байт для локальных переменных. Максимум: 2048 байт. *//*насос*/ unsigned long mill; // переменная под millis() //-------кнопки--------------------- const byte Btn1Pin =/*пин*/2; const byte Btn2Pin =/*пин*/3; const byte Btn3Pin =/*пин*/4; //-------насос--------------------- const byte pumpPin =/*пин*/13; byte state = 0; /*0 выкл /1 вкл /2 собирается выкл/3 собирается вкл*/ const unsigned long timeON = 180000; const unsigned long timeOFF = 60000; unsigned long pastPump; void stand(byte s) { /*установить в состояние*/ state = s; pastPump = mill; switch (s) { case 0:/*0 выкл*/ digitalWrite(pumpPin, LOW); break; case 1:/*1 вкл*/ digitalWrite(pumpPin, HIGH); break; } } void initPump() { /* инициализация воткнуть в setup*/ pinMode(Btn1Pin, OUTPUT); stand(0); } void runPump() { /*воткнуть в loop*/ if (state == 2 && mill - pastPump >= timeON ) stand(0); if (state == 3 && mill - pastPump >= timeOFF) stand(1); } void ONtime() { /*вкл с задержкой*/ if (state == 1)return; if (state == 3)return; stand(3); } void OFFtime() { /*выкл с задержкой*/ if (state == 0)return; if (state == 2)return; stand(2); } //--------------main-------------- void setup() { pinMode(Btn1Pin, INPUT_PULLUP); pinMode(Btn2Pin, INPUT_PULLUP); pinMode(Btn3Pin, INPUT_PULLUP); initPump(); } void loop() { mill = millis(); bool Btn1 = digitalRead(Btn1Pin); bool Btn2 = digitalRead(Btn2Pin); bool Btn3 = digitalRead(Btn3Pin); if (!Btn1 || !Btn2 || !Btn3) { /*если одна из кнопок нажата*/ ONtime(); /*то включить насос с задержкой 3 мин*/ } if (Btn1 && Btn2 && Btn3) { /*если все кнопки отжаты */ OFFtime(); /*то отключить насос с задержкой 1 мин*/ } runPump() ; } /*Скетч использует 1384 байт (4%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 18 байт (0%) динамической памяти, оставляя 2030 байт для локальных переменных. Максимум: 2048 байт. */Так скетч Блинкер. Задаете программу и мигает по программе. Нажали кнопку включилось. еще раз нажали выключилось. Можно хоть на мигать различными ногами и по своей программе.
/**/ unsigned long mill; typedef void (*pDo)() ;// тип -функция обработчик //------------------------------------ typedef struct { /*формат записи программы*/ byte maxTick; // количество миганий unsigned long OnTick; // сколько нужно светить unsigned long OffTick; // сколько "держать паузу } Tick_t; enum {sStop = 0, sStart, sOnTick, sOffTick, sPause}; class Cl_Blinker { protected: byte pin;/*нога*/ Tick_t *prog; unsigned long past, interval; const unsigned long pause = 1000;/*длительность паузы между сериями*/ byte iTick, iPeriod, maxTick, maxPeriod; byte state; void stand(byte s) { state = s; past = mill; switch (state) { case sStop: digitalWrite(pin, LOW); break; case sStart: iTick = 0; iPeriod = 0; maxTick = prog[iPeriod].maxTick; state = sOnTick; case sOnTick: interval = prog[iPeriod].OnTick; digitalWrite(pin, HIGH); break; case sOffTick: interval = prog[iPeriod].OffTick; digitalWrite(pin, LOW); break; case sPause: interval = pause; break; } } public: Cl_Blinker(byte p, Tick_t *pr, byte s) : pin(p), prog(pr), maxPeriod(s) {} void init() { pinMode(pin, OUTPUT); stand(sStop); } void run() { if (state == sOnTick && mill - past >= interval) stand(sOffTick); if (state == sOffTick && mill - past >= interval) { iTick++; if (iTick >= maxTick) { iPeriod++; if (iPeriod >= maxPeriod) { stand(sPause); return; } else { iTick = 0; maxTick = prog[iPeriod].maxTick; stand(sOnTick); } } else stand(sOnTick); } if (state == sPause && mill - past >= interval) stand(sStart); } void start() { stand(sStart); } void stop() { stand(sStop); } }; //------Cl_Btn---------------------- // класс кнопка class Cl_Btn { protected: const byte pin; pDo Do1, Do2; //обработчик 1 и 2 bool bounce = 0; bool btn = 1, oldBtn; unsigned long past; byte stand = 0; void tick() { if (stand == 0) { stand = 1; Do1(); } else { stand = 0; Do2(); } } public: /*конструктор*/ Cl_Btn(byte pin_, pDo D1, pDo D2) : pin(pin_), Do1(D1), Do2(D2) {} /*инициализация-вставить в setup()*/ void init() { pinMode(pin, INPUT_PULLUP); tick(); } /*работа-вставить в loop()*/ void run() { bool newBtn = digitalRead(pin); if (!bounce && newBtn != btn) { bounce = 1; past = mill; } if (bounce && mill - past >= 10) { bounce = 0 ; oldBtn = btn; btn = newBtn; if (!btn && oldBtn) tick(); } } }; //------Компоновка------------------------------- Tick_t prog[] = { /* maxTick OnTick OffTick*/ {3, 100 , 100}, // 3 коротких {3, 500 , 100}, // 3 длиных {3, 100 , 100}, // 3 коротких }; byte step = sizeof(prog) / sizeof(Tick_t); // вычисляем сколько у нас всего "комманд". Cl_Blinker Blinker(/*пин*/13,/*программа*/prog,/*количество*/step); void Do1Btn1() { Blinker.start(); } void Do2Btn1() { Blinker.stop(); } Cl_Btn Btn1(/*пин*/2,/*обработчик 1*/Do1Btn1,/*обработчик 2*/Do2Btn1); //---------Main---------------------------- void setup() { Blinker.init(); Btn1.init(); } void loop() { mill = millis(); Blinker.run(); Btn1.run(); } /*Скетч использует 1910 байт (6%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 74 байт (3%) динамической памяти, оставляя 1974 байт для локальных переменных. Максимум: 2048 байт. */Светофор через цифровой автомат.
Это картинка не подходит для программирования.Попробуем немного изменить.
Вот получился скетч.
/*TrafficLight светофор*/ unsigned long mill; // переменная под millis() //-------------------------------- enum {sOFF = 0, sRed, sYellow1, sGreen, sYellow2}; class Cl_TrafficLight { protected: byte Rpin, Ypin, Gpin; unsigned long past; byte state; void stand(byte s) { past = mill; state = s; switch (state) { case sOFF: digitalWrite(Rpin, LOW); digitalWrite(Ypin, LOW); digitalWrite(Gpin, LOW); break; case sRed: digitalWrite(Ypin, LOW); digitalWrite(Rpin, HIGH); break; case sYellow1: digitalWrite(Rpin, LOW); digitalWrite(Ypin, HIGH); break; case sGreen: digitalWrite(Ypin, LOW); digitalWrite(Gpin, HIGH); break; case sYellow2: digitalWrite(Gpin, LOW); digitalWrite(Ypin, HIGH); break; } } public: /**/ Cl_TrafficLight(byte R, byte Y, byte G) : Rpin(R), Ypin(Y), Gpin(G) {} /**/ void init() { pinMode(Rpin, OUTPUT); pinMode(Ypin, OUTPUT); pinMode(Gpin, OUTPUT); OFF(); } /**/ void run() { if (state == sRed && mill - past >= 3000)stand(sYellow1); if (state == sYellow1 && mill - past >= 1000)stand(sGreen); if (state == sGreen && mill - past >= 3000)stand(sYellow2); if (state == sYellow2 && mill - past >= 1000)stand(sRed); } /*включить*/ void ON() { stand(sRed); } /*выключить*/ void OFF() { stand(sOFF); } }; //---Компоновка----------------------------- Cl_TrafficLight Light(/*пин Красный*/2,/*пин Желтый*/3,/*пин Зеленый*/4); //---main----------------------------- void setup() { Light.init(); Light.ON(); } void loop() { mill = millis(); Light.run(); } /*Скетч использует 1382 байт (4%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 21 байт (1%) динамической памяти, оставляя 2027 байт для локальных переменных. Максимум: 2048 байт. */Нипонял, а где мигание зеленого за 3сек до переключения на желтый и где одновременное горение желтого и красного перед переключением на зеленый?
По коду,
voidstand(bytes)выполняет 5 действий (причем 2 из них совпадают) в зависимости от параметра, а два из этих действий обернуты в отдельный вызов в стр55-62. Это явно надумано. Делаем просто 4 функцииvoidstandOFF()voidstandRed()..... и массив указателей на них, заполненный по порядку их включения. И паузы тоже в массив. В результате стр.50-53 приятно ужимаются почти в одну и их кол-во перестает зависить от числа режимов. И тогда любые хотелки типа мигания зеленого легко добавляются причем почти без правки кода, только добавлением в массив указателей на функции и массив пауз. А совсем уж по уму держать один массив структур.Logik, здесь используется цифровой автомат. И решается через цифровой автомат. Если начать оптимизировать, то точно сведется к черному ящику и нефиг лезть туда, где и так все работает.
Logik, здесь используется цифровой автомат
таниужели! Ого как! )))) Может добавить знак "Осторожно, цифровой автомат!" ;)
Если начать оптимизировать, то точно сведется к черному ящику и нефиг лезть туда, где и так все работает.
Я и не предлагал Вам от цифрового автомата отказыватся. Эта штука годная. Но похоже Вам нравится одиночество в этой теме. Продолжайте.
/*TrafficLight светофор*/ unsigned long mill; // переменная под millis() typedef void (*pDo)() ;// тип -функция обработчик //---------------Cl_Led--------- //класс Cl_Led управление светодиодом enum {sLedOFF = 0, sLedON, sLedBlink}; class Cl_Led { byte pin;//нога светодиода bool led;// уровень на выводе светодиода uint32_t time;// полупериод мигания светодиода uint32_t past;// время последнего переключения byte state; void stand(byte s) { state = s; past = mill; switch (state) { case sLedOFF: digitalWrite(pin, led = HIGH); break; case sLedON: digitalWrite(pin, led = LOW); break; case sLedBlink: digitalWrite(pin, led = !led); break; } } public: // конструктор класса Cl_Led(int p): pin(p) {} // метод setup() void init() { pinMode(pin, OUTPUT); stand(sLedOFF); } void run() { if (state == sLedBlink && mill - past >= time)stand(sLedBlink); } // включить светодиод void ON() { stand(sLedON); } // выключить светодиод void OFF() { stand(sLedOFF); } // мигать светодиодом void blink(uint32_t t = 500) { time = t; stand(sLedBlink); } }; //-------------------------------- enum {sOFF = 0, sRed, sYellow1, sGreen, sYellow2, sFault}; class Cl_TrafficLight { protected: Cl_Led LedRed1, LedYellow1, LedGreen1, LedRed2, LedYellow2, LedGreen2; unsigned long past; byte state; void stand(byte s) { past = mill; state = s; switch (state) { case sOFF: LedRed1.OFF();/*выкл*/ LedYellow1.OFF(); LedGreen1.OFF(); LedRed2.OFF(); LedYellow2.OFF(); LedGreen2.OFF(); break; case sRed: /*крвсный*/ LedRed1.ON(); LedGreen2.ON(); LedYellow1.OFF(); LedYellow2.OFF(); break; case sYellow1: /*мигает желтый*/ LedRed1.OFF(); LedGreen2.OFF(); LedYellow1.blink(200); LedYellow2.blink(200); break; case sGreen: /*зеленый*/ LedGreen1.ON(); LedRed2.ON(); LedYellow1.OFF(); LedYellow2.OFF(); break; case sYellow2:/*мигает желтый*/ LedGreen1.OFF(); LedRed2.OFF(); LedYellow1.blink(200); LedYellow2.blink(200); break; case sFault:/*авария*/ LedRed1.OFF(); LedYellow1.ON(); LedGreen1.OFF(); LedRed2.OFF(); LedYellow2.ON(); LedGreen2.OFF(); break; } } public: /**/ Cl_TrafficLight(byte R1, byte Y1, byte G1, byte R2, byte Y2, byte G2) : LedRed1(R1), LedYellow1(Y1), LedGreen1(G1), LedRed2(R2), LedYellow2(Y2), LedGreen2(G2) {} /**/ void init() { LedRed1.init(); LedYellow1.init(); LedGreen1.init(); LedRed2.init(); LedYellow2.init(); LedGreen2.init(); OFF(); } /**/ void run() { LedRed1.run(); LedYellow1.run(); LedGreen1.run(); LedRed2.run(); LedYellow2.run(); LedGreen2.run(); if (state == sRed && mill - past >= 3000)stand(sYellow1); if (state == sYellow1 && mill - past >= 1000)stand(sGreen); if (state == sGreen && mill - past >= 3000)stand(sYellow2); if (state == sYellow2 && mill - past >= 1000)stand(sRed); } /*запустить*/ void start() { stand(sRed); } /*остановить*/ void stop() { stand(sFault); } /*выключить*/ void OFF() { stand(sOFF); } }; //------Cl_Btn---------------------- // класс кнопка class Cl_Btn { protected: const byte pin; pDo Do1, Do2; //обработчик 1 и 2 bool bounce = 0; bool btn = 1, oldBtn; unsigned long past; byte stand = 0; void tick() { if (stand == 0) { stand = 1; Do1(); } else { stand = 0; Do2(); } } public: /*конструктор*/ Cl_Btn(byte pin_, pDo D1, pDo D2) : pin(pin_), Do1(D1), Do2(D2) {} /*инициализация-вставить в setup()*/ void init() { pinMode(pin, INPUT_PULLUP); tick(); } /*работа-вставить в loop()*/ void run() { bool newBtn = digitalRead(pin); if (!bounce && newBtn != btn) { bounce = 1; past = mill; } if (bounce && mill - past >= 10) { bounce = 0 ; oldBtn = btn; btn = newBtn; if (!btn && oldBtn) tick(); } } }; //---Компоновка----------------------------- Cl_TrafficLight Light(/*пин Красный1*/3,/*пин Желтый1*/4,/*пин Зеленый1*/5,/*пин Красный2*/6,/*пин Желтый2*/7,/*пин Зеленый2*/8); void Do1Btn1() { Light.start(); } void Do2Btn1() { Light.stop(); } Cl_Btn Btn1(/*пин*/2,/*обработчик 1*/Do1Btn1,/*обработчик 2*/Do2Btn1); //---main----------------------------- void setup() { Light.init(); Btn1.init(); } void loop() { mill = millis(); Light.run(); Btn1.run(); } /*Скетч использует 2614 байт (8%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 97 байт (4%) динамической памяти, оставляя 1951 байт для локальных переменных. Максимум: 2048 байт. */Пух, ну вот КАК тебе удается нести херню, вроде бы, с виду правильными словами? Я вот когда несу, у меня слова неправильные, а у тебя дар. Я прям завидую.
))))
Это потому что у него нетрадиционное виденье поддерживается крепостью веры.
Зато когда вижу типа такого
LedRed1.run(); LedYellow1.run(); LedGreen1.run(); LedRed2.run(); LedYellow2.run(); LedGreen2.run(); if (state == sRed && mill - past >= 3000)stand(sYellow1); if (state == sYellow1 && mill - past >= 1000)stand(sGreen); if (state == sGreen && mill - past >= 3000)stand(sYellow2); if (state == sYellow2 && mill - past >= 1000)stand(sRed);понимаю что в китайском коде некоторые китайцам и фору дать могут.
https://vk.com/wall-51126445?q=Arduino
За тему большое спасибо!
Для новичков или подзабывших про программаж на С/С++ очень полезно.
Спасибо вам за тему! Очень полезная. Вы советовали книгу вначале темы. И там как мне показалось указано, что нельзя при создании класса присваивать значение переменным в этом классе. Строки 16 и 17. Однако ваш код работает. class Cl_Btn { 13 byte pin; // номер ноги на кнопке 14 void (* Do)();// указатель на обработчик 15 bool btn, btn_old; 16 bool bounce = 0; // антидребезговый флаг 17 uint32_t past = 0 ; 18 public: 19 // конструктор класса 20 Cl_Btn( byte _pin, void (* _Do)()): pin(_pin), Do(_Do) {} 21 // метод setup() 22 void setup() { 23 pinMode(pin, INPUT_PULLUP);// подключить кнопку 1 с подтяжкой 24 btn = digitalRead(pin); // прочитать реальное значение на выводе}; 25 } 26 // метод loop() 27 void loop() { 28 if (! bounce && btn != digitalRead(pin)) { // если прошел фронт изм на выводн 29 bounce = 1; // выставить флаг 30 past = millis(); // сделать временую засветку 31 } 32 else if ( bounce && millis() - past >= 5 ) { // если прошло антидребезговое время 33 bounce = 0; // то снять флаг 34 btn_old = btn ; 35 btn = digitalRead(pin) ; // прочитать реальное значение на выводе 36 if (btn_old && ! btn) Do(); 37 } 38 } 39 };freeman86, а вот здесь вылез факт о котором новички не догадываются. Они считают что Си/Си++ уже не развивается и не меняется. А последняя редакция Си произошла в 2017 году. А книга о Си написана еще до этих изменений.
https://www.youtube.com/watch?v=eSwrisPYrXE
нельзя при создании класса присваивать значение переменным в этом классе. Строки 16 и 17.
Без крайней нужды этого лучше не делать. А если делать, то точно знать что именно Вы делаете. Там очень много тонкостей, и очень многое может пойти не так. Инициализация в конструкторе - значительно проще и надёжнее.
Еще вопросы по дальнейшему коду, если не возражаете. Я все сам переписываю и загружаю в плату )
http://arduino.ru/forum/programmirovanie/klassy-arduino-po-qwone-dlya-ch...
вот тут по ссылке бит инверсии. Не понимаю, в чем преимущество такого варианты перед led = !led? И как понимать синтаксис led ^ inv, в таблице я оператор ^ не нашел, только ^=.
Шаблоны для тех кто не знал, а потом случилось несчастье забыл. Код отсюда #10
Класс
/**/ //------------------------------- class Cl_Stack { protected: byte *ptr; byte size; int top; public: Cl_Stack(int s = 10); ~Cl_Stack(); bool push(byte num); bool pop(byte & num); }; Cl_Stack::Cl_Stack(int s) { size = s > 0 ? s : 10; // инициализировать размер стека ptr = new byte[size]; // выделить память под стек top = -1; // значение -1 говорит о том, что стек пуст } Cl_Stack::~Cl_Stack() { delete [] ptr; } bool Cl_Stack::push(byte num) { if (top > size) return 0; top++; ptr[top] = num; return 1; } bool Cl_Stack::pop(byte & num) { if (top < 0) return 0; num = ptr[top]; top--; return 1; } //------------------------------- const byte len = 5; Cl_Stack Stack(len); byte num; //------------------------------- void setup() { Serial.begin(9600); for (int i = 0; i < len; i++) { Stack.push(i); } for (int i = 0; i < len; i++) { Stack.pop(num); Serial.print(" "); Serial.print(num); } Serial.println(); } void loop() { } /*Скетч использует 2392 байт (7%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 204 байт (9%) динамической памяти, оставляя 1844 байт для локальных переменных. Максимум: 2048 байт. */И через шаблон
/**/ //------------------------------- template <typename T> class Cl_Stack { protected: T *ptr; byte size; int top; public: Cl_Stack(int s = 10); ~Cl_Stack(); bool push(T num); bool pop(T & num); }; template <typename T> Cl_Stack<T>::Cl_Stack(int s) { size = s > 0 ? s : 10; // инициализировать размер стека ptr = new T[size]; // выделить память под стек top = -1; // значение -1 говорит о том, что стек пуст } template <typename T> Cl_Stack<T>::~Cl_Stack() { delete[] ptr; } template <typename T> bool Cl_Stack<T>::push(T num) { if (top > size) return 0; top++; ptr[top] = num; return 1; } template <typename T> bool Cl_Stack<T>::pop(T & num) { if (top < 0) return 0; num = ptr[top]; top--; return 1; } //------------------------------- const byte len = 5; Cl_Stack<byte> Stack(len); byte num; //------------------------------- void setup() { Serial.begin(9600); for (int i = 0; i < len; i++) { Stack.push(i); } for (int i = 0; i < len; i++) { Stack.pop(num); Serial.print(" "); Serial.print(num); } Serial.println(); } void loop() { } /*Скетч использует 2392 байт (7%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 204 байт (9%) динамической памяти, оставляя 1844 байт для локальных переменных. Максимум: 2048 байт. */А на мой вопрос по поводу бита инверсии и led ^ inv ответите? )
freeman86,Возьмем таблицу операторов в Си. https://msdn.microsoft.com/ru-ru/library/126fe14k.aspx ^ Побитовое исключающее ИЛИ led здесь bool- то есть два значения. Это по синтасису.
Теперь по программе. Есть реле (светодиоды и т д) . Некоторые срабатывают при HIGH, другие по LOW. Можно написать для них два класса. Но можно написать универсальный, где ввести в консруктор дополнитнльную переменную inv. Если inv - LOW , то это срабатывание при HIGH. И обратно. То есть использование оператора ^ упрощает и сокращает код. И в конце концов делает "универсальный класс".
Шаблоны для тех кто не знал, а потом случилось несчастье забыл. Код отсюда #10
И через шаблон
/**/ //------------------------------- template <typename T> class Cl_Stack { protected: T *ptr; byte size; int top; public: Cl_Stack(int s = 10); ~Cl_Stack(); bool push(T num); bool pop(T & num); }; template <typename T> Cl_Stack<T>::Cl_Stack(int s) { size = s > 0 ? s : 10; // инициализировать размер стека ptr = new T[size]; // выделить память под стек top = -1; // значение -1 говорит о том, что стек пуст } template <typename T> Cl_Stack<T>::~Cl_Stack() { delete[] ptr; } template <typename T> bool Cl_Stack<T>::push(T num) { if (top > size) return 0; top++; ptr[top] = num; return 1; } template <typename T> bool Cl_Stack<T>::pop(T & num) { if (top < 0) return 0; num = ptr[top]; top--; return 1; } //------------------------------- const byte len = 5; Cl_Stack<byte> Stack(len); byte num; //------------------------------- void setup() { Serial.begin(9600); for (int i = 0; i < len; i++) { Stack.push(i); } for (int i = 0; i < len; i++) { Stack.pop(num); Serial.print(" "); Serial.print(num); } Serial.println(); } void loop() { } /*Скетч использует 2392 байт (7%) памяти устройства. Всего доступно 30720 байт. Глобальные переменные используют 204 байт (9%) динамической памяти, оставляя 1844 байт для локальных переменных. Максимум: 2048 байт. */Квон, тебе не надоело с напыщенностью усталого ментора постить код с детскими ошибками?
Лови пример для твоего класса с шаблоном:
void setup() { Cl_Stack<long> Stack1(2); Serial.begin(57600); String pushRes = "PUSH RESULT: "; for (int i = 0; i < 3; i++) { const int val = i + 100; pushRes += "push("; pushRes += val; pushRes += ")-"; pushRes += Stack1.push(val) ? "succ" : "fail"; pushRes += "; "; } Serial.println(pushRes); } void loop() {} // // Результат // SH RESULT: push(100)-succ; push(101)-succ; push(102)-succ;А теперь объясни мне. Все пуши завершились успешно, так какая же зараза стырила первые две буквы выводной строки? Куда они делись?
И это кстати, не единственная ошибка в этом коротеньком куске говнокода. Вторая, правда, не детская, а скорее идеологическая. Показать?
для твоего класса с шаблоном:
А код без шаблонов что, лучше? Те же самые детские ошибки. Но ТС не очень адекватно реагирует на сообщения об ошибках, так что я уж давно помалкиваю.
Чёт квон не спешит ошибки править. Решил кинуть своих читателей, которые надеются найти у него решение своих проблем :(((
В большинстве случаев, это неважно, там разница маленькая, но методологически это неправильно.
а так сойдёт?
void loop() { if (uint32_t m = millis() - past > 100) { *_pnt = map(analogRead(_pin), 0, 1023, 0, 31000);// 31 Ампер past = m; //millis(); // Измеряем раз в 100 миллисекунд } }Смотря для какой цели. Попробуй после второй строки m попечатать и посмотри, устроит тебя или не очень :-)
Скажите пожалуйста, а как сделать так, чтоб этот код, описанный в посте #18, на выходе выдавал, скажем, 3 импульса по 2 секунды с интервалом между импульсами в 5 секунд?
Скажите пожалуйста, а как сделать так, чтоб этот код, описанный в посте #18, на выходе выдавал, скажем, 3 импульса по 2 секунды с интервалом между импульсами в 5 секунд?
Не нужно разбрасывать свой вопрос одновременно по нескольким темам.
Ответил в соседней.
Кроме того, похожий вопрос обвсуждался здесь: http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/imitatsiya-bortovykh-ognei-samoleta