RPM and the arduino playground

So I'm pretty much using the code from the Arduino playground for RPM and I'm not seeing any values being display. I'm using pin 2 for my interrupt and grounded that pin. I'm tapping a resistor to the pin from a 5v source. Any thoughts? I'm also using my strong hand lol.
this is all on a bread board. I'm using a ssd1306 OLED

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// GLOBALS
// Pins   // use Pro Mini
// following pins for trinket M0
int AC_RPM = 2;

int highPin = 7;
int highpin = 8;

// constants
int RPMtimer;

//variables
volatile byte count;
unsigned int RPM;
unsigned long TimeNow;
unsigned long TimeThen;
unsigned long Time;
void setup() {
  Serial.begin(9600);
  pinMode(highPin, OUTPUT);
  pinMode(highpin, OUTPUT);
  //pinMode(AC_RPM, INPUT);
  RPMtimer = 1250;

  // attachInterrupt(0 , RevCount, RISING);
  attachInterrupt(digitalPinToInterrupt(0), RevCount, RISING);
  count = 0;
  Time = 0;
  TimeNow = 0;
  TimeThen = 0;

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(50); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  // Show the display buffer on the screen. You MUST call display() after
  // drawing commands to make them visible on screen!
  display.display();
  delay(1000);
  // display.display() is NOT necessary after every single drawing command,
  // unless that's what you want...rather, you can batch up a bunch of
  // drawing operations and then update the screen all at once by calling
  // display.display(). These examples demonstrate both approaches...

  testscrolltext();
  digitalWrite(highPin, HIGH);
  digitalWrite(highpin, HIGH);
}
void loop() {
  TimeNow = millis();

  if (TimeThen == TimeNow - RPMtimer) {
    OLED();
  }

  if (count >= 20) {
    //Update RPM every 20 counts, increase this for better RPM resolution,
    //decrease for faster update
    RPM = ((30 * 1000) / ((millis() - Time) * count));  //Math will be differnt for locomotive
    // print or displace statement here.....
    Time = millis();
    count = 0;
  }
}

void OLED(void) {
  display.clearDisplay();
  display.setTextSize(1);             // Normal 1:1 pixel scale
  display.setTextColor(WHITE);        // Draw white text
  display.setCursor(0, 0);            // Start at top-left corner
  display.println(F("   Tachometer"));
  display.setTextColor(WHITE, BLACK); 
  display.println("~~~~~~~~~~~~~~~~~~~~~");
  display.setTextSize(2);             // Draw 2X-scale text
  display.setTextColor(WHITE);
  display.println(" RPM");
  display.setTextSize(1);
  display.println("");
  display.setTextSize(2);
  display.print(RPM);
  display.display();
}

void testscrolltext(void) {
  display.clearDisplay();
  display.setTextSize(5); // Draw 5X-scale text
  display.setTextColor(WHITE);
  display.setCursor(4, 0);
  display.println(F("SIXX"));
  display.setTextSize(2);
  display.setTextColor(BLACK, WHITE);
  display.println("      LLW.");
  display.display();      // Show initial text
  delay(1000);
}

void RevCount () {
  count++;
}

Just perusing:

  attachInterrupt(digitalPinToInterrupt(0), RevCount, RISING);

Your RPM input is pin 2, no? If so, why use digitalPinToInterrupt(0)?

As well, that pin should be set to INPUT...

I tried both 0 and 2, no difference. digital pin 2 is interrupt 0? isnt it?
the code on the playgound is 0 I think.

LandonW:
digital pin 2 is interrupt 0?

That depends on which microcontroller you're using. The whole point of the digitalPinToInterrupt() macro is that you don't need to think about that. digitalPinToInterrupt() takes an Arduino pin number. If you want an interrupt on Arduino pin 2 then you need to do this:

attachInterrupt(digitalPinToInterrupt(2), RevCount, RISING);

Better yet, use the dang variable you defined in your sketch!:

attachInterrupt(digitalPinToInterrupt(AC_RPM), RevCount, RISING);

LandonW:
the code on the playgound is 0 I think.

Please post a link to the Playground page.

Blackfin:
As well, that pin should be set to INPUT...

Pins are set to INPUT by default.

LandonW:
I'm using pin 2 for my interrupt and grounded that pin. I'm tapping a resistor to the pin from a 5v source.

You got it backwards. Connect the pin to ground via the resistor. This will act as a pull-down, so that the pin will always be in a known state rather than floating (switching to random states). Then when you want to trigger the interrupt, connect the pin to 5 V. That will overpower the pull-down resistor and pull the pin HIGH. You should study this tutorial:
https://www.arduino.cc/en/Tutorial/Button
Or much easier is to use the microcontroller's internal pull-up resistors:

pinMode(AC_RPM, INPUT_PULLUP);

Attach the interrupt like so:

attachInterrupt(digitalPinToInterrupt(AC_RPM), RevCount, FALLING);

Then connect the pin directly to ground to trigger the interrupt. No external resistor needed!
More information on INPUT_PULLUP:

LandonW:
I'm tapping a resistor to the pin from a 5v source. Any thoughts? I'm also using my strong hand lol.

Using interrupts to monitor a mechanical contact sounds like a seriously bad idea! :astonished:

The Arduino playground also sounds like a somewhat dubious source of information. :roll_eyes:

pert:
Better yet, use the dang variable you defined in your sketch!:

that would probably help lol

as requested, here is the link to the playground

https://playground.arduino.cc/Main/ReadingRPM

Paul__B:
Using interrupts to monitor a mechanical contact sounds like a seriously bad idea! :astonished:

why is that? aren't they used for button presses and such?

The capsense and led as light detector Playground articles taught me a lot.

If the contacts were debounced in hardware would that interrupt be okay?

For buttons you don't need interrupts.

GoForSmoke:
The capsense and led as light detector Playground articles taught me a lot.

If the contacts were debounced in hardware would that interrupt be okay?

For buttons you don't need interrupts.

I will look that up. I have seen interrupts on buttons. Check the link

LandonW:
I'm using pin 2 for my interrupt and grounded that pin. I'm tapping a resistor to the pin from a 5v source. Any thoughts?

First thought: Grounding the input pin will guarantee that you will never get an input other than LOW.
Try putting the resistor between the pin and Ground. Then tap the pin side of the resistor with a wire from +5V.
Or set the pinMode() to INPUT_PULLUP and tap the bare pin with a wire to Ground.

johnwasser:
First thought: Grounding the input pin will guarantee that you will never get an input other than LOW.
Try putting the resistor between the pin and Ground. Then tap the pin side of the resistor with a wire from +5V.
Or set the pinMode() to INPUT_PULLUP and tap the bare pin with a wire to Ground.

yes, good call sir.
when you declare a pin as an interrupt can you still us pinMode with it? I don't think that is shown in the examples under the reference tab.

I use the program in this link to measure the speed of a small DC motor.

...R

johnwasser:
First thought: Grounding the input pin will guarantee that you will never get an input other than LOW.
Try putting the resistor between the pin and Ground. Then tap the pin side of the resistor with a wire from +5V.
Or set the pinMode() to INPUT_PULLUP and tap the bare pin with a wire to Ground.

this seemed to help a lot, now im getting some values.

@Robbin2
I will look into that.

Thanks guys. Happy new year

LandonW:
I will look that up. I have seen interrupts on buttons. Check the link
https://youtu.be/J61_PKyWjxU

Interrupts have overhead and serial already use interrupts so unless I really NEED to use one, I don't.

If I used blocking code with things like delay or a wait-loop then I might feel the need and still get crap response but I use non-blocking code and can debounce buttons usually in 5 ms or less. During bounce time the pin state changes dozens of times per millisecond, will your interrupt debounce any better than a fast polling routine or a wait and see 20 ms later debounce poller? A human hit the button, it's not a precision event!

Physics: Every voltage has a gap that it will spark across. Physical contacts get sparks jumping when very close and Arduino is easily fast enough to sense them as many transitions in a very short time. I used port read code and an array to hold results and watched bounces down to 4 micros (the limit of micros resolution). An interrupt has over 5 micros overhead, how will the interrupt routine know when the bouncing has ended when it only runs when triggered by a change? My debounce routines look for the pin to be stable for some time and they always run with loop().

GoForSmoke:
Interrupts have overhead and serial already use interrupts so unless I really NEED to use one, I don't.

My debounce routines look for the pin to be stable for some time and they always run with loop().

can you post an example? with my current coding abilities I can usually get something to work.... how smooth or user friendly is a different story.
I usually use a small delay for debounce when I use buttons. However, I'm trying to get away from delay as much as possible (for learning purposes) and in this particular project a half bridge rectifier will trigger an opto….so no buttons.

my old sunpro tach in my car finally went bad after many years. so I decided to make one. I'm pulling signal from the AC signal wires of the distributor.

LandonW:
when you declare a pin as an interrupt can you still us pinMode with it?

Yes. Pins are in INPUT mode by default so you might see code that uses attachInterrupt() without a call to pinMode(), but if you want to activate the internal pull-up resistors you can use pinMode.

LandonW:
I don't think that is shown in the examples under the reference tab.

It certainly does:

const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}

void loop() {
  digitalWrite(ledPin, state);
}

void blink() {
  state = !state;
}

Note that code is not ideal because it doesn't do any debouncing of the input, but I decided it was better to avoid adding code that was not specifically related to the subject matter.

Thank you. I stand corrected