clock online

Тема в разделе "Arduino & Shields", создана пользователем Mestniy, 8 апр 2016.

  1. Mestniy

    Mestniy Гуру

    Всем привет. Подскажите пожалуйста, от куда можно взять время онлайн посредством отправления запроса с esp на сервер? Мне нужно только московское время. Буду благодарен любой помощи в этом вопросе. Пока наткнулся, на немного сложную статью: http://www.instructables.com/id/Internet-time-syncronized-clock-for-Arduino/.
    Усложняется там все OLED. Когда я в коде дошел до места, где разбирается получение данных времени у меня буквально голова задымилась. Вот этот огрызок:
    Код (C++):
    boolean connectWiFi()
    {
      String cmd = "AT+CWJAP=\""; //form eg: AT+CWJAP="dynamode","555555555"
      cmd += SSID;
      cmd += "\",\"";
      cmd += PASS;
      cmd += "\"\r\n";
      Serial1.print(cmd);
      delay(5000); //give it time - my access point can be very slow sometimes
      if (Serial1.find("OK")) //healthy response
      {
        Serial.println("Connected to WiFi...");
        return true;
      }
      else
      {
        Serial.println("Not connected to WiFi.");
        return false;
      }
    }
    //--------------------------------------------------------------------------------
    //ditch this in favour of hardware reset. Done
    boolean softwarereset()
    {
      Serial1.print("AT+RST\r\n");
      if (Serial1.find("ready"))
      {
        Serial1.print("ATE0\r\n");
        return true;
      }
      else
      {
        return false;
      }
    }
    //--------------------------------------------------------------------------------
    void reset()
    {
      digitalWrite(RESET, LOW);
      digitalWrite(LED, HIGH);
      delay(100);
      digitalWrite(RESET, HIGH);
      digitalWrite(LED, LOW);
    }
    //------------------------------------------------------------------------------
    boolean cwmode3()
    // Odd one. CWMODE=3 means configure the device as access point & station. This function can't fail?

    {
      Serial1.print("AT+CWMODE=3\r\n");
      if (Serial1.find("no change"))  //only works if CWMODE was 3 previously
      {
        Serial1.print("AT+CIPMUX=0\r\n");
        return true;
      }
      else
      {
        return false;
      }
    }
    //----------------------------------------------------------------------------------
    boolean cipmux0()
    {
      Serial1.print("AT+CIPMUX=0\r\n");
      if (Serial1.find("OK"))
      {
        return true;
      }
      else
      {
        return false;
      }
    }
    //-----------------------------------------------------------------------
    boolean cipmode0()
    {
      Serial1.print("AT+CIPMODE=0\r\n");
      if (Serial1.find("OK"))
      {
        return true;
      }
      else
      {
        return false;
      }
    }
    //------------------------------------------------------------------------
    void hang(String error_String)    //for debugging
    {
      Serial.print("Halted...   ");
      Serial.println(error_String);
      while (1)
      {
        digitalWrite(LED, HIGH);
        delay(100);
        digitalWrite(LED, LOW);
        delay(100);
      }
    }
    //----------------------------------------------------------------------------
    void hangreset (String error_String)    //for debugging
    {
      Serial.print(error_String);
      Serial.println(" - resetting");
      reset();
    }

    int connect()
    {
    }

    char * get_date_from_header(char *date_string)
    {
      tmElements_t tmx;

      // reset();  //only CERTAIN way I've found of keeping it going
      delay(5000);  //esp takes a while to restart

      // Serial.print("loops = ");  //check for successful connections to server
      //Serial.println(loops);
      loops++;
      String cmd = "AT+CIPSTART=\"TCP\",\"";  //make this command: AT+CPISTART="TCP","146.227.57.195",80
      cmd += DST_IP;
      cmd += "\",80";

      Serial1.println(cmd);  //send command to device

      delay(3000);  //wait a little while for 'Linked' response - this makes a difference
      if (Serial1.find("Linked")) //message returned when connection established WEAK SPOT!! DOESN'T ALWAYS CONNECT
      {
        // Serial.print("Connected to server at ");  //debug message
        // Serial.println(DST_IP);
      }
      else
      {
        //  Serial.println("'Linked' response not received");  //weak spot! Need to recover elegantly
      }

      cmd =  "GET / HTTP/1.0\n";  //construct http GET request
      cmd += "Host:1.1.1.1\r\n\r\n";        //test file on my web
      Serial1.print("AT+CIPSEND=");                //www.cse.dmu.ac.uk/~sexton/test.txt
      Serial1.println(cmd.length());  //esp8266 needs to know message length of incoming message - .length provides this

      if (Serial1.find(">"))   //prompt offered by esp8266
      {
        Serial.println("found > prompt - issuing GET request");  //a debug message
        Serial1.print(cmd);  //this is our http GET request
      }
      else
      {
        Serial1.print("AT+CIPCLOSE\r\n");  //doesn't seem to work here?
        Serial.println(cmd);
        Serial.println("No '>' prompt received after AT+CIPSEND");
        connectWiFi();
      }

      //Parse the returned header & web page. Looking for 'Date' line in header

      if (Serial1.find("Date: ")) //get the date line from the http header (for example)
      {
        int i;
        for (i = 0; i < 31; i++) //31 this should capture the 'Date: ' line from the header
        {
          if (Serial1.available())  //new characters received?
          {
            char c = Serial1.read(); //print to console
            Serial.write(c);
            date_string[i] = c;
          }
          else i--;  //if not, keep going round loop until we've got all the characters
        }
      }

      Serial1.println("AT+CIPCLOSE");

      if (Serial1.find("Unlink")) //rarely seems to find Unlink? :(
      {
        Serial.println("Connection Closed Ok...");
      }
      else
      {
        //Serial.println("connection close failure");
      }
      return date_string;
    }

    void setup()  //initialise device & connect to access point in setup
    {
      LEDPIN_Init();
      LED_Init();
      LED_Fill(0x00);

      LED_P8x16Str(2, 2, "Connecting to");
      LED_P8x16Str(2, 4, DST_IP);
      //pinMode(RESET,OUTPUT);
      //reset();
      //pinMode(LED,OUTPUT);

      Serial1.begin(9600);    // hardware serial connects to esp8266 module
      Serial.begin(115200); // usb serial connects to to pc
      delay(4000);    //wait for usb serial enumeration on 'Serial' & device startup
      if (!cwmode3()) Serial.println("cwmode3 failed");
      boolean wifi_connected = false; //not connected yet...
      for (int i = 0; i < 5; i++) //attempt 5 times to connect to wifi - this is a good idea
      {
        if (connectWiFi()) //are we connected?
        {
          wifi_connected = true;  //yes
          LED_P8x16Str(2, 6, "Connected!");
          LED_P8x16Str(2, 0, "Reading time..");
          break;              //get outta here!
        }
        LED_P8x16Str(2, 0, "Trying again ..");
      }
      if (!wifi_connected) {
        hang("wifi not connected");  //these seem ok - never had a problem
        LED_P8x16Str(2, 0, "Wifi not connected!");
      }
      delay(250);
      if (!cipmux0()) hang("cipmux0 failed");
      delay(250);
      if (!cipmode0()) hang("cipmode0 failed");
      delay(250);

      // Initial time structure for testing
      tmi.Year = (uint8_t) 30 + 15;
      tmi.Month = 10;
      tmi.Day = 25;
      tmi.Hour = 0;
      tmi.Minute = 0;
      tmi.Second = 0;
      time_t ti = makeTime(tmi);

      setTime(0); //

    }

    void loop()
    {
      static int counter = 0;
      char date_string[32];
      char *datep = &date_string[0];

      tmElements_t tmx;

      if (counter++ % 1000 == 0) {
        datep = get_date_from_header(datep);
        // Sat, 28 Mar 2015 13:53:38 GMT

        string_to_tm(&tmx, date_string);
        int offset = daylight_saving(tmx);
        long before = now();
        setTime(makeTime(tmx) + offset);
        long after = now();
        Serial.print("Local time difference to network time = ");
        Serial.print(before-after);
        Serial.println(" before synchronization");
      }

      breakTime(now(), tmx);
      disp(&tmx);
      delay(5000);
    }


    void disp(tmElements_t * tme) {
      static int old_offset;
      static int move_counter;
      static int screen_x_offset;
      static int screen_y_offset;

      char temp_str[7];

      // Move text slightly, so that it will not burn in, if same text
      // will be shown constantly for very long times.
      if (move_counter++ % 600== 0) {
        screen_x_offset = ++screen_x_offset % 4;
        screen_y_offset = ++screen_y_offset % 3;
        Set_Display_Offset(screen_y_offset);
        LED_Fill(0x00);
      }
     
      if (tme->Hour < 6) {
        // inverted "Night mode" 00:00 - 05:59
        Set_Inverse_Display(0x01);  // Inverse Display On (0x00/0x01)  
      }
      else {
        Set_Inverse_Display(0x00);  // Disable Inverse Display On (0x00/0x01)
      }

      int time_x_offset;

      if (tme->Hour > 9) {
        time_x_offset = 0;
      } else {
        // only one hour digit, move time to the center of the screen
        time_x_offset = 12;
      }
     
      if (old_offset != time_x_offset) {
        // clear screen after big offset change
        old_offset = time_x_offset;
        LED_Fill(0x00);
      }

      sprintf(temp_str, "%d%c%02d", tme->Hour, '0' + 16, tme->Minute);

      LED_P23x32Str(3 + screen_x_offset + time_x_offset, 3 , temp_str);

      char s[20];
      char *week_day[] = {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"};

      sprintf(s, "%s, %d.%d.%d", week_day[tme->Wday - 1], tme->Day, tme->Month, tme->Year + 1970);
      LED_P8x16Str(13 + screen_x_offset, 0, s);
    }
     
  2. Mestniy

    Mestniy Гуру

    Вот весь код!!!
     

    Вложения:

  3. Mestniy

    Mestniy Гуру

    У меня у самого четырехтактный семисегментный индикатор. Вот на него и хочу отправлять время.
     
  4. Tomasina

    Tomasina Сушитель лампочек Модератор

    время можно получить UTC (единое по планете) ;)
    Для Москвы просто сделать смещение на нужный часовой пояс.
    http://www.esp8266.com/viewtopic.php?p=43744
     
    Mestniy нравится это.
  5. CryNET

    CryNET Гик

    Mestniy нравится это.
  6. Tomasina

    Tomasina Сушитель лампочек Модератор

    да это одно и то же, просто маршруты получения конечного результата разные.
     
    Mestniy нравится это.
  7. Mestniy

    Mestniy Гуру

    Я честно говоря не совсем разобрался, как работает этот код. Но думаю скоро допетрю))))
     
  8. Mestniy

    Mestniy Гуру

    Спасибо попробую и его реализовать)))
     
    CryNET нравится это.