[SOLVED] Tachometer for coil winder

ted
Sat Dec 08, 2018 6:17 pm
Hi
This code is a pulses counter, I can count total pulses.
The question is: how to count numbers pulses per second ?

#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
int state = LOW;
int lastState = LOW;
int count = 0;

void setup()
{
lcd.begin(16, 2);
pinMode(PB12, INPUT_PULLDOWN);
state = digitalRead(PB12);
}
void loop()
{
if (state == HIGH && lastState == LOW)
{
count++;
}
lastState = state;
state = digitalRead(PB12);
digitalWrite (PB7, HIGH);
lcd.setCursor(3, 1);
lcd.print(count);
//delay(30);

}


mrburnette
Sat Dec 08, 2018 8:17 pm
For hobby use, you can just use Arduino’s internal timers:
http://forum.arduino.cc/index.php?topic=299311.0

For more precision, you can use an external GPS PPS TTL signal to gate your loop.

Dan Drown has notes on some of the high precision clock modules which could also be used if GPS is not usable (indoors, etc.)
http://blog.dan.drown.org/rtc-comparison

Ray


ted
Sun Dec 09, 2018 12:06 am
Almost there
It is working with analog input PA6 but have a problem to make it work with digital PB12


#include<LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);

//this code measures the difference between two rising edges of the digitalised signal coming from hall sensor and then prints the rpm.
//pin A0 is the signal pin
int refsig = 200; //for converting the analog signal coming from hall sensor to digital through arduino code
int val;//the digital value of the incoming analog signals
int prev_val = 0;
unsigned long t, cur_t; //time variables
void setup()
{
Serial.begin(115200);
lcd.begin(16, 2);
//pinMode(PA6, INPUT_PULLDOWN);
pinMode(PB12, INPUT_PULLDOWN);
}
void loop()//Measure RPM
{
//int sig = analogRead(PA6); //read raw value of hall sensor
int sig = digitalRead(PB12);
if (sig > refsig) val = HIGH; //convert it to digital 0,1 form
else val = LOW;
if (prev_val == 0 && val == 1) { //check for rising edge
cur_t = micros();
Serial.println(1000000 * 60 / (cur_t - t)); //print the rpm
lcd.setCursor(8, 1);
lcd.print("RPM=");
lcd.print(1000000 * 60 / (cur_t - t));
t = micros();
}

prev_val = val;

}


idahowalker
Sun Dec 09, 2018 1:50 am
How about looking to some of the frequency counter libraries?

mrburnette
Sun Dec 09, 2018 3:46 am
FYI…

https://www.google.com/search?q=arduino … ensor+tach
===> https://maker.pro/arduino/tutorial/how- … th-arduino

There are many types of Hall effect sensors, and certain types are better for certain applications. For applications where the speed of detection is not crucial, ordinary Hall effect sensors like 44E can be used. However, for applications that involve high-speed detection, like in the case of speedometers, high-frequency Hall effect sensors like US5881 or US1881 should be used. There are two main types of Hall effect sensors: latching and non-latching.

ImageThe US5881 is a non-latching Hall effect sensor. The sensor gives an output HIGH voltage whenever the north pole of a magnet is brought close to it, and switches LOW whenever the magnet is removed.

3144 digital input code here:
https://engineersportal.com/blog/2018/1 … from-a-fan


ted
Sun Dec 09, 2018 5:08 am
Thanks mr burnett
the last one it is working almost ok – long delay time delay, about 5 sec when combining it with pulse counter, which is not working after joining both programs iven when I seperate the inputs.

#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
//////////////////////////////////////////////
int state = LOW;
int lastState = LOW;
int count = 0;
///////////////////////////////////////////////
// digital pin 2 is the hall pin
int hall_pin = PB12;
// set number of hall trips for RPM reading (higher improves accuracy)
float hall_thresh = 100.0;

void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(115200);
lcd.begin(16, 2);
//////////////////////////////////////////
lcd.begin(16, 2);
pinMode(PB4, INPUT_PULLDOWN);
state = digitalRead(PB4);
/////////////////////////////////////////
// make the hall pin an input:
pinMode(hall_pin, INPUT);
}

// the loop routine runs over and over again forever:
void loop() {
// preallocate values for tach
float hall_count = 1.0;
float start = micros();
bool on_state = false;
// counting number of times the hall sensor is tripped
// but without double counting during the same trip
while (true) {
if (digitalRead(hall_pin) == 0) {
if (on_state == false) {
on_state = true;
hall_count += 1.0;
}
} else {
on_state = false;
}

if (hall_count >= hall_thresh) {
break;
}
}
//////////////////////////////////////

if (state == HIGH && lastState == LOW)
{
count++;
}
lastState = state;
state = digitalRead(PB4);
digitalWrite (PB7, HIGH);
lcd.setCursor(3, 0);
lcd.print(count);
//delay(30);

///////////////////////////////////////
// print information about Time and RPM
float end_time = micros();
float time_passed = ((end_time - start) / 1000000.0);
Serial.print("Time Passed: ");
Serial.print(time_passed);
Serial.println("s");
float rpm_val = (hall_count / time_passed) * 60.0;
Serial.print(rpm_val);
Serial.println(" RPM");
lcd.setCursor(3, 1);
lcd.print(rpm_val);
//delay(1); // delay in between reads for stability

}


ted
Sun Dec 09, 2018 5:48 am
Both programs are working, counter OK, RPM long time between reading -5sec.

#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
//////////////////////////////////////////////
int state = LOW;
int lastState = LOW;
int count = 0;
///////////////////////////////////////////////
// digital pin 2 is the hall pin
int hall_pin = PB12;
// set number of hall trips for RPM reading (higher improves accuracy)
float hall_thresh = 100.0;

void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(115200);
lcd.begin(16, 2);
//////////////////////////////////////////
lcd.begin(16, 2);
pinMode(PB12, INPUT_PULLDOWN);
state = digitalRead(PB12);
/////////////////////////////////////////
// make the hall pin an input:
pinMode(hall_pin, INPUT);
}

// the loop routine runs over and over again forever:
void loop() {
// preallocate values for tach
float hall_count = 1.0;
float start = micros();
bool on_state = false;
// counting number of times the hall sensor is tripped
// but without double counting during the same trip
while (true) {
if (digitalRead(hall_pin) == 0) {
if (on_state == false) {
on_state = true;
hall_count += 1.0;
}
} else {
on_state = false;
}

if (hall_count >= hall_thresh) {
break;
}
///////////////////////////////
if (state == HIGH && lastState == LOW)
{
count++;
}
lastState = state;
state = digitalRead(PB12);
digitalWrite (PB7, HIGH);
lcd.setCursor(3, 0);
lcd.print(count);
//delay(30);
/////////////////////////////
}

//////////////////////////////////////

///////////////////////////////////////
// print information about Time and RPM
float end_time = micros();
float time_passed = ((end_time - start) / 100000.0);
Serial.print("Time Passed: ");
Serial.print(time_passed);
Serial.println("s");
float rpm_val = (hall_count / time_passed) * 60.0;
Serial.print(rpm_val);
Serial.println(" RPM");
lcd.setCursor(3, 1);
lcd.print(rpm_val);
//delay(1); // delay in between reads for stability

}


RogerClark
Sun Dec 09, 2018 6:57 am
[idahowalker – Sun Dec 09, 2018 1:50 am] –
How about looking to some of the frequency counter libraries?

+1

Most of this could be done by using 2 counters. One to count the pulses and another to specify the measurement window.


ted
Sun Dec 09, 2018 2:36 pm
[idahowalker – Sun Dec 09, 2018 1:50 am] –
How about looking to some of the frequency counter libraries?

I did but not find the good one.


ted
Sun Dec 09, 2018 2:44 pm
[RogerClark – Sun Dec 09, 2018 6:57 am] –

[idahowalker – Sun Dec 09, 2018 1:50 am] –
How about looking to some of the frequency counter libraries?

+1

Most of this could be done by using 2 counters. One to count the pulses and another to specify the measurement window.

The first part is done the second I am considering something like this.
#include<LiquidCrystal.h>
LiquidCrystal lcd(12,11,6,5,4,3);
int pwm=9;
int pot=A0;
float value=0;
int percent;
float rev=0;
int rpm;
int oldtime=0;
int time;

void isr() //interrupt service routine
{
rev++;
}

void setup()
{
lcd.begin(16,2); //initialize LCD
attachInterrupt(0,isr,RISING); //attaching the interrupt
}

void loop()
{
delay(1000);
detachInterrupt(0); //detaches the interrupt
time=millis()-oldtime; //finds the time
rpm=(rev/time)*60000; //calculates rpm
oldtime=millis(); //saves the current time
rev=0;
value=analogRead(pot); //reads the speed control POT
value=value/4;
analogWrite(pwm,value); //sets the desired speed
percent=(value/255)*100; //finds the duty cycle %
lcd.clear();
lcd.setCursor(0,0);
lcd.print("___TACHOMETER___cd.setCursor(0,1);
lcd.print(rpm);
lcd.print(" RPM");
lcd.print(" ");
lcd.print(percent);
lcd.print("%");
attachInterrupt(0,isr,RISING);


ted
Sun Dec 09, 2018 5:10 pm
This one is fill up all LCD with RPM=0, starts with one RPM=0 and add another every 1 sec, no responding to input signal


///////////////////////////
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);

////////////////////////////
int hallsensor = PB12; // Hall sensor at pin 2

volatile byte counter;

unsigned int rpm;

unsigned long passedtime;

void isr()

{

//Each rotation, this interrupt function is run twice, so take that into consideration for

//calculating RPM

//Update count

counter++;

}
void setup()

{ Serial.begin(9600);
/////////////////////////////
lcd.begin(16, 2);
// pinMode(PB12, INPUT_PULLDOWN);
///////////////////////////////

//Intiates Serial communications

attachInterrupt(0, isr, RISING); //Interrupts are called on Rise of Input

pinMode(hallsensor, INPUT); //Sets hallsensor as input

counter = 0;

rpm = 0;

passedtime = 0; //Initialise the values

}
void loop()
{
delay(1000);//Update RPM every second

detachInterrupt(0); //Interrupts are disabled

rpm = 60 * 1000 / (millis() - passedtime) * counter;

passedtime = millis();

counter = 0;

Serial.print("RPM=");

Serial.println(rpm); //Print out result to monitor
lcd.print("RPM=");
lcd.print(rpm);

attachInterrupt(0, isr, RISING); //Restart the interrupt processing

}


ted
Sun Dec 09, 2018 6:20 pm
problem solved, now I can make my 50 000 turns coil in 20 min.

#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
int hallsensor = PB12;
float value = 0;
int percent;
float rev = 0;
int rpm;
int oldtime = 0;
int time;

void isr() //interrupt service routine
{
rev++;
}

void setup()
{
lcd.begin(16, 2); //initialize LCD

attachInterrupt(PB12, isr, RISING); //attaching the interrupt
pinMode(hallsensor, INPUT);
}

void loop()
{
delay(1000);

detachInterrupt(PB12); //detaches the interrupt
time = millis() - oldtime; //finds the time
rpm = (rev / time) * 60000; //calculates rpm
oldtime = millis(); //saves the current time
rev = 0;

//lcd.clear();
lcd.setCursor(0, 0);
lcd.print("RPM=");
lcd.print(rpm);

attachInterrupt(PB12, isr, RISING);

}


mrburnette
Sun Dec 09, 2018 7:04 pm
https://github.com/rogerclarkmelbourne/ … t-handlers

ted
Sun Dec 09, 2018 7:30 pm
Thanks for link, it will help to understand what I’m doing

Leave a Reply

Your email address will not be published. Required fields are marked *