Detect Moteino board type at compile time?

Started by scott216, December 20, 2017, 01:10:22 PM

Felix

Ethernet lib hanging and tandem with RFM69 has been discussed on several occasions in the forum, I don't have a link offhand but if you search, I think some folks posted solutions and perhaps forks of the lib(s), maybe some good stuff there.

scott216

Quote from: perky on December 27, 2017, 10:40:51 AM
I suspect this is down to SPI being a shared resource and during an SPI access for one device it is interrupted by the other device which then tries to use the same resource. You woud need to put some protection mechanisms in there to prevent it, for example disabling the interrupt for the other device while the SPI is being used. If the radio library ISR only sets a flag rather than accessing the SPI, and all accesses to SPI for the radio are done in the main loop, then you may get away with simply disabling the ethernet interrupt during those accesses. You'd need to look carefully at what the code is doing, but hanging like this is typical of this type of problem.

Mark.

You're entering territory that's above my pay grade. I'm not very well versed in interrupts and I have no idea what the Ethernet and Radio libraries are doing behind the scenes with interrupts.  I do use the watchdog timer library to reboot if it hangs, but I have to disable the WDT when I'm using the radio because it takes so long. I'm thinking I might be better not having the Ethernet library running on my Moteine.  Instead get a 2nd Arduino device or RPi and send the data to it via I2C.  Then the 2nd device would run Ethernet.

BTW - The Moteino is listening to weather station data from my Davis weather station.  Getting new data from the weather station normally takes about 2.5 seconds, but every once in a while I get a CRC error and then it take about 70 seconds to get.

perky

If your watchdog timer is timing out it implies there's blocking code in your main loop (by that I mean you are waiting in a loop for an external event to happen before moving to the next instruction). I'm not sure of the ethernet library but it may well have functions that need to be called regularly in a timely fashion.  Are you polling receiveDone() in a loop and waiting for it to be become active?

Mark.

scott216

Quote from: perky on December 28, 2017, 05:15:59 PM
If your watchdog timer is timing out it implies there's blocking code in your main loop (by that I mean you are waiting in a loop for an external event to happen before moving to the next instruction). I'm not sure of the ethernet library but it may well have functions that need to be called regularly in a timely fashion.  Are you polling receiveDone() in a loop and waiting for it to be become active?

Mark.

Every 30 seconds, from loop() I'm calling this routine to upload data to Weather Underground.  I time how long it takes to upload to weather underground, and it's usually a couple seconds.  I've got the WDT set to timeout at 8 seconds.  From what I can tell, the sketch usually locks up when the radio is busy doing something.  I think there's some frequency hopping stuff that occasionally takes a while.  I didn't write the library for the radio, so I don't know much about how it works behind the scenes.


//=============================================================================
// Upload to Weather Underground
//=============================================================================
bool uploadWeatherData()
{
  uint32_t uploadApiTimer = millis();  // Used to time how long it takes to upload to WU
  
  wdt_reset();

  // Send the Data to weather underground
  if (client.connect(g_server, 80))
  {
    #ifdef PRINT_DEBUG_WU_UPLOAD
      Serial.print(F("Connected to: "));
      Serial.println(g_server);  
    #endif
    
    client.print("GET /weatherstation/updateweatherstation.php?ID=");
    client.print(WUNDERGROUND_STATION_ID);
    client.print("&PASSWORD=");
    client.print(WUNDERGROUND_PWD);
    client.print("&dateutc=now");
    client.print("&winddir=");
    client.print(g_windDirection_Avg);
    client.print("&windspeedmph=");
    client.print(g_windSpeed);
    client.print("&windgustmph=");
    client.print(g_windgustmph);
    client.print("&tempf=");
    client.print((float)g_outsideTemperature / 10.0);
    client.print("&rainin=");
    client.print(g_rainRate);  
    client.print("&dailyrainin=");  
    client.print("&softwaretype=Arduino%20Moteino");
    client.print(VERSION);
    client.print("&action=updateraw");
    client.print("&realtime=1&rtfreq=");  
    client.print(UPLOAD_FREQ_SEC);        
    client.println("/ HTTP/1.1\r\nHost: host:port\r\nConnection: close\r\n\r\n"); 
  }
  else
  {
    #ifdef PRINT_DEBUG_WU_UPLOAD
      Serial.println(F("\nWU connection failed"));
    #endif
    client.stop();
    delay(500);
    return false;
  }
  
  uint32_t lastRead = millis();
  uint32_t connectLoopCounter = 0;  // used to timeout ethernet connection 
  wdt_reset();

  while (client.connected() && (millis() - lastRead < 1000))  // wait up to one second for server response
  {
    while (client.available()) 
    {
      char c = client.read();
      connectLoopCounter = 0;  // reset loop counter
      #ifdef PRINT_DEBUG_WU_UPLOAD
        Serial.print(c);  
      #endif
    }  
    
    connectLoopCounter++;
    // if more than 10000 loops since the last packet, then timeout
    if( connectLoopCounter > 10000L )
    {
      client.stop();
      #ifdef PRINT_DEBUG_WU_UPLOAD
        Serial.print(F("\n\nEthernet Timeout. Waited "));
        Serial.print((long)(millis() - uploadApiTimer));
        Serial.println(F(" mS"));
      #endif
      return false;
    }    
  }  // end while (client.connected() )
  
  wdt_reset();
  
  client.stop();

  #ifdef PRINT_DEBUG_WU_UPLOAD
    if ( (long)(millis() - uploadApiTimer) > 1500 )
    {
      Serial.print(F("WU upload took (mS): "));
      Serial.println((long)(millis() - uploadApiTimer));
    }
  #endif
  
  wdt_reset();

  return true;
  
}