Пользует ли кто WiFi-модули ESP8266 ? Поделитесь впечатлениями.

Samodelkin
Offline
Зарегистрирован: 07.06.2012

А вот подскажите, можно ли средствами esp парсить сайт (например вытянуть с сайта курс валют или другие даннын) и зашпульнуть это в юарт ардуины?

Logik
Offline
Зарегистрирован: 05.08.2014

Можна. Хоть NodeMCU+Lun хоть свою прошу на Wiringe (ну на Си  в общем) из ИДЕ ардуиновского. В своем коде делаете что хотите, парсите шлите в юарт и пр.

Logik
Offline
Зарегистрирован: 05.08.2014

sadman41 пишет:

Знаете, не всегда стоит тех, кто пишет на этот форум, считать глупыми рукожопами, которые на самом деле повара, но зачем-т взяли в руки ардуину ;) 

Я лил ту прошивку, под которую нашел библиотеку с подходящим мне синтаксисом. У NodeMCU, который был залит первоначально  в мой ESP, я не нашёл способа извлечения входящих данных и внешнего управления процессом коммуницирования со внешним хостом.

Второй абзац как раз и дает основания считать так, как в первом описано;)

sadman41 пишет:

Цитата:
Полученый поток данных ESP отправляет по UART. Из W5100 контроллер тоже извлекает поток данных. Два потока данных у контролера есть, он выбирает какой нужен и начинает парсить пакет, отсылать ответ и т.д. уже единообразно.

Написать можно всё, но не все стоит того, чтобы писать. Мысль я вашу понимаю, но пока не вижу простого способа интеграции ESP в свой проект. А перекурочивать отлаженный код ради модной возможности засрать эфир мне как-то пока не хочется. 

 Невидете так не видете. Забейте. Проехали, действительно засерать эфир не стоит.

Samodelkin
Offline
Зарегистрирован: 07.06.2012

Logik пишет:

Можна. Хоть NodeMCU+Lun хоть свою прошу на Wiringe (ну на Си  в общем) из ИДЕ ардуиновского. В своем коде делаете что хотите, парсите шлите в юарт и пр.

Это хорошо,  а где бы посмотреть примеры или алгоритм? Может чтиво есть какое? Из опыта делал парсер на питоне, еще примеры на php изучал, а с этим прям не знаю как )) 

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

Samodelkin пишет:

Logik пишет:

Можна. Хоть NodeMCU+Lun хоть свою прошу на Wiringe (ну на Си  в общем) из ИДЕ ардуиновского. В своем коде делаете что хотите, парсите шлите в юарт и пр.

Это хорошо,  а где бы посмотреть примеры или алгоритм? Может чтиво есть какое? Из опыта делал парсер на питоне, еще примеры на php изучал, а с этим прям не знаю как )) 

сайт напрямую сложно, а вот для систем, котоые имеют API вполне себе можно

Logik
Offline
Зарегистрирован: 05.08.2014

Сложно, если весь DOM разбирать по полочкам. Если выцепить чего по уникальному фрагменту то чепуховина.

Samodelkin
Offline
Зарегистрирован: 07.06.2012

Logik пишет:

Сложно, если весь DOM разбирать по полочкам. Если выцепить чего по уникальному фрагменту то чепуховина.

Да, нужно именно фрагмент

 

Logik
Offline
Зарегистрирован: 05.08.2014

Samodelkin пишет:

Logik пишет:

Сложно, если весь DOM разбирать по полочкам. Если выцепить чего по уникальному фрагменту то чепуховина.

Да, нужно именно фрагмент

 

ключевое слово "уникальный". Если так, то просто поиск. Если сложней, можна вспомнить про регулярные выражения (к матюкам это никак не относится).

Logik
Offline
Зарегистрирован: 05.08.2014

В процессе написания в IDE 1.6.5 кода вебсервака наткнулся на неприятный факт, попытка сделать страничку немного более чем хелоуворд приводит к проблеме. обявляю

const char* PROGMEM webs="<html><head><meta charset='utf-8'></head>....

 

и т.д. всего строк 20, при компиляции вываливает

at java.util.regex.Pattern$CharProperty.match(Pattern.java:3777)
at java.util.regex.Pattern$Branch.match(Pattern.java:4604)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4658)
at java.util.regex.Pattern$Loop.match(Pattern.java:4785)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4717)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4568)
 
далее многократно повторяющееся. Без указания на ошибку и др. сообщений. При этом по прогресбару 3 деления и компиляция не завершается никогда. Подозреваю что проявляется проблема отправки только одного пакета TCP, а при более - фиг. Я такое в луне видел и лечил, но только там на стадии выполнения. Сокращение странички приводит к нормальной работе.
Кто чего про это знает?
andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Для начала все служебеые символы внутри кавычек заменить на управляющие последовательности. (' => \')

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

andriano пишет:

Для начала все служебеые символы внутри кавычек заменить на управляющие последовательности. (' => \')

andriano будьте так любезны ткните носом где про это можно почитать, желательно по русски.

у меня на такое компилятор ругается варнингом

String html_script()
{
  String str = "<script>\n\
  var xmlHttp=createXmlHttpObject();\n\
  \
  function createXmlHttpObject()\n\{\n\
  if(window.XMLHttpRequest)\n\{\n\
  xmlHttp=new XMLHttpRequest();\n\}\n\
  else{\n\
  xmlHttp=new ActiveXObject('Microsoft.XMLHTTP');\n\}\n\
  return xmlHttp;\n}\n\
  \
  function process(){\n\
  if(xmlHttp.readyState==0 || xmlHttp.readyState==4){\n\
  xmlHttp.open('PUT','xml',true);\n\
  xmlHttp.onreadystatechange=handleServerResponse;\n\
  xmlHttp.send(null);\n}\n\
  setTimeout('process()',1000);\n}\n\
  \
  function handleServerResponse(){\n\
  if(xmlHttp.readyState==4 && xmlHttp.status==200){\n\
  xmlResponse=xmlHttp.responseXML;\n\
  xmldoc=xmlResponse.getElementsByTagName('current');\n\
  document.getElementById('cur_time').value=xmldoc[0].firstChild.nodeValue;\n\
  }\n}\n\
  </script>\n";
  return str;
  str = String();
}

На первые две строчки внутри функции

Вот так это выглядит в браузере


  var xmlHttp=createXmlHttpObject();
    function createXmlHttpObject()
{
  if(window.XMLHttpRequest)
{
  xmlHttp=new XMLHttpRequest();
}
  else{
  xmlHttp=new ActiveXObject('Microsoft.XMLHTTP');
}
  return xmlHttp;
}
    function process(){
  if(xmlHttp.readyState==0 || xmlHttp.readyState==4){
  xmlHttp.open('PUT','xml',true);
  xmlHttp.onreadystatechange=handleServerResponse;
  xmlHttp.send(null);
}
  setTimeout('process()',1000);
}
    function handleServerResponse(){
  if(xmlHttp.readyState==4 && xmlHttp.status==200){
  xmlResponse=xmlHttp.responseXML;
  xmldoc=xmlResponse.getElementsByTagName('current');
  document.getElementById('cur_time').value=xmldoc[0].firstChild.nodeValue;
  }
}
  

 

Logik
Offline
Зарегистрирован: 05.08.2014

andriano пишет:

Для начала все служебеые символы внутри кавычек заменить на управляющие последовательности. (' => \')

Это разумеется самособой. В HTML в основном с двойніми кавічками затык, но они заменяются на одинарніе и все. или обратную косую перед ними. Если этого не делать то ругается корректно

error: missing terminating " character

А вот от длины сообщения по прежнему фигня.

Logik
Offline
Зарегистрирован: 05.08.2014

В общем оно просто глючит :( Код без внесения изменений иногда собирается, иногда нет.

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

Logik пишет:

В общем оно просто глючит :( Код без внесения изменений иногда собирается, иногда нет.

Мое мнение - лутче сервер писать вовне. С еспишки тока запускать. Сами страницы хранить в  виде html. хоть на том же spiffs, или на SD. Я когда делал примитивную вебморду в 5 закладок по 10 строк у меня тоже все дико глючило. Там же везде String(). Это неимоверно жрет ОЗУ

Logik
Offline
Зарегистрирован: 05.08.2014

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

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015
String str = "Начало";
str += "продолжение";
...
str += "конец";

может так попробывать?

Logik
Offline
Зарегистрирован: 05.08.2014

Я String не использую,  хочу const char* PROGMEM. Втулил посреди длинной строки "+". Не шарит "invalid operands of types 'const char [625]' and 'const char [246]' to binary 'operator+'" Но в общем и не должен шарит. Зато теперь знаю длину проблемной строки 871 символ. На размер пакета TCP не тянет. Глючит просто. Зараза.

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

c /const char* PROGMEM/ низзя делать "+" или "-"

Попробуйте несколько разных const char* желательно не более 255 символов.

Logik
Offline
Зарегистрирован: 05.08.2014

Не, с const char* вобщето тоже низя. Просто уже ясно что не в том дело.

Компиляция одного и того же кода проходит раз с 3-5 запусков. Оно просто глючит.

Шоле на ИДЕ новей перейти? или поддержку ESP переставить? ХЗ...

Logik
Offline
Зарегистрирован: 05.08.2014

Причем глючит препроцесор ардуиновский. Если в коде есть ошибка то её находит тоже с 3-5 запуска.

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

Logik пишет:

Шоле на ИДЕ новей перейти? или поддержку ESP переставить? ХЗ...

Или код в студию (тогда поржем) проверим на иде 1,8,1 с версией есп 2,3,0

Logik
Offline
Зарегистрирован: 05.08.2014

Та ржите, мне не жалко. Как есть, даю, прям в процессе, пока либ не понацеплял, там sha, base64 и прочая дребедень щас будет цеплятся ...

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char* ssid = "хервам";
const char* password = "хервамхервам";

WiFiServer serverWS(5000);

ESP8266WebServer server(80);

const char* PROGMEM webs="<html><head><meta charset='utf-8'></head><h1>Svetofor</h1>   \
<table><tr><td><input type='button' onclick='OpenWS()' value='Open'/> \
</td><td><input type='button' onclick='CloseWS()'value='Close'/>  \
</td><td><input type='button' onclick='snd(22)' value=\"Send\"/>  \
</td><td><input type='button' onclick='ld()' value='Load'/>                                  \
</td></tr></table>  \
<script language='Javascript'>  \
ESP_URL = 'ws://192.168.0.21:5000'; \
cmdPas='^9h87hg8yg'; \
var socketW=null;  \
function RecWS(messageEvent){}   \
function snd(d){if(socketW!=null)socketW.send(d);}  \
function OpenWS() {                                                  \
if(socketW==null) socketW= new WebSocket(ESP_URL);                                 \
  if(socketW!=null){socketW.onmessage=RecWS;}                         \
}                                                            \
</script></html>  \
";


void handleRoot() {
  server.send(200, "text/html", webs);
}

void handleNotFound(){
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

// пины для SPI
#define PIN_DATA_SPI 12
#define PIN_CLK_SPI  16
#define PIN_SET_SPI  14

//логический порядок сигналов 
#define SVET_DONE 4 
#define SVET_PLS  2 
#define SVET_UP   1 
#define SV1(a) (a<<4) //сдвиг  SVET_хх для получения распайки на 74HC595 
#define SV2(a) (a<<1) //сдвиг  SVET_хх для получения распайки на 74HC595 




void setup() {
	delay(1000);
	Serial.begin(115200);
  WiFi.begin(ssid, password);

  

  pinMode(PIN_DATA_SPI, OUTPUT);
  pinMode(PIN_CLK_SPI, OUTPUT);
  pinMode(PIN_SET_SPI, OUTPUT);


}



void SetSPI(byte c)
{

  for(byte i=0;i<8;i++)
  {
   digitalWrite(PIN_CLK_SPI, LOW);  
   digitalWrite(PIN_DATA_SPI, c&_BV(7-i));
   digitalWrite(PIN_CLK_SPI, HIGH);
  }
}

void OutSPI(byte b)
{
  digitalWrite(PIN_SET_SPI, LOW);
  SetSPI(b); 
  digitalWrite(PIN_SET_SPI, HIGH);
  
}

void OutBufSPI(byte* b, byte len)
{
  digitalWrite(PIN_SET_SPI, LOW);
  for(byte i=len;i;i--){SetSPI(b[i-1]);} 
  digitalWrite(PIN_SET_SPI, HIGH);
}

//этими макросами задаем цвета мигания
#define UP_RED     1
#define UP_GREEN   2
#define UP_YELLOW  3
#define DONE_RED     4
#define DONE_GREEN   8
#define DONE_YELLOW  12
#define BLINK_PHASE(a)  (a<<4)             //для смены фазы мигания
#define BLINK_NO(a)  (a |  BLINK_PHASE(a)) // для горения без мигания

byte t;  

byte processSvetofor(byte mode, byte next=0)
{
  static byte m;
  static byte bl;
    
  if(next)
    m++;
  if(m==80) //пора мигнуть
  {
     m=0;
     bl=!bl; //фаза мигания
  }
   if(bl)
     mode=mode>>4;
    byte p=m&2?SVET_PLS:0; //реверса SVET_PLS и остальных выводов
    if(m&1) mode&=0xaa; //светим красный через раз для выравнивания яркрсти с зеленым
    if(p)
    {
      if(!(mode&UP_GREEN))p|=SVET_UP; //не UP_GREEN  или UP_YELLO
      if(!(mode&DONE_RED))p|=SVET_DONE;
    }
    else
    {
      if((mode&UP_RED))  p|=SVET_UP;
      if((mode&DONE_GREEN)) p|=SVET_DONE;
    }
    return p;
 
}

bool timerSvetofor(void)
{
  static byte T;
  if(byte(t-T)>6) 
  {
    T+=6;
    return true;
  }
  return false;
}


// таблица режимов сменяющих друг друга по циклу
byte SV_cikle[]=
{
  UP_RED| BLINK_PHASE(DONE_YELLOW),
  BLINK_NO(UP_GREEN), 
  BLINK_NO(UP_RED),
  BLINK_NO(DONE_YELLOW),
  BLINK_NO(DONE_YELLOW)|UP_YELLOW,
  DONE_YELLOW|BLINK_PHASE(UP_YELLOW),
  BLINK_NO(DONE_GREEN), 
  BLINK_NO(DONE_RED),
  UP_RED|BLINK_PHASE(UP_GREEN),
  UP_RED|BLINK_PHASE(UP_YELLOW),
};











//unsigned long previousMillis = 0;
//const long interval = 500;
//int r;

byte DataSPI[3];
byte Svetofor[2*sizeof(DataSPI)];

void loop() {
  static byte c;
  static byte T;
  
  t=millis();
  if(byte(t-T)>250) //формируем 0,25сек для счета смены режима
  {
    T+=250;
    static byte n;
    
    if(n) //не пора менять режим
     n--;
    else
    {    //пора менять режим
     n=10;
     static byte m;
     Svetofor[0]=SV_cikle[m++];
     if(m==sizeof(SV_cikle)) //организовуем цикл
       m=0;
     Svetofor[1]=SV_cikle[m];
    }
    
  }

  if(timerSvetofor())
  {
    for(byte i=0;i<sizeof(DataSPI);i++)
    {
     DataSPI[i]=SV1(processSvetofor(Svetofor[2*i],!i))|SV2(processSvetofor(Svetofor[2*i+1]));
    }
    OutBufSPI(DataSPI, sizeof(DataSPI));
  }
  
  
  static bool FlStart=true;
  
 if((WiFi.status() == WL_CONNECTED) && (FlStart))
 {
  FlStart=false;
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
    MDNS.addService("http", "tcp", 80);
    MDNS.addService("ws", "tcp", 5000);
  }

  server.on("/", handleRoot);
  server.onNotFound(handleNotFound);
  server.begin();
  Serial.println("HTTP server started");
  serverWS.begin();
 }
 server.handleClient();

 TCPServer ();
}

#define HEAP_PAGE_SIZE 256
void TCPServer () 
{
  static WiFiClient client;
  static bool(*FnRecive)(uint8_t* pBuf, word LenData);
  if (client) 
  {
    if (client.connected()) 
    {
      static uint8_t* pBuf;
      static word LenBuf;
      static word LenData;
      
      word l;
     if (l=client.available() > 0) 
     {
      word LenData1=LenData+l;         
      word LenBuf1=((LenData1/HEAP_PAGE_SIZE)+1)*HEAP_PAGE_SIZE;
      if(pBuf)
      {
        if(LenData+l>LenBuf)
        {
          uint8_t* pBuf1=new uint8_t[LenBuf];
          memcpy(pBuf, pBuf1, LenData);
          delete[] pBuf;
          pBuf=pBuf1;
        }
     }
      else
        pBuf=new uint8_t[LenBuf1];

      client.read(pBuf+LenData, l); 
      LenData=LenData1;
      LenBuf=LenBuf1;

      if(FnRecive(pBuf,LenData))
      {
        delete[] pBuf;
        pBuf=NULL;
        LenBuf=0;
        LenData=0;
      }

      
     }
    }
  }
  else 
  {
   client = serverWS.available();
   FnRecive=[](uint8_t* pBuf, word LenData)->bool
   {
    Serial.write(pBuf,LenData);
    return true;
   };
  }
}

Это будет управление сфетофорами на цепочке 74hc595(грубо говоря светодиодами на ЖД макете) по WebSocet.

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

https://yadi.sk/d/Gjqw1w7o3GT3NK результат компиляции

Скетч использует 251171 байт (24%) памяти устройства. Всего доступно 1044464 байт.
Глобальные переменные используют 36736 байт (44%) динамической памяти, оставляя 45184 байт для локальных переменных. Максимум: 81920 байт.
 
Logik
Offline
Зарегистрирован: 05.08.2014

И стабильно?

У меня в 20% попыток тоже выдает.

 
Sketch uses 246 514 bytes (23%) of program storage space. Maximum is 1 044 464 bytes.
Global variables use 36 388 bytes (44%) of dynamic memory, leaving 45 532 bytes for local variables. Maximum is 81 920 bytes.
pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

2 раза подряд без проблем

Logik
Offline
Зарегистрирован: 05.08.2014

Неохота третий ИДЕ ставить. Зоопарк получится ;) Буду еще думать.

Logik
Offline
Зарегистрирован: 05.08.2014

Значить пофиксили таки в 1.8.1

Logik
Offline
Зарегистрирован: 05.08.2014

О как оно умеет, если границу выделеной памяти нарушить, молодца! Хароший проц! Не то что некоторые )))

 
Exception (3):
epc1=0x401003e9 epc2=0x00000000 epc3=0x00000000 excvaddr=0x400279e9 depc=0x00000000
 
ctx: sys 
sp: 3ffffd50 end: 3fffffb0 offset: 01a0
 
>>>stack>>>
3ffffef0:  3ffeaf57 3ffeaf3c 3ffeaf44 3ffeaf51  
3fffff00:  00000000 3ffeafb3 3ffeafcf 40105cd8  
3fffff10:  00219bed 3ffef1c4 000003e8 401004d8  
3fffff20:  3ffefda8 40222ff6 00000012 40106b44  
3fffff30:  40222dc3 00000000 00000000 4022a5f2  
3fffff40:  40105cd8 00000000 40105cf1 00000000  
3fffff50:  4022a72c 3ffeddb8 0021ba3b 4022a725  
3fffff60:  00000000 4021d825 3ffee548 3ffee570  
3fffff70:  0e07a28b 60000600 3ffe9430 3ffe9430  
3fffff80:  4021d86a 3fffdab0 00000000 3fffdcb0  
3fffff90:  3ffee588 3fffdad0 3ffefdb4 40206623  
3fffffa0:  40000f49 40000f49 3fffdab0 40000f49  
<<<stack<<<
 
 ets Jan  8 2013,rst cause:4, boot mode:(1,0)
 
Logik
Offline
Зарегистрирован: 05.08.2014

Усе. Заработало. Ни коментов ни структуры, ни излишков интерфейса. Чистый функционал. 

Поправлены ошибки выложеного ранее кода и добито до конца.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include "sha1.h"

const char* ssid = "нафиг";
const char* password = "нафигнафигнафиг";

WiFiServer serverWS(5000);

ESP8266WebServer server(80);

const char* PROGMEM webs="<html><head><meta charset='utf-8'></head><h1>Svetofor</h1> \
<table><tr><td><input type='button' onclick='OpenWS()' value='Open'/> \
</td><td><input type='button' onclick='CloseWS()'value='Close'/> \
</tr><tr> \
</td><td><input type='button' onclick='snd(0x11)' value=\"UpRed\"/> \
</td><td><input type='button' onclick='snd(0x22)' value=\"UpGreen\"/> \
</td><td><input type='button' onclick='snd(0x33)' value=\"UpYellow\"/> \
</td><td><input type='button' onclick='snd(0x44)' value=\"Red\"/> \
</td><td><input type='button' onclick='snd(0x88)' value=\"Green\"/> \
</td><td><input type='button' onclick='snd(0xcc)' value=\"Yellow\"/> \
</td><td><input type='button' onclick='snd(0x04)' value=\"Red blink\"/> \
</td></tr></table> \
<script language='Javascript'> \
ESP_URL = 'ws://192.168.0.21:5000'; \
var socketW=null;  \
function RecWS(messageEvent){} \
function snd(d){if(socketW!=null)socketW.send(d);} \
function OpenWS(){if(socketW==null) socketW= new WebSocket(ESP_URL);if(socketW!=null){socketW.onmessage=RecWS;} \
}  \
function OnClose(Event){socketW=null;}  \
</script></html> \
";

  enum {
        NOINIT,
        NOCONECT,
        CONECT_ERR,
        ND,
        CLOSE,
        CONECT,
        FRAME_TEXT,
        FRAME_BIN,
        FRAME_CONT,
        FRAME_CLOSE,
        FRAME_PING,
        FRAME_PONG,
        FRAME_UNDEF
        };
        
void handleRoot() {
  server.send(200, "text/html", webs);
}

void handleNotFound(){
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

// пины для SPI
#define PIN_DATA_SPI 12
#define PIN_CLK_SPI  16
#define PIN_SET_SPI  14

//логический порядок сигналов 
#define SVET_DONE 4 
#define SVET_PLS  2 
#define SVET_UP   1 
#define SV1(a) (a<<4) //сдвиг  SVET_хх для получения распайки на 74HC595 
#define SV2(a) (a<<1) //сдвиг  SVET_хх для получения распайки на 74HC595 




void setup() {
	delay(1000);
	Serial.begin(115200);
  WiFi.begin(ssid, password);

  

  pinMode(PIN_DATA_SPI, OUTPUT);
  pinMode(PIN_CLK_SPI, OUTPUT);
  pinMode(PIN_SET_SPI, OUTPUT);


}



void SetSPI(byte c)
{

  for(byte i=0;i<8;i++)
  {
   digitalWrite(PIN_CLK_SPI, LOW);  
   digitalWrite(PIN_DATA_SPI, c&_BV(7-i));
   digitalWrite(PIN_CLK_SPI, HIGH);
  }
}

void OutSPI(byte b)
{
  digitalWrite(PIN_SET_SPI, LOW);
  SetSPI(b); 
  digitalWrite(PIN_SET_SPI, HIGH);
  
}

void OutBufSPI(byte* b, byte len)
{
  digitalWrite(PIN_SET_SPI, LOW);
  for(byte i=len;i;i--){SetSPI(b[i-1]);} 
  digitalWrite(PIN_SET_SPI, HIGH);
}

//этими макросами задаем цвета мигания
#define UP_RED     1
#define UP_GREEN   2
#define UP_YELLOW  3
#define DONE_RED     4
#define DONE_GREEN   8
#define DONE_YELLOW  12
#define BLINK_PHASE(a)  (a<<4)             //для смены фазы мигания
#define BLINK_NO(a)  (a |  BLINK_PHASE(a)) // для горения без мигания

byte t;  

byte processSvetofor(byte mode, byte next=0)
{
  static byte m;
  static byte bl;
    
  if(next)
    m++;
  if(m==80) //пора мигнуть
  {
     m=0;
     bl=!bl; //фаза мигания
  }
   if(bl)
     mode=mode>>4;
    byte p=m&2?SVET_PLS:0; //реверса SVET_PLS и остальных выводов
    if(m&1) mode&=0xaa; //светим красный через раз для выравнивания яркрсти с зеленым
    if(p)
    {
      if(!(mode&UP_GREEN))p|=SVET_UP; //не UP_GREEN  или UP_YELLO
      if(!(mode&DONE_RED))p|=SVET_DONE;
    }
    else
    {
      if((mode&UP_RED))  p|=SVET_UP;
      if((mode&DONE_GREEN)) p|=SVET_DONE;
    }
    return p;
 
}

bool timerSvetofor(void)
{
  static byte T;
  if(byte(t-T)>6) 
  {
    T+=6;
    return true;
  }
  return false;
}


// таблица режимов сменяющих друг друга по циклу
byte SV_cikle[]=
{
  UP_RED| BLINK_PHASE(DONE_YELLOW),
  BLINK_NO(UP_GREEN), 
  BLINK_NO(UP_RED),
  BLINK_NO(DONE_YELLOW),
  BLINK_NO(DONE_YELLOW)|UP_YELLOW,
  DONE_YELLOW|BLINK_PHASE(UP_YELLOW),
  BLINK_NO(DONE_GREEN), 
  BLINK_NO(DONE_RED),
  UP_RED|BLINK_PHASE(UP_GREEN),
  UP_RED|BLINK_PHASE(UP_YELLOW),
};









  struct WebSockFrame
  {
    char Opcod;
    char Flags;
    long int Len;
    char* pData;
  };
WebSockFrame w;
 
char* GetText(WebSockFrame w);

//unsigned long previousMillis = 0;
//const long interval = 500;
//int r;

byte DataSPI[3];
byte Svetofor[2*sizeof(DataSPI)];

void loop() {
  static byte c;
  static byte T;
  
  t=millis();
  if(byte(t-T)>250) //формируем 0,25сек для счета смены режима
  {
    T+=250;
    static byte n;
    
    if(n) //не пора менять режим
     n--;
    else
    {    //пора менять режим
     n=10;
     static byte m;
     Svetofor[0]=SV_cikle[m++];
     if(m==sizeof(SV_cikle)) //организовуем цикл
       m=0;
    // Svetofor[1]=SV_cikle[m];
    }
    
  }

  if(timerSvetofor())
  {
    for(byte i=0;i<sizeof(DataSPI);i++)
    {
     DataSPI[i]=SV1(processSvetofor(Svetofor[2*i],!i))|SV2(processSvetofor(Svetofor[2*i+1]));
    }
    OutBufSPI(DataSPI, sizeof(DataSPI));
  }
  
  
  static bool FlStart=true;
  
 if((WiFi.status() == WL_CONNECTED) && (FlStart))
 {
  FlStart=false;
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
    MDNS.addService("http", "tcp", 80);
    MDNS.addService("ws", "tcp", 5000);
  }

  server.on("/", handleRoot);
  server.onNotFound(handleNotFound);
  server.begin();
  Serial.println("HTTP server started");
  serverWS.begin();
 }
 server.handleClient();

 if(TCPServer ()==FRAME_TEXT)
 {
  Serial.print("WS text[");
  Serial.print(GetText(w));
  Svetofor[1]=atoi(GetText(w));
  Serial.println("]");
 }
}
const char WebSocketGet[]="GET / HTTP/1.1\r\n";
const char WebSocketEnd[]="\r\n\r\n";
const char WebSocketAnsvKey[]="Sec-WebSocket-Key: ";
const char WebSocketAnsvKeyEnd[]="==\r\n";
const char WebSockAnsv[]="HTTP/1.1 101 Switching Protocols\r\n\
Upgrade: websocket\r\n\
Connection: Upgrade\r\n\
Sec-WebSocket-Accept: ";


 
#define HEAP_PAGE_SIZE 256

long int DecodeFrame(char* b, long int l, WebSockFrame* f);
char TCPServer () 
{
  static WiFiClient client;
  static bool(*FnRecive)(uint8_t* pBuf, word LenData, char* rc);
  if (client) 
  {
    if (client.connected()) 
    {
      static uint8_t* pBuf;
      static word LenBuf;
      static word LenData;
      
      word l;
     if (l=client.available() > 0) 
     {
      word LenData1=LenData+l;         
      word LenBuf1=((LenData1/HEAP_PAGE_SIZE)+1)*HEAP_PAGE_SIZE;
      if(pBuf)
      {
        if(LenData1>LenBuf)
        {
          uint8_t* pBuf1=new uint8_t[LenBuf1];
          memcpy(pBuf1, pBuf, LenData);
          delete[] pBuf;
          pBuf=pBuf1;
          LenBuf=LenBuf1;
        }
     }
      else
      {
        pBuf=new uint8_t[LenBuf1];
        LenBuf=LenBuf1;
      }
      client.read(pBuf+LenData, l); 
      LenData=LenData1;

      char retcode;
      if(FnRecive(pBuf,LenData, &retcode))
      {
        delete[] pBuf;
        pBuf=NULL;
        LenBuf=0;
        LenData=0;
      }
      return retcode;
     }
    }
  }
  else 
  {
   client = serverWS.available();
   
   if(!client)
    return NOINIT;
    
   FnRecive=[&FnRecive](uint8_t* pBuf, word L, char* rc)->bool
   {
     if(rc) *rc=NOCONECT;
    if(L<sizeof(WebSocketGet))
     return false; //мало, ждем

    if(!strstr( (char*)pBuf,WebSocketGet))
    {
      if(rc) *rc=CONECT_ERR;
      return true; //не заголовок HTTP
    }


    if(!strstr( (char*)pBuf,WebSocketEnd)) 
      return false; //нет конца заголовок HTTP, ждем

    Autentification(pBuf);
    client.write(WebSockAnsv,sizeof(WebSockAnsv)-1);
    client.write((char*)pBuf, strlen((char*)pBuf));
    client.write(WebSocketEnd,sizeof(WebSocketEnd)-1);
    if(rc) *rc=CONECT;
    FnRecive=[&FnRecive](uint8_t* pBuf, word L, char* rc)->bool
    {
  
      long int LenFrame=DecodeFrame((char*)pBuf, L, &w);
    
      if(!LenFrame)
       {
         if(rc) *rc=ND;
         return false;
       }
      
      if(rc) *rc=FrameType(w.Opcod);
      if(w.pData) delete[] w.pData;
      w.pData=new char[w.Len];
      memcpy(w.pData,pBuf,w.Len);
      return true;
    };

    return true;
   };
   return NOCONECT;
  }
}


char guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
void Autentification(uint8_t* buf)
{
  //получаем ключ из пришедшего сообщения
  char* pStKey=strstr((char*)buf,WebSocketAnsvKey)+strlen(WebSocketAnsvKey);
  char* pStKeyEnd=strstr((char*)pStKey, WebSocketAnsvKeyEnd)+2;
  uint8_t Criptogr[200];
  memcpy(Criptogr, pStKey, pStKeyEnd-pStKey);
  memcpy(&Criptogr[pStKeyEnd-pStKey], guid, strlen(guid)+1);

  //формируем ответное криптосообщение
  char hash[20];
  sha1(Criptogr,strlen((char*)Criptogr),(unsigned char*)hash);
  char* ansKey=(char*)encode64((unsigned char*)hash,20);
  strcpy((char*)buf,ansKey); 

  delete[] ansKey;

}

unsigned char* encode64(unsigned char *Buf,int Length) 
{
    char Codes64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    int Byte3=0;
    unsigned char* Res=new unsigned char[Length*2];
    unsigned char* R=Res;

    for (int i=0; i<Length; i++) {
        Byte3=(Byte3<<8)+(int)Buf[i];
        if ((i+1)%3==0) {
            *R=Codes64[(Byte3>>18)&0x3F];R++;
            *R=Codes64[(Byte3>>12)&0x3F];R++;
            *R=Codes64[(Byte3>>6)&0x3F];R++;
            *R=Codes64[(Byte3)&0x3F];R++;
            Byte3=0;
        }
    }

    int Rest=Length%3;
    switch (Rest) {
        case 1:
            Byte3=Byte3<<4;
            *R=Codes64[(Byte3>>6)&0x3F];R++;
            *R=Codes64[(Byte3)&0x3F];R++;
            *R='=';R++;
            *R='=';R++;
             break;
        case 2:
            Byte3=Byte3<<2;
            *R=Codes64[(Byte3>>12)&0x3F];R++;
            *R=Codes64[(Byte3>>6 )&0x3F];R++;
            *R=Codes64[(Byte3)&0x3F];R++;
            *R='=';R++;
            break;
    }
   *R=0;
    return Res;
}

#define WEB_SOCK_FRAME_FLAG_MASKED 0x10

char* GetText(WebSockFrame w)
{
 if((w.Opcod!=1) ||(w.Len>125))
  return NULL;

 w.pData[w.Len]=0;
 return w.pData;
}

long int DecodeFrame(char* b, long int l, WebSockFrame* f)
{
  if(l<3)
    return 0;
    
  f->Opcod=b[0]&0x0f;
  f->Flags=(b[0]>>4)|((b[1]>>3)&0x10);
  int Mask;
  long int Len=b[1]&0x7f;
  long int Ofs;

  switch (Len)
  {
   case 126:
    Len=(uint16_t)b[2];
    Ofs=4;
    break;

   case 127:
    Len=(uint64_t)b[2];
    Ofs=10;
    break;

   default:
    Ofs=2;
  }
 

  f->Len=Len;
  if(f->Flags&WEB_SOCK_FRAME_FLAG_MASKED)
  {
    memcpy(&Mask, &b[Ofs], sizeof(Mask));
    Ofs+=4;
    
    if(l<Len+Ofs)
     return 0;

    for(long int i =Ofs, j=0; i < Len+Ofs; i++,j++)
    {
       b[j]=b[i]^((char*)&Mask)[j%4];
    }

  }
  else
  {
     if(l<Len+Ofs)
     return 0;

    for(long int i =Ofs, j=0; i < Len+Ofs; i++,j++)
    {
       b[j]=b[i];
    }

  }

  return Len+Ofs;
}


char FrameType(char b)
{
switch(b)
        {
          case 1:return FRAME_TEXT;
          case 21:return FRAME_BIN;
          case 0:return FRAME_CONT;
          case 8:return FRAME_CLOSE;
          case 9:return FRAME_PING;
          case 10:return FRAME_PONG;
          default:  return FRAME_UNDEF;
        }
}


Каждая новая строка в html-е снижала вероятность успешной компиляции. Писец глюкавое ИДЕ.

ПС. Код причешу, поровняю и покрашу позже, может быть ))) Но закрытие сокета точно доделаю;)

Logik
Offline
Зарегистрирован: 05.08.2014

Поборол таки глюк компилятора. Если оч длинную строку с html-ом  вида

const char* PROGMEM webs="<html><head><meta charset='utf-8'></head>....

вынести в отдельный ашник, то компиляция идет стабильно :)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013
helix59
Offline
Зарегистрирован: 05.05.2017

Добрый день. Вопрос. Нужно подключить модуль gy-801 (гироскоп L3G4200D и акселерометр adxl345) к esp8266-12. При этом нужно использовать фильтр Калмана, для определения угла поворота. На ардуино все выходит хорошо, показания стабильны и точны.
При подключению gy-801 к esp8266-12 показания углов гироскопа и акселерометра отображаются правильно (нормально), но обработка результатов по Калману - это ужас. Результаты бегают как хотят. Что делать? Есть ли библиотека фильтра Калмана к esp8266 ?

 

Logik
Offline
Зарегистрирован: 05.08.2014

Logik пишет:

Samodelkin пишет:

Logik пишет:

Сложно, если весь DOM разбирать по полочкам. Если выцепить чего по уникальному фрагменту то чепуховина.

Да, нужно именно фрагмент

 

ключевое слово "уникальный". Если так, то просто поиск. Если сложней, можна вспомнить про регулярные выражения (к матюкам это никак не относится).

Появилась у меня илюстрация к этому процессу. 

Загружаем стартовую страницу http://arduino.ru и из неё выводим на экран "тем временем на форуме" и темы из этого списка. Работаем без буферирования, посимвольно, каждый очередной символ передаем в функцию http_recive , второй параметр будет true только при первом вызове.

//парсим поток и ищем нужные данные, как найдем - выводим на экран.
void http_recive(byte r, boolean FlBegin)
{
  static byte y;
  static byte state;
  static byte cnt;
  static char buf[21];
  
  if(FlBegin)
  { 
    DravString(4,3,"R E C I V E");
    state=0;
  }
 
  switch(state)
  {
    case 0:
     FiltrTag_h4.Reset();
     cnt=0;
    case 1:
      if(FiltrTag_h4.Find(r))
      {
        y=0;
        cnt++;
        if(cnt==2)
        {
          state=2;
          ClrScr();
          cnt=0;
        }
      }
      else
        state=1;
      break; 
    case 2:
      if(!(r=ConvUTF8(r)))
        break;
      if(r=='<')
        r=0;  
      buf[cnt]=r;
      cnt++;
       if((cnt==20) || !r) 
      {
        buf[20]=0;
        cnt=0;
        state=3;     
        DravString(0,1,buf);
      }
      
      break;  
    case 3:
      if(FiltrTag_A.Find(r))
        state=4;
      break;
    case 4:
      if(r=='>')
      {
        cnt=0;
        state=5;
      }
      break;
    case 5:
      if(!(r=ConvUTF8(r)))
        break;
       if(r=='<')
        r=0;  
       buf[cnt]=r;
       cnt++;
       if((cnt==20) || !r) 
       {
         buf[20]=0;
         DravString(0,y+3,buf);
   
         y++;
         if(y==5)
         {
           state=1;
           cnt=2;
           y=0;
         }
         else
          state=3;     
      }
      break;  
  }
}

class StreamFiltr
{
  const char * et;
  byte c;
  byte l;
  public:
   StreamFiltr(const char * e) {et=e;l=strlen(et)-1;}
   boolean Find(char r)
   {
    if(r==et[c])
    {
      if(c==l)
      {
        c=0;
        return true;
      }
      c++;
    }
    else
      c=0;
    return false;
   };
   void Reset(void){c=0;}
};

StreamFiltr FiltrTag_h4("<h4>");
StreamFiltr FiltrTag_A("<a href=");

byte ConvUTF8(byte r)
{
  static byte utf8_1;

  if(r&0x80)  //UTF-8 только двухбайтовая кирилица
  {
     if(r&0x40)
     {
        utf8_1=r;
        return 0;
     }
     else
     {
       r=byte(r&0x3f | byte(utf8_1<<6));
       if(r==0x051) r=0x35; //ё
       if(r==0x001) r=0x15;  //Ё
       r+=0xb0;
    }
  }
  return r;
}

Вспомогательные класс StreamFiltr ищет заданую строку в потоке а ConvUTF8 преобразует кирилицу из UTF8 в читаемое.

По алгоритму - сначала ищем в потоке приходящего текста строку "<h4>". Она на страничке встречается 2 раза, первый для списка "новое на arduino.ru" - его мы пропустим и второй раз для "тем временем на форуме" - его мы "цепляем" выводим строку за ним (собственно "тем временем на форуме") на экран и готовимся выводить список тем. Каждая тема ищется по строке "<a href=" и завершается по '<' но не более 20 символов.

Про функции очистки экрана и вывода на экран не пишу, думаю и так ясно.

Результат 

Таким образом даже не по уникальному фрагменту можна получать нужное с сайта. И что важно - независимо от размера странички и без существенных затрат памяти. 

orcsin
Offline
Зарегистрирован: 12.06.2015

Здравствуйте!

Использую esp8266-01, GPIO 0 и GPIO 2 использую под i2с, а GPIO 3 (RXD) GPIO 1 (TXD) хочу использовать или под управление реле, или светодиоды или датчик температуры, но сталкнулся со следующем, на выходе GPIO 3 (RXD) при работе есть небольшое мерцание, скорее всего какая то сжубебная информация идёт по TX-RX.  И поэтому светодиодная лента мерцает, попробовал перекинуть выходы на управление BT138 - с RXD заработало, а с подключенным  МОС к TXD просто не стартует.

Можно ли как то отключить функцию UARTа на GPIO 3 и GPIO 1, что бы использовать их полноценно?
 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Нашел интересную библиотеку. Вернее две:

1) На ESP (прямо через ARDUINO IDE) заливается https://github.com/JiriBilek/WiFiSpiESP и эмулирует WiFi Shield, который работает по SPI.

2) Со стороны Arduino SPI обслуживается при помощи https://github.com/JiriBilek/WiFiSpi. 

Плюсы - не нужно на мелком камешке устраивать парсинг AT-команд и тратить всю память на буфера. Ресурсы МК занимаются чуть больше, чем библиотечкой Ethernet, но меньше чем UIPEthernet, т.е. приемлемо.

Минусы - нужен скоростной согласователь TTL уровней. Мой алиэкспрессный, изготовленный из неизвестных мне транзисторов, работающий нормально с UART на 9600, тест со SPI не прошел и работал в 10% случаев. Однако, скетч из примеров сливал страницу с гугла нормально. TCP-сервер тоже удалось запустить, даже приконнектился пару раз к нему. WPA/WPA2 тянет.

Решение, конечно, не лучшее - сложнее, чем Shield напялить, но думаю, что этот комплект может быть полезен тому,  кто-то делает устройство с заменяемым физическим сетевым интерфейсом провод/воздух. 

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

sadman41, а в чём прикол подключать "мелкий камешек" к ESP?  Он же сам по себе  мощный 32-битный МК с  12ю портами...

sadman41
Offline
Зарегистрирован: 19.10.2016

dimax пишет:

sadman41, а в чём прикол подключать "мелкий камешек" к ESP?  Он же сам по себе  мощный 32-битный МК с  12ю портами...

Это вопрос скорее философский - нужен ESP для МК или нет. 

У меня, например, есть обкатанное самопальное устройство с подключением по Ethernet (W5100/ENС28J60 на выбор). Но иногда тянуть провод к экземпляру этого устройства не хочется/нет возможности/все порты заняты/т.д. Поэтому ему не не помешает такой вот WiFi shield. Переписывать всю массу кода под ESP я не хочу, так как придется сопровождать две ветки - для AVR и ESP.

PS. Вопрос как к специалисту - что из двунаправленного четырехканального и легкодоступного можете посоветовать в качестве TTL level shifter для SPI-скоростей? На рассыпухе собирать нет интереса для одного раза. Спасибо.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

sadman41, попробуйте обойтись без него, SPI это достаточно быстрая шина, любое вмешательство погубно скажется на фронтах. Если уж никак, то нужно спец чип брать, что скоростной был, со скоростью переключения в единицы наносекунд. Примеров к сожалению не назову.

sadman41
Offline
Зарегистрирован: 19.10.2016

Т.е., in general, менять 5V МК на 3.3V МК? 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

sadman41, смотря что за МК. Если мега328, то она устойчиво пашет и на 3.3 вольта, а если и частоту снизить до 8МГц, то и штатно работает от 3в.

pilnikov
pilnikov аватар
Offline
Зарегистрирован: 28.08.2015

74hct245 Используется как согласователь уровней в диодных матрицах

orcsin
Offline
Зарегистрирован: 12.06.2015

Господа, после долгих мучений, мне стал противен ESP8266-01, злости на него не хватает.

При работе со следующими библиотеками:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
#include <Wire.h>
#include <OneWire.h>
#include <DS18B20Lib.h>
#include <RTClib.h>

запускается через раз, хотел отловить в каком месте глюк, но раз из пяти раз не стартует даже void setup(), то есть контроллер даже до него не доходит :(

И очень намучался с управлением поливика, правда я взял IRF640, и пытался управлять им через транзисторный усилитель, но как не бился, какие схемы не пробовал (я не спец в радиоэлетронике), но нормально открыть его так и не удалось. Я уже почти забил, но лежит ещё 12 версия, и там всё равно 3.3 В.

Подскажите пожалуйста реально рабочую схему полного открытия полевика от 3.3В или http://www.kosmodrom.com.ua/el.php?name=IRLR024NTRPBF решит всем мои проблемы? Но все равно первая версия работает не стибильно :( Возможно проблема в том что шьётся он через Ардуино IDE.

 

Logik
Offline
Зарегистрирован: 05.08.2014

Реально рабочая будет схема, обеспечивающая подачу на затвор напряжения достаточного для открытия ключа при заданом токе нагрузки. Открываем даташит на ваш 640-й, ищем там

Видим набор графиков зависимостей токов от напряжений при некоторых значениях напряжения на затворе.

Рассмотрим самый нижний, соответствующий 4,5В на затворе. Видно что сразу, при напряжениях питания до 0,3-0,4В ток растет, достигает 0,4А а затем остается практически постоянным аж до 50В. Соответственно если хотим иметь ток нагрузки более 0,4А, то необходимо подавать на затвор большее напряжение. Например при 5В на затворе можна 2-2,5А получить. Для 3,3В графика нет, очевидно все там очень плохо.

Таким образом Вы можете выбрать мосфет устраивающий вас. 

А схема - зависит от многих условий, её так просто не посоветуеш.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

orcsin пишет:

Господа, после долгих мучений, мне стал противен ESP8266-01, злости на него не хватает.

Отличная безотказная штучка, зря вы так.

Logik
Offline
Зарегистрирован: 05.08.2014

Да, отличная. Но глянте на либы у orcsin. Удивительно что оно вобще хоть както шевелилось. Миф о библиотеках-кирпичиках из которых как в лего все собирается не одного сгубил.

orcsin
Offline
Зарегистрирован: 12.06.2015

Logik, слишком жирно библиотек для этого камня? Переполнение стека?

Мне нужно отображать время и температуру в веб. МОжет посоветуете самый легковесный и простой вариант.

Самое ужасное, что я не могу отследить ошибку, но точно знаю что при подключении часов начинаются перебои, только вот физические или программные, не понятно. :(

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

orcsin пишет:

Мне нужно отображать время и температуру в веб. МОжет посоветуете самый легковесный и простой вариант.

Ручками, протокол что у DS1307, что у DS3231 - не бином Ньютона, там библиотеки не нужно, от слова "совсем". Ну а уж опросить один температурный DS18B20 - нахер либу тащить, если там с десяток строк кода надо, т.к. на адреса на шине - пофик?

 

negavoid
Offline
Зарегистрирован: 09.07.2016

Ну на самом-то деле да, активно пользую платы наподобие wemos d1 и бывают глюки, иногда не стартует плата. Пару раз даже бывало, что вебморда у роутера подвисала, хоть сам роутер и работал. Ещё иногда бывает, что не коннектится к вайфаю. Но я смирился, так как в 99% случаев лечится одним ручным нажатием на ресет, а преимуществ проц esp в домашних поделиях даёт много.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Из НЕ очень большого опыта работы с ESP8266 понял следущие вещи - качественный и мощный  БП должен быть обязательно, без него в любой момент может повиснуть.  Нет смысла начинать возится с глюками, если ваш БП -дешевое говно. Но даже с хорошим БП иногда плохо стартует -лечится электролитом между ресетом и землёй. После этих мероприятий работает стабильно и надёжно.

Logik
Offline
Зарегистрирован: 05.08.2014

DIYMan пишет:

orcsin пишет:

Мне нужно отображать время и температуру в веб. МОжет посоветуете самый легковесный и простой вариант.

Ручками, протокол что у DS1307, что у DS3231 - не бином Ньютона, там библиотеки не нужно, от слова "совсем". ....

 

Да, orcsin. Именно это я и имел ввиду. Про БП  - да, нужен не чтопопало, но не так чтоб уж очень критично. А вот электролит по питанию - очень критично. Импульсное потребление. Я сделал переходничек, чтоб ESP-01 подключать через него к UART от конвертора USB-UART. С кнопкой для выбора режима програмирование/работа. По питанию не потянул, глючил через раз. Добавил емкость - и терерь програмирует и работает стабильно.