Официальный сайт компании Arduino по адресу arduino.cc
Впихнуть невпихуемое
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Здравствуйте уважаемые Копперфильды !
Мне снова понадобилась ваша помощь.
Захотелось мне изобрести очень или не очень умный таймер для управлением водонагревателем. Вроде ничего сложного.Начал с написания меню и даже написал.Задача - установить время и дату. Работает.
НО !!! Заметил и ужаснулся - ведь это фактически четверть меню , а будет еще код управления .
вот
"Скетч использует 10 108 байт (32%) памяти устройства. Всего доступно 30 720 байт.Глобальные переменные используют 1 508 байт (73%) динамической памяти, оставляя 540 байт для локальных переменных. Максимум: 2 048 байт."
73% памяти съедено ХЗ чем. Ну не совсем ХЗ- библиотеками.
Вот код
#include <EEPROM.h> // подключаем библиотеку EEPROM #include <DS1307.h> #include "lcd1202.h" #include "ClickButton.h" LCD1202 lcd(8, 7, 6, 5); // RST, CS, MOSI, SCK DS1307 rtc(SDA, SCL); #define LED 11 // пин светодиода const int LBUTTONPIN = 10; const int RBUTTONPIN = 9; byte SetTimeH = 0; byte SetTimeMIN = 0; byte F_SetTime = 1; byte F_SetTimeH = 0; byte F_SetTimeMIN = 0; byte SetDataDay = 1; byte SetDataMonth = 1; byte SetDataGod = 19; byte F_SetData = 1; byte F_SetDataDay = 0; byte F_SetDataMonth = 0; byte F_SetDataGod = 0; ClickButton LBUTTON(LBUTTONPIN, LOW, CLICKBTN_PULLUP); ClickButton RBUTTON(RBUTTONPIN, LOW, CLICKBTN_PULLUP); void setup() { pinMode(LED, OUTPUT); LBUTTON.maxPresses = 1; // max button multiclick count LBUTTON.debounceTime = 5; // Debounce timer in ms LBUTTON.multiclickTime = 250; // Time limit for multi clicks LBUTTON.heldDownTime = 1000; // time until "held-down clicks" register lcd.Inicialize(); //Инициализация дисплея lcd.Clear_LCD(); //Очистка дисплея // Initialize the rtc object rtc.begin(); rtc.setSQWRate(SQW_RATE_1); // Задать частоту на выводе SQW равной 1Гц // Set the clock to run-mode rtc.halt(false); // The following lines can be uncommented to set the time //rtc.setDOW(FRIDAY); // Set Day-of-Week to SUNDAY //rtc.setTime(16, 40, 0); // Set the time to 12:00:00 (24hr format) //rtc.setDate(14, 4, 2019); // Set the date to October 3th, 2010 //*********************************************************************************************************************** //rtc.setDate(18, 4, 2019); // Установка даты //rtc.setTime(23, 44, 0); // Установка времени //********************************************************************************************************************* // установка время //*********************************************************************************************************************** lcd.print(0, 15, 1, " ВРЕМЯ "); lcd.print(22, 27, 1, rtc.getTimeStr()); lcd.print(15, 41, 1, "УСТАНОВИТЬ ?"); lcd.print(0, 60, 0, " да "); lcd.print(65, 60, 0, " нет ");; ramka (); while (F_SetTime == 1) { LBUTTON.Update(); RBUTTON.Update(); if (RBUTTON.click == 1) { F_SetTime = 0; } if (LBUTTON.click == 1) { F_SetTimeH = 1; F_SetTimeMIN = 1; F_SetTime = 0; } lcd.Update(); } lcd.Clear_LCD(); lcd.Update(); //*********************************************************************************************************************** // установка время (ЧАСЫ) //*********************************************************************************************************************** ramka (); lcd.print(0, 15, 1, " ВРЕМЯ "); lcd.print(22, 27, 1, rtc.getTimeStr()); lcd.print(0, 60, 0, " + "); lcd.print(65, 60, 0, " ok ");; lcd.print(45, 46, 1, ":"); lcd.print(55, 46, 1, SetTimeMIN); while (F_SetTimeH == 1) { LBUTTON.Update(); RBUTTON.Update(); lcd.print(30, 46, 0, SetTimeH); lcd.Update(); if (LBUTTON.click == 1) { // установка часов digitalWrite(LED, !digitalRead(LED)); SetTimeH++; } if (SetTimeH > 23) { SetTimeH = 0; } if (RBUTTON.click == 1) { F_SetTimeH = 0 ; } } //*********************************************************************************************************************** lcd.Clear_LCD(); lcd.Update(); //*********************************************************************************************************************** // установка время (МИНУТЫ) //*********************************************************************************************************************** ramka (); lcd.print(0, 15, 1, " ВРЕМЯ "); lcd.print(22, 27, 1, rtc.getTimeStr()); lcd.print(0, 60, 0, " + "); lcd.print(65, 60, 0, " ok ");; lcd.print(30, 46, 1, SetTimeH); lcd.print(45, 46, 1, ":"); while (F_SetTimeMIN == 1) { LBUTTON.Update(); RBUTTON.Update(); lcd.print(55, 46, 0, SetTimeMIN); lcd.Update(); if (LBUTTON.click == 1) { // установка часов digitalWrite(LED, !digitalRead(LED)); SetTimeMIN++; } if (SetTimeMIN > 59) { SetTimeMIN = 0; } if (RBUTTON.click == 1) { F_SetTimeMIN = 0 ; } rtc.setTime(SetTimeH, SetTimeMIN, 0); // Установка времени } lcd.Clear_LCD(); lcd.Update(); lcd.print(25, 10, 1, " ВРЕМЯ"); lcd.print(15, 22, 1, "УСТАНОВЛЕНО"); lcd.print(22, 35, 1, rtc.getTimeStr()); lcd.Update(); delay (2000); //*********************************************************************************************************************** lcd.Clear_LCD(); lcd.Update(); //*********************************************************************************************************************** //*********************************************************************************************************************** // установка дата //*********************************************************************************************************************** ramka (); lcd.print(0, 15, 1, " ДАТА "); lcd.print(22, 27, 1, rtc.getDateStr()); lcd.print(15, 41, 1, "УСТАНОВИТЬ ?"); lcd.print(0, 60, 0, " да "); lcd.print(65, 60, 0, " нет ");; while (F_SetData == 1) { LBUTTON.Update(); RBUTTON.Update(); if (RBUTTON.click == 1) { F_SetData = 0; } if (LBUTTON.click == 1) { F_SetDataDay = 1; F_SetDataMonth = 1; F_SetDataGod = 1; F_SetData = 0; } lcd.Update(); } //*********************************************************************************************************************** lcd.Clear_LCD(); lcd.Update(); //*********************************************************************************************************************** //*********************************************************************************************************************** // установка дата (число) //*********************************************************************************************************************** lcd.print(0, 15, 1, " ДАТА "); ramka (); lcd.print(22, 27, 1, rtc.getDateStr()); lcd.print(0, 60, 0, " + "); lcd.print(65, 60, 0, " ok ");; lcd.print(10, 46, 1, "Число"); lcd.print(45, 46, 1, ":"); while (F_SetDataDay == 1) { LBUTTON.Update(); RBUTTON.Update(); lcd.print(55, 46, 0, SetDataDay); lcd.Update(); if (LBUTTON.click == 1) { digitalWrite(LED, !digitalRead(LED)); SetDataDay++; } if (SetDataDay > 31) { SetDataDay = 1; } if (RBUTTON.click == 1) { F_SetDataDay = 0 ; } } //*********************************************************************************************************************** lcd.Clear_LCD(); lcd.Update(); //*********************************************************************************************************************** // установка дата (Месяц) //*********************************************************************************************************************** lcd.print(0, 15, 1, " ДАТА "); ramka (); lcd.print(22, 27, 1, rtc.getDateStr()); lcd.print(0, 60, 0, " + "); lcd.print(65, 60, 0, " ok ");; lcd.print(10, 46, 1, "Месяц"); lcd.print(45, 46, 1, ":"); while (F_SetDataMonth == 1) { LBUTTON.Update(); RBUTTON.Update(); lcd.print(55, 46, 0, SetDataMonth); lcd.Update(); if (LBUTTON.click == 1) { digitalWrite(LED, !digitalRead(LED)); SetDataMonth++; } if (SetDataMonth > 12) { SetDataMonth = 1; } if (RBUTTON.click == 1) { F_SetDataMonth = 0 ; } } //*********************************************************************************************************************** lcd.Clear_LCD(); lcd.Update(); //*********************************************************************************************************************** // установка дата (Год) //*********************************************************************************************************************** lcd.print(0, 15, 1, " ДАТА "); ramka (); lcd.print(22, 27, 1, rtc.getDateStr()); lcd.print(0, 60, 0, " + "); lcd.print(65, 60, 0, " ok ");; lcd.print(10, 46, 1, "Год"); lcd.print(45, 46, 1, ":"); while (F_SetDataGod == 1) { LBUTTON.Update(); RBUTTON.Update(); lcd.print(55, 46, 0, SetDataGod); lcd.Update(); if (LBUTTON.click == 1) { digitalWrite(LED, !digitalRead(LED)); SetDataGod++; } if (SetDataGod > 30) { SetDataGod = 19; } if (RBUTTON.click == 1) { F_SetDataGod = 0 ; } rtc.setDate(SetDataDay, SetDataMonth, 2000 + SetDataGod); // Установка даты } lcd.Clear_LCD(); lcd.Update(); lcd.print(25, 10, 1, " ДАТА"); lcd.print(15, 22, 1, "УСТАНОВЛЕНА"); lcd.print(22, 35, 1, rtc.getDateStr()); lcd.Update(); delay (2000); F_SetTime = 1; F_SetTimeH = 0; F_SetTimeMIN = 0; F_SetData = 1; F_SetDataDay = 0; F_SetDataMonth = 0; F_SetDataGod = 0; //*********************************************************************************************************************** lcd.Clear_LCD(); lcd.Update(); } void loop() { lcd.print_1607(0, 1, 1, rtc.getTimeStr()); // печать время lcd.print_1607(0, 0, 1, rtc.getDateStr()); // печать дата lcd.print_1607(0, 2, 1, rtc.getDOWStr()); // печать день недели lcd.Update(); digitalWrite(LED, !digitalRead(LED)); } void ramka () { // lcd.drawRect(0, 0, 96, 13, 1); //Рисуем прямоугольник по координатам x, y, высота, ширина, цвет //lcd.drawRect(0, 12, 96, 13, 1); //Рисуем прямоугольник по координатам x, y, высота, ширина, цвет lcd.drawRect(0, 24, 96, 13, 1); //Рисуем прямоугольник по координатам x, y, высота, ширина, цвет lcd.print(0, 3, 1, " НАСТРОЙКА "); }
А вот так жрут память библиотеки .Половину памяти !!! Тут так "Скетч использует 3 112 байт (10%) памяти устройства. Всего доступно 30 720 байт.
#include <EEPROM.h> // подключаем библиотеку EEPROM #include <DS1307.h> #include "lcd1202.h" #include "ClickButton.h" LCD1202 lcd(8, 7, 6, 5); // RST, CS, MOSI, SCK DS1307 rtc(SDA, SCL); #define LED 11 // пин светодиода const int LBUTTONPIN = 10; const int RBUTTONPIN = 9; byte SetTimeH = 0; byte SetTimeMIN = 0; byte F_SetTime = 1; byte F_SetTimeH = 0; byte F_SetTimeMIN = 0; byte SetDataDay = 1; byte SetDataMonth = 1; byte SetDataGod = 19; byte F_SetData = 1; byte F_SetDataDay = 0; byte F_SetDataMonth = 0; byte F_SetDataGod = 0; ClickButton LBUTTON(LBUTTONPIN, LOW, CLICKBTN_PULLUP); ClickButton RBUTTON(RBUTTONPIN, LOW, CLICKBTN_PULLUP); void setup() { pinMode(LED, OUTPUT); LBUTTON.maxPresses = 1; // max button multiclick count LBUTTON.debounceTime = 5; // Debounce timer in ms LBUTTON.multiclickTime = 250; // Time limit for multi clicks LBUTTON.heldDownTime = 1000; // time until "held-down clicks" register lcd.Inicialize(); //Инициализация дисплея lcd.Clear_LCD(); //Очистка дисплея // Initialize the rtc object rtc.begin(); rtc.setSQWRate(SQW_RATE_1); // Задать частоту на выводе SQW равной 1Гц // Set the clock to run-mode rtc.halt(false); // The following lines can be uncommented to set the time //rtc.setDOW(FRIDAY); // Set Day-of-Week to SUNDAY //rtc.setTime(16, 40, 0); // Set the time to 12:00:00 (24hr format) //rtc.setDate(14, 4, 2019); // Set the date to October 3th, 2010 } void loop(){ }
Направьте пожалуйста на путь просветления ! Как освободить память ?
Начните с макроса F()
Как минимум повторяющийся код в функции оформить и вызывать когда нужно вместо того чтобы дублировать
Например это
В это
И вызывать в нужном месте
Можно весь повторяющийся текст меню сохронить в PROGMEM и читать оттуда (пробелы в тексте тоже память отжирают...)
И т.п.
Начните с макроса F()
Почитал - пишут "Если в коде используется инструкция вроде...
...то выводимая на экран строка, как правило, сохраняется в RAM. Таким образом, если в вашем скетче много подобных строк, которые выводятся на Serial Monitor, то ресурс RAM-памяти может закончиться очень быстро. Однако если у вас есть свободное место во flash-памяти, то вышеуказанную инструкцию можно изменить таким образом, чтобы строка сохранялась именно туда."
Этот номер проходит только с Serial.print ? или везде ?
Почти везде.
Уточню: в "драйверах", которые написаны авторами, не поленившимися указать родителем своего класса наследника класса Print - работает. В ликвидкристале, например, - всё ок.
Ругается на строку
ошибка "exit status 1
macro "F" passed 4 arguments, but takes just 1"
Как победить ?
Поставить букву F в правильное место.
Она относится ТОЛЬКО к строке, а не ко всему барахлу, что ещё в программе есть.
Ругается на строку
ошибка "exit status 1
macro "F" passed 4 arguments, but takes just 1"
Как победить ?
ты вапще что на этом форуме 3 года делал? Пошто не ходил на занятия?
Поставить букву F в правильное место.
Она относится ТОЛЬКО к строке, а не ко всему барахлу, что ещё в программе есть.
Спасибо !
Так работает
Ругается на строку
ошибка "exit status 1
macro "F" passed 4 arguments, but takes just 1"
Как победить ?
ты вапще что на этом форуме 3 года делал? Пошто не ходил на занятия?
На занятия я ходил , но только в начальную школу))
за три года здесь, абычна, уже монстров тяжелого ардуиностроения выпускают.
НО !!! Заметил и ужаснулся - ведь это фактически четверть меню , а будет еще код управления .
к сожалению, это типично. Та часть кода которая составляет суть и которая будет работать постоянно - занимает 10% программы, а остальные 90% - это меню, которым ты будешь пользоваться от силы 10 минут в месяц
Тут как бы два варианта - либо принять это как есть, либо выкинуть меню нафик и сделать программу полностью автоматической.
Тут как бы два варианта - либо принять это как есть, либо выкинуть меню нафик и сделать программу полностью автоматической.
Согласен.Да так бы и сделал если б себе. Устройством будут пользоваться люди далекие от arduin.
Вот что получилось после замены всего "строкового мусора" на F
Рано я обрадовался - залил это в arduino . Место надписей пишутся цыфры
Вместо надписи цыфра 104
Вместо надписи цыфра 511
Что не так ?
Классический случай - нет перегрузки функции под FlashStringHelper*
Классический случай - нет перегрузки функции под FlashStringHelper*
А можно по-русски ? Ну не программист я .
По-русски для непрограммистов:
То, что не в F() - при старте переносится в RAM (дублируется), а то что в F() - остаётся лежать в ROM. Методы доступа к данным в RAM и ROM различаются. В своей тайной библиотеке вы имеете только print(), который умеет читать RAM. Для чтения из ROM нужно библиотеку слегонца подрихтовать - задублировать фунцию и добавить пару строк.
По-русски для непрограммистов:
То, что не в F() - при старте переносится в RAM (дублируется), а то что в F() - остаётся лежать в ROM. Методы доступа к данным в RAM и ROM различаются. В своей тайной библиотеке вы имеете только print(), который умеет читать RAM. Для чтения из ROM нужно библиотеку слегонца подрихтовать - задублировать фунцию и добавить пару строк.
Спасибо за подробное объяснение ! "библиотеку слегонца подрихтовать" мне не под силу .
Получается у меня из вариантов
1. менять библиотеку
2. менять дисплей
3. менять ардуину на более "мозговитую"
4. просить Деда Семена написать за меня бесплатно (он же может )
Для начала покажите либу. По хидеру будущее не предсказывают.
Для начала покажите либу. По хидеру будущее не предсказывают.
Тут https://yadi.sk/d/rCJLYdOU6aLQRQ
По хидеру будущее не предсказывают.
Как то некрасиво, а вас ведь могут читать дети... Правильно хедер.)
Раз скрывает библиотеку - значит хидер ;)
mobistrike, напиши мне на wrk.sadman@gmail.com - я скину копипасту. У меня дисплея нет, проверить не могу.
4. просить Деда Семена написать за меня бесплатно (он же может )
дальше даже смотреть не стал
дальше даже смотреть не стал
А чо? Кjнструкция как конструкция - предобъвление функции :))
Аптамуш, я какта настороженно отношуся к библиотекам людей, каторые не наследуют класс вывода от Print, и делають ошибки в слове Initialize
Аптамуш, я какта настороженно отношуся к библиотекам людей, каторые не наследуют класс вывода от Print, и делають ошибки в слове Initialize
Он так видит .
Он так видит .
Заработал там грязный хак?
Он так видит .
Заработал там грязный хак?
Почти . Я на почту скинул фотки . Взгляните.
Не тому скинул, наверное.
Выражаю огромную благодарность sadman41 за помощь в правке библиотеки! После его колдовства все заработало правильно , RAM пока хватает, функция F работает )) . Если интересно , могу выложить изменения , естественно с разрешения sadman41 .
Картинка после второй правки
Еще раз СПАСИБО !
PS . мыло в 23 посте потри.
Выкладывать лучше в той теме, где библиотека обсуждается (в проектах вроде) - тут потонет всё.
Выкладывать лучше в той теме, где библиотека обсуждается (в проектах вроде) - тут потонет всё.
Ее бы найти еще ... Поищу вечером .
ЗЫ. Отписался в той теме.
mobistrike пишет:
Ее бы найти еще ... Поищу вечером .
ЗЫ. Отписался в той теме.
Дайте ссылку на этот пост, пожалуйста!
Дайте ссылку на этот пост, пожалуйста.
http://arduino.ru/forum/programmirovanie/biblioteka-dlya-lcd-nokia-1100#...
Таймер в работе !