Arduino Anemometer

Hi all,

I have a problem with a project I am currently doing. I am building an anemometer and have been debugging it via proteus. The schematic is attached to the post. The basic setup is this: there is a rotary encoder which is clocking a counter. The counter bits are being fed to the arduino together with the MR (Master Reset) of the counter. Now the arduino code should do the following:
Set the MR low so that the counter resets.
Every 0.5ms it should read the value of the 4 bits and use the equation found here(Support) to calculate the velocity.
This velocity is displayed on the LCD.
The MR pin is then pulsed so that the counter resets.

The problem is that according to the simulation, the lcd is simply displaying a velocity of -1 and it never changes. I see the counter incrementing and the MR pin being pulsed but the LCD isn't displaying the velocity value. Could someone suggest any possible solutions to the problem?

The code is as follows:

#include <LiquidCrystal.h>

// Connections:
// rs (LCD pin 4) to Arduino pin 19
// rw (LCD pin 5) to Arduino pin 3
// enable (LCD pin 6) to Arduino pin 4
// LCD pin 15 to Arduino pin 13										
// LCD pins d4, d5, d6, d7 to Arduino pins 6, 25, 12, 14
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int bitstate [4] = {0,0,0,0};
int bitaddress[4] = {6, 7, 8, 9};
int RSTaddress = 0;
int backLight = 13;    // pin 13 will control the backlight
int pulses = 100; // indicates the number of pulses per revolution
int fixedtime = 0.5; //fixed time interval in ms
long encoderval = 0; 
//int encoderval1,encoderval2 =0;
long velocity=0;
long time = 0;
void setup()
{
  pinMode (bitaddress[0], INPUT);
  pinMode (bitaddress[1], INPUT);
  pinMode (bitaddress[2], INPUT);
  pinMode (bitaddress[3], INPUT);
  pinMode (RSTaddress, OUTPUT);
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.
  lcd.begin(16,2);              // columns, rows.  use 16,2 for a 16x2 LCD, etc.
  lcd.clear();                  // start with a blank screen
  lcd.setCursor(0,0);           // set cursor to column 0, row 0 (the first row)
  lcd.print("Wind Speed: ");    // change this text to whatever you like. keep it clean.
  digitalWrite (RSTaddress, HIGH);

  

}

void loop()
{
  encoderval = 0;
  velocity = 0;
  digitalWrite (RSTaddress, LOW);
  delayMicroseconds (fixedtime*1000); //waits for 0.5ms
  bitstate[0]= digitalRead(bitaddress[0]);
  bitstate[1]= digitalRead(bitaddress[1]);
  bitstate[2]= digitalRead(bitaddress[2]);
  bitstate[3]= digitalRead(bitaddress[3]);
  encoderval = bitstate[0] + (bitstate[1]*2) + (bitstate[2]*4) + (bitstate[3]*8); 
  //encoderval1 = PORTD & B11000000;
  //encoderval2 = PORTB & B00000011;
  //encoderval = (encoderval1 >> 6) & (encoderval2 << 2);
  time = fixedtime/1000;
  velocity = (encoderval*60)/(pulses*time);
  lcd.setCursor (0,1);
  lcd.print (velocity);
  digitalWrite (RSTaddress, HIGH);
  delay (1);
  return;
}

Thanks in advance for any help!

int fixedtime = 0.5; //fixed time interval in ms

0.5 isn't an integer.

You have 'time' declared as an integer, which is good. You then set it to fixedtime/1000 which is equivalent to 0.

Then you set 'velocity' to (encoderval60)/(pulses0) which causes a math error (division by zero)

Best not to mix floats and longs. You should try doing everything in microseconds (time = 500).

You are also holding the reset line low throughout the measurement period, resulting in a reading of 0.

Hey guys,

Thanks for all the help! Solved the problem of getting -1 on the LCD. I noticed that the resolution of the system was not up to standard so I decided to add another binary counter and connecting its outputs to the analog pins of the arduino. All well and good but for some strange reason the value outputted on the encoder is now always 1.5 times the rpm value of the encoder!
Here's the updated code :

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int bitstate [8] = {0,0,0,0,0,0,0,0};
int bitaddress[4] = {6, 7, 8, 9};
int abitaddress[4] = {14,15,16,17};
int RSTaddress = 0;
int backLight = 13;    // pin 13 will control the backlight
int pulses = 100; // indicates the number of pulses per revolution
float fixedtime = 31.8; //fixed time interval in ms
int encoderval = 0; 
//int encoderval1,encoderval2 =0;
float velocity= 0.00;
void setup()
{
  pinMode (bitaddress[0], INPUT);
  pinMode (bitaddress[1], INPUT);
  pinMode (bitaddress[2], INPUT);
  pinMode (bitaddress[3], INPUT);
  pinMode (abitaddress[0], INPUT);
  pinMode (abitaddress[1], INPUT);
  pinMode (abitaddress[2], INPUT);
  pinMode (abitaddress[3], INPUT);
  pinMode (RSTaddress, OUTPUT);
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.
  lcd.begin(16,2);              // columns, rows.  use 16,2 for a 16x2 LCD, etc.
  lcd.clear();                  // start with a blank screen
  lcd.setCursor(0,0);           // set cursor to column 0, row 0 (the first row)
  lcd.print("Wind Speed: ");    // change this text to whatever you like. keep it clean.
//  lcd.setCursor(0,1);           // set cursor to column 0, row 1
}

void loop()
{
  digitalWrite (RSTaddress, HIGH);
  delayMicroseconds (100);
  digitalWrite (RSTaddress, LOW);
  delay(fixedtime); //waits for 0.5ms
  bitstate[7]= digitalRead(abitaddress[3]);
  bitstate[6]= digitalRead(abitaddress[2]);
  bitstate[5]= digitalRead(abitaddress[1]);
  bitstate[4]= digitalRead(abitaddress[0]);
  bitstate[3]= digitalRead(bitaddress[3]);
  bitstate[2]= digitalRead(bitaddress[2]);
  bitstate[1]= digitalRead(bitaddress[1]);
  bitstate[0]= digitalRead(bitaddress[0]);
  encoderval = bitstate[0] + (bitstate[1]*2) + (bitstate[2]*4) + (bitstate[3]*8)+(bitstate[4]*16)+(bitstate[5]*32)+(bitstate[6]*64)+(bitstate[7]*128); 
//  encoderval1 = PORTD & B11000000;
//  encoderval2 = PORTB & B00000011;
//  encoderval = (encoderval1 >> 6) & (encoderval2 << 2);
  velocity = (encoderval*60000)/(pulses*fixedtime);
  lcd.setCursor (0,1);
  lcd.print (velocity);
  return;
}

Note: in the attached screenshot the rpm was set 1000 and the value outputted was varying from 1548 and 1470. Adding a dc value to Aref had no effect. The same result occurred with no Aref.

Thanks once again for all the help!

Found the problem, the motor encoder had a load/torque ratio that was effecting the output of the LCD. By changing this with a normal clock the problem was solved and everything seems to be working as expected! :slight_smile: Hopefully in practice this will also be the case! Thanks once again for all the help