ARDuino Ethernet Shield
- Войдите на сайт для отправки комментариев
Доброго времени суток!
Купил комплект ARDuino UNO + Ethernet Shield.
Хочу управлять гаджетом с компа через Ethernet (USB уже не в теме ))) ).
Вобщем собрал парочку примеров из уроков по Ethernet Shield http://www.instructables.com/id/Arduino-Ethernet-Shield-Tutorial/step4/S..., вроде все ОК, все нормуль, но понял что браузер - это не интересно.
Вот пытаюсь собрать прогу в Delphi на основе Client Socket для управления Ethernet Shield.
И получается ARDuino является сервером, а прога на дельфи клиентом. И вообще правильна ли такая схема?
Вроде все ОК, но я запутался в типах данных, вот что передается и что получается и вообще какие типы данных можно и нужно при этом передавать...
Прошу подсказать.
Олег, там все не сложно
Ардуино будет сервером, к нему подключается клиент и передает команды, на что сервер может выполнять какие то действия.
Передавать нужно в зависимости от того что вы хотите получить и сугобо индивидуально - вы сами разрабатываете свой протокол. Через сокет пробегают массивы байт - то есть самый простой метод - посылаете набор байт -
в нем первый инт\лонг - длина команды, чтобы сервер получив его понял сколько ему еще читать осталось.
ну а дальше упаковываете байты - byte, char, short, int, long (если очень хочется), в общем все базовые и даже структуры - их нужно просто упаковать в набор байт (с правильной последоватльностью битов - это нужно сделать на стороне клиента).
Изучите мой код в той теме, он вам очень поможет и я набил очень много шишек пока понял как это работает. Для простого управления железячкой (моторами, сервоприводами, чтения показаний датчиков и простого дергания ножками) - модуля с избытком достаточно.
А Ваш код работает в браузере?
Вот что то я попытался сделать самостоятельно:
Прога клиента в Delphi:
var Res: array[0..5] of byte; PerDann: array[0..5] of byte; ... //В процедуре Timer1Timer Form1.ClientSocket1.Socket.ReceiveBuf(Res, 6); Form1.Memo1.Lines.Add('>>Ï ! '+format('%X %X %X %X %X %X',[Res[0],Res[1],Res[2],Res[3],Res[4], Res[5]])); PerDann[0]:= 45; PerDann[1]:= 65; PerDann[2]:= 85; PerDann[3]:= 105; PerDann[4]:= 125; PerDann[5]:= 145; Form1.Memo1.Lines.Add('<<Î ! '+format('%X %X %X %X %X %X',[PerDann[0],PerDann[1],PerDann[2],PerDann[3],PerDann[4], PerDann[5]])); form1.ClientSocket1.Socket.SendBuf(PerDann,6);Прога Сервера в ARDuino:
char Pold[5]; ... void loop() { EthernetClient client = server.available(); // Ожидание сигнала входящих клиентов client.readBytes(Pold,6); //Читаем 5 байт пересылаемых данных (почему то здесь можно работать только с char) server.println(byte(Pold[0])); server.println(byte(Pold[1])); server.println(byte(Pold[2])); server.println(byte(Pold[3])); server.println(byte(Pold[4])); server.println(byte(Pold[5])); delay(10); }Итого получается:
Отправляю: 2D 41 55 69 7D 91
Получаю: 31 30 35 D A 31
Как видно разные отправлемые и получаемые значения, почему это может быть?
Заранее спасибо за помощь.
Олег, терпеть не могу делфи.. пришлось искать, качать, ставить, вспоминать.. бррр =)
Вот что у меня получилось
Кусок клиента:
procedure TClientForm.ButtonSendStringClick(Sender: TObject); var Line: String; data: Array [0..5] of byte; i : Integer; ms: TMemoryStream; begin data[0]:= 45; data[1]:= 65; data[2]:= 85; data[3]:= 105; data[4]:= 125; data[5]:= 145; ms:= TMemoryStream.Create; try ms.Write(data, SizeOf(data)); IdTCPClient1.IOHandler.Write(ms); finally ms.Free; end; end; procedure TClientForm.CheckBoxConnectDisconnetClick(Sender: TObject); begin if ( CheckBoxConnectDisconnet.Checked = True ) then begin IdTCPClient1.Host := '192.168.1.190'; IdTCPClient1.Port := 7777; IdTCPClient1.Connect; end else IdTCPClient1.Disconnect; end;Скейтч на ардуино
#include <SPI.h> #include <Ethernet.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress ip(192,168,1,190); // local port to listen on const int LOCAL_PORT = 7777; EthernetServer server(LOCAL_PORT); EthernetClient client; void setup() { // Init Serial and Ethernet Serial.begin(57600); Ethernet.begin(mac,ip); server.begin(); client.setTimeout(100); Serial.println("INIT READY"); } void loop() { // listen for incoming clients client = server.available(); // if client data available if (client.available()) { for(int i=0; i<6; i++) { char raw_data[1]; client.readBytes(raw_data,1); byte data = *(byte*)raw_data; Serial.println(data); } /* // Get one byte from client - also work fine char raw_data[1]; client.readBytes(raw_data,1); byte data = *(byte*)raw_data; Serial.println(data); //look at this: if read 6 bytes together - bytes data is corrupted char raw_data[6]; client.readBytes(raw_data, sizeof(raw_data)); for(int i=0; i<sizeof(raw_data); i++) { byte b = *(byte*)raw_data[i]; Serial.println(b); } */ } }В итоге отправляется в сокет
а получается
В итоге, чтобы передать несколько байт по сети, этого кода достаточно, однако что будет если послать инт ( 4 байта ) Код внизу ардино-скейтча как раз бы мог прочитать инт если длину масива уменьшить до 4, прочесть эти 4 байта и преобразовать что получилось в инт. Однако есть маааленькая загвоздка. Когда вы оправляете байты из клиента - нужно специальным образом менять последовательность Бит в Байте каждого числа - поглядите в эту степь и добавлять уже в правильном порядке в поток. У Инди, насколько я понял, есть уже готовые функции чтобы преобразовать таким образом байты.
Внимательным образом изучите мой код, по тому как он сильно отличается от того что у вас получилось.
P/S Черт, я привык к дотнету, его мини фреймворки делают рельно вещи быстрее чем на делфи - концентрируешься на задаче а не на том как поменять местами элементы в массиве ) Программист обязан уметь все это, но если уже все готово и позволит съекономить 5 минут на набор текста - я лучше посплю побольше =))
Надеюсь, дальше разберетесь .)
Извиняюсь что долго отсутствовал
Мининова, а можите для полного моего счастья кинуть мне Ваши исходники :-)???
Тот, что написал для Вас ? Можно. Повезло что не убил.
http://yadi.sk/d/o9QwmECJ3gUqQ
Забирайте =) Взял из примера по инди, слегка обработал напильником =) Разумеется никаких проверок и многопоточности. Как пример - сойдет.