Большие часы на esp8266 с NTP, погодой, внутренним датчиком DH11 и вебинтерфейсом

Dmitry Matveev
Dmitry Matveev аватар
Offline
Зарегистрирован: 01.07.2018

Решил рассказать о своем проекте NTP часов. Несмотря на то, что таких проектов большие тысячи, попытаюсь претендовать на оригинальность. С одной стороны это сам «дизайн», если это можно назвать таким словом ), с другой — почему то не встретил проектов часов, которые могли бы делать хоть что то, кроме того, что бы закидывать ежесекундно буржуйский NTP сервер запросами и показывать полученное время. Этакий маленький, безобидный, зато свой DDoS ик. Соответственно, нет соединения, нет времени Я пошел другим путем. Часы собраны всего на этих элементах — Блок пиитания 5V, 400ma модуль ESP 8266 драйвер 7-ми семи сегментного светодиодного индикатора MAX 7219 Датчик температуры и влажности DH11 Стабилизатор AMS1117 на 3.3 V

Основной функционал:

 

Настройка основных параметров производится через WEB морду:

По надписям, думаю, сразу понятно, какой функционал в часах реализован. Если не понятно, дальше будет видео. Часть видео – побаловался в анимацией 3D MAX, не пропадать же было модели, которую рисовал для печати ).

Сам скетч я слепил из различных примеров, которых можно найти бесчисленное множество (хотя, как правило, это будет один и тот же пример, миллион раз у друг друга скопированный). Единственное, что должен заметить — редкий случай, чтобы пример сразу заработал на новой версии IDE Arduino и свежих библиотеках. Почти все скаченное не работало, без предварительной обработки напильником.

Копипастить все материалы и описания, которые вошли в разработку программы, смысла не вижу. Про погодный сайт openweathermap.org стоит загуглить и почитать в любом случае, т.к. на нем потребуется получить персональный ID для доступа и прописать его в код. ID получается бесплатно, но нужно зарегистрироваться. Так же получить ID местности, для которой будет получаться погода GET запросом.

Обращение к нему в этих стоках кода

client.println("GET /data/2.5/weather?id=524901&appid=18535f37de018c7caf730aa957221d6b HTTP/1.1");
client.println("Host: api.openweathermap.org");

   Как говорил ранее, время я считаю по внутреннему таймеру процессора, а при каждом удачном подключении к NTP серверу его корректирую. Периодичность корректировки времени можно задать опять же через WEB морду. По умолчанию — 1 час. Есть фича — если часы уже подключились к WIFI точке, но не смогли прочитать время с NTP, они будут показывать совсем не то время, пока не достучаться до NTP сервера. Исправить не сложно, а вот открутить их от стенки, уже сложнее. Это не большая проблема, но она может произойти, к примеру, после отключения света. Самоустраняется через час, после следующего запроса к серверу или ручного изменения частоты запроса к NTP.

 

Скетч выкладываю.



 
 * Параметры:
 * addr    адрес дисплея драййвера (количество драйверов подключенных последовательно)
 * digit  положение цифры на дисплее (0..7)
 * value  значение, которое будет отображаться. (0x00..0x0F)
 * dp     установка десятичной точки.
 * 
 * 
 * 
void setChar(int addr, int digit, char value, boolean dp);
(адрес драйвера, 0 для 7 индикатора номер цифры, hex значения символа, dp вкл и выкл);
void setDigit(int addr, int digit, byte value, boolean dp);
/* 
 * Установите статус одного Led.
 * Params :
 * addr  адрес дисплея драййвера (количество драйверов подключенных последовательно)
 * row   сегмент-row(seg) (0..7)
 * col   цифра-col(dig) (0..7)
 * boolean state : true включен led, false выключен led  
 *   
 *   void setLed(int addr, int row, int col, boolean state);
 *   зажигаем определенный LED 
 *   at col, row (0,цифра-col(dig),сегмент-row(seg), true) включен led 
 *   at col, row (0,цифра-col(dig),сегмент-row(seg), false) выключен led 
 *   в помощь картинка ниже для определения параметров led
 */ 

//      1          a
//    -----      -----        -----      -----   1100111
//   |6    |2   |f    |b     |     |    |     |   
//   |     |    |     |      |     |    |     |
//    --7--      ---g--       -----      ----- 
//   |5    |3   |e    |c     |     |    |     | 
//   |     |    |     |      |     |    |     |  
//    -----  0   -----  0     -----  0   -----  0 
//      4          d

// col   3         2           1         0
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <Ticker.h>
#include "LedControl.h" //  Подключаем библиотеку
#include "DHT.h"
#include <ArduinoJson.h>


const char* Weatherhost = "api.openweathermap.org";
String line; 
const int httpPort = 80;


#define DHTPIN 14     // what digital pin we're connected to
#define DHTTYPE DHT11   // DHT 11
#define chr_C B10011100
#define chr_i B00001100
#define chr_t B00011110
#define chr_Y B01110110
#define chr_deg B11000110
#define chr_H B01101110
#define chr_P B11001110

DHT dht(DHTPIN, DHTTYPE);

LedControl lc=LedControl(16,4,5,1); 
// pin 5 is connected to the CS (CS)(LOAD)
// pin 4 is connected to the CLK (CLK) 
// pin 16 is connected to LOAD(DIN) 

#define GMT 3 
#define SECS_PER_HOUR 60
const int timeZone = 1;     // Central European Time   


const char* host = "esp8266-Clock";
char ssid[] = "MyRouter";             //  your network SSID (name)
char pass[] = "MyPassWord";        // your network password

byte hour, minute, second;
boolean point;

unsigned int localPort = 2390;      // local port to listen for UDP packets

unsigned long TimeDelta=0;
unsigned long PrevTimeDelta=0;
unsigned long LastUpdateTime=0;
unsigned long LastShowTime=0;
unsigned long lastShowTemp=0;
unsigned long LastUpdateWeather=0;
unsigned long LastShowWeather=0;

int Curhour = 0;
int Curminute = 0;
int Cursecond = 0;

//Edit from site
unsigned long PauseBetwinTemp = 60000; 
unsigned long PauseBetwinWeather = 40000; 
unsigned long TimeShowTH = 2500;
unsigned long NtpReqMs = 3600000;
unsigned long TimeShowSityTH=2800;
int BrightClock=15;



/* Don't hardwire the IP address or we won't get the benefits of the pool. *  Lookup the IP address for the host name instead */
//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
IPAddress timeServerIP; // time.nist.gov NTP server address
const char* ntpServerName = "us.pool.ntp.org";
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message

byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

// A UDP instance to let us send and receive packets over UDP
WiFiUDP   EthernetUdp;

void flip();
void GetNTPTime();
unsigned long sendNTPpacket(IPAddress& address);
void ConvertTime();
ESP8266WebServer server(httpPort);
void HTTP_handleRoot(void);
void handleGenericArgs();
void getTemp();
void WeatherGet();
void ShowWeather();
void FreeChar (byte MyChar, int row, boolean setPoint, int delTime);




void setup()
{

  
  //Инициируем MAX7219
  lc.shutdown(0,false);// включаем дисплей энергосбережение дисплей
  lc.setIntensity(0,BrightClock);// устанвливаем яркость (0-минимум, 15-максимум) 
  lc.clearDisplay(0);// очищаем дисплей 
  
	lc.clearDisplay(0); // 
	delay(500);
	lc.setChar(0,0,'h',false);
	delay(500);
	lc.setChar(0,1,'e',false);
	delay(500);
	lc.setChar(0,2,'l',false);
	delay(500);
	lc.setChar(0,3,'0',false);

	delay(1500);
	lc.setChar(0,0,' ',false); // пустота
	lc.setChar(0,1,' ',false);
	lc.setChar(0,2,' ',false);
	lc.setChar(0,3,' ',false);
	 
	lc.clearDisplay(0);

  Serial.begin(115200); 

  // We start by connecting to a WiFi network
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);
  int row=0;
  while (WiFi.status() != WL_CONNECTED) {
	lc.setLed(0, row, 7, true);
    delay(150);
	row++;
	if (row>3)
	{
		row=0;
		lc.clearDisplay(0);
		delay(150);
	}
	
    Serial.print(".");
  }
  Serial.println("");
  lc.clearDisplay(0);
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  Serial.println("Starting UDP");
  EthernetUdp.begin(localPort);
  Serial.print("Local port: ");
  Serial.println(EthernetUdp.localPort());

  GetNTPTime();    /// синхронизируем время при включении 	  
 
// Запуск WEB-сервера
 MDNS.begin(host);
 server.on ( "/", HTTP_handleRoot );
 server.onNotFound ( HTTP_handleRoot );
 server.begin();    
 Serial.printf( "HTTP server ok! Open http://%s.local in your browser\n", host);

 dht.begin();   	  
 WeatherGet();  
 }



void loop()
{ 
 int row=0;
 while (WiFi.status() != WL_CONNECTED) {
	lc.setLed(0, row, 7, true);
    delay(150);
	row++;
	if (row>3)
	{
		row=0;
		lc.clearDisplay(0);
		delay(150);
	}
  }
// long CurDelta = TimeDelta-PrevTimeDelta; 
 //if(millis()-LastUpdateTime>NtpReqMs || CurDelta<0 || CurDelta+5000<NtpReqMs)
 if(millis()-LastUpdateTime>NtpReqMs)
 {
     GetNTPTime(); 
	 //delay(150);                 
  }
  
  if(millis()-LastShowTime>500)
 {
      ConvertTime();
	  flip(); 
	  LastShowTime=millis();	  
  }
   
    
    if(millis()-lastShowTemp>PauseBetwinTemp)
 {
      getTemp();
	  lastShowTemp=millis();	  
  }
  
   if(millis()-LastUpdateWeather>3600000)
	 {
      WeatherGet();  
	  LastUpdateWeather=millis();
	 }
 
   
   
   	 if(millis()-LastShowWeather>PauseBetwinWeather)
	 {
      ShowWeather();  
	  LastShowWeather=millis();
	 }
 
  // Serial.print("Curhour ");       // UTC is the time at Greenwich Meridian (GMT)
  // Serial.print(Curhour); // print the hour (86400 equals secs per day)
  // Serial.print(" : "); // print the hour (86400 equals secs per day)
  // Serial.print(Curminute);
  
  
   server.handleClient();
  if (server.args()>0)
  {
    handleGenericArgs();
  delay(1500);
  HTTP_handleRoot();
    }
}

void GetNTPTime()
{
  //get a random server from the pool
  WiFi.hostByName(ntpServerName, timeServerIP); 

  sendNTPpacket(timeServerIP); // send an NTP packet to a time server 
  // Serial.print(ntpServerName);
  // Serial.print(": ");
  // Serial.println(timeServerIP);
  sendNTPpacket(timeServerIP);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500) {
    int size = EthernetUdp.parsePacket();
    if (size >= NTP_PACKET_SIZE) {
      
      EthernetUdp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;

	  Serial.print("TimeDelta: ");
      Serial.println("secsSince1900 ");
	  Serial.println(secsSince1900);
      Serial.println("packetBuffer ");
	  Serial.println(packetBuffer[40]);
	  
	  LastUpdateTime = millis(); 	
	  if (secsSince1900>0)
	  {
		TimeDelta=secsSince1900-(millis()/1000);  
	  }

    }
  }



}

void ConvertTime()
{
    unsigned long secsSince1900 = TimeDelta+(millis()/1000);
    // now convert NTP time into everyday time:
   // Serial.print("Unix time = ");
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;
    // print Unix time:
    // корректировка часового пояса и синхронизация 
    epoch = epoch + GMT * 3600;     
    
    Curhour =   (epoch  % 86400L) / 3600;
    Curminute = (epoch  % 3600) / 60;
    Cursecond =  epoch % 60;   
}

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
  Serial.println("sending NTP packet...");
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  EthernetUdp.beginPacket(address, 123); //NTP requests are to port 123
  EthernetUdp.write(packetBuffer, NTP_PACKET_SIZE);
  EthernetUdp.endPacket();
}


void flip(){ 
  point = !point;
  lc.setChar(0,0, Curhour / 10 ,point);  
  lc.setChar(0,1, Curhour % 10 ,point); 
  lc.setChar(0,2, Curminute  / 10 ,point); 
  lc.setChar(0,3, Curminute  % 10 ,point); 
  //delay(600);
  
  

} 




 // Оработчик главной страницы сервер
void HTTP_handleRoot(void) {
 
	String out = "";
	
	int NtpReqMs_sec=NtpReqMs/1000;
	int TimeShowSityTH_sec=TimeShowSityTH/1000;
	int PauseBetwinWeather_sec=PauseBetwinWeather/1000;
	int TimeShowTH_sec=TimeShowTH/1000;
	int PauseBetwinTemp_sec=PauseBetwinTemp/1000;
	
 
	out ="<meta charset=\"utf-8\" />\
		<form method=get name=ptemp>\
		<style>\
		   body { background-color: #88d3fa; font-family: Arial, Helvetica, Sans-Serif; Color: #000080; }\
		</style>\
		<p><span style=""font-size:24px""><span style=""color:#000080""><strong>&nbsp; &nbsp;<img alt=""enlightened"" src=""https://png.pngtree.com/element_origin_min_pic/16/12/17/b3930dbab66d03332b0ded64bb03f69d.jpg"" style=""height:350px; width:242px"" title=""enlightened"" /></strong></span></span></p>\
		<p><font color=""#000080""><b><font size=""7""><var>Настройки часов</var></font></b></font></p>\
		<p>&nbsp;</p>\
		<p>Яркость &nbsp;<input maxlength=""2"" name=""BrightClock"" size=""2"" type=""text"" value="+(String)BrightClock+"></p>\
		<hr />\
		<p>Частота показа домашней температуры и влажности &nbsp;<input maxlength=""10"" name=""PauseBetwinTemp"" size=""10"" type=""text"" value="+(String)PauseBetwinTemp_sec+">&nbsp;(сек)</p>\
		<p>Время показа домашней температуры&nbsp; <input maxlength=""10"" name=""TimeShowTH"" size=""10"" type=""text"" value="+(String)TimeShowTH_sec+">&nbsp;(сек)</p>\
		<p>Частота показа Московской погоды&nbsp;<input maxlength=""10"" name=""PauseBetwinWeather"" size=""10"" type=""text"" value="+(String)PauseBetwinWeather_sec+">&nbsp;(сек)</p>\
		<p>Время показа Московской погоды&nbsp;<input maxlength=""10"" name=""TimeShowSityTH"" size=""10"" type=""text"" value="+(String)TimeShowSityTH_sec+">&nbsp;(сек)</p>\
		<p>&nbsp;</p>\
		<p>Частота обновления с NTP сервера&nbsp;<input maxlength=""10"" name=""NtpReqMs"" size=""10"" type=""text"" value="+(String)NtpReqMs_sec+">&nbsp;(сек)</p>\
		<p>&nbsp;</p>\
		<p>&nbsp;</p>\
		<p><input name=""But1"" type=""submit"" style=""height:40px; width:260px"" value=""Coxранить параметры"" onclick="" location.href='""../""' />  </p>\
		<hr />\
		<p><span style=""font-size:9px""><span style=""font-family:comic sans ms,cursive"">MDB (c) 30.06.2018</span></span></p>\
		";
 
	server.send ( 200, "text/html", out );
}
//<p><span style=""font-size:16px""><span style=""color:#f1c40f""><img alt="""" src=""http://photoshopia.ru/gallery_bkg/data/631/thumbs/black_cats_photoshopia_ru_9.jpg"" style=""float:left; height:120px; width:120px"" /></span></span></p>\


void handleGenericArgs() 
{ 
//Serial.println("-----------------------------------");


for (int i = 0; i < server.args(); i++) {
  String aName=server.argName(i);
  String aVal=server.arg(i);
   
  
	if (aName=="BrightClock") 
		BrightClock=aVal.toInt();
	
	 else if (aName=="PauseBetwinTemp") 
		 PauseBetwinTemp=aVal.toInt()*1000;
    else if (aName=="PauseBetwinWeather") 
		PauseBetwinWeather=aVal.toInt()*1000;  
    else if (aName=="TimeShowTH") 
		TimeShowTH=aVal.toInt()*1000;
    else if (aName=="NtpReqMs") 
		NtpReqMs=aVal.toInt()*1000;
    else if (aName=="TimeShowSityTH") 
		TimeShowSityTH=aVal.toInt()*1000;
   HTTP_handleRoot();
} 

  // Serial.print("TimeDaySw1 ");   
  // Serial.println(TimeDaySw1);  
   
  lc.setIntensity(0,BrightClock);
  
}


void getTemp() {
	
  lc.clearDisplay(0);
  
  
  int h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  int t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  //float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }


  lc.setChar(0,0, t  / 10 ,point); 
  lc.setChar(0,1, t  % 10 ,point); 
  
  // lc.setLed(0, 2, 1, true);
  // lc.setLed(0, 2, 2, true);
  // lc.setLed(0, 2, 7, true);
  // lc.setLed(0, 2, 6, true);
  FreeChar (chr_deg, 2, true,200); 
  delay (TimeShowTH);
 
  lc.clearDisplay(0);
 
  FreeChar (chr_H, 2, true,200); //C
  lc.setChar(0,2,'h',true);  
  lc.setChar(0,0, h / 10 ,point);  
  lc.setChar(0,1, h % 10 ,point); 
  delay (TimeShowTH);  
}



	
void WeatherGet() {
  
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(Weatherhost, httpPort)) {
    Serial.println("connection failed");
    return;
  }
  
    client.println("GET /data/2.5/weather?id=524901&appid=18535f37de018c7caf730aa957221d6b HTTP/1.1");
    client.println("Host: api.openweathermap.org");
    client.println("Connection: close");
    client.println();
 
  delay(1500);
  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    line = client.readStringUntil('\r'); 
  }
  Serial.print(line);
  Serial.println();
  Serial.println("closing connection");
}


void ShowWeather()
{
   StaticJsonDocument<1400> doc;
   DeserializationError error = deserializeJson(doc, line);
  // Test if parsing succeeds.
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return;
  }

  // Test if parsing succeeds.
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return;
  }

  // Get the root object in the document
  JsonObject& root = doc.as<JsonObject>();  
  float tempK = root["main"]["temp"];                   // достаем температуру из структуры main
  float tempC = tempK - 273.15;                         // переводим кельвины в цельси
  
  int pressurehPa = root["main"]["pressure"]; 
  float pressure = pressurehPa/1.333;

  int humidity = root["main"]["humidity"]; 
 
  lc.clearDisplay(0); 
  FreeChar (chr_C, 0, true,50); //C
  FreeChar (chr_i, 1, true,50); 
  FreeChar (chr_t, 2, true,50); 
  FreeChar (chr_Y, 3, true,50); 
  delay(700);  
  
  lc.clearDisplay(0); 
   
  if (tempC<0)
  {
	lc.setLed(0, 1, 7, true); 	
	tempC = -tempC;
	delay(400);
  }	
  lc.setChar(0,2, (int)tempC / 10 ,point);  
  lc.setChar(0,3, (int)tempC % 10 ,point); 
  FreeChar (chr_t, 0, true,200);  
  for (int a=1; a<4;a++)
  {
	  FreeChar (chr_t, 0, true,0);
	  delay(200);
	  lc.setChar(0,0, ' ' ,point);
	  delay(100);
  }
  delay(TimeShowSityTH); 
  
  lc.clearDisplay(0);   
  lc.setChar(0,2, (int)humidity / 10 ,point);  
  lc.setChar(0,3, (int)humidity % 10 ,point);  
  FreeChar (chr_H, 0, true,200);
  for (int a=1; a<4;a++)
  {
	  FreeChar (chr_H, 0, true,0);
	  delay(200);
	  lc.setChar(0,0, ' ' ,point);
	  delay(100);
  }  
 
  delay(TimeShowSityTH); 
  
  lc.clearDisplay(0);  
 
  lc.setChar(0,1, (int)pressure / 100 ,false);  
  lc.setChar(0,2, (int)pressure % 100/ 10 ,false);  
  lc.setChar(0,3, (int)pressure % 10 ,false);  
  FreeChar (chr_P, 0, true,200);
  for (int a=1; a<4;a++)
  {
	  FreeChar (chr_P, 0, true,0);
	  delay(200);
	  lc.setChar(0,0, ' ' ,point);
	  delay(100);
  }  
  delay(TimeShowSityTH); 
  
	
}



void FreeChar (byte MyChar, int row, boolean setPoint, int delTime)
{ 
  int sectNum=1;
  for (int i=7; i>-1; i--)
  {
     if (MyChar & (1<<i))
     lc.setLed(0, row, sectNum, true);    
     sectNum++;
     delay(delTime);
  } 
   Serial.println("");
}

 

Корпус

Корпус нарисовал в 3d max и напечатал на 3D принтере пластиком SBS . Прозрачные сегменты печатал отдельно, бесцветным SBSом потом наклеивал супер-клеем. Вот такой «милый» конструктор у меня получился:

 

 

Dmitry Matveev
Dmitry Matveev аватар
Offline
Зарегистрирован: 01.07.2018

Светодиоды воткнул по 2 на сегмент. Не стал вставлять центральный, т.к. и 2 вполне достаточно, ну и лень, в добавок. Занятие это, оказалось самым трудоемким. Далее вывел провода в центральную коробку корпуса. Обратную сторону (ту, с которой втыкал диоды) не стал ни чем закрывать, залил горячими соплями, что бы ничего не отвалилось (провода и сами диоды). Причем заливал так: Накидал обрезки трубок клея и расплавил паяльным феном, получилось достаточно ровно и красиво. С синим цветом, по моему, ошибся - не очень хорошо видно, лучше другие цвета использовать.

 

Блок Питания

Хочу рассказать об этом отдельно. Использовал самый дешевый 5V блок питания (порядка 80 руб). Понятно, что для ESP нужно 3.3 v, но для драйвера MAX — 5 v. Большинство схем просмотренных мной на просторах интернета, говорят о том, что Максиму этому и 3.3 v вполне хватит... Но, я больше верю Даташиту производителя.

Как то случайно заметил на плате питания пустое место, которое мне что то напомнило по форме (вполне приличное, разумеется).

И, вот оно, чудо! Просто добавь AMS1117!

По даташиту положено еще 2 конденсатора на выход. Их я разместил уже на самой плате.

 

Плата часов

В связи с некоторыми трагичными обстоятельствами, рисунки платы (lay6) были утрачены бесследно. Выложить не смогу. Но, думаю срисовать или нарисовать круче по своему, никакого труда у не составит, если вдруг, появится желание. Схема устройства — практически нарисована в Даташите на MAX 7219. Тут про саму идею -

Плата двусторонняя, изготовлена фоторезистом. Блок питания разместил прямо на плате, пытаясь сэкономить место и избавиться от проблем с его креплением в корпусе. Предусмотрел на плате штекер для подключения USB конвертора и перемычку, при установки которой ESP переходит в режим программирования. Таким образом получил и готовое устройство и отладочную плату, как говориться все в одном. Причем, достаточно комфортно использовать программатор только с RX и TX. REST сделал кнопкой и это ничуть не напрягало. Штекер для DH11 в последствии убрал и поставил на его место сам DH11, места за счет этого стало больше. Так же пришлось пожертвовать штекером питания.

 

Вот так выглядит обратная сторона платы.

Антенну, изначально использовать не хотел. Но без нее не захотел у меня ESP к точке цепляться. Дом перегружен сетями и сколько бы я роутеров не сменил, во все углы квартиры, все равно не добивает. Название антены для покупки - ESP8266 ESP-07 Remote Serial Port WIFI Transceiver Wireless Module.

 

Ну и видео тут

https://www.youtube.com/attribution_link?a=f0oOxTUqe6r80ql4&u=/watch%3Fv%3DtZqPHaRlwm4%26feature%3Dem-share_video_user

yucan
Offline
Зарегистрирован: 20.04.2015

Дмитрий, что это ? 3D- печать или какой то готовый набор? 

yucan
Offline
Зарегистрирован: 20.04.2015

И ещё просьба - если можно, бинарник выложите. Компиляция не проходит. В разных версиях IDE пробовал - куча ошибок...

yucan
Offline
Зарегистрирован: 20.04.2015

Про корпуса прочитал, что сделаны 3D печатью)

Dmitry Matveev
Dmitry Matveev аватар
Offline
Зарегистрирован: 01.07.2018

Спасибо за интерес. Бинарник не прокатит. Там нужен свой ИД прописать на погоду, свои данные по Wi Fi точке. А чтоб не было ошибок, нужно все библиотеки установить/ обновить до последней версии, и платформу arduino то же обновить.

yucan
Offline
Зарегистрирован: 20.04.2015

Спасибо за ответ. Значит из веб интерфейса этого сделать нельзя?

Какую версию ардуино IDE Вы использовали?