Библиотека Parola и часы DS3231

EDIT2: Ну, это «новый» код, и он просто отображает случайные точки на матрицах:

#include "RTClib.h"

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

// Определяем количество устройств у нас в цепочке и аппаратный интерфейс
// ПРИМЕЧАНИЕ. Эти номера контактов, вероятно, не будут работать с вашим оборудованием и могут
// нужно адаптировать
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 16
#define NUM_ZONES 4

#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

// Аппаратное соединение SPI
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Произвольные выходные контакты
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

RTC_DS3231 rtc;
#define SPEED_TIME  25
#define PAUSE_TIME  1000

uint8_t lastUpdateMin = 0;
uint8_t lastUpdateHour = 0;

// Глобальная переменная
const char  *pc[NUM_ZONES] =
{
  "TIME",
  "ROOM", //0
  "SUBJECT", //1
  "GRADE",//2
  };

void setup(void)
{

  P.begin();
    if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

 if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
// Если RTC потерял питание, он установит RTC на дату & время, когда этот скетч был скомпилирован в следующую строку
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
 }

 P.begin(4);
  P.setZone(0, 0, 3); // Модули 0-3 в зоне 0
  P.setZone(1, 4, 7); // Модули 4-7 в зоне 1
  P.setZone(2, 8, 11); // Модули 8-11 в зоне 2
  P.setZone(3, 12, 15); // Модули 12-15 в зоне 3
}

void loop(void)
{

 DateTime now = rtc.now();
 if(lastUpdateMin != now.minute()){  // меняем каждую минуту
     lastUpdateMin = now.minute();
 char buffer[] = "hh:mm";  // часы и минуты
P.displayZoneText(0,now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);

    if(lastUpdateHour != now.hour()){     // меняем каждый час
     lastUpdateHour = now.hour();
   P.displayZoneText(1, pc[1], PA_RIGHT, 0, 0, PA_PRINT, PA_NO_EFFECT);
   P.displayZoneText(2, pc[2], PA_LEFT, 0, 0, PA_PRINT, PA_NO_EFFECT);  // отображать
   P.displayZoneText(3, pc[3], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
   }
  }
   P.displayAnimate();
}

Если я сделаю вот что:

void loop(void)
{

 DateTime now = rtc.now();
 if(lastUpdateMin != now.minute()){  // меняем каждую минуту
     lastUpdateMin = now.minute();
 char buffer[] = "hh:mm";  // часы и минуты
P.displayZoneText(0,now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
 }
     if(lastUpdateHour != now.hour()){     // меняем каждый час
     lastUpdateHour = now.hour();

     }

   P.displayAnimate();
}

отображает часы:минуты. проблема в том, что он не отображает время и другой текст одновременно

EDIT: если я выполню этот код ниже, он отобразит текст в первой строке, но мой вопрос будет заключаться в том, как мне одновременно отображать час:минуты с часов и какой-либо текст по моему выбору?

void setup(void)
{

  P.begin();
    if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

 if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
// Если RTC потерял питание, он установит RTC на дату & время, когда этот скетч был скомпилирован в следующую строку
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
 }

 P.begin(4);
  P.setZone(0, 0, 3); // Модули 0-3 в зоне 0
  P.setZone(1, 4, 7); // Модули 4-7 в зоне 1
  P.setZone(2, 8, 11); // Модули 8-11 в зоне 2
  P.setZone(3, 12, 15); // Модули 12-15 в зоне 3

for (uint8_t i=0; i<NUM_ZONES; i++)
    P.displayZoneText(0, pc[0], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);

}

void loop(void)
{

 DateTime now = rtc.now();
 char buffer[] = "hh:mm";  // часы и минуты

// P.displayZoneText(0,now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT); // отображать
//если(сейчас.час()==12){
// P.displayZoneText(0, pc[0], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
//}
//еще{
 // P.displayZoneText(1, pc[1], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT); // отображать
//}
   P.displayAnimate();
}

У меня есть несколько модулей FC-16 на основе светодиодных матриц MAX7219, и я хочу использовать их и часы реального времени DS3231 для построения расписания занятий.

Я хочу, чтобы светодиодные модули работали по концепции зон. Я хочу создать зону для каждой строки текста (зона — это непрерывный блок модулей, образующих своего рода вспомогательный дисплей), как я сделал здесь: P.begin(4); // У нас будет 4 зоны P.setZone(0, 0, 3); // Модули 0-3 в зоне 0 P.setZone(1, 4, 7); // Модули 4-7 в зоне 1 P.setZone(2, 8, 11); // Модули 8-11 в зоне 2 P.setZone(3, 12, 15); // Модули 12-15 в зоне 3

Мне нужно это, чтобы иметь возможность изменять текст в строке, не изменяя другие строки.

Затем мне нужно использовать часы и минуты из модуля часов DS3231 и отобразить их в первой строке дисплея, а в остальных 3-х строках мне нужно отобразить номер комнаты, предмет и класс .

const char  *pc[NUM_ZONES] =
{
  "ROOM",
  "SUBJECT",
  "CLASS",};

И когда час в первой строке изменяется, текст в трех других строках должен измениться одновременно. Это довольно простая концепция, но я не знаю, как с этим справиться. Это весь код, который я собрал на данный момент:

#include "RTClib.h"

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

// Определяем количество устройств у нас в цепочке и аппаратный интерфейс
// ПРИМЕЧАНИЕ. Эти номера контактов, вероятно, не будут работать с вашим оборудованием и могут
// нужно адаптировать
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 16
#define NUM_ZONES 4

#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

// Аппаратное соединение SPI
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Произвольные выходные контакты
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
RTC_DS3231 rtc;
#define SPEED_TIME  25
#define PAUSE_TIME  1000

// Глобальные переменные
uint8_t  curText;
const char  *pc[NUM_ZONES] =
{
  "ROOM",
  "SUBJECT",
  "CLASS",

};

void setup(void)
{

  P.begin();
    if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

 if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
// Если RTC потерял питание, он установит RTC на дату & время, когда этот скетч был скомпилирован в следующую строку
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
 }

 P.begin(4);
  P.setZone(0, 0, 3); // Модули 0-3 в зоне 0
  P.setZone(1, 4, 7); // Модули 4-7 в зоне 1
  P.setZone(2, 8, 11); // Модули 8-11 в зоне 2
  P.setZone(3, 12, 15); // Модули 12-15 в зоне 3

}

void loop(void)
{

 DateTime now = rtc.now();
 char buffer[] = "hh:mm";  // часы и минуты

   for (uint8_t i=0; i<NUM_ZONES; i++)
    P.displayZoneText(i-1, now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);

P.displayAnimate();
}

Я не знаю, как отображать час:минуты и мой текст одновременно, чтобы я мог сделать все остальное:

{

 DateTime now = rtc.now();
 char buffer[] = "hh:mm";  // hours and minutes

   for (uint8_t i=0; i<NUM_ZONES; i++)
    P.displayZoneText(i-3, now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT); //here I want to display the hour:minutes on the first row

P.displayAnimate();
}```

, 👍0

Обсуждение

отредактировано только что, @Rehoboam

Я знаю, как отображать текст во всех 4 зонах. Я не знаю, как отображать реальное время с модуля часов и какой-то другой текст одновременно, @Rehoboam

я тоже знаю как это сделать, @Rehoboam

Что такое библиотека Parola? Где ваши читатели могут найти эту библиотеку? С каким дисплеем работает? Вкратце, что это дает вам? Вы должны предоставить всю эту информацию в своем вопросе., @Duncan C

Parola в основном используется для форматирования текста на светодиодных матричных дисплеях. Мои светодиодные модули FC16 основаны на светодиодных матрицах MAX7219. Я не могу понять, как правильно отображать время и сообщение одновременно, @Rehoboam

вы говорите, что можно преобразовать время в текст, и можно отображать текст во всех зонах, тогда в чем собственно проблема? ... я просто не могу понять, с чем у вас проблема ... пожалуйста, добавьте несколько фотографий, которые показывают проблему, @jsotola


1 ответ


Лучший ответ:

1

Ваша первая проблема связана с определением текстового массива:

const char  *pc[NUM_ZONES] =
{ "TIME",      // Это будет заменено на реальное время здесь только для логики строк
  "ROOM",
  "SUBJECT",
  "CLASS"
};

тогда нам нужен таймер, так как вы показываете только минуты, нам нужно только изменить время в этом интервале, чтобы предотвратить мерцание и другие нежелательные эффекты, и час для изменения текста позже:

uint8_t lastUpdateMin = 0;
uint8_t lastUpdateHour = 0;

Тогда цикл выглядит так

void loop() {
   DateTime now = rtc.now();
   if(lastUpdateMin != now.minute()){  // меняем каждую минуту
     lastUpdateMin = now.minute();
     char buffer[] = "hh:mm";  // часы и минуты
     P.displayZoneText(0, now.toString(buffer), PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT); // 1-я строка
    }
  if(lastUpdateHour != now.hour()){     // меняем каждый час
     lastUpdateHour = now.hour();
     P.displayZoneText(1, pc[1], PA_RIGHT, 0, 0, PA_PRINT, PA_NO_EFFECT);  // 2-я строка
     P.displayZoneText(2, pc[2], PA_LEFT, 0, 0, PA_PRINT, PA_NO_EFFECT);   // 3-я строка
     P.displayZoneText(3, pc[3], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT); // 4-я строка
    }
P.displayAnimate();
}

Что нужно сделать — определить двухмерную таблицу символов со всеми текстами, необходимыми для разных часов

#define NUM_LECTUREHOURS 7       // семичасовые лекции
const char *pc[NUM_LECTUREHOURS][NUM_ZONES] = {
  { "TIME", "ROOM_0", "SUBJECT_0", "CLASS_0"},
  { "TIME", "ROOM_1", "SUBJECT_1", "CLASS_1"},
  { "TIME", "ROOM_2", "SUBJECT_2", "CLASS_2"},
  ...
  { "TIME", "ROOM_Last", "SUBJECT_Last", "CLASS_Last"}  // _Last в этом примере = 6
};

и отображать с переменной в зависимости от часа, поэтому, если ваши занятия начинаются в 9:00, вы должны использовать

uint8_t lectureHour= now.hour() - 9; // так как массивы начинаются с 0

и ваши разные тексты будут называться как

  P.displayZoneText(1, pc[lectureHour][1], PA_RIGHT, 0, 0, PA_PRINT, PA_NO_EFFECT); // 2-я строка

Если ваш массив символов становится слишком большим (в зависимости от текстов), вам придется использовать PROGMEM, что само по себе является проблемой. Надеюсь, это поможет вам начать работу

ОБНОВЛЕНО Если вы хотите меняться каждые два часа, вы делаете это

if(lastUpdateHour != now.hour() && lastUpdateHour +1 != now.hour() ){ // изменение каждые два часа

или короче для переменного промежутка времени (например, каждые три часа)

 if( now.hour() - lastUpdateHour > 3 ){     // изменение каждые три часа
,

Я сделал все, что вы мне показали, до таблицы символов, и это не работает. Он ничего не отображает. И когда я создаю таблицу char, она говорит: «Конфликтующая декларация 'const char* pc [7][4['», @Rehoboam

Пожалуйста, начните с простого примера и протестируйте, не ищите полное решение, пока не сделаете простую работу. И отредактируйте свой вопрос и покажите «новый» код, @Codebreaker007

только что сделал это., @Rehoboam

Я думаю, вы просто запускаете свой ESP, поэтому час возвращается = 0, поэтому либо подождите один час (шутка), либо установите начальный час на 99 и используйте мой оригинальный цикл, так как в вашей программе есть ошибка в скобках!, @Codebreaker007

Бог благословил! а если я хочу менять текст каждые 2 часа?, @Rehoboam

Смотрите мое редактирование в ответе, @Codebreaker007

Оно работает. Скажите, почему тот же код, который работал минуту назад, в следующий момент вообще не работает, когда я заливаю? Например. некоторое время назад он работал нормально, а теперь вообще ничего не отображает или отображает только несколько случайных точек. Без внесения аппаратных изменений. Это аппаратная проблема или софтовая? Тот же код, те же нетронутые жесткие соединения. Когда-то работает, когда-то нет., @Rehoboam

Может быть проблема с используемыми библиотеками, поиск проблемных библиотек на github для похожих проблем/решений. Ссылку можно найти в менеджере библиотек IDE под используемой библиотекой., @Codebreaker007