RPM speed measuring, and light and sound effect

Hello fellow professionals

I am here to ask a little question which I haven’t been able to resolve the problem in my project. First let me introduce you to my project, the aim of the project is to measure the speed of a wheel using a hall effect sensor and then according to the speed measured the RGB LED will change colours like less than 15mph red, above 30mph green and so on and after that when the speed reaches above 30mph there should be a sound of people cheering.

Anyways I got all working, the speed is measure, the lighting effect is doing its job and the sound is working. But, the sound only works in the beginning which means it only sound when the speed reached above 30mph in the first round after that when I stop the wheel and start it again it doesn’t sound at all other wise I have t start the Arduino UNO.

In my case I have used two Arduinos as in master and slave, the slave is holding the sound system and the master is working with the other 2. Here I will post my code and if you have anything in mind which might help me O would appreciate to share it with me.

I think the problem that I have to work is with the second Arduino which is doing the work for the sound system, to restart when the speed stops and starts again any way check my code and see if there is anything I have to add thank you.

Master Code

#include <FastLED.h>
#define hallPin  2//pin connected to read switch
#define LED_PIN 7
#define NUM_LEDS 256
#define Out_pin 8

CRGB leds[NUM_LEDS];


//storage variables
float radius = 10;// tire radius (in inches)- CHANGE THIS FOR YOUR OWN BIKE
int ledpin = 3;
int hallVal;
long timer = 0;// time between one full rotation (in ms)
float mph = 0.00;
float circumference;
char value  = 0;


int maxhallCounter = 100;//min time (in ms) of one rotation (for debouncing)
int hallCounter;


void setup(){

  hallCounter = maxhallCounter;
  circumference = 2*3.14*radius;
  pinMode(LED_PIN,OUTPUT);
  pinMode(ledpin,OUTPUT);
  pinMode(hallPin, INPUT);
  pinMode(Out_pin, OUTPUT);
 
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(32);
  
  // TIMER SETUP- the timer interrupt allows preceise timed measurements of the reed switch
  //for mor info about configuration of arduino timers see http://arduino.cc/playground/Code/Timer1
  cli();//stop interrupts

  //set timer1 interrupt at 1kHz
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;
  // set timer count for 1khz increments
  OCR1A = 1999;// = (1/1000) / ((1/(16*10^6))*8) - 1
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS11 bit for 8 prescaler
  TCCR1B |= (1 << CS11);   
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  
  sei();//allow interrupts
  //END TIMER SETUP
  
  Serial.begin(9600);
 }


ISR(TIMER1_COMPA_vect) {//Interrupt at freq of 1kHz to measure reed switch
  hallVal = digitalRead(hallPin);//get val of hall sensor
  if (hallVal==LOW){//if reed switch is closed
    if (hallCounter == 0){//min time between pulses has passed
      mph = (53.8*float(circumference))/float(timer);//calculate miles per hour
      timer = 0;//reset timer
      hallCounter = maxhallCounter;//reset hallCounter
    }
    else{
      if (hallCounter > 0){//don't let reedCounter go negative
        hallCounter -= 1;//decrement reedCounter
      }
    }
  }
  else{//if reed switch is open
    if (hallCounter > 0){//don't let reedCounter go negative
      hallCounter -= 1;//decrement reedCounter
    }
  }
  if (timer > 2000){
    mph = 0;//if no new pulses from reed switch- tire is still, set mph to 0
  }
  else{
    timer += 1;//increment timer
  } 
}


void loop(){
  if(hallVal == LOW){
    digitalWrite(ledpin, HIGH);
  }
  else{
    digitalWrite(ledpin, LOW);
  }
  //print mph once a second
  Serial.println(mph);
  if (mph == 0) {
    for(int i=0; i<=255; i++){
      leds[i] = CRGB(0,0,0);
    }
    FastLED.show();
  }
  else if (mph <= 15 && mph>0) {
    for(int i=0; i<=255; i++){
      leds[i] = CRGB(255,0,0);
    }
    FastLED.show();
  }
  else if (mph <= 30 && mph>15) {
    for(int i=0; i<=255; i++){
      leds[i] = CRGB(255,105,0);
    }
    FastLED.show();
  }
  else if (mph > 30) {
    for(int i=0; i<=255; i++){
      leds[i] = CRGB(0,255,0);
      
    }
    FastLED.show();
    digitalWrite(Out_pin, HIGH);
  }
  else{
    digitalWrite(Out_pin, LOW);
  }
}

Slave Code

#include <SD.h>
#define SD_ChipSelectPin 4
#include <TMRpcm.h>
#include <SPI.h>

const int Speaker = 9;
const int SPEEDIN = 8;


int SPEEDINcounter = 0;
int SPEEDINVal = 0;
int LastSPEEDINVal = 0;
TMRpcm tmrpcm;
char mychar;


void setup() {
  // put your setup code here, to run once:


   pinMode(Speaker, OUTPUT);
   pinMode(SPEEDIN, INPUT);

  Serial.begin(9600);
  
tmrpcm.speakerPin = 9;
if(!SD.begin(SD_ChipSelectPin)){
  Serial.println("SD fail");
  return;
} 
tmrpcm.setVolume(5);
}


void loop() {
  // put your main code here, to run repeatedly:
//  unsigned long currentMillis = millis();
   SPEEDINVal = digitalRead(SPEEDIN);
//   if(currentMillis - previousMillis > interval){
//    previousMillis = currentMillis;
    if(SPEEDINVal != LastSPEEDINVal){
   if(SPEEDINVal == HIGH){
    SPEEDINcounter++;
       digitalWrite(Speaker, HIGH);
       tmrpcm.play("23.wav");
       delay(3000);
//       previousMillis = millis();
   }
    
   else{
        digitalWrite(Speaker, LOW);
        delay(1000);
   }  
  }
    LastSPEEDINVal = SPEEDINVal;
}
#define Out_pin 8

That is a useless name.

  pinMode(Out_pin, OUTPUT);

So, we know that the pin is an output pin, but not why it is being used as an output, or what is connected to it.

long timer = 0;// time between one full rotation (in ms)

This variable holds a time, not a timer. Why doesn’t the name reflect that? Do you really expect to hold negative times?

int hallVal;

Variables shared between interrupt service routines and non-interrupt-service-routines, like loop(), MUST be declared volatile.

  if (mph == 0) {

Exact comparison of floating point values is NOT a good idea.

  else if (mph <= 15 && mph>0) {

Do you think that way? Personally, I think that a value is in a range if it is greater than the low end and less than the high end, in that order.

Hello Paul

I mean I didn't get what you are saying at some points but to clarify what Pin_out on digital pin 8 of the master slave is connected is to the pin 8 of the slave Arduino, which means the connecrion between the 2 Arduinos is a digital pin.

Can you explain it to me what the other things are thanks for the reply Paul I really appreciate it.

but to clarify what Pin_out on digital pin 8 of the master slave is connected is to the pin 8 of the slave Arduino

The "master slave"? The device is a master or it is a slave. Certainly a better name for the slave trigger pin could be used. Like maybe slaveTriggerPin.

The rest of the issues just indicate sloppy thinking.

You have a Serial.begin() statement, but only one Serial.println() call, which sends some unidentified value to the Serial Monitor application. Add more Serial.print() statements, to learn that your program is doing.

Pay attention to the series of if/else if/else statements. Identify the condition(s) that cause the else statement's body to be executed. If you are expecting the pin to go LOW again, after you set it HIGH, you need to think about whether that will actually happen, and, if so, under what circumstances.

Hello Guys

Is there any advice or recommendation to my question. I mean the system is working and the sound is working with the speed of the wheel, what I couldn't figure out is why isn't the sound resetting again after it does the sound ones.

Or is there a way that I can make the slave Arduino restart again after doing the sound ones, because what is happening here is that if I restart the Arduino manually then it works perfectly.

Any help would be appreciated thanks a lot.

I mean the system is working

And that's a problem?

Post your current code, that has addressed the issues pointed out so far.

Hello Paul

Okay I will post both my codes for the master Arduino which controls the speed measurement and the lighting effect on RGB LED, and the Slave Arduino code that controls the sound system.

Master Arduino code

#include <FastLED.h>
#define hallPin  2//pin connected to read switch or hall effect sensor
#define LED_PIN 7
#define NUM_LEDS 256
#define Strigger 8

CRGB leds[NUM_LEDS];


//storage variables
float radius = 10;// tire radius (in inches)- CHANGE THIS FOR YOUR OWN BIKE
int ledpin = 3;
int hallVal;
long timer = 0;// time between one full rotation (in ms)
float mph = 0.00;
float circumference;
char value  = 0;


int maxhallCounter = 100;//min time (in ms) of one rotation (for debouncing)
int hallCounter;


void setup(){

  hallCounter = maxhallCounter;
  circumference = 2*3.14*radius;
  pinMode(LED_PIN,OUTPUT);
  pinMode(ledpin,OUTPUT);
  pinMode(hallPin, INPUT);
  pinMode(Strigger, OUTPUT);
 
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(32);
  
  // TIMER SETUP- the timer interrupt allows preceise timed measurements of the reed switch
  //for mor info about configuration of arduino timers see http://arduino.cc/playground/Code/Timer1
  cli();//stop interrupts

  //set timer1 interrupt at 1kHz
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;
  // set timer count for 1khz increments
  OCR1A = 1999;// = (1/1000) / ((1/(16*10^6))*8) - 1
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS11 bit for 8 prescaler
  TCCR1B |= (1 << CS11);   
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  
  sei();//allow interrupts
  //END TIMER SETUP
  
  Serial.begin(9600);
}


ISR(TIMER1_COMPA_vect) {//Interrupt at freq of 1kHz to measure reed switch
  hallVal = digitalRead(hallPin);//get val of hall sensor
  if (hallVal==LOW){//if reed switch is closed
    if (hallCounter == 0){//min time between pulses has passed
      mph = (53.8*float(circumference))/float(timer);//calculate miles per hour
      timer = 0;//reset timer
      hallCounter = maxhallCounter;//reset hallCounter
    }
    else{
      if (hallCounter > 0){//don't let reedCounter go negative
        hallCounter -= 1;//decrement reedCounter
      }
    }
  }
  else{//if reed switch is open
    if (hallCounter > 0){//don't let reedCounter go negative
      hallCounter -= 1;//decrement reedCounter
    }
  }
  if (timer > 2000){
    mph = 0;//if no new pulses from reed switch- tire is still, set mph to 0
  }
  else{
    timer += 1;//increment timer
  } 
}


void loop(){
  if(hallVal == LOW){
    digitalWrite(ledpin, HIGH);
  }
  else{
    digitalWrite(ledpin, LOW);
  }
  //print mph once a second
  Serial.println(mph);
  if (mph == 0) {
    for(int i=0; i<=255; i++){
      leds[i] = CRGB(0,0,0);
    }
    FastLED.show();
  }
  else if (mph>0 && mph<=15) {
    for(int i=0; i<=255; i++){
      leds[i] = CRGB(255,0,0);
    }
    FastLED.show();
  }
  else if (mph >15 && mph<=30) {
    for(int i=0; i<=255; i++){
      leds[i] = CRGB(255,105,0);
    }
    FastLED.show();
  }
  else if (mph > 30) {
    for(int i=0; i<=255; i++){
      leds[i] = CRGB(0,255,0);
      
    }
    FastLED.show();
    digitalWrite(Strigger, HIGH);
  }
  else{
    digitalWrite(Strigger, LOW);
  }
}

And here is the Slave Arduino code

#include <SD.h>
#define SD_ChipSelectPin 4
#include <TMRpcm.h>
#include <SPI.h>

#define SpeakerPin 9   //Speaker out put pin
#define SPEEDINPin 8  //the input pin from the Master Arduino

int Speaker = LOW;
int SPEEDINcounter = 0;
int SPEEDINVal = 0;
int LastSPEEDINVal = 0;
TMRpcm tmrpcm;
char mychar;


void setup() {
  // put your setup code here, to run once:


   pinMode(SpeakerPin, OUTPUT);
   pinMode(SPEEDINPin, INPUT);
  Serial.begin(9600);
  
tmrpcm.speakerPin = 9;
if(!SD.begin(SD_ChipSelectPin)){
  Serial.println("SD fail");
  return;
} 
tmrpcm.setVolume(5);
}


void loop() {
  // put your main code here, to run repeatedly:
   SPEEDINVal = digitalRead(SPEEDINPin);

    if(SPEEDINVal != LastSPEEDINVal){
   if(SPEEDINVal == HIGH){
    SPEEDINcounter++;
       digitalWrite(Speaker, HIGH);
       tmrpcm.play("23.wav");
       delay(3000);
   }
    
   else{
        digitalWrite(Speaker, LOW);
        delay(1000);
   }  
  }
    LastSPEEDINVal = SPEEDINVal;
}

I think I have to make changes on the Slave Arduino code as the system works as I wanted it when I restart the Master Arduino or the Slave Arduino. Thanks for you help Paul

Hello Paul

After trying a lot of modification I have finally done it. It works perfectly now with out restarting the board manually, thanks for your help. I just did a little modifications on the Master Arduino code, it is not even a modification thanks a lot though.

:slight_smile: :slight_smile: ;D

[quote author=PaulS link=msg=4138084 date=1555341389]
code]  if (mph == 0) {

Exact comparison of floating point values is NOT a good idea.

[/quote]
You can rely on comparison for small integer values stored in a float though, these are encoded
exactly.