Так оно очень редко будет сбиваться. Совсем редко. Чтобы оно сбилось нужно, чтобы прерывание по таймеру пришлось на момент, когда часть переменной timer0_millis уже считана, а остальное ещё нет. Но и этого мало. Надо ещё, чтобы при обработке прерывания произошёл перенос разряде из считанной части в несчитанную. Вот тогда прочитает криво.
Парень, ты не ерепенься, а просто прикинь. Вот, допустим, у тебя в скетче с пяток кнопок, пара датчиков, ну, там, скажем, с десяток объектов. Это ведь нормально? Десяток объектов на скетч, правда?
А теперь
qwone пишет:
Вопрос : Сколько раз вызывается функция millis() за проход loop().
Ответ: в лучшем случае 10 раз, а в худшем - 20 раз.
Вот скажи честно, НАФИГА? В каком месте у Мейера написано, что millis нужно десять-двадцать раз вызывать?
Если уж ты решил, что
qwone пишет:
я требую от классов:
1 - что бы в них обязательно были public методы setup() и loop()
2- что бы представители этих классов,что из одного класса,что из разных, могли взаимно не тормозить друг друга.
то, начни с того, что создай абстрактный класс ArduinoBase с двумя абстрактыми ( = 0) методами setup и loop, а все классы объектов наследуй от него. И это будет, кстати, гораздо более "по Мейеру"! А функции loop сделай константный параметр currentMillis. Тогда ты будешь один раз спрашивать millis в начале глобального loop и просто всем остальным loop'ам его передавать. Тогда millis будет спрашиваться один раз за проход loop, а не 10-20. А больше и не надо.
Нет криво может прочитать только timer0_millis потому что при вашем чтении может вклинится прерывание и испортить. Обвяжите запретом прерывания 9 и 10 строчку и всё будет нормально. Кстати, испортить может на 1001 раз.
А функции loop сделай константный параметр currentMillis. Тогда ты будешь один раз спрашивать millis в начале глобального loop и просто всем остальным loop'ам его передавать. Тогда millis будет спрашиваться один раз за проход loop, а не 10-20. А больше и не надо.
Вот только код будет выглядить так .
/*
*/
unsigned long mill;
//------------------------------------------------
class Cl_Led {
const byte _pin;
bool led;
unsigned long past = 0;
public:
Cl_Led(byte pin): _pin(pin) {}
void setup() {
pinMode(_pin, OUTPUT);
digitalWrite(_pin, led = 0);
}
void loop() {
if (mill - past >= 200) {
past = mill;
digitalWrite(_pin, led = !led);
}
}
};
//----------Компоновка--------------------------------------
Cl_Led Led(/*пин*/13);
//--------main()----------------------------------------
void setup() {
Led.setup();
}
void loop() {
mill = millis();
Led.loop();
}
/*Скетч использует 926 байт (2%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 19 байт (0%) динамической памяти, оставляя 2029 байт для локальных переменных. Максимум: 2048 байт.
*/
ПС: В Си сначало надо объявить, а потом использовать. Но никак наоборот.:(
Нет криво может прочитать только timer0_millis потому что при вашем чтении может вклинится прерывание и испортить. Обвяжите запретом прерывания 9 и 10 строчку и всё будет нормально. Кстати, испортить может на 1001 раз.
А если прерывание пройдет когда был запрет. Вот один тик и улетит.
Нет не улетит. Тики улетают если время обработки прерывани больше двойного времени тика. Флаг прерывания никуда не девается. После разрешения всё обработается.
Нет не улетит. Тики улетают если время обработки прерывани больше двойного времени тика. Флаг прерывания никуда не девается. После разрешения всё обработается.
Тогда код будет таким. Или есть лучше?
/*
*/
unsigned long mill;
extern unsigned long timer0_millis;
//------------------------------------------------
class Cl_Led {
const byte _pin;
bool led;
unsigned long past = 0;
public:
Cl_Led(byte pin): _pin(pin) {}
void setup() {
pinMode(_pin, OUTPUT);
digitalWrite(_pin, led = 0);
}
void loop() {
if (mill - past >= 1000) {
past = mill;
digitalWrite(_pin, led = !led);
}
}
};
//----------Компоновка--------------------------------------
Cl_Led Led(/*пин*/13);
//--------main()----------------------------------------
void setup() {
Led.setup();
}
void loop() {
uint8_t oldSREG = SREG;
cli();
mill = timer0_millis;
SREG = oldSREG;
Led.loop();
}
/*Скетч использует 944 байт (2%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 19 байт (0%) динамической памяти, оставляя 2029 байт для локальных переменных. Максимум: 2048 байт.
*/
Есть такое правило хорошего тона: "если не собираешься изменять переменную (а я как раз не собираюсь), скажи об этом компилятору". Часто это не влияет ни на что, но иногда облегчает ему работу по оптимизации. Поэтому привычка объявлять неизменяемые переменные константами хорошая. Хуже не будет, а лучше может быть.
Есть такое правило хорошего тона: "если не собираешься изменять переменную (а я как раз не собираюсь), скажи об этом компилятору". Часто это не влияет ни на что, но иногда облегчает ему работу по оптимизации. Поэтому привычка объявлять неизменяемые переменные константами хорошая. Хуже не будет, а лучше может быть.
Зачем вводить методы класса еще один параметр. Попробуйте написать скетч целиком, а не выкладывать кусочки-"объедки". По которым я как археолог должен догадываться как в древности жили люди.
Клапауций 112 Ну это очень просто. Скетчи приведеные здесь это просто переходный вариант к этому.#1173
// Скетч расчитан на кнопки с подтяжкой резисторов 10к на землю
class Cl_Sys;// предварительно объявить о создании класса Sys для послед подключения к нему
//----------------Cl_LED------------------------------------------------------------
class Cl_LED {
byte pin; // нога для подключения светодиода
bool inv; // 0 светодиод горит при 1/ 1 светодиод горит при 0
bool stat_ON = 0, led = 0;
uint32_t time = 500, past = 0;
public:
//указатель на следующий компонент
Cl_LED *pnt_LED;
//конструктор
Cl_LED(Cl_Sys *Sys, byte _pin, bool _inv);
// setup()
void setup() {
pinMode(pin, OUTPUT);// подключить светодиод
led = 0;
digitalWrite(pin, led ^ inv) ; // погасить светодиод
}
// loop()
void loop() {
if (stat_ON && millis() - past >= time)OFF();
}
// включить светодиод
void ON() {
stat_ON = 0;
led = 1;
digitalWrite(pin, led ^ inv) ; // зажечь светодиод
}
// включить светодиод на время
void ON( uint32_t _time) {
time = _time;
stat_ON = 1;
past = millis();
led = 1;
digitalWrite(pin, led ^ inv) ; // зажечь светодиод
}
// выключить светодиод
void OFF() {
stat_ON = 0;
led = 0;
digitalWrite(pin, led ^ inv) ; // погасить светодиод
}
};
//----------------Cl_Mech_BTN------------------------------------------------------------
// класс на механич кнопку подкл к кнопке Ардуины.
class Cl_Mech_BTN {
byte pin; // номер ноги на кнопке
void (* Do)();// указатель на обработчик
bool btn, btn_old;
bool bounce = 0; // антидребезговый флаг
uint32_t past = 0 ;
public:
//указатель на следующий компонент
Cl_Mech_BTN *pnt_Mech_BTN;
//конструктор
Cl_Mech_BTN(Cl_Sys *Sys, byte _pin, void (* _Do)());
void setup() {
pinMode(pin, INPUT);// подключить кнопку
btn = digitalRead(pin); // прочитать реальное значение на выводе};
}
void loop () {
if (! bounce && btn != digitalRead(pin)) { // если прошел фронт изм на выводн
bounce = 1; // выставить флаг
past = millis(); // сделать временую засветку
}
else if ( bounce && millis() - past >= 5 ) { // если прошло антидребезговое время
bounce = 0; // то снять флаг
btn_old = btn ;
btn = digitalRead(pin) ; // прочитать реальное значение на выводе
if (!btn_old && btn) Do();
}
}
};
//----------------Cl_Sys------------------------------------------------------------
class Cl_Sys {
public:
// указатели на блоки однотипных классов в системе
Cl_LED * Start_LED = NULL;
Cl_Mech_BTN * Start_Mech_BTN = NULL;
void setup() {
for (Cl_LED *i = Start_LED; i != NULL; i = i->pnt_LED) i->setup();
for (Cl_Mech_BTN *i = Start_Mech_BTN; i != NULL; i = i->pnt_Mech_BTN) i->setup();
}
void loop () {
for (Cl_LED *i = Start_LED; i != NULL; i = i->pnt_LED) i->loop ();
for (Cl_Mech_BTN *i = Start_Mech_BTN; i != NULL; i = i->pnt_Mech_BTN) i->loop ();
}
};
//-----------------конструкторы классов вход в систему-------------------------------
Cl_LED::Cl_LED(Cl_Sys *Sys, byte _pin, bool _inv): pin(_pin), inv(_inv) {
pnt_LED = Sys->Start_LED;
Sys->Start_LED = this;
}
Cl_Mech_BTN::Cl_Mech_BTN(Cl_Sys *Sys, byte _pin, void (* _Do)()): pin(_pin), Do(_Do) {
pnt_Mech_BTN = Sys->Start_Mech_BTN;
Sys->Start_Mech_BTN = this;
}
//------------------компоновка-------------------------------------------------------
Cl_Sys *Sys = new Cl_Sys();
Cl_LED *LED1 = new Cl_LED(Sys,/*пин*/A0,/*инверсия*/0);// создать светодиод LED1
Cl_LED *LED2 = new Cl_LED(Sys,/*пин*/A1,/*инверсия*/0);// создать светодиод LED2
Cl_LED *LED3 = new Cl_LED(Sys,/*пин*/A2,/*инверсия*/0);// создать светодиод LED3
Cl_LED *LED4 = new Cl_LED(Sys,/*пин*/A3,/*инверсия*/0);// создать светодиод LED4
Cl_LED *LED5 = new Cl_LED(Sys,/*пин*/A4,/*инверсия*/0);// создать светодиод LED5
Cl_LED *LED6 = new Cl_LED(Sys,/*пин*/A5,/*инверсия*/0);// создать светодиод LED6
Cl_LED *LED7 = new Cl_LED(Sys,/*пин*/11,/*инверсия*/0);// создать светодиод LED7
Cl_LED *LED8 = new Cl_LED(Sys,/*пин*/12,/*инверсия*/0);// создать светодиод LED8
void Do_BTN1() {
LED1->ON(2000);
}
void Do_BTN2() {
LED2->ON(2000);
}
void Do_BTN3() {
LED3->ON(2000);
}
void Do_BTN4() {
LED4->ON(2000);
}
void Do_BTN5() {
LED5->ON(2000);
}
void Do_BTN6() {
LED6->ON(2000);
}
void Do_BTN7() {
LED7->ON(2000);
}
void Do_BTN8() {
LED8->ON(2000);
}
Cl_Mech_BTN *BTN1 = new Cl_Mech_BTN(Sys,/*пин*/2,/*обработчик*/Do_BTN1);// создать кнопку BTN1
Cl_Mech_BTN *BTN2 = new Cl_Mech_BTN(Sys,/*пин*/3,/*обработчик*/Do_BTN2);// создать кнопку BTN2
Cl_Mech_BTN *BTN3 = new Cl_Mech_BTN(Sys,/*пин*/4,/*обработчик*/Do_BTN3);// создать кнопку BTN3
Cl_Mech_BTN *BTN4 = new Cl_Mech_BTN(Sys,/*пин*/5,/*обработчик*/Do_BTN4);// создать кнопку BTN4
Cl_Mech_BTN *BTN5 = new Cl_Mech_BTN(Sys,/*пин*/6,/*обработчик*/Do_BTN5);// создать кнопку BTN5
Cl_Mech_BTN *BTN6 = new Cl_Mech_BTN(Sys,/*пин*/7,/*обработчик*/Do_BTN6);// создать кнопку BTN6
Cl_Mech_BTN *BTN7 = new Cl_Mech_BTN(Sys,/*пин*/8,/*обработчик*/Do_BTN7);// создать кнопку BTN7
Cl_Mech_BTN *BTN8 = new Cl_Mech_BTN(Sys,/*пин*/9,/*обработчик*/Do_BTN8);// создать кнопку BTN8
//------------------ main()----------------------------------------------------------
void setup() {
Sys->setup();
}
void loop() {
Sys->loop();
}
То есть к пакетной обработке. Разумеется я не нашел пока лучше этой конструкции. Но я придерживаюсь правила , что методы в классе должны быть void setup(void) , void loop(void) , хотя и их можно перегружать, а вот установочные данные надо вводить конструктором И да, я не навязываю стандарты, просто я думаю, что так проще перейти к ООП.
Все та же проблема, различные ключевые моменты в программировании приводят некоторой несовместимости скетчей. Так для вас событие это ввзведеный бит, а у меня повод вызвать обработчик этого события. Или же запихнуть его в очередь. И тот же обработчик это void Do(void){/*код обработки*/}.
Все та же проблема, различные ключевые моменты в программировании приводят некоторой несовместимости скетчей.
это ты сейчас о каких несовместимостях скетчей?
если о велосипеде, то все версии велосипедов 100% совместимы с версиями скетчей, написанными для этих версий. :D
qwone пишет:
Так для вас событие это ввзведеный бит, а у меня повод вызвать обработчик этого события. Или же запихнуть его в очередь. И тот же обработчик это void Do(void){/*код обработки*/}.
тю. так вызови обработчик, когда бит равен 1 или пихай его куда тебе желается.
про очередь - непонятное и сколько тебе понадобится оперативки, что бы хранить очередь длинной полчаса?
Битва титанов......Титаны не засоряйте эфир.Создавайте свои темы и продвигайте там свои методы.Человеку не понимающему в программировании побарабану как это написано лиж-бы работало,а там можно уже головой поработать как и что где подкрутить.Лучшеб помогли каму нибуть.
Битва титанов......Титаны не засоряйте эфир.Создавайте свои темы и продвигайте там свои методы.Человеку не понимающему в программировании побарабану как это написано лиж-бы работало,а там можно уже головой поработать как и что где подкрутить.Лучшеб помогли каму нибуть.
блин. я так и думал - придёт какой-нибудь карлик и закроет тему.
qwone, закрывай контору - уходим прадавать каму нибуть буквари великага рускага языка.
Вот так же и вы обсуждаете между собой а новичку не понятно
Мля, люди открыли тему и обсуждают что-то между собой. Тут в их тему вваливается новичёк, которому что-то там не понятно и начинает учить людей о чём им можно говорить, а о чём нельзя в их собственных темах! Вы ... это ... вообще здоровы? Вас так по жизни часто нах посылают или не очень? :))))
Мля, люди открыли тему и обсуждают что-то между собой. Тут в их тему вваливается новичёк, которому что-то там не понятно и начинает учить людей о чём им можно говорить, а о чём нельзя в их собственных темах! Вы ... это ... вообще здоровы? Вас так по жизни часто нах посылают или не очень? :))))
Извиняюсь но тема называется.
Классы Ардуино по qwone для чайников.
И ни кого я не учил.Хотите обсуждайте свои три строчки.Только кому это интерестно.
А почему у Вас исполнители - всегда внешние функции (типа Do1_Btn) а не виртуальные методы?
Зачем мне виртуальные методы. Я пока наследование не сильно применяю.
По "моей терминологии", но я не навязываю ни кому, классы с внешними обработчиками void Do(void) это классы Do (классы Ду). Есть еще классы Is (классы Из) но я редко их применяю. Это класс потенциометр. Там указатель на внешнюю переменную.
Зачем мне виртуальные методы. Я пока наследование не сильно применяю.
Так вопрос-то был как раз "почему Вы выбрали такое решение"? Обычно (в том же MFC и ещё в миллионе библиотек классов) обработчики - это виртуальные методы: там, типа onClick, onButtonUp, onMouseOver и т.д. и т.п.
Вы жу почему-то применяете внешние функции. Из каких соображений?
Вы жу почему-то применяете внешние функции. Из каких соображений?
какие умею, такие и применяю. Если научите другие, и они окажутся лучше поменяю.
ЕвгенийП пишет:
Обычно (в том же MFC и ещё в миллионе библиотек классов) обработчики - это виртуальные методы: там, типа onClick, onButtonUp, onMouseOver и т.д. и т.п.
А вот то что вы перечислили это отдельный класс обработчиков и то под GUI. А у меня нет GUI, вот и с этими обработчиками не задалось.
ну, так впиши в тело класса свои функции и вызывай их в контексте экземпляра класса
Вот здесь все не очень. Вот класс для меня это как "черный ящик", а точнее "серый ящик". В черный ящик лезть не надо. А вот в серый можно, но когда очень хочется . Для отладки программы лучше менять в разделе Компановка и main . А другие разделы это как подключаемые файлы. Но на форум лучше выкладывать одним файлом. Вот и внешний обработчик он создается в разделе Компоновка. Хотя если буду собирать большой класс из мелких улетит на верх.
Вот здесь все не очень. Вот класс для меня это как "черный ящик", а точнее "серый ящик". В черный ящик лезть не надо.
никто не предлагает тебе лезть в готовый чёрный ящик, но странно выглядит чёрный ящик с кишками, валяющимися вне его - прячь всё внутрь и юзай ящик, бросая в него извне информацию и/или нажимая на нужные рычаги и кнопки управления, находящиеся на поверхности ящика.
Так вопрос-то был как раз "почему Вы выбрали такое решение"? Обычно (в том же MFC и ещё в миллионе библиотек классов) обработчики - это виртуальные методы: там, типа onClick, onButtonUp, onMouseOver и т.д. и т.п.
Вы имели ввиду это?
/**/
//-------Cl_Btn----------------------
// класс кнопка
class Cl_Btn {
byte pin; // номер ноги на кнопке
bool btn, btn_old;
bool bounce = 0; // антидребезговый флаг
uint32_t past = 0 ;
public:
void (*onClick)(); // указатель на обработчик
Cl_Btn( byte _pin, void (* _onClick)() = NULL): pin(_pin), onClick(_onClick) {}
void setup() {
pinMode(pin, INPUT_PULLUP);// подключить кнопку 1 с подтяжкой
btn = digitalRead(pin); // прочитать реальное значение на выводе};
}
void loop() {
if (! bounce && btn != digitalRead(pin)) { // если прошел фронт изм на выводн
bounce = 1; // выставить флаг
past = millis(); // сделать временую засветку
}
else if ( bounce && millis() - past >= 5 ) { // если прошло антидребезговое время
bounce = 0; // то снять флаг
btn_old = btn ;
btn = digitalRead(pin) ; // прочитать реальное значение на выводе
if (btn_old && ! btn) (*onClick)();
}
}
};
//---------компоновка--------------------
Cl_Btn Btn(/*пин*/2);
void func() {
Serial.println("func()");
}
//-----------main()------------------
void setup() {
Serial.begin(9600);
Btn.setup();
Btn.onClick = &func;
}
void loop() {
Btn.loop();
}
/*Скетч использует 1986 байт (6%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 202 байт (9%) динамической памяти, оставляя 1846 байт для локальных переменных. Максимум: 2048 байт.
*/
ПС: это мне непривычно. Проще воткнуть один раз в конструктор и забыть. Хотя если там меню или перепрограммируемые кнопки ,то можно.
Ну, если это для чайников, поставили бы проверку выделения памяти, а то они бедные, даже не знают, что это в принципе можно делать. И Вы их заодно учите небрежно работать с памятью.
АААА! Началось! New показался!!!! Память у МК маленькая. Кто контролировать расход будет?
new-фобия напоминает мне типичную жертву американской рекламы, которую можно видеть в любом фастфуде в Америке - человек берёт диетическую колу (чтобы не полнеть) и к ней здоровенный бургер. А чо, про колу в рекламе говорят, а про бургеры - нет.
Так и здесь. Народ предаёт страшной анафеме new, но при этом спокойно пользуется классом String :)))))
200 кнопок для контроллера? Больше шести не разу не пришлось окучивать. А писать блиньк через классы - только для тренировки навыка. В реальном проекте как то всё пишется прямо.
Я не против NEW. Я против классов в микроконтроллере. Для стабильной работы вся память должна быть распределена до рантайма.
Как там : " И маленькую собачонку. Однако За время пути. Собака Могла подрасти!" . Так что микроконтроллеры уже немного подрасли. А вот программисты на микроконтроллерах этого не заметили. Да что говорить , они даже провтыкали как Си перерос в С++ , да С++ не стоит на месте . Сейчас С++11 и дальше развивается. Опять же практически все библиотеки пишутся с помощью классов. Но при вроде распростаненности классов, народ не умеет писать программы при помощи классов.
ПС: Для стабильной работы надо уметь писать программы. Так что эта тема скорее всего для меня, ну и тем кому интересно это направление.
Так оно очень редко будет сбиваться. Совсем редко. Чтобы оно сбилось нужно, чтобы прерывание по таймеру пришлось на момент, когда часть переменной timer0_millis уже считана, а остальное ещё нет. Но и этого мало. Надо ещё, чтобы при обработке прерывания произошёл перенос разряде из считанной части в несчитанную. Вот тогда прочитает криво.
Парень, ты не ерепенься, а просто прикинь. Вот, допустим, у тебя в скетче с пяток кнопок, пара датчиков, ну, там, скажем, с десяток объектов. Это ведь нормально? Десяток объектов на скетч, правда?
А теперь
Вопрос : Сколько раз вызывается функция millis() за проход loop().
Ответ: в лучшем случае 10 раз, а в худшем - 20 раз.
Вот скажи честно, НАФИГА? В каком месте у Мейера написано, что millis нужно десять-двадцать раз вызывать?
Если уж ты решил, что
то, начни с того, что создай абстрактный класс ArduinoBase с двумя абстрактыми ( = 0) методами setup и loop, а все классы объектов наследуй от него. И это будет, кстати, гораздо более "по Мейеру"! А функции loop сделай константный параметр currentMillis. Тогда ты будешь один раз спрашивать millis в начале глобального loop и просто всем остальным loop'ам его передавать. Тогда millis будет спрашиваться один раз за проход loop, а не 10-20. А больше и не надо.
Нет криво может прочитать только timer0_millis потому что при вашем чтении может вклинится прерывание и испортить. Обвяжите запретом прерывания 9 и 10 строчку и всё будет нормально. Кстати, испортить может на 1001 раз.
Вот только код будет выглядить так .
ПС: В Си сначало надо объявить, а потом использовать. Но никак наоборот.:(
Нет криво может прочитать только timer0_millis потому что при вашем чтении может вклинится прерывание и испортить. Обвяжите запретом прерывания 9 и 10 строчку и всё будет нормально. Кстати, испортить может на 1001 раз.
А если прерывание пройдет когда был запрет. Вот один тик и улетит.
Нет не улетит. Тики улетают если время обработки прерывани больше двойного времени тика. Флаг прерывания никуда не девается. После разрешения всё обработается.
Нет не улетит. Тики улетают если время обработки прерывани больше двойного времени тика. Флаг прерывания никуда не девается. После разрешения всё обработается.
Тогда код будет таким. Или есть лучше?
Есть. Сохранять регистр нужно в прерываниях. А так быстрее
Я бы не стал делать currentMillis static - зачем? По мне, вот так лучше:
а, const зачем?
а, const зачем?
Есть такое правило хорошего тона: "если не собираешься изменять переменную (а я как раз не собираюсь), скажи об этом компилятору". Часто это не влияет ни на что, но иногда облегчает ему работу по оптимизации. Поэтому привычка объявлять неизменяемые переменные константами хорошая. Хуже не будет, а лучше может быть.
а, const зачем?
Есть такое правило хорошего тона: "если не собираешься изменять переменную (а я как раз не собираюсь), скажи об этом компилятору". Часто это не влияет ни на что, но иногда облегчает ему работу по оптимизации. Поэтому привычка объявлять неизменяемые переменные константами хорошая. Хуже не будет, а лучше может быть.
ок.
Вот только код будет выглядить так .
ПС: В Си сначало надо объявить, а потом использовать. Но никак наоборот.:(
Не будет. Я же написал "параметр" и даже выделил жирным. А ты зачем-то глобальную переменную завёл.
Объявлени loop будет выглядеть примерно так:
void loop(const uint32_t currentMillis) { ... }
ну, не знаю - как-то дико и бессмысленно это смотрится в классе.
10
public
:
12
void
setup
() {
16
void
loop
() {
а, если что-то третье нужно сделать, кроме сетап и луп, то что? - вся концепция теряется, возвращаемся к классическому именованию подпрограмм?
Объявлени loop будет выглядеть примерно так:
void loop(const uint32_t currentMillis) { ... }
Зачем вводить методы класса еще один параметр. Попробуйте написать скетч целиком, а не выкладывать кусочки-"объедки". По которым я как археолог должен догадываться как в древности жили люди.
ну, не знаю - как-то дико и бессмысленно это смотрится в классе
а, если что-то третье нужно сделать, кроме сетап и луп, то что? - вся концепция теряется, возвращаемся к классическому именованию подпрограмм?
Расматривайте что это независимые программы. Вас же не раздражает, что каждый новый скетч это снова и снова setup() loop()
ок. а, как у тебя будет именоваться третья и более "независимая" программа в классе?
*с двумя понятно - настройки и регулярное исполнение, а внезапно - третья?
ну, и далее - если у тебя есть метод сетап в классе, то почему ты не делаешь так?
12
void
setup
(
byte
pin
) {13
pinMode(pin, OUTPUT);
14
digitalWrite(pin, led = 0);
15
}
ведь сетап именно для этого предназначен, а не только для того, что бы что-то запустить один раз.
Клапауций 112 Ну это очень просто. Скетчи приведеные здесь это просто переходный вариант к этому.#1173
То есть к пакетной обработке. Разумеется я не нашел пока лучше этой конструкции. Но я придерживаюсь правила , что методы в классе должны быть void setup(void) , void loop(void) , хотя и их можно перегружать, а вот установочные данные надо вводить конструктором И да, я не навязываю стандарты, просто я думаю, что так проще перейти к ООП.
Клапауций 112 Ну это очень просто. Скетчи приведеные здесь это просто переходный вариант к этому.#1173
а, зачем? - я же уже написал велосипед для кнопок.
забиваешь номера пинов, указываешь тип подтяжки, тип подключения - обычное или матрица... и всё.
Все та же проблема, различные ключевые моменты в программировании приводят некоторой несовместимости скетчей. Так для вас событие это ввзведеный бит, а у меня повод вызвать обработчик этого события. Или же запихнуть его в очередь. И тот же обработчик это void Do(void){/*код обработки*/}.
Все та же проблема, различные ключевые моменты в программировании приводят некоторой несовместимости скетчей.
это ты сейчас о каких несовместимостях скетчей?
если о велосипеде, то все версии велосипедов 100% совместимы с версиями скетчей, написанными для этих версий. :D
Так для вас событие это ввзведеный бит, а у меня повод вызвать обработчик этого события. Или же запихнуть его в очередь. И тот же обработчик это void Do(void){/*код обработки*/}.
тю. так вызови обработчик, когда бит равен 1 или пихай его куда тебе желается.
про очередь - непонятное и сколько тебе понадобится оперативки, что бы хранить очередь длинной полчаса?
Внешняя аналаговая клавиатура из 5 кнопок.
Битва титанов......Титаны не засоряйте эфир.Создавайте свои темы и продвигайте там свои методы.Человеку не понимающему в программировании побарабану как это написано лиж-бы работало,а там можно уже головой поработать как и что где подкрутить.Лучшеб помогли каму нибуть.
Битва титанов......Титаны не засоряйте эфир.Создавайте свои темы и продвигайте там свои методы.
А это и есть тема одного из них. Так что они создали и продвигают, в точном соответствии с Вашими ценными указаниями.
А что нужно
Человеку не понимающему в программировании
в этой теме всем
побарабану
Битва титанов......Титаны не засоряйте эфир.Создавайте свои темы и продвигайте там свои методы.Человеку не понимающему в программировании побарабану как это написано лиж-бы работало,а там можно уже головой поработать как и что где подкрутить.Лучшеб помогли каму нибуть.
Вот так же и вы обсуждаете между собой а новичку не понятно
Мля, люди открыли тему и обсуждают что-то между собой. Тут в их тему вваливается новичёк, которому что-то там не понятно и начинает учить людей о чём им можно говорить, а о чём нельзя в их собственных темах! Вы ... это ... вообще здоровы? Вас так по жизни часто нах посылают или не очень? :))))
Мля, люди открыли тему и обсуждают что-то между собой. Тут в их тему вваливается новичёк, которому что-то там не понятно и начинает учить людей о чём им можно говорить, а о чём нельзя в их собственных темах! Вы ... это ... вообще здоровы? Вас так по жизни часто нах посылают или не очень? :))))
Извиняюсь но тема называется.
Классы Ардуино по qwone для чайников.
И ни кого я не учил.Хотите обсуждайте свои три строчки.Только кому это интерестно.
Только кому это интерестно.
мне.
Только кому это интерестно.
Всем, кроме Вас.
Вот есть программа.Обычная программа светодиод с кнопкой.
А теперь надо написать класс светодиод+кнопка, который объединит класс светодиод и класс кнопку
Диковатая конструкция, хотя и работает. Я пытался объединить их внутри, но пока ничего не выходит. Разберусь выложу.
Теперь подошло время указателей на методы класса. Возьмем простой скетч светодиод с кнопкой.
И вот оно то самое "счастье"
ПС: И осталось ответить на "извечный еврейский вопрос": И оно нам надо?.
А почему у Вас исполнители - всегда внешние функции (типа Do1_Btn) а не виртуальные методы?
А почему у Вас исполнители - всегда внешние функции (типа Do1_Btn) а не виртуальные методы?
Зачем мне виртуальные методы. Я пока наследование не сильно применяю.
По "моей терминологии", но я не навязываю ни кому, классы с внешними обработчиками void Do(void) это классы Do (классы Ду). Есть еще классы Is (классы Из) но я редко их применяю. Это класс потенциометр. Там указатель на внешнюю переменную.
ПС: Да если кому-то хочется почитать про указатели вот хорошая статья.http://rsdn.org/article/cpp/fastdelegate.xml
Зачем мне виртуальные методы. Я пока наследование не сильно применяю.
Так вопрос-то был как раз "почему Вы выбрали такое решение"? Обычно (в том же MFC и ещё в миллионе библиотек классов) обработчики - это виртуальные методы: там, типа onClick, onButtonUp, onMouseOver и т.д. и т.п.
Вы жу почему-то применяете внешние функции. Из каких соображений?
ну, так впиши в тело класса свои функции и вызывай их в контексте экземпляра класса.
Вот здесь все не очень. Вот класс для меня это как "черный ящик", а точнее "серый ящик". В черный ящик лезть не надо.
никто не предлагает тебе лезть в готовый чёрный ящик, но странно выглядит чёрный ящик с кишками, валяющимися вне его - прячь всё внутрь и юзай ящик, бросая в него извне информацию и/или нажимая на нужные рычаги и кнопки управления, находящиеся на поверхности ящика.
ПС: это мне непривычно. Проще воткнуть один раз в конструктор и забыть. Хотя если там меню или перепрограммируемые кнопки ,то можно.
Скетч с использованием шаблонов на классы и структуры.
Ну, если это для чайников, поставили бы проверку выделения памяти, а то они бедные, даже не знают, что это в принципе можно делать. И Вы их заодно учите небрежно работать с памятью.
АААА! Началось! New показался!!!! Память у МК маленькая. Кто контролировать расход будет?
АААА! Началось! New показался!!!! Память у МК маленькая. Кто контролировать расход будет?
new-фобия напоминает мне типичную жертву американской рекламы, которую можно видеть в любом фастфуде в Америке - человек берёт диетическую колу (чтобы не полнеть) и к ней здоровенный бургер. А чо, про колу в рекламе говорят, а про бургеры - нет.
Так и здесь. Народ предаёт страшной анафеме new, но при этом спокойно пользуется классом String :)))))
.......
Так и здесь. Народ предаёт страшной анафеме new, но при этом спокойно пользуется классом String :)))))
До первого глюка с переполнением памяти.
Я не против NEW. Я против классов в микроконтроллере. Для стабильной работы вся память должна быть распределена до рантайма.
до рантайма.
это как?
Я против классов в микроконтроллере.
код для 200 кнопок будешь копипастом писать?
200 кнопок для контроллера? Больше шести не разу не пришлось окучивать. А писать блиньк через классы - только для тренировки навыка. В реальном проекте как то всё пишется прямо.
ПС: Для стабильной работы надо уметь писать программы. Так что эта тема скорее всего для меня, ну и тем кому интересно это направление.
Сейчас С++11 и дальше развивается.
Вы хотели сказать "14"? А то уж скоро стандарт 17 выйдет.
200 кнопок для контроллера?
нет - для суперкомпьютера