intermittantly corrupted web page

I occasionally get a corrupted webpage as in the pdf, but on next request correct data comes out. indicates to me something is happening between data buffers and web page transmit. The data set is from RPM measurements gathered from an interrupt.

suggestions?

int sensorTemp1Pin = A0;    // select the input pin for temp1
int sensorTemp2Pin = A1;    // select the input pin for temp2
int sensorTempAmbPin = A2;  // select the input pin for temp_ambient
int sensorExtVrefPin = A3;  // select the input pin to measure external AD780, 3.00v half value, 2x 1k
int sensorExt5vPin = A4;  // select the input pin to measure 5v rail 40% value via 1.5k and 1k Resistors
int ledPin = 13;      // select the pin for the LED
#define ARRAY_LENGTH 96     // elements of the temperature arrays, ints, 3 arrays for temp, mega has 8192 bytes memory, 8 hours
                            // read once per 1 min = 60 * 8 = 480
                            // read once per 5 min = 12 * 8 = 480
        
#define ARRAY_LENGTH_RPM 2880  //  elements of RPM array
          

#define VoltsPerBit 0.002930     //  external Vref, AD780,3.00v 
                                 
#define Adj 0.9                 // adjustment factor for temperature reading accuracy  0014650
#define LoadResistor 4870  // Load resistor for temp sensor AD594, 1ua/deg K, 4870 ohms
#define NumberOneSecBetweenReadings 1 
#define NumberRPMBetweenTemps 3  //  20   5 min = 300sec = 300/NumberOneSecBetweenRPM
#define NumberOneSecBetweenRPM 1   // 15
int sensorValueTemp1[ARRAY_LENGTH];    // temperature(degF) coming from the sensor
int sensorValueTemp2[ARRAY_LENGTH] ;    // temperature(degF) coming from the sensor
int sensorValueTempAmb[ARRAY_LENGTH] ;  // temperature(degF) coming from the sensor
unsigned int sensorRPM[ARRAY_LENGTH_RPM] ; // RPM values  coming from 3ph voltage
unsigned int temp_RPM = 0;
unsigned int NumberOfBlips = 0;
long int RPMsubArray[60 * NumberOneSecBetweenReadings+1];   //average before report array
long int RPMAverager = 0;
#define NumTurbinePoles 42
#define ABS_MAX_RPM 4000

//int sensorValueCircularTest[ARRAY_LENGTH];  // test
int sensorBitsTemp1 = 0;  //ADC conversion bits
int sensorBitsTemp2 = 0;
int sensorBitsTempAmb = 0;
int ExtVrefBits = 0;
int Ext5vBits = 0;

float MicroAmps = 0;           // temp variable for temperature calculation
float temp7 = 0;
int temp_index = 0;
int temp_out_index = 0;
int array_index = 0;
int last_index = 0;  //
int temp_cntr = 0;
int temp_Temp_cntr = 0;
short Temp_flag = 0;

int DelayTime = 0;
int idx = 0;
int temp_val = 0; 

int temp_index_RPM = 0;
int temp_out_index_RPM = 0;
int array_index_RPM = 0;
int last_index_RPM = 0;
int temp_RPM_cntr = 0;
short RPM_flag = 0;

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE
};
IPAddress ip(192, 168, 1, 19);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
const int chipSelect = 4;

//setup for RPM measurement
// period of pulse accumulation and serial output, milliseconds
#define MainPeriod 100
long previousMillis = 0; // will store last time of the cycle end

volatile unsigned long duration=0; // accumulates pulse width
volatile unsigned int pulsecount=0;
volatile unsigned long previousMicros=0;


void setup() {

  // declare the ledPin as an OUTPUT:
  pinMode(ledPin, OUTPUT);
  analogReference(EXTERNAL);

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  attachInterrupt(0, myinthandler, RISING);  // setup interrupt
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

void loop() {
delay(1000); //  1 sec
  unsigned long currentMillis = millis();
  temp_RPM_cntr++;
  if (temp_RPM_cntr >= NumberOneSecBetweenRPM)
  {
    temp_RPM_cntr = 0;   // wait till reading trigger
    RPM_flag = 1;
    array_index_RPM++;
    if (temp_Temp_cntr > NumberRPMBetweenTemps)
      {
      temp_Temp_cntr = 0;
      Temp_flag = 1;
      array_index++;
      if (array_index >= ARRAY_LENGTH)          //  make arrays circular
        array_index = 0;
      }
  }
  if (array_index_RPM >= ARRAY_LENGTH_RPM)   //  make array circular
    array_index_RPM = 0;



//RPM stuff
if ( millis() - previousMillis >= MainPeriod)
  {
      Serial.print(RPM_flag);
      Serial.println("
");
      //previousMillis = currentMillis;
      previousMillis += MainPeriod;
      // need to bufferize to avoid glitches
      noInterrupts();
      unsigned long _duration = duration;
      unsigned long _pulsecount = pulsecount;
      duration = 0; // clear counters
      pulsecount = 0;
      interrupts();
      float Freq = 1e6 / float(_duration);
      Freq *= _pulsecount; // calculate F
      
      if (RPM_flag)            // take a reading
      {
      sensorRPM[array_index_RPM] = Freq * 60 * 2 / NumTurbinePoles; //  external /2 in hardware compensation
    
      temp_Temp_cntr++;
      RPM_flag = 0;
    }
  }

  if (Temp_flag)
  {
  // temperature code
  }


// listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
      //   client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");

  
          client.print("EBRC Field Network, Temperature Monitor Page ");
          client.println("
");

               
  
           client.print("Wind Turbine RPM ");
           temp_out_index_RPM = last_index_RPM;
           for ( temp_index_RPM = 0;  temp_index_RPM <= last_index_RPM ;  temp_index_RPM++ )
            {
            client.print(sensorRPM[temp_out_index_RPM]);
            temp_out_index_RPM = temp_out_index_RPM -1;
            client.print(", ");
            }
           temp_out_index_RPM = ARRAY_LENGTH_RPM;
           for (int temp_index_RPM = 0; temp_index_RPM < (ARRAY_LENGTH_RPM - last_index_RPM)  ; temp_index_RPM++ )
            {
            client.print(sensorRPM[temp_out_index_RPM]);
            temp_out_index_RPM = temp_out_index_RPM -1;
            client.print(", "); 
            }
          client.println("
");
          
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}

void myinthandler() // interrupt handler
{
  unsigned long currentMicros = micros();
  duration += currentMicros - previousMicros;
  previousMicros = currentMicros;
  pulsecount++;
}

occasional corruption.pdf (834 KB)

Could it be the interrupt is occurring during the client's webpage download? That could cause corruption of that variable.

How much corruption are you getting? The whole page or just the data part?

sometimes the corruption is like the uploaded pdf. other times it's just in the data portion.

I suspected some interference from the interrupt regarding the webpage, and was hoping declaring certain variables as volatile might help, but I'm not experienced with web things, I'm mostly a data acquisitions guy.

before I added the interrupt, there was also occasional corruption, but not to the current extent.

Which Arduino are you using? It is possible you are running out of memory or overflowing a buffer.

Using mega 2560. I’m confident it’s not a memory problem as a second read gives good data set

You are writing an unsigned long value in the interrupt. If the ethernet shield is in the process of printing (converting) that number when the interrupt occurs, you could get some corruption. I don't know how the ethernet shield does if you stop interrupts during its conversion of the unsigned long, but I think I would give it a try.

edit: It appears you are stopping the interrupts in one location in your sketch, but I haven't checked all of it.

I'm stopping interrupts in a critical region of the interrupt during an rpm measurement to ensure integrity of the count.

I'll give this a try once I get off travel

The corruption is well beyond a single value, typically a range of values. In the full sketch, there are 3 other tables in addition to the rpm table. Sometimes these get messed up as well so the trouble isn't specific to this one table, and seems to occur randomly somewhere in the web page.

I was thinking that the destination address might be getting messed up by the. Interrupt, but it was unclear to me how to protect it

Tim

Then I suggest you go through the code to insure you are not overflowing an array somewhere.