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 /home/roland/Dropbox/Projekte/ethernet/home/webclient/index.odt 5/5