Friday, 2 March 2018

Arduino based RPM meter (3D printed case)

IIn this project we will use the basics of an IR senosr to measure the speed of rotation of a shaft. The idea is to dectect or not the infrared light. Having some sort of reflecting material on the rotating shaft we cold detect a peak of the sensed light and measure the time between those peaks. The measured time is the time that the shaft take to make one full rotation.



Material

This project is simple. The total price is under 10 dollars. If you don't have a 3D printer you should create any kind of small case and fit everything in place. So lets see what we need.


Find the full part list and best prices here:



I  IR LED and senosr: LINK
   Arduino NANO: LINK
   LM324 amplifier: LINK
   Push button: LINK
   Slide button: LINK
   OLED screen: LINK
   30AWG wire: LINK
   Cheap lser diode: LINK
   9V battery connector: LINK
   9V battery: LINK
   drilled PCB: LINK

 
To emit infrared light we need a IR LED and to detect it a IR snesible transistor. Usually you could find those as a one unique module. To amplify the signal I've used the LM324 amplifier. You will also need a 100 ohm resistor and a 4.7k ohm one. To supply the system we will need a basic 9V battery na connector, an Arduino NANO and an OLED screen. The case is 3D printed and you could download the STL files from the next link below:
Download the STL files for the 3D printed case here:





Theory

Ok, so how this RPM meter works. Well, we have a IR LED that will emit light. The light will reflect on the surface of the moving part. The reflected light will then touch the sensitive base of the IR sensor.
IR sensor This IR sensor works exactly like a commune BJT transistor but instead of controlling the current from the collector to the emitter by applying a small current to the base we control the current applying infrared light. The base of this transistor is exposed to the light and when the infrared wave touches the base, the circuit is open and no current flow through the transistor. But when no light is exposed current could flow. So basically, this is a switch activated by light. So, the detection circuit is something like this.
IR sensor

The output will be the emitter of the transistor. We add a pulldown resistor to the output. In this way when the circuit is open the output will be ground and when the circuit is closed the output is a high value, in this case 5 volts because that’s the basic voltage of the Arduino. Actually, the output is a voltage divider between the resistance of the transistor and the pulldown. So, the pulldown should have a high value, in this case 4.7 kilo ohm, so when the transistor is conducting, the voltage drop between the collector and emitter should be very small and all the voltage should drop on the pulldown resistor. Next, we should add a small resistor, around 100 ohms to the positive pin of the infrared LED in order to limit the current and not burn it.
IR sensor


So just like that we've detected IIR light. So now if I put something white in front of the IR LED and sensor, light will reflect, the circuit will be open and the output will be 0. When I remove the white object, light will no more touch the sensor and once again the output will be 5 volts. Just like that we could obtain a square wave if a spinning object with a white stripe is placed in front of the sensor.


The circuit

If we analyze with the oscilloscope the output signal while the shaft is spinning we can see some errors. The signal is not a perfect square wave and has a sinusoidal shape. In order to improve the signal and obtain a perfect square wave we should use an operational amplifier. I’ve use the LM324 OP amp. Connect the output from the sensor to the positive input of the OP amp and the negative input to a voltage divider made with a potentiometer. In this way, we could regulate the sensing distance of the sensor depending on the intensity of the light.
arduino RPM tachometer meter circuit

Ok, as you can see in the schematic above, we have a 9V input from the battery. The slide switch will turn on and off the entire system. Connect the output from the switch to the Vin pin of the arduino. Also connect ground. Next you should supply 5V and connect GND to the OLED screen and the LM324 amplifier. Also connect 5V to the push button. Add a 1k pulldown resistor to the push button. In this way when the button is pressed the D9 input will be high and when the button is released the input will be low. We will use this button to put the arduino in low power mode when not measuring.

Add a 100 ohm between the positive pin of the IR LED and 5V. Also connect a 4.7k ohm between the emmiter off the phototransistor and ground. Now connect the emmiter to the positive input of the LM324 OPAMP. Create a voltage divider between 5V and groudn with a potentiometer and connect the middle pin to the negative input of the LM324 amplifier. Using this potentiometer we could adjust the detection distance/intensity. Finally connect the amplifier output to digital pin 13 of the arduino. The circuit is ready.

Using this black and white paper I check the functionality. The black color should absorb all the light so no light will reflect into the transistor base so the circuit is still open. When white color is placed in front of the LED, the light reflects and hits the transistor base closing the circuit. So, imagine a white stripe on the exterior of the motor. Each time the stripe pass in front of the sensor we will have 0 volts at the output and 5 volts in the rest of time.
Let's build this thing.



Building it

Ok, I've used a 3D printed case. You have the download link with the STL belwo. Download it and print the parts using 2 perimeters adn 20% infill. I've used my Anet A8 printer and a 0.3mm nozzle. Use support material for the parts with the (use_support) file name.
STL files 3d printed tachometer

Download the STL files for the 3D printed case here:

Libraries

Now that we have the case we have to program the Arduino. For that you first need to download the next two libraries for the OLED screen. Download them from the next link or install them using the library manager in the Arduino IDE.


Download the Adafruit_GFX.h library here:
Download the Adafruit_SSD1306.h library here:



Or you could just install the libraries using the Arduino IDE. For that go to Sketch, include library, library managesr and search for your desired library. Once found, select the version and click install just as in the picture below.
install Arduino library





The code

The code is simple. When the push button is pressed, the meter is activated. We know that the LM324 will give us a low pulse each time the white stripe pases in front of the sensor representing one full rotation. We have to start a counter when we detect the first positive edge representing the final of the white stripe and count the time till we detect another positive pulse, representing the start of the white stripe again. We make the difference of the measure counters and we obtain the time for one rotation in microseconds. We divide one minute (60.000.000us) by that value and we obtain the rotations per minute. We print the value to the OLED screen uisng the text function.

When the push button is released the Arduino will be in low power mode. You could turn it off with the slide switch as well.
Download the full code here:
First we include all the libraries. Remember to download the liblaries above. Now that we have the libraries we define the vareiables and start the Setup loop. In the Setup loop we start the OLED screen, define the pins as inputs and print the electronoobs LOGO.

Be careful, the i2c adress in my case is 0x3C in the display.begin function in the Setup void. If you don't knwo the i2c adress of your module use the next code to find it. Download the sketch. Upload it to your arduino. Connect the SCD and SDA pins and open the Arduino monitor. Select 9600 baudrate. The i2c adress will be printed on the monitor.
Download the i2c scanner code here:

The Full Code:

void loop() {


if(digitalRead(pushbutton))
{

  //Arduino low power enabled
  if(disabled==0)
  {
    sleep_disable();
    disabled = 1;
  }
///////////////////////one rotation measure///////////////////
   if (digitalRead(in) == 1 && previous == 0)
  {
    previous = 1;
    duration = elapsed - elapsed_prev;
    elapsed_prev  = micros();    
  }
  if (digitalRead(in) == 1 && previous == 1)
  {
    previous = 1;       
  }
  if (digitalRead(in) == 0 && previous == 1)
  {
    previous = 0;     
  }
  if (digitalRead(in) == 0 && previous == 0)
  {
    previous = 0;
    elapsed = micros();    
  }
//////////////////////////////////////////////////////////////
   
   
   
   rpm = 60000000/duration;


//We add a small error in the rpm value (in this case +-2)
if ( (rpm_a-2) < rpm  &&  rpm < (rpm_a+2))
{
  rpm_a = rpm;
  counter = counter +1;
  if (counter == 50)
  {
     // text display tests
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    display.println("ELECTRONOOBS RPMmeter");  
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(0,19);
    display.println("RPM:");
    display.setCursor(80,19);
    display.println(rpm);  
    display.display();
    counter = 0;
  }
}

if (!( (rpm_a-2) < rpm  &&  rpm < (rpm_a+2)))
{
  rpm_a=rpm;
}
}//end if pushbutton=1



else{
  //Variables
  display.display();
  display.clearDisplay();
  delay(10);
  duration = 0;
  rpm = 0;
  rpm_a = 0;
  counter = 0;
  present = 0;
  previous = 0;
  
  //Arduino low power enabled
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  sleep_enable();
  disabled = 0;
}//end pushbutton =0
}//end of void loop








void scrollENlogo(void) {
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(7,0);
  display.clearDisplay();
  display.println("ELECTRONOOBS");
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,10);
  display.println("WELCOME");
  display.display();
  delay(1);
 
  display.startscrolldiagright(0x00, 0x07);
  delay(5000);
  display.stopscroll();
  }

 


No comments:

Post a Comment