Skateboard, RPM, measure acceleration or braking, only Hall Sensor

Hello forum, for an electro skateboard project I need some help.
I like to measure the skateboard acceleration or braking process only with a used wheel hall sensor over RPM.
I need to know how strong the acceleration/braking actual is. Or in other word, how strong is the change (delta) of the measured the RPM within a loop of of e.g 500ms?

Of cause there are other ways to do this (sensors like e.g GY-521).
The sample code I use is similar to the known “Van RPM” (Arduino Playground - Tachometer).

Any ideas how to do this?

hall sensor skateboard.txt (1.86 KB)

Your use of the servo library is totally irrelevant to this project. Servos have a means to send back their position to the MCU. A hall effect sensor works completely differently. It only tells whether a magnetic field is present or not.

So you need to build a function that will look at the sensor and time it's rises and falls to calculate RPM. Then, for your application, you want to be able to compare the current RPM against previous readings to get a acceleration/deceleration figures.

Hello Ken, thank you. The attaced code includes the servo.h for some other functions I use.
The RPM are calculated with digitalread (0). This code is working. This part is working fine.
But I need to know how can I meassure any delta of RPM changing?

// the code!
//digital read Hall Sensor on "val=digitalRead(0);".
//This part is working.

//Include Servo Library
#include <Servo.h>

//Define Pins
int servoPin = 9; //ESC control an 9
int calSpeed = 0; //Variable für Servo

//Create Servo Object
Servo juergenServo; // Servo

// Ab hier die Erfassung von des Radsensors (RPM, "rounds p. minute")
int val;
long last=0;
int stat=LOW;
int stat2;
int contar=0;

int sens=1; // Sensor/Magnet -> auf 0V,
int nPalas=5; // the number of blades of the propeller

int milisegundos=500; // the time it takes each reading

void setup()
{
//Attaches the Servo to our object
juergenServo.attach(servoPin);

Serial.begin(9600);
pinMode(13,OUTPUT);
}

void loop()
{
val=digitalRead(0); //
if(val<sens)
stat=LOW;
else
stat=HIGH;
digitalWrite(13,stat); //as iR light is invisible for us, the led on pin 13
//indicate the state of the circuit.

if(stat2!=stat){ //counts when the state change, thats from (dark to light) or
//from (light to dark), remmember that IR light is invisible for us.
contar++;
stat2=stat;

{
//Read the Distance Sensor and adjust values
int calSpeed = ((double)contar/nPalas)/2.0*60000.0/(milisegundos);
int pos = map(calSpeed, 0, 1023, 0, 180);

juergenServo.write(pos);

}

}
if(millis()-last>=milisegundos)
{
double rps=((double)contar/nPalas)/2.01000.0/milisegundos;
double rpm=((double)contar/nPalas)/2.0
60000.0/(milisegundos);
int calSpeed=((int)contar/nPalas)/2.0*60000.0/(milisegundos);
//Serial.print((contar/2.0));
Serial.print("RPS ");Serial.print(rps);
Serial.print(" RPM");Serial.print(rpm);
Serial.print(" CAL SPEED ");Serial.print(calSpeed);
Serial.print(" VAL ");Serial.println(val);
contar=0;
last=millis();

}

}

To find the change in RPM from one measurement interval to the next, store the RPM from the last interval, and subtract it from the current RPM measurement.

RPMchange = RPMnow - RPMlast;

Sorry I lost track. He's using a hall effect transistor that senses going from dark to light (remember IR is invisible!) and he's using the servo library to control it :open_mouth:

Ok, let's change the focus to solve this problem.

I need to compare RPM_last in a delay with the RPM_now.

  • Is RPM_last > than RPM_now = acceleration
  • Is RPM_last < than RPM_now = braking
  • Depending from the delta of RPM_last to RPM_now, I know strong acceleraton/braking is.

The Smoothing code (http://arduino.cc/en/Tutorial/Smoothing) could be the basis.
The array is with 10 loops for smooth the analog signal.

Is it possible to generate the "reading delay" with an array to compare the oldest (#10 value) with the latest (#1 value)?
How can I read out the oldest value from an array?

I need some example code to understand how to do this.

The Smoothing code:

const int numReadings = 10;

int readings[numReadings]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average

int inputPin = A0;

void setup()
{
// initialize serial communication with computer:
Serial.begin(9600);
// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++)
readings[thisReading] = 0;
}

void loop() {
// subtract the last reading:
total= total - readings[index];
// read from the sensor:
readings[index] = analogRead(inputPin);
// add the reading to the total:
total= total + readings[index];
// advance to the next position in the array:
index = index + 1;

// if we're at the end of the array...
if (index >= numReadings)
// ...wrap around to the beginning:
index = 0;

// calculate the average:
average = total / numReadings;
// send it to the computer as ASCII digits
Serial.println(average);
delay(1); // delay in between reads for stability
}

//J

in the code above, you already have 10 readings in an array.. the farthest reading from the reading[now] would always be reading[now]+ 1 unless it's reading[10] then it will be -9 but it has to be read before it is deleted at the first of the loop