Jump to content
  • 0

WF32 soft reset


Daniel H

Question

Hey all,

 I'm trying to figure out how to do a soft reset on the WF32. I've got a TCPClient program running that keeps getting stuck trying to reconnect to my network whenever there is some kind of failure. Resetting the board manually via BTN1 seems to fix the problem whenever it occurs, but if I'm not there to notice and reset it I'm gonna loose some data (the boards are continuously recording some sensors and sending it to a remote machine). Is there a way to program the board in MPIDE to automatically reset itself when it gets stuck like this?

Here is my code if you're interested.

/************************************************************************/
/*                                                                      */
/*        TCPClient                                                     */       
/*                                                                      */
/************************************************************************/
/*        original Author:         Keith Vogel                          */
/*        modified for WSU spokane vivarium by Daniel Harvey            */
/************************************************************************/

#include <WiFiShieldOrPmodWiFi_G.h> // This is for the MRF24WGxx on a pmodWiFi or WiFiShield

#include <DNETcK.h>
#include <DWIFIcK.h>

#include <DHT22.h>
#include <stdio.h>
#include <string.h>

char * szIPServer = "10.80.44.250";    // server to connect to
const IPv4 clientIP = {10,80,44,15};
const IPv4 gatewayIP = {10,80,44,1};
const IPv4 subnetMaskIP = {255,255,255,0};
const IPv4 DNS1IP = {69,166,36,80};
const IPv4 DNS2IP = {69,166,36,82};
unsigned short portServer = DNETcK::iPersonalPorts44 + 300; //port to connect to

// Specify the SSID
const char * szSsid = "Utility";

// select 1 for the security you want, or none for no security
#define USE_WPA2_PASSPHRASE

// modify the security key to what you have.
#if defined(USE_WPA2_PASSPHRASE)

    const char * szPassPhrase = "********";  
    #define WiFiConnectMacro() DWIFIcK::connect(szSsid, szPassPhrase, &status)

#endif
   
//******************************************************************************************
//***************************** END OF CONFIGURATION ***************************************
//******************************************************************************************

typedef enum
{
    NONE = 0,
    CONNECT_SERVER,
    CONNECT_NETWORK,
    READ,
    WRITE,
    CLOSE,
    ERROR,
} STATE;

STATE state = CONNECT_NETWORK;

TcpClient tcpClient;
byte rgbRead[1024];
int cbRead = 0;

int conID = 0;
    DNETcK::STATUS status;
/* ------------------------------------------------------------ */

void setup() {

    Serial.begin(9600);
    Serial.println("WiFiTCPClient on Chipkit WF32");
    Serial.println("vivarium project");
    Serial.println("");
    
}
/* ------------------------------------------------------------ */
//variable for data collection
int i=0;
uint8_t lightPin[6] = {A0,A1,A2,A3,A4,A5};
int lightValue[6] = {0,0,0,0,0,0};    //analog values for TEMT6000
DHT22 dht22Value[6]={(2),(3),(4),(5),(6),(7)};//digital values for dht22

char buf[1024] = "";
char buff[64] = "";

void loop() 
{
  switch(state)
  {
    case CONNECT_NETWORK:
      Serial.println("connect to network");
      //ermaherg idk how to connect
      conID = DWIFIcK::INVALID_CONNECTION_ID;
      if((conID = WiFiConnectMacro()) != DWIFIcK::INVALID_CONNECTION_ID)
      {
          Serial.print("Connection Created, ConID = ");
          Serial.println(conID, DEC);
          state = CONNECT_SERVER;
      }
      else
      {
          Serial.print("Unable to connection, status: ");
          Serial.println(status, DEC);
          Serial.println("Closing Client");
          state = ERROR;
      }
      DNETcK::begin(clientIP, gatewayIP, subnetMaskIP, DNS1IP, DNS2IP); // connect to network
    break;
    
    case CONNECT_SERVER:
      Serial.println("connect to server");
      tcpClient.connect(szIPServer, portServer); //connect to server
      state = READ;
    break;
    
    case READ:
      if(tcpClient.isConnected())
      {
        // see if we got anything to read
        if((cbRead = tcpClient.available()) > 0)
        {
          cbRead = cbRead < sizeof(rgbRead) ? cbRead : sizeof(rgbRead);
          cbRead = tcpClient.readStream(rgbRead, cbRead);
          for(int i=0; i < cbRead; i++) 
          {
            Serial.print(rgbRead);//, BYTE); ?!?
          }
          state = WRITE;
        }
      }
      else
      {
        state = CLOSE;
      }
    break;
    
    case WRITE:
      if(tcpClient.isConnected())
      {
        bzero(buf,1024);  //clear buffer
        for(i=0;i<6;i++)
        {
          bzero(buff,64);
          lightValue = analogRead(lightPin);
          sprintf(buff, "TEMT6000_%d:%d \n",i,lightValue);
          strcat(buf,buff);
        }
        for(i=0;i<6;i++)
        {
          bzero(buff,64);
          sprintf(buff, "DHT22_%d:",i+2);
          strcat(buf,buff);
          bzero(buff,64);
          dht22_errorchk(dht22Value, buff);
          strcat(buf,buff);
        }
        Serial.println(buf);
        tcpClient.print(buf);
        state = CLOSE;
      }
      else
      {
        state = CLOSE;
      }
    break;
    
    case CLOSE:
      tcpClient.close();
      if(DNETcK::isStatusAnError(status))
      {
        DNETcK::end();
        state = CONNECT_NETWORK;
      }
      else
      {
        delay(1000);
        state = CONNECT_SERVER;
      }
    break;
    
    case ERROR: 
      Serial.println("error... grrr");
      digitalWrite(65,HIGH);//reset?
    break;
    
    default:
    break;
  }
  // keep the stack alive each pass through the loop()
  DNETcK::periodicTasks(); 
}

//forgot where I got this from, but I did not write it
void dht22_errorchk(DHT22 current, char *buff)
{
  DHT22_ERROR_t errorCode;
  errorCode = current.readData();
  switch(errorCode)
  {
    case DHT_ERROR_NONE:
      sprintf(buff, "T:%hi.%01hi C, H:%i.%01i %% RH \n", current.getTemperatureCInt()/10, abs(current.getTemperatureCInt()%10), current.getHumidityInt()/10, current.getHumidityInt()%10);
      break;
    case DHT_ERROR_CHECKSUM:
      sprintf(buff, "check sum error T:%hi.%01hi C, H:%i.%01i %% RH \n", current.getTemperatureCInt()/10, abs(current.getTemperatureCInt()%10), current.getHumidityInt()/10, current.getHumidityInt()%10);
      break;
    case DHT_BUS_HUNG:
      sprintf(buff, "BUS Hung \n");
      break;
    case DHT_ERROR_NOT_PRESENT:
      sprintf(buff, "Not Present \n");
      break;
    case DHT_ERROR_ACK_TOO_LONG:
      sprintf(buff, "ACK time out \n");
      break;
    case DHT_ERROR_SYNC_TIMEOUT:
      sprintf(buff, "Sync Timeout \n");
      break;
    case DHT_ERROR_DATA_TIMEOUT:
      sprintf(buff, "Data Timeout \n");
      break;
    case DHT_ERROR_TOOQUICK:
      sprintf(buff, "Polled to quick \n");
      break;
    default:
      break;
  }
}

Link to comment
Share on other sites

4 answers to this question

Recommended Posts

Thanks LariSan, I was able to get my code to run using those newer libraries, however my server is still occasionally crashing for some reason and the boards are not automatically reconnecting as I expected them to. I'll keep at it, but I was also able to figure out a soft reset if anyone else finds this and is interested. There is a function to do this in one of the peripheral libraries for the pic32mc. Just include PLIB.h and call SoftReset(); 

Link to comment
Share on other sites

 

What libraries are you including (which network stack)?

Where did you get it from? time line?

 

There was a slight modification to an older version of the network stack that had a hang-up (it was fetching time from (NTP) and that could cause issues). This was later fixed. 

 

Link to comment
Share on other sites

After answering another forum post... I thought this may help too. 
This is from a training that the author of both libraries DEIPcK and DNETcK did for us earlier last year. 

These have been helpful for me in the past, so maybe they will help you. 

=============

First, we DO recommend you using the updated DEIPcK instead of the DNETcK. On the WF32, there should be almost no difference between the two stacks, except for the examples have been optimized. 

  • chipKITEthernet ---> This is the original drop of MPIDE that is a direct port from the Arduino Network stack, it's extremely top heavy and not optimized in any way (hard to combine other libraries with it). 
  • What your code is using--> DNETck/DWIFIck--> This was the first version of the Network Stack that was created for the WiFi Shield. It uses Microchip's MLA for the software (not fully Open Source) Since then it's been updated and optimized to 
  • What we recommend--> DEIPcK/ DEWFcK--> This should be included in the latest version of MPIDE, it is completely open source and supports both the Pic32MX (which is on the Uno, UC32, Cmod CK, DP32 and WF32) and the Pic32 MZ (Wifire) . This library uses a memory abstraction layer to make it compatible with the WiFire.

DNETck vs DEIPck

When using a network application there are a few rules that should be adhered to. 

Since DEIPcK is an embedded stack... it doesn't have a real time kernal (like you would find in Linux or other OS)

This means that you need to follow a couple of design guidelines:

The Network Stack needs to be run regularly.
-DEIPck:: peridoicTasks()

No operations should be blocking/ delayed for any extended periods. 
Your loop needs to service everything in the application, including the network stack. This means you need to write a part of your code that keeps your network stack continually engaged. (keep your function operations short to prevent starving other functions in the same loop (e.g. your network stack) ). 

 

If you write your code around DEIPcK, there looks to be a few provisions to help with this issue. 

  • -All network functions were written to return immediately, unlick DNETcK where there were provisions to block on a method. 
  • Poll until the operation completes or gets a hard error
  • parameters Must remain valid until the operation completes, so string and structure parameters should be declared static or global. 

 

Hopefully there is something useful in there?

 

Link to comment
Share on other sites

I'll keep at it, but I was also able to figure out a soft reset if anyone else finds this and is interested. There is a function to do this in one of the peripheral libraries for the pic32mc. Just include PLIB.h and call SoftReset(); 

That's super helpful. Thank you for sharing the soft reset!

I'm interested to find out what you discover is making your server crash periodically (e.g .if it's a network routine issue or if it's a best practice that we should recommend). Please keep us posted!

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...