Wiznet makers

mark

Published May 27, 2024 ©

62 UCC

8 WCC

40 VAR

0 Contests

0 Followers

0 Following

Detection and bugfix procedures for S2E modules

An automated program for detection and error correction of an S2E module based on W5100S-EVB-PICO.

COMPONENTS Hardware components

WIZnet - W5100S

x 1


PROJECT DESCRIPTION

The Hong Kong office needs to inspect the S2E modules after they receive them from the manufacturer.  Generally, random inspections will be conducted to check whether the module information matches and whether there are production errors.

This requires a detection program to assist.  We decided to write an automation program based on W5100S-EVB-PICO.  The program requirements is:
1. Automatically check all parameters, mainly MAC address and SN number;
2. Ability to automatically correct information errors when encountered;
3. Simple serial Ethernet communication test.

 

Cable Connection:

First define an array to store all S2E module information.

struct S2E_DATA {
  char      SERH[4];
  uint8_t   MAC[6];
  uint8_t   DEVICE_ID[16];
  uint8_t   STATE;
  uint8_t   SW_VER[2];
  char      DEVICE_TYPE[16];
  char      DEVICE_NAME[16];
  char      DEVICE_PWD[16];
  uint16_t  HTTP_PORT;
  uint32_t  FW_LEN;
  uint32_t  FW_CHECKSUM;
  uint8_t   DEBUG_FLAG;
  uint8_t   ECHO_FLAG;
  uint8_t   NETBIOS;
  uint8_t   DHCP;
  uint8_t   LOCAL_IP[4];
  uint8_t   SUBNET[4];
  uint8_t   GATEWAY[4];
  uint8_t   DNS[4];
  uint8_t   BAUDRATE;
  uint8_t   DATABIT;
  uint8_t   PARITY;
  uint8_t   STOPBIT;
  uint8_t   FLOWCONTROL;
  uint8_t   MODE;
  uint16_t  LOCAL_PORT;
  uint8_t   REMOTE_IP[4];
  uint16_t  REMOTE_PORT;
  uint8_t   DNS_FLAG;
  char      DOMAIN[32];
  uint16_t  INACTIVITY;
  uint16_t  RECONNECT;
  uint16_t  NAGLE_TIME;
  uint16_t  PACK_LEN;
  uint16_t  KEEP_ALIVE;
  uint8_t   BIND_PORT;
  uint8_t   LINK_CLEAR_BUF;
  uint8_t   LINK_PWD;
  uint8_t   LINK_MSG;
  uint8_t   LINK_CONDITION;
  uint8_t   START_MODE;
  uint16_t  CRC16;
  uint32_t  NET_SEND_NUM;
  uint32_t  NET_RCV_NUM;
  uint32_t  SEC_SEND_NUM;
  uint32_t  SEC_RCV_NUM;
  uint32_t  ON_TIME;
  uint8_t  RUN_MODE;
  uint8_t  TEMPERATURE;
};

RP2040 has two type serial ports, one is hardware UART and the other is software UART. The advantage of SoftwareSerial is that it can use any IO of RP2040.

SoftwareSerial W7500S2E_UART(1, 0);

There are two main data sources for information errors. One is from the module power-on  message, and the other is that it can be judged from the received UDP response message through UDP "Discovery" broadcast.

S2E power-on  message sample:

15:13:34.128 -> Device Name:W7500S2E-R1
15:13:34.874 -> MAC:00.08.DC.36.B9.7A
15:13:34.920 -> Firmware Version:2.9
15:13:34.920 -> Current Mode:AT-Command Mode
15:13:34.920 -> IP:192.168.1.88
15:13:34.920 -> SN:255.255.255.0
15:13:34.920 -> GW:192.168.1.1
15:13:34.920 -> DNS:114.114.114.114

Determine that the module has been initialized based on the power-on information and look for the "114" at the end of the power-on message.

    case POWER_UP_W7500S2E:
    {
      //digitalWrite(LED_BUILTIN, (millis() / 500) & 1);
      while (W7500S2E_UART.available())
      {
        char a = W7500S2E_UART.read();
        Serial.print(a);
        data_String += a;
        //Serial.print(data_String.indexOf("114\r\n"));
        if(data_String.indexOf("114\r\n")!= -1)
        {
          w7500s2e_mac = data_String.substring((data_String.indexOf("MAC:")+strlen("MAC:")),data_String.indexOf("\r\nFirm"));
          Serial.print("ok");
          data_String = "";
          W7500S2E_UART.flush();
          delay(3000);
          W7500S2E_UART.println("AT+SN?");
          CurrentState = GET_W7500S2E_INFO;
        }
      }
    }
    break;

Determine whether the device's MAC, SN and other data are incorrect.

    case CHECK_W7500S2E_SN:
    {
      while (W7500S2E_UART.available())
      {
        char a = W7500S2E_UART.read();
        Serial.print(a);
        data_String += a;
      }
      if(data_String.indexOf("OK\r\n")!= -1)
      {
        W7500S2E_UART.flush();
        data_String = "";
        CurrentState = POWER_UP_W7500S2E;
      }
    }
    break;

Get all module information and automatically correct it if there is an error in the "SN".

    case GET_W7500S2E_INFO:
    {
      digitalWrite(LED_BUILTIN, 0);
      while (W7500S2E_UART.available())
      {
        char a = W7500S2E_UART.read();
        Serial.print(a);
        data_String += a;
      }
      if(data_String.indexOf("OK\r\n")!= -1)
      {
        //data_String = "";
        w7500s2e_sn = data_String.substring(data_String.indexOf("[SN] Value is:")+strlen("[SN] Value is:"),data_String.indexOf("OK")-2);
        Serial.println(w7500s2e_sn);
        data_String = "";
        W7500S2E_UART.flush();
        w7500s2e_sn = "240425-"+ w7500s2e_mac.substring(9,11)+w7500s2e_mac.substring(12,14)+w7500s2e_mac.substring(15,17);
        W7500S2E_UART.println("AT+<WIZNET>&DSN="+w7500s2e_sn);  
        w7500s2e_sn = "";
        w7500s2e_mac = "";
        CurrentState = CHECK_W7500S2E_SN;
      }        
    }
    break;

UDP info message:

The config tool of the S2E module uses UDP broadcast to send the search message "SERH" to (255.255.255.255). After receiving the "SERH" message, the S2E series module will respond to its own module information by broadcast(255.255.255.255).

  server.begin(); // start the server
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

  udp.begin(8888); 

sendBroadcastPacket()

void sendBroadcastPacket() {
  char data[] = "SERH";                 // Discovery String
  udp.beginPacket(broadcastIp, 1460);   // open udp socket
  udp.write(data);                      // Write your data to the packet
  udp.endPacket();                      // end 
  Serial.println("Discovery packet sent.");
}

After the module Reset, obtain all parameters through the printReceivedPackets function and determine whether there are any errors.

void printReceivedPackets() {
  startTime = millis();
  while (millis() - startTime < 500) {
    int packetSize = udp.parsePacket();
    if (packetSize) {
      int len = udp.read((byte*)&s2eData, sizeof(s2eData) - 1);
      if (len > 0) {        
        for(uint8_t m=0; m<16; m++)
        {
          if((s2eDataArray[m].MAC[3] != s2eData.MAC[3])||(s2eDataArray[m].MAC[4] != s2eData.MAC[4])||(s2eDataArray[m].MAC[5] != s2eData.MAC[5]))
          {  
            memcpy(&s2eDataArray[count], &s2eData, sizeof(s2eData));             
            Serial.print("Module NO.");
            Serial.print(count+1);
            Serial.print(" [");
            Serial.print(s2eDataArray[count].DEVICE_TYPE);
            Serial.print("] ");
            Serial.print("[MAC]:");
            for (int i = 0; i < 6; i++) {
              Serial.printf("%02X",s2eDataArray[count].MAC[i]);
              if(i<5)
              {
                Serial.print(":");
              }else{
                Serial.print(" ");
                break;
              }
            }
            Serial.print("[IP]:");
            for (int n = 0; n < 4; n++) {
              Serial.print(s2eDataArray[count].LOCAL_IP[n]);
              if(n<3)
              {
                Serial.print(".");
              }else{
                break;
              }
            }
            Serial.print(" [Run Time]: ");
            Serial.print(s2eDataArray[count].ON_TIME/(60*60*24));
            Serial.print("d/");
            Serial.print((s2eDataArray[count].ON_TIME/(60*60))%24);
            Serial.print("h/");
            Serial.print((s2eDataArray[count].ON_TIME/(60))%60);
            Serial.print("m/");
            Serial.print((s2eDataArray[count].ON_TIME)%60);
            Serial.println("s");
            count ++;
            break;
          }          
        }
      }
    }
  }
}
Documents
Comments Write