Help please

I am doing a speed sensor project using optocoupler to count pulses , I uses Color Graphic LCD with I2C Interface here is the link of the lcd http://www.web4robot.com/GraphicLCD.html I don't know how to write a code to link the optocoupler with the lcd to print the rpm of a dc motor

http://www.web4robot.com/files/GLCD-I2C.zip

I could probably guess, but, what's the role of the opto-coupler here?
(It's more fun for me to dig the details out of you.)

I'm using optocoupler to count the RPM of a DC motor and her is the code , The problem is that the LCD write RPM=0 however i run the dc motor

volatile byte rpmcount;
unsigned int rpm;
unsigned long timeold;

// include the library code:
#include <GLCDI2C.h>
#include <Wire.h>

// Color definitions
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF

unsigned int maxX = 160; // LCD x-resolution
unsigned int maxY = 128; // LCD y-resolution
unsigned char i2cAddress = 0x46; // LCD module I2C address
unsigned int counter;
unsigned int tmp;
GLCDI2C lcd = GLCDI2C(maxX, maxY, i2cAddress);

void rpm_fun()
{

rpmcount++;
}

void setup()
{
delay(500);
Wire.begin();
lcd.init();

attachInterrupt(0, rpm_fun, FALLING);

rpmcount = 0;
rpm = 0;
timeold = 0;
}

void loop()
{

delay(1000);

detachInterrupt(0);

rpm = 30*1000/(millis() - timeold)*rpmcount;
timeold = millis();
rpmcount = 0;

delay(500);
lcd.setColor(BLACK);
lcd.clear();
lcd.fontType(FONT_SMALL);
lcd.setColor(WHITE);
lcd.cursor(15,15);

lcd.print("RPM=");
lcd.print(rpm);
delay(3000);

attachInterrupt(0, rpm_fun, FALLING);
}

mohamed92:
The problem is that the LCD write RPM=0 however i run the dc motor

Is that because you have rpmcount=0 in your void loop( ) ?

 void loop()
 {  
    delay(1000);  
    detachInterrupt(0); 
    rpm = 30*1000/(millis() - timeold)*rpmcount;
    timeold = millis();
    rpmcount = 0;     \\ <<<<<<<< rpmcount=0!

The use of delay is not adviced but OK,

I have rewritten the code a bit

  • more clear that you measure 1 second
  • add a bit of debugging info
  • reformulated the core formula

give it a try, code not tested :wink:

// vars here

void rpm_fun()
{
  rpmcount++;
}

void setup()
{
  Serial.begin(115200); // debugging output
  Wire.begin();  
  lcd.init();

  rpmcount = 0; // set it before the ISR is attached
  timeold = 0;
}

void loop()
{
  // measure for about 1000 milliseconds
  timeold = millis();
  attachInterrupt(0, rpm_fun, FALLING);
  delay(1000);
  detachInterrupt(0);
  unsigned long now = millis();

  // do some math
  unsigned long duration = now - timeold;
  rpm = rpmcount *30UL * 1000UL/duration;       // changed this formula notice the UL for Unsigned Long
  rpmcount = 0;  // reset

  // debugging
  Serial.print("duration=");
  Serial.println(duration);
  Serial.print("rpmcount=");
  Serial.println(rpmcount);
  Serial.print("rpm=");
  Serial.println(rpm);

  // display results
  lcd.setColor(BLACK);
  lcd.clear();
  lcd.fontType(FONT_SMALL);
  lcd.setColor(WHITE);
  lcd.cursor(15,15);
  lcd.print("RPM=");
  lcd.print(rpm);
}