qpanda 发表于 2015-9-19 22:46:28

加一段看门狗代码,检查系统是否存活,自动重启

dcopyboy 发表于 2015-9-22 11:05:57

该模块,日常使用是非常稳定的。楼主可以贴出代码看看,我估计是出在 缓冲处理 不当上,我刚开始的时候,返回 1K左右的页面就卡死,几百字节的页面 多访问几次也卡死。后来正确出来缓冲后,循环合成的数十K的页面 访问也非常稳定。

tempchar 发表于 2015-9-22 14:33:30

想到两个可能,楼主试下排查
1是程序有问题,内存泄漏导致程序跑着跑着就不行了
2是供电问题,继电器的工作电流加上ENC28J60的工作电流是否超过40ma?拿万用表测试一下。arduino输出电流不能超过50ma的,要从外部供电给继电器和ENC28J60

zzjj296 发表于 2015-9-24 08:19:31

dcopyboy 发表于 2015-9-22 11:05 static/image/common/back.gif
该模块,日常使用是非常稳定的。楼主可以贴出代码看看,我估计是出在 缓冲处理 不当上,我刚开始的时候,返 ...

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

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

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

byte Ethernet::buffer;
bool useDHCP = true;

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

uint16_t calculateCRC(constchar* _regs, uint16_t arraySize)
{
unsigned int temp, temp2, flag;
temp = 0xFFFF;
for (unsigned char i = 0; i < arraySize; i++)
{
    temp = temp ^ *(_regs + i);
    for (unsigned char j = 1; j <= 8; j++)
    {
      flag = temp & 0x0001;
      temp >>= 1;
      if (flag)
      temp ^= 0xA001;
    }
}
temp2 = temp >> 8;
temp = (temp << 8) | temp2;
temp &= 0xFFFF;
return temp;
}

uint8_t responseData(uint8_t ID, uint8_t function, uint16_t address, uint8_t *data, uint8_t len, char *result)
{
uint8_t MaxLen = sizeof(char) * (1 + 1 + 1 + len + 2);
*(result + 0) = ID;
*(result + 1) = function;
*(result + 2) = len;
int n = 3;
for (int i = 0; i < len; i++)
{
    *(result + (n++)) = data;
}
uint16_t crc16 = calculateCRC(result, n);
*(result + (n++)) = crc16 >> 8;
*(result + (n++)) = crc16 & 0xff;
return MaxLen;
}

void responseError( uint8_t function, uint8_t wrongNumber, uint16_t sport, const uint8_t *dip, uint16_t dport)
{
char frame;
uint16_t crc16;
frame = slaveID;
frame = function + 0x80;
frame = wrongNumber;
crc16 = calculateCRC(frame, 3);
frame = crc16 >> 8;
frame = crc16 & 0xFF;
ether.sendUdp(frame, 5 , sport, dip, dport );
}

void udpSerialPrint(uint16_t port, uint8_tip, uint16_t src_port, const char *data, uint16_t len) {
IPAddress src(ip, ip, ip, ip);

if (data == slaveID && len >= 8)
{
    if (data == 0x03)
    {
      uint16_t address = (data << 8) + (data & 0xff);
      uint16_t datalen = (data << 8) + (data & 0xff);
      if (address + datalen <= sizeof(io_flag))
      {
      uint16_t crc16_1 = calculateCRC(data, len - 2);
      uint16_t crc16_2 = (data << 8) + (data & 0xff);
      if (crc16_1 == crc16_2)
      {
          uint8_t respdata;
          for (int i = 0 ; i < datalen; i++)
          {
            respdata = io_flag;
          }
          chara[] = {};
          uint8_t l = (responseData(slaveID, data, address, respdata, datalen, a));
          ether.sendUdp(a, l , port, ip, src_port );
      }
      else
      {
          responseError(0x00, 0x03, port, ip, src_port);
          Serial.println("Crc16 Err");
      }
      }
      else
      {
      responseError(0x00, 0x03, port, ip, src_port);
      Serial.println("Address not is Range");
      }
    }
    else if (data == 0x06)
    {
      uint16_t address = (data << 8) + (data & 0xff);
      uint16_t datavalue = (data << 8) + (data & 0xff);

      if (address < sizeof(io_flag))
      {
      io_flag = (bool)datavalue;
      if (io_flag)
      {
          digitalWrite(io_num, HIGH);
      }
      else
      {
          digitalWrite(io_num, LOW);
      }

      ether.sendUdp( data, len, port, ip, src_port );
      }
      else
      {
      responseError(0x00, 0x03, port, ip, src_port);
      Serial.println("Address not is Range");
      }
    }
    else
    {
      responseError(0x00, 0x01, port, ip, src_port);
      Serial.println("Function not is 0x03 or 0x06");
    }
}
else
{
    responseError(0x00, 0x01, port, ip, src_port);
    Serial.println("Number not is 0x01");
}
}

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

for (int i = 0 ; i < sizeof(io_flag); i++) {
    pinMode(io_num, OUTPUT);
    digitalWrite(io_num, LOW);
}

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

if (useDHCP)
{
    if (!ether.dhcpSetup())
    {
      Serial.println("Failed to get configuration from DHCP");
    }
    else
    {
      Serial.println("DHCP configuration done");
    }
}
else
{
    if (!ether.staticSetup(myip, gwip, dnsip, mask)) {
      Serial.println("Failed to set IP address");
    }
}

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

ether.udpServerListenOnPort(&udpSerialPrint, 5000);
}

void loop() {
ether.packetLoop(ether.packetReceive());
}






dcopyboy 发表于 2015-10-13 10:54:30

byte Ethernet::buffer;
这缓冲太大了,你可以修改成 byte Ethernet::buffer; 试试。
另 我是采用ether.httpServerReply_with_flags(strlen(funcstr), TCP_FLAGS_ACK_V); 语句进行应答的。

suoma 发表于 2015-11-2 19:04:41

试一下byte Ethernet::buffer;

追风逐梦 发表于 2020-11-16 17:25:51

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

大缓存空间,接收短数据,如900btyes 的空间,接收200bytes数据帧,这样设置合理吗
页: 1 [2]
查看完整版本: 求助UNOR3+ENC28J60+继电器+电磁阀 不时定死机问题