ARDuino Ethernet Shield

1988Олег1988
Offline
Зарегистрирован: 23.03.2013

 

Доброго времени суток!

Купил комплект 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 является сервером, а прога на дельфи клиентом. И вообще правильна ли такая схема?

Вроде все ОК, но я запутался в типах данных, вот что передается и что получается и вообще какие типы данных можно и нужно при этом передавать...
Прошу подсказать.

Мининова
Offline
Зарегистрирован: 08.06.2012

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

ну а дальше упаковываете байты - byte, char, short, int, long (если очень хочется), в общем все базовые и даже структуры - их нужно просто упаковать в набор байт (с правильной последоватльностью битов - это нужно сделать на стороне клиента).

Изучите мой код в той теме, он вам очень поможет и я набил очень много шишек пока понял как это работает. Для простого управления железячкой (моторами, сервоприводами, чтения показаний датчиков и простого дергания ножками) - модуля с избытком достаточно.

 

1988Олег1988
Offline
Зарегистрирован: 23.03.2013

А Ваш код работает в браузере?

 

Вот что то я попытался сделать самостоятельно:

Прога клиента в 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

Как видно разные отправлемые и получаемые значения, почему это может быть?

Заранее спасибо за помощь.

Мининова
Offline
Зарегистрирован: 08.06.2012

Олег, терпеть не могу делфи.. пришлось искать, качать, ставить, вспоминать.. бррр =)
Вот что у меня получилось
Кусок клиента:

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);    
     }
*/
  }
}

В итоге отправляется в сокет

  data[0]:= 45;
  data[1]:= 65;
  data[2]:= 85;
  data[3]:= 105;
  data[4]:= 125;
  data[5]:= 145;

а получается

45
65
85
105
125
145

В итоге, чтобы передать несколько байт по сети, этого кода достаточно, однако что будет если послать инт ( 4 байта ) Код внизу ардино-скейтча как раз бы мог прочитать инт если длину масива уменьшить до 4, прочесть эти 4 байта и преобразовать что получилось в инт. Однако есть маааленькая загвоздка. Когда вы оправляете байты из клиента - нужно специальным образом менять последовательность Бит в Байте каждого числа - поглядите в эту степь и добавлять уже в правильном порядке в поток. У Инди, насколько я понял, есть уже готовые функции чтобы преобразовать таким образом байты.

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

P/S Черт, я привык к дотнету, его мини фреймворки делают рельно вещи быстрее чем на делфи - концентрируешься на задаче а не на том как поменять местами элементы в массиве ) Программист обязан уметь все это, но если уже все готово и позволит съекономить 5 минут на набор текста - я лучше посплю побольше =))

Надеюсь, дальше разберетесь .)

1988Олег1988
Offline
Зарегистрирован: 23.03.2013

Извиняюсь что долго отсутствовал

Мининова, а можите для полного моего счастья кинуть мне Ваши исходники :-)???

Мининова
Offline
Зарегистрирован: 08.06.2012

Тот, что написал для Вас ? Можно. Повезло что не убил.

http://yadi.sk/d/o9QwmECJ3gUqQ

Забирайте =) Взял из примера по инди, слегка обработал напильником =) Разумеется никаких проверок и многопоточности. Как пример - сойдет.