Переход с УНО на ESP32

Ну это только половина пути. Как с модулем времени работать? У меня ЕСП32 такая:


Как питать модуль? На уно, помню от перестал работать при питании 3,7 В. Поэтому питал строго 5 В. А здесь? Логика же у ЕСП32 3,3В. Короче схема мне нужна, библиотека и скетч :frowning:
…Ещё покупал вместо литиевых батареек для питания аккумуляторы на 3,7 В для этих модулей.

Это да, но дисплей конкретно этого производителя брать стоит, ибо дёшево и совместимо с ПО других производителей.

Так написано же - GPIO22 - SCL, GPIO21 - SDA

DS3231 работает от 3,3v безо всяких проблем

Скетчи - в примерах ))

Не понял как время начальное записывать? В примерах вроде нет. Нашёл только в h. файле

DateTime (uint16_t year, uint8_t month, uint8_t day,
                uint8_t hour =0, uint8_t min =0, uint8_t sec =0);

Но тут нет дня недели.

День недели - это функция от даты. В модуле есть регистр дня недели, но он, имхо, не контролирует его валидность. Т.е. ты можешь задать вторник 30.08.2024, и модуль не поморщится ))

// Определение дня недели по дате в интервале 2000-2099 года, 0 - воскресенье
byte getDayOfWeek(byte _day, byte _month, word _year)
{
  static byte m[12] = {6, 2, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};

  byte y1 = _year % 100;
  byte t1 = y1 / 12 + y1 % 12 + y1 % 12 / 4;
  byte t2 = m[_month - 1];
  if (_month < 3 && y1 % 4 == 0)
  {
    t2--;
  }
  byte dow = (t1 + t2 + _day) % 7;
  return (dow);
}

Это не установка времени, а тип данных, содержащих текущее время и дату. По установке там есть

		void DS3231::setSecond(byte Second);
			// In addition to setting the seconds, this clears the
			// "Oscillator Stop Flag".
		void DS3231::setMinute(byte Minute);
			// Sets the minute
		void DS3231::setHour(byte Hour);
			// Sets the hour
		void DS3231::setDoW(byte DoW);
			// Sets the Day of the Week (1-7);
		void DS3231::setDate(byte Date);
			// Sets the Date of the Month
		void DS3231::setMonth(byte Month);
			// Sets the Month of the year
		void DS3231::setYear(byte Year);
			// Last two digits of the year
		void DS3231::setClockMode(bool h12);
			// Set 12/24h mode. True is 12-h, false is 24-hour.

А значения переменных куда вводить?.. Я посмотрел другой пример:

/*

Sets the time from input and prints back time stamps for 5 seconds

Based on DS3231_set.pde
by Eric Ayars
4/11

Added printing back of time stamps and increased baud rate
(to better synchronize computer and RTC)
Andy Wickert
5/15/2011

Clean for SAMD arch, add explanation, respect code-style and
fix interpretation of Serial input if used more than once
Olivier Staquet
4/26/2020

*/

#include <DS3231.h>
#include <Wire.h>

DS3231 myRTC;

byte year;
byte month;
byte date;
byte dow;
byte hour;
byte minute;
byte second;

bool century = false;
bool h12Flag;
bool pmFlag;

/*****************************************************************************************************
 * Setup
 *  - Open Serial and Wire connection
 *  - Explain to the user how to use the program
 *****************************************************************************************************/
void setup() {
  // Start the serial port
  Serial.begin(57600);

  // Start the I2C interface
  Wire.begin();

  // Request the time correction on the Serial
  delay(4000);
  Serial.println("Format YYMMDDwhhmmssx");
  Serial.println("Where YY = Year (ex. 20 for 2020)");
  Serial.println("      MM = Month (ex. 04 for April)");
  Serial.println("      DD = Day of month (ex. 09 for 9th)");
  Serial.println("      w  = Day of week from 1 to 7, 1 = Sunday (ex. 5 for Thursday)");
  Serial.println("      hh = hours in 24h format (ex. 09 for 9AM or 21 for 9PM)");
  Serial.println("      mm = minutes (ex. 02)");
  Serial.println("      ss = seconds (ex. 42)");
  Serial.println("Example for input : 2004095090242x");
  Serial.println("-----------------------------------------------------------------------------");
  Serial.println("Please enter the current time to set on DS3231 ended by 'x':");
}

/*****************************************************************************************************
 * Loop
 *  - Each time we receive the time correction on the Serial
 *  - Set the clock of the DS3231
 *  - Echo the value from the DS3231 during 5 seconds
 *****************************************************************************************************/
void loop() {
  // If something is coming in on the serial line, it's
  // a time correction so set the clock accordingly.
  if (Serial.available()) {
    inputDateFromSerial();

    myRTC.setClockMode(false);  // set to 24h

    myRTC.setYear(year);
    myRTC.setMonth(month);
    myRTC.setDate(date);
    myRTC.setDoW(dow);
    myRTC.setHour(hour);
    myRTC.setMinute(minute);
    myRTC.setSecond(second);

    // Give time at next five seconds
    for (uint8_t i = 0; i < 5; i++){
        delay(1000);
        Serial.print(myRTC.getYear(), DEC);
        Serial.print("-");
        Serial.print(myRTC.getMonth(century), DEC);
        Serial.print("-");
        Serial.print(myRTC.getDate(), DEC);
        Serial.print(" ");
        Serial.print(myRTC.getHour(h12Flag, pmFlag), DEC); //24-hr
        Serial.print(":");
        Serial.print(myRTC.getMinute(), DEC);
        Serial.print(":");
        Serial.println(myRTC.getSecond(), DEC);
    }

    // Notify that we are ready for the next input
    Serial.println("Please enter the current time to set on DS3231 ended by 'x':");
  }
  delay(1000);
}

/*****************************************************************************************************
 * inputDateFromSerial
 *  - Read and interpret the data from the Serial input
 *  - Store the data in global variables
 *****************************************************************************************************/
void inputDateFromSerial() {
	// Call this if you notice something coming in on
	// the serial port. The stuff coming in should be in
	// the order YYMMDDwHHMMSS, with an 'x' at the end.
	boolean isStrComplete = false;
	char inputChar;
	byte temp1, temp2;
	char inputStr[20];

	uint8_t currentPos = 0;
	while (!isStrComplete) {
		if (Serial.available()) {
			inputChar = Serial.read();
			inputStr[currentPos] = inputChar;
			currentPos += 1;

      // Check if string complete (end with "x")
			if (inputChar == 'x') {
				isStrComplete = true;
			}
		}
	}
	Serial.println(inputStr);

  // Find the end of char "x"
  int posX = -1;
  for(uint8_t i = 0; i < 20; i++) {
    if(inputStr[i] == 'x') {
      posX = i;
      break;
    }
  }

  // Consider 0 character in ASCII
  uint8_t zeroAscii = '0';

	// Read Year first
	temp1 = (byte)inputStr[posX - 13] - zeroAscii;
	temp2 = (byte)inputStr[posX - 12] - zeroAscii;
	year = temp1 * 10 + temp2;

	// now month
	temp1 = (byte)inputStr[posX - 11] - zeroAscii;
	temp2 = (byte)inputStr[posX - 10] - zeroAscii;
	month = temp1 * 10 + temp2;

	// now date
	temp1 = (byte)inputStr[posX - 9] - zeroAscii;
	temp2 = (byte)inputStr[posX - 8] - zeroAscii;
	date = temp1 * 10 + temp2;

	// now Day of Week
	dow = (byte)inputStr[posX - 7] - zeroAscii;

	// now Hour
	temp1 = (byte)inputStr[posX - 6] - zeroAscii;
	temp2 = (byte)inputStr[posX - 5] - zeroAscii;
	hour = temp1 * 10 + temp2;

	// now Minute
	temp1 = (byte)inputStr[posX - 4] - zeroAscii;
	temp2 = (byte)inputStr[posX - 3] - zeroAscii;
	minute = temp1 * 10 + temp2;

	// now Second
	temp1 = (byte)inputStr[posX - 2] - zeroAscii;
	temp2 = (byte)inputStr[posX - 1] - zeroAscii;
	second = temp1 * 10 + temp2;
}

Правильно понимаю, что после загрузки скетча надо вводить данные в монитор порта?

Да …

Ответ очень соблазнителен для заказа!
Интересно всё же потребление во время перерисовки (на сколько хватит таких часов с перерисовкой каждую минуту)?

Пробовал новым прибором с цветным электронным дисплеем. Показывает на 3,3В ток при перерисовке 2,0-2,5 мА, после 0,5-0,8мА. Можно паспортные данные поискать попробовать.

Ну это ты в сон не уходил и не отключал питание? Или я ошибаюсь?

Конечно, это его потребление при включенной схеме… С календарём проще поставить выключатель - включил-перелистнул-выключил… Смену года не делал, чтоб по честному - год прошёл - бери новый календарь (перезагружай скетч с новой фоновой картинкой).

Дороговато, но заинтриговал, зараза…)))

Не знаю, эти производители самые доступные по цене. Сравните иные аналоги:

Заработал календарь, не знаю, вроде знаки зодиака верно определяются:

#include <SPI.h>
#include "epd4in2_V2.h"
#include "imagedata.h"
#include <DS3231.h>
#include <Wire.h>

DS3231 myRTC;
bool century = false;
const struct { 
    const unsigned char *bitmap;
  }
 arhiv_znaki[12]={znak_1,znak_2,znak_3,znak_4,znak_5,znak_6,znak_7,znak_8,znak_9,znak_10,znak_11,znak_12};//размер значка 96Х96 пикселей
 const struct { 
    const unsigned char *bitmap;
  }
 arhiv_mes[12]={mes_1,mes_2,mes_3,mes_4,mes_5,mes_6,mes_7,mes_8,mes_9,mes_10,mes_11,mes_12};//размер шильда 56Х248 пикселей
 const struct {
     const unsigned char *bitmap;
  }
 arhiv_ned[7]={ned_1,ned_2,ned_3,ned_4,ned_5,ned_6,ned_7};//размер шильда 32Х200 пикселей
 const struct {
     const unsigned char *bitmap;
  }
 arhiv_chis[10]={chis_0,chis_1,chis_2,chis_3,chis_4,chis_5,chis_6,chis_7,chis_8,chis_9,};//размер шильда 144X72 пикселей
 
byte CH=3;byte M=9;byte N=2;byte Z=8;//числа данных календаря - число, месяц, день недели, текущий знак гороскопа

void setup() {
   Wire.begin();
   Epd epd;
  epd.Init();
  epd.Clear();
/////////////////////
/*
for(int i=0;i<12;i++){
epd.Display_Partial_Not_refresh(arhiv_znaki[i].bitmap, 0+(i%4)*96, 0+(i/4)*96, 96+(i%4)*96, 96+(i/4)*96);
if(i==11){epd.Display_Partial(arhiv_znaki[i].bitmap,0+(i%4)*96, 0+(i/4)*96, 96+(i%4)*96, 96+(i/4)*96);}
}
*/
//получение данных о времени с модуля часов
CH=myRTC.getDate();
M=myRTC.getMonth(century);
N=myRTC.getDoW();
//вычисление знака зодиака
if((M==1&&CH>=20)||(M==2&&CH<=19)){Z=1;}
if((M==2&&CH>=20)||(M==3&&CH<=20)){Z=2;}
if((M==3&&CH>=21)||(M==4&&CH<=19)){Z=3;}
if((M==4&&CH>=20)||(M==5&&CH<=20)){Z=4;}
if((M==5&&CH>=21)||(M==6&&CH<=20)){Z=5;}
if((M==6&&CH>=21)||(M==7&&CH<=22)){Z=6;}
if((M==7&&CH>=23)||(M==8&&CH<=22)){Z=7;}
if((M==8&&CH>=23)||(M==9&&CH<=22)){Z=8;}
if((M==9&&CH>=23)||(M==10&&CH<=23)){Z=9;}
if((M==10&&CH>=24)||(M==11&&CH<=22)){Z=10;}
if((M==11&&CH>=23)||(M==12&&CH<=21)){Z=11;}
if((M==12&&CH>=21)||(M==1&&CH<=19)){Z=12;}
//отрисовка листка календаря
epd.Display_Partial_Not_refresh(fon_, 0, 0, 400, 300);
if(CH>9){epd.Display_Partial_Not_refresh(arhiv_chis[CH/10].bitmap, 220, 80, 220+144, 80+72);epd.Display_Partial_Not_refresh(arhiv_chis[CH%10].bitmap, 220, 80+72, 220+144, 80+72+72);}
else{epd.Display_Partial_Not_refresh(arhiv_chis[CH].bitmap, 220, 116, 220+144, 116+72);}
epd.Display_Partial_Not_refresh(arhiv_mes[M-1].bitmap, 180, 26, 180+56, 26+248);
epd.Display_Partial_Not_refresh(arhiv_ned[N-1].bitmap, 140, 40, 140+32, 40+200);
epd.Display_Partial(arhiv_znaki[Z-1].bitmap,40, 100, 96+40, 96+100);
epd.Sleep();
}

void loop() {
  // put your main code here, to run repeatedly:
}

Таблица соединений:

Esp32 3,3V GND IO23 IO18 IO16 IO27 IO14 IO17 SDA SCL
E paper VCC GND DIN CLK CS DC RST BUSY
Ds3231 VCC GND SDA SCL

@lilik , а те что до этого были (плоские) сколько по времени обновляются и как купить?

Потребление и тп невозможно уже «снять»?

Красно-чёрно-белые обновляются десяток, другой секунд. Потребление не замерял ибо с теорией всё равно нигде не сойдётся (волшебное слово - “типовое” потребление мощности при обновлении) :slight_smile:

4,2 дюймовый экран для электронной бумаги и электронных чернил
Рабочее напряжение: 3,3 V / 5V
Интерфейс связи: 3-проводный SPI, 4-проводный, SPI
Размер формы: 103,0*78,5 мм
Размер дисплея: 84,8*63,6 мм
Шаг: 0,212*0,212 мм
Разрешение: 400*300
Цвет дисплея: черный белый, черный белый желтый и черный белый красный (пожалуйста, выберите и отметьте при заказе)
Шкала серого: 4
Потребляемая мощность обновления: 26,4 мВт (тип.)
Энергопотребление в режиме ожидания: <0,017 мВт
Угол обзора: >170 градусов

Покупал тут:
https://aliexpress.ru/item/1005004644515880.html?sku_id=12000034319637608&spm=a2g2w.productlist.search_results.0.78643456C7aR6S
Производитель WeAct studio. На слуху ещё две фирмы…надо вспомнить.
… Waveshare и Goodisplay.

Он только полностью перерисовывается или можно часть перерисовывать?

Наверно можно, но у меня не получилось, пока. От ПО зависит многое :slight_smile: Для WeAct использую от Waveshare. На Waveshare пробовал ради интереса от Goodisplay. Я так пониманию, что один пиксель он обновлять не может.