United Kingdom
Offline
Faraday Member
Karma: 130
Posts: 4644
|
 |
« Reply #60 on: February 16, 2012, 08:16:44 am » |
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. http://www.eschertech.com
|
|
|
|
INDIA
Offline
Sr. Member
Karma: 0
Posts: 331
Arduino rocks
|
 |
« Reply #61 on: February 16, 2012, 08:26:15 am » |
I already wired up both the buttons to AD3 with resistor...  hummm.. So now after reading your post I am connecting them to separate pins and the GND..  Ok... Can you help me with some ideas with the MODE part please... How do I start with them...An outline... 
|
|
|
|
« Last Edit: February 16, 2012, 08:32:06 am by Joy »
|
Logged
|
|
|
|
|
INDIA
Offline
Sr. Member
Karma: 0
Posts: 331
Arduino rocks
|
 |
« Reply #62 on: February 24, 2012, 04:28:19 am » |
Please check if this code is fine for calculating the speed #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
Faraday Member
Karma: 130
Posts: 4644
|
 |
« Reply #63 on: February 25, 2012, 05:18:49 pm » |
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. http://www.eschertech.com
|
|
|
|
INDIA
Offline
Sr. Member
Karma: 0
Posts: 331
Arduino rocks
|
 |
« Reply #64 on: February 26, 2012, 01:05:09 am » |
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... 
|
|
|
|
|
Logged
|
|
|
|
|
United Kingdom
Offline
Faraday Member
Karma: 130
Posts: 4644
|
 |
« Reply #65 on: February 26, 2012, 02:59:48 am » |
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. http://www.eschertech.com
|
|
|
|
INDIA
Offline
Sr. Member
Karma: 0
Posts: 331
Arduino rocks
|
 |
« Reply #66 on: February 26, 2012, 03:15:14 am » |
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...  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.. #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..?? if (wheelRevs == 0xFFFFFFFFUL) { // must be the first time we have run wheelRevs = 0UL; }
|
|
|
|
|
Logged
|
|
|
|
|
United Kingdom
Offline
Faraday Member
Karma: 130
Posts: 4644
|
 |
« Reply #67 on: February 26, 2012, 03:41:44 am » |
But it looks little odd that the bike has stopped and for 8 seconds it is showing the last speed...  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..?? 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. http://www.eschertech.com
|
|
|
|
INDIA
Offline
Sr. Member
Karma: 0
Posts: 331
Arduino rocks
|
 |
« Reply #68 on: February 27, 2012, 02:41:13 pm » |
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
Faraday Member
Karma: 130
Posts: 4644
|
 |
« Reply #69 on: February 27, 2012, 07:27:41 pm » |
What code did you use?
|
|
|
|
|
Logged
|
Formal verification of safety-critical software, software development, and electronic design and prototyping. http://www.eschertech.com
|
|
|
|
INDIA
Offline
Sr. Member
Karma: 0
Posts: 331
Arduino rocks
|
 |
« Reply #70 on: February 29, 2012, 03:50:16 am » |
What code did you use?
something like this 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
Faraday Member
Karma: 130
Posts: 4644
|
 |
« Reply #71 on: March 04, 2012, 04:45:04 am » |
And how often were you executing the following lines? 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. http://www.eschertech.com
|
|
|
|
|