Ethernet сеть
- Войдите на сайт для отправки комментариев
Здравствуйте!
Описание проекта в целом:
У меня есть 4 объекта управления. Посердством цифровых и аналоговых входов/выходов я подключил их к arduino uno. Используя ethernet shield на базе w5100 я их объединил в сеть через коммутатор. В который также подключены и компьютеры. На компьюторе будет программа для управления объектом испытания. Один объект управления может работать только с одним компьтером. Это выбирается в программе.
Как работать с цифровыми входами/выходами это я понял из раздела программирования. Я умею небольшие познания работы на Delphi, поэтому программу на компьюторе мне будет понятней попытаься написать на ней. Еще поставил качать LabView, почитал вроде несложно. Посмотреть хотябы для общего развития;)
Почему я за это взялся, у меня скоро диплом, сделать удобным для людей управление оборудованием, заняться чем-нибудь путнем и полезным;)
Почему ethernet - объекты управления находятся достаточно далековато от компьютеров.
Начнем с малого
Вопрос:
Как организовать обмен между компьютером и arduino посредством ethernet? Хотябы включать-выключать светодиод? Примеры в оболочке я посмотрел, но там в основном вебинтерфейс. В делфи использовать компонет tcp клиент, слать запрос на включение? А в arduino ждать запроса? Протом включать и отправлять ответ, что включил светодиод?
Как в arduino можно управлять сокетами?
Завтра покажу как я делал, у меня не получилось;(
Тоже начал изучать 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
утилита подключается к шилду и потом шлет все, что дальше будуте нажимать
По netcat утилите еще такое замечание. Там в конце страницы две ссылки Download Netcat for Windows и Download Netcat for Windows (without -e). Разница между двумя сборками в том, что во второй выключена функция удаленного запуска исполняемых файлов. Вот за эту функцию утилита была помечена как вирусосодержащая. Если у вас ругается антивирус, то качать нужно вторую, в этой сборке такой фунции нет. Сама по себе фунция безопасна, просто незамысловатые кулхацкеры использовали ее, поставив утилиту с соответсвующими ключами в автозагрузку, чтобы она слушала порт и запускала файлы при поступлении команды.
Вот я тут кое-что накидал
//Процедура устанвоки соединения между сервером и клиентом
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'); } } }Появились вопросы:
1) int socket = EthernetClient();
в переменной socket окажется номер теукущего сокета, который подключен?
2) командой client.stop(); отключаются все клиенты по инициативе сервера?
3)client.stop(1); - оотключается клиент от сокета 1 ?
4) client.write ('busy_ok'); - этой командой я могу передать клиенту данные - в скобочках?
5) как оформить процедуры, что бы их потом вызывать в процессе основной программы?
6) данные буду передаваться в моем случае через протокол TCP? или просто протокол ETHERNET, в котором будет мой протокол
//Процедура включения оборудование
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'); } } }Я в делфи на кидал прогу: клиент ТСР, кнопка и текстовое поле для вывода сообщений. Но у меня не выходит соединиться и принять сообщение от сервера.
Zaliv огромное спасибо!!!
Получилось :dan_ser:
Написал программу в Delphi: TCP клиент, кнопки и метка. Все работает отлично. Программа простая, установили соединения и опрашиваем сервер :) В прошлый раз наверное неудачный адрес и порт выбрал...
Сделал еще так: крутишь патенциометр и в реальном масштабе времени в прогресбар передаются значение из АЦП (бегающая полосочка :hi_hi_hi: ).
Буду дальше пробовать;))
Вопрос про управления сокетами в ардуино остается открытым, это реально?
Тоже начал изучать 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
где туплю - не пойму.
По идее нет обратной зоны в ДНС ...
но почему не конектит не могу исправить =(
А откуда у Вас такой странный адрес - 192.167.1.177. В моем примере было 192.168.1.177, но главное Вы уверены, что компьютер с которого вы шлете пакет находится в той-же подсети, т.е. его ip 192.168.1.* ? Проверить можно командой ipconfig из командной строки.
Если у Вашего компа адрес, например, 10.10.1.156, то дайте Arduino 10.10.1.157 если он не занят, т.к. если адреса в разных подсетях, то пакет скорее всего не дойдет, во всяком случае нужны соответствующие настройки роутера. Вышесказанное относится к локальным сетям.
прошу прошения , там опечатка , на самом деле ..168..
с настройками все верно, я пингую шилд.
тоже мучаю делфу и ардуино для связи. пока как-то не очень сростается.
Вот эту строчку не понял, ведь 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.Вот рабочая связка 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.