Отправка и прием данных от сервера

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

  1. one_player

    one_player Нерд

    Добрый день.
    Подскажите как можно реализовать отправку данных с arduino с помощью W5100 на сервер php и принять ответ от сервера.
    Т.е. ардуинка к примеру каждый час отправляет GET запросом единицу "1"
    Код (C++):

    client.connect(server, 80);
    client.print( "GET /index.php?int=1");
     
    Эта единица уходит на сервер. Сервер принимает, обрабатывает эту единицу и в конце своего скрипта посылает GET на ардуинку. Ардуинка принимает данные от сервера и выдает внешний признак(мигает диод, пищит, дергает серву и т.д).
    На данный момент ардуинка умеет отправлять данные на сервер и сервер их обрабатывает. Но вот удачно отработал скрипт или нет ардуинка не знает. Хотелось бы что бы ардуинка могла принимать от сервера что то вроде "1" или "0".
    Подскажите может кто то делал уже такое. Кто сильно добрый, поделитесь куском кода.
     
  2. rkit

    rkit Гуру

    PHP:
    <?php echo 1; ?>
     
  3. one_player

    one_player Нерд

    Сами то поняли что написали? :)
    Зачем писать в теме абы что?
     
  4. rkit

    rkit Гуру

    Понял. Жаль, что вы не поняли.
     
    sslobodyan и one_player нравится это.
  5. one_player

    one_player Нерд

    Признаю, был не прав, молодой был горячий :)
    Ответ нашел на форуме.
    Код (C++):
     
    String currentLine = "";
      client.connect(server, 80);
      client.print( "GET /index.php?dat=");
      client.print(dat);
      client.println();
      delay (50);
              if (client.connected())
              {
                while (client.available())
                {
                  char inChar = client.read();
                  currentLine += inChar;
                  if (currentLine == "1")
                  {
                      tone(3,800,200);
                      delay(2000);
                   }
                  if(currentLine == "0")
                  {
                      tone(3,1000,200);
                   }
                }
                client.stop();
              }
     
  6. mofo

    mofo Нуб

    Никак не могу понять как сделать, чтобы определённые данные на странице обновлялись постоянно, но при этом не рефрешить всю страницу. Суть в том что на странице размещены кнопки управления реле, и рядом с каждой кнопкой, статус устройства (вкл/выкл). Вот этот статус должен постоянно обновляться, например зашёл на страницу, и видишь что одно из устройств ВЫКЛ. нажал кнопку включения и через какое то время увидел что оно включилось (или нет). статус определяю через аналоговые входы. Всю страницу нельзя обновлять по причине, во первых это моветон, во вторых при каждом обновлении будет нажиматься последняя нажатая кнопка а этого нельзя делать. Всё что нашёл в инете, это динамическое обновление через JavaScript, Но в примерах не могу понять как они читают нужное значение с сервера и выводят его в <div></div>
    Вот самый лучший пример из тех что я нашёл:
    Код (Javascript):
    <!DOCTYPE HTML>
    <html>
    <head>
    user-scalable=0;" />
    <meta http-equiv='content-type' content='text/html; charset=UTF-8'>
    <link rel="
    shortcut icon" href="/favicon.ico" type="image/x-icon">
    <title>Данные с датчиков</title>
    <script>
    function GetFlameState()
    {
    nocache = "
    &nocache=" + Math.random() * 1000000;
    var request = new XMLHttpRequest();
    request.onreadystatechange = function()
    {
    if (this.readyState == 4) {
    if (this.status == 200) {
    if (this.responseText != null) {
    var from = 0;
    var to = this.responseText.indexOf(':');
    document.getElementById("
    flame_txt").innerHTML = this.responseText.substring(from,to);
    from = to+1;
    to = this.responseText.indexOf(':',from);
    document.getElementById("
    temp_txt").innerHTML = this.responseText.substring(from,to);
    from = to+1;
    document.getElementById("
    humid_txt").innerHTML = this.responseText.substring(from);
    }
    }
    }
    }
    request.open("
    GET", "ajax_flame" + nocache, true);
    request.send(null);
    setTimeout('GetFlameState()', 1000);
    }

    </script>

    </head>

    <body onload="
    GetFlameState()">
    <img src='flame.png' />Датчик дыма = <span id="
    flame_txt">null</span><br>
    <img src='temp.png' />Температура = <span id="
    temp_txt">null</span>°C<br>
    <img src='humid.png' />Влажность = <span id="
    humid_txt">null</span>%<br><br>
    <form action='https://vk.com/programerge"
    target="_blank"><button type="submit" >Кнопка</button></form>
    </Body>
    </html>
    Первое не пойму как работает этот кусок:

    document.getElementById("flame_txt").innerHTML = this.responseText.substring(from,to);
    from = to+1;
    to = this.responseText.indexOf(':',from);
    document.getElementById("temp_txt").innerHTML = this.responseText.substring(from,to);
    from = to+1;
    document.getElementById("humid_txt").innerHTML = this.responseText.substring(from);

    Второе и совсем непонятное, что ЭТО:

    request.open("GET", "ajax_flame" + nocache, true);

    То есть это как раз запрос на сервер, за инфой, Но что такое ajax_flame?????? это должен быть путь, но я не пойму что это.

    Ребят кто делал веб сервер с динамически обновляемой инфой, поделитесь опытом прошу!
     
  7. rkit

    rkit Гуру

    Кошмар какой. Никогда не пишите на голом JS в вебе, это мазохизм. Используйте хотя бы jQuery.
    https://api.jquery.com/jquery.get/
    HTML:
    <!DOCTYPE html>
    <html>
    <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script>
    $(document).ready(function(){
        $("button").click(function(){
            $.get("script.php", function(data){
                    $("#result").html(data);
            });
        });
    });
    </script>
    </head>
    <body>

    <button>Click</button>
    <div id="result"></div>

    </body>
    </html>
     
     
  8. sslobodyan

    sslobodyan Гик

    Все правильно, только JQuery я б загружал из своего подкаталога, мы же не знаем есть ли выход в и-нет или все крутится на домашнем серваке.
     
  9. mofo

    mofo Нуб

    Проблема в том что мне нужно не по действию клиента обновлять данные а перманентно, но без обновления страницы. Идея в том чтобы на странице отображалось состояние трёх аналоговых входов и постоянно обновлялось. И на этой же странице например ниже были три кнопки управляющие цифровыми выходами(реле). У меня щас работает ИЛИ одно ИЛИ второе. То есть либо я нормально вижу изменения на аналоговых входах. Либо кнопки управления цифровыми. Как ни пытался объединить это на странице, не получается.
     
  10. mofo

    mofo Нуб

    Вот код который на 100% работает в части отображения аналоговых выходов:

    Код (C++):
    #include <SPI.h>
    #include <Ethernet.h>

    // MAC address from Ethernet shield sticker under board
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
    IPAddress ip(10, 222, 51, 17); // IP address, may need to change depending on network
    EthernetServer server(80);  // create a server at port 80

    String HTTP_req;            // stores the HTTP request
    boolean newInfo = 0;

    int apin0 = 0;
    int apin1 = 1;
    int apin2 = 2;
    int val0,val1,val2 = 0;
    char* out[ ] = {"ON", "OFF"};
    char* out2[ ] = {"ON", "OFF"};
    char* out3[ ] = {"ON", "OFF"};

    void setup()
    {
        Ethernet.begin(mac, ip);  // initialize Ethernet device
        server.begin();           // start to listen for clients
        Serial.begin(9600);       // for diagnostics
    }

    void loop()
    {
        EthernetClient client = server.available();  // try to get client

        if (client) {  // got client?
            boolean currentLineIsBlank = true;
            while (client.connected()) {
                if (client.available()) {   // client data available to read
                    char c = client.read(); // read 1 byte (character) from client
                 
                    HTTP_req += c;  // save the HTTP request 1 char at a time
                    // last line of client request is blank and ends with \n
                    // respond to client only after last line received
                    if (c == '\n' && currentLineIsBlank) {
                        // send a standard http response header
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-Type: text/html");
                        client.println("Connection: keep-alive");
                        client.println();
                        // AJAX request for switch state
                        if (HTTP_req.indexOf("ajax_switch") > -1) {
                            // read switch state and analog input
                            GetAjaxData(client);
                        }
                        else {  // HTTP request for web page
                            // send web page - contains JavaScript with AJAX calls
                            client.println("<!DOCTYPE html>");
                            client.println("<html>");
                            client.println("<head>");
                            client.println("<title>Arduino Web Page</title>");
                            client.println("<script>");
                            client.println("function GetSwitchAnalogData() {");
                            client.println(
                                "nocache = \"&nocache=\" + Math.random() * 1000000;");
                            client.println("var request = new XMLHttpRequest();");
                            client.println("request.onreadystatechange = function() {");
                            client.println("if (this.readyState == 4) {");
                            client.println("if (this.status == 200) {");
                            client.println("if (this.responseText != null) {");
                            client.println("document.getElementById(\"sw_an_data\")\
    .innerHTML = this.responseText;"
    );
                            client.println("}}}}");
                            client.println(
                            "request.open(\"GET\", \"ajax_switch\" + nocache, true);");
                            client.println("request.send(null);");
                            client.println("setTimeout('GetSwitchAnalogData()', 1000);");
                            client.println("}");
                            client.println("</script>");
                            client.println("</head>");
                            client.println("<body onload=\"GetSwitchAnalogData()\">");
                            client.println("<h1>Arduino RIGS Controll</h1>");
                            client.println("<div id=\"sw_an_data\">");
                            client.println("</div><br>");
                            client.println("</body>");
                            client.println("</html>");
                        }
                        // display received HTTP request on serial port
                        Serial.print(HTTP_req);
                        HTTP_req = "";            // finished with request, empty string
                        break;
                    }
                    // every line of text received from the client ends with \r\n
                    if (c == '\n') {
                        // last character on line of received text
                        // starting new line with next character read
                        currentLineIsBlank = true;
                    }
                    else if (c != '\r') {
                        // a text character was received from client
                        currentLineIsBlank = false;
                    }
                } // end if (client.available())
            } // end while (client.connected())
            delay(1);      // give the web browser time to receive the data
            client.stop(); // close the connection
        } // end if (client)
    }

    // send the state of the switch to the web browser
    void GetAjaxData(EthernetClient cl)
    {
        analogReference(DEFAULT);
      val0 = analogRead(apin0);
      val1 = analogRead(apin1);
      val2 = analogRead(apin2);
        if (val0 < 600)
            {
              cl.println("RIG1 - ");
              cl.println(out[1]);
              cl.print("<br>");
            }
          else
            {
              cl.println("RIG1 - ");
              cl.println(out[0]);
              cl.print("<br>");
            }
            if (val1 < 600)
            {
              cl.println("RIG2 - ");
              cl.println(out[1]);
              cl.print("<br>");
            }
          else
            {
              cl.println("RIG2 - ");
              cl.println(out[0]);
              cl.print("<br>");
            }
            if (val2 < 600)
            {
              cl.println("RIG3 - ");
              cl.println(out[1]);
              cl.print("<br>");
            }
          else
            {
              cl.println("RIG3 - ");
              cl.println(out[0]);
            }
    }
    Но как сюда прикрутить ещё три кнопки (вкл/выкл реле)?? не могу допереть.
     
    VadimB нравится это.
  11. sslobodyan

    sslobodyan Гик

    Для перманентного обновления применяют таймеры, которые автоматом запускают нужную функцию через определенный интервал. А в функции тот же get-запрос с обновлением ваших показометров.
     
  12. mofo

    mofo Нуб

    Вот код который даёт три кнопки управления реле:
    Код (C++):
    #include <SPI.h>             //библиотека для работы с SPI
    #include <Ethernet.h>        //библиотека для работы с Ethernet
    boolean newInfo = 0;        //переменная для новой информации
    //MAC адрес вашего Ethernet-модуля, если его у вас нет, введите любой
    //или оставьте тот, что в примере
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };    

    //указываем IP адрес
    //будьте внимательны! IP адрес указывается тот, который вы получили запустив пример DhcpAdressPrinter
    IPAddress ip(10, 222, 51, 17);    //пример МОЕГО IP адреса, вы вводите сюда СВОЙ

    //инифиализация библиотеки Ethernet server library
    EthernetServer server(80);

    void setup()
    {
      pinMode(2, OUTPUT);                               //инициализируем 8 пин как выход для светодиода                
      pinMode(3, OUTPUT);
      pinMode(5, OUTPUT);
      digitalWrite(2, HIGH);
      digitalWrite(3, HIGH);
      digitalWrite(5, HIGH);
      //запускаем сервер с указанными ранее MAC и вашим IP
      Ethernet.begin(mac, ip);
      server.begin();
      Serial.begin(9600);
    }

    void loop()
    {
      //принимаем данные, посылаемые клиентом
      EthernetClient client = server.available();
      if(client){                                       //если запрос оканчивается пустой строкой
      boolean currentLineIsBlank = true;                //ставим метку об окончании запроса (дословно: текущая линия чиста)
      while (client.connected()) {                      //пока есть соединение с клиентом
        if (client.available()) {                       //если клиент активен
          char c = client.read();                       //считываем посылаемую информацию в переменную "с"
                Serial.print(c);                                    
          if(newInfo && c == ' '){                      //если переменная новой информации = 1 и "с", в которой записан запрос, равен пустой строке
            newInfo = 0;                                //то обнуляем переменную поступления новой информации
          }
          if(c == '$'){                                 //если переменная "с", несущая отправленный нам запрос, содержит символ $
                                                        //(все новые запросы) - "$" подразумевает разделение получаемой информации (символов)
            newInfo = 1;                                //то пришла новая информация, ставим метку новой информации в 1
          }
                                                         //Проверяем содержание URL - присутствует $1 или $2
          if(newInfo == 1){                              //если есть новая информация
              //Serial.println(c);
              if(c == '1'){                              //и "с" содержит 1
              Serial.println("0.5sec rig1");
              digitalWrite(2, LOW);                     //то зажигаем светодиод
              delay(100);
              digitalWrite(2, HIGH);
              }
             
              if(c == '2'){                              //если "с" содержит 2
              Serial.println("11sec rig1");
              digitalWrite(2, LOW);                     //гасим светодиод
              delay(11000);
              digitalWrite(2, HIGH);
              }

              if(c == '3'){
                Serial.println("0.5sec rig2");
                digitalWrite(3, LOW);
                delay(100);
                digitalWrite(3, HIGH);
              }
              if(c == '4'){
                Serial.println("11sec rig2");
                digitalWrite(3, LOW);
                delay(11000);
                digitalWrite(3, HIGH);
              }
              if(c == '5'){
                Serial.println("0.5sec rig3");
                digitalWrite(5, LOW);
                delay(100);
                digitalWrite(5, HIGH);
              }
              if(c == '6'){
                Serial.println("11sec rig3");
                digitalWrite(5, LOW);
                delay(11000);
                digitalWrite(5, HIGH);
              }
            }
         
          if (c == '\n') {                              //если "с" равен символу новой строки
            currentLineIsBlank = true;                  //то начинаем новую строку
          }
          else if (c != '\r') {                         //иначе, если "с" не равен символу возврата курсора на начало строки
            currentLineIsBlank = false;                 //то получаем символ на текущей строке
          }
       
          if (c == '\n' && currentLineIsBlank) {        //выводим HTML страницу
            client.println("HTTP/1.1 200 OK");          //заголовочная информация
            client.println("Content-Type: text/html");
            client.println("Connection: close");
            //client.println("Refresh: 5");              //автоматическое обновление каждые 30 сек
            client.println();
            client.println("<!DOCTYPE HTML>");          //HTML тип документа
            client.println("<html>");                   //открытие тега HTML
            client.print("<title>My web Server</title>");                  //название страницы
            client.print("<H1><font face=arial>Arduino Rig's Web Controll</font></H1>");                        //заголовк на странице
            client.println("<table border=\"0\" width=\"100%\"><tr>");
            client.print("<td valign=top><h2><font face=arial>P8H61</h2><br><br>STATUS: Pwr ON<br>Controll: <a href=\"/$1\"><button>0.5 sec</button></a>&nbsp<a href=\"/$2\"><button>11 sec</button></a></font></td>");
            client.print("<td valign=top><h2><font face=arial>M2N32</h2><br><br>STATUS: Pwr ON<br>Controll: <a href=\"/$3\"><button>0.5 sec</button></a>&nbsp<a href=\"/$4\"><button>11 sec</button></a></font></td>");
            client.print("<td valign=top><h2><font face=arial>H81M</h2><br><br>STATUS: Pwr ON<br>Controll: <a href=\"/$5\"><button>0.5 sec</button></a>&nbsp<a href=\"/$6\"><button>11 sec</button></a></font></td>");
            client.print("</tr></table>");
            client.println("</html>");                  //закрываем тег HTML
            break;                                      //выход
          }
       
        }
       
      }
      delay(1);                                          //время на получение новых данных
      client.stop();                                     //закрываем соеднение
    }
    }
    По отдельности они работают а вместе нет.
     
  13. mofo

    mofo Нуб

    Если я объединяю эти вещи то страница адово задваиваться, релешки начинают сами по себе щёлкать.
     
  14. VadimB

    VadimB Нуб

    Код (C++):
     GetAjaxData(client);
    Вот за это спасибо.
    Голову сломал как заставить функцию отправлять сообщения в сеть, а оказывается ей ссылку скормить нужно было.