Please help an old fart - Rallye Tripmeter

68gt500

New Member
Hello all,
I am 60 years old and doing my first picaxe projects.

I do have some basic electronics knowledge, some (probably outdated BASIC experience..) and the drive to learn "new" stuff.

This project is a Rallye Meter - with several electromechanical counters (10m).
I am using a 20m2 - enough reserves .. ;)
The signal source is a industry std. proximity switch (Hall Sensor NPN, NO).
The maximum expected frequency should be about 150 HZ.
I have tried 2 ways to count the incoming pulses
- setint %00000010,%00000010
- if pinc.1=1 then ....

Both approaches do work.
The correct calibration (for this one set of tires) is 2535 pulses per km.

The electromechanical counters are fired by:
-pulsout B.6,2000 - a Darlington does the switching - works fine

I have an OLED display that should display:
- signal source - works ok.
- driven meters in 10 m increments - works ok.
- an speed output (averaged over the last 3 seconds) - does not...

My problems:
- I am firing the darlington when the count reaches 253 (and and not 253,5 - introducing some error here)
- how do I calculate a speed over the last few seconds (no decimals)
- I need to make the calibration adjustable - via switches, thumbwheels and such (like +-30)

Here is the code:
Code:
; Rallye Tripmeter
; triggers electromechanical 10m counter
; displays Pulses, Time,  Meters and inst. Speed on OLED
; Speed not working yet
; 
; Initialise variables
symbol counter=w0
symbol speed=w1
symbol distance=w2
symbol meter=w3
symbol calibration=w4
symbol counter2=w5
symbol kph=w6
counter2=0
calibration=3  			;Impulses/km/10   set low for Bench testing  actual 2520-2540
distance=0
meter=0
pause 3000 				;OLED init
Serout B.7,N2400,(254,1)	;OLED clear
;TIME=0
counter=0
pause 30
debug
setint %00000010,%00000010   ; C.1 on high

main: 
	Serout B.7,N2400,(254,128)	; OLED Move to Z1 S1
	Serout B.7,N2400,("Imp ",#counter,"  ",#TIME)
		if counter>=calibration then  ;  Calibration number Impulse/km/10
			pulsout B.6,2000  ;10m Puls an B7
      		meter=meter+10 ;
			counter2=counter
			counter=counter-calibration
			Serout B.7,N2400,(254,138); OLED Move to Z1 Sxx
      		serout B.7,N2400,(#meter,"m")  ;
		endif
      pause 2000 					; Wait 2 Sec for the inst Speed calc
	distance=counter2/calibration*100	; distance=counter2/calibration*circumference   
      speed=distance/Time  					;m/s 
      kph=speed*36/100           				;km/H 
      Serout B.7,N2400,(254,192)				; OLED Move to Z2 S1
	serout B.7,N2400,("                          ");
      Serout B.7,N2400,(254,192)				; OLED Move to Z2 S1
	serout B.7,N2400,(#distance,"m ",#TIME,"sec ",#kph,"km/h") ;
	TIME=0 
      counter2=0
	distance=0
 ;     endif 
goto main 

interrupt:	
		inc counter						; increase w0
			intwait: if pinc.1=1 then intwait	; wait for int to clear
			setint %00000010,%00000010   		; C.1 on high
		return					; return from sub
The formulas I have modified back and forth to get "any" output ..

Any help would be greatly appreciated!

oh yes, I did search this forum - and that is what got me as far as i am now - most of the code are snippets stolen from different projects...:cool:

Future developments would include
- average speed since last start
- Input a target average speed
- show deviation of that target average speed.
- many more...

Greetings

Mike
 

AllyCat

Senior Member
Hi Mike,

Welcome to the forum. First, beware that the "interrupts" in a PICaxe are primarily polled (executed only between instructions in the main program) and some instructions (in particular SEROUT here) are "blocking". Each character at 2400 baud will last about 4 ms and your 150 Hz is only 7 ms, so you may need to latch the input pulse and/or to ensure that each character is transmitted individually (perhaps in a subroutine) and/or using HSEROUT.

Various "tricks" can be used to achieve better accuracy in any calculations. For example you might simply transmit a pulse after counts of alternatively 253 and 254 to give the required division by 253.5. For "decimal" calculations you can multiply (all) the values by 10 or 100 and then "display" the results with a decimal point in the correct position. Here, the // operator ("remainder") can be useful.

For calibrating scale factors, the ** operator can be particularly useful. It multiplies by the subsequent number, but then divides by 65536 (2^16). So any "fractional multiplier" (up to unity) can be included easily. For example if you want to scale by 0.54321 then use a pocket calculator to multiply it by 65536 (gives 35600 rounded) and use ** 35600 in the program.

You can also use the ** operator to multiply numbers up to more than 2^16 bits, so PICaxe division is usually the greatest restriction. Sometimes it can be replaced by a multiplication process, or I have contributed some higher resolution subroutines in the "Code Snippetts" section of the forum.

Note there is also said to be a "bug" when using a variable in the first line of an interrupt routine, but I can't say that I've noticed it myself.

Cheers, Alan.
 

68gt500

New Member
Hi Alan,

thanks for the input.
i will look into that scale factor and try to understand ..
re reading my post I see an error - I am triggering the 10m counter at 100m - not 10. That would make that 25,35 counts.

Any ideas for the speed output?

Also on making that Calibration variable "user adjustable" ?

Some code snippets would be great.

Greetings

Mike
 

AllyCat

Senior Member
Hi Mike,

Any ideas for the speed output?

Also on making that Calibration variable "user adjustable" ?
The speed output issue may be the "classic" question of when to use the PICaxe COUNT and when the PULSIN commands (or equivalent "bit bashing" code). There are lots of threads with members calculating engine RPM or bicycle speedometers, etc. from magnetic or optical pulses.

The problem with COUNTing over a short period is that only a rather small number is measured, e.g. 15 pulses in 100ms for your "150 Hz". One "solution" is to measure the time between two pulses, for example PULSIN will measure 666 at 150 Hz and gets larger for lower frequencies. But that adds complications, e.g. you may need to measure both the "pulse" and the "gap" times and must calculate the reciprocal of the "time" to give the equivalent "frequency":

That's basically a "division" process, which is why I've written quite a lot on the forum about it! However, just ensuring that the numerator is approaching 65535 (but never higher) and the divisor is close to 256 will often give a result that is "good enough" with a PICaxe. Note that the CALIBADC command needs rather similar mathematical processing, so some of the code snippets on that topic might be helpful (or maybe not).

One method of "calibration" would be to attach a potentiometer (wiper) to a PICaxe ADC input pin, with the end terminals attached to supply and ground. Then you can read the position of the pot with a READADC10, to about 0.1% resolution, and use that number as a "scaling factor" in your calculations. Sorry, more "maths" which are not always easy with a PICaxe, but probably easier than jumping through all the hoops to use floating point in the "C" language. ;)

Alternatively you could add program code to make the pot "emulate" a 10-way rotary switch, or could use one of the low-cost quadrature stepping "rotary encoders" (on two PICaxe pins). Again there are lots of threads on that topic, probably because they're not particularly easy to use. :(

Cheers, Alan.

PS: As you're new to the forum you might not have "discovered" the very useful Basic Commands, Manuals and (Advanced) Search links at the top of the forum pages. ;)
 

68gt500

New Member
Thanks for all the input.

My head is still buzzing with those math "solutions" - really cool info.

I have been trying different approaches and it seems to me that I can either implement:
- the speed measurement via count
- the distance measurement via setint
- one of the above plus a serout to display the Data on the OLED.

But not all without sporadically loosing impulses for the distance measurement - which is the first priority.

Would it make sense to separate the two(3) functions into several Picaxe(s) or a Picaxe and something like a MC14569 or 40103B (divide by N counter IC) plus a Picaxe for the display?

I am still amazed at the amount of time you can sink into this stuff.

Any input appreciated..

Mike
 

AllyCat

Senior Member
Hi Mike,

I waited to see if anybody else had any suggestions, but it looks like you're stuck with me again. Yes, many would recommend using more than one PICaxe, particularly hippy, but then part of his "job" is to sell PICaxes. ;)

Personally, I treat it as a "fun challenge" to try to do everything with just one PICaxe, but others might consider me a masochist. However, do bear in mind that two PICaxes then need to "talk" to each other, or a separate "dumb" counter still needs to be read and perhaps controlled (asynchronously). So you might just be jumping "out of the frying pan and into the fire".

It may be necessary to raise the clock frequency (SETFREQ) and split the serial comms routines to transmit only short sequences of characters (to avoid blocking any polled signals), but I don't believe that any input pulses need be missed. If the pulses are narrow then there are methods to latch one edge, using on-chip hardware. Or, I have reported a method (admittedly rather obscure) that can use the "Timer 1 Gate hardware" (with PEEK/POKE-SFR commands) to latch up to three external pulses before the program needs to log them.

I think my "one PICaxe is enough" approach was vindicated in this recent thread, but then the OP himself considered it a "simple" program.

Cheers, Alan.
 

hippy

Technical Support
Staff member
Yes, many would recommend using more than one PICaxe, particularly hippy, but then part of his "job" is to sell PICaxes. ;)
:)

Most of my recommendations for multiple PICAXE chips are to simplify the design, minimise the effort. It is usually much easier to have two or more PICAXE chips each doing very simple things than try and have one chip doing everything. Much like people keeping their spinning tops spinning is easier than having one person run between them while trying to do other things as well.

I'll happily admit that it would increase the number of PICAXE sales, boosts our revenue, increases end user cost, but with the benefit of saving time, effort and frustration, so it's not all one sided.

In this case I did think multiple PICAXE might be the way to go but I am not sure how multiple PICAXE would best be used, how the work could be divied-out between them to make it an easier solution.

Spontaneous speed is easy enough because one can determine the latest measurement, process and display it, repeat. COUNT and PULSIN makes that straight forward. It doesn't matter what's missed while updating the display; the next data will be correct when it is sampled.

Once one needs to capture all measurements without missing any it becomes more complicated, and there's the added time and distance domain aspects as well.

I am not convinced a separate PICAXE would have much added benefit as the main issue is to not miss measurements. Solving that would be the most important thing. After that one can then look to see if moving things to a multi-PICAXE system would be of benefit.

I haven't thought enough about how it could all be done to say what would be best.
 

68gt500

New Member
Thank you BOTH for the input.

I had some days off to rethink and also time for the additional PICAXEs to come in. ;-).

Yes, I will break it up into easier tasks and try to integrate later on.

The instantaneous speed calculation already works halfway decently.

Now on to find which strategy gives the most reliable odometer.


Still struggeling with an easily adjustable Calibration.
Tried an 40103B progr. freq. divider - with some dip switches - but that is introducing additional inaccuracies.


Thanks
Mike
 

StefanST

New Member
First of all, if I misunderstood your project:
(1) Is the OLED display part of your Rallye Meter, or is intended for testing and the main display means are electromechanical counters?
(2) As you stated "This project is a Rallye Meter - with several electromechanical counters (10m)." Q: How and where is used the rest of the electromechanical counters?
---------------

I can see three variants (with one processor):

(A) As proposed, 20M2 is used. All facts and suggestions for this variation have already been mentioned in previous posts:
- Input pulses with maximal frequency 150Hz triggers the hardware interrupt. The interrupt routine is used to count impulses.
- All the computing a displaying the results is done in time slots (6.6ms and more) in pauses between pulses. So, any command line in the program may not exceed 6ms.
- To catch the input pulses is used SR-latch, to improve timing.
- Data to the display are sent as individual characters commands (at 2400 baud it is about 4ms/char).

(B) In the second variant with 20M2, an external counter IC is used to count the lower 6-10 bits. The overflow of the counter triggers an interrupt where it counts the upper bits.
- The 6-bit counter reduces the interruption frequency to 2.5 Hz (150 Hz / 64), i.e., to the period of 400ms. In the case of 10-bit counter, it's 6.4 sec. So, the program may contain command lines with a longer duration (still about serout command).
- The disadvantage is the requirement for free input pins. Look at the scheme.
Variant_B.png

(C) 28X2 processor has two timers.
** The first timer, by using the "SETTIMER COUNT preload" command, we will use as a 16-bit counter to count pulses. The counter status is accessible in the system variable "timer".
- 16-bit is enough for 65536/2535 = 25.8km, so we need to extend the counter range with the help of additional 8/16 bit variable.
- The overflow of the counter triggers an interrupt (see the hsetint command and the toflag break-flag command), so it is easy to increment the added variable on overflow.

** The next Timer3 has a step of 33ms to 262ms (0.5us*65536*prescaler(1-8) at 8MHz clock). The time value is in the system variable "timer3".
- The full range of timer3 is 2000sec = 33min (65536 * 33ms). Adding one byte word variable for a range extension can increase all the time to approximately 140 hours.
- Unfortunately, timer3 do not trigger the interrupt, so we need to catch timer overflow programmatically - once in 33min.

** When using an internal counter and timer, we can use long-term commands as needed to transmit serial data to the display at a 2400 bit rate.


---------------
Several questions to add to the specification:
(3) What data do you really need to see in the app? The amount of the data to display with your program code is probably for testing, I think.

(4) How often do you need to calculate and refresh the data on the display?

(5) Displayed data:
* Distance in the 999.999km or 999.9km format or other? Is the max. distance > 999km?
* Time in hh:mm:ss format or is hh:mm sufficient?
* Speed in 999km/h format, maximum speed about 230km/h (150Hz), minimum 10 km/h?
* What speeds do you need:
- instantaneous speed
- average in 3 sec
- the overall average from the beginning
- would the longer average (e.g. 5min) be useful?
* How often do you need to refresh the data? (Is it enough once in a second?)

(6) Can you tell us how to reach the calibration constant? Is it the state of the pulse counter after driving the calibration kilometer? How often do you need to measure and set the calibration constant?

Edit: corrected a typo
 
Last edited:

68gt500

New Member
Wow StefanST!
Thank you for all your input. Greatly appreciated.

The constraints are somewhat easier.

Regularity rallies are run at much lower speeds, I think my initial assumption of 150Hz is way too high- 75Hz should be enough.

You need one counter to keep track of the total km (999,9) and a second one for partial distances (99,9) Each one can be individualy resetted to zero. Both are driven by the same impulse signal.

Depending on the kind of rallye, you might be limited to strictly electromecanical counters.

I have a working prototype & code for this part.

For less restrictive Rallyes I would like to:
- have the OLED to make sure the electromecanical counters are not skipping.
- display the actual speed

For both versions I am still lookig for an easy way to change the calibration setting. The reason is that each set of tires is slightly different and also many Rallye Organiser will deliberately use a slightly longer - or shorter km. :D

- Icing oon the cake would be calculationg & displaying an average speed over the last section - complexity, that I am probably not up to and not a high priority

Greetings

Michael
 

AllyCat

Senior Member
Hi,

For both versions I am still lookig for an easy way to change the calibration setting.
It really depends what is the procedure/reference for setting the calibration. Driving a "known" distance and then setting a +/-% value, or something else?

To input a value, the simplest and most "universal" method is probably a rotary potentiometer with its end pins to Supply and Ground and the "wiper" to an ADC input. A READAC10 will give a value of between 0 and 1023 which the program can interpret in any desired way. It might be a continuous +/- 10% (or as required) or the value might be divided into bands so that the Pot behaves like a rotary switch with a pointer to 10, 20 or whatever number positions. Or you might add a display to confirm the offset setting, or the result of the calibration.......

Of course if this is to be used whilst actually "on the road", then you might need something much more "Jog-Proof", perhaps some big push-buttons? In either case, the actual "mathematics" is often best done by multiplication, particularly using the ** operator, but we can deal with that when the actual values and range are clearer.

Cheers, Alan.
 

StefanST

New Member
(7) Adjustable calibration constant:
68gt500 said:
#1 ... I need to make the calibration adjustable - via switches, thumbwheels and such (like +-30)

#3 ... Also on making that Calibration variable "user adjustable" ? Some code snippets would be great.

#11 ... I am still lookig for an easy way to change the calibration setting.
Here is the example of the simple adjustment of the calibration constant, incorporated to your sample code, published in #1. It use three buttons: one to select the calibration mode and next two to the value increment/decrement.

CODE in attachment: View attachment ST_RayleTripmeter_20M2_SETUP_1a_.bas
Note: For actual use, comment out the #DEFINE SIMULATION directive at the beginning of the program code.

It's just a sample. Your code will do more settings under different conditions, I think. The way of control can also be changed. We will see this when designing the UI.


(8) Speed testing and the 150Hz pulse generator
#11
I have a working prototype & code for this part.
That's a good news.
Was it tested with a 2535 calibration constant or only 3 (suitable for SW simulations)?
How the prototype behaves at the maximum frequency of the pulses?
How do you know if pulses are lost in the Count variable?
Is the interrupt routine triggered to increment Count variable for each pulse or not?

For real-time testing, a 1Hz-150Hz generator based on the 555 IC would be suitable.
With the option of manual sending of individual pulses.
Do you have such or do you know how to design and build it?

Low frequencies 1Hz-10Hz are good for testing functionality (whether the device does what we want).
At higher frequencies 50Hz-150Hz, timing is tested to see if it still works well.

Do you have an oscilloscope or at least oscilloscope using your computer's sound cards? For frequencies up to 1kHz.


(9) Various:
Regularity rallies are run at much lower speeds, I think my initial assumption of 150Hz is way too high - 75Hz should be enough.
It is all about Regularity rallies?
75Hz corresponds to the 110km/h rate. If it will work, max.frequency of this device could correspond to the maximum car rate - for possible other use.


Depending on the kind of rallye, you might be limited to strictly electromecanical counters.
Then you must not use electronic version? How do you will send 20ms pulses to the electromechanical counters (another pulse generator)?

... to change the calibration setting.
The reason is that each set of tires is slightly different and also many Rallye Organiser will deliberately use a slightly longer - or shorter km.
(a) You can alocate a memory to store more calibration constants.
(b) "a slightly longer - or shorter km" - How do you want to set calibration constant for such case?
If you accept the organiser kilometer, then the rate is also slightly changed. What is your approach in such situation?

- Icing on the cake would be calculationg & displaying an average speed over the last section - complexity, that I am probably not up to and not a high priority
An average speed over the last section -> add to your REQUIREMENTS.
OK, it's not too complicated. Just another variable Count_Section for calculating km/h, space on the display, reset button, and a bit of code.
 
Last edited:

68gt500

New Member
Alan & Stefan,

your answers are nothing short of amazing! Thank you!

To answer some of your questions:
Calibration:
Usually takes place before the Rallye. The organiser will lay out a track and a corresponding distance. You usually drive with your "normal" setting and check for deviation at the end. To correct I use a little simple math. Nothing fancy needed in the code. On rare cases calibration has to be changed during an Event. But that is easy - I have a notepad to keep track of the "correct" settings.:D
I will put that one calibration setting into the eeprom.

Speeds:
Regularity Rallyes are usually limited to a maximum average speed of 50 km/h. Catching up after taking a wrong turn or other "mishaps" are the only reason for the higher rates.

Pulse generation:
Depending on the Rallye, only electromecanical "displays" are accepted. The generation of the pulses itself can be done electronically.

Calibration setting:
I will try both of your Ideas, the rotary Potentiometer (seems easy enough) and also the version with 3 push-buttons. I think both are within my capabilities.

Loosing pulses:
That is a high priority. The traditional, pragmatic approach is to drive a known distance twice, one at a very low speed, the second at the highest speed anticipated. Both have to match.
I do have a frequency generator that I can set for any practical road speed. I do have an old Hameg oscilloscope, but I am not that great in using it.

Pulses/km.
Having about 2535 impulses per km I divide by 100 to generate a 10m Impulse. Loosing the non integer part and a little distance every time
I was thinking of keeping track of the real impulses and correct the distance at every full km. Which also negates the use of an external counter IC. Does my reasoning make sense? :confused:

I know what I will be doing this weekend :)

Greetings Mike
 
Top