OK, I need this for use as a tool to develop a display code. I need to see mph and rpm on a lcd and have a corresponding output. To that end I have gotten this far with the coding but I think it now needs to use timer for the output? That is something I have never been good at! How to accomplish this?
//mph and rpm test generator
//for testing gear position code
int pot1 = A2; // select the input pin for the pot for rpm
int pot2 = A3; // select the input pin for the pot for mph
int rpmValue = 0; // variable to set rpm
int mphValue = 0; // variable to set mph
int rpmPin = 4; // select the pin for the output for rpm
int mphPin = 7; // select the pin for the output for mph
int RPM;
int MPH;
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// set the LCD address to 0x3f for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
void setup() {
//Serial.begin(115200);
//Serial.println("starting...");
lcd.begin(20, 4); // initialize the lcd for 20 chars 4 lines, turn on backlight
lcd.setCursor(1, 0); // lcd display setup of unchanging headings
lcd.print("RPM:"); // print fixed characters
lcd.setCursor(1, 2);
lcd.print("MPH:");
pinMode(rpmPin, OUTPUT); // declare the outputPin as an OUTPUT
pinMode(mphPin, OUTPUT); // declare the chargePin as an OUTPUT
}
void loop()
{
rpmValue = analogRead(pot1);
mphValue = analogRead(pot2);
RPM = map(rpmValue, 0, 1023, 800, 8000);
MPH = map(mphValue, 0, 1023, 0, 140);
lcd.setCursor(6, 0);
lcd.print(" "); // print blank spaces to clear old data
lcd.setCursor(6, 0);
lcd.print(RPM);
lcd.setCursor(6, 2);
lcd.print(" "); // print blank spaces to clear old data
lcd.setCursor(6, 2);
lcd.print(MPH);
delay (500);
}
Are you intending to input pulses, calculate RPM and also output a regenerated pulse? Or, are you building a pulse generator?
Usually I prefer to create off microcontroller pulse generator and use that when writing code. Frankly, once working the real electronics stuff is valuable to keep around.
Ok, well no one gets it so maybe I should clarify. I use 2 pots and display shows rpm and mph on different lines. So now I need output of the data shown. If it shows 3465 for rpm, I need output pluses of 3645 pulsed per minute. MPH may show 35 and there may be x number of pulses per mile but I think I can solve that math once I see how to have output based on the settings. ETC. It is variable, no fixed values.
OK well thanks for the help, strange that the help topic here says it is perfectly OK to declare a variable as global, but lets get back to why I posted here in the first place.
With rpm values of 800-8000 rpm you should be able to use a blink without delay software timer to generate your pulses.
You will map you pot values to an interval for the timer.
I would use microseconds instead of milliseconds for the software timer. Convert the rpm values to rps values and then take the inverse for the time period.
For example 1200 rpm = 20 rps and the period for the square wave is 1/20 = .05 second = 50000 microseconds.
I'm not clear if the mph values are derived from rpm or if they are a separate value.
Cattledog, Hi, initially I see 2 things I am not clear on but I have not spent much time with it yet. Taking the RPM since it is simpler math, I would have 180,000 blinks per minute for 3000 rpm so the 'const long interval =' would be 180 if it were Millis?
Then there would be 2 routines running, one for each pot?
Unless I've had too much New Years Eve cheer, I think your math needs some brushing up.
Using your example 3000 revolutions per minute = 50 revolutions per second. That is, you divide rpm by 60 to get rps. rps = rpm/60.
If your top rpm is 8000 then for good resolution its best to work in microseconds. So rpus = revolutions per microsecond = rpm/60,000,000.
The time period for each pulse is 1/frequency. So, in microseconds the period is 1/rpus = 60000000/rpm. So for 3000 rpm, each pulse will happen in every 20,000 microseconds (20 milliseconds).
If you want a square wave with equal high and low, then each level will last period/2 or 10,000 microseconds.
Then there would be 2 routines running, one for each pot?
How do you plan to read the mph pulses at the other end?
If you are going to sum up the counts for a second, and report that number as mph, then you could use milliseconds for timing the output pulses.
OK, I took a stab at it, it compiles and display works but no output pulse
//mph and rpm test generator
//for testing gear position code
int pot1 = A2; // select the input pin for the pot for rpm
//int pot2 = A3; // select the input pin for the pot for mph
int rpmValue = 0; // variable to set rpm
//int mphValue = 0; // variable to set mph
int rpmPin = 4; // select the pin for the output for rpm
//int mphPin = 7; // select the pin for the output for mph
int RPM;
//int MPH;
int rpmState = LOW; // rpmState used to set the rpmPin
unsigned long previousMicros = 0; // will store last time rpmPin was updated
// constants won't change:
const long interval = (RPM); // interval at which to blink (microseconds)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// set the LCD address to 0x3f for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
void setup() {
//Serial.begin(115200);
//Serial.println("starting...");
lcd.begin(20, 4); // initialize the lcd for 20 chars 4 lines, turn on backlight
lcd.setCursor(1, 0); // lcd display setup of unchanging headings
lcd.print("RPM:"); // print fixed characters
// lcd.setCursor(1, 2);
// lcd.print("MPH:");
pinMode(rpmPin, OUTPUT); // declare the outputPin as an OUTPUT
// pinMode(mphPin, OUTPUT); // declare the chargePin as an OUTPUT
}
void loop()
{
rpmValue = analogRead(pot1);
// mphValue = analogRead(pot2);
RPM = map(rpmValue, 0, 1023, 800, 8000);
// MPH = map(mphValue, 0, 1023, 0, 140);
lcd.setCursor(6, 0);
lcd.print(" "); // print blank spaces to clear old data
lcd.setCursor(6, 0);
lcd.print(RPM);
//lcd.setCursor(6, 2);
//lcd.print(" "); // print blank spaces to clear old data
//lcd.setCursor(6, 2);
//lcd.print(MPH);
delay (500);
unsigned long currentMicros = micros();
if (currentMicros - previousMicros >= RPM) {
// save the last time you pulsed rpmpin
previousMicros = currentMicros;
// if the rpmpin is off turn it on and vice-versa:
if (rpmPin == LOW) {
rpmPin = HIGH;
} else {
rpmPin = LOW;
}
// set the rpmpin with the rpmState of the variable:
digitalWrite(rpmPin, rpmState);
}
}