0

Problems using the IR Optical Sensor with the Huzzah32
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Problems using the IR Optical Sensor with the Huzzah32

by flcharron on Mon Aug 12, 2019 1:28 pm

I am trying to create a tachometer like the one in the Pro Trinket Tachometer guide https://learn.adafruit.com/pro-trinket-tachometer/circuit-design using the same reflective IR Optical Sensor https://www.adafruit.com/product/2349.

I will be using a HUZZAH32 for the final product as it will require wifi access and pushing pixels to the 3.5" TFT feather.

I started with the same base sketch as the guide, used an UNO R3 for the prototype, glued a white paper square on the chuck of my cordless drill and the RPMs seem to be displaying correctly in the serial monitor. All is good!

However, when I try to port this to my HUZZAH32, I am getting all sorts of ridiculously high values. This is my first time using an ESP32 and I am wondering if someone can help me find the solution.

Here's my circuit; pretty much the same as the one in the guide except for:
- pin 21 for the interrupt
- 3v instead of 5v
- no 7 segment backpack

HUZZAH32_RPM.png
Circuit
HUZZAH32_RPM.png (79.63 KiB) Viewed 56 times

And here's the code:

Code: Select all | TOGGLE FULL SIZE
#define interruptPin 21

long lastUpdate = 0;               // for timing display updates
volatile long accumulator = 0;         // sum of last 8 revolution times
volatile unsigned long startTime = 0;   // start of revolution in microseconds
volatile unsigned int revCount = 0;      // number of revolutions since last display update

void IRAM_ATTR tach_interrupt();

void setup() {
   Serial.begin(115200);
   pinMode(interruptPin, INPUT_PULLUP);
   attachInterrupt(digitalPinToInterrupt(interruptPin), tach_interrupt, FALLING);
}

void loop() {
   if (millis() - lastUpdate > 1000) {      // update every second
      unsigned int rpm = 0;
      
      
      // divide number of microseconds in a minute, by the average interval.
      if (revCount > 0) {
            rpm = 60000000 / (accumulator>>3);
      }
   
    Serial.print(rpm); Serial.println(" RPM");
   
    lastUpdate = millis();
    revCount = 0;
  }
}

void IRAM_ATTR tach_interrupt() {
  // calculate the microseconds since the last interrupt
  long usNow = micros();
  long elapsed = usNow - startTime;
  startTime = usNow;  // reset the clock
 
  // Accumulate the last 8 interrupt intervals
  accumulator -= (accumulator >> 3);
  accumulator += elapsed;
  revCount++;
}


Again, pretty much the same as the guide except for:
- pin 21
- IRAM_ATTR attribute for ESP32 interrupts
- removed the 7seg code

Here is a sample serial output from my original UNO R3 test, beginning with my drill stopped, revving it up and back down.

Code: Select all | TOGGLE FULL SIZE
0 RPM
0 RPM
0 RPM
93 RPM
126 RPM
496 RPM
662 RPM
711 RPM
774 RPM
830 RPM
902 RPM
861 RPM
816 RPM
0 RPM
0 RPM
0 RPM


And here is a sample output from the HUZZAH32, doing a similar test with my drill.

Code: Select all | TOGGLE FULL SIZE
0 RPM
0 RPM
0 RPM
759493 RPM
340909 RPM
111111 RPM
50804 RPM
394736 RPM
0 RPM
0 RPM
0 RPM


Does anyone have an idea of where to look? Are there really way too many interrupts, and if so, for what reason?

Thanks!

flcharron
 
Posts: 1
Joined: Wed Jul 03, 2019 2:03 pm

Please be positive and constructive with your questions and comments.