Arduino uno RPM Temp Volts and Current sensor

Hi Everybody,

I am making a project to sense and display 3V toy motor RPM, operating Temperature and Volts and current using Arduino Uno, 2C21 hall effect sensor for RPM, LM35 temperature sensor, INA219 for voltage and current sensing and 40x4 LCD with I2C Serial Adapter.

For the code, I am using a combination of several codes which I found online and this code looks like working too.

My problem is, (1) the display is not working properly ("S" is out from "Speed"), (2) and it's getting hang when I increase the voltage to the motor. (3)Also, it displays the RPM even when I keep the sensor away from the motor.

I really appreciate if someone can help me to fix these issues.
Thank you.

#include <Wire.h>//volt current
#include <INA219_WE.h>//volt current
#include <LiquidCrystal_I2C.h>       //i2c library file 
LiquidCrystal_I2C lcd(0x3F, 20, 4);  // set the LCD address to 0x27 for a 16 chars and 2 line display
#define I2C_ADDRESS 0x40//volt current
INA219_WE ina219(I2C_ADDRESS);//volt current
//temp
#define ADC_VREF_mV    5000.0 // in millivolt
#define ADC_RESOLUTION 1024.0

#define PIN_LM35 A0 // pin connected to LM35 temperature sensor
//temp end
float value = 0;
float rev = 0;
int rpm;
int oldtime = 0;
int time;

void isr()          //interrupt service routine
{
  rev++;
}

void setup()
{
  lcd.init();                       // initialize the lcd
  lcd.init();
  lcd.backlight();
  Serial.begin(9600);
  attachInterrupt(0, isr, RISING); //attaching the interrupt
  //volt current
  Wire.begin();
  if(! ina219.init()){
  //Serial.println("INA219 not connected!");
  //while (1) { delay(10); }
  //lcd.print("INA219");
  //lcd.setCursor(0,1);
  //lcd.print(" not connected!");
  //Serial.println("INA219 Current Sensor with solar panel");
}

  //volt current end
}

void loop() {
  //delay(1000);
  detachInterrupt(0);           //detaches the interrupt
  time = millis() - oldtime;    //finds the time
  rpm = (rev / time) * 60000;   //calculates rpm
  oldtime = millis();           //saves the current time
  rev = 0;
  //temp
  int adcVal = analogRead(PIN_LM35);
  // convert the ADC value to voltage in millivolt
  float milliVolt = adcVal * (ADC_VREF_mV / ADC_RESOLUTION);
  // convert the voltage to the temperature in Celsius
  float tempC = milliVolt / 10;
  float tempF = tempC * 9 / 5 + 32; // convert Celsius to Fahrenheit
  //temp end
  //volt current
  float shuntVoltage_mV = 0.0;
  float loadVoltage_V = 0.0;
  float busVoltage_V = 0.0;
  float current_mA = 0.0;
  float power_mW = 0.0;
  bool ina219_overflow = false;

  shuntVoltage_mV = ina219.getShuntVoltage_mV();
  busVoltage_V = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getBusPower();
  loadVoltage_V  = busVoltage_V + (shuntVoltage_mV / 1000);
  ina219_overflow = ina219.getOverflow();

  Serial.print("Shunt Voltage [mV]: "); Serial.println(shuntVoltage_mV);
  Serial.print("Bus Voltage [V]: "); Serial.println(busVoltage_V);
  Serial.print("Load Voltage [V]: "); Serial.println(loadVoltage_V);
  Serial.print("Current[mA]: "); Serial.println(current_mA);
  Serial.print("Bus Power [mW]: "); Serial.println(power_mW);

  //volt current end

  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Speed: ");
  lcd.setCursor(7, 0);
  lcd.print(rpm);
  lcd.setCursor(15, 0);
  lcd.print("RPM");
  lcd.print("   ");
  attachInterrupt(0, isr, RISING);
  //delay(500);
  //temp
  lcd.setCursor(0, 1); // start to print at the first row
  lcd.print("MotorTemp:");
  lcd.print(tempC);    // print the temperature in Celsius
  lcd.print("C");
  //delay(500);
  //temp end
  //volt current
  lcd.setCursor(0, 2);
  lcd.print("Volts:");
  lcd.print(loadVoltage_V);
  lcd.print("V     ");
  lcd.setCursor(0, 3);
  lcd.print("Current:");
  lcd.print(current_mA);
  lcd.print("mA        ");
  if(!ina219_overflow){
    Serial.println("Values OK - no overflow");
  }
  else{
    Serial.println("Overflow! Choose higher PGAIN");
  }
  Serial.println();
  //volt current end
  delay(1000);
}```

What is that attachinterrupt statement doing there?

Hi, @aquila2heman
Welcome to the forum.

Thanks for the attached information.
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, component names and pin labels.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

attachInterrupt(0, isr, RISING);

No idea, it was there on the original code.

this looks like a display issue. i simulated that code and couldn't find an explanation.

i would try testing with less external hardware to very the behavior of the display code and convince yourself that it is correct and then see if the external hardware interferes

Hope this will work, All the + and - connected to arduino + and -, Also I have used external 9V supply to supply arduino separatly.

Thank you very much.

Often that missing character at the start of a line, is caused by overwriting a ‘too long’ line further down the display.

LCDs are usually natively addressed as alternating lines , so maybe look at the code for lines 3 and 4 (2 and 3).

Hi,
Thanks for the diag.

Can you post link to data/specs of the HallEffect device, does it need a pull-up resistor on its output, or is one on the module PCB?
Most HallEffect elements have open collector if just a HIGH/LOW signal.

The INA219 is not isolated type, so your erratic readings could be due to motor noise.
Can you try a 0.1uF capacitor across the motor terminals on the motor?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Sorry, can you make it a little more clear, please.

If you write too much in line 3, chances are it will wrap around to line 0 etc.

@lastchancename
Thanks for the advice, I remove some unwanted spaces and edit some code to reduce LCD char now char disappearing issue is fixed.

lcd.print("V     ");
lcd.print("mA        ");

to

lcd.print("V");
lcd.print("mA");

and

lcd.setCursor(1, 0);
  lcd.print("Speed: ");
  lcd.setCursor(7, 0);
  lcd.print(rpm);
  lcd.setCursor(15, 0);
  lcd.print("RPM");
  lcd.print("   ");

to

lcd.setCursor(0, 0);
  lcd.print("Speed:");
  //lcd.setCursor(7, 0);
  lcd.print(rpm);
  //lcd.setCursor(13, 0);
  lcd.print(" RPM");
  //lcd.print("   ");

@TomGeorge
Hi, I'm using KY-003 Sensor. It is on the module, and datasheet for it is http://www.datasheet-pdf.com/PDF/KY-003-Datasheet-Joy-IT-1321960.

I add a 0.1uF capacitor across the motor terminals, but still it's the same, giving an RPM reading even without bringing the sensor near to the motor.

Hi,
Where in your code do you pinMode the Halleffect sensor input?
It needs to have INPUT_PULLUP mode or you need to fit a 10K or 4K7 between the sensor output and 5V.

Can you please post your new working code please?

Did you try the example code in the data sheet you just link?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

In my code, I don't have pin mode with INPUT_PULLUP mode, but after reading some other posts on the web, I added a 10K pull-up resister between 5v and signal. Also, I tried using INPUT_PULLUP mode according to the data sheet code after your reply, but still it's same.

Actually the Halleffect sensor is working correctly when I test it alone but when I add INA219 V and C sensor things going wrong, Also I found if I remove the signal pin from HE sensor false RPM reading also goes to 0.

Also, I found when I increase the motor voltage above 2.8-3 v LCD getting hang.

Thank you.

This is the modified code.

#include <Wire.h>//volt current
#include <INA219_WE.h>//volt current
#include <LiquidCrystal_I2C.h>       //i2c library file 
LiquidCrystal_I2C lcd(0x3F, 20, 4);  // set the LCD address to 0x27 for a 16 chars and 2 line display
#define I2C_ADDRESS 0x40//volt current
INA219_WE ina219(I2C_ADDRESS);//volt current
//temp
#define ADC_VREF_mV    5000.0 // in millivolt
#define ADC_RESOLUTION 1024.0

#define PIN_LM35 A0 // pin connected to LM35 temperature sensor
int Sensor = 2; // Declaration of the sensor input pin
//temp end
float value = 0;
float rev = 0;
int rpm;
int oldtime = 0;
int time;

void isr()          //interrupt service routine
{
  rev++;
}

void setup()
{
 pinMode (Sensor, INPUT) ; // Sensor pin initialization
 digitalWrite(Sensor, HIGH); // Activation of internal pull-up resistor
//}
//{
  lcd.init();                       // initialize the lcd
  //lcd.init();
  lcd.backlight();
  Serial.begin(9600);
  attachInterrupt(0, isr, RISING); //attaching the interrupt
  //volt current
  Wire.begin();
  if(! ina219.init()){
  //Serial.println("INA219 not connected!");
  //while (1) { delay(10); }
  //lcd.print("INA219");
  //lcd.setCursor(0,1);
  //lcd.print(" not connected!");
  //Serial.println("INA219 Current Sensor with solar panel");
}

  //volt current end
}

void loop() {
  //delay(1000);
  detachInterrupt(0);           //detaches the interrupt
  time = millis() - oldtime;    //finds the time
  rpm = (rev / time) * 60000;   //calculates rpm
  oldtime = millis();           //saves the current time
  rev = 0;
  //temp
  int adcVal = analogRead(PIN_LM35);
  // convert the ADC value to voltage in millivolt
  float milliVolt = adcVal * (ADC_VREF_mV / ADC_RESOLUTION);
  // convert the voltage to the temperature in Celsius
  float tempC = milliVolt / 10;
  //float tempF = tempC * 9 / 5 + 32; // convert Celsius to Fahrenheit
  //temp end
  //volt current
  float shuntVoltage_mV = 0.0;
  float loadVoltage_V = 0.0;
  float busVoltage_V = 0.0;
  float current_mA = 0.0;
  float power_mW = 0.0;
  bool ina219_overflow = false;

  shuntVoltage_mV = ina219.getShuntVoltage_mV();
  busVoltage_V = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  power_mW = ina219.getBusPower();
  loadVoltage_V  = busVoltage_V + (shuntVoltage_mV / 1000);
  ina219_overflow = ina219.getOverflow();

  Serial.print("Shunt Voltage [mV]: "); Serial.println(shuntVoltage_mV);
  Serial.print("Bus Voltage [V]: "); Serial.println(busVoltage_V);
  Serial.print("Load Voltage [V]: "); Serial.println(loadVoltage_V);
  Serial.print("Current[mA]: "); Serial.println(current_mA);
  Serial.print("Bus Power [mW]: "); Serial.println(power_mW);

  //volt current end
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Speed:");
  //lcd.setCursor(7, 0);
  lcd.print(rpm);
  //lcd.setCursor(13, 0);
  lcd.print(" RPM");
  //lcd.print("   ");
  attachInterrupt(0, isr, RISING);
  //delay(500);
  //temp
  lcd.setCursor(0, 1); // start to print at the first row
  lcd.print("MotorTemp:");
  lcd.print(tempC);    // print the temperature in Celsius
  lcd.print("C");
  //delay(500);
  //temp end
  //volt current
  lcd.setCursor(0, 2);
  lcd.print("Volts:");
  lcd.print(loadVoltage_V);
  //lcd.print(busVoltage_V);
  lcd.print("V");
  lcd.setCursor(0, 3);
  lcd.print("Current:");
  lcd.print(current_mA);
  lcd.print("mA");
  if(!ina219_overflow){
    Serial.println("Values OK - no overflow");
  }
  else{
    Serial.println("Overflow! Choose higher PGAIN");
  }
  Serial.println();
  //volt current end
  delay(1000);
}

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