极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 19565|回复: 7

ethercard用于UDP发送的奇怪问题

[复制链接]
发表于 2013-2-21 00:16:27 | 显示全部楼层 |阅读模式
本帖最后由 superid888 于 2013-3-2 16:56 编辑

想用Arduino+ENC28J60+DHT11+两位7段数码管做一个带显示的温湿度监控下位机,各硬件和子模块测试正常,ENC28J60的CS接在D10,实测供电电压为3.25V,IDE用的1.03版,EtherCard用的是最新版,所有功能在开winshake抓包时正常,用上位机能正确显示温湿度,但不开开winshake时上位机就接收不到UDP数据,请问可能是什么问题?谢谢!
附上代码和测试的上位机程序

  1. #include <EtherCard.h>
  2. static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
  3. static byte myip[] = {192,168,2,23};
  4. static byte gwip[] = {192,168,23,254};
  5. byte Ethernet::buffer[100];
  6. static byte destip[]= {192,168,2,10};
  7. static int myport=1000,destport=1001;

  8. // bits representing segments A through G (and decimal point) for numerals 0-9
  9. const int numeral[10] = {
  10. //ABCDEFG /dp
  11. B11111100, // 0
  12. B01100000, // 1
  13. B11011010, // 2
  14. B11110010, // 3
  15. B01100110, // 4
  16. B10110110, // 5
  17. B10111110, // 6
  18. B11100000, // 7
  19. B11111110, // 8
  20. B11110110, // 9
  21. };
  22. // pins for decimal point and each segment
  23. // dp,G,F,E,D,C,B,A
  24. const int segmentPins[] = { 9,8,7,6,5,4,3,2};
  25. const int nbrDigits= 2; // the number of digits in the LED display
  26. //dig 1 2
  27. const int digitPins[nbrDigits] = { A4,A5};
  28. int dppin=A3; //set the decimal point link to PIN A3

  29. #include <dht11.h>
  30. dht11 DHT11;
  31. #define DHT11PIN A0 //DHT11 PIN 3 连接UNO A0

  32. char string1[2];//温度值字符串变量
  33. char string2[2];//温度值字符串变量

  34. void setup()
  35. {
  36.   Serial.begin(19200);
  37.   
  38.   if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0)
  39.     Serial.println( "Failed to access Ethernet controller");
  40.   if (!ether.staticSetup(myip))
  41.     Serial.println("Failed to set IP address");
  42.    
  43.      //    ether.setGwIp(gwip);
  44.    
  45. for(int i=0; i < 8; i++)
  46. pinMode(segmentPins[i], OUTPUT); // set segment and DP pins to output
  47. for(int i=0; i < nbrDigits; i++)
  48. pinMode(digitPins[i], OUTPUT);

  49. }

  50. void loop()
  51. {
  52.   
  53.   int chk = DHT11.read(DHT11PIN);

  54.   Serial.print("Read sensor: ");
  55.   switch (chk)
  56.   {
  57.    case DHTLIB_OK:
  58.                 Serial.println("OK");
  59.                 break;
  60.     case DHTLIB_ERROR_CHECKSUM:
  61.                 Serial.println("Checksum error");
  62.                 break;
  63.     case DHTLIB_ERROR_TIMEOUT:
  64.                 Serial.println("Time out error");
  65.                 break;
  66.     default:
  67.                 Serial.println("Unknown error");
  68.                 break;
  69.   }

  70. int humd=int(DHT11.humidity);
  71. int temp=int(DHT11.temperature-2);

  72. itoa(humd,string1,10);
  73. itoa(temp,string2,10);

  74. ether.sendUdp ((char*) string1, 4, myport, destip, destport);
  75. Serial.println("DATA send by UDP ");
  76. Serial.println(humd);
  77. Serial.println(temp);
  78. //  delay(2000);


  79. //Display on 7segment
  80.   int counter1=200;
  81. while(counter1)
  82. {
  83.     counter1--;
  84. //    showNumber(DHT11.humidity);
  85. showNumber(humd);
  86.    }
  87.     counter1=200;
  88. while(counter1)
  89. {
  90.     counter1--;
  91.     analogWrite(dppin,0);
  92. //    showNumber(DHT11.temperature-2);
  93. showNumber(temp);
  94.     analogWrite(dppin,200);
  95.    }
  96. }


  97. void showNumber( int number)
  98. {
  99. if(number == 0)
  100. showDigit( 0, nbrDigits-1) ; // display 0 in the rightmost digit
  101. else
  102. {
  103. // display the value corresponding to each digit
  104. // leftmost digit is 0, rightmost is one less than the number of places
  105. for( int digit = nbrDigits-1; digit >= 0; digit--)
  106. {
  107. if(number > 0)
  108. {
  109. showDigit( number % 10, digit) ;
  110. number = number / 10;
  111. }
  112. }
  113. }
  114. }
  115. // Displays given number on a 7-segment display at the given digit position
  116. void showDigit( int segnumber, int digit)
  117. {
  118. digitalWrite( digitPins[digit], HIGH );
  119. for(int segment = 1; segment <8; segment++)
  120. {
  121. boolean isBitSet = bitRead(numeral[segnumber], segment);
  122. // isBitSet will be true if given bit is 1

  123. //isBitSet = ! isBitSet; // remove this line if common cathode display

  124. digitalWrite( segmentPins[segment], isBitSet);
  125. }
  126. delay(5);
  127. digitalWrite( digitPins[digit], LOW );
  128. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

 楼主| 发表于 2013-2-21 00:32:33 | 显示全部楼层
不知道是ethercard库的原因还是代码的问题,硬件肯定是没问题的,抓包软件起了什么作用,唤醒?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-2-21 12:29:17 | 显示全部楼层
本帖最后由 superid888 于 2013-2-21 12:33 编辑

通过wireshake抓包分析,只要上位机在本端网口137端口发送NetBIOS name service询问包后,就能接收到ethercard的UDP数据,停止发送询问包,就收不到UDP数据,这是什么原因?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-2-24 10:26:59 来自手机 | 显示全部楼层
用w5100替代enc28j60,用arduino的标准库替代ethercard,发送udp包完全正常,估计ethercard库的软件堆栈还不完善。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-3-1 08:18:11 来自手机 | 显示全部楼层
本帖最后由 superid888 于 2013-3-1 20:49 编辑

对比w5100和28j60的ethercard库,发现thercard库缺少类似bind这样的函数,请问有什么办法?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-3-2 16:55:51 | 显示全部楼层
问题解决了,是erthercard库的问题,换了另外一个老库EtherShield,在IDE0023下编译通过,代码还变小了,只有不到6K,下一步把代码烧到ATMEGA8L试试看。


  1. /*
  2. This sketch receives humidity and temperature from sensor DHT11,
  3. display on two digits seven-segment LED and send UDP message to remote server, prints them to the serial port.
  4. The code can only compily by IDE 002X
  5. Created 10 Feb 2013, by Chen JW. [email][email protected][/email]
  6. */

  7. #include "EtherShield.h"
  8. static uint8_t mymac[6] = { 0x54,0x55,0x58,0x10,0x00,0x25};
  9. static uint8_t myip[4] = { 192,168,2,23};
  10. static uint8_t broadcastip[4] = { 192,168,2,255};
  11. // DestPort 1001, SrcPort 1000
  12. #define DEST_PORT_L  0xE9
  13. #define DEST_PORT_H  0x03
  14. #define SRC_PORT_L  0xE8
  15. #define SRC_PORT_H  0x03
  16. const char iphdr[] PROGMEM ={ 0x45,0,0,0x82,0,0,0x40,0,0x20}; // 0x82 is the total

  17. struct UDPPayload {
  18. uint8_t data[2];
  19. };
  20. UDPPayload udpPayload;

  21. // Packet buffer, must be big enough to packet and payload
  22. #define BUFFER_SIZE 150
  23. static uint8_t buf[BUFFER_SIZE+1];

  24. EtherShield es=EtherShield();

  25. // bits representing segments A through G (and decimal point) for numerals 0-9
  26. const int numeral[10] = {
  27. //ABCDEFG /dp
  28. B11111100, // 0
  29. B01100000, // 1
  30. B11011010, // 2
  31. B11110010, // 3
  32. B01100110, // 4
  33. B10110110, // 5
  34. B10111110, // 6
  35. B11100000, // 7
  36. B11111110, // 8
  37. B11110110, // 9
  38. };
  39. // pins for decimal point and each segment
  40. // dp,G,F,E,D,C,B,A
  41. const int segmentPins[] = { 9,8,7,6,5,4,3,2};
  42. const int nbrDigits= 2; // the number of digits in the LED display
  43. //dig 1 2
  44. const int digitPins[nbrDigits] = { A4,A5};
  45. int dppin=A3; //set the decimal point link to PIN A3

  46. #include <dht11.h>
  47. dht11 DHT11;
  48. #define DHT11PIN A0 //DHT11 PIN 3 == UNO A0

  49. char string1[2];//Humd
  50. char string2[2];//Temp

  51. void setup(){

  52.   Serial.begin(19200);

  53.   es.ES_enc28j60Init(mymac);
  54.   //init the ethernet/ip layer:
  55.   es.ES_init_ip_arp_udp_tcp(mymac,myip,80);

  56. for(int i=0; i < 8; i++)
  57. pinMode(segmentPins[i], OUTPUT); // set segment and DP pins to output
  58. for(int i=0; i < nbrDigits; i++)
  59. pinMode(digitPins[i], OUTPUT);

  60. //  delay(1000);
  61. }

  62. void loop(){

  63. int chk = DHT11.read(DHT11PIN);

  64.   Serial.print("Read sensor: ");
  65.   switch (chk)
  66.   {
  67.    case DHTLIB_OK:
  68.                 Serial.println("OK");
  69.                 break;
  70.     case DHTLIB_ERROR_CHECKSUM:
  71.                 Serial.println("Checksum error");
  72.                 break;
  73.     case DHTLIB_ERROR_TIMEOUT:
  74.                 Serial.println("Time out error");
  75.                 break;
  76.     default:
  77.                 Serial.println("Unknown error");
  78.                 break;
  79.   }

  80. int humd=int(DHT11.humidity);
  81. int temp=int(DHT11.temperature-2);

  82. //itoa(humd,string1,10);
  83. //itoa(temp,string2,10);
  84. //byte babb = 0x45;
  85. //string ass = ((char)babb).ToString();

  86. Serial.println(humd);
  87. Serial.println(temp);

  88. udpPayload.data[0] =humd;
  89. udpPayload.data[1] =temp;

  90. //udpPayload.data[0] =string1;
  91. //udpPayload.data[1] =string2;

  92. broadcastData() ;

  93. //Display on 7segment
  94.   int counter1=200;
  95. while(counter1)
  96. {
  97.     counter1--;
  98. //    showNumber(DHT11.humidity);
  99. showNumber(humd);
  100.    }
  101.     counter1=200;
  102. while(counter1)
  103. {
  104.     counter1--;
  105.     analogWrite(dppin,0);
  106. //    showNumber(DHT11.temperature-2);
  107. showNumber(temp);
  108.     analogWrite(dppin,200);
  109.    }
  110. }

  111. // Broadcast the data in the udpPayload structure
  112. void broadcastData( void ) {
  113.   uint8_t i=0;
  114.   uint16_t ck;
  115.   // Setup the MAC addresses for ethernet header
  116.   while(i<6){
  117.     buf[ETH_DST_MAC +i]= 0xff; // Broadcsat address
  118.     buf[ETH_SRC_MAC +i]=mymac[i];
  119.     i++;
  120.   }
  121.   buf[ETH_TYPE_H_P] = ETHTYPE_IP_H_V;
  122.   buf[ETH_TYPE_L_P] = ETHTYPE_IP_L_V;
  123.   es.ES_fill_buf_p(&buf[IP_P],9,iphdr);

  124.   // IP Header
  125.   buf[IP_TOTLEN_L_P]=28+sizeof(UDPPayload);
  126.   buf[IP_PROTO_P]=IP_PROTO_UDP_V;
  127.   i=0;
  128.   while(i<4){
  129.     buf[IP_DST_P+i]=broadcastip[i];
  130.     buf[IP_SRC_P+i]=myip[i];
  131.     i++;
  132.   }
  133.   es.ES_fill_ip_hdr_checksum(buf);
  134.   buf[UDP_DST_PORT_H_P]=DEST_PORT_H;
  135.   buf[UDP_DST_PORT_L_P]=DEST_PORT_L;
  136.   buf[UDP_SRC_PORT_H_P]=SRC_PORT_H;
  137.   buf[UDP_SRC_PORT_L_P]=SRC_PORT_L; // lower 8 bit of src port
  138.   buf[UDP_LEN_H_P]=0;
  139.   buf[UDP_LEN_L_P]=8+sizeof(UDPPayload); // fixed len
  140.   // zero the checksum
  141.   buf[UDP_CHECKSUM_H_P]=0;
  142.   buf[UDP_CHECKSUM_L_P]=0;
  143.   // copy the data:
  144.   i=0;
  145.   // most fields are zero, here we zero everything and fill later
  146.   uint8_t* b = (uint8_t*)&udpPayload;
  147.   while(i< sizeof( UDPPayload ) ){
  148.     buf[UDP_DATA_P+i]=*b++;
  149.     i++;
  150.   }
  151.   // Create correct checksum
  152.   ck=es.ES_checksum(&buf[IP_SRC_P], 16 + sizeof( UDPPayload ),1);
  153.   buf[UDP_CHECKSUM_H_P]=ck>>8;
  154.   buf[UDP_CHECKSUM_L_P]=ck& 0xff;
  155.   es.ES_enc28j60PacketSend(42 + sizeof( UDPPayload ), buf);
  156. }

  157. void showNumber( int number)
  158. {
  159. if(number == 0)
  160. showDigit( 0, nbrDigits-1) ; // display 0 in the rightmost digit
  161. else
  162. {
  163. // display the value corresponding to each digit
  164. // leftmost digit is 0, rightmost is one less than the number of places
  165. for( int digit = nbrDigits-1; digit >= 0; digit--)
  166. {
  167. if(number > 0)
  168. {
  169. showDigit( number % 10, digit) ;
  170. number = number / 10;
  171. }
  172. }
  173. }
  174. }
  175. // Displays given number on a 7-segment display at the given digit position
  176. void showDigit( int segnumber, int digit)
  177. {
  178. digitalWrite( digitPins[digit], HIGH );
  179. for(int segment = 1; segment <8; segment++)
  180. {
  181. boolean isBitSet = bitRead(numeral[segnumber], segment);
  182. // isBitSet will be true if given bit is 1

  183. //isBitSet = ! isBitSet; // remove this line if common cathode display

  184. digitalWrite( segmentPins[segment], isBitSet);
  185. }
  186. delay(5);
  187. digitalWrite( digitPins[digit], LOW );
  188. }

  189. // End
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2013-10-25 11:41:16 | 显示全部楼层
我也遇到了同样的问题。我如果不经过路由器,用网线直连电脑和arduino就没问题,如果通过路由连接arduino可以收到udp,但是发送不了udp

但是今天试着用makeUdpReply()又可以,看来是sendUdp()的问题。可能是header哪里有问题。。。
回复 支持 反对

使用道具 举报

发表于 2013-10-25 11:50:05 | 显示全部楼层
果然是header的问题,udprepare()里面的这一行有问题
  if ((dip[0] & 0xF0) == 0xE0 || *((long*) dip) == 0xFFFFFFFF)
    EtherCard::copyMac(gPB + ETH_DST_MAC, allOnes);
把它注释之后就可以了。。。。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-5 12:29 , Processed in 0.049000 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表