Вы хотели сказать "14"? А то уж скоро стандарт 17 выйдет.
Да и это тоже. Вот только туговато у меня получается с теорией как писать программы на Си++, с применением ООП ,Абстрактного класса и Абстракного типа данных. Это как электрический ток . Вроде все ясно, но в все равно окончательного ответа не получается.
Приветствую,можно ли привести пример простенькой программки для nano ,чтобы светодиод моргал сначала 1 раз,потом 2,3 и так далее до бесконечности.Заранее -Спасибо.
решение через delay
/**/
//-------компоновка----------------------------
const byte pin =/*пин*/13;
//-------main()----------------------------
void setup() {
pinMode(pin, OUTPUT);
for (int n = 1;; ++n) {
for (int i = 0; i < n; ++i) {
digitalWrite(pin, HIGH);
delay(/*время вкл*/200);
digitalWrite(pin, LOW);
delay(/*время выкл*/200);
}
delay(/*пауза между сериями*/500);
}
}
void loop() {
}
/*Скетч использует 968 байт (3%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт.
*/
Промежуточная разметка
/**/
//-------компоновка----------------------------
const byte pin =/*пин*/13;
//-------main()----------------------------
void setup() {
pinMode(pin, OUTPUT);
for (int n = 1;; ++n) {
for (int i = 0; i < n; ++i) { // stat =0
digitalWrite(pin, HIGH); // stat =1
delay(/*время вкл*/200); // stat =2
digitalWrite(pin, LOW);
delay(/*время выкл*/200); // stat =3
} // stat =4
delay(/*пауза между сериями*/500); // stat =5
}
}
void loop() {
}
/*Скетч использует 968 байт (3%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт.
*/
Ну и перевод в millis()
/**/
//-------компоновка----------------------------
const byte pin =/*пин*/13;
int stat = 0, n = 1, i;
uint32_t mill, past;
//-------main()----------------------------
void setup() {
pinMode(pin, OUTPUT);
}
void loop() {
mill = millis();
if (stat == 0) { // 0
stat = 1;
i = 1;
}
if (stat == 1) { // 1
stat = 2;
digitalWrite(pin, HIGH);
past = mill;
}
if (stat == 2 && mill - past >=/*время вкл*/200) { // 2
stat = 3;
digitalWrite(pin, LOW);
past = mill;
}
if (stat == 3 && mill - past >=/*время выкл*/200) { // 3
stat = 4;
digitalWrite(pin, LOW);
past = mill;
}
if (stat == 4) { // 4
if (i < n) {
stat = 1;
++i;
}
else stat = 5;
}
if (stat == 5 && mill - past >=/*пауза между сериями*/500) { // 5
stat = 0;
past = mill;
++n;
}
}
/*Скетч использует 1268 байт (3%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 23 байт (1%) динамической памяти, оставляя 2025 байт для локальных переменных. Максимум: 2048 байт.
*/
А теперь упакован код в класс
/**/
uint32_t mill;//millis()
//-----------------------------------------------------
class Cl_Led {
const byte pin ;
int stat = 0, n = 1, i;
uint32_t past;
public:
Cl_Led(byte _pin): pin(_pin) {}
void setup() {
pinMode(pin, OUTPUT);
stat = 0;
}
void loop() {
if (stat == 0) { // 0
stat = 1;
i = 1;
}
if (stat == 1) { // 1
stat = 2;
digitalWrite(pin, HIGH);
past = mill;
}
if (stat == 2 && mill - past >=/*время вкл*/200) { // 2
stat = 3;
digitalWrite(pin, LOW);
past = mill;
}
if (stat == 3 && mill - past >=/*время выкл*/200) { // 3
stat = 4;
digitalWrite(pin, LOW);
past = mill;
}
if (stat == 4) { // 4
if (i < n) {
stat = 1;
++i;
}
else stat = 5;
}
if (stat == 5 && mill - past >=/*пауза между сериями*/500) { // 5
stat = 0;
past = mill;
++n;
}
}
};
//-------компоновка----------------------------
Cl_Led Led(/*пин*/13);
//-------main()----------------------------
void setup() {
Led.setup();
}
void loop() {
mill = millis();
Led.loop();
}
/*Скетч использует 1340 байт (4%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 24 байт (1%) динамической памяти, оставляя 2024 байт для локальных переменных. Максимум: 2048 байт.
*/
ПС: Тут скорее появился вопрос: Зачем? delay компактнее. Ответ. delay просто съедает ресурсы производительности процессора. А без этих ресурсов сэкономленая флеш и Озу память бесполезна для будущей модернизации программы.
// а вы уверены что так?
PIND |= (1 << 3);
// а может так
*out ^=bit&inv;
// а то у Метров такие мелочи не волнуют
Вопрос не понятен. Я написал "Например для третьего пина". Так вот, для тертьего пина - это действительно так, я уверен (и даташит тоже). А как Вам это перевести в Ваш класс и сделать универсально для любого пина - это Ваша забота.
Только не забывайте. так как я написал - это ОДНА машинная команда и НОЛЬ байтов дополнительной памяти данных. Вы же зачем-то пытаетесь помнить какую-то переменную и выполнять логику с нею. Зачем? Для инвертирования пина, как я Вам писал, достаточно записать 1 в нужный бит PINx (и неважно. что там было раньше - запишете единицу ещё раз - инвертируется ещё раз). Попробуйте.
/**/
uint32_t mill;// переменная под millis()
//---------Cl_Led----------------------------------
//класс светодиод
class Cl_Led {
uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход
volatile uint8_t *reg; // указатель на регистр настройки порта
volatile uint8_t *out; // указатель на регистр входа порта
bool inv;// состояние бита инверсии выхода
bool stat;// 1 мигать / 0 нет
unsigned long past, time;
public:
/*
конструктор Cl_Led
Описание создает класс
Ввод pin: подключение к ноге
inv: бит инвертирования 0 нет / 1 инверсия
Вывод нет
*/
Cl_Led (uint8_t pin, uint8_t _inv = 0): inv(_inv) {
bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin); // получить номер порта
reg = portModeRegister(port);
out = portOutputRegister(port);
}
/*
Функция setup
Описание иницирование класса
Ввод нет
Вывод нет
*/
void setup() {
uint8_t oldSREG = SREG;
cli();
*reg |= bit;
if (inv) *out &= ~bit;
else *out |= bit;
SREG = oldSREG;
stat = 0;
}
/*
Функция OFF
Описание выключить светодиод
Ввод нет
Вывод нет
*/
void OFF() {
uint8_t oldSREG = SREG;
cli();
if (inv) *out &= ~bit;
else *out |= bit;
SREG = oldSREG;
stat = 0;
}
/*
Функция ON
Описание включить светодиод
Ввод нет
Вывод нет
*/
void ON() {
uint8_t oldSREG = SREG;
cli();
if (inv) *out |= bit;
else *out &= ~bit;
SREG = oldSREG;
stat = 0;
}
/*
Функция blink
Описание мигать светодиодои
Ввод _time - полупериод мигания
Вывод нет
*/
void blink(unsigned long _time = 500) {
time = _time;
stat = 1;
past = mill;
uint8_t oldSREG = SREG;
cli();
*out ^= bit;
SREG = oldSREG;
}
/*
Функция loop
Описание для нормальной работе разместить в loop программы
Ввод нет
Вывод нет
*/
void loop() {
if (!stat) return;
if (mill - past >= time) {
past = mill;
uint8_t oldSREG = SREG;
cli();
*out ^= bit;
SREG = oldSREG;
}
}
};
//------Cl_Btn------------------------------------------
// класс кнопка c програмной подтяжкой
class Cl_Btn {
uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход
volatile uint8_t *reg; // указатель на регистр настройки порта
volatile uint8_t *out; // указатель на регистр выхода порта
uint8_t port; // номер порта на выводе
const byte pin;
void (*Do1)(), (*Do2)();
bool btn, btn_old, btn_new;
bool bounce = 0; // антидребезговый флаг
uint32_t past = 0 ;
public:
/*
конструктор Cl_Btn
Описание создает класс
Ввод pin: подключение к ноге
_Do1: фунция обработчик нажатия кнопки
_Do2: фунция обработчик отжатия кнопки
Вывод нет
*/
Cl_Btn(byte pin, void (*_Do1)(), void (*_Do2)()): Do1(_Do1), Do2(_Do2) {
bit = digitalPinToBitMask(pin);
port = digitalPinToPort(pin); // получить номер порта
reg = portModeRegister(port);
out = portOutputRegister(port);
}
/*
Функция setup
Описание иницирование класса
Ввод нет
Вывод нет
*/
void setup() {
uint8_t oldSREG = SREG;
cli();
*reg &= ~bit; //INPUT
*out |= bit; //PULLUP
SREG = oldSREG;
btn_old = (*portInputRegister(port) & bit) == 0;
}
/*
Функция loop
Описание для нормальной работе разместить в loop программы
Ввод нет
Вывод нет
*/
void loop() {
btn_new = (*portInputRegister(port) & bit) == 0;
if (! bounce && btn != btn_new) { // если прошел фронт изм на выводн
bounce = 1; // выставить флаг
past = mill; // сделать временую засветку
}
else if ( bounce && mill - past >= 5 ) { // если прошло антидребезговое время
bounce = 0; // то снять флаг
btn_old = btn ;
btn = btn_new ; // прочитать реальное значение на выводе
if (btn_old && ! btn)(*Do1)();
if (!btn_old && btn)(*Do2)();
}
}
};
//-------------компоновка-----------------------------------
Cl_Led Led1(/*пин*/13,/*инв*/1);
void Do1_Btn1() {
Led1.ON();
}
void Do2_Btn1() {
Led1.OFF();
}
Cl_Btn Btn1(/*пин*/2,/*обраб наж*/Do1_Btn1,/*обраб отж*/Do2_Btn1);
//-------------main()-----------------------------------
void setup() {
Led1.setup();
Btn1.setup();
}
void loop() {
mill = millis();
Led1.loop();
Btn1.loop();
}
/*Скетч использует 1308 байт (4%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 47 байт (2%) динамической памяти, оставляя 2001 байт для локальных переменных. Максимум: 2048 байт.
*/
Вы хотя бы компилировать свои опусы пробуете (я уж не говорю запускать)? Или вот как в голову пришло, так публикуете?
Ваш код элементарно не компилируется потому, что Вы в 108 строку засунули константый член класса, которым нигде и никогда не пользуетесь (главное - не инициализируете)!
Вы хотя бы компилировать свои опусы пробуете (я уж не говорю запускать)? Или вот как в голову пришло, так публикуете?
Ваш код элементарно не компилируется потому, что Вы в 108 строку засунули константый член класса, которым нигде и никогда не пользуетесь (главное - не инициализируете)!
Ну компилируется вы же видели это /* */ И работает. Ну да остались рудименты. Так компилятор это и опускает. Умный блин однако, это я про компилятор. const byte pin все же загружаемая переменная, но только с конструктора.
ПС: хотя да без нее на один байт в программе меньше.
/**/
uint32_t mill;// переменная под millis()
//---------Cl_Led----------------------------------
//класс светодиод
class Cl_Led {
uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход
volatile uint8_t *reg; // указатель на регистр настройки порта
volatile uint8_t *out; // указатель на регистр входа порта
bool inv;// состояние бита инверсии выхода
bool stat;// 1 мигать / 0 нет
unsigned long past, time;
public:
/*
конструктор Cl_Led
Описание создает класс
Ввод pin: подключение к ноге
inv: бит инвертирования 0 нет / 1 инверсия
Вывод нет
*/
Cl_Led (uint8_t pin, uint8_t _inv = 0): inv(_inv) {
bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin); // получить номер порта
reg = portModeRegister(port);
out = portOutputRegister(port);
}
/*
Функция setup
Описание иницирование класса
Ввод нет
Вывод нет
*/
void setup() {
uint8_t oldSREG = SREG;
cli();
*reg |= bit;
if (inv) *out &= ~bit;
else *out |= bit;
SREG = oldSREG;
stat = 0;
}
/*
Функция OFF
Описание выключить светодиод
Ввод нет
Вывод нет
*/
void OFF() {
uint8_t oldSREG = SREG;
cli();
if (inv) *out &= ~bit;
else *out |= bit;
SREG = oldSREG;
stat = 0;
}
/*
Функция ON
Описание включить светодиод
Ввод нет
Вывод нет
*/
void ON() {
uint8_t oldSREG = SREG;
cli();
if (inv) *out |= bit;
else *out &= ~bit;
SREG = oldSREG;
stat = 0;
}
/*
Функция blink
Описание мигать светодиодои
Ввод _time - полупериод мигания
Вывод нет
*/
void blink(unsigned long _time = 500) {
time = _time;
stat = 1;
past = mill;
uint8_t oldSREG = SREG;
cli();
*out ^= bit;
SREG = oldSREG;
}
/*
Функция loop
Описание для нормальной работе разместить в loop программы
Ввод нет
Вывод нет
*/
void loop() {
if (!stat) return;
if (mill - past >= time) {
past = mill;
uint8_t oldSREG = SREG;
cli();
*out ^= bit;
SREG = oldSREG;
}
}
};
//------Cl_Btn------------------------------------------
// класс кнопка c програмной подтяжкой
class Cl_Btn {
uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход
volatile uint8_t *reg; // указатель на регистр настройки порта
volatile uint8_t *out; // указатель на регистр выхода порта
uint8_t port; // номер порта на выводе
void (*Do1)(), (*Do2)();
bool btn, btn_old, btn_new;
bool bounce = 0; // антидребезговый флаг
uint32_t past = 0 ;
public:
/*
конструктор Cl_Btn
Описание создает класс
Ввод pin: подключение к ноге
_Do1: фунция обработчик нажатия кнопки
_Do2: фунция обработчик отжатия кнопки
Вывод нет
*/
Cl_Btn(byte pin, void (*_Do1)(), void (*_Do2)()): Do1(_Do1), Do2(_Do2) {
bit = digitalPinToBitMask(pin);
port = digitalPinToPort(pin); // получить номер порта
reg = portModeRegister(port);
out = portOutputRegister(port);
}
/*
Функция setup
Описание иницирование класса
Ввод нет
Вывод нет
*/
void setup() {
uint8_t oldSREG = SREG;
cli();
*reg &= ~bit; //INPUT
*out |= bit; //PULLUP
SREG = oldSREG;
btn_old = (*portInputRegister(port) & bit) == 0;
}
/*
Функция loop
Описание для нормальной работе разместить в loop программы
Ввод нет
Вывод нет
*/
void loop() {
btn_new = (*portInputRegister(port) & bit) == 0;
if (! bounce && btn != btn_new) { // если прошел фронт изм на выводн
bounce = 1; // выставить флаг
past = mill; // сделать временую засветку
}
else if ( bounce && mill - past >= 5 ) { // если прошло антидребезговое время
bounce = 0; // то снять флаг
btn_old = btn ;
btn = btn_new ; // прочитать реальное значение на выводе
if (btn_old && ! btn)(*Do1)();
if (!btn_old && btn)(*Do2)();
}
}
};
//-------------компоновка-----------------------------------
Cl_Led Led1(/*пин*/13,/*инв*/1);
void Do1_Btn1() {
Led1.ON();
}
void Do2_Btn1() {
Led1.OFF();
}
Cl_Btn Btn1(/*пин*/2,/*обраб наж*/Do1_Btn1,/*обраб отж*/Do2_Btn1);
//-------------main()-----------------------------------
void setup() {
Led1.setup();
Btn1.setup();
}
void loop() {
mill = millis();
Led1.loop();
Btn1.loop();
}
/*Скетч использует 1308 байт (4%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 46 байт (2%) динамической памяти, оставляя 2002 байт для локальных переменных. Максимум: 2048 байт.
*/
Считается если объявлена константа, то ее изменять нельзя. Потому что это константа. Но конструктор может, так как он создает класс. Но видно для новичков Ардуино это убрали в некоторых версиях среды.
1.8.1 - выдаёт не ошибку, но предупреждение (в отличие от 1.6.5 и 1.6.12 - те выдают ошибку - опции разные)
Вот предупреждение 1.8.1
C:\Users\Admin\Google Диск\Soft\Kaka\Kaka0\Kaka0.ino: In constructor 'Cl_Btn::Cl_Btn(byte, void (*)(), void (*)())':
C:\Users\Admin\Google Диск\Soft\Kaka\Kaka0\Kaka0.ino:122:5: warning: uninitialized const member in 'const byte {aka const unsigned char}' [-fpermissive]
C:\Users\Admin\Google Диск\Soft\Kaka\Kaka0\Kaka0.ino:108:16: note: 'const byte Cl_Btn::pin' should be initialized
-------------------
Вы же понимаете, что неинициализировать константу неправильно? Так исправьте, чего спорить-то, проще же просто исправить ошибку чем докуазывать недоказуемое.
Считается если объявлена константа, то ее изменять нельзя. Потому что это константа. Но конструктор может, так как он создает класс. Но видно для новичков Ардуино это убрали в некоторых версиях среды.
Не в том дело кто может менять, а кто - нет.
Если в классе объявлена константа, конструктор обязан её инициализировать. Вы этого не сделали, вот и ругается.
Если в классе объявлена константа, конструктор обязан её инициализировать. Вы этого не сделали, вот и ругается.
Ну зеванул. Точнее мне захотелось посмотреть код где убран pinMode(),digitalWrite(),digitalRead(). Точнее их раскрыл уже внутри класса. Затем убрал лишние куски, что бы не мешались. Но мой компилятор не предупредил, хотя программа загрузилась и работала. Значит все нормально. Вот даже переменая pin - нога не понадобилась. И да если компилятор чистит код, то глобальные переменые оставляет. Даже если это глобально внутри класса. Этого не знал.
Считается если объявлена константа, то ее изменять нельзя. Потому что это константа. Но конструктор может, так как он создает класс. Но видно для новичков Ардуино это убрали в некоторых версиях среды.
ну, так и попробуй изменить...
class Cl_AAA {
public:
const byte aaa;//<--- нормально так работает
Cl_AAA(byte _aaa): aaa(_aaa) {}
};
Cl_AAA AAA(/*константа*/1);
void setup() {
AAA.aaa = 5;
}
void loop() {}
sketch_aug13a:8: error: assignment of read-only member 'Cl_AAA::aaa'
AAA.aaa = 5;
/**/
//------qwString---------------------------
//класс стринг
class qwString {
char *buffer;
unsigned len;// длина строки боз последнего \0
/*функция destroy
описание очистить кучу
ввод нет
вывод нет
*/
void destroy() {
if (buffer)
delete[] buffer;
}
public:
/*конструктор qwString
описание конструктор по умолчанию
ввод *data:строка
вывод нет
*/
qwString (): len(0) {
buffer = new char;
buffer[len] = 0;
}
/*конструктор qwString
описание конструктор копирования
ввод data:строка
вывод нет
*/
qwString (qwString & obj) {
len = obj.len;
buffer = new char[len + 1];
strcpy(buffer, obj.buffer);
buffer[len] = 0;
}
/*конструктор qwString
описание перенести данные во вновь создаваемый объект
ввод &&tmp:другой компонент
вывод нет
*/
qwString(qwString&& tmp)
: len(tmp.len), buffer(tmp.buffer) {
tmp.buffer = NULL;
}
/*конструктор qwString
описание создать класс со строкой в 1 символ
ввод data:строка
вывод нет
*/
qwString (char data) {
len = 1;
buffer = new char[2];
buffer[0] = data;
buffer[len] = 0;
}
/*конструктор qwString
описание создать класс со значением строки
ввод *data:строка
вывод нет
*/
qwString (char *data) {
len = strlen(data);
buffer = new char[len + 1];
strcpy(buffer, data);
buffer[len] = 0;
}
/*функция operator=
описание организовать присвоение
ввод other:другой компонент
вывод нет
*/
qwString& operator=(const qwString& other) {
destroy();
len = other.len;
buffer = new char[len + 1];
strcpy(buffer, other.buffer);
buffer[len] = 0;
return *this;
}
/*функция operator=
описание организовать присвоение c переносом
ввод &&tmp:другой компонент
вывод нет
*/
qwString& operator=(qwString&& tmp) {
destroy();
len = tmp.len;
buffer = tmp.buffer;
tmp.buffer = NULL;
return *this;
}
/*деструктор qwString
описание удалить класс
ввод нет
вывод нет
*/
~qwString () {
destroy();
}
/*функция viev
описание показать значение
ввод нет
вывод нет
*/
void viev() {
Serial.print(len);
Serial.print(" ");
Serial.print(buffer);
Serial.println();
}
};
/*функция для проверки перехвата конечного результата функции*/
qwString Create(char *const data) {
qwString _data(data);
return _data;
}
//-------Компоновка----------------------------
//------main()----------------------
void setup() {
Serial.begin(9600);
qwString AAA1 = Create("123"); // срабатывает конструктор перемещения
AAA1.viev();
qwString AAA2 = AAA1; // срабатывает конструктор копирования
AAA2.viev();
AAA2 = Create("456"); // срабатывает конструктор перемещения, затем оператор перемещения
AAA2.viev();
AAA2 = AAA1; // срабатывает оператор присваивания
AAA2.viev();
}
void loop() {
}
/*Скетч использует 2618 байт (8%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 206 байт (10%) динамической памяти, оставляя 1842 байт для локальных переменных. Максимум: 2048 байт.
*/
Строки 73-80 (а также 86-92) - тпипчная ошибка реализации оператора присваивания. При такой реализации присваивание объекта класса самому себе непредсказуемо.
Не всё так просто. Вы используете конструкцию "if(this== &tmp)", но при этом оператор "==" у Вас не определён. Работать-то будет, но не всегда так, как Вы ожидаете - надеюсь, что Вы знаете, что делаете.
Не всё так просто. Вы используете конструкцию "if(this== &tmp)", но при этом оператор "==" у Вас не определён. Работать-то будет, но не всегда так, как Вы ожидаете - надеюсь, что Вы знаете, что делаете.
Разумеется. Там и кроме этого куча ошибок. Но пока не смогу сжевать этот кактус, то о дальнейшем изучении С++ и ОПП говорить бессмысленно.
Этой фразы я не понял. Причём тут Ардуино? То, что разработчики IDE по умолчанию заткнули warning'и, так я Вам уже советовал включить - увидели бы сообщение.
/**/
unsigned long mill;
//------------------------------
const byte led1 =/*пин 1 светодиода*/2;
const byte led2 =/*пин 2 светодиода*/3;
const byte led3 =/*пин 3 светодиода*/4;
void setupLeds() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
}
void runLeds(bool stat) {
static unsigned long past;
static byte step;
if (stat) step = 0;
switch (step) {
case 0:
digitalWrite(led1, HIGH);
past = mill;
step = 1;
break;
case 1:
if (mill - past >= 200) { // delay(200);
digitalWrite(led1, LOW);
digitalWrite(led2, HIGH);
past = mill;
step = 2;
}
break;
case 2:
if (mill - past >= 200) { // delay(200);
digitalWrite(led2, LOW);
digitalWrite(led3, HIGH);
past = mill;
step = 3;
}
break;
case 3:
if (mill - past >= 200) { // delay(200);
digitalWrite(led3, LOW);
step = 4;
}
break;
}
}
//----main--------------------------
void setup() {
setupLeds();
runLeds(1);
}
void loop() {
mill = millis();
runLeds(0);
}
/*Скетч использует 1150 байт (3%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 18 байт (0%) динамической памяти, оставляя 2030 байт для локальных переменных. Максимум: 2048 байт.
*/
Понятно что код непривычен для тех кто мыслит процедурно. Одна и таже процедура(функция) запускается в версии с 1 и в версии с 0. И в setup() и в loop() За то не размазывается по программе как после фугасной бомбы
Ну классов там действительно нету, но ерунды достаточно. И наибольшая в том, что для решения банальнейшего вопроса выдается такой кривой код. А потом удивляемся, почему на форуме простыни кода забитого повторяющимися фрагментами и прочей ерундой. Дак их так учили здесь, примеры такие. Если уж Вы qwone, взялись за неимоверно тяжкую задачу убрать делеи, то предлагайте нормальное решение, а не то за которое будут чмырить позже. Публикуемый код должен быть образцем, а не пробой пера, пробу пера не обязательно людям показывать (за исключением случая когда надо чтоб код оценили и поругали), а тем более советовать как решение. А то ж народ привыкнет так писать.
Смотрю ваш код, нового и оригинального в нем ровно 0. А 3 минуты правки и 2 минуты на тест позволяют преобразовать его, сократив размер скомпилированого на 10%. (с 1300 до 1070 байт) Всего два момента легкой оптимизацией, а структура кода стала более явной, обработчики завершения временных интервалов каждый в своей функции, механизм легко маштабируем и т.д. Так что не публикуйте кривое и сырое, оставте это удовольствие велосипедостроителю ;)
Зачем мне эта грязная простыня? Вы ща как Клапауций, ныть будете "ну глянь, ну попробуй"? Так упреждаю. Я глянул раз, и у него и у Вас. Больше не стоит время терять. Глянул, сделал вывод изложил и даже проилюстрировал. А Ваш уровень писания кода - ваша проблема, плохо что другие на ваш код смотрят и себе так пишут. Хотя и это тоже вобщем не моя проблема ;)
Тема плавно переходит в сборище говнокода от qwone. Но зато наглядно видно что не в классах дело, ох не в классах.
Logik. Меня удивляет ,то что вы здесь пытаетесь найти для себя полезное. Вы ковыряетесь в Си++ больше меня. Это вы должны выкладывать код, а я искать что-то полезное. Но похоже я такой темы не наблюдаю. Может я плохо ищу, или в гугл вашу тему обходит стороной. А то что тема исчерпала себя я давно знаю. Что мог то рассказал. А новое оно очень сырое. Вот у меня вопрос вываливать это новое сюда и слышать, что я говнокодю или работать в стол. Похоже последнее вернее всего.
Logik. Меня удивляет ,то что вы здесь пытаетесь найти для себя полезное. Вы ковыряетесь в Си++ больше меня. Это вы должны выкладывать код, а я искать что-то полезное. Но похоже я такой темы не наблюдаю. Может я плохо ищу, или в гугл вашу тему обходит стороной. А то что тема исчерпала себя я давно знаю. Что мог то рассказал. А новое оно очень сырое. Вот у меня вопрос вываливать это новое сюда и слышать, что я говнокодю или работать в стол. Похоже последнее вернее всего.
Первый раз открывая тему действительно допускал что чего толковоги и оригинального увижу. Иначе бы и не открывал разумеется. Мой код найти не можете? Странно, его здесь много есть, например из последнего http://arduino.ru/forum/apparatnye-voprosy/dtmf-gsm#comment-302080 . Захотите найти - найдете. Например по работе с модемом А8 большой и оч. интересный код публиковал. Так что упрек не по адресу.
А сырое и кривое точно публиковать не надо, за исключением случая чтоб поругали. Сырого и кривого и на гитхабе теперь валом ;)
Тема выдохлась. И скатилась в замену делея на милис. Напомню только про http://arduino.ru/forum/programmirovanie/klassy-arduino-po-qwone-dlya-ch.... Возможно это было бы интересней. И для Вас точно полезней, в ООП продвинулись бы. Например написали бы абстрактный класс реализующий вызов метода через интервалы времени, а на его базе и свой пример последний музыкальный, описав мелодию масивом констант разумеется а не тем бредовым свичем.
Например написали бы абстрактный класс реализующий вызов метода через интервалы времени, а на его базе и свой пример последний музыкальный, описав мелодию масивом констант разумеется а не тем бредовым свичем.
Про астрактный класс (данных или объекта обрабатывающие эти данные )могу сказать одно. Не все что хорошо в теории, хорошо ложится в код. В Гардвадской организации и небольшой памяти точно. Опять я специально привел тот бредовый код , что бы выложить получше сейчас. Ведь пока не видишь разницы думаешь, что есть лучше.
Лучше. Только melody ну никак не массив интов. Массив должен состоять из однотипных величин, а у вас там вперемешку частоты и длительности (тот факт что они инт влезли еще не означает их однотипность). Заведите соответствующую структуру и melody массив структур. Строки 88-91 и 96-98 подозрительно похожи, не так ли? Ну и voidmusic(bytenum) тоже полезно в класс, аналогичный Btn. А если бы они оба наследовали один базовый класс с абстрактным сетапом и лопом то все бы стало еще интересней.
Про архитектуру и как ложится - не переживайте, ляжет. Только напишите ;)
200 кнопок для контроллера?
нет - для суперкомпьютера
Да, у них как-то ваще кнопок негусто - у многих ни одной нет:)
Вот еще задание от сюда http://arduino.ru/forum/programmirovanie/morganie-svetodioda-nuzhnoe-kolichestvo-raz
решение через delay
/**/ //-------компоновка---------------------------- const byte pin =/*пин*/13; //-------main()---------------------------- void setup() { pinMode(pin, OUTPUT); for (int n = 1;; ++n) { for (int i = 0; i < n; ++i) { digitalWrite(pin, HIGH); delay(/*время вкл*/200); digitalWrite(pin, LOW); delay(/*время выкл*/200); } delay(/*пауза между сериями*/500); } } void loop() { } /*Скетч использует 968 байт (3%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт. */Промежуточная разметка
/**/ //-------компоновка---------------------------- const byte pin =/*пин*/13; //-------main()---------------------------- void setup() { pinMode(pin, OUTPUT); for (int n = 1;; ++n) { for (int i = 0; i < n; ++i) { // stat =0 digitalWrite(pin, HIGH); // stat =1 delay(/*время вкл*/200); // stat =2 digitalWrite(pin, LOW); delay(/*время выкл*/200); // stat =3 } // stat =4 delay(/*пауза между сериями*/500); // stat =5 } } void loop() { } /*Скетч использует 968 байт (3%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт. */Ну и перевод в millis()
/**/ //-------компоновка---------------------------- const byte pin =/*пин*/13; int stat = 0, n = 1, i; uint32_t mill, past; //-------main()---------------------------- void setup() { pinMode(pin, OUTPUT); } void loop() { mill = millis(); if (stat == 0) { // 0 stat = 1; i = 1; } if (stat == 1) { // 1 stat = 2; digitalWrite(pin, HIGH); past = mill; } if (stat == 2 && mill - past >=/*время вкл*/200) { // 2 stat = 3; digitalWrite(pin, LOW); past = mill; } if (stat == 3 && mill - past >=/*время выкл*/200) { // 3 stat = 4; digitalWrite(pin, LOW); past = mill; } if (stat == 4) { // 4 if (i < n) { stat = 1; ++i; } else stat = 5; } if (stat == 5 && mill - past >=/*пауза между сериями*/500) { // 5 stat = 0; past = mill; ++n; } } /*Скетч использует 1268 байт (3%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 23 байт (1%) динамической памяти, оставляя 2025 байт для локальных переменных. Максимум: 2048 байт. */А теперь упакован код в класс
/**/ uint32_t mill;//millis() //----------------------------------------------------- class Cl_Led { const byte pin ; int stat = 0, n = 1, i; uint32_t past; public: Cl_Led(byte _pin): pin(_pin) {} void setup() { pinMode(pin, OUTPUT); stat = 0; } void loop() { if (stat == 0) { // 0 stat = 1; i = 1; } if (stat == 1) { // 1 stat = 2; digitalWrite(pin, HIGH); past = mill; } if (stat == 2 && mill - past >=/*время вкл*/200) { // 2 stat = 3; digitalWrite(pin, LOW); past = mill; } if (stat == 3 && mill - past >=/*время выкл*/200) { // 3 stat = 4; digitalWrite(pin, LOW); past = mill; } if (stat == 4) { // 4 if (i < n) { stat = 1; ++i; } else stat = 5; } if (stat == 5 && mill - past >=/*пауза между сериями*/500) { // 5 stat = 0; past = mill; ++n; } } }; //-------компоновка---------------------------- Cl_Led Led(/*пин*/13); //-------main()---------------------------- void setup() { Led.setup(); } void loop() { mill = millis(); Led.loop(); } /*Скетч использует 1340 байт (4%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 24 байт (1%) динамической памяти, оставляя 2024 байт для локальных переменных. Максимум: 2048 байт. */ПС: Тут скорее появился вопрос: Зачем? delay компактнее. Ответ. delay просто съедает ресурсы производительности процессора. А без этих ресурсов сэкономленая флеш и Озу память бесполезна для будущей модернизации программы.
Вариант связки классов через статическую переменную и статические функции класса
/**/ //--------Cl_AAA---------------------------- // эскиз связки класса в блок через статическиую переменную и статические функции класса class Cl_AAA { Cl_AAA *next; // <-- указатель на след элемент public: static Cl_AAA *start; //<-- статический указатель на начало списка static void setup() { for (Cl_AAA *ii = start; ii != NULL; ii = ii->next)ii->init(); } static void loop() { for (Cl_AAA *ii = start; ii != NULL; ii = ii->next)ii->run(); } Cl_AAA() { // <-- конструктор this->next = start ; start = this; } void init() {} void run() {} }; Cl_AAA *Cl_AAA::start = NULL; //---------Компановка--------------------------- Cl_AAA AAA1;//<-- объявление объекта AAA1 Cl_AAA AAA2;//<-- объявление объекта AAA2 //----------main()-------------------------- void setup() { Cl_AAA::setup(); } void loop() { Cl_AAA::loop(); } /*Скетч использует 564 байт (1%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 15 байт (0%) динамической памяти, оставляя 2033 байт для локальных переменных. Максимум: 2048 байт. */Вариант связки классов
Каких классов? В скетче, вроде, один всего класс.
Ну можно так
/**/ uint32_t mill;// переменная под millis() //--------Cl_Led---------------------------- // класс светодиод class Cl_Led { Cl_Led *next; // <-- указатель на след элемент const byte pin; const bool inv; bool led; public: static Cl_Led *start; //<-- статический указатель на начало списка static void setup() { for (Cl_Led *ii = start; ii != NULL; ii = ii->next)ii->init(); } Cl_Led(byte _pin, bool _inv) // <-- конструктор : pin(_pin), inv(_inv) { this->next = start ; start = this; } void init() { pinMode(pin, OUTPUT); OFF(); } void ON() { led = 1; digitalWrite(pin, led ^ inv); } void OFF() { led = 0; digitalWrite(pin, led ^ inv); } }; Cl_Led *Cl_Led::start = NULL; //------Cl_Btn------------------------------------------ // класс кнопка class Cl_Btn { Cl_Btn *next; // <-- указатель на след элемент const byte pin; void (*Do1)(), (*Do2)(); bool btn, btn_old; bool bounce = 0; // антидребезговый флаг uint32_t past = 0 ; public: static Cl_Btn *start; //<-- статический указатель на начало списка static void setup() { for (Cl_Btn *ii = start; ii != NULL; ii = ii->next)ii->init(); } static void loop() { for (Cl_Btn *ii = start; ii != NULL; ii = ii->next) { ii->run(); } } Cl_Btn(byte _pin, void (*_Do1)(), void (*_Do2)()) : pin(_pin), Do1(_Do1), Do2(_Do2) { this->next = start ; start = this; } void init() { pinMode(pin, INPUT_PULLUP); btn_old = digitalRead(pin); } void run() { if (! bounce && btn != digitalRead(pin)) { // если прошел фронт изм на выводн bounce = 1; // выставить флаг past = mill; // сделать временую засветку } else if ( bounce && mill - past >= 5 ) { // если прошло антидребезговое время bounce = 0; // то снять флаг btn_old = btn ; btn = digitalRead(pin) ; // прочитать реальное значение на выводе if (btn_old && ! btn) Do1(); if (!btn_old && btn) Do2(); } } }; Cl_Btn *Cl_Btn::start = NULL; //---------Компановка--------------------------- Cl_Led Led(/*пин*/13,/*инв*/0); void Do1_Btn() { Led.ON(); } void Do2_Btn() { Led.OFF(); } Cl_Btn Btn(/*пин*/2,/*обраб наж*/Do1_Btn,/*обраб отж*/Do2_Btn); //----------main()-------------------------- void setup() { Cl_Led::setup(); Cl_Btn::setup(); } void loop() { mill = millis(); Cl_Btn::loop(); } /*Скетч использует 1368 байт (4%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 36 байт (1%) динамической памяти, оставляя 2012 байт для локальных переменных. Максимум: 2048 байт. */Или так
/**/ uint32_t mill;// переменная под millis() //--------Cl_Led---------------------------- // класс светодиод class Cl_Led { Cl_Led *next; // <-- указатель на след элемент const byte pin; const bool inv; bool led; public: static Cl_Led *start; //<-- статический указатель на начало списка static void setup() { for (Cl_Led *ii = start; ii != NULL; ii = ii->next)ii->init(); } Cl_Led(byte _pin, bool _inv) // <-- конструктор : pin(_pin), inv(_inv) { this->next = start ; start = this; } void init() { pinMode(pin, OUTPUT); OFF(); } void ON() { led = 1; digitalWrite(pin, led ^ inv); } void OFF() { led = 0; digitalWrite(pin, led ^ inv); } }; Cl_Led *Cl_Led::start = NULL; //------Cl_Btn------------------------------------------ // класс кнопка class Cl_Btn { Cl_Btn *next; // <-- указатель на след элемент const byte pin; void (*Do1)(), (*Do2)(); bool btn, btn_old; bool bounce = 0; // антидребезговый флаг uint32_t past = 0 ; public: static Cl_Btn *start; //<-- статический указатель на начало списка static void setup() { for (Cl_Btn *ii = start; ii != NULL; ii = ii->next)ii->init(); } static void loop() { for (Cl_Btn *ii = start; ii != NULL; ii = ii->next) { ii->run(); } } Cl_Btn(byte _pin, void (*_Do1)(), void (*_Do2)()) : pin(_pin), Do1(_Do1), Do2(_Do2) { this->next = start ; start = this; } void init() { pinMode(pin, INPUT_PULLUP); btn_old = digitalRead(pin); } void run() { if (! bounce && btn != digitalRead(pin)) { // если прошел фронт изм на выводн bounce = 1; // выставить флаг past = mill; // сделать временую засветку } else if ( bounce && mill - past >= 5 ) { // если прошло антидребезговое время bounce = 0; // то снять флаг btn_old = btn ; btn = digitalRead(pin) ; // прочитать реальное значение на выводе if (btn_old && ! btn) Do1(); if (!btn_old && btn) Do2(); } } }; Cl_Btn *Cl_Btn::start = NULL; //---------Компановка--------------------------- Cl_Led Led1(/*пин*/13,/*инв*/0); Cl_Led Led2(/*пин*/12,/*инв*/0); void Do1_Btn1() { Led1.ON(); } void Do2_Btn1() { Led1.OFF(); } Cl_Btn Btn1(/*пин*/2,/*обраб наж*/Do1_Btn1,/*обраб отж*/Do2_Btn1); void Do1_Btn2() { Led2.ON(); } void Do2_Btn2() { Led2.OFF(); } Cl_Btn Btn2(/*пин*/3,/*обраб наж*/Do1_Btn2,/*обраб отж*/Do2_Btn2); //----------main()-------------------------- void setup() { Cl_Led::setup(); Cl_Btn::setup(); } void loop() { mill = millis(); Cl_Btn::loop(); } /*Скетч использует 1484 байт (4%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 55 байт (2%) динамической памяти, оставляя 1993 байт для локальных переменных. Максимум: 2048 байт. */А можно так
/**/ uint32_t mill;// переменная под millis() //--------Cl_Led---------------------------- // класс светодиод class Cl_Led { Cl_Led *next; // <-- указатель на след элемент const byte pin; const bool inv; bool led; bool stat;// 1 мигает 0 нет uint32_t past, time; public: static Cl_Led *start; //<-- статический указатель на начало списка static void setup() { for (Cl_Led *ii = start; ii != NULL; ii = ii->next)ii->init(); } static void loop() { for (Cl_Led *ii = start; ii != NULL; ii = ii->next)ii->run(); } Cl_Led(byte _pin, bool _inv) // <-- конструктор : pin(_pin), inv(_inv) { this->next = start ; start = this; } void init() { pinMode(pin, OUTPUT); OFF(); } void ON() { led = 1; digitalWrite(pin, led ^ inv); stat = 0; } void OFF() { led = 0; digitalWrite(pin, led ^ inv); stat = 0; } void blink(uint32_t _time = 500) { time = _time; past = mill; stat = 1; led = 1; digitalWrite(pin, led ^ inv); } void run() { if (!stat) return; if (mill - past >= time) { past = mill; led = !led; digitalWrite(pin, led ^ inv); } } }; Cl_Led *Cl_Led::start = NULL; //------Cl_Btn------------------------------------------ // класс кнопка class Cl_Btn { Cl_Btn *next; // <-- указатель на след элемент const byte pin; void (*Do1)(); bool btn, btn_old; bool bounce = 0; // антидребезговый флаг uint32_t past = 0 ; public: static Cl_Btn *start; //<-- статический указатель на начало списка static void setup() { for (Cl_Btn *ii = start; ii != NULL; ii = ii->next)ii->init(); } static void loop() { for (Cl_Btn *ii = start; ii != NULL; ii = ii->next) { ii->run(); } } Cl_Btn(byte _pin, void (*_Do1)()) : pin(_pin), Do1(_Do1) { this->next = start ; start = this; } void init() { pinMode(pin, INPUT_PULLUP); btn_old = digitalRead(pin); } void run() { if (! bounce && btn != digitalRead(pin)) { // если прошел фронт изм на выводн bounce = 1; // выставить флаг past = mill; // сделать временую засветку } else if ( bounce && mill - past >= 5 ) { // если прошло антидребезговое время bounce = 0; // то снять флаг btn_old = btn ; btn = digitalRead(pin) ; // прочитать реальное значение на выводе if (btn_old && ! btn) Do1(); } } }; Cl_Btn *Cl_Btn::start = NULL; //---------Компановка--------------------------- Cl_Led Led1(/*пин*/13,/*инв*/0); void Do_Btn1() { Led1.ON(); } void Do_Btn2() { Led1.OFF(); } void Do_Btn3() { Led1.blink(200); } Cl_Btn Btn1(/*пин*/2,/*обраб наж*/Do_Btn1); Cl_Btn Btn2(/*пин*/3,/*обраб наж*/Do_Btn2); Cl_Btn Btn3(/*пин*/4,/*обраб наж*/Do_Btn3); //----------main()-------------------------- void setup() { Cl_Led::setup(); Cl_Btn::setup(); } void loop() { mill = millis(); Cl_Led::loop(); Cl_Btn::loop(); } /*Скетч использует 1614 байт (5%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 67 байт (3%) динамической памяти, оставляя 1981 байт для локальных переменных. Максимум: 2048 байт. */Всем известна программа Blink с delay()
/**/ void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); delay(1000); } /*Скетч использует 928 байт (2%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт. */Вот вариант с классом .заменил pinMode и digitalWrite
/* */ //---------Cl_led---------------------------------- //класс светодиод class Cl_led { uint8_t bit ;// номер бита uint8_t port ; // номер порта volatile uint8_t *reg, *out; public: Cl_led(uint8_t pin) { bit = digitalPinToBitMask(pin); port = digitalPinToPort(pin); reg = portModeRegister(port); out = portOutputRegister(port); } void setup() { uint8_t oldSREG = SREG; cli(); *reg |= bit; SREG = oldSREG; } void ON() { uint8_t oldSREG = SREG; cli(); *out |= bit; SREG = oldSREG; } void OFF() { uint8_t oldSREG = SREG; cli(); *out &= ~bit; SREG = oldSREG; } }; //------------------------------------------- Cl_led led(13); //------------------------------------------- void setup() { led.setup(); } void loop() { led.ON(); delay(200); led.OFF(); delay(200); } /*Скетч использует 874 байт (2%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 15 байт (0%) динамической памяти, оставляя 2033 байт для локальных переменных. Максимум: 2048 байт. */Ужался код немного.
Добавил в класс инвесию
/* */ //---------Cl_led---------------------------------- //класс светодиод class Cl_led { uint8_t bit ;// номер бита uint8_t port ; // номер порта volatile uint8_t *reg, *out; bool led; // состояние светодиода bool inv;// состояние бита инверсии public: Cl_led(uint8_t pin, uint8_t _inv = 0): inv(_inv) { bit = digitalPinToBitMask(pin); port = digitalPinToPort(pin); reg = portModeRegister(port); out = portOutputRegister(port); } void setup() { uint8_t oldSREG = SREG; cli(); *reg |= bit; led = 0; if (led ^ inv == 0) *out &= ~bit; else *out |= bit; SREG = oldSREG; } void ON() { uint8_t oldSREG = SREG; cli(); led = 1; if (led ^ inv == 0) *out &= ~bit; else *out |= bit; SREG = oldSREG; } void OFF() { uint8_t oldSREG = SREG; cli(); led = 0; if (led ^ inv == 0) *out &= ~bit; else *out |= bit; SREG = oldSREG; } }; //------------------------------------------- Cl_led led(/*пин*/13,/*инверсия*/0); //------------------------------------------- void setup() { led.setup(); } void loop() { led.ON(); delay(200); led.OFF(); delay(200); } /*Скетч использует 958 байт (2%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 17 байт (0%) динамической памяти, оставляя 2031 байт для локальных переменных. Максимум: 2048 байт. */Странная у Вас инверсия. Для того, чтобы инвертировать пин, достаточно прописать 1 в соответствующий бит регистра PINx.
Например для третьего пина:
и это странслируется в одну единственную машинную команду
Вопрос не понятен. Я написал "Например для третьего пина". Так вот, для тертьего пина - это действительно так, я уверен (и даташит тоже). А как Вам это перевести в Ваш класс и сделать универсально для любого пина - это Ваша забота.
Только не забывайте. так как я написал - это ОДНА машинная команда и НОЛЬ байтов дополнительной памяти данных. Вы же зачем-то пытаетесь помнить какую-то переменную и выполнять логику с нею. Зачем? Для инвертирования пина, как я Вам писал, достаточно записать 1 в нужный бит PINx (и неважно. что там было раньше - запишете единицу ещё раз - инвертируется ещё раз). Попробуйте.
Третий скетч отсюда #109
Получился таким.
/* */ //---------Cl_led---------------------------------- //класс светодиод class Cl_led { uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход volatile uint8_t *reg; // указатель на регистр настройки порта volatile uint8_t *out; // указатель на регистр входа порта bool inv;// состояние бита инверсии выхода public: Cl_led(uint8_t pin, uint8_t _inv = 0): inv(_inv) { bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); // получить номер порта reg = portModeRegister(port); out = portOutputRegister(port); } void setup() { uint8_t oldSREG = SREG; cli(); *reg |= bit; if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; } void OFF() { uint8_t oldSREG = SREG; cli(); if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; } void ON() { uint8_t oldSREG = SREG; cli(); if (inv) *out |= bit; else *out &= ~bit; SREG = oldSREG; } }; //-----Компоновка---------------------------------- Cl_led led(/*пин*/13,/*инверсия*/1); //-----main()-------------------------------------- void setup() { led.setup(); } void loop() { led.ON(); delay(200); led.OFF(); delay(200); } /*Скетч использует 940 байт (2%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 15 байт (0%) динамической памяти, оставляя 2033 байт для локальных переменных. Максимум: 2048 байт. */Такой же в работе код, но уже на millis()
/* */ unsigned long mill = 0; // переменная millis() //---------Cl_led---------------------------------- //класс светодиод class Cl_led { uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход volatile uint8_t *reg; // указатель на регистр настройки порта volatile uint8_t *out; // указатель на регистр входа порта bool inv;// состояние бита инверсии выхода bool stat;// 1 мигать / 0 нет unsigned long past, time; public: Cl_led(uint8_t pin, uint8_t _inv = 0): inv(_inv) { bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); // получить номер порта reg = portModeRegister(port); out = portOutputRegister(port); } void setup() { uint8_t oldSREG = SREG; cli(); *reg |= bit; if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; stat = 0; } void OFF() { uint8_t oldSREG = SREG; cli(); if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; stat = 0; } void ON() { uint8_t oldSREG = SREG; cli(); if (inv) *out |= bit; else *out &= ~bit; SREG = oldSREG; stat = 0; } void blink(unsigned long _time = 500) { time = _time; stat = 1; past = mill; uint8_t oldSREG = SREG; cli(); *out ^= bit; SREG = oldSREG; } void loop() { if (!stat) return; if (mill - past >= time) { past = mill; uint8_t oldSREG = SREG; cli(); *out ^= bit; SREG = oldSREG; } } }; //-----Компоновка---------------------------------- Cl_led led(/*пин*/13,/*инверсия*/1); //-----main()-------------------------------------- void setup() { led.setup(); led.blink(1000);// мигать 1сек горит+1сек нет } void loop() { mill = millis(); led.loop(); } /*Скетч использует 896 байт (2%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 28 байт (1%) динамической памяти, оставляя 2020 байт для локальных переменных. Максимум: 2048 байт. */Код на 3 кнопки и светодиод с миганием на таком же принципе
/**/ uint32_t mill;// переменная под millis() //---------Cl_Led---------------------------------- //класс светодиод class Cl_Led { uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход volatile uint8_t *reg; // указатель на регистр настройки порта volatile uint8_t *out; // указатель на регистр входа порта bool inv;// состояние бита инверсии выхода bool stat;// 1 мигать / 0 нет unsigned long past, time; public: Cl_Led (uint8_t pin, uint8_t _inv = 0): inv(_inv) { bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); // получить номер порта reg = portModeRegister(port); out = portOutputRegister(port); } void setup() { uint8_t oldSREG = SREG; cli(); *reg |= bit; if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; stat = 0; } void OFF() { uint8_t oldSREG = SREG; cli(); if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; stat = 0; } void ON() { uint8_t oldSREG = SREG; cli(); if (inv) *out |= bit; else *out &= ~bit; SREG = oldSREG; stat = 0; } void blink(unsigned long _time = 500) { time = _time; stat = 1; past = mill; uint8_t oldSREG = SREG; cli(); *out ^= bit; SREG = oldSREG; } void loop() { if (!stat) return; if (mill - past >= time) { past = mill; uint8_t oldSREG = SREG; cli(); *out ^= bit; SREG = oldSREG; } } }; //------Cl_Btn------------------------------------------ // класс кнопка c програмной подтяжкой class Cl_Btn { uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход volatile uint8_t *reg; // указатель на регистр настройки порта volatile uint8_t *out; // указатель на регистр выхода порта uint8_t port; // номер порта на выводе const byte pin; void (*Do)(); bool btn, btn_old, btn_new; bool bounce = 0; // антидребезговый флаг uint32_t past = 0 ; public: Cl_Btn(byte pin, void (*_Do)()): Do(_Do) { bit = digitalPinToBitMask(pin); port = digitalPinToPort(pin); // получить номер порта reg = portModeRegister(port); out = portOutputRegister(port); } void setup() { //pinMode(pin, INPUT_PULLUP); uint8_t oldSREG = SREG; cli(); *reg &= ~bit; //INPUT_PULLUP *out |= bit; SREG = oldSREG; btn_old = (*portInputRegister(port) & bit) == 0; } void loop() { btn_new = (*portInputRegister(port) & bit) == 0; if (! bounce && btn != btn_new) { // если прошел фронт изм на выводн bounce = 1; // выставить флаг past = mill; // сделать временую засветку } else if ( bounce && mill - past >= 5 ) { // если прошло антидребезговое время bounce = 0; // то снять флаг btn_old = btn ; btn = btn_new ; // прочитать реальное значение на выводе if (btn_old && ! btn)(*Do)(); } } }; //-------------компоновка----------------------------------- Cl_Led Led1(/*пин*/13,/*инв*/1); void Do_Btn1() { Led1.ON(); } void Do_Btn2() { Led1.OFF(); } void Do_Btn3() { Led1.blink(200); } Cl_Btn Btn1(/*пин*/2,/*обраб наж*/Do_Btn1); Cl_Btn Btn2(/*пин*/3,/*обраб наж*/Do_Btn2); Cl_Btn Btn3(/*пин*/4,/*обраб наж*/Do_Btn3); //-------------main()----------------------------------- void setup() { Led1.setup(); Btn1.setup(); Btn2.setup(); Btn3.setup(); } void loop() { mill = millis(); Led1.loop(); Btn1.loop(); Btn2.loop(); Btn3.loop(); } /*Скетч использует 1472 байт (4%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 79 байт (3%) динамической памяти, оставляя 1969 байт для локальных переменных. Максимум: 2048 байт. */Последний скетч немного оптимизировал
/**/ uint32_t mill;// переменная под millis() //---------Cl_Led---------------------------------- //класс светодиод class Cl_Led { uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход volatile uint8_t *reg; // указатель на регистр настройки порта volatile uint8_t *out; // указатель на регистр входа порта bool inv;// состояние бита инверсии выхода bool stat;// 1 мигать / 0 нет unsigned long past, time; public: Cl_Led (uint8_t pin, uint8_t _inv = 0): inv(_inv) { bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); // получить номер порта reg = portModeRegister(port); out = portOutputRegister(port); } void setup() { uint8_t oldSREG = SREG; cli(); *reg |= bit; if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; stat = 0; } void OFF() { uint8_t oldSREG = SREG; cli(); if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; stat = 0; } void ON() { uint8_t oldSREG = SREG; cli(); if (inv) *out |= bit; else *out &= ~bit; SREG = oldSREG; stat = 0; } void blink(unsigned long _time = 500) { time = _time; stat = 1; past = mill; uint8_t oldSREG = SREG; cli(); *out ^= bit; SREG = oldSREG; } void loop() { if (!stat) return; if (mill - past >= time) { past = mill; uint8_t oldSREG = SREG; cli(); *out ^= bit; SREG = oldSREG; } } }; //------Cl_Btn------------------------------------------ // класс кнопка c програмной подтяжкой class Cl_Btn { uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход uint8_t port; // номер порта на выводе void (*Do)(); bool btn, btn_old; bool bounce = 0; // антидребезговый флаг uint32_t past = 0 ; public: Cl_Btn(byte pin, void (*_Do)()): Do(_Do) { bit = digitalPinToBitMask(pin); port = digitalPinToPort(pin); // получить номер порта } void setup() { uint8_t oldSREG = SREG; cli(); volatile uint8_t *reg = portModeRegister(port); volatile uint8_t *out = portOutputRegister(port); *reg &= ~bit; //INPUT *out |= bit; //_PULLUP SREG = oldSREG; btn_old = (*portInputRegister(port) & bit) == 0; } void loop() { bool btn_new = (*portInputRegister(port) & bit) == 0; if (! bounce && btn != btn_new) { // если прошел фронт изм на выводн bounce = 1; // выставить флаг past = mill; // сделать временую засветку } else if ( bounce && mill - past >= 5 ) { // если прошло антидребезговое время bounce = 0; // то снять флаг btn_old = btn ; btn = btn_new ; // прочитать реальное значение на выводе if (btn_old && ! btn)(*Do)(); } } }; //-------------компоновка----------------------------------- Cl_Led Led1(/*пин*/13,/*инв*/1); void Do_Btn1() { Led1.ON(); } void Do_Btn2() { Led1.OFF(); } void Do_Btn3() { Led1.blink(200); } Cl_Btn Btn1(/*пин*/2,/*обраб наж*/Do_Btn1); Cl_Btn Btn2(/*пин*/3,/*обраб наж*/Do_Btn2); Cl_Btn Btn3(/*пин*/4,/*обраб наж*/Do_Btn3); //-------------main()----------------------------------- void setup() { Led1.setup(); Btn1.setup(); Btn2.setup(); Btn3.setup(); } void loop() { mill = millis(); Led1.loop(); Btn1.loop(); Btn2.loop(); Btn3.loop(); } /*Скетч использует 1502 байт (4%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 61 байт (2%) динамической памяти, оставляя 1987 байт для локальных переменных. Максимум: 2048 байт. */А эта версия если кнопки или датчики у вас без дребезга
/**/ uint32_t mill;// переменная под millis() //---------Cl_Led---------------------------------- //класс светодиод class Cl_Led { uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход volatile uint8_t *reg; // указатель на регистр настройки порта volatile uint8_t *out; // указатель на регистр входа порта bool inv;// состояние бита инверсии выхода bool stat;// 1 мигать / 0 нет unsigned long past, time; public: Cl_Led (uint8_t pin, uint8_t _inv = 0): inv(_inv) { bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); // получить номер порта reg = portModeRegister(port); out = portOutputRegister(port); } void setup() { uint8_t oldSREG = SREG; cli(); *reg |= bit; if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; stat = 0; } void OFF() { uint8_t oldSREG = SREG; cli(); if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; stat = 0; } void ON() { uint8_t oldSREG = SREG; cli(); if (inv) *out |= bit; else *out &= ~bit; SREG = oldSREG; stat = 0; } void blink(unsigned long _time = 500) { time = _time; stat = 1; past = mill; uint8_t oldSREG = SREG; cli(); *out ^= bit; SREG = oldSREG; } void loop() { if (!stat) return; if (mill - past >= time) { past = mill; uint8_t oldSREG = SREG; cli(); *out ^= bit; SREG = oldSREG; } } }; //------Cl_Btn------------------------------------------ // класс кнопка на бездребезговый выход class Cl_Btn { uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход uint8_t port; // номер порта на выводе void (*Do)(); bool btn, btn_old; public: Cl_Btn(byte pin, void (*_Do)()): Do(_Do) { bit = digitalPinToBitMask(pin); port = digitalPinToPort(pin); // получить номер порта } void setup() { uint8_t oldSREG = SREG; cli(); volatile uint8_t *reg = portModeRegister(port); volatile uint8_t *out = portOutputRegister(port); *reg &= ~bit; //INPUT SREG = oldSREG; btn = (*portInputRegister(port) & bit) == 0; } void loop() { btn_old = btn; btn = (*portInputRegister(port) & bit) == 0; if (!btn_old && btn)(*Do)(); } }; //-------------компоновка----------------------------------- Cl_Led Led1(/*пин*/13,/*инв*/1); void Do_Btn1() { Led1.ON(); } void Do_Btn2() { Led1.OFF(); } void Do_Btn3() { Led1.blink(200); } Cl_Btn Btn1(/*пин*/2,/*обраб наж*/Do_Btn1); Cl_Btn Btn2(/*пин*/3,/*обраб наж*/Do_Btn2); Cl_Btn Btn3(/*пин*/4,/*обраб наж*/Do_Btn3); //-------------main()----------------------------------- void setup() { Led1.setup(); Btn1.setup(); Btn2.setup(); Btn3.setup(); } void loop() { mill = millis(); Led1.loop(); Btn1.loop(); Btn2.loop(); Btn3.loop(); } /*Скетч использует 1314 байт (4%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 46 байт (2%) динамической памяти, оставляя 2002 байт для локальных переменных. Максимум: 2048 байт. */Уроки программирования Ардуино. http://mypractic.ru/uroki-programmirovaniya-arduino-navigaciya-po-urokam
/**/ uint32_t mill;// переменная под millis() //---------Cl_Led---------------------------------- //класс светодиод class Cl_Led { uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход volatile uint8_t *reg; // указатель на регистр настройки порта volatile uint8_t *out; // указатель на регистр входа порта bool inv;// состояние бита инверсии выхода bool stat;// 1 мигать / 0 нет unsigned long past, time; public: /* конструктор Cl_Led Описание создает класс Ввод pin: подключение к ноге inv: бит инвертирования 0 нет / 1 инверсия Вывод нет */ Cl_Led (uint8_t pin, uint8_t _inv = 0): inv(_inv) { bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); // получить номер порта reg = portModeRegister(port); out = portOutputRegister(port); } /* Функция setup Описание иницирование класса Ввод нет Вывод нет */ void setup() { uint8_t oldSREG = SREG; cli(); *reg |= bit; if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; stat = 0; } /* Функция OFF Описание выключить светодиод Ввод нет Вывод нет */ void OFF() { uint8_t oldSREG = SREG; cli(); if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; stat = 0; } /* Функция ON Описание включить светодиод Ввод нет Вывод нет */ void ON() { uint8_t oldSREG = SREG; cli(); if (inv) *out |= bit; else *out &= ~bit; SREG = oldSREG; stat = 0; } /* Функция blink Описание мигать светодиодои Ввод _time - полупериод мигания Вывод нет */ void blink(unsigned long _time = 500) { time = _time; stat = 1; past = mill; uint8_t oldSREG = SREG; cli(); *out ^= bit; SREG = oldSREG; } /* Функция loop Описание для нормальной работе разместить в loop программы Ввод нет Вывод нет */ void loop() { if (!stat) return; if (mill - past >= time) { past = mill; uint8_t oldSREG = SREG; cli(); *out ^= bit; SREG = oldSREG; } } }; //------Cl_Btn------------------------------------------ // класс кнопка c програмной подтяжкой class Cl_Btn { uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход volatile uint8_t *reg; // указатель на регистр настройки порта volatile uint8_t *out; // указатель на регистр выхода порта uint8_t port; // номер порта на выводе const byte pin; void (*Do1)(), (*Do2)(); bool btn, btn_old, btn_new; bool bounce = 0; // антидребезговый флаг uint32_t past = 0 ; public: /* конструктор Cl_Btn Описание создает класс Ввод pin: подключение к ноге _Do1: фунция обработчик нажатия кнопки _Do2: фунция обработчик отжатия кнопки Вывод нет */ Cl_Btn(byte pin, void (*_Do1)(), void (*_Do2)()): Do1(_Do1), Do2(_Do2) { bit = digitalPinToBitMask(pin); port = digitalPinToPort(pin); // получить номер порта reg = portModeRegister(port); out = portOutputRegister(port); } /* Функция setup Описание иницирование класса Ввод нет Вывод нет */ void setup() { uint8_t oldSREG = SREG; cli(); *reg &= ~bit; //INPUT *out |= bit; //PULLUP SREG = oldSREG; btn_old = (*portInputRegister(port) & bit) == 0; } /* Функция loop Описание для нормальной работе разместить в loop программы Ввод нет Вывод нет */ void loop() { btn_new = (*portInputRegister(port) & bit) == 0; if (! bounce && btn != btn_new) { // если прошел фронт изм на выводн bounce = 1; // выставить флаг past = mill; // сделать временую засветку } else if ( bounce && mill - past >= 5 ) { // если прошло антидребезговое время bounce = 0; // то снять флаг btn_old = btn ; btn = btn_new ; // прочитать реальное значение на выводе if (btn_old && ! btn)(*Do1)(); if (!btn_old && btn)(*Do2)(); } } }; //-------------компоновка----------------------------------- Cl_Led Led1(/*пин*/13,/*инв*/1); void Do1_Btn1() { Led1.ON(); } void Do2_Btn1() { Led1.OFF(); } Cl_Btn Btn1(/*пин*/2,/*обраб наж*/Do1_Btn1,/*обраб отж*/Do2_Btn1); //-------------main()----------------------------------- void setup() { Led1.setup(); Btn1.setup(); } void loop() { mill = millis(); Led1.loop(); Btn1.loop(); } /*Скетч использует 1308 байт (4%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 47 байт (2%) динамической памяти, оставляя 2001 байт для локальных переменных. Максимум: 2048 байт. */Послушайте, qwone,
Вы хотя бы компилировать свои опусы пробуете (я уж не говорю запускать)? Или вот как в голову пришло, так публикуете?
Ваш код элементарно не компилируется потому, что Вы в 108 строку засунули константый член класса, которым нигде и никогда не пользуетесь (главное - не инициализируете)!
Послушайте, qwone,
Вы хотя бы компилировать свои опусы пробуете (я уж не говорю запускать)? Или вот как в голову пришло, так публикуете?
Ваш код элементарно не компилируется потому, что Вы в 108 строку засунули константый член класса, которым нигде и никогда не пользуетесь (главное - не инициализируете)!
Ну компилируется вы же видели это /* */ И работает. Ну да остались рудименты. Так компилятор это и опускает. Умный блин однако, это я про компилятор. const byte pin все же загружаемая переменная, но только с конструктора.
ПС: хотя да без нее на один байт в программе меньше.
/**/ uint32_t mill;// переменная под millis() //---------Cl_Led---------------------------------- //класс светодиод class Cl_Led { uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход volatile uint8_t *reg; // указатель на регистр настройки порта volatile uint8_t *out; // указатель на регистр входа порта bool inv;// состояние бита инверсии выхода bool stat;// 1 мигать / 0 нет unsigned long past, time; public: /* конструктор Cl_Led Описание создает класс Ввод pin: подключение к ноге inv: бит инвертирования 0 нет / 1 инверсия Вывод нет */ Cl_Led (uint8_t pin, uint8_t _inv = 0): inv(_inv) { bit = digitalPinToBitMask(pin); uint8_t port = digitalPinToPort(pin); // получить номер порта reg = portModeRegister(port); out = portOutputRegister(port); } /* Функция setup Описание иницирование класса Ввод нет Вывод нет */ void setup() { uint8_t oldSREG = SREG; cli(); *reg |= bit; if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; stat = 0; } /* Функция OFF Описание выключить светодиод Ввод нет Вывод нет */ void OFF() { uint8_t oldSREG = SREG; cli(); if (inv) *out &= ~bit; else *out |= bit; SREG = oldSREG; stat = 0; } /* Функция ON Описание включить светодиод Ввод нет Вывод нет */ void ON() { uint8_t oldSREG = SREG; cli(); if (inv) *out |= bit; else *out &= ~bit; SREG = oldSREG; stat = 0; } /* Функция blink Описание мигать светодиодои Ввод _time - полупериод мигания Вывод нет */ void blink(unsigned long _time = 500) { time = _time; stat = 1; past = mill; uint8_t oldSREG = SREG; cli(); *out ^= bit; SREG = oldSREG; } /* Функция loop Описание для нормальной работе разместить в loop программы Ввод нет Вывод нет */ void loop() { if (!stat) return; if (mill - past >= time) { past = mill; uint8_t oldSREG = SREG; cli(); *out ^= bit; SREG = oldSREG; } } }; //------Cl_Btn------------------------------------------ // класс кнопка c програмной подтяжкой class Cl_Btn { uint8_t bit ; // номер бита в виде 00010000,1 находится там где выход volatile uint8_t *reg; // указатель на регистр настройки порта volatile uint8_t *out; // указатель на регистр выхода порта uint8_t port; // номер порта на выводе void (*Do1)(), (*Do2)(); bool btn, btn_old, btn_new; bool bounce = 0; // антидребезговый флаг uint32_t past = 0 ; public: /* конструктор Cl_Btn Описание создает класс Ввод pin: подключение к ноге _Do1: фунция обработчик нажатия кнопки _Do2: фунция обработчик отжатия кнопки Вывод нет */ Cl_Btn(byte pin, void (*_Do1)(), void (*_Do2)()): Do1(_Do1), Do2(_Do2) { bit = digitalPinToBitMask(pin); port = digitalPinToPort(pin); // получить номер порта reg = portModeRegister(port); out = portOutputRegister(port); } /* Функция setup Описание иницирование класса Ввод нет Вывод нет */ void setup() { uint8_t oldSREG = SREG; cli(); *reg &= ~bit; //INPUT *out |= bit; //PULLUP SREG = oldSREG; btn_old = (*portInputRegister(port) & bit) == 0; } /* Функция loop Описание для нормальной работе разместить в loop программы Ввод нет Вывод нет */ void loop() { btn_new = (*portInputRegister(port) & bit) == 0; if (! bounce && btn != btn_new) { // если прошел фронт изм на выводн bounce = 1; // выставить флаг past = mill; // сделать временую засветку } else if ( bounce && mill - past >= 5 ) { // если прошло антидребезговое время bounce = 0; // то снять флаг btn_old = btn ; btn = btn_new ; // прочитать реальное значение на выводе if (btn_old && ! btn)(*Do1)(); if (!btn_old && btn)(*Do2)(); } } }; //-------------компоновка----------------------------------- Cl_Led Led1(/*пин*/13,/*инв*/1); void Do1_Btn1() { Led1.ON(); } void Do2_Btn1() { Led1.OFF(); } Cl_Btn Btn1(/*пин*/2,/*обраб наж*/Do1_Btn1,/*обраб отж*/Do2_Btn1); //-------------main()----------------------------------- void setup() { Led1.setup(); Btn1.setup(); } void loop() { mill = millis(); Led1.loop(); Btn1.loop(); } /*Скетч использует 1308 байт (4%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 46 байт (2%) динамической памяти, оставляя 2002 байт для локальных переменных. Максимум: 2048 байт. */qwone, ну реально какой-то поток сознания - нахрена это всё?
Ну компилируется вы же видели это /* */ И работает.
Я вставил в IDE. И ни хрена не компилируется. Как и следовало ожидать выдаёт сообщение
так у меня Ардуино 1.8.0 . Заходит нормально.
Да так смотрю как программа выглядил на форуме с такими комментариями. Всегда найдутся люди со строны и увидят что-то не так.
ок а, тема как называется?
я сюда захожу, что бы научиться чему-то новому.
и, что я вижу - бред сумасшедшего.
да - оно компилится ровно так, как речь шизофреника логически связна, но при длительном наблюдении оказывается бредом.
class Cl_AAA { const byte aaa;//<--- нормально так работает public: Cl_AAA(byte _aaa): aaa(_aaa) {} }; Cl_AAA AAA(/*константа*/1); void setup() { } void loop() { } /*Скетч использует 488 байт (1%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 10 байт (0%) динамической памяти, оставляя 2038 байт для локальных переменных. Максимум: 2048 байт. *///<--- нормально так работает
почему не должно работать?
//<--- нормально так работает
почему не должно работать?
так у меня Ардуино 1.8.0 . Заходит нормально.
1.8.1 - выдаёт не ошибку, но предупреждение (в отличие от 1.6.5 и 1.6.12 - те выдают ошибку - опции разные)
Вот предупреждение 1.8.1
Считается если объявлена константа, то ее изменять нельзя. Потому что это константа. Но конструктор может, так как он создает класс. Но видно для новичков Ардуино это убрали в некоторых версиях среды.
Не в том дело кто может менять, а кто - нет.
Если в классе объявлена константа, конструктор обязан её инициализировать. Вы этого не сделали, вот и ругается.
Ну зеванул. Точнее мне захотелось посмотреть код где убран pinMode(),digitalWrite(),digitalRead(). Точнее их раскрыл уже внутри класса. Затем убрал лишние куски, что бы не мешались. Но мой компилятор не предупредил, хотя программа загрузилась и работала. Значит все нормально. Вот даже переменая pin - нога не понадобилась. И да если компилятор чистит код, то глобальные переменые оставляет. Даже если это глобально внутри класса. Этого не знал.
мой компилятор не предупредил
Посмотрите в настройках IDE "Compiler warnings". По умолчанию "из коробки" там стоит "None". Поставьте "All" - для разработчика это более адекватно.
Считается если объявлена константа, то ее изменять нельзя. Потому что это константа. Но конструктор может, так как он создает класс. Но видно для новичков Ардуино это убрали в некоторых версиях среды.
ну, так и попробуй изменить...
class Cl_AAA { public: const byte aaa;//<--- нормально так работает Cl_AAA(byte _aaa): aaa(_aaa) {} }; Cl_AAA AAA(/*константа*/1); void setup() { AAA.aaa = 5; } void loop() {}Код
/**/ //------qwString--------------------------- //класс стринг class qwString { char *buffer; unsigned len;// длина строки боз последнего \0 /*функция destroy описание очистить кучу ввод нет вывод нет */ void destroy() { if (buffer) delete[] buffer; } public: /*конструктор qwString описание конструктор по умолчанию ввод *data:строка вывод нет */ qwString (): len(0) { buffer = new char; buffer[len] = 0; } /*конструктор qwString описание конструктор копирования ввод data:строка вывод нет */ qwString (qwString & obj) { len = obj.len; buffer = new char[len + 1]; strcpy(buffer, obj.buffer); buffer[len] = 0; } /*конструктор qwString описание перенести данные во вновь создаваемый объект ввод &&tmp:другой компонент вывод нет */ qwString(qwString&& tmp) : len(tmp.len), buffer(tmp.buffer) { tmp.buffer = NULL; } /*конструктор qwString описание создать класс со строкой в 1 символ ввод data:строка вывод нет */ qwString (char data) { len = 1; buffer = new char[2]; buffer[0] = data; buffer[len] = 0; } /*конструктор qwString описание создать класс со значением строки ввод *data:строка вывод нет */ qwString (char *data) { len = strlen(data); buffer = new char[len + 1]; strcpy(buffer, data); buffer[len] = 0; } /*функция operator= описание организовать присвоение ввод other:другой компонент вывод нет */ qwString& operator=(const qwString& other) { destroy(); len = other.len; buffer = new char[len + 1]; strcpy(buffer, other.buffer); buffer[len] = 0; return *this; } /*функция operator= описание организовать присвоение c переносом ввод &&tmp:другой компонент вывод нет */ qwString& operator=(qwString&& tmp) { destroy(); len = tmp.len; buffer = tmp.buffer; tmp.buffer = NULL; return *this; } /*деструктор qwString описание удалить класс ввод нет вывод нет */ ~qwString () { destroy(); } /*функция viev описание показать значение ввод нет вывод нет */ void viev() { Serial.print(len); Serial.print(" "); Serial.print(buffer); Serial.println(); } }; /*функция для проверки перехвата конечного результата функции*/ qwString Create(char *const data) { qwString _data(data); return _data; } //-------Компоновка---------------------------- //------main()---------------------- void setup() { Serial.begin(9600); qwString AAA1 = Create("123"); // срабатывает конструктор перемещения AAA1.viev(); qwString AAA2 = AAA1; // срабатывает конструктор копирования AAA2.viev(); AAA2 = Create("456"); // срабатывает конструктор перемещения, затем оператор перемещения AAA2.viev(); AAA2 = AAA1; // срабатывает оператор присваивания AAA2.viev(); } void loop() { } /*Скетч использует 2618 байт (8%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 206 байт (10%) динамической памяти, оставляя 1842 байт для локальных переменных. Максимум: 2048 байт. */ПС: как работает не спрашивайте. Вроде понимаю, но похоже не очень твердо.
увековечил в железобетоне #48
Код
/**/ //------qwString--------------------------- //класс стринг class qwString { char *buffer; unsigned len;// длина строки боз последнего \0 /*функция destroy описание очистить кучу ввод нет вывод нет */ void destroy() { if (buffer) delete[] buffer; } public: /*конструктор qwString описание конструктор по умолчанию ввод *data:строка вывод нет */ qwString (): len(0) { buffer = new char; buffer[len] = 0; } /*конструктор qwString описание конструктор копирования ввод data:строка вывод нет */ qwString (qwString & obj) { len = obj.len; buffer = new char[len + 1]; strcpy(buffer, obj.buffer); buffer[len] = 0; } /*конструктор qwString описание перенести данные во вновь создаваемый объект ввод &&tmp:другой компонент вывод нет */ qwString(qwString&& tmp) : len(tmp.len), buffer(tmp.buffer) { tmp.buffer = NULL; } /*конструктор qwString описание создать класс со строкой в 1 символ ввод data:строка вывод нет */ qwString (char data) { len = 1; buffer = new char[2]; buffer[0] = data; buffer[len] = 0; } /*конструктор qwString описание создать класс со значением строки ввод *data:строка вывод нет */ qwString (char *data) { len = strlen(data); buffer = new char[len + 1]; strcpy(buffer, data); buffer[len] = 0; } /*функция operator= описание организовать присвоение ввод other:другой компонент вывод нет */ qwString& operator=(const qwString& other) { destroy(); len = other.len; buffer = new char[len + 1]; strcpy(buffer, other.buffer); buffer[len] = 0; return *this; } /*функция operator= описание организовать присвоение c переносом ввод &&tmp:другой компонент вывод нет */ qwString& operator=(qwString&& tmp) { destroy(); len = tmp.len; buffer = tmp.buffer; tmp.buffer = NULL; return *this; } /*деструктор qwString описание удалить класс ввод нет вывод нет */ ~qwString () { destroy(); } /*функция viev описание показать значение ввод нет вывод нет */ void viev() { Serial.print(len); Serial.print(" "); Serial.print(buffer); Serial.println(); } }; /*функция для проверки перехвата конечного результата функции*/ qwString Create(char *const data) { qwString _data(data); return _data; } //-------Компоновка---------------------------- //------main()---------------------- void setup() { Serial.begin(9600); qwString AAA1 = Create("123"); // срабатывает конструктор перемещения AAA1.viev(); qwString AAA2 = AAA1; // срабатывает конструктор копирования AAA2.viev(); AAA2 = Create("456"); // срабатывает конструктор перемещения, затем оператор перемещения AAA2.viev(); AAA2 = AAA1; // срабатывает оператор присваивания AAA2.viev(); } void loop() { } /*Скетч использует 2618 байт (8%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 206 байт (10%) динамической памяти, оставляя 1842 байт для локальных переменных. Максимум: 2048 байт. */Строки 73-80 (а также 86-92) - тпипчная ошибка реализации оператора присваивания. При такой реализации присваивание объекта класса самому себе непредсказуемо.
Класс qwStr строковая переменная(не полная буду наполнять)
/*qwStr.ino*/ //-----------qwStr-------------------------------------------- // класс строковая переменная class qwStr { protected: char *str; unsigned int len; unsigned int size; public: /*конструктор qwStr описание конструктор ввод value:строка вывод нет */ qwStr (const char *value = "") { size = len = strlen(value); str = new char[len + 1]; strncpy(str, value, len + 1); } /*конструктор qwStr описание конструктор ввод value:число типа char вывод нет */ explicit qwStr (const char value) { size = len = 1; str = new char[len + 1]; str[0] = value; str[1] = 0; } /*конструктор qwStr описание конструктор ввод value:число типа unsigned char base:10 - вывести в 10-м виде вывод нет */ explicit qwStr(unsigned char value, unsigned char base = 10) { size = len = 8 * sizeof(unsigned char); char buf[len + 1]; utoa(value, buf, base); *this = buf; } /*конструктор qwStr описание конструктор ввод value:число типа int base:10 - вывести в 10-м виде вывод нет */ explicit qwStr(int value, unsigned char base = 10) { size = len = 8 * sizeof(unsigned char) + 1; char buf[len + 1]; itoa(value, buf, base); *this = buf; } /*конструктор qwStr описание конструктор ввод value:число типа unsigned int base:10 - вывести в 10-м виде вывод нет */ explicit qwStr(unsigned int value, unsigned char base = 10) { size = len = 8 * sizeof(unsigned char); char buf[len + 1]; utoa(value, buf, base); *this = buf; } /*конструктор qwStr описание конструктор ввод value:число типа long base:10 - вывести в 10-м виде вывод нет */ explicit qwStr(long value, unsigned char base = 10) { size = len = 8 * sizeof(unsigned char) + 1; char buf[len + 1]; ltoa(value, buf, base); *this = buf; } /*конструктор qwStr описание конструктор ввод value:число типа unsigned long base:10 - вывести в 10-м виде вывод нет */ explicit qwStr(unsigned long value, unsigned char base = 10) { size = len = 8 * sizeof(unsigned char) + 1; char buf[len + 1]; ultoa(value, buf, base); *this = buf; } /*конструктор qwStr описание конструктор ввод value:число типа float base:10 - вывести в 10-м виде вывод нет */ explicit qwStr(float value, unsigned char decimalPlaces = 2) { size = len = 32; char buf[len + 1]; *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); } /*конструктор qwStr описание конструктор ввод value:число типа unsigned char base:10 - вывести в 10-м виде вывод нет */ explicit qwStr(double value, unsigned char decimalPlaces = 2) { size = len = 32; char buf[len + 1]; *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); } /*конструктор qwStr описание конструктор ввод &value:строка вывод нет */ qwStr (const qwStr & value) { size = len = value.size; str = new char[len + 1]; strncpy(str, value.str, len + 1); } /*конструктор qwStr описание перенести данные во вновь создаваемый объект ввод &&tmp:другой компонент вывод нет */ qwStr(qwStr&& tmp) : size(tmp.size), len(tmp.len), str(tmp.str) { tmp.str = NULL; } /*деструктор qwStr описание деструктор ввод нет вывод нет */ ~qwStr () { delete[] str; } /*функция operator= описание организовать присвоение значений текущего от нового ввод &tmp:новый компонент вывод нет */ qwStr& operator=(const qwStr &tmp) { if (this == &tmp) return *this; if (tmp.size > size) { delete[] str; size = len = tmp.size; str = new char[len + 1]; } strncpy(str, tmp.str, len + 1); return *this; } /*функция move описание перенести значение от нового к текущему с обнулением нового ввод &tmp:новый компонент вывод нет */ void qwStr::move(qwStr &tmp) { if (str) { //если текущий буфер не пустой if (size >= tmp.len) { // и если емкость текущего больше длины нового strcpy(str, tmp.str); // то просто скопировать len = tmp.len; tmp.len = 0; return; // и все } else delete[] str; } str = tmp.str;// перенос значения нового текущему size = tmp.size; len = tmp.len; tmp.str = NULL; // обнуление значений нового tmp.size = 0; tmp.len = 0; } /*функция operator= описание организовать присвоение ввод tmp:другой компонент вывод нет */ qwStr& operator=( qwStr &&tmp) { if (this != &tmp) move(tmp); return *this; } /*функция viev описание показать значение в Serial ввод нет вывод нет */ void viev() { Serial.print(len); Serial.print(" "); Serial.print(str); Serial.println(); } }; //------------------------------------------------------- qwStr aaa1(1234, HEX); qwStr aaa2(11.4); qwStr aaa3 = aaa2; qwStr aaa4(aaa1); //-----main()-------------------------------------------------- void setup() { Serial.begin(9600); aaa1.viev(); aaa2.viev(); aaa3.viev(); aaa4.viev(); } void loop() { } /*Скетч использует 4640 байт (14%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 222 байт (10%) динамической памяти, оставляя 1826 байт для локальных переменных. Максимум: 2048 байт. */Не всё так просто. Вы используете конструкцию "
if(this== &tmp)", но при этом оператор "==" у Вас не определён. Работать-то будет, но не всегда так, как Вы ожидаете - надеюсь, что Вы знаете, что делаете.Не всё так просто. Вы используете конструкцию "
if(this== &tmp)", но при этом оператор "==" у Вас не определён. Работать-то будет, но не всегда так, как Вы ожидаете - надеюсь, что Вы знаете, что делаете.Разумеется. Там и кроме этого куча ошибок. Но пока не смогу сжевать этот кактус, то о дальнейшем изучении С++ и ОПП говорить бессмысленно.
Вот еще один вариант класса строковой переменных
/**/ //--------qwStrA------------------- // класс строковая переменная qwStrA class qwStrA { protected: char *str; unsigned int len; unsigned int size; //** внутрение функции для обработки /*функция init() описание инициализация ввод нет вывод нет */ inline void init() { str = NULL; size = len = 0; } /*функция clear() описание очистка ввод нет вывод нет */ inline void clear() { if (str) free(str); init(); } /*функция reserve описание зарезервировать память ввод _size:какое кол-во памяти надо выделить вывод 1 Ок/ 0 error */ unsigned char reserve(unsigned int _size) { if (str && size >= _size) return 1;// выйти если памяти хватает if (changeSize(_size)) { // задать новый размер if (len == 0) str[0] = 0; // очистить содержимое return 1; } return 0; } /*функция changeSize описание изменить размер ввод newSize:новый размер вывод 1 Ок/ 0 error */ unsigned char changeSize(unsigned int newSize) { char *new_str = (char *)realloc(str, newSize + 1); if (new_str) { str = new_str; size = newSize; return 1; } return 0; } /*функция copy описание скопировать строку в класс ввод _str:строка _len:длина копирования вывод 1 Ок/ 1 error */ void copy(const char *_str, unsigned int _len) { if (!reserve(_len)) { clear(); return *this; } len = _len; strcpy(str, _str); return *this; } /*функция move описание перенести значение от нового к текущему с обнулением нового ввод &obj:новый компонент вывод нет */ void move(qwStrA &obj) { if (str) { //если текущий буфер не пустой if (size >= obj.len) { // и если емкость текущего больше длины нового strcpy(str, obj.str); // то просто скопировать len = obj.len; obj.len = 0; return; // и все } else delete[] str; } str = obj.str;// перенос значения нового текущему size = obj.size; len = obj.len; obj.str = NULL; // обнуление значений нового obj.size = 0; obj.len = 0; } public: //** конструкторы и деструктор /* конструктор qwStrA описание создать объект по знач строковую перем ввод *obj: указатель на строковую перем вывод нет */ qwStrA(const char *obj = "") { init(); if (obj) copy(obj, strlen(obj)); } /* конструктор qwStrA описание конструктор копирования ввод *obj: указатель на перем для копирования вывод нет */ qwStrA(const qwStrA &obj) { init(); *this = obj; } /* конструктор qwStrA описание конструктор ввод c: переменная char вывод нет */ explicit qwStrA(char c) { init(); char buf[2]; buf[0] = c; buf[1] = 0; *this = buf; } /*конструктор qwStr описание конструктор ввод value:число типа unsigned char base:10 - вывести в 10-м виде вывод нет */ explicit qwStrA(unsigned char value, unsigned char base = 10) { init(); char buf[1 + 8 * sizeof(unsigned char)]; utoa(value, buf, base); *this = buf; } /* конструктор qwStrA описание конструктор ввод value:число типа int base:10 - вывести в 10-м виде вывод нет */ explicit qwStrA(int value, unsigned char base = 10) { init(); char buf[2 + 8 * sizeof(int)]; itoa(value, buf, base); *this = buf; } /* конструктор qwStrA описание конструктор ввод value:число типа unsigned int base:10 - вывести в 10-м виде вывод нет */ explicit qwStrA(unsigned int value, unsigned char base = 10) { init(); char buf[1 + 8 * sizeof(unsigned int)]; utoa(value, buf, base); *this = buf; } /* конструктор qwStrA описание конструктор ввод value:число типа long base:10 - вывести в 10-м виде вывод нет */ explicit qwStrA(long value, unsigned char base = 10) { init(); char buf[2 + 8 * sizeof(long)]; ltoa(value, buf, base); *this = buf; } /* конструктор qwStrA описание конструктор ввод value:число типа unsigned long base:10 - вывести в 10-м виде вывод нет */ explicit qwStrA(unsigned long value, unsigned char base = 10) { init(); char buf[1 + 8 * sizeof(unsigned long)]; ultoa(value, buf, base); *this = buf; } /* конструктор qwStrA описание конструктор ввод value:число типа float base:10 - вывести в 10-м виде вывод нет */ explicit qwStrA(float value, unsigned char base = 2) { init(); char buf[33]; *this = dtostrf(value, base + 2, base, buf); } /* конструктор qwStrA описание конструктор ввод value:число типа double base:10 - вывести в 10-м виде вывод нет */ explicit qwStrA(double value, unsigned char base = 2) { init(); char buf[33]; *this = dtostrf(value, base + 2, base, buf); } /* деструктор ~qwStrA() описание уничтожить объект ввод нет вывод нет */ ~qwStrA() { free(str); } //** функция operator = /*функция operator= описание организовать присвоение ввод obj:другой компонент вывод нет */ qwStrA & operator = (qwStrA &&obj) { if (this != &obj) move(obj); return *this; } /*функция operator= описание организовать присвоение значений текущего от нового ввод &obj:новый компонент вывод нет */ qwStrA & operator=(const qwStrA &obj) { if (this == &obj) return *this; if (obj.size > size) { delete[] str; size = len = obj.size; str = new char[len + 1]; } strncpy(str, obj.str, len + 1); return *this; } /*функция operator= описание организовать присвоение значений текущего от нового ввод &tmp:новое значение в *char вывод нет */ qwStrA & operator=(const char *obj) { if (obj) copy(obj, strlen(obj)); else clear(); return *this; } //** функции перевода значения в другой формат /*функция toInt описание перевести значение в long ввод нет вывод результат:long */ long toInt(void) const { if (str) return atol(str); return 0; } /*функция toFloat описание перевести значение в float ввод нет вывод результат:float */ float toFloat(void) const { return float(toDouble()); } /*функция toDouble описание перевести значение в double ввод нет вывод результат:double */ double toDouble(void) const { if (str) return atof(str); return 0; } //** функции сравнения /*функция compareTo описание сравнить с другим объектом ввод *obj: другой объект вывод 1 - Верно / 0 - Неверно */ int compareTo(const qwStrA &obj) const { if (!str || !obj.str) { if (obj.str && obj.len > 0) return 0 - *(unsigned char *)obj.str; if (str && len > 0) return *(unsigned char *)str; return 0; } return strcmp(str, obj.str); } /*функция equals описание сравнить с другим объектом ввод *obj: другой объект вывод 1 - Верно / 0 - Неверно */ unsigned char equals(const qwStrA &obj) const { return (len == obj.len && compareTo(obj) == 0); } /*функция equals описание сравнить со строчной переменной ввод *obj: строчная переменная для сравнения вывод 1 - Верно / 0 - Неверно */ unsigned char equals(const char *obj) const { if (len == 0) return (obj == NULL || *obj == 0); if (obj == NULL) return str[0] == 0; return strcmp(str, obj) == 0; } /*функция operator == описание сравнить со строчной переменной ввод *obj: строчная переменная для сравнения вывод 1 - Верно / 0 - Неверно */ unsigned char operator == (const qwStrA &obj) const { return equals(obj); } /*функция operator == описание сравнить со строчной переменной ввод *obj: строчная переменная для сравнения вывод 1 - Верно / 0 - Неверно */ unsigned char operator == (const char *obj) const { return equals(obj); } /*функция operator != описание сравнить со строчной переменной ввод &obj: строчная переменная для сравнения вывод 1 - Верно / 0 - Неверно */ unsigned char operator != (const qwStrA &obj) const { return !equals(obj); } /*функция operator != описание сравнить со строчной переменной ввод *obj: строчная переменная для сравнения вывод 1 - Верно / 0 - Неверно */ unsigned char operator != (const char *obj) const { return !equals(obj); } //** функции показ /*функция viev описание показать значение в Serial ввод нет вывод нет */ void viev() { Serial.print(len); Serial.print(" "); Serial.print(str); Serial.println(); } }; //--------Компоновка------------------- qwStrA aaa1(123); qwStrA aaa2 = "234"; //-----main()---------------------- void setup() { Serial.begin(9600); aaa1.viev(); aaa2.viev(); if (aaa1 == aaa2) Serial.println("TRUE"); if (aaa1 != aaa2) Serial.println("FALSE"); } void loop() {} /*Скетч использует 3478 байт (10%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 226 байт (11%) динамической памяти, оставляя 1822 байт для локальных переменных. Максимум: 2048 байт. */Строки 64 и 68 выглядят странно, учитывая, что функция описана как void. Остальное не смотрел.
Строки 64 и 68 выглядят странно, учитывая, что функция описана как void. Остальное не смотрел.
Ну да . В Ардуно вообще код идет такой
String & String::copy(const char *cstr, unsigned int length) { if (!reserve(length)) { invalidate(); return *this; } len = length; strcpy(buffer, cstr); return *this; }Но метод protected: и возвращаемое значение не используется в дальнейшем внутри класса
Ну да . В Ардуно вообще код идет такой
Этой фразы я не понял. Причём тут Ардуино? То, что разработчики IDE по умолчанию заткнули warning'и, так я Вам уже советовал включить - увидели бы сообщение.
Часто идет вопрос : Как заменить delay() на millis(). Две несхожые функции. Это как слона менять на коня. Попробую предложить свой вариант.
Вот есть код.
/**/ //------------------------------ //---Компановка------------------- const byte led1 =/*пин 1 светодиода*/2; const byte led2 =/*пин 1 светодиода*/3; const byte led3 =/*пин 1 светодиода*/4; void setupLeds() { pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); } void runLeds() { digitalWrite(led1, HIGH); delay(200); digitalWrite(led1, LOW); digitalWrite(led2, HIGH); delay(200); digitalWrite(led2, LOW); digitalWrite(led3, HIGH); delay(200); digitalWrite(led3, LOW); } //----main-------------------------- void setup() { setupLeds(); runLeds(); } void loop() { } /*Скетч использует 1000 байт (3%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт. */Ну и результат обмена.
/**/ unsigned long mill; //------------------------------ const byte led1 =/*пин 1 светодиода*/2; const byte led2 =/*пин 2 светодиода*/3; const byte led3 =/*пин 3 светодиода*/4; void setupLeds() { pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); } void runLeds(bool stat) { static unsigned long past; static byte step; if (stat) step = 0; switch (step) { case 0: digitalWrite(led1, HIGH); past = mill; step = 1; break; case 1: if (mill - past >= 200) { // delay(200); digitalWrite(led1, LOW); digitalWrite(led2, HIGH); past = mill; step = 2; } break; case 2: if (mill - past >= 200) { // delay(200); digitalWrite(led2, LOW); digitalWrite(led3, HIGH); past = mill; step = 3; } break; case 3: if (mill - past >= 200) { // delay(200); digitalWrite(led3, LOW); step = 4; } break; } } //----main-------------------------- void setup() { setupLeds(); runLeds(1); } void loop() { mill = millis(); runLeds(0); } /*Скетч использует 1150 байт (3%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 18 байт (0%) динамической памяти, оставляя 2030 байт для локальных переменных. Максимум: 2048 байт. */Понятно что код непривычен для тех кто мыслит процедурно. Одна и таже процедура(функция) запускается в версии с 1 и в версии с 0. И в setup() и в loop() За то не размазывается по программе как после фугасной бомбы
Человек просил помощи, а вы ему классы, не занимайтесь ерундой.
Человек просил помощи, а вы ему классы, не занимайтесь ерундой.
Где вы видели там классы.Я ему метод, как решать такие проблемы. причем без классов. Знание методы банально упрощает решение задачи.
Ну классов там действительно нету, но ерунды достаточно. И наибольшая в том, что для решения банальнейшего вопроса выдается такой кривой код. А потом удивляемся, почему на форуме простыни кода забитого повторяющимися фрагментами и прочей ерундой. Дак их так учили здесь, примеры такие. Если уж Вы qwone, взялись за неимоверно тяжкую задачу убрать делеи, то предлагайте нормальное решение, а не то за которое будут чмырить позже. Публикуемый код должен быть образцем, а не пробой пера, пробу пера не обязательно людям показывать (за исключением случая когда надо чтоб код оценили и поругали), а тем более советовать как решение. А то ж народ привыкнет так писать.
Смотрю ваш код, нового и оригинального в нем ровно 0. А 3 минуты правки и 2 минуты на тест позволяют преобразовать его, сократив размер скомпилированого на 10%. (с 1300 до 1070 байт) Всего два момента легкой оптимизацией, а структура кода стала более явной, обработчики завершения временных интервалов каждый в своей функции, механизм легко маштабируем и т.д. Так что не публикуйте кривое и сырое, оставте это удовольствие велосипедостроителю ;)
/**/ byte mill; //------------------------------ const byte led1 =/*пин 1 светодиода*/2; const byte led2 =/*пин 2 светодиода*/3; const byte led3 =/*пин 3 светодиода*/4; void setupLeds() { pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); } void FnLED0(void) { digitalWrite(led1, HIGH); } void FnLED1(void) { digitalWrite(led1, LOW); digitalWrite(led2, HIGH); } void FnLED2(void) { digitalWrite(led1, LOW); digitalWrite(led2, HIGH); } void FnLED3(void) { digitalWrite(led3, LOW); } typedef void (*pFnLed)(void); pFnLed arrLED[]={FnLED0, FnLED1, FnLED2, FnLED3}; void runLeds(bool stat) { static byte past; static byte step; if (stat) step = 0; if(((step) && ((byte)(mill - past) < 200)) || (step>3)) return; arrLED[step](); past = mill; step++; } //----main-------------------------- void setup() { setupLeds(); runLeds(1); } void loop() { mill = millis(); runLeds(0); } /*Скетч использует 1150 байт (3%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 18 байт (0%) динамической памяти, оставляя 2030 байт для локальных переменных. Максимум: 2048 байт. */Logik. Тот скетч я специально не пытался оптимизировать. Я просто показал как переходить с delay на millis хотя бы за счет простыней.
Вот вам еще одна простыня и музакальная пауза одновременно
/* пин 2 -> кнопка на землю пин 8 -> динамик */ unsigned long mill;//переменая для millis() //------------music---------------------------------------- const byte tonePin =/*пин*/8; /* функция music описание проиграть мелодию ввод num: 0-текучка / 1-старт/2-стоп вывод нет */ void music(byte num) { static byte step = 66; static unsigned long past; if (num == 1) step = 0; if (num == 2) step = 66; if (step == 0) { step++; past = mill; tone(tonePin, 329, 338); } if (step == 1 && mill - past >= 417) { step++; past = mill; tone(tonePin, 329, 1012); } if (step == 2 && (millis() - past) >= 1250) { ++step; past = mill; tone(tonePin, 440, 169); } if (step == 3 && mill - past >= 207) { ++step; past = mill; tone(tonePin, 391, 169); } if (step == 4 && mill - past >= 209) { ++step; past = mill; tone(tonePin, 349, 675); } if (step == 5 && mill - past >= 833) { ++step; past = mill; tone(tonePin, 293, 338); } if (step == 6 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 261, 338); } if (step == 7 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 246, 338); } if (step == 8 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 329, 675); } if (step == 9 && mill - past >= 833) { ++step; past = mill; tone(tonePin, 293, 338); } if (step == 10 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 261, 338); } if (step == 11 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 220, 675); } if (step == 12 && mill - past >= 833) { ++step; past = mill; tone(tonePin, 391, 338); } if (step == 13 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 391, 506); } if (step == 14 && mill - past >= 625) { ++step; past = mill; tone(tonePin, 261, 506); } if (step == 15 && mill - past >= 625) { ++step; past = mill; tone(tonePin, 329, 338); } if (step == 16 && mill - past >= 625) { ++step; past = mill; tone(tonePin, 391, 338); } if (step == 17 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 523, 338); } if (step == 18 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 493, 338); } if (step == 19 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 440, 338); } if (step == 20 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 415, 1350); } if (step == 21 && mill - past >= 2917) { ++step; past = mill; tone(tonePin, 329, 338); } if (step == 22 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 523, 675); } if (step == 23 && mill - past >= 833) { ++step; past = mill; tone(tonePin, 493, 338); } if (step == 24 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 523, 338); } if (step == 25 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 493, 338); } if (step == 26 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 440, 675); } if (step == 27 && mill - past >= 833) { ++step; past = mill; tone(tonePin, 329, 338); } if (step == 28 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 440, 338); } if (step == 29 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 440, 338); } if (step == 30 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 391, 338); } if (step == 31 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 440, 338); } if (step == 32 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 391, 338); } if (step == 33 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 349, 675); } if (step == 34 && mill - past >= 833) { ++step; past = mill; tone(tonePin, 349, 338); } if (step == 35 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 329, 675); } if (step == 36 && mill - past >= 833) { ++step; past = mill; tone(tonePin, 391, 338); } if (step == 37 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 349, 338); } if (step == 38 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 329, 338); } if (step == 39 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 293, 338); } if (step == 40 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 261, 338); } if (step == 41 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 246, 338); } if (step == 42 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 220, 1350); } if (step == 43 && mill - past >= 2917) { ++step; past = mill; tone(tonePin, 329, 338); } if (step == 44 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 523, 675); } if (step == 45 && mill - past >= 833) { ++step; past = mill; tone(tonePin, 493, 338); } if (step == 46 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 523, 338); } if (step == 47 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 493, 338); } if (step == 48 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 440, 675); } if (step == 49 && mill - past >= 833) { ++step; past = mill; tone(tonePin, 329, 338); } if (step == 50 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 440, 338); } if (step == 51 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 440, 338); } if (step == 52 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 391, 338); } if (step == 53 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 440, 338); } if (step == 54 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 391, 338); } if (step == 55 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 349, 675); } if (step == 56 && mill - past >= 833) { ++step; past = mill; tone(tonePin, 349, 338); } if (step == 57 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 329, 675); } if (step == 58 && mill - past >= 833) { ++step; past = mill; tone(tonePin, 391, 338); } if (step == 59 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 349, 338); } if (step == 60 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 329, 338); } if (step == 61 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 293, 338); } if (step == 62 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 261, 338); } if (step == 63 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 246, 338); } if (step == 64 && mill - past >= 417) { ++step; past = mill; tone(tonePin, 220, 1350); } if (step == 65 && mill - past >= 1500) { ++step; } } //---------Cl_Btn------------------------------------------------- // класс кнопка class Cl_Btn { const byte pin; void (*Do)(); bool btn, oldBtn = 1; bool bounce = 0; unsigned long past; public: /*конструктор Cl_Btn описание создать объект ввод _pin: нога _inv: инверсия выхода вывод нет */ Cl_Btn(byte _pin, void (_Do)()): pin(_pin), Do(_Do) {} /*функция setup описание иницилизация ввод нет вывод нет */ void setup() { pinMode(pin, INPUT); btn = digitalRead(pin); } /*функция loop описание для нормальной работы вставить в тело loop() ввод нет вывод нет */ void loop() { bool newBtn = digitalRead(pin); if (bounce && newBtn != btn) { bounce = 1; } if (!bounce && mill - past >= 10) { past = mill; bounce = 0; oldBtn = btn; btn = newBtn; if (!btn && oldBtn) (*Do)(); } } }; //----компановка------------------------------------------------ void Do_Btn() { music(1);// проиграть музыку } Cl_Btn Btn(/*пин*/2,/*обработчик*/Do_Btn); //---mail()------------------------------------------------- void setup() { Btn.setup(); } void loop() { mill = millis(); Btn.loop(); music(0); } /*Скетч использует 9694 байт (30%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 50 байт (2%) динамической памяти, оставляя 1998 байт для локальных переменных. Максимум: 2048 байт. */Зачем мне эта грязная простыня? Вы ща как Клапауций, ныть будете "ну глянь, ну попробуй"? Так упреждаю. Я глянул раз, и у него и у Вас. Больше не стоит время терять. Глянул, сделал вывод изложил и даже проилюстрировал. А Ваш уровень писания кода - ваша проблема, плохо что другие на ваш код смотрят и себе так пишут. Хотя и это тоже вобщем не моя проблема ;)
Тема плавно переходит в сборище говнокода от qwone. Но зато наглядно видно что не в классах дело, ох не в классах.
Logik. Меня удивляет ,то что вы здесь пытаетесь найти для себя полезное. Вы ковыряетесь в Си++ больше меня. Это вы должны выкладывать код, а я искать что-то полезное. Но похоже я такой темы не наблюдаю. Может я плохо ищу, или в гугл вашу тему обходит стороной. А то что тема исчерпала себя я давно знаю. Что мог то рассказал. А новое оно очень сырое. Вот у меня вопрос вываливать это новое сюда и слышать, что я говнокодю или работать в стол. Похоже последнее вернее всего.
Вы ща как Клапауций, ныть будете "ну глянь, ну попробуй"? Так упреждаю. Я глянул раз, и у него и у Вас. Больше не стоит время терять.
тогда, иди на йух, упреждатель хренов - напиши библиотеку для кнопки лучше, чем у меня.
делов то.
или, смени ник на Дъартаньян.
Logik. Меня удивляет ,то что вы здесь пытаетесь найти для себя полезное. Вы ковыряетесь в Си++ больше меня. Это вы должны выкладывать код, а я искать что-то полезное. Но похоже я такой темы не наблюдаю. Может я плохо ищу, или в гугл вашу тему обходит стороной. А то что тема исчерпала себя я давно знаю. Что мог то рассказал. А новое оно очень сырое. Вот у меня вопрос вываливать это новое сюда и слышать, что я говнокодю или работать в стол. Похоже последнее вернее всего.
Первый раз открывая тему действительно допускал что чего толковоги и оригинального увижу. Иначе бы и не открывал разумеется. Мой код найти не можете? Странно, его здесь много есть, например из последнего http://arduino.ru/forum/apparatnye-voprosy/dtmf-gsm#comment-302080 . Захотите найти - найдете. Например по работе с модемом А8 большой и оч. интересный код публиковал. Так что упрек не по адресу.
А сырое и кривое точно публиковать не надо, за исключением случая чтоб поругали. Сырого и кривого и на гитхабе теперь валом ;)
Тема выдохлась. И скатилась в замену делея на милис. Напомню только про http://arduino.ru/forum/programmirovanie/klassy-arduino-po-qwone-dlya-ch.... Возможно это было бы интересней. И для Вас точно полезней, в ООП продвинулись бы. Например написали бы абстрактный класс реализующий вызов метода через интервалы времени, а на его базе и свой пример последний музыкальный, описав мелодию масивом констант разумеется а не тем бредовым свичем.
Про астрактный класс (данных или объекта обрабатывающие эти данные )могу сказать одно. Не все что хорошо в теории, хорошо ложится в код. В Гардвадской организации и небольшой памяти точно. Опять я специально привел тот бредовый код , что бы выложить получше сейчас. Ведь пока не видишь разницы думаешь, что есть лучше.
/* пин 2 -> кнопка на землю пин 8 -> динамик */ unsigned long mill;//переменая для millis() //------------music---------------------------------------- const byte tonePin =/*пин*/8; const unsigned int melody[] = { // тон, длительность ноты ,полная длительность 329, 338, 417 , 329, 1012, 1250 , 440, 169, 207 , 391, 169, 209 , 349, 675, 833 , 293, 338, 417 , 261, 338, 417 , 246, 338, 417 , 329, 675, 833 , 293, 338, 417 , 261, 338, 417 , 220, 675, 833 , 391, 338, 417 , 391, 506, 625 , 261, 506, 625 , 329, 338, 625 , 391, 338, 417 , 523, 338, 417 , 493, 338, 417 , 440, 338, 417 , 415, 1350, 2917 , 329, 338, 417 , 523, 675, 833 , 493, 338, 417 , 523, 338, 417 , 493, 338, 417 , 440, 675, 833 , 329, 338, 417 , 440, 338, 417 , 440, 338, 417 , 391, 338, 417 , 440, 338, 417 , 391, 338, 417 , 349, 675, 833 , 349, 338, 417 , 329, 675, 833 , 391, 338, 417 , 349, 338, 417 , 329, 338, 417 , 293, 338, 417 , 261, 338, 417 , 246, 338, 417 , 220, 1350, 2917 , 329, 338, 417 , 523, 675, 833 , 493, 338, 417 , 523, 338, 417 , 493, 338, 417 , 440, 675, 833 , 329, 338, 417 , 440, 338, 417 , 440, 338, 417 , 391, 338, 417 , 440, 338, 417 , 391, 338, 417 , 349, 675, 833 , 349, 338, 417 , 329, 675, 833 , 391, 338, 417 , 349, 338, 417 , 329, 338, 417 , 293, 338, 417 , 261, 338, 417 , 246, 338, 417 , 220, 1350, 1500 }; /* функция music описание проиграть мелодию ввод num: 0-текучка / 1-старт/2-стоп вывод нет */ void music(byte num) { const int temPlay = 2; // темр игры static byte step = 66; static byte stepEnd = 0 ; static unsigned long past, time; if (num == 1) { stepEnd = sizeof( melody) / sizeof(unsigned int) / 3; step = 0; tone(tonePin, melody[0], melody[1] / temPlay); time = melody[2] / temPlay; past = mill; } if (num == 2) step = 100; if (step <= stepEnd && mill - past >= time) { step++; past = mill; tone(tonePin, melody[step * 3], melody[step * 3 + 1] / temPlay); time = melody[step * 3 + 2] / temPlay; } } //---------Cl_Btn------------------------------------------------- // класс кнопка class Cl_Btn { const byte pin; void (*Do)(); bool btn, oldBtn = 1; bool bounce = 0; unsigned long past; public: /*конструктор Cl_Btn описание создать объект ввод _pin: нога _inv: инверсия выхода вывод нет */ Cl_Btn(byte _pin, void (_Do)()): pin(_pin), Do(_Do) {} /*функция setup описание иницилизация ввод нет вывод нет */ void setup() { pinMode(pin, INPUT); btn = digitalRead(pin); } /*функция loop описание для нормальной работы вставить в тело loop() ввод нет вывод нет */ void loop() { bool newBtn = digitalRead(pin); if (bounce && newBtn != btn) { bounce = 1; } if (!bounce && mill - past >= 10) { past = mill; bounce = 0; oldBtn = btn; btn = newBtn; if (!btn && oldBtn) (*Do)(); } } }; //----компановка------------------------------------------------ void Do_Btn() { music(1);// проиграть музыку } Cl_Btn Btn(/*пин*/2,/*обработчик*/Do_Btn); //---mail()------------------------------------------------- void setup() { Btn.setup(); } void loop() { mill = millis(); Btn.loop(); music(0); } /*Скетч использует 3558 байт (11%) памяти устройства. Всего доступно 32256 байт. Глобальные переменные используют 445 байт (21%) динамической памяти, оставляя 1603 байт для локальных переменных. Максимум: 2048 байт. */Лучше. Только melody ну никак не массив интов. Массив должен состоять из однотипных величин, а у вас там вперемешку частоты и длительности (тот факт что они инт влезли еще не означает их однотипность). Заведите соответствующую структуру и melody массив структур. Строки 88-91 и 96-98 подозрительно похожи, не так ли? Ну и
voidmusic(bytenum)тоже полезно в класс, аналогичный Btn. А если бы они оба наследовали один базовый класс с абстрактным сетапом и лопом то все бы стало еще интересней.Про архитектуру и как ложится - не переживайте, ляжет. Только напишите ;)
один базовый класс с абстрактным сетапом и лопом
Про это ТС говорили ещё месяц назад, но, похоже, здесь принципиальное неприятие :)
Вот у меня вопрос вываливать это новое сюда и слышать, что я говнокодю или работать в стол. Похоже последнее вернее всего.
согласен