极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

12
返回列表 发新帖
楼主: zzjj296

求助UNOR3+ENC28J60+继电器+电磁阀 不时定死机问题

[复制链接]
发表于 2015-9-19 22:46:28 | 显示全部楼层
加一段看门狗代码,检查系统是否存活,自动重启
回复 支持 反对

使用道具 举报

发表于 2015-9-22 11:05:57 | 显示全部楼层
该模块,日常使用是非常稳定的。楼主可以贴出代码看看,我估计是出在 缓冲处理 不当上,我刚开始的时候,返回 1K左右的页面就卡死,几百字节的页面 多访问几次也卡死。后来正确出来缓冲后,循环合成的数十K的页面 访问也非常稳定。
回复 支持 反对

使用道具 举报

发表于 2015-9-22 14:33:30 | 显示全部楼层
想到两个可能,楼主试下排查
1是程序有问题,内存泄漏导致程序跑着跑着就不行了
2是供电问题,继电器的工作电流加上ENC28J60的工作电流是否超过40ma?拿万用表测试一下。arduino输出电流不能超过50ma的,要从外部供电给继电器和ENC28J60
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-9-24 08:19:31 | 显示全部楼层
dcopyboy 发表于 2015-9-22 11:05
该模块,日常使用是非常稳定的。楼主可以贴出代码看看,我估计是出在 缓冲处理 不当上,我刚开始的时候,返 ...

应该不会是缓冲区的问题吧,发送无数个查询开关状态的命令都没问题有时个只发送一次控制开关的命令就挂掉了。。

PS:这论坛验证码好难输。。。
  1. #define slaveID 1

  2. #include <EtherCard.h>
  3. #include <IPAddress.h>
  4. static byte mymac[] = {0x74, 0x69, 0x69, 0x2D, 0x30, 0x31};
  5. static byte myip[] = { 192, 168, 1, 253};
  6. static byte gwip[] = { 192, 168, 1, 1 };
  7. static byte dnsip[] = { 192, 168, 1, 1 };
  8. static byte mask[] = { 255, 255, 255, 0 };

  9. byte Ethernet::buffer[700];
  10. bool useDHCP = true;

  11. static uint8_t io_num[] = {6, 7, 8, 9};
  12. static bool io_flag[] = {false, false, false, false};

  13. uint16_t calculateCRC(const  char* _regs, uint16_t arraySize)
  14. {
  15.   unsigned int temp, temp2, flag;
  16.   temp = 0xFFFF;
  17.   for (unsigned char i = 0; i < arraySize; i++)
  18.   {
  19.     temp = temp ^ *(_regs + i);
  20.     for (unsigned char j = 1; j <= 8; j++)
  21.     {
  22.       flag = temp & 0x0001;
  23.       temp >>= 1;
  24.       if (flag)
  25.         temp ^= 0xA001;
  26.     }
  27.   }
  28.   temp2 = temp >> 8;
  29.   temp = (temp << 8) | temp2;
  30.   temp &= 0xFFFF;
  31.   return temp;
  32. }

  33. uint8_t responseData(uint8_t ID, uint8_t function, uint16_t address, uint8_t *data, uint8_t len, char *result)
  34. {
  35.   uint8_t MaxLen = sizeof(char) * (1 + 1 + 1 + len + 2);
  36.   *(result + 0) = ID;
  37.   *(result + 1) = function;
  38.   *(result + 2) = len;
  39.   int n = 3;
  40.   for (int i = 0; i < len; i++)
  41.   {
  42.     *(result + (n++)) = data[i];
  43.   }
  44.   uint16_t crc16 = calculateCRC(result, n);
  45.   *(result + (n++)) = crc16 >> 8;
  46.   *(result + (n++)) = crc16 & 0xff;
  47.   return MaxLen;
  48. }

  49. void responseError( uint8_t function, uint8_t wrongNumber, uint16_t sport, const uint8_t *dip, uint16_t dport)
  50. {
  51.   char frame[5];
  52.   uint16_t crc16;  
  53.   frame[0] = slaveID;  
  54.   frame[1] = function + 0x80;
  55.   frame[2] = wrongNumber;  
  56.   crc16 = calculateCRC(frame, 3);
  57.   frame[3] = crc16 >> 8;
  58.   frame[4] = crc16 & 0xFF;
  59.   ether.sendUdp(frame, 5 , sport, dip, dport );
  60. }

  61. void udpSerialPrint(uint16_t port, uint8_t  ip[4], uint16_t src_port, const char *data, uint16_t len) {
  62.   IPAddress src(ip[0], ip[1], ip[2], ip[3]);

  63.   if (data[0] == slaveID && len >= 8)
  64.   {
  65.     if (data[1] == 0x03)
  66.     {
  67.       uint16_t address = (data[2] << 8) + (data[3] & 0xff);
  68.       uint16_t datalen = (data[4] << 8) + (data[5] & 0xff);
  69.       if (address + datalen <= sizeof(io_flag))
  70.       {
  71.         uint16_t crc16_1 = calculateCRC(data, len - 2);
  72.         uint16_t crc16_2 = (data[6] << 8) + (data[7] & 0xff);
  73.         if (crc16_1 == crc16_2)
  74.         {
  75.           uint8_t respdata[datalen];
  76.           for (int i = 0 ; i < datalen; i++)
  77.           {
  78.             respdata[i] = io_flag[address + i];
  79.           }
  80.           char  a[] = {};
  81.           uint8_t l = (responseData(slaveID, data[1], address, respdata, datalen, a));
  82.           ether.sendUdp(a, l , port, ip, src_port );
  83.         }
  84.         else
  85.         {
  86.           responseError(0x00, 0x03, port, ip, src_port);
  87.           Serial.println("Crc16 Err");
  88.         }
  89.       }
  90.       else
  91.       {
  92.         responseError(0x00, 0x03, port, ip, src_port);
  93.         Serial.println("Address not is Range");
  94.       }
  95.     }
  96.     else if (data[1] == 0x06)
  97.     {
  98.       uint16_t address = (data[2] << 8) + (data[3] & 0xff);
  99.       uint16_t datavalue = (data[4] << 8) + (data[5] & 0xff);

  100.       if (address < sizeof(io_flag))
  101.       {
  102.         io_flag[address] = (bool)datavalue;
  103.         if (io_flag[address])
  104.         {
  105.           digitalWrite(io_num[address], HIGH);
  106.         }
  107.         else
  108.         {
  109.           digitalWrite(io_num[address], LOW);
  110.         }

  111.         ether.sendUdp( data, len, port, ip, src_port );
  112.       }
  113.       else
  114.       {
  115.         responseError(0x00, 0x03, port, ip, src_port);
  116.         Serial.println("Address not is Range");
  117.       }
  118.     }
  119.     else
  120.     {
  121.       responseError(0x00, 0x01, port, ip, src_port);
  122.       Serial.println("Function not is 0x03 or 0x06");
  123.     }
  124.   }
  125.   else
  126.   {
  127.     responseError(0x00, 0x01, port, ip, src_port);
  128.     Serial.println("Number not is 0x01");
  129.   }
  130. }

  131. void setup () {
  132.   Serial.begin(57600);

  133.   for (int i = 0 ; i < sizeof(io_flag); i++) {
  134.     pinMode(io_num[i], OUTPUT);
  135.     digitalWrite(io_num[i], LOW);
  136.   }

  137.   if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0) {
  138.     Serial.println( "Failed to access Ethernet controller");
  139.   }

  140.   if (useDHCP)
  141.   {
  142.     if (!ether.dhcpSetup())
  143.     {
  144.       Serial.println("Failed to get configuration from DHCP");
  145.     }
  146.     else
  147.     {
  148.       Serial.println("DHCP configuration done");
  149.     }
  150.   }
  151.   else
  152.   {
  153.     if (!ether.staticSetup(myip, gwip, dnsip, mask)) {
  154.       Serial.println("Failed to set IP address");
  155.     }
  156.   }

  157.   ether.printIp("IP Address:\t", ether.myip);
  158.   ether.printIp("Netmask:\t", ether.netmask);
  159.   ether.printIp("Gateway:\t", ether.gwip);

  160.   ether.udpServerListenOnPort(&udpSerialPrint, 5000);
  161. }

  162. void loop() {
  163.   ether.packetLoop(ether.packetReceive());
  164. }
复制代码






本帖子中包含更多资源

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

x
回复 支持 反对

使用道具 举报

发表于 2015-10-13 10:54:30 | 显示全部楼层
byte Ethernet::buffer[700];
这缓冲太大了,你可以修改成 byte Ethernet::buffer[400]; 试试。
另 我是采用  ether.httpServerReply_with_flags(strlen(funcstr), TCP_FLAGS_ACK_V); 语句进行应答的。
回复 支持 反对

使用道具 举报

发表于 2015-11-2 19:04:41 | 显示全部楼层
试一下byte Ethernet::buffer[512];
回复 支持 反对

使用道具 举报

发表于 2020-11-16 17:25:51 | 显示全部楼层
dcopyboy 发表于 2015-9-11 08:15
ENC28J60 是一个比较理想的网络模块,我也曾多次使用,非常的稳定。
ENC28J60 关键要控制好收发缓冲,一旦 ...

大缓存空间,接收短数据,如900btyes 的空间,接收200bytes数据帧,这样设置合理吗
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-23 21:10 , Processed in 0.042147 second(s), 20 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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