Pages: 1 ... 3 4 [5]   Go Down
Author Topic: Motorcycle Data Monitoring project ( need guidance )  (Read 7118 times)
0 Members and 1 Guest are viewing this topic.
United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6619
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

That's right, if you use a separate pin for each switch and enable the internal pullup resistors on them, then you don't need any external resistors (unless the switch wires pick up a lot of noise), just connect each switch between ground and the pin.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

INDIA
Offline Offline
Sr. Member
****
Karma: 0
Posts: 382
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I already wired up both the buttons to AD3 with resistor...smiley-razz
hummm.. So now after reading your post I am connecting them to separate pins and the GND.. smiley

Ok...
Can you help me with some ideas with the MODE part please...
How do I start with them...An outline... smiley-sad
« Last Edit: February 16, 2012, 08:32:06 am by Joy » Logged

INDIA
Offline Offline
Sr. Member
****
Karma: 0
Posts: 382
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please check if this code is fine for calculating the speed

Code:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 10, 9);
volatile unsigned int kmph = 0;
const int odometerPin = 3;
const int odometerInterrupt = 1;

const float wheelCircumference = 2035;      // wheel circumference in cm
const unsigned int HallPulsesPerRev = 1;

unsigned long lastHallPulseTime = 0;

void speedo()
{
  unsigned long now = micros();
  unsigned long interval = now - lastHallPulseTime;
  if (interval > 2000)
  {
   kmph = (wheelCircumference * 3600UL)/interval;
    
          lastHallPulseTime = now;
  }  
}

void setup()
{
  lcd.begin(16,2);
  pinMode(odometerPin, INPUT);
  attachInterrupt(odometerInterrupt, &speedo, FALLING);
}

void loop()
{
  lcd.setCursor(0, 0);
  lcd.print(kmph);
  lcd.print("     ");
}
« Last Edit: February 25, 2012, 12:15:56 pm by Joy » Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6619
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks OK, apart from the following:

1. Your comment "wheel circumference in cm" should presumably read "mm" not "cm".

2. In loop(), you should disable interrupts, copy kph to a local variable, then re-enable interrupts, then print the value of the local variable. This it in case an interrupt occurs between reading the low and high bytes of kph.

3. You will need a timeout mechanism to reset kph to zero when no pulses are arriving from the Hall sensor, similar to the one you have for the RPM sensor.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

INDIA
Offline Offline
Sr. Member
****
Karma: 0
Posts: 382
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
You will need a timeout mechanism to reset kph to zero when no pulses are arriving from the Hall sensor, similar to the one you have for the RPM sensor.

I am having little problem with this part..

If I try like

if(interval >10000){
  kmph = 0;
}

then it does not print the speed when I am moving at 1 ro 2 kms per hour... smiley-sad
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6619
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

At 1km/h there will be 1000000/2035 pulses per hour, so 1000000/(2035 * 60 * 60) pulses per second. So the interval will be (2035 * 60 * 60)/1000000 seconds = 7.32 seconds = 7320000us. So you should only set the reading to 0 when the interval exceeds this.

However, what you actually need is a timeout instead. if the bike is moving at e.g. 2km/h and then stops suddenly, there will be no more pulses and kph will not get reset to zero So what you should do instead is reset kph to zero if it is longer than about 8 seconds since the last pulse arrived.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

INDIA
Offline Offline
Sr. Member
****
Karma: 0
Posts: 382
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

yes thats what I did..
But it looks little odd that the bike has stopped and for 8 seconds it is showing the last speed... smiley-razz lol...
I think it would have become much more easier if there were more that 1 pulse per revolutions..What do you say..??


Another thing please make me understand for the rpm code you provided me..

Code:
#include <EEPROM.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 10, 9);

const int odometerPin = 3;
const int odometerInterrupt = 1;
const int odometerEepromLocation = 0;  // address of the first of 4 bytes in which the total wheel revs is stored
const int powerPin = A0;               // analog pin used to sense impending loss of power

const float wheelCircumference = 0.002035;  // wheel circumference in km
const int minPowerOkReading = 700;          // minimum reading on the power sense analog input that indicates good power
const int minPowerRestoredReading = 750;    // minimum reading on the power sense analog input that indicates we have powered back up

volatile unsigned long wheelRevs;       // total wheel revolutions counted, will overflow after 85 million km
unsigned long lastDisplayedMs = 0UL;    // time when we last refreshed the display

void setup()
{
  lcd.begin(16,2);
  // Initialise wheel revs from value stored in EEPROM
  wheelRevs = 0UL;
  for (int i = odometerEepromLocation + 3; i >= odometerEepromLocation; --i)
  {
    wheelRevs <<= 8;
    wheelRevs |= (unsigned long)EEPROM.read(i);
  }
 
  if (wheelRevs == 0xFFFFFFFFUL)
  {
    // must be the first time we have run
    wheelRevs = 0UL;
  }
 
  // Set up the odometer sensor pin and interrupt
  pinMode(odometerPin, INPUT);
  attachInterrupt(odometerInterrupt, odometerIsr, FALLING); 
}

void odometerIsr()
{
  ++wheelRevs;
}

void loop()
{
  // Capture the wheel revs with interrupts disabled in case it changes while we read it
  noInterrupts();
  unsigned long savedWheelRevs = wheelRevs;
  interrupts();
 
  if (analogRead(powerPin) < minPowerOkReading)
  {
    // Looks like power is going down, so write wheel revs to EEPROM (takes 13.2ms to write 4 bytes)
    for (int i = odometerEepromLocation; i < odometerEepromLocation + 4; ++i)
    {
      EEPROM.write(i, (unsigned char)savedWheelRevs);
      savedWheelRevs >>= 8;
    }
   
    // wait until either we die or the power comes back up
    while (analogRead(powerPin) < minPowerRestoredReading)
    {
      delay(200);
    }   
  }
  else
  { 
    unsigned long now = millis();
    if (now - lastDisplayedMs >= 200)    // update display every 200ms
    {
      lastDisplayedMs = now;
      float km = wheelCircumference * savedWheelRevs;
      lcd.setCursor(0, 0);
      lcd.print(km, 1);
      lcd.print("Km");
     
    }
    delay(5);    // repeat after 5ms so that we check for power down often enough
  }
}

My bike has already run for few thousands of km... now how do I insert the present km in in code here..??

Code:
  if (wheelRevs == 0xFFFFFFFFUL)
  {
    // must be the first time we have run
    wheelRevs = 0UL;
  }
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6619
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

But it looks little odd that the bike has stopped and for 8 seconds it is showing the last speed... smiley-razz lol...
I think it would have become much more easier if there were more that 1 pulse per revolutions..What do you say..??

Yes, with 2 pulses per rev you would only need to wait half as long to detect that the bike is going more slowly than 1km/h. You can get more pulses per rev by attaching extra magnets to the wheel. Just make sure they are evenly spaced and alternating N and S poles.

You could also decide that you are not interested in displaying speed below 2km/h instead of 1km/h, then once again you would only need to wait half as long.

Another thing please make me understand for the rpm code you provided me..
...
My bike has already run for few thousands of km... now how do I insert the present km in in code here..??

Code:
  if (wheelRevs == 0xFFFFFFFFUL)
  {
    // must be the first time we have run
    wheelRevs = 0UL;
  }

Just calculate how many wheel revs your bike has done so far and write a small program to store that value in the odometer EEPROM cells.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

INDIA
Offline Offline
Sr. Member
****
Karma: 0
Posts: 382
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi david..!!

I tried your way of timeout you are using for RPM in the speed calculation..But it does not seem to work properly...
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6619
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What code did you use?
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

INDIA
Offline Offline
Sr. Member
****
Karma: 0
Posts: 382
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What code did you use?

something like this

Code:
volatile uint8_t SpeedTimeout;
const uint8_t initiaSpeedlTimeout = 5;



void speedo()
{
  unsigned long nowPulse = micros();
  unsigned long intervalSpeed = nowPulse - lastHallPulseTime;

   kmphCalc = (wheelCircumferencemcm * 3600UL)/intervalSpeed;
         
          SpeedTimeout = initialSpeedTimeout;
         
          lastHallPulseTime = nowPulse;
          ++wheelRevs;
}

void loop(){
     lcd.setCursor(0, 0);
     lcd.print("Speed ");
 if (SpeedTimeout == 0)
     {
        lcd.print("0      ");
     }
     else
     {
       --SpeedTimeout;
       lcd.print(kmphCalc);
 
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6619
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

And how often were you executing the following lines?

Code:
if (SpeedTimeout == 0)
     {
        lcd.print("0      ");
     }
     else
     {
       --SpeedTimeout;
       lcd.print(kmphCalc);

You need to ensure that they are executed according to a strict schedule - just as you did for the RPM - so that SpeedTimeout gets decremented at regular known intervals. Then you can adjust initialSpeedTimeout so that the kph is printed as 0 at the right time.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Pages: 1 ... 3 4 [5]   Go Up
Jump to: