Ethernet сеть

alchi
Offline
Зарегистрирован: 13.02.2012

Здравствуйте!

Описание проекта в целом:

У меня есть 4 объекта управления. Посердством цифровых и аналоговых входов/выходов я подключил их к arduino uno. Используя ethernet shield на базе w5100 я их объединил в сеть через коммутатор. В который также подключены и компьютеры. На компьюторе будет программа для управления объектом испытания. Один объект управления может работать только с одним компьтером. Это выбирается в программе.

Как работать с цифровыми входами/выходами это я понял из раздела программирования. Я умею небольшие познания работы на Delphi, поэтому программу на компьюторе мне будет понятней попытаься написать на ней. Еще поставил качать LabView, почитал вроде несложно. Посмотреть  хотябы для общего развития;)

Почему я за это взялся, у меня скоро диплом, сделать удобным для людей управление оборудованием, заняться чем-нибудь путнем и полезным;)

Почему ethernet - объекты управления находятся достаточно далековато от компьютеров.

Начнем с малого

Вопрос:

Как организовать обмен между компьютером и arduino посредством ethernet? Хотябы включать-выключать светодиод? Примеры  в оболочке  я посмотрел, но там в основном вебинтерфейс. В делфи использовать компонет tcp клиент, слать запрос на включение? А в arduino ждать запроса? Протом включать и отправлять ответ, что включил светодиод?

Как в arduino  можно управлять сокетами?

 

 

alchi
Offline
Зарегистрирован: 13.02.2012

Завтра покажу как я делал, у меня не получилось;(

Zaliv
Offline
Зарегистрирован: 05.03.2011

 Тоже начал изучать Ethernet shield. У меня вот такой тестовый пример вышел. Плата получает байт по tcp и пишет его в serial. и я его вижу в Serial monitor.

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

byte mac[] = { 0x90, 0xB2, 0xDA, 0x07, 0x00, 0xA4 };  
byte ip[] = { 192, 168, 1, 177 };  


EthernetServer server = EthernetServer(233);
char receivedByte;

void setup() {
  Ethernet.begin(mac,ip);
  server.begin();
  Serial.begin(9600);
}

void loop()
{

  EthernetClient client = server.available();
  
  if (client == true) {
    receivedByte = client.read();
    Serial.write(receivedByte);
  }
  delay(10);  
} 

Отправляю байты с помощью netcat утилиты командной строки. Скачать утилиту можно тут http://joncraton.org/blog/46/netcat-for-windows. Команда такая 
nc -v 192.168.1.177 233
утилита подключается к шилду и потом шлет все, что дальше будуте нажимать 

 

Zaliv
Offline
Зарегистрирован: 05.03.2011

 По netcat утилите еще такое замечание. Там в конце страницы две ссылки Download Netcat for Windows и Download Netcat for Windows (without -e). Разница между двумя сборками в том, что во второй выключена функция удаленного запуска исполняемых файлов. Вот за эту функцию утилита была помечена как вирусосодержащая. Если у вас ругается антивирус, то качать нужно вторую, в этой сборке такой фунции нет. Сама по себе фунция безопасна, просто незамысловатые кулхацкеры использовали ее, поставив утилиту с соответсвующими ключами в автозагрузку, чтобы она слушала порт и запускала файлы при поступлении команды.

alchi
Offline
Зарегистрирован: 13.02.2012

Вот я тут кое-что накидал

//Процедура устанвоки соединения между сервером и клиентом

    if (client.available())
      {
      //Если от клиент получена команда 'work', то
        if (client.read() == 'work')
          {
            //Включаем оборудование устанавливая цифровой пин 3  в HIGH
            digitalWrite(3,HIGH); 
            //Задержка 0,5 с для включения оборудования
            delay(500);
            //Если на пине 4 LOW, т.е. оотсутствуют блокировки
            if (digitalRead(4)==LOW)
              {
                //Передаем клиенту noterror, т.е. можно работать
                client.write('noterror');
              }
            else
              {
                //Выключаем оборудование устанавливая цифровой пин 3  в LOW
                digitalWrite(3,LOW);
                //Передача клиенту информации о срабатывании блокировки
                client.write('error');
              } 
          }   
      }    


 

 

 

alchi
Offline
Зарегистрирован: 13.02.2012

Появились вопросы:
1) int socket = EthernetClient();
в переменной socket окажется номер теукущего сокета, который подключен?
2) командой client.stop(); отключаются все клиенты по инициативе сервера?
3)client.stop(1); - оотключается клиент от сокета 1 ?
4) client.write ('busy_ok'); - этой командой я могу передать клиенту данные - в скобочках?
5) как оформить процедуры, что бы их потом вызывать в процессе основной программы?
6) данные буду передаваться в моем случае через протокол TCP? или просто протокол ETHERNET, в котором будет мой протокол

alchi
Offline
Зарегистрирован: 13.02.2012

//Процедура включения оборудование

    if (client.available())
      {
      //Если от клиент получена команда 'work', то
        if (client.read() == 'work')
          {
            //Включаем оборудование устанавливая цифровой пин 3  в HIGH
            digitalWrite(3,HIGH); 
            //Задержка 0,5 с для включения оборудования
            delay(500);
            //Если на пине 4 LOW, т.е. оотсутствуют блокировки
            if (digitalRead(4)==LOW)
              {
                //Передаем клиенту noterror, т.е. можно работать
                client.write('noterror');
              }
            else
              {
                //Выключаем оборудование устанавливая цифровой пин 3  в LOW
                digitalWrite(3,LOW);
                //Передача клиенту информации о срабатывании блокировки
                client.write('error');
              } 
          }   
      }    
alchi
Offline
Зарегистрирован: 13.02.2012

Я в делфи на кидал прогу: клиент ТСР, кнопка и текстовое поле для вывода сообщений. Но у меня не выходит соединиться и принять сообщение от сервера.

Zaliv огромное спасибо!!!

alchi
Offline
Зарегистрирован: 13.02.2012

Получилось :dan_ser:
Написал программу в Delphi: TCP клиент, кнопки и метка. Все работает отлично. Программа простая, установили соединения и опрашиваем сервер :) В прошлый раз наверное неудачный адрес и порт выбрал...
Сделал еще так: крутишь патенциометр и в реальном масштабе времени в прогресбар передаются значение из АЦП (бегающая полосочка :hi_hi_hi: ).

Буду дальше пробовать;))

Вопрос про управления сокетами в ардуино остается открытым, это реально?

Fess
Fess аватар
Offline
Зарегистрирован: 26.10.2011

Zaliv пишет:

 Тоже начал изучать Ethernet shield. У меня вот такой тестовый пример вышел. Плата получает байт по tcp и пишет его в serial. и я его вижу в Serial monitor.

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

byte mac[] = { 0x90, 0xB2, 0xDA, 0x07, 0x00, 0xA4 };  
byte ip[] = { 192, 168, 1, 177 };  


EthernetServer server = EthernetServer(233);
char receivedByte;

void setup() {
  Ethernet.begin(mac,ip);
  server.begin();
  Serial.begin(9600);
}

void loop()
{

  EthernetClient client = server.available();
  
  if (client == true) {
    receivedByte = client.read();
    Serial.write(receivedByte);
  }
  delay(10);  
} 

Отправляю байты с помощью netcat утилиты командной строки. Скачать утилиту можно тут http://joncraton.org/blog/46/netcat-for-windows. Команда такая 
nc -v 192.168.1.177 233
утилита подключается к шилду и потом шлет все, что дальше будуте нажимать 

 

 

не пойму, не хочет конектить пишет :

192.167.1.177: inverse host lookup failed: h_errno 11004: NO_DATA

где туплю - не пойму.

По идее нет обратной зоны в ДНС  ... 

но почему не конектит не могу исправить =(

Zaliv
Offline
Зарегистрирован: 05.03.2011

 А откуда у Вас такой странный адрес - 192.167.1.177. В моем примере было 192.168.1.177, но главное Вы уверены, что компьютер с которого вы шлете пакет находится в той-же подсети, т.е. его ip 192.168.1.* ? Проверить можно командой ipconfig из командной строки.
Если у Вашего компа адрес, например, 10.10.1.156, то дайте Arduino 10.10.1.157 если он не занят, т.к. если адреса в разных подсетях, то пакет скорее всего не дойдет, во всяком случае нужны соответствующие настройки роутера. Вышесказанное относится к локальным сетям.

Fess
Fess аватар
Offline
Зарегистрирован: 26.10.2011

прошу прошения , там опечатка , на самом деле ..168..

с настройками все верно, я пингую шилд.

gonzales
Offline
Зарегистрирован: 13.07.2015

тоже мучаю делфу и ардуино для связи. пока как-то не очень сростается.

if (client.read() == 'work')

Вот эту строчку не понял, ведь client.read выдает char, как его можно сравнивать со строкой?

У меня пока вот что получилось

void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    if (client.available()) {
      String c = client.readString();
      Serial.println(c);
      client.write("222");
  }
}
}

Но  client.readString() работает достаточно медленно, а как переделать на быстрый client.read() не пойму.

В дельфях использую компонент TIdTCPClient

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdBaseComponent,
  IdComponent, IdTCPConnection, IdTCPClient;

type
  TForm1 = class(TForm)
    Client1: TIdTCPClient;
    Button1: TButton;
    Label1: TLabel;
    Edit1: TEdit;
    Button2: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
if form1.Client1.Connected=false then
form1.Client1.Connect;
if form1.Client1.Connected=true then
begin
 form1.Label1.Caption:='conected';
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
form1.Client1.Socket.Write('work');
memo1.Lines.Add(form1.Client1.Socket.ReadString(3));
end;

end.

 

gonzales
Offline
Зарегистрирован: 13.07.2015

Вот рабочая связка DELPHI+ARDUINO для пересылки пакета байтов. Может кому пригодится

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


  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    if (client.available()) {
      byte c = client.read();
      byte c1 = client.read();
      Serial.println(c);
      Serial.println(c1);
      client.write(100);
      client.write(200); 
  }
}
}
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdBaseComponent,
  IdComponent, IdTCPConnection, IdTCPClient, IdGlobal;

type TBuffer = record
  d1:byte;
  d2:byte;
end;


type
  TForm1 = class(TForm)
    Client1: TIdTCPClient;
    Button1: TButton;
    Label1: TLabel;
    Edit1: TEdit;
    Button2: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
if form1.Client1.Connected=false then
begin
form1.Client1.Connect;
label1.Caption:='connected';
end
else if form1.Client1.Connected=true then
begin
form1.Client1.Disconnect;
label1.Caption:='DISconnected';
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
t:TIdBytes;
buffer:TBuffer;
begin
buffer.d1:=50;
buffer.d2:=80;

SetLength(t, SizeOf(buffer));
Move(buffer, t[0], SizeOf(buffer));
form1.Client1.Socket.Write(t);

form1.Client1.Socket.ReadBytes(t, SizeOf(buffer), False);
Move(t[0], buffer, Length(t));

Memo1.Lines.Add('d1='+IntToStr(buffer.d1));
Memo1.Lines.Add('d2='+FloatToStr(buffer.d2));
end;

end.