13.01.2009

Ethernet Shield для Arduino

Итак, как я уже писал, ко мне приехала посылка из SmartProjects. Половина стоимости пришлась на Ethernet Shield:



... который я тут же начал испытывать со своим Arduino Diecimila:



Удобнее всего его подключать на работе к локалке, благо она под рукой в невероятных количествах ;)



Три коробочки вверху - это мегаизвращение, к которому я прибег при отсутствии под рукой блока питания 9В: берется источник DC 48В (от ~220В), втыкается в PoE-инжектор DLink DWL-P200, который вводит его в кабель Ethernet, затем в PoE-сплиттер, который, наоборот, отделяет питание, но попутно он умеет преобразовывать его при помощи DC-DC в 5 или 12 вольт, как раз под разъем питания для Arduino (2,1 мм, в центре - плюс).

Не пытайтесь повторить ;) лучше купите БП на 9В (от 12В стабилизатор на Arduino довольно сильно греется).

Что дальше?

Запускаем Arduino 0012, говорим "New", затем "Import Library | Ethernet". Появляются инклудники. Можно добавить пустые setup и loop и компильнуть: как видите, sketch занял около 8 Кбайт! (в память ATMEGA8 это уже точно не влезет).

Вернемся к Ethernet. Первым делом, можно попробовать пример Telnet, который есть в дистрибутиве Arduino.

#include <Ethernet.h>

// network configuration.  gateway and subnet are optional.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 10, 0, 0, 177 };
byte gateway[] = { 10, 0, 0, 1 };
byte subnet[] = { 255, 255, 0, 0 };

// telnet defaults to port 23
Server server = Server(23);

void setup()
{
  // initialize the ethernet device
  Ethernet.begin(mac, ip, gateway, subnet);

  // start listening for clients
  server.begin();
}

void loop()
{
  Client client = server.available();
  if (client) {
    server.write(client.read());
  }
}

Суть примера - после подключения по порту telnet (команда telnet arduino_ip), любой вводимый символ возвращается обратно.

Для того, чтобы попугать коллег, я решил переделать этот пример в имитацию веб-сервера. Поскольку TCP-соединение устанавливается совершенно прозрачно, то меняем порт с 23 на 80, а в обработчике добавляем считывание запроса и вывод HTML-странички.

Поскольку мне было лень считать количество информации на выходе, я ограничился только строкой Content-Type, а Content-Length посылать не стал. Браузеры у коллег наивно пытались дождаться завершения принимаемой информации, но навсегда повисали в этом состоянии. Пришлось добавить несколько команд, чтобы разрушить соединение:

#include <Client.h>
#include <Ethernet.h>
#include <Print.h>
#include <Server.h>

byte mac[] = { 0x00, 0x1D, 0x60, 0xAF, 0x03, 0x30 };
byte ip[] = { 10, 57, 3, 1 };
byte gw[] = { 10, 57, 0, 1 };
byte subnet[] = { 255, 255, 0, 0 };

//Server server = Server(23);
Server server = Server(80);

void setup() {
  Ethernet.begin(mac, ip, gw, subnet);
  server.begin();
  Serial.begin(38400);
}

void loop() {
  Client client = server.available();
  if (client) {
    while (client.available()) {
      Serial.print(client.read(),BYTE);
    }
    client.println("HTTP/1.1 200 OK");
    client.println("Content-type: text/html");
    client.println("");
    client.println("&lt;html&gt;&lt;title&gt;Arduino Ethernet&lt;/title&gt;&lt;body&gt;&lt;h1&gt;Hello, I'm Arduino Ethernet Shield!&lt;/h1&gt;Version 0001 with disconnect!&lt;/body&gt;&lt;/html&gt;");
    client.flush();
    client.stop();
  }
}

На все эксперименты ушло около 15 минут, включая подключение и короткое обдумывание "чего бы такого наваять". Я писал эту статью в блог и делал картинки гораздо дольше ;)

3 комментария:

  1. занимательная конструкция а на модификации duemilanove повторить это можно?

    ОтветитьУдалить
  2. Красота! Всё руки не доходят заказать себе эзернет-шилд.

    ОтветитьУдалить
  3. Повторить на Duemilanova - можно. Она же от Delicima отличается только автовыбором источника питания, а в остальном - отличий нет.

    ОтветитьУдалить