ESP, IoT [MatrixClock] Большие часы 64х32, ESP32

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
РЕЛИЗ 2 в разработке с 16.04.23

  • переход на GyverHub​
  • обновление интерфейса​
  • замена библиотек датчиков​
  • обновление интерфейса вывода информации на дисплее​
  • оптимизация кода вывода показаний с датчиков​

 
Изменено:

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
РЕЛИЗ 1
Пост перенесен, файлы перезалиты 28.04.2023...

Данный проект выполнен на светодиодной матрице 64х32
Спроектирована плата для быстрого подключения датчиков и ESP платы и уменьшения кол-ва проводов.

Установка:
Необходимые библиотеки находим в репозитории программы IDE.
Настраиваем прошивку под себя, если нужно, меняем пароли для точки и OTA, WiFi можно не задавать.
Меняем цвета под себя #97-100
Если не задавали настройки WiFi, то стартует точка, адрес стандартный 192.168.4.1 пароль по умолчанию adminadmin, задавать не менее 8 символов, иначе название точки не отобразится, а будет ее внутреннее имя, типа ESP12345.
Адрес портала http://clock.local/ или по IP адресу, выданному роутером

Для подключения к сервису "Народный мониторинг" MAC адрес отображается на соответствующей странице, вводите этот адрес при регистрации устройства.

Наполнение в процессе...
Будем развивать и дорабатывать проект)

Баги: оформление OTA и переадресация после обновления, ждем фикса в следующем обновлении библиотеки.
Остались 4 платы, если кто хочет аналогично сделать, пишите в ЛС, решим, что можно сделать)

HUB 75 PANEL ESP 32 PIN

R1 -> IO25 G1 -> IO26
B1 -> IO27
R2 -> IO14 G2 -> IO12
B2 -> IO13 E -> N/A (required for 1/32 scan panels, like 64x64. Any available pin would do, i.e. IO32 )
A -> IO23 B -> IO19
C -> IO05 D -> IO17
CLK -> IO16 LAT -> IO 4
OE -> IO15 GND -> ESP32 GND

SDA -> IO21
SCL -> IO22

ds18b20 -> 0
ldr -> 33
 

Вложения

Изменено:

bort707

★★★★★★✩
21 Сен 2020
3,046
909
если есть выбор между 8266 и esp32 - берите последний, на 8266 возможны проблемы при одновременной работе матрицы и вайфая. На ЕСП32 два ядра, проблем нет.
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@bort707, так я взял esp32, но увы) новый 600р будет)
сейчас адаптирую скетч и буду пробовать подключать)
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
я за 300р брал)

как и ожидалось, код не рабочий, на панели только мигает один диод при нажатии сброса, больше ничего)

п.с. стандартные примеры из библиотеки работают...

стандартный скетч на показ картинок, потребление БП 4,3 -6,8Вт 34-52мА

начало есть)
C++:
#include <PxMatrix.h>
#include <Ticker.h>
Ticker display_ticker;
#define P_LAT 16
#define P_A 5
#define P_B 4
#define P_C 15
#define P_D 12
#define P_E 0
#define P_OE 2
PxMATRIX display(64, 32, P_LAT, P_OE, P_A, P_B, P_C, P_D, P_E);
void display_updater() {
  display.display(60);
}
void setup() {
  display.begin(16);
  display.setBrightness(80);
  display_ticker.attach(0.004, display_updater);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(display.color565(255, 0, 255));
  display.setCursor(10, 2);
  display.print("Hello!!!");
  display.setCursor(10, 18);
  display.print("npuBeT!!!");
  display.display();
}
void loop() {
}
IMG_20220307_192343.jpg
 
Изменено:

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@bort707, мне тоже не нравится, буду менять. Основа понятна. Потом надо будет понять с перерисовкой дисплея, менять по изменению минуты) а то вроде и стоит задержка 500, но мерцания заметны. Также на камеру видны мерцания.

На матрицу интереснее выводить информацию. Только насколько видно будет ее, при плохом зрении)
 

bort707

★★★★★★✩
21 Сен 2020
3,046
909
вроде и стоит задержка 500, но мерцания заметны
задержка чего 500 ? - эту матрицу надо обновлять сотни раз в секунду, иначе будет очень некрасиво. Это вам не лента, где один раз вывел изображение и можно не трогать, пока картинка не изменится.
Хотя там скорее всего в библиотеке обновление по таймеру.
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@bort707,
C++:
  display.clearDisplay();
  Time();
  Dots();
  TempHome();
  TempStreet();
  Press();
  Hum();
  delay(30000);
пока сделал так, для отладки, не мелькает на глазах.
без очистки не очищаются диоды, а без задержки мерцают)
IMG_20220309_193129.jpg
 
Изменено:
  • Лойс +1
Реакции: Maxx1200

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
привет, помогите)
в коде записи ошибок не выдается)
13 строка в мониторе порта отображается правильно.
C++:
bool saveConfig() {

  StaticJsonDocument<800> doc;
  doc["j_ssid"] = newssid;
  doc["j_pass"] = newpass;
  doc["j_zone"] = newt_z;

  File configFile = LittleFS.open("/config.json", "w");
  if (!configFile) {
    Serial.println("Не удалось открыть файл конфигурации для записи в saveConfig");
    return false;
  }
  Serial.println((String)"Write FS: ""j_ssid = " + newssid + " j_pass = " + newpass + " j_zone = " + newt_z);
  serializeJson(doc, configFile);
  return true;
}
а при чтении выдает ошибку
Монтирование LittleFS прошло успешно!
Не удалось открыть файл конфигурации в loadConfig
C++:
bool loadConfig() {
  if (!LittleFS.begin()) { // если не удалось монтировать SPIFFS память
    Serial.println("Ошибка при монтировании LittleFS");
  } else {
    Serial.println("Монтирование LittleFS прошло успешно!");
  }
  delay(1000);
  File configFile = LittleFS.open("/config.json", "r");
  if (!configFile) {
    Serial.println("Не удалось открыть файл конфигурации в loadConfig");
    return false;
  }
  size_t size = configFile.size();
  if (size > 1024) {
    Serial.println("Размер файла конфигурации слишком велик");
    return false;
  }
  // Выделить буфер для хранения содержимого файла.
  std::unique_ptr<char[]> buf(new char[size]);
  configFile.readBytes(buf.get(), size);

  StaticJsonDocument<800> doc;
  DeserializationError error = deserializeJson(doc, buf.get());

  if (error) {
    Serial.println("Не удалось разобрать файл конфигурации");
    Serial.println(error.c_str());
    return false;
  }

  strcpy(ssid, doc["j_ssid"]);
  strcpy(pass, doc["j_pass"]);
  strcpy(t_z, doc["j_zone"]);
  Serial.println((String)"Read FS: ""j_ssid = " + ssid + " j_pass = " + pass + " j_zone = " + t_z);
  return true;
}
а если вставить код чтения в конец saveconfig после return, то ошибок не выдает)
C++:
  File configFileRead = LittleFS.open("/config.json", "r");
  if (!configFileRead) {
    Serial.println("Не удалось открыть файл конфигурации Read");
    return false;
  }
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
Перенес код в отдельный проект.
Запись и чтение работает исправно, а в общем не хочет))
Удивительно))
Привязал для проверки WiFi, но почему-то туда не передаются переменные ssid и pass, хотя в load выводится правильно...
C++:
#include <LittleFS.h>
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>

void setup() {
  Serial.begin(115200);
  Serial.println("Start!");
  delay(5000);
}
String newssid = "Admin";
String newpass = "password";
String newt_z = "3";
char* ssid;
char* pass;
char* t_z;

bool loadConfig() {
  if (!LittleFS.begin()) { // если не удалось монтировать SPIFFS память
    Serial.println("Ошибка при монтировании LittleFS");
  } else {
    Serial.println("Монтирование LittleFS прошло успешно!");
  }
  delay(1000);
  File configFile = LittleFS.open("/config.json", "r");
  if (!configFile) {
    Serial.println("Не удалось открыть файл конфигурации в loadConfig");
    return false;
  }
  size_t size = configFile.size();
  if (size > 1024) {
    Serial.println("Размер файла конфигурации слишком велик");
    return false;
  }
  // Выделить буфер для хранения содержимого файла.
  std::unique_ptr<char[]> buf(new char[size]);
  configFile.readBytes(buf.get(), size);

  StaticJsonDocument<950> doc;
  DeserializationError error = deserializeJson(doc, buf.get());

  if (error) {
    Serial.println("Не удалось разобрать файл конфигурации");
    Serial.println(error.c_str());
    return false;
  }
  const char*    ssid = doc["j_ssid"];
  const char*    pass = doc["j_pass"];
  const char*    t_z = doc["j_zone"];
  Serial.println((String)"Read FS: ""j_ssid = " + ssid + " j_pass = " + pass + " j_zone = " + t_z);
  wifi_connected();
  return true;
}

bool saveConfig() {
  if (!LittleFS.begin()) { // если не удалось монтировать SPIFFS память
    Serial.println("Ошибка при монтировании LittleFS");
  } else {
    Serial.println("Монтирование LittleFS прошло успешно!");
  }
  delay(1000);
  StaticJsonDocument<950> doc;
  doc["j_ssid"] = newssid;
  doc["j_pass"] = newpass;
  doc["j_zone"] = newt_z;
  //serializeJson(doc, Serial);

  File configFile = LittleFS.open("/config.json", "w");
  if (!configFile) {
    Serial.println("Не удалось открыть файл конфигурации для записи в saveConfig");
    return false;
  }
  Serial.println((String)"Write FS: ""j_ssid = " + newssid + " j_pass = " + newpass + " j_zone = " + newt_z);

  serializeJson(doc, configFile);
  return true;
  delay(5000);
}

void loop() {
  saveConfig();
  delay(10000);
  loadConfig();
  delay(10000);
}

void wifi_connected() {
  WiFi.disconnect();
  delay(1000);
  Serial.println((String)"WiFi Connected: " "ssid = "  + ssid + " pass = " + pass);
  Serial.print("WIFI: "); Serial.println(ssid);
  Serial.print("PASS: "); Serial.println(pass);
  WiFi.mode(WIFI_STA);
  byte tries = 20;
  WiFi.begin(ssid, pass);
  while (--tries && WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay (1000);
  }
  if (WiFi.status() != WL_CONNECTED)
  {
    // Если не удалось подключиться запускаем в режиме AP
    Serial.println("");
    Serial.println("WiFi не работает");
  }
  else {
    Serial.println("");
    Serial.println("WiFi запущен");
    Serial.println("IP адрес: ");
    Serial.println(WiFi.localIP());
  }
}
Монтирование LittleFS прошло успешно!
Write FS: j_ssid = Admin j_pass = password j_zone = 3
Монтирование LittleFS прошло успешно!
Read FS: j_ssid = Admin j_pass = password j_zone = 3
WIFI:
PASS:
...................
WiFi не работает
 

bort707

★★★★★★✩
21 Сен 2020
3,046
909
кмк, проблема та же самая, как в теме, которую вы зачистили - опять сохраняете указатели на строчки вместо самих строк.
Заведите чар-массивы под ssid и pass и копируйте в них то, что получили из json
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@bort707, я пытался без них, но компилятор просил указатели) когда поставил их, компиляция заработала)
Да и всегда в ssid и pass используют const char*...
 

bort707

★★★★★★✩
21 Сен 2020
3,046
909
Все правильно, нужны указатели. Но они должны указывать на строчки, а не на пустое место, как у вас. Я же вроде в прошлый раз вам обьяснил, в чем проблема.
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@bort707, я хотел изначально использовать strcpy, но esp крашится)
 

bort707

★★★★★★✩
21 Сен 2020
3,046
909
Судя по всему, неверно использовали. Код покажите
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@bort707,
C++:
strcpy(ssid, doc["j_ssid"]);
strcpy(pass, doc["j_pass"]);
strcpy(t_z, doc["j_zone"]);
 

bort707

★★★★★★✩
21 Сен 2020
3,046
909
А ssid и остальные как описаны? Опять char* ? А кто память выделять под них будет?
 
  • Лойс +1
Реакции: ASM

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@bort707,
поставил строки, все равно пустые)
C++:
String ssid = doc["j_ssid"];
String pass = doc["j_pass"];
String t_z = doc["j_zone"];
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@bort707, подправил, теперь не крашится
C++:
char ssid[32];
char pass[32];
char t_z[5];

strcpy(ssid, doc["j_ssid"]);
strcpy(pass, doc["j_pass"]);
strcpy(t_z, doc["j_zone"]);
@bort707, так и сделал, но значение не передается)

нашел решение))
C++:
char ssid[32] = "";
char pass[32] = "";
char t_z[5] = "";
попробовал запускать сразу с load, т.к. конфиг по идее должен остаться в памяти, он же не перезаписывается?
Монтирование LittleFS прошло успешно!
Не удалось открыть файл конфигурации в loadConfig
я накосячил, all flash content было)
такой вариант правильный?)
C++:
char t_z[5] = "";
int zone = (int)t_z - '0';
NTPClient ntpClient(udp, ntp_srv, (zone * 60 * 60), 60000);
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
3,046
909
ASM написал(а):
такой вариант правильный?)
нет, конечно.
Если вы хотите преобразовать в число первый символ t_z . то и обращайтесь к ПЕРВОМУ символу, а не ко всему массиву

int zone = t_z[0] - '0';
(если символов более одного или цифра не в первом, то делать надо вообще совсем не так)

И нелишне сначала проверить, есть ли в этом первом символе цифра. А то если сделать так, по аналогии с тем как написано выше
C++:
char t_z[5] = "";
int zone = t_z[0] - '0';
у вас zone будет равно (-48), не думаю что вы этого хотели

@ASM, у вас все-таки ОГРОМНЕЙШИЙ пробел в знаниях на тему "переменные, массивы и указатели". У вас сейчас в проекте почти все будет построено на этой теме, очень советую ее подтянуть. Не жалейте на это время, в итоге вы это выиграете, а не потеряете. Вот посмотрите - без этого вы тратите по два дня на пару элементарных строчек.

ЗЫ Если хотите добавить вопрос - делайте это новым сообщением, а не добавляйте к старому, иначе не приходят уведомления.
 
Изменено:
  • Лойс +1
Реакции: ASM