Как заставить Ethernet Shield постоянно опрашивать сервер?

Тема в разделе "Arduino & Shields", создана пользователем andreuku, 18 фев 2014.

  1. andreuku

    andreuku Нерд

    Занимаюсь ардуино недавно. Переделал один пример под свои нужды. Но не могу заставить ардуино постоянно опрашивать сервер. Условия такие: Если на сервере ноль то ничего не происходит если на сервере один то загорается светодиод на секунду и потом гаснет. Чтобы отделить нужный ноль и едниницу, среди прочей информации посылаемой сервером, перед ними стоит знак доллара.
    То есть сейчас у меня при включении ардуино и выключенной кнопке на сайте(http://door.dev.pichesky.ru/) ничего не происходит, а при включении ардуино и включенной кнопке на сайте загорается светодиод. Как сделать так чтобы сервер опрашивался постоянно, в ожидании единицы, а не только при включении ардуино? Помогите пожалуйста.
    Мой корявый код:




    #include <SPI.h>
    #include <Ethernet.h>
    int ledRed = 2;
    int prom;
    char copy;
    // Введите MAC-адрес и IP-адрес вашего контроллера
    // IP-адрес должен соответствовать вашей локальной сети
    byte mac[] = {
    0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01 };
    IPAddress ip(192,168,3,164); //<<< IP-АДРЕС ВВОДИТЬ СЮДА!!!

    // инициализации экземпляра библиотеки:
    EthernetClient client;
    // задержка между запросами
    const int requestInterval = 1000;
    // URL сервера, которому будем отправлять запросы
    char serverName[] = "door.dev.pichesky.ru";
    // сделан ли запрос после подключения
    boolean requested;
    // время в милисекундах с последнего подключения к серверу
    long lastAttemptTime = 0;


    void setup() {

    pinMode(ledRed, OUTPUT);
    digitalWrite(ledRed, LOW);

    // инициализация последовательного порта:
    Serial.begin(9600);
    // попытка подключения с DHCP:
    if (!Ethernet.begin(mac)) {
    // если DHCP-сервер отсутствует в сети,
    // подключаемся с заданным нами IP-адресом:
    Ethernet.begin(mac, ip);
    }
    // подключаемся к door:
    connectToServer();
    }

    void loop()
    {
    if (client.connected()) {
    if (client.available()) {
    // считываем полученные байты:
    char inChar = client.read();
    Serial.println(inChar);

    //моя часть программы

    copy = inChar;
    if (copy == '$'){
    prom = 1;
    }

    if (prom == 1){
    if (copy == '1'){
    Serial.println(prom);
    Serial.println(copy);
    Serial.println("GOOD");
    prom = 0;
    digitalWrite(ledRed, HIGH);
    delay(1500);
    digitalWrite(ledRed, LOW);
    }
    }

    }
    }
    }

    // функция подключения к серверу door:
    void connectToServer() {

    Serial.println("connecting to server...");
    if (client.connect(serverName, 80)) {
    Serial.println("making HTTP request...");
    Serial.println("GOOD");
    // Создаем GET HTTP-запрос к door:
    client.println("GET /status/get.php HTTP/1.1");
    client.println("HOST: door.dev.pichesky.ru");
    client.println();
    }
    // записываем в переменную время текущей попытки соединения:
    lastAttemptTime = millis();
    }



    Спасибо!
     
  2. sagis

    sagis Нерд

    Сразу не вникая в суть, вы открываете соединение только в void setup(), перенесите его в тело и контролируйте.
    При существующей ситуации вы конектитесь на сервер, получаете данные и собственно все код окончен. если соединении с сервером будет вызываться из void loop() скетч будет выполнятся по кругу.
    Подробно не смотрел так то возможно еще есть ошибки
     
  3. NR55RU

    NR55RU Гик

    На самом деле TCP/IP имеет свой взгляд на так называемое соединение.
    TCP/IP не предоставляет какого бы то ни было физического соединения между точками, оно может предоставить лишь "логическое" соединение и не больше.

    Представьте что вы приходите на почту и горите что хотите арендовать абонентский ящик и что все что вы положите в данный ящик должно будет оказаться в другом абонентском ящике например ящике вашего друга в другом городе.
    Почта принимает вашу заявку, связывается с почтовым отделением вашего друга и просит выделить абонентский ящик куда будут поступать все что вы положите у себя и все что положит ваш друг должно будет быть передано в ваш ящик, после чего почта дает вам ключ от вашего ящика.
    Все, только что вы установили логическое соединение со своим другом.
    Примерно так в самой примитивной форме работает TCP.

    А теперь представьте что вы хотите узнать какая погода в городе вашего друга и кладете в свой ящик бумажку с вопросом, адрес друга не надо, мы же установили логическое соединение, то есть все что положите в этот ящик окажется в ящике друга.
    Друг через какое то время пришел открыл ящик, взял бумажку, прочитал, написал на другой бумажке данные о погоде и положил в свой ящик.
    Вы пришли открыли ваш ящик и нашли эту бумажку и вы знаете какая погода.
    Но вот на следующий день вы снова решили узнать о погоде, пришли открыли ящик а там пусто, и на следующий день и через два дня и так далее.
    В чем же дело,а все просто, вы послали просьбу другу он ее выполнил а так как просьб от вас больше не поступало он и не сообщает вам о погоде так как просьба была разовая.

    Примерно это вы и пытаетесь сделать, вы единожды кидаете HTTP запрос и получаете на него ответ, а потом просто пытаетесь читать данные из соединения, но HTTP запрос это разовая просьба, попросили вам ответили, как и с вашим другом вам надо каждый день посылать другу просьбы рассказать о погоде так и тут вам надо как только вам требуются данные с сервера послать ему запрос :)

    Есть еще вариант, послать другу просьбу каждый день самостоятельно отсылать вам данные о погоде НО это уже друга тема :)

    В общем тема работы с TCP/IP это тема целых книг, посему я лишь в самых общих чертах подкинул информацию.
    Весьма интересная книга по этой теме :
    Эффективное программирование TCP/IP Автор: Ион Снейдер ISBN 978-594074-670-6

    P.s. Надеюсь ничего не напутал :) Тему сетевого уровня и работы с TCP/IP я как раз сейчас изучаю и посему мог ченить не верно изложить, так как пока тока вгрызаюсь в данную тему :)
     
    acos, Megakoteyka, Unixon и ещё 1-му нравится это.
  4. andreuku

    andreuku Нерд

    Всем спасибо за помощь, у меня получилось сделать постоянное обращение к сайту в ожидании нужной информации. Выкладываю рабочий код с описанием. Конечно он корявенький, но может кому-то он пригодится на начальной стадии изучения.
    Часть информации можно почерпнуть тут http://diy-blog.net/arduino-ethernet-shield-opisanie-shilda-i-primeryi-ispolzovaniya/



    /*

    В этом скетче показано как с помощью arduino Ethernet Shield и arduino UNO можно сделать постоянное обращение к сайту(серверу) через GET запросы.
    В данном случае если на сайте кто-то нажал кнопку то появляется значение $1,
    если кнопка не нажата, то значение равно $0. Знак доллара я поставил для того чтобы выделить нужные мне символы.

    Дело в том что при обращении через GET я получаю кучу лишней информации, которая мне совсем не нужна.
    Светодиод подключен к 3(аналоговому) пину. Когда на сайте нажата кнопка светодиод плавно загорается, горит две секунды и плавно гаснет.

    */

    #include <SPI.h>
    #include <Ethernet.h>
    int ledRed = 3; // светодиод подключен к 3 аналоговому входу
    int prom;
    int stepRed = 0;
    // Введите MAC-адрес и IP-адрес вашего контроллера
    // IP-адрес должен соответствовать вашей локальной сети
    byte mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    IPAddress ip(192,168,3,164); //<<< IP-АДРЕС ВАШЕГО АРДУИНО ВВОДИТЬ СЮДА!!!

    // инициализации экземпляра библиотеки:
    EthernetClient client;

    // URL сервера, которому будем отправлять запросы
    char serverName[] = "door..ru"; //<<< Адрес сайта вводить сюда!!!(адрес не рабочий)



    void setup() {

    pinMode(ledRed, OUTPUT);
    digitalWrite(ledRed, LOW);

    // инициализация последовательного порта:
    Serial.begin(9600);

    // попытка подключения с DHCP:
    if (!Ethernet.begin(mac)) {

    // если DHCP-сервер отсутствует в сети,
    // подключаемся с заданным нами IP-адресом:
    Ethernet.begin(mac, ip);
    }
    // подключаемся к Сайту:
    connectToServer();
    }

    void loop()
    {
    if (client.connected()) {

    if (client.available()) {

    // считываем полученные байты:
    char inChar = client.read();
    Serial.println(inChar);
    /* показывает в окне Монитора порта полученные символы
    если цикл находит нужный символ($), он записывает в переменную prom единицу
    */

    if (inChar == '$'){

    prom = 1;
    }

    /* Тут мы проверяем что идет после символа $, если ноль то закрываем соединение,
    присваиваем переменной prom ноль и снова вызываем сервер
    */
    if (prom == 1 && inChar == '0'){

    Serial.println("CLOSED"); //Вы водит сообщение CLOSED в мониторе порта
    client.stop();
    prom = 0;
    connectToServer();
    }
    /* Если после символа $, идет единица,
    (это то чего мы ждали, значит кто-то на сайте нажал кнопку),
    то выполняем цикл при котором светодиод плавно загорается,
    горит две секунды и потом плавно тухнет. После этого закрываем соединение,
    присваиваем переменной prom ноль и снова вызываем сервер
    */

    if (prom == 1 && inChar == '1'){

    Serial.println("OPEN");
    //Вы водит сообщение OPEN в мониторе

    while(stepRed < 256 ) {//while - запускает цикл который плавно увеличивает яркость светодиода

    analogWrite(ledRed, stepRed);
    stepRed++;
    delay(5);
    }
    delay(2000);

    while(stepRed > -1 ) {

    analogWrite(ledRed, stepRed);
    stepRed--;
    delay(5);
    }
    client.stop();
    prom = 0;
    connectToServer();
    }
    }
    }
    }

    // функция подключения к нашему серверу :
    void connectToServer() {

    Serial.println("connecting to server...");
    if (client.connect(serverName, 80)) {

    Serial.println("making HTTP request...");
    Serial.println("GOOD");
    // Создаем GET HTTP-запрос к Сайту:
    client.println("GET /status/get.php HTTP/1.1"); //<<< Сюда вводим свой GET запрос!!! этот адрес не рабочий
    client.println("HOST: door.ru"); //<<< Адрес сайта вводить сюда!!! этот адрес не рабочий
    client.println();
    }

    }
     

    Вложения:

    Последнее редактирование: 19 фев 2014
    acos нравится это.