Впихнуть невпихуемое
- Войдите на сайт для отправки комментариев
Здравствуйте уважаемые Копперфильды !
Мне снова понадобилась ваша помощь.
Захотелось мне изобрести очень или не очень умный таймер для управлением водонагревателем. Вроде ничего сложного.Начал с написания меню и даже написал.Задача - установить время и дату. Работает.
НО !!! Заметил и ужаснулся - ведь это фактически четверть меню , а будет еще код управления .
вот
"Скетч использует 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()
Как минимум повторяющийся код в функции оформить и вызывать когда нужно вместо того чтобы дублировать
Например это
В это
void printTime(){ lcd.print(0, 15, 1, " ВРЕМЯ "); lcd.print(22, 27, 1, rtc.getTimeStr()); }И вызывать в нужном месте
Можно весь повторяющийся текст меню сохронить в 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
lcd.print(0, 15, 1, F(" ВРЕМЯ "));Вместо надписи цыфра 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. просить Деда Семена написать за меня бесплатно (он же может )
class LCD1202 { public: LCD1202(uint8_t _RES, uint8_t _CS, uint8_t _Data, uint8_t _Clock); void Inicialize();дальше даже смотреть не стал
class LCD1202 { public: LCD1202(uint8_t _RES, uint8_t _CS, uint8_t _Data, uint8_t _Clock); void Inicialize();дальше даже смотреть не стал
А чо? Кjнструкция как конструкция - предобъвление функции :))
Аптамуш, я какта настороженно отношуся к библиотекам людей, каторые не наследуют класс вывода от Print, и делають ошибки в слове Initialize
Аптамуш, я какта настороженно отношуся к библиотекам людей, каторые не наследуют класс вывода от Print, и делають ошибки в слове Initialize
Он так видит .
Он так видит .
Заработал там грязный хак?
Он так видит .
Заработал там грязный хак?
Почти . Я на почту скинул фотки . Взгляните.
Не тому скинул, наверное.
Выражаю огромную благодарность sadman41 за помощь в правке библиотеки! После его колдовства все заработало правильно , RAM пока хватает, функция F работает )) . Если интересно , могу выложить изменения , естественно с разрешения sadman41 .
Картинка после второй правки
Еще раз СПАСИБО !
PS . мыло в 23 посте потри.
Выкладывать лучше в той теме, где библиотека обсуждается (в проектах вроде) - тут потонет всё.
Выкладывать лучше в той теме, где библиотека обсуждается (в проектах вроде) - тут потонет всё.
Ее бы найти еще ... Поищу вечером .
ЗЫ. Отписался в той теме.
mobistrike пишет:
Ее бы найти еще ... Поищу вечером .
ЗЫ. Отписался в той теме.
Дайте ссылку на этот пост, пожалуйста!
Дайте ссылку на этот пост, пожалуйста.
http://arduino.ru/forum/programmirovanie/biblioteka-dlya-lcd-nokia-1100#...
Таймер в работе !