Using Interrupts and then sending the resulting value to Pure Data

I'd like to use interrupts to read a frequency from a TSL237 using an Arduino then send the result to Pure Data. Most of the existing PD stuff - firmata and simple messaging system doesn't seem to be geared toward this. Can anyone give me advice on how to do this, please?

Nick Gammon has a good tutorial on interrupts

The important thing is not to try sending data from within an interrupt routine.

I wonder is there any need to use interrupts?


Great, will look at the tutorial - thanks for your help with that. Maybe the serial connection has to be open and closed before reading the interrupt... this will cause problems with responsiveness from PD if it is happening every other second... I'd like to use interrupts because the TSL237 outputs frequency rather than a voltage, i'm trying to read the frequency. If i extend the period the interrupt samples for (reads the frequency) i can extend the sensitivity of the sensor and detect very low quantities of light. Using the sensor as an audio channel in PD doesn't quite give the sensitivity required - so back to trying to read interrupts back into Pure Data.

This is the code I'm using to read the interrupt and detect the frequency produced by the TSL237:

// Reading The Frequency of TSL237 Using An Interrupt
//Taos TSL237S-LF light-to-frequency sensor:

//These define the pin connections of the Arduino.  
//They can be changed but only use digital in 2 or 3 for the Freq pin
#define TSL_FREQ_PIN 2 // output use digital pin2 for interrupt

float fD = 0.1; // Dark frequency
float Re = 2.3; // Irradiance responsivity
float eff475 = 0.113; // Luminous efficiency at 475nm, for dinoflagellate bioluminescence

int timing = 1000; // in milliseconds
volatile unsigned long pulse_cnt = 0;

void setup() {

void loop() {
 float Ee;

 // attach interrupt to pin2, send output pin of TSL230R to arduino 2
 // call handler on each rising pulse

 // High light intensity will trigger interrupts faster than the Arduino can handle, 
 // which may screw up timing of millis() and delay(), which are also interrupt based.
 // To flag excessive interrupts, keep track of both millis() and the RTC time 
 // before and after the sampling interval.
 uint32_t millis1 = millis();
// DateTime time1 =;
 attachInterrupt(0, add_pulse, RISING);
 delay(timing); // this is set earlier in the sketch to 1000 (one second) increase for increased sensitivity?

 uint32_t millis2 = millis();
// DateTime time2 =;
 unsigned long finalcnt=pulse_cnt;

 Ee = (finalcnt/(timing/1000.0) - fD)/1000.0/Re; // fO = fD + (Re)(Ee)

 Serial.print(", ");    
 Serial.print(finalcnt, 10);
 Serial.print(", ");
 Serial.print(Ee, 10);
 Serial.print(", ");

void add_pulse() {

 // increase pulse count
// Serial.println(pulse_cnt); // this line uncommented was causing everything to stop working!!!

This is the code I'm using to read the interrupt and detect the frequency produced by the TSL237:

That code is crap. It is NOT necessary to detach and attach the interrupt handler. It is NOT necessary to sit around with you thumb up your wherever while reading the frequency.

Please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

The correct way to do what you want is to have the ISR increment the counter continuously.

Use millis() to manage timing as illustrated in Several Things at a Time

When each second has elapsed then your code in loop() needs to capture the latest value in the counter - something like this

prevCount = latestCount;
latestCount = pulse_cnt;
countsThisSecond = latestCount - prevCount;