Hello,
I am working in a project and I have a brushless motor controlled through an ESC and I want to get the speed data while the motor is running. However I did not manage to do that. Below you can see the code for running the motor and the hall effect sensor code
How can I combine these two codes and get the speed readings from the hall effect sensor while the motor is running in the same manner?
Brushless motor code:
#include <Wire.h>
#include <Servo.h>
Servo esc_signal;
int velocity = 8;
void setup() {
esc_signal.attach(9);
esc_signal.write(velocity);
delay(100);
for (velocity = 8; velocity <= 17; velocity += 1)
{
esc_signal.write(velocity);
delay(1000);
}
for (velocity = 17; velocity >= 0; velocity -= 1)
{
esc_signal.write(velocity);
delay(1500);
}
esc_signal.write(0);
delay(1000);
}
Hall effect sensor code:
volatile float rpmcount = 0;
float rpm = 0;
float radial_vel = 0;
float linear_vel = 0;
unsigned long lastmillis = 0;
void setup()
{
Serial.begin(9600);
attachInterrupt(0, rpm_bike, FALLING); //interrupt zero (0) is on pin two(2).
}
void loop()
{
if (millis() - lastmillis == 1000)
{ /Uptade every one second, this will be equal to reading frecuency (Hz)./
detachInterrupt(0); //Disable interrupt when calculating.
rpm = rpmcount * 60; //Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.
radial_vel = rpm * M_PI / 30; //convert rpm to radial velocity in rad/s.
linear_vel = radial_vel * 0.33; //convert radial velocity to linear velocity in m/s.
Serial.print("RPM = "); //print the word "RPM".
Serial.print(rpm); // print the rpm value.
Serial.print("\t\t Linear Speed = "); //print the word "Linear Velocity".
Serial.print(linear_vel); //print the linear velocity value.
Serial.println(" m/s"); //print the word "m/s".
rpmcount = 0; // Restart the RPM counter
lastmillis = millis(); // Update lasmillis
attachInterrupt(0, rpm_bike, FALLING); //enable interrupt
}
}
void rpm_bike()
{ /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
rpmcount++;
}
Do both programs work the way you want?
Paul
Yes! Both the motor and hall effect sensor codes are working fine when I run them one at a time. I just want to combine both of them and get the speed value while the motor is running. My project is an autonomous bicycle so I have a hall effect sensor to measure the speed of the wheel and the electric motor is connected to the bicycle and drives it.
Unless you only want to report the speed when the output changes you will have to get rid of the delay() calls. This is necessary when two or more tasks are to share the same processor.
#include <Servo.h>
Servo esc_signal;
int velocity = 8;
enum {Idle, RampingUp, RampingDown, Stopped} State = Idle;
unsigned long StateStartTime = 0;
void setup()
{
esc_signal.attach(9);
esc_signal.write(velocity);
delay(100);
}
void loop()
{
unsigned long currentTime = millis();
switch (State)
{
case Idle:
StateStartTime = currentTime;
velocity = 8;
esc_signal.write(velocity);
State = RampingUp;
break;
case RampingUp:
if (currentTime - StateStartTime >= 1000)
{
StateStartTime += 1000;
velocity++;
if (velocity > 17)
{
velocity = 17;
esc_signal.write(velocity);
State = RampingDown;
}
else
{
esc_signal.write(velocity);
}
}
break;
case RampingDown:
if (currentTime - StateStartTime >= 1500)
{
StateStartTime += 1500;
velocity--;
if (velocity < 0)
{
velocity = 0;
esc_signal.write(velocity);
State = Stopped;
}
else
{
esc_signal.write(velocity);
}
}
break;
case Stopped:
delay(1000);
break;
}
}
Thank you John for your message! But now where should I implement the hall effect sensor code? In the void loop, before or after the motor code?
Excuse me for asking all these but I am a beginner with Arduino and I really need some help!
Christoforos
chrismil:
But now where should I implement the hall effect sensor code? In the void loop, before or after the motor code?
Yes. Before or after.
To make things cleaner you could have a function that does the motor control and call it from loop(). Then you could put the RPM reporting before or after the function call.
void loop()
{
MotorControl();
ReportRPM();
}
void MotorControl()
{
unsigned long currentTime = millis();
switch (State)
If you could see my hall effect sensor code I have a loop called void rpm_bike()
void rpm_bike()
{
rpmcount++
}
Do I need to keep this loop in order to get a new RPM value every second according to my code?
chrismil:
If you could see my hall effect sensor code I have a loop called void rpm_bike()
void rpm_bike()
{
rpmcount++
}
Do I need to keep this loop in order to get a new RPM value every second according to my code?
That's called a "function", not a "loop".
If you leave out that function, the two places where you set it as the interrupt service routine (ISR) for interrupt zero will have errors. The big 'if' statement in your loop() function is where you calculate the RPM's once per second. Put that in the "ReportRPM()" function.
WARNING! The millis() counter sometimes goes up by 2 instead of 1. You should change your test from:
if (millis() - lastmillis == 1000)
to if (millis() - lastmillis >= 1000)
Thank you for that! It worked 