Клиент Arduino uno+enc28j60+Apache

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Здравствуйте, делаю тестовый веб-клиент на базе arduino uno+enc28j60+ubuntu(с установленным LAMP). Код ардуино:

// Библиотека для работы с сетевой картой
#include <EtherCard.h>

// Буффер сетевой карты
byte Ethernet::buffer[200];

// Адрес сайта на который будем стучаться (в моем случае он запускается на одном с сервером IP)
const char website[] PROGMEM = "192.168.1.2"; //Замените на ip адрес вашего компьютера

// IP адрес сервера.
static byte websiteip[] = { 192,168,1,2 }; //Замените на ip адрес вашего компьютера
static uint32_t timer;

// Действия после успешной отправки данных

//Мак-адрес устройства
static byte mac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

//функция колбэка (нелбходима для обраюотки полученных данных)
static void callback (byte status, word off, word len) {
  Serial.println(">>>");
  Ethernet::buffer[off+300] = 0;
  Serial.print((const char*) Ethernet::buffer + off);
  Serial.println("...");
}

// Функция отправки данных на сервер
void send_package(){
    ether.packetLoop(ether.packetReceive());
    if (millis() > timer) {
      Serial.println(F("<<PING"));
      timer = millis() + 5000;
      ether.browseUrl(PSTR("192.168.1.2?"),"user_name=i_love_arduno", website, callback);
  }
}

void setup () {
  Serial.begin(9800);

  if (ether.begin(sizeof Ethernet::buffer, mac,8) == 0)
    Serial.println(F("Failed to access Ethernet controller"));
  else
    Serial.println(F("Successfully to access Ethernet controller"));
  if (!ether.dhcpSetup())
    Serial.println(F("DHCP failed"));
  else
    Serial.println(F("Successfully DHCP"));

  memcpy(ether.hisip, websiteip, sizeof(websiteip));
  ether.printIp(F("SRV: "), ether.hisip);
}

void loop () {
  //отправляем данные
  send_package();
}

код сайта размещенный на сервере (php):

<?php
    if (isset($_GET['user_name'])) {
        echo "<h2>Сервер отвечает:</h2>";
        echo "Ваше имя:<strong>".$_GET['user_name']."</strong></br>";   
    }
?>

Код сайта размещенный на сервере прекрасно работает если подключить компьютер к роутеру и зайти на него например с планшета. Проблема заключается в том, что клиент, выполненный на arduino не отправляет get-запрос на сервер (компьютер)

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Попробуйте библиотеку:

https://github.com/ntruchsess/arduino_uip

Потом в примере:

/*
  Web client
 
 This sketch connects to a website (http://www.google.com)
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe, based on work by Adrian McEwen
 
 */

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
char server[] = "www.google.com";    // name address for Google (using DNS)

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,0,177);

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /search?q=arduino HTTP/1.1");
    client.println("Host: www.google.com");
    client.println("Connection: close");
    client.println();
  } 
  else {
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop()
{
  // if there are incoming bytes available 
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }
}

#include <Ethernet.h>

Заменить на:

#include <UIPEthernet.h>

 

Ну и адаптировать под свои нужнды.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Andrei250292 пишет:

Проблема заключается в том, что клиент, выполненный на arduino не отправляет get-запрос на сервер 

С чего Вы взяли? Вы смотрели лог сервера? Посмотрите. Почти уверен, что отпрпавляет. Что там за запрос - другое дело.

Сравните свой код

Andrei250292 пишет:

      ether.browseUrl(PSTR("192.168.1.2?"),"user_name=i_love_arduno", website, callback);

с описание метода broweURL

/**   @brief  Prepare HTTP request
 *     @param  urlbuf Pointer to c-string URL folder
 *     @param  urlbuf_varpart Pointer to c-string URL file
 *     @param  hoststr Pointer to c-string hostname
 *     @param  callback Pointer to callback function to handle response
 *     @note   Request sent in main packetloop
*/

Ну как, разницу видите? Первым параметром должен быть фолдер, а вторым - имя файла на сервере, а у Вас что?

 

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Переписал: ether.browseUrl(PSTR("/cgi-bin/handler.py?"),"cxem=i_love_arduno", website, callback); не работает все равно

 

Andrei250292
Offline
Зарегистрирован: 21.01.2017

А как enc28j60 назначить статический ip-адрес, т. к. она напрямую подключена к компьютеру, а в коде подключение судя по всему происходит через роутер

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Andrei250292 пишет:

Переписал: ether.browseUrl(PSTR("/cgi-bin/handler.py?"),"cxem=i_love_arduno", website, callback); не работает все равно

Так, Вы вообще читали описание параметров? Перечитайте ещё раз.  Столько раз, сколько будет нужно, чтобы понять то, что я Вам писал: 1-ый параметр - фолдер, 2-ой - имя файла. А у Вас что? То, что Вы написали - бред сивой кобылы.

И ... опять же повторяю во второй раз ... читайте Вы наконец лог сервера, там бы всё увидели, что не туда обращаетесь.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Andrei250292 пишет:

А как enc28j60 назначить статический ip-адрес, т. к. она напрямую подключена к компьютеру, а в коде подключение судя по всему происходит через роутер

На кой чёрт клиенту статический адрес? Если сильно приспичило - обратитесь к администратору Вашей сети. Откуда кому знать как там у Вас что назначается.

Andrei250292
Offline
Зарегистрирован: 21.01.2017

По вашему выходит устройству ip вообще не нужен? Этот бред сивой кобылы расположен на cxem.net!!!

Andrei250292
Offline
Зарегистрирован: 21.01.2017

И этот бред прекрасно работает на компьютере!

vitalikost
Offline
Зарегистрирован: 28.11.2014


Вот код:
/*
  Web client
 
 This sketch connects to a website (<a href="http://www.google.com" title="http://www.google.com" rel="nofollow">http://www.google.com</a>)
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe, based on work by Adrian McEwen
 
 */

#include <SPI.h>
//#include <Ethernet.h>
#include <UIPEthernet.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
char server[] = "192.168.1.2";    // name address for Google (using DNS)

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,1,199);

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /?user_name=i_love_arduno HTTP/1.1");
    client.println("Host: 192.168.1.2");
    client.println("Connection: close");
    client.println();
  } 
  else {
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop()
{
  // if there are incoming bytes available 
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }
}

 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Andrei250292 пишет:

По вашему выходит устройству ip вообще не нужен? 

Статический? Клиенту? Нет, не нужен.

Andrei250292 пишет:

Этот бред сивой кобылы расположен на cxem.net!!!

Да хоть на заборе, мне без разницы. Если функция ожидает имени файла, а Вы ей передаёте "i love arduino", то перестаньте плакать, что она не работает.

Andrei250292 пишет:

И этот бред прекрасно работает на компьютере!

Что работает на компьютере? ether.browseUrl? Круто!

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

Andrei250292
Offline
Зарегистрирован: 21.01.2017

vitalikost, этот код в котором CS=10 пин, а как заменить на 8-й? Может 45-ю строку изменить:

if (Ethernet.begin(mac) == 0,8)

Andrei250292
Offline
Зарегистрирован: 21.01.2017

А какой нужен ip клиенту тогда? 

Andrei250292
Offline
Зарегистрирован: 21.01.2017

[quote=ЕвгенийП]

Да хоть на заборе, мне без разницы. Если функция ожидает имени файла, а Вы ей передаёте "i love arduino", то перестаньте плакать, что она не работает.

Файл - это я как понимаю обработчик запроса? А фолдер это что такое?

 

 

vitalikost
Offline
Зарегистрирован: 28.11.2014

Если не получает от роутера IPAddress ip(192,168,1,199)

Как сменить пин, не знаю, у меня все по умолчанию

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Так роутера и нет. Копм-кабель-модуль

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Динамический. При каждом запуске ему дают какой-нибудь свободный.

Andrei250292
Offline
Зарегистрирован: 21.01.2017

А разве этот динамический айпи не компьютеру дается? Файл - это я как понимаю обработчик запроса? А фолдер это что такое?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Andrei250292 пишет:

Файл - это я как понимаю обработчик запроса? А фолдер это что такое?

Директория.

В Вашем случае файл находится в директории cgi-bin и называется handler.py , правильно? Если так, то должно быть примерно :

browseUrl("/cgi-bin/","handler.py?cxem=i_love_arduno", "192.168.1.2", callback)
 
Или, может: browseUrl(PSTR("/cgi-bin"),"handler.py?cxem=i_love_arduno", "192.168.1.2", callback)
 
А может в первую / тоже убрать надо. Пробуйте.
 
Первый параметр - директория, второй - файл, третий - сервер, четвёртый обработчик
 
Возожно (хотя, не думаю) в третьем параметре нужно ещё протокол указать, экспериментируйте
browseUrl(PSTR("/cgi-bin"),"handler.py?cxem=i_love_arduno", "http://192.168.1.2", callback)
 
А вообще, читайте логи сервера! Там написано куда Вы полезли и если не туда, так правьте.
 
 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Andrei250292 пишет:

А разве этот динамический айпи не компьютеру дается? 

А Ваш сетевой шилд или что там у Вас - это и есть "компьютер". Ему также всё должно даваться, как любому другому клиенту. Для этого нужно нормально сконфигурировать сеть. У Вас есть администратор или это домашняя сеть? В любом случае, конфигурировать её надо.

Но, Вы бли в лог-то сервера гляньте, который раз уж прошу! К нему вообще запросы приходят? Если приходят, то всё нормально с адресами.

Andrei250292
Offline
Зарегистрирован: 21.01.2017

В лог ничего не приходит

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Когда тестировал питоновский скрипт, в логе указывалось дата, время, какой запрос (get), файл-обработчик, переданная переменная. А сейчас пусто

Andrei250292
Offline
Зарегистрирован: 21.01.2017

шилдту ничего не дается

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Тогда сконфигурируте сеть нормально. Он должен получать адрес.

Andrei250292
Offline
Зарегистрирован: 21.01.2017

А какие могут быть направления для конфигурирования?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Обратиться к сисадмину. Если это домашняя сеть, то пригласить знакомого сисадмина, угостить его пивом и попросить сконфигурировать сеть. ну или самому освоить сисадминство.

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Моя сеть включает шилдт и комп

 

nik182
Offline
Зарегистрирован: 04.05.2015

Без роутера? Порт компа может автоматически определять направление передачи или кабель кроссовер?

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Без роутера

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

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

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Хорошо, попробую

 

nik182
Offline
Зарегистрирован: 04.05.2015

Роутер не нужен, если кабель кросс. Роутер нужен, если нужно раздавать адрес по DHCP или есть два пачкорда, а кросса нет . Если использовать статические адреса то всё работает без роутера. http://www.linuxdvr.ru/rus/docs/crossover.html

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

nik182, ТС не сделает этого сам, только мучиться будет. Пусть пригласит знакомого админа и тот решит проблему.

nik182
Offline
Зарегистрирован: 04.05.2015

Я хочу сказать, что соединив обычным прямым пачкордом кабелем TC ничего не получит, даже если поднимет роутер на компе. Если возмёт кроссовер ( например  http://www.eldorado.ru/cat/detail/71086317/ ) то связь будет. И даже без приглашения сисадмина.    

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Установил и настроил на ubutu сервер dhcp - теперь хоть айпишник шилдт назначается

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Andrei250292 пишет:

Установил и настроил на ubutu сервер dhcp - теперь хоть айпишник шилдт назначается

Молодец!

Ну, если нормально назначается, то дальше победите.

Andrei250292
Offline
Зарегистрирован: 21.01.2017

А версия arduino ide может играть роль?

 

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Шилдт все равно не отправляет данные

Andrei250292
Offline
Зарегистрирован: 21.01.2017

И не срабатывает функция callback

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Пробовал пинговать с компа-пингуется, в логе сервера то шилда ничего нет

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Проверил работу скрипта на сервере введя в адресной строке браузера: 192.168.0.10/handler.py?cxem=i_love_arduino

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

дайте сюда текущий скетч как он есть

Andrei250292
Offline
Зарегистрирован: 21.01.2017
// Библиотека для работы с сетевой картой
#include <EtherCard.h>

// Буффер сетевой карты
byte Ethernet::buffer[700];

// Адрес сайта на который будем стучаться (в моем случае он запускается на одном с сервером IP)
const char website[] PROGMEM = "192.168.0.10"; //Замените на ip адрес вашего компьютера

// IP адрес сервера.
static byte websiteip[] = { 192,168,0,10 }; //Замените на ip адрес вашего компьютера
static uint32_t timer;

// Действия после успешной отправки данных

//Мак-адрес устройства
static byte mac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

//функция колбэка (нелбходима для обраюотки полученных данных)
static void callback (byte status, word off, word len) {
  Serial.println(">>>");
  Ethernet::buffer[off+300] = 0;
  Serial.print((const char*) Ethernet::buffer + off);
  Serial.println("...");
}

// Функция отправки данных на сервер
void send_package(){
    ether.packetLoop(ether.packetReceive());
    if (millis() > timer) {
      Serial.println(F("<<PING"));
      timer = millis() + 2000;
      ether.browseUrl(PSTR("/"),"index.php?user_name=arduino", website, callback);
  }
}

void setup () {
  Serial.begin(9800);

  if (ether.begin(sizeof Ethernet::buffer, mac,8) == 0)
    Serial.println(F("Failed to access Ethernet controller"));
  else
    Serial.println(F("Successfully to access Ethernet controller"));
  if (!ether.dhcpSetup())
    Serial.println(F("DHCP failed"));
  else
    Serial.println(F("Successfully DHCP"));
  memcpy(ether.hisip, websiteip, sizeof(websiteip));
  ether.printIp("My IP: ", ether.myip);
  ether.printIp(F("SRV: "), ether.hisip);
}

void loop () {
  //отправляем данные
  send_package();
}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

имя папки

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Полный путь к index.php: /var/www/html/index.php

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вы писали

Andrei250292 пишет:

Проверил работу скрипта на сервере введя в адресной строке браузера: 192.168.0.10/handler.py?cxem=i_love_arduino

А в скетче у Вас 192.168.0.10/index.php?user_name=arduino

Это нормально? на сервере есть такой файл? Вы его (именно так) проверяли из браузера?

Дальше, Вы печатаете IP в строках 49, 50 - нормально печатаются?

И последнее, в логе web-сервера точно ничего по-прежнему нет?

 

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Да я набрал в адресной строке: 192.168.0.10/index.php?user_name=arduino и сервер ответил нормально на запрос

Файл index.php на сервере имеется

IP в строках 49, 50 печатаются нормально. IP шилдта 192.168.0.21, компьютера 192.168.0.10

 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так, а браузер на том же компьютере, что и сервер? А на этом компьютере нет какого-нибудь фаирвола, виндовс-дефендера или ещё какой хрени такого же типа? Если есть есть, посмотрите их логи, может они блокируют?

А вообще, Вы зря пренебрегаете моим советом, пригласить знакомого сисадмина. Он быстро отследит Ваш запрос и найдёт где он затыкается. Так заочно это очень трудно сделать.

Andrei250292
Offline
Зарегистрирован: 21.01.2017

С браузера другого компьютера тоже все хорошо работает

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, попробуйте более низкоуровневые вызовы, хотя, самое лучшее -  позовите сисадмина, поставьте пиво и решите проблему.

Andrei250292
Offline
Зарегистрирован: 21.01.2017

Хорошо, попробуем с сисадмином понервничать