Arduino Uno na płytce stykowej

Po dłuższej prz­er­wie nad­szedł czas na powrót do arduino. Tym razem nic skom­p­likowanego jed­nak będącego pod­stawą do pro­jek­tów które będą przenos­zone z płytek stykowych na płytki obwodów drukowanych — czyli arduino (Uno) stwor­zone od zera na płytce stykowej i pro­gramowane przez inter­fejs ISP.

Schemat:

arduino Uno simple schema

 

Schemat połączeń jest prosty i sprawd­zony. Po złoże­niu układu i podłącze­niu go do pro­gram­a­tora (Ja uży­wam USBasp) trzeba wgrać boot­loader, tu spotkałem się z małym prob­le­mem — pro­gram­a­tor nie umiał się sko­mu­nikować z ukła­dem. Powo­dem było ustaw­ie­nie pro­gram­a­tora na  pro­gramowanie układów tak­towanych częs­totli­woś­cią więk­sza niż 1,5 MHz a ponieważ był to układ świeżo zaku­pi­ony, to był tak­towany zegarem wewnętrznym 1kHz (z tego co pamię­tam). Przestaw­ie­nie pro­gram­a­tora na “niską częs­totli­wość” załatwiło sprawę.

Boot­loader wgrałem dla poniższych ustaw­ień płytki (w pliku boards.txt):

uno.name=Arduino Uno
uno.upload.protocol=stk500
uno.upload.maximum_size=32256
uno.upload.speed=115200
uno.bootloader.low_fuses=0xff
uno.bootloader.high_fuses=0xde
uno.bootloader.extended_fuses=0x05
uno.bootloader.path=optiboot
uno.bootloader.file=optiboot_atmega328.hex
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
uno.build.variant=standard

Po wgra­niu boot­load­era należy przestawić pro­gram­a­tor na “wysoką częs­totli­wość” i można wgry­wać już pro­gramy (np. stan­dar­d­owy przykład z miga­jącą diodą na D13). I tu się pojawił kole­jny prob­lem — nie mogłem wgrać pro­gramu. Chwile googlowa­nia i po dopisa­niu do pliku boards.txt linii “uno.build.variant=standard” wszys­tko zaczęło działać.

To be con­tin­ued.… :)

 

 

Sterowanie urządzeniami przez ethernet — UDP

Długo to trwało ale wresz­cie pro­jekt zaczyna wychodzić z etapu testowa­nia i wchodzi w etap tworzenia konkret­nych aplikacji.

Poniżej przed­staw­iam dzi­ała­jący pro­to­typ który odczy­tuje kon­fig­u­rację sieciową z karty SD, inicjuje połącze­nie z kom­put­erem poprzez Eth­er­net (data­gramy UDP) i steruje dio­dami — te grają tu rolę atrapy urządzenia które może być sterowanie (czego dusza zaprag­nie — tu docelowo będą sil­niki krokowe i prądu stałego). Pro­to­typ zbu­dowany na pod­stawie Arduino Mega 2560 rev3 z dodatkiem mod­ułu kart SD i mod­ułu Eth­er­net na ENC28j60. Całość podzielę na części by było to czytelniejsze.

1. Struk­tura pliku konfiguracyjnego

Plik o nazwie “config.txt” jest zapisany w kat­a­logu głównym karty. Początek każdej linii zaczy­nać musi się od znaku “;” i kończyć znakiem “:” — są to znaki steru­jące sek­wencją odczytu i przyp­isy­wa­nia wartości do zmi­en­nych w pro­gramie. Plik zaw­iera następu­jące informacje:

  •  linie 1 — 6: Adres MAC urządzenia, zapisane w formie dziesięt­nej (każdy oktet osobno)
  • linie 7 — 10: Adres IP urządzenia, zapisane w formie dziesięt­nej (każdy oktet osobno)
  • linie 11 — 14: Adres IP kom­put­era z którym następuje komu­nikacja, zapisane w formie dziesięt­nej (każdy oktet osobno)
  • linia 15: Port na którym nasłuchuje komputer
Przykład­owy plik konfiguracyjny:
;00207:
;00112:
;00124:
;00228:
;00138:
;00184:
;00192:
;00168:
;00050:
;00002:
;00192:
;00168:
;00050:
;00001:
;29543:

2. Połącze­nie

Karta SD:
SD.Miso = Mega.50
SD.Mosi = Mega.51
SD.Sck = Mega.52
SD.CS = Mega.22

!!! WAŻNE !!! Zasi­lanie kary SD przez nóżkę 3,3V pod­piętą pod 5V — inaczej nie da się zainic­jal­i­zować karty SD (za niskie napię­cie lub błąd w mod­ule karty SD) — możliwe że mam jakiś wadliwy moduł a może prob­lem z zasi­laniem (mimo że pobier­ane bezpośred­nio z płytki Arduino)

Eth­er­net:
Ethernet.SI = MEGA.51 (MOSI)
Ethernet.SO = MEGA.50 (MISO)
Ethernet.CS = MEGA.10 (narzu­cone przez bib­lioteke !!!)
Ethernet.SCK = MEGA.52 (SCK)

Diody (przez rezys­tor 470Ohm):
czer­wona = MEGA.30;
zielona = MEGA.32;
żółta = MEGA.34;

3. Najważniejsza rzecz!!!!

W kodzie pro­gramu użyta jest funkcja “ES_udp_send” jest ona uży­wana ze sterown­ika Ether­Shield lecz w stan­dard­zie nie jest ona widoczna, trzeba ją dodać do pliku nagłówkowego i pliku źródeł.

Plik nagłówkowy:

void ES_udp_send(uint8_t *buf,char *data,uint8_t datalen,uint16_t sport, uint8_t *dip, uint16_t dport);

Plik źródeł:

 void EtherShield::ES_udp_send(uint8_t *buf,char *data,uint8_t datalen,uint16_t sport, uint8_t *dip, uint16_t dport){
 send_udp(buf,data,datalen,sport, dip, dport);
}

 

4. Kod pro­gramu mikrokontrolera

#include <SD.h> //biblioteka obsługi kart SD
#include "EtherShield.h" //biblioteka obsługi moduły ethernet
#include "enc28j60.h" //biblioteka do obsługi wysyłki pakiety udp
//zmienne dotyczące odczytu konfiguracji z karty SD
File confFile; //obiekt pliku konfiguracyjnego
unsigned char configFileLineCounter = 0;
unsigned char configLineCharCounter = -1;
char znakZPlikuKonfiguracji = ' ';
char liniaPlikuKonfiguracji[5] = {0,0,0,0,0};
boolean czyKonfiguracja = false;
//zmienne dotyczące modułu ethernet
uint8_t MAC[6] = {0, 0, 0, 0, 0, 0};
uint8_t IP[4] = {0, 0, 0, 0};
uint8_t IP_COMP[4] = {0, 0, 0, 0};
uint16_t PORT = 0;
uint16_t MYWWWPORT = 80;
#define BUFFER_SIZE 750
static uint8_t buf[BUFFER_SIZE+1];
EtherShield es=EtherShield();
uint16_t dat_p;
//odpowiedz do komputera
char reply[]="Odp_1"; //tekst odpowiedzi
char reply0[]="odebrano";
int var = 0;
//led
int lR = 30;
int lG = 32;
int lY = 34;
//zmienne programu
int msg_counter = 0;
int strToInt(char s[]) //metoda do przekształcenia linii z pliku konfiguracyjnego do integer'a (48 to wartosc dla znaku '0' - zero)
{
 return ((s[0] - 48) * 10000) + ((s[1] - 48) * 1000) + ((s[2] - 48) * 100) + ((s[3] - 48) * 10) + ((s[4] - 48) * 1);
}
void obslugaKomunikatu(uint8_t p[])
{
 Serial.println("obsluga komuniaktu");

 if (char(p[42]) == '1')
 {
 digitalWrite(lR,HIGH);
 }
 else
 {
 digitalWrite(lR,LOW);
 }

 if (char(p[43]) == '1')
 {
 digitalWrite(lG,HIGH);
 }
 else
 {
 digitalWrite(lG,LOW);
 }
if (char(p[44]) == '1')
 {
 digitalWrite(lY,HIGH);
 }
 else
 {
 digitalWrite(lY,LOW);
 }
}
void setup() {
 pinMode(53, OUTPUT); //obowiązkowe ustawienie pin d53 jako output - innaczej nie dziala SPI

 //led
 pinMode(lR, OUTPUT);
 pinMode(lG, OUTPUT);
 pinMode(lY, OUTPUT);
 digitalWrite(lR,LOW);
 digitalWrite(lG,LOW);
 digitalWrite(lY,LOW);

 Serial.begin(9600);//inicjalizacja obsługi portu szeregowego (do debugu)

 if (SD.begin(22)) //Inicjalizacja karty SD - CS na d22
 {
 Serial.println("inicjalizacja karty SD: OK");

 //odczyt konfiguracji z karty SD z pliku "CONFIG.TXT"
 confFile = SD.open("CONFIG.TXT");//otwarcie pliku do odczytu

 if(confFile)
 {
 Serial.println("otwarcie pliku CONFIG.TXT: OK");
 Serial.println("zawartosc pliku CONFIG.TXT:");

 while (confFile.available()) //odczyt linii z pliku
 {
 znakZPlikuKonfiguracji = confFile.read();
if(znakZPlikuKonfiguracji==':')
 {
 czyKonfiguracja = false;
 configLineCharCounter = -1;

 //zapisanie do konkretnej zmiennej
 //MAC
 if(configFileLineCounter == 1) MAC[0] = strToInt(liniaPlikuKonfiguracji);
 if(configFileLineCounter == 2) MAC[1] = strToInt(liniaPlikuKonfiguracji);
 if(configFileLineCounter == 3) MAC[2] = strToInt(liniaPlikuKonfiguracji);
 if(configFileLineCounter == 4) MAC[3] = strToInt(liniaPlikuKonfiguracji);
 if(configFileLineCounter == 5) MAC[4] = strToInt(liniaPlikuKonfiguracji);
 if(configFileLineCounter == 6) MAC[5] = strToInt(liniaPlikuKonfiguracji);
 //IP URZADZENIA
 if(configFileLineCounter == 7) IP[0] = strToInt(liniaPlikuKonfiguracji);
 if(configFileLineCounter == 8) IP[1] = strToInt(liniaPlikuKonfiguracji);
 if(configFileLineCounter == 9) IP[2] = strToInt(liniaPlikuKonfiguracji);
 if(configFileLineCounter == 10) IP[3] = strToInt(liniaPlikuKonfiguracji);
 //IP KOMPUTERA STERUJACEGO
 if(configFileLineCounter == 11) IP_COMP[0] = strToInt(liniaPlikuKonfiguracji);
 if(configFileLineCounter == 12) IP_COMP[1] = strToInt(liniaPlikuKonfiguracji);
 if(configFileLineCounter == 13) IP_COMP[2] = strToInt(liniaPlikuKonfiguracji);
 if(configFileLineCounter == 14) IP_COMP[3] = strToInt(liniaPlikuKonfiguracji);
 //PORT DO ODPOWIEDZI
 if(configFileLineCounter == 15) PORT = strToInt(liniaPlikuKonfiguracji);
 }

 if(czyKonfiguracja)
 {
 configLineCharCounter++;
 liniaPlikuKonfiguracji[configLineCharCounter] = znakZPlikuKonfiguracji;
 }

 if(znakZPlikuKonfiguracji==';')
 {
 configFileLineCounter++;
 czyKonfiguracja = true;
 }

 }
 Serial.println("KONIEC POBIERANIA Z PLIKU CONF");
 confFile.close();
 }
 else
 {
 Serial.println("otwarcie pliku CONFIG.TXT: BLAD");
 }

 Serial.println("proba inicjacji modulu ethernet");
 //inicjacja modułu ethernet
 //port 29543
 es.ES_enc28j60Init(MAC);
 Serial.println("modul ethernet: nadanie MAC");
 es.ES_init_ip_arp_udp_tcp(MAC,IP, MYWWWPORT);
 Serial.println("modul ethernet zainicjowany");

 }
 else
 {
 Serial.println("inicjalizacja karty SD: BLAD");
 }
}
void loop() {
//obsługa PING i odebranie pakietu
 dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf)); //odbior pakietu i odpowiedz na PING

 if (buf[IP_PROTO_P]==IP_PROTO_UDP_V) //sprawdzenie czy przetwarzany pakiet jest pakietem udp innym niż PING
 { 
 obslugaKomunikatu(buf);
 es.ES_udp_send(buf,reply0,sizeof(reply0),PORT, IP_COMP, PORT);
 buf[IP_PROTO_P]=0; // tu jest ana razie zagadka 
 }
}

5. Aplikacja komputerowa

Pro­gram który wysyła komendy z kom­put­era do urządzenia (widoczny na filmie) pochodzi ze strony KMtronic można z niej go pobrać wraz ze źródłami.

Dzi­ałanie

Po podłacze­niu i uru­chomie­niu najlepiej jest puś­cić ping do urządzenia — powinien dość szy­bko odpowiadać. Po uru­chomie­niu aplikacji podaje się adres IP urządzenia oraz port na którym ma słuchać kom­puter oraz wciskamy przy­cisk “Open”. Steru­jąc słowem (3 znaki “0” lub “1”) steru­jemy odpowied­nio dio­dami (dzi­ałanie pokazane na filmie).

Arduino mega 2560

No i przy­jechał długo wyczeki­wany arduino mega 2560.… i od razu pier­wsze wraże­nie: jakie to jest maleństwo :D . I teraz siedzę i myślę co można z nim zro­bić… i prob­lem mam wielkiej wagi.… bo jego możli­wości mnie trochę onieśmielają :) . Ale na pier­wszy ogień pójdzie ponowne pode­jś­cie do tem­atu zapisy danych na kar­cie SD (co było doty­chczas prob­le­mem ponieważ na atm168 było mało ramu (1KB), tu jest go pod dostatkiem.

All I want for Xmas is.… Arduino :)

Święta, Święta i po świę­tach. A na po świę­tach trzeba sobie prezent zro­bić :) i tak przy­były dwa nowe uC: atmega88 i atmega328, 4 sil­niki krokowe (taka ilość to już wystar­czy do wszys­tkiego :) ) oraz czu­jnik zbliże­niowy (tak by poekspery­men­tować sobie).

W kole­jce czeka jeszcze Arduino MEGA 2560 ale by to sfi­nal­i­zować czekam na dobrą ofertę :) .

Dodatkowo zakupiłem ogniwa do gąsienic z LEGO TECHNIC (dziękować bogom za Lego Edu­ca­tion :) i fir­mie akces.poznan.pl ). Teraz to mam zagadkę jak wkom­ponować sil­nik krokowy do mod­elu z lego.…

Arduino: silnik krokowy 28BYJ-48

Układ tes­tu­jący sil­nik krokowy 28BYJ-48. Tu potrzebne jest kilka słów wyjaśnienia, sil­nik posi­ada 64 kroków (po 5,625 stopni) oraz przekład­nię 1:32, infor­ma­cja o przekładni jest dość istotna ponieważ w nocie tech­nicznej znalazłem zapis o przekładni 1:64 co okazuje się błę­dem (sprawd­zone ekspery­men­tal­nie oraz wyczy­tane w odmę­tach internetu).

Przykład prezen­tuje jeden pełen obrót oraz obrót powrotny stop­niowo zwalniający.

Układ:

Połącze­nie silnika:

in1 = ard.8

in2 = ard.10

in3 = ard.11

in4 = ard.9

UWAGA: w przykładach arduino wydaje się że jest błąd (tam połącze­nie jest podane w kole­jności 8,9,10,11)

Dzi­ałanie:

Kod:

#include <Stepper.h>
#define STEPS 2048 //definicja ilości kroków na pełen obrót
 // 64 kroków na silniku (po 5.625 stopnia) razy 32 -
 // 1:32 (przekładnia, choć niestety w dokumentacja mówi o 1:64)
// inicjalizacja obiektu do kontroli silnika
Stepper myStepper(STEPS, 8,10,9,11);
void setup() {
myStepper.setSpeed(14.99); //to się wydaje być prędkość maksymalna 
 //15 RPM jest już wartością przy której silnik już nie działa
 myStepper.step(2048); //pełen obrót
 delay(1000);
 myStepper.setSpeed(14); //pełen obrót w drugą stronę - zwalniające
 myStepper.step(-146); 
 myStepper.setSpeed(13);
 myStepper.step(-146);
 myStepper.setSpeed(12);
 myStepper.step(-146);
 myStepper.setSpeed(11);
 myStepper.step(-146);
 myStepper.setSpeed(10);
 myStepper.step(-146);
 myStepper.setSpeed(9);
 myStepper.step(-146);
 myStepper.setSpeed(8);
 myStepper.step(-146);
 myStepper.setSpeed(7);
 myStepper.step(-146);
 myStepper.setSpeed(6);
 myStepper.step(-146);
 myStepper.setSpeed(5);
 myStepper.step(-146);
 myStepper.setSpeed(4);
 myStepper.step(-146);
 myStepper.setSpeed(3);
 myStepper.step(-146);
 myStepper.setSpeed(2);
 myStepper.step(-146);
 myStepper.setSpeed(1);
 myStepper.step(-150); //uzupełniono o utracone 4 kroki
}
void loop() {
}

 

 

Silnik krokowy — tak mało pinów a tak dużo silników

No to stało się jasne że bez dodatkowych nakładów pracy nie ma możli­wości by do atm168/328 podłączyć 6 sil­ników krokowych (takie były założe­nia). Jako że układ ma w sumie 20 wyjść/wejść, a podłącze­nie 1 sil­nika idzie na 4 złączach to nawet fizy­cznie się tego by nie dało (potzeb­nych nóżek to prze­cież 24 sztuki). Należy jeszcze pamię­tać że dodatkowo potrzebne są piny do obsługi Eth­er­netu, karty SD i wyświ­et­lacza LCD (w sumie to 6). I tu się się pojawia kwes­tia dodatkowych nakładów pracy. Możliwe jest połącze­nie sil­nika przez tylko 2 piny, traci sie tu dobrodziejstwo półkroków ale założe­nia nie przewidują robi­ena za pomocą tego rozwiąza­nia maszyn dokład­nych (np. frezarek CNC — do tego wystar­czą 3 sil­niki które da się podłączyć do tego układu w takiej kon­fig­u­racji poprzez 4 rzyłowe linie sterujące).

Na razie i tak jedzie do mnie tylko 1 sil­nik to potrenuję na nim sterowanie na 4 kablach. Poniżej podaję schemat połączenia na ULN2003 dla sterowa­nia na 2 kablach. W przyszłości trzeba będzie poprostu przy­go­tować sobie dedykowane płytki tego typu (myślę żeby za jed­nym zamachem zro­bić 10 sztuk, układ w smd kosz­tuje 90 gr do tego dioda i rezys­tory bez robo­cizny układ powinien kosz­tować nie więcej jak 3,50 — 4 złote).

Ram potrzebny od zaraz

A tak w ogóle to chyba kole­jny raz stykam się z prob­le­mem za małej ilości pamięci oper­a­cyjnej :( . Tym razem jest prob­lem z funkc­jami kon­wer­tu­ją­cymi int() i char() oraz z przyp­isy­waniem wartości do ele­mentu w tabeli np: zmiennaTabChar[0] = ‘a’. Tu znowu kła­ni­ają się ograniczenia ATM168. No nic, zakup ATM328 jest już przesąd­zony, może tydzień, może dwa i będzie. Ważą się też decyzje nad zaku­pem ARDUINO Mega :) , zobaczymy jak budżet będzie wyglą­dał :) . A na razie czekam na sil­nik krokowy ze sterown­ikiem ULN2003 oraz ekran LCD z nokii 3310/5110. Szczegól­nie czekam na wyświ­et­lacz — ostatni niestety przez własne lenistwo zniszczyłem przez co porzu­ciłem na razie inny pro­jekt — wygląda na to że jed­nak do niego powrócę :) .

Kaprysy modułu karty SD

Spotkałem się z dzi­wnym prob­le­mem związanym z zasi­laniem układu. Chodzi o prob­lem z inic­jal­iza­cją karty
SD na zasi­la­niu zewnętrznym przez zasi­lacz i sta­bi­liza­tor L7805CV. Układ zasi­lany przez pro­gram­a­tor (poprzez łącze ISP) nie sprawia żadnych prob­lemów. Zmierzyłem napię­cie na uC (zasi­lanie z pro­gram­a­tora) i na sta­bi­liza­torze, jako że mój miernik nawet nie ma określonej klasy błędu (takie małe gówienko za 20 zł :) ale do tych celów wystar­czy) to i odczyty są obar­c­zone błę­dem ale z uC dostają napię­cie 5,05V a ze sta­bi­liza­tora 4,95V. Zas­tanawia mnie czy różnica 0,1V może spraw­iać kar­cie SD tak wielki prob­lem.… takie to dość zas­tanaw­ia­jące — może kiedyś poz­nam odpowiedź.

Zro­biłem też dość ryzykowny ekspery­ment. Przy zasi­la­niu przez sta­bi­liza­tor, napię­cie do karty SD podałem na nóżkę dedykowaną dla 3,3V, najlep­sze w tym jest to że przy takim połącze­niu wszys­tko chodzi sta­bil­nie :D . Pewnie układ/karta nie zniesie takiego połączenia za długo ale dobrze wiedzieć ze jest taka możli­wość.… albo przy­na­jm­niej podawać tam 3,7V — to może być bezpieczniejsze.

Oby jak najm­niej takich niespodzianek.

Arduino — co dalej??

Do przetestowa­nia jest jeszcze sterowanie sil­nikiem krokowym — jest to chyba ostat­nia tech­nika jaką trzeba opanować przed przys­tąpi­e­niem do pisa­nia pro­gramu który zbierze wszys­tko “do kupy”. Po drodze zro­bię jeszcze test obsługi wyświ­et­lacza z nokii 5110/3310 — to się przyda do innego pro­jektu, może wplotę go do tego pro­to­typu również.

Kole­jnym etapem będzie opanowanie jed­noczes­nego obsługi­wa­nia karty SD i karty sieciowej a w później dodanie do tego obsługi sil­nika krokowego… i to by było już pewnie na tyle — pro­to­typ byłby gotowy. Później jeszcze trzeba będzie zro­bić model którym będzie to wszys­tko sterowało.

No a po tym to już tylko zostanie prze­niesie­nie pro­to­typu na dedykowaną płytkę i do dedykowanej obu­dowy, ale to jest raczej pieśń przyszłości…

Komunikacja sieciowa — datagramy UDP na ENC28j60 przy użyciu biblioteki EtherShield

Opis:

Układ i pro­gram real­izu­jący min­i­malne ustaw­ienia które umożli­wiają na przesłanie infor­ma­cji z kom­put­era na uC i z powrotem poprzez data­gramy UDP. Do sprawdzenia dzi­ała­nia przy­daje się jakiś mon­i­tor sieciowy (np. Wire­shark) oraz mały pro­gram umożli­wia­jący wysłanie i odbiór paki­etu UDP. Jako że wpis jest napisany na pod­stawie wiedzy zawartej na stronie KMTronic, tam też można znaleźć wspom­ni­any pro­gram do wysyłki i odbioru paki­etów wraz z jego kodem źródłowym (C#).

Sam pro­gram nie robi za wiele, czeka na pakiet UDP i jak go dostaje to odpowiada na niego ustalonym tek­stem (odpowiedź pokazy­wana w mon­i­torze sieciowym lub pro­gramie wys/odb.)

Układ:

 

 

Dzi­ałanie:

Kod:

#include "EtherShield.h" //dodanie obslugi wymaganej biblioteki
uint8_t mymac[6] = {0xCF,0x70,0x7C,0xE4,0x8A,0xB8}; //mac adres
uint8_t myip[4] = {192,168,50,2}; //adres ip 
uint16_t portNasluchuUDP = 12345; //port odpowiedzi 
uint16_t MYWWWPORT = 80; //port dla serwisu WWW ale po co on tu jest to nie wiadomo :)  
 //EDIT: najwidoczniej jest potrzebny bo biblioteka Ether Shield zawiera w sobie namiastke serwera WWW
 // portu po stronie mikrokontrolera nie ma
#define BUFFER_SIZE 750 //definicja wielkosci bufora
static uint8_t buf[BUFFER_SIZE+1]; //definicja bufora
char reply[]="raz, dwa, trzy: proba mikrofonu"; //tekst odpowiedzi
EtherShield es=EtherShield(); //obiekt bosługujacy komunikacje
uint16_t dat_p; //zmianna przechowujaca odebrany pakiet (??)
void setup()
{
 es.ES_enc28j60Init(mymac); //nadanie MAC adresu
 es.ES_init_ip_arp_udp_tcp(mymac,myip, MYWWWPORT); //inicjalizacja stosu tcp/udp.... chyba :) 
}
void loop()
{
dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf)); //odbior pakietu
 
 if (buf[IP_PROTO_P]==IP_PROTO_UDP_V) //sprawdzenie czy przzetwarzany pakiet jest pakietem udp
 {
 es.ES_make_udp_reply_from_request(buf,reply,sizeof(reply),portNasluchuUDP); //wysłanie odpowiedzi do nadajacego
 buf[IP_PROTO_P]=0; // tu jest ana razie zagadka 
 }
}