LM393 Speed sensor with Arduino using L9110 motor driver, circuit and Code explained
Table of Contents
LM393 Speed Sensor with Arduino:
LM393 Speed Sensor and L9110 Motor Driver with Arduino- I have been using DC Motors and Stepper Motors in different intermediate and advanced level projects. Seriously it’s fun to control the speed of the dc motors and you have so many options to do it. You can use L298N Motor Driver, or you can simply use a MOSFET, etc. I also have a very detailed tutorial on the DC Motor Constant Speed Controller, I highly recommend read this article.
In this tutorial, we are going to use LM393 IR speed sensor to count the pulses or in simple words the revolutions of the DC motor using L9110 motor Driver. The L9110 motor driver and potentiometer will help us to regulate the speed of the motor. We are going to use a speed sensor which is nothing but a simple IR Sensor, which will gives us rotations per second of the dc motor, each time the IR beam is blocked it will increment the counter. This is usually used for the DC motors; because DC motors depending on how much current you are giving them they will go faster or slower, but it’s not an exact precise motor like a stepper motor. A stepper motor can be very precise because of its number of steps, so you can know exactly how much you are making your motor move; while in DC motors, you know they tend to drift a little bit. So by knowing the speed of the motor you can in your code regulate the speed based on the number of rotation that it’s doing. So, you know approximately how much it has moved.
Amazon Links:
Arduino Nano USB-C Type (Recommended)
LM393 IR Speed Sensor for Arduino
*Disclosure: These are affiliate links. As an Amazon Associate I earn from qualifying purchases.
L9110 Motor Driver:
L9110 Motor Driver as you can see in the image given below is basically a dual motors driver, which can be used to control a stepper motor, but it can also be used to control two DC motors at the same time.
Module supply voltage :2.5-12V
Suitable motor Range: between the motor operating voltage 2.5v-12V, the maximum operating current 0.8A, voltage and current smart car currently available in the market are within this range
Can drive two DC motors , or a 4-wire 2 -phase stepper motor.
PCB size : 2.8cm * 2.1cm ultra- small size, suitable for assembly
A fixed mounting hole diameter : 3mm
6P black bent pin description
External 2.5V-12V voltage VCC
External GND GND
IA1 external microcontroller IO port
IB1 external microcontroller IO port
IA2 external microcontroller IO port
IB2 external microcontroller IO port
4P Green Terminal Description
OA1 OB1 DC 2 -pin connection , without direction
OA2 OB2 DC 2 -pin connection , without direction
Switched VCC, GND module power indicator light
IA1 input high , IA1 input low , [ OA1 OB1 ] motor is transferred ;
IA1 input low , IA1 input high , [ OA1 OB1 ] motor reversal ;
IA2 input high , IA2 input low , [ OA2 OB2 ] motor is transferred ;
IA2 input low , IA2 input high , [ OA2 OB2 ] motor reversal ;
LM393 Speed Sensor
Module Features:
Use imported groove coupler sensor
Groove Width: 5mm
Output state indicator lights
Obscured output high; unobstructed output low
The comparator output, the signal is clean, the waveform, driving ability, more than 15mA
Operating Voltage: 3.3V-5V
The output in the form: Digital switching outputs (0 and 1)
A fixed bolt hole for easy installation
Small plates PCB Dimensions: 3.2 x 1.4cm / 1.25 * 0.55″
Using a wide voltage LM393 comparator
Module Using The Instructions:
Module slot unobstructed, receiver tube conduction module DO output low, shelter, DO output high
Module DO connected to the relay, composed of the limit switch functions can also be connected to the active buzzer module, composed of the alarm
LM393 Speed Sensor with Arduino, Circuit diagram:
We have a potentiometer that is connected to the analog pin A1. So we will map that value to set the speed of the motor and using the L9110 Motor Driver we will be able to control the speed of the motor using the potentiometer. TheLM393 Speed Sensor here only needs one pin and that is connected to pin 2 on the Arduino UNO and pin 2 is linked to interrupts 0 in the code and that is why we are using pin 2 because we are going to use an interrupt to actually counts the pulses which are generated each time the IR beam is blocked, so this way you can increment the counter. So basically every time this pin goes high it means that the beam has been open or blocked. So basically it will increase a counter and we are going to use another interrupts in a library called TimerOne which we are going to use to start a timer for one second and once that timer is elapsed then it’s going to call another interrupt and then display on the serial monitor the value of the counter. Now, the disk, the encoder disk, that’s spinning on the motor, now considers that it consists of twenty holes in them in it. So basically one full rotation will give us twenty pulses on the sensor. So once the timer elapsed and we go to the serial monitor to display the information we are going to take the value of the counter and divide it by twenty because we have 20 holes in our disk but if you are using your own disk or whatever just you are going to divide the value by the number of holes that are in your encoder disk to get the number of rotation per second. Now you could improve on that, you could use a little LCD display, you can make many calculations; you know if you want to set specific speed of your motor? you can take that value and instead of using potentiometer you could code that inside to regulate the speed of the DC motor. We are actually powering the L9110 Motor Driver using a little power supply five volt and 2amps, because DC motors tend to draw more current than the Arduino UNO could provide directly and the potentiometer is just connected to voltage and ground and the analog to analog one.
I applied power to the L9110 Motor Driver first and it is receiving 5 volts and I am using a little power supply that has 5 volt 2amps. Now I connected the right leg of the potentiometer with the 5V supply of the Arduino, the middle leg with the A1 pin of the Arduino, and the left leg with the ground. Then, to connect the LM393 speed sensor connect the vcc of the LM393 speed sensor with the 5V of the Arduino, connect the ground pin of the LM393 speed sensor with the ground of the Arduino, and connect the D0 pin of the sensor with digital pin2 of the Arduino.
Now will connect the L9110 Motor Driver with the Arduino connect the B-1A pin of the motor driver with the digital pin of the Arduino and connect the B-1B pin of the motor driver with the digital pin 6 of the Arduino. Connect the VCC and ground of the L9110 Motor Driver with the power jack. Now connect the terminals of motor with the Motor B terminals of the L9110 Motor drive.
LM393 Speed Sensor with Arduino Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#include "TimerOne.h" unsigned int counter=0; int b1a = 6; // L9110 B-1A int b1b = 9; // L9110 B-1B void docount() // counts from the speed sensor { counter++; // increase +1 the counter value } void timerIsr() { Timer1.detachInterrupt(); //stop the timer Serial.print("Motor Speed: "); int rotation = (counter / 20); // divide by number of holes in Disc Serial.print(rotation,DEC); Serial.println(" Rotation per seconds"); counter=0; // reset counter to zero Timer1.attachInterrupt( timerIsr ); //enable the timer } void setup() { Serial.begin(9600); pinMode(b1a, OUTPUT); pinMode(b1b, OUTPUT); Timer1.initialize(1000000); // set timer for 1sec attachInterrupt(0, docount, RISING); // increase counter when speed sensor pin goes High Timer1.attachInterrupt( timerIsr ); // enable the timer } void loop() { int potvalue = analogRead(1); // Potentiometer connected to Pin A1 int motorspeed = map(potvalue, 0, 680, 255, 0); analogWrite(b1a, motorspeed); // set speed of motor (0-255) digitalWrite(b1b, 1); // set rotation of motor to Clockwise } |
We are going ahead to compile this code and then upload it to the Arduino UNO or Arduino Nano or Arduino Mega. But, before the working, I am going to explain the code.
LM393 Speed Sensor with Arduino, Code Explanation:
We are going to start at the top basically we are including the TimerOne library as you can see here:
1 |
#include <TimerOne.h> |
So, basically after downloading the TimerOne Zip folder you can right-click on the TimerOne Library to extract it, then open the folder and copy the TimerOne folder and then go to documents>Arduino>Libraries and paste is. Or we can insert the library through the following steps:
Go to the sketch then click on the include library and then in the include library click on add zip library.
After that we will open the folder where the timer library is saved and click on open.
Now the library is added to the IDE.
Now to add it in the code we will perform the following steps:
And then we are declaring a variable called counter and setting it to 0.
1 |
unsigned int counter=0; |
This will hold the pulses of the LM393 IR speed sensor and then we are declaring the pins which will be connected to the L9110 Motor Driver pins are connected to pin 6 and pin 9 which will be b1a and b1b respectively.
1 2 3 |
int b1a =6;// L9110 B-1A int b1b =9;// L9110 B-1B |
Here are the two interrupts that we are going to use, one is used for counting the speed sensor and the other one is done when the timer has elapsed to display the information on the serial monitor. So in the void setup function we are doing the Serial.begin() to enable the serial monitor and we set the pin mode b1a and b1b as outputs for the controlling the speed of the motor on the L9110 Dual Motor Driver.
1 2 3 4 5 |
Serial.begin(9600); pinMode(b1a,OUTPUT); pinMode(b1b,OUTPUT); |
We are declaring the timer, timer1.initialize() with a value of 1 million, basically, so we are setting the timer for 1 second, so that sets the timer1 for 1 second interval.
1 |
Timer1.initialize(1000000);// set timer for 1sec |
After that we are attaching the interrupts, attachinterrupt 0 which correspond to pin 2 on the Arduino board and we are saying when the interrupt0 gets a rising signal meaning the pin on the sensor goes to high then you are going to do the interrupts called docount .
1 |
attachInterrupt(0, docount,RISING); |
As we can see in the docount function:
1 2 3 |
voiddocount()// counts from the speed sensor { counter++;// increase +1 the counter value} |
So, when this function gets called it increases the counter variable meaning increasing it by 1. So, every time the sensor gets blocked and by the encoded disk when it hits a hole then it goes to high does the interrupt and we are increasing the counter.
Now again go to the void setup we are attaching an interrupt to the timer. So one second, when the timer elapsed we are attaching the interrupts called timerIsr and that’s enabling the timer.
1 |
Timer1.attachInterrupt( timerIsr );// enable the timer |
So, we go to the function timerIsr and the first thing we do that we detach the interrupts. So basically stopping the timer:
1 |
Timer1.detachInterrupt();//stop the timer |
Then we will serial printing motor speed and we are setting variable called rotation equal to counter divided by 20. We are dividing by 20 because like I said the little encoded disk is that we are using has 20 holes in it. So we want to know the rotation per second so we’re dividing the total value of counter up to that one second by 20 and I will say we will printing the rotation value in decimal and rotation per second just to put some text on the serial monitor.
1 2 3 4 5 |
Serial.print("Motor Speed: "); int rotation =(counter /20);// divide by number of holes in Disc Serial.print(rotation,DEC); Serial.println(" Rotation per seconds"); |
Once that is done we are resetting the counter to zero to start over again and we are reattaching the interrupt so we are renaming the timer for another second.
1 2 3 |
counter=0;// reset counter to zero Timer1.attachInterrupt( timerIsr );//enable the timer |
So it keeps doing that and when after that we go to the main loop basically what it does it takes the pot value variable and puts the analog read 1 a1 because that’s where our potentiometer is connected and puts that value in that variable
1 |
int potvalue =analogRead(1);// Potentiometer connected to Pin A1 |
Then we do another variable motor speeds is equal to mapping so we are making mapping the pot value from 0 to 680 to 255 to 0. So 0 will be 255 and 680would be 0.
1 |
int motorspeed =map(potvalue,0,680,255,0); |
It is going to make the calculation in between so that will set the speed of a motor as we turn the potentiometer and to move the motor. We do an analogWrite of the pin b1a with the value motor speed so that will set the speed and we do a digitalWrite of the b1b to 1 and it will set the rotation of the motor to clockwise and if you put it to 0 then it goes the other way.
1 2 3 |
analogWrite(b1a, motorspeed);// set speed of motor (0-255) digitalWrite(b1b,1);// set rotation of motor to Clockwise |
So as you can see by using interrupts our main loop basically just controls the motor and when an interrupt happens, would it be the interrupts 0 for the speed sensor or the timer elapsing calling this interrupts.
1 2 3 |
attachInterrupt(0, docount,RISING);// increase counter when speed sensor pin goes High Timer1.attachInterrupt( timerIsr );// enable the timer |
So it does interrupt but this keeps going so by using interrupts you can make your Arduino UNO do other things while you are waiting for an interrupt to happen.
LM393 Speed Sensor, Working:
We will monitor the working of the LM393 speed sensor on the serial monitor when we will rotate the potentiometer the speed of the motor will be changing and we can see it through serial monitor and the sensor will start counting the pulses using an interrupt. So when it goes high it’s going to increase by 1 and at the same time like you saw in the code we are starting a timer for one second. So after one second of counting the timer will elapse go inside the other interrupt and display the value divided by 20.
how did you do that schematic diagram , please help i want to know