WS2812b fastled

First problem is you must measure the distance from the center of the wheel hub to the pavement the tire is resting on. From that compute the circumference. The tire is flattened by the weight of the vehicle.
Adjust your calculation to the working circumference, not the tire size.

It's possible, but the size would vary a little...

Of course it will! That is why your mileage is better with a fully inflated tire that it is with a 1/2 flat tire.

You are basing speed on total distance traveled (pulse_distance * dist_pulse_count), not on the rate of pulses. Try it this way:

const float pulse_distance = 1.784;  // in meters

volatile unsigned long dist_pulse_count;
volatile unsigned long interval = 0;
volatile unsigned long lastPulseTime;

unsigned speed;

void setup() {
  Serial.begin(115200);
  attachInterrupt(0, isr, RISING);
}

void loop() {
  unsigned long local_dist_pulse_count;
  unsigned long local_interval;
  unsigned long localLastPulseTime;

  // Read voltile variable only with interrupts disbled
  noInterrupts();
  local_dist_pulse_count = dist_pulse_count;
  local_interval = interval;
  localLastPulseTime = lastPulseTime;
  interrupts();

  float odometer = pulse_distance * local_dist_pulse_count;
  Serial.println(odometer);  //en km

  if (micros() - localLastPulseTime > 1000000) {
    speed = 0;
  } else {
    unsigned pps = 1000000ul / local_interval;  // Pulses Per Second
    speed = (pps * pulse_distance) * (3600 / 1000);  // Kilometers per Hour
  }

  Serial.println(speed);
}

void isr() {
  dist_pulse_count++;
  unsigned long now = micros();
  interval = now - lastPulseTime;
  lastPulseTime = now;
}
1 Like

Never mind the below, still working on getting sand out of my ear, sry.

OIC Your two topics on the same or similar subject have been merged.

So you may have skipped over the part that warns about accessing a multi byte variable that may be changed by an interrupt service routine.

volatile is only half the battle. You shoukd safely make your own copy of any variables used in the ISR.

Here's a recent example:

  noInterrupts() ;
  uint32_t counterCopy = counter ;
  interrupts() ;

Interrupts are disabled, then a copy of the volatile variable counter from the ISR is made, counterCopy.

Then use the countrrCopy wherever you want the value of counter.

Adjust for your situation.

a7

Your two topics on the same or similar subject have been merged.

I Notice you also have posts in the Spanish section.
Please pick a single language and stick to it as multiple posts about the same topic even in different language forums may be DELETED.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.

thanks for your reply.

I can't stop the interruptions.

In the same code, the engine rpm and speed are acquired.

They are two totally different things... One is how to obtain an animation with some leds and another is how to obtain the speed of a vehicle...

I have tried it. Works! but the speed activates from 5km/h to 5km/h. What happen??

I guess I figured the pulses would be more frequent. I set a lower limit of 1 pulse per second but I see that 1 pps is 6.4224 KPH. Let's change the lower limit to 0.1 PPS (0.64224 KPH).

  if (micros() - localLastPulseTime > 10000000ul) {
    speed = 0;
  } else {
    float pps = 1000000.0 / local_interval;  // Pulses Per Second
    speed = (pps * pulse_distance) * (3600 / 1000);  // Kilometers per Hour
  }

Hi and thanks for your answer.

It behaves the same. The speed is updated from 5 to 5 km/h. What can be happening??

One mistake I made is using "(3600 / 1000)". Since both are integers the answer is '3' add not '3.6' so the result is about 20% low. Change that to "(3600.0 / 1000.0)" and test again.

Post the latest code here and we can check for errors.

I think that now it goes up by 6 by 6... The truth is that the test I'm passing a magnet to the hall sensor

const float pulse_distance = 1.784;  // in meters

volatile unsigned long dist_pulse_count;
volatile unsigned long interval = 0;
volatile unsigned long lastPulseTime;

unsigned speed;


unsigned long previousMillis = 0;  // will store last time LED was updated

// constants won't change:
const long intervalmillis = 100;  //

void setup() {
  Serial.begin(115200);
  attachInterrupt(2, isr, RISING);
}

void loop() {
  unsigned long local_dist_pulse_count;
  unsigned long local_interval;
  unsigned long localLastPulseTime;
  

  // Read voltile variable only with interrupts disbled
  detachInterrupt(2);
  local_dist_pulse_count = dist_pulse_count;
  local_interval = interval;
  localLastPulseTime = lastPulseTime;
  attachInterrupt(2, isr, RISING);

  float odometer = pulse_distance * local_dist_pulse_count;
  //Serial.println(odometer);  //en km

  if (micros() - localLastPulseTime > 10000000) {
    speed = 0;
  } else {
    unsigned pps = 1000000ul / local_interval;  // Pulses Per Second
    speed = (pps * pulse_distance) * (3600.0 / 1000.0);  // Kilometers per Hour
  }
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= intervalmillis) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

  Serial.print(speed);
  
  Serial.println("   km/h");
  }
    
}

void isr() {
  dist_pulse_count++;
  unsigned long now = micros();
  interval = now - lastPulseTime;
  lastPulseTime = now;
}

You missed where I changed that to:
float pps = 1000000.0 / local_interval; // Pulses Per Second
This is going to make any value under 1pps (6.4224 KPH) equal to zero.

You also missed where I explicitly made the value unsigned long when changing from 1 million to 10 million:
if (micros() - localLastPulseTime > 10000000ul) {
(That should not cause a difference but it is good practice.)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.