Hello, I have been working on a IR transmitter and receiver that puts out 5v and drops to 0v when object passes by. Most code examples are for rpm. I am using the Lafvin Nanos to do so. I cant get the rpm value to be constant at low rpm (like a bike wheel) to be steady, even using two reflectors on wheel. All I really want to do is map the number of the rpm or frequency of reflective hits, to a amp and speaker to speed up clicks or sound as the wheel speeds up and slows down. I am emulating what we all did as kids when we put a card on our bike wheel to sound like a motorcycle.....grin. Can anyone advise me on a better way to do this ?
Thanks, Randy
Hi @mc2,
How are you controlling the speaker? I would assume through a gpio pin, correct? If that's the case then you could use a PWM IO pin and map the RPM input into a PWM out (0-255) via a map & constrain pair and then that value to an analogWrite to set the PWM.
Sounds like a fun project 🙂
Scott
Sounds like a FUN project...
Looks like it needs more experimentation... maybe a special workbench setup with a motor hooked up, etc. so you could easily make changes and get quick results... Like maybe have more Markers around the rim and measure Time from one marker to the next... calc. rpm from the time... All markers would have to be equidistant from each other... maybe divide the cicumference by 10 for 10 markers and go from there?
How are you going to drive the Speaker for the sound of the Card?
Thanks for keeping us updated.
Have Fun,
Joe Lyddon
www.woodworkstuff.net
This idea is a little different and may not be right for what you want, but here goes. You could affix the IR sensor to pick up the teeth on the front sprocket. This could be fun as you could simulate a idle sound when the peddle is not turning but then use the feedback from the sensor to speed up the sound when peddling. This would actually more closely emulate how an actual engine would work. 😉
If you are just trying to get rpm you can tape a magnet on the wheel and use a hal effect sensor. You can prob. get by with one of those fridge magnets. Once you get the rpms worked out then start on the other parts of the project.
Thanks for all of your advice...! I moved to the hall Effect due to the sun reeked havoc on the IR sensors....Got the code to map tone to rpm count like 0 to 20 rpm, mapped to 32hrz to 45hrz high. One last snag though.....need it to increase not just pitch ,but the freq of the timing of it....Like a harley or a card pined to fork speeds up ...looking for bop.bop.bop. I tried "notone" with delay, pulse count linked to map/tone also.....no luck... Would post code and video, but not sure how to do that here.....
Randy (MC2)
The Code.......
// Useing Nano Tachometer
//-------------------------------------
#include <Wire.h>
//#include "Adafruit_LEDBackpack.h"
// External interrpt pin for sensor
#define interruptPin 2
//Adafruit_7segment matrix = Adafruit_7segment();
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
//-------------------------------------
// Setup - runs once at startup
//-------------------------------------
void setup()
{
// Initialize the serial port and display
Serial.begin(115200);
//matrix.begin(0x70);
// Enable the pullup resistor and attach the interrupt
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), tach_interrupt, FALLING);
}
//-------------------------------------
// Main Loop - runs repeatedly.
// Calculate RPM and Update LCD Display
//-------------------------------------
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 = 6000000 / (accumulator>>2);
}
Serial.println(rpm);
int sensorReading = (rpm);
int thisPitch = map(sensorReading, 0, 17, 31, 38);
// play the pitch:
tone(9, thisPitch, 1150);
//tone(10, thisPitch, 1050);
delay(1); // delay in between reads for stability
//matrix.println(rpm);
//matrix.writeDisplay();
lastUpdate = millis();
revCount = 0;
}
}
//-------------------------------------
// Interrupt Handler
// Magnetic sensor - target passed
// Calculate revolution time
//-------------------------------------
void 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 >> 2);
accumulator += elapsed;
revCount++;
}
Video of Bike wheel mounted to desk....
The map function worked great, but only to tone/pitch......BUT....I added today the ..
const int ledPin = LED_BUILTIN;
int ledState = LOW;
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change:
const long interval = 50;........
command to blink output pin...which is output for tone same......to pulse/blink 50ms on same output pin...........looking or should I say sounding good now......like a dirt bike...lol