Beispielprogramm etherShield-client für Arduino enc28j60 Ethernet-Controller-Shield aus http://www.nuelectronics.com/download/projects/etherShield.zip Der Client schickt alle 10s eine Anfrage auf Port 1200 an den Webserver 192.168.0.201. Der Webserver speichert die übergebenen Parameter in einen Datei index.php:<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<?php
if ($f=fopen("/tmp/xxx.txt","a"))
echo("file open");
else ("kann Datei nicht öffnen");
fwrite($f, "pwd=".$_GET["pwd"]."\n");
fclose($f);
if ($_GET["pwd"]=="abc")
{
//echo "authenticated";
}
else echo "password failed";
?>
</body>
</html>
oder mit WireShark auf dem Server-PC sniffen: Filter ip.addr==192.168.0.16
Achtung! Wireshark unter ubuntu mit starten: sudo wireshark
1 /*
2
3 */
4
5 extern "C" void __cxa_pure_virtual(void); //for C++ defines
6 void __cxa_pure_virtual(void) {};
7
8 #include <WProgram.h> //set the Path in Porject/Build Options/ Search dir Compiler
9 #include "../etherShield.h"
10
11 // please modify the following lines. mac and ip have to be unique
12 // in your local area network. You can not have the same numbers in
13 // two devices:
14
static
uint8_t mymac[6]
= {0x54,0x55,0x58,0x10,0x00,0x24};
//Achtung,
muss bei mehreren Clients individuell sein
15 static uint8_t myip[4] = {192,168,1,88};
16 static uint16_t my_port = 1200; // client port
17
18 // client_ip - modify it when you have multiple client on the network
19 // for server to distinguish each ethershield client
20 static char client_ip[] = "192.168.0.16";
21
22 // server settings - modify the service ip to your own server
23 static uint8_t dest_ip[4]={192,168,0,201};
24
static
uint8_t dest_mac[6];
Die
Macadr. Des Servers wird durch ARP automatisch ermittelt
25
26 enum CLIENT_STATE
27 {
28 IDLE, ARP_SENT, ARP_REPLY, SYNC_SENT
29 };
30
31 static CLIENT_STATE client_state;
32
33 static uint8_t client_data_ready;
34
35 static uint8_t syn_ack_timeout = 0;
36
37
38 #define BUFFER_SIZE 500
39 static uint8_t buf[BUFFER_SIZE+1];
40
41 char sensorData[10];
42
43 EtherShield es=EtherShield();
44
45 // prepare the webpage by writing the data to the tcp send buffer
46 uint16_t print_webpage(uint8_t *buf);
47 int8_t analyse_cmd(char *str);
48 // get current temperature
49 #define TEMP_PIN 3
50 void getCurrentTemp( char *temperature);
51 void client_process(void);
52
53 void setup(){
54
55 /*initialize enc28j60*/
56 es.ES_enc28j60Init(mymac);
57 es.ES_enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
58 delay(10);
59
60 /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
61 // LEDA=greed LEDB=yellow
62 //
63 // 0x880 is PHLCON LEDB=on, LEDA=on
64 // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00);
65 es.ES_enc28j60PhyWrite(PHLCON,0x880);
66 delay(500);
67 //
68 // 0x990 is PHLCON LEDB=off, LEDA=off
69 // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00);
70 es.ES_enc28j60PhyWrite(PHLCON,0x990);
71 delay(500);
72 //
73 // 0x880 is PHLCON LEDB=on, LEDA=on
74 // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00);
75 es.ES_enc28j60PhyWrite(PHLCON,0x880);
76 delay(500);
77 //
78 // 0x990 is PHLCON LEDB=off, LEDA=off
79 // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00);
80 es.ES_enc28j60PhyWrite(PHLCON,0x990);
81 delay(500);
82 //
83 // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
84 // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10);
85 es.ES_enc28j60PhyWrite(PHLCON,0x476);
86 delay(100);
87
88 //init the ethernet/ip layer:
89 es.ES_init_ip_arp_udp_tcp(mymac,myip,80);
90
91 // intialize varible;
92 syn_ack_timeout =0;
93 client_data_ready = 0;
94 client_state = IDLE;
95
//
initialize DS18B20 datapin
ein Onewire Temperatursensor
96 digitalWrite(TEMP_PIN, LOW);
97 pinMode(TEMP_PIN, INPUT); // sets the digital pin as input (logic 1)
98
99
100 }
101
102 void loop(){
103
104
if(client_data_ready==0){
neue Temperaturmessung nur
dann, wenn keine aktuellen Messdaten (immer dann, wenn der aktuelle
Messwert gerade verschickt wurde)
105 delay(10000UL); // delay 60s
106 // getCurrentTemp(sensorData);
107 client_data_ready = 1;
108 }
109 client_process();
110
111 }
112
113 uint16_t gen_client_request(uint8_t *buf )
114 {
115 uint16_t plen;
116 byte i;
117
118 plen= es.ES_fill_tcp_data_p(buf,0, PSTR ( "GET /ethershield_log/save.php?pwd=secret&client=" ) );
119 /* for(i=0; client_ip[i]!='0'; i++){
120 buf[TCP_DATA_P+plen]=client_ip[i];
121 plen++;
122 }
123 plen= es.ES_fill_tcp_data_p(buf,plen, PSTR ( "&status=temperature-" ) );
124 for(i=0; sensorData[i]!='0'; i++){
125
126 buf[TCP_DATA_P+plen]=sensorData[i];
127 plen++;
128 }
129 */
130
131 plen= es.ES_fill_tcp_data_p(buf, plen, PSTR ( " HTTP/1.0" ));
132 plen= es.ES_fill_tcp_data_p(buf, plen, PSTR ( "Host: 192.168.1.4" ));
133 plen= es.ES_fill_tcp_data_p(buf, plen, PSTR ( "User-Agent: AVR ethernet" ));
134 plen= es.ES_fill_tcp_data_p(buf, plen, PSTR ( "Accept: text/html" ));
135 plen= es.ES_fill_tcp_data_p(buf, plen, PSTR ( "Keep-Alive: 300" ));
136 plen= es.ES_fill_tcp_data_p(buf, plen, PSTR ( "Connection: keep-alive" ));
137
138 return plen;
139 }
140
141 //*****************************************************************************************
142 //
143 // Function : client_process
144 // Description : send temparature to web server, this option is disabled by default.
145 // YOU MUST install webserver and server script before enable this option,
146 // I recommented Apache webserver and PHP script.
147 // More detail about Apache and PHP installation please visit http://www.avrportal.com/
148 //
149 //*****************************************************************************************
150 void client_process ( void )
151 {
152 uint16_t plen;
153 uint8_t i;
154
155 if (client_data_ready == 0) return; // nothing to send
156
157 if(client_state == IDLE){ // initialize ARP
158 es.ES_make_arp_request(buf, dest_ip);
159
160 client_state = ARP_SENT;
161 return;
162 }
163
164
165 if(client_state == ARP_SENT){
166
167 plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf);
168
169 // destination ip address was found on network
170 if ( plen!=0 )
171 {
172 if ( es.ES_arp_packet_is_myreply_arp ( buf ) ){
173 client_state = ARP_REPLY;
174 syn_ack_timeout=0;
175 return;
176 }
177
178 }
179 delay(10);
180 syn_ack_timeout++;
181
182
183 if(syn_ack_timeout== 100) { //timeout, server ip not found
184 client_state = IDLE;
185 client_data_ready =0;
186 syn_ack_timeout=0;
187 return;
188 }
189 }
190
191
192
193 // send SYN packet to initial connection
194 if(client_state == ARP_REPLY){
195 // save dest mac
196 for(i=0; i<6; i++){
197 dest_mac[i] = buf[ETH_SRC_MAC+i];
198 }
199
200 es.ES_tcp_client_send_packet (
201 buf,
202 80,
203 1200,
204 TCP_FLAG_SYN_V, // flag
205 1, // (bool)maximum segment size
206 1, // (bool)clear sequence ack number
207 0, // 0=use old seq, seqack : 1=new seq,seqack no data : new seq,seqack with data
208 0, // tcp data length
209 dest_mac,
210 dest_ip
211 );
212
213 client_state = SYNC_SENT;
214 }
215 // get new packet
216 if(client_state == SYNC_SENT){
217 plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf);
218
219 // no new packet incoming
220 if ( plen == 0 )
221 {
222 return;
223 }
224
225 // check ip packet send to avr or not?
226 // accept ip packet only
227 if ( es.ES_eth_type_is_ip_and_my_ip(buf,plen)==0){
228 return;
229 }
230
231 // check SYNACK flag, after AVR send SYN server response by send SYNACK to AVR
232 if ( buf [ TCP_FLAGS_P ] == ( TCP_FLAG_SYN_V | TCP_FLAG_ACK_V ) )
233 {
234
235 // send ACK to answer SYNACK
236
237 es.ES_tcp_client_send_packet (
238 buf,
239 80,
240 1200,
241 TCP_FLAG_ACK_V, // flag
242 0, // (bool)maximum segment size
243 0, // (bool)clear sequence ack number
244 1, // 0=use old seq, seqack : 1=new seq,seqack no data : new seq,seqack with data
245 0, // tcp data length
246 dest_mac,
247 dest_ip
248 );
249 // setup http request to server
250 plen = gen_client_request( buf );
251 // send http request packet
252 // send packet with PSHACK
253 es.ES_tcp_client_send_packet (
254 buf,
255 80, // destination port
256 1200, // source port
257 TCP_FLAG_ACK_V | TCP_FLAG_PUSH_V, // flag
258 0, // (bool)maximum segment size
259 0, // (bool)clear sequence ack number
260 0, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
261 plen, // tcp data length
262 dest_mac,
263 dest_ip
264 );
265 return;
266 }
267 // after AVR send http request to server, server response by send data with PSHACK to AVR
268 // AVR answer by send ACK and FINACK to server
269 if ( buf [ TCP_FLAGS_P ] == (TCP_FLAG_ACK_V|TCP_FLAG_PUSH_V) )
270 {
271 plen = es.ES_tcp_get_dlength( (uint8_t*)&buf );
272
273 // send ACK to answer PSHACK from server
274 es.ES_tcp_client_send_packet (
275 buf,
276 80, // destination port
277 1200, // source port
278 TCP_FLAG_ACK_V, // flag
279 0, // (bool)maximum segment size
280 0, // (bool)clear sequence ack number
281 plen, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
282 0, // tcp data length
283 dest_mac,
284 dest_ip
285 );;
286 // send finack to disconnect from web server
287
288 es.ES_tcp_client_send_packet (
289 buf,
290 80, // destination port
291 1200, // source port
292 TCP_FLAG_FIN_V|TCP_FLAG_ACK_V, // flag
293 0, // (bool)maximum segment size
294 0, // (bool)clear sequence ack number
295 0, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
296 0,
297 dest_mac,
298 dest_ip
299 );
300
301 return;
302
303 }
304 // answer FINACK from web server by send ACK to web server
305 if ( buf [ TCP_FLAGS_P ] == (TCP_FLAG_ACK_V|TCP_FLAG_FIN_V) )
306 {
307 // send ACK with seqack = 1
308 es.ES_tcp_client_send_packet(
309
310 buf,
311 80, // destination port
312 1200, // source port
313 TCP_FLAG_ACK_V, // flag
314 0, // (bool)maximum segment size
315 0, // (bool)clear sequence ack number
316 1, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
317 0,
318 dest_mac,
319 dest_ip
320 );
321 client_state = IDLE; // return to IDLE state
322 client_data_ready =0; // client data sent
323 }
324 }
325 }
326
327 void OneWireReset(int Pin) // reset. Should improve to act as a presence pulse
328 {
329 digitalWrite(Pin, LOW);
330 pinMode(Pin, OUTPUT); // bring low for 500 us
331 delayMicroseconds(500);
332 pinMode(Pin, INPUT);
333 delayMicroseconds(500);
334 }
335
336 void OneWireOutByte(int Pin, byte d) // output byte d (least sig bit first).
337 {
338 byte n;
339
340 for(n=8; n!=0; n--)
341 {
342 if ((d & 0x01) == 1) // test least sig bit
343 {
344 digitalWrite(Pin, LOW);
345 pinMode(Pin, OUTPUT);
346 delayMicroseconds(5);
347 pinMode(Pin, INPUT);
348 delayMicroseconds(60);
349 }
350 else
351 {
352 digitalWrite(Pin, LOW);
353 pinMode(Pin, OUTPUT);
354 delayMicroseconds(60);
355 pinMode(Pin, INPUT);
356 }
357
358 d=d>>1; // now the next bit is in the least sig bit position.
359 }
360
361 }
362
363 byte OneWireInByte(int Pin) // read byte, least sig byte first
364 {
365 byte d, n, b;
366
367 for (n=0; n<8; n++)
368 {
369 digitalWrite(Pin, LOW);
370 pinMode(Pin, OUTPUT);
371 delayMicroseconds(5);
372 pinMode(Pin, INPUT);
373 delayMicroseconds(5);
374 b = digitalRead(Pin);
375 delayMicroseconds(50);
376 d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position
377 }
378 return(d);
379 }
380
381
382 void getCurrentTemp(char *temp)
383 {
384 int HighByte, LowByte, TReading, Tc_100, sign, whole, fract;
385
386 OneWireReset(TEMP_PIN);
387 OneWireOutByte(TEMP_PIN, 0xcc);
388 OneWireOutByte(TEMP_PIN, 0x44); // perform temperature conversion, strong pullup for one sec
389
390 OneWireReset(TEMP_PIN);
391 OneWireOutByte(TEMP_PIN, 0xcc);
392 OneWireOutByte(TEMP_PIN, 0xbe);
393
394 LowByte = OneWireInByte(TEMP_PIN);
395 HighByte = OneWireInByte(TEMP_PIN);
396 TReading = (HighByte << 8) + LowByte;
397 sign = TReading & 0x8000; // test most sig bit
398 if (sign) // negative
399 {
400 TReading = (TReading ^ 0xffff) + 1; // 2's comp
401 }
402 Tc_100 = (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25
403
404 whole = Tc_100 / 100; // separate off the whole and fractional portions
405 fract = Tc_100 % 100;
406
407 if(sign) temp[0]='-';
408 else temp[0]='+';
409
410
411 temp[1]= (whole-(whole/100)*100)/10 +'0' ;
412 temp[2]= whole-(whole/10)*10 +'0';
413
414 temp[3]='.';
415 temp[4]=fract/10 +'0';
416 temp[5]=fract-(fract/10)*10 +'0';
417
418 temp[6] = '0';
419 }
Kner
2011