why does my interrupt keep firing?

Actually with D1 in that position I'm amazed it worked at all, and if so would have been flaky. I don't see why the opto is needed at all, if the sensor produces enough voltage to light the opt LED then that's enough to be read as high by the processor. Not optimal but should be enough, ie the uC should read high at about 1v+, you need more than that to fire the LED.

I'd put a comparator in there with hysterisis as mentioned above.

The 328 will catch an interrupt pulse of just a couple of clock cycles IIRC or even less, so I doubt the pulse width would be a problem.

In the code

const int  dataLedPin    =  4;  // LED indicating sensor data is received
const int  logLedPin     =  5;  // LED flashes during a log attemp

const int logInterrupt = 1; // ATmega 168 and 328 - interrupt 0 = pin 2, 1 = pin 3
const int interruptPin = 3;

For hardcoded magic number like these I think it's better to use defines

#define DATA_LED_PIN 4

with uppercase, admittedly this is a stylistic issue but defines don't consume any memory and upper case means that when you look at the value 200 lines down the code you know it's a constant, not a variable.

But that has nothing to do with the problem.

    uint8_t oldSREG = SREG;   // save interrupt register
    cli();                    // prevent interrupts while accessing the count

This is dodgy, you could easily get an interrupt between these two lines of code. Also when you restore SREG you could kill other status flags that were set since saving it.

You could do

   cli();                    // prevent interrupts while accessing the count  
    sensor_count = sensor; //get the count from the interrupt handler
    sensor = 0;           //reset the watts count
    sei();

But as the interrupts are occuring at a really slow rate (I assume) and you run this code straight after the ISR I doubt you need to disable interrupts.

delay(6000);

What is this for? Are the pulses occuring more frequently than 6 seconds? If so you'll miss counts.

Also do you know you're getting a clean interrupt pulse?


Rob