# Help with Speedometer using stepper motor and BX24

Started by November 21, 2010
I would like to ask some help here.
I have a personal car project (mix of track and street use) and would
like to build my own dashboard.
I know most of people would recommend to use a regular 7-segment display
for speedometer . However I want to keep the traditional look of analog
speedo with needle style. However the stepper motor offers high
precision.
I built a simple circuit with BX24 and Swisstec X25 stepper motor and
started playing with. It works fine.
Now I would like to ask for some help:
- any suggestion on which kind of circuit should I use to read the
gearbox electronic speedo sensor signal? I know it is a square wave
which modulates frequency according the speed. I believe most cars are
like this. I don't have any idea on how to connect the speedo signal and
process that data. Should I do a frequency-to-voltage converter? Or any
other idea? Or should I use just the BX24 to count pulses and make all
data processing to convert to the speedo signal information into pulses
for the stepper motor?
- any suggestion on software code to properly move the stepper motor
according the car speed? Should I do some internal register in software
so I know exactly where the needle is in the dash? I mean, should I
always know where the needle is exactly and how much up/down movement it
is necessary as next step? Because I need to control clockwise and
counter clockwise movements.
Any suggestion on how to proceed with this project?
Here is the simple code I did just to test the stepper motor and confirm
that basic circuit is working fine.

-----------Option Explicit
Public Sub Main()
Dim n as integerConst M1 as Byte = 12 'this is the pin to drive Motor
Pin1Const M2 as Byte = 11 'this is the pin to drive Motor
Pin2=Pin3Const M4 as Byte = 10 'this is the pin to drive Motor
Pin4Const POn as Byte = 0 'NOR port working as inverter, so the logic
should be inverted.This case "Pulse On=0"Const POff as Byte = 1 'This
case "Pulse Off=1"
'simple testing
for n = 1 to 50'#1 Call PulseOut(M1, 0.002, POn ) 'M1=1 after NOR ( inverter) Call PulseOut(M2, 0.002, POff) 'M2=0 after NOR ( inverter) Call PulseOut(M4, 0.002, POn ) 'M4=1 after NOR ( inverter) '#2 Call PulseOut(M1, 0.002, POn ) 'M1=1 after NOR ( inverter) Call PulseOut(M2, 0.002, POff) 'M2=0 after NOR ( inverter) Call PulseOut(M4, 0.002, POff) 'M4=0 after NOR ( inverter) '#3 Call PulseOut(M1, 0.002, POn) 'M1=1 after NOR ( inverter) Call PulseOut(M2, 0.002, POn) 'M2=1 after NOR ( = inverter)
Call PulseOut(M4, 0.002, POff) 'M4=0 after NOR ( = inverter)'#4 Call
PulseOut(M1, 0.002, POff) 'M1=0 after NOR ( = inverter) Call
PulseOut(M2, 0.002, POn) 'M2=1 after NOR ( = inverter) Call
PulseOut(M4, 0.002, POff) 'M4=0 after NOR ( = inverter)'#5 Call
PulseOut(M1, 0.002, POff) 'M1=0 after NOR ( = inverter) Call
PulseOut(M2, 0.002, POn) 'M2=1 after NOR ( = inverter) Call
PulseOut(M4, 0.002, POn) 'M4=1 after NOR ( = inverter)'#6 Call
PulseOut(M1, 0.002, POff) 'M1=0 after NOR ( = inverter) Call
PulseOut(M2, 0.002, POff) 'M2=0 after NOR ( = inverter) Call
PulseOut(M4, 0.002, POn) 'M4=1 after NOR ( = inverter) Next
End Sub
-----------
Also the diagram for the stepper motor control circuit. As you can see,
there is enough pins available for more implementation.

http://i8.photobucket.com/albums/a10/ericksoares/swapeando/Schematic01.j\
pg

Thanks
Erick

f/v are nice since it simplifies your programming. Also the LM2917 chip
goes to zero with zero input - this saves hassle of dealing with
overruns on very slow rotations.

Richard

From: b... [mailto:b...] On Behalf
Of ericksoliveira
Sent: Sunday, November 21, 2010 8:25 PM
To: b...
Subject: [BasicX] Help with Speedometer using stepper motor and BX24

I would like to ask some help here.
I have a personal car project (mix of track and street use) and would
like to build my own dashboard.
I know most of people would recommend to use a regular 7-segment display
for speedometer . However I want to keep the traditional look of analog
speedo with needle style. However the stepper motor offers high
precision.
I built a simple circuit with BX24 and Swisstec X25 stepper motor and
started playing with. It works fine.
Now I would like to ask for some help:
- any suggestion on which kind of circuit should I use to read the
gearbox electronic speedo sensor signal? I know it is a square wave
which modulates frequency according the speed. I believe most cars are
like this. I don't have any idea on how to connect the speedo signal and
process that data. Should I do a frequency-to-voltage converter? Or any
other idea? Or should I use just the BX24 to count pulses and make all
data processing to convert to the speedo signal information into pulses
for the stepper motor?
- any suggestion on software code to properly move the stepper motor
according the car speed? Should I do some internal register in software
so I know exactly where the needle is in the dash? I mean, should I
always know where the needle is exactly and how much up/down movement it
is necessary as next step? Because I need to control clockwise and
counter clockwise movements.
Any suggestion on how to proceed with this project?
Here is the simple code I did just to test the stepper motor and confirm
that basic circuit is working fine.

-----------Option Explicit
Public Sub Main()
Dim n as integerConst M1 as Byte = 12 'this is the pin to drive Motor
Pin1Const M2 as Byte = 11 'this is the pin to drive Motor
Pin2=Pin3Const M4 as Byte = 10 'this is the pin to drive Motor
Pin4Const POn as Byte = 0 'NOR port working as inverter, so the logic
should be inverted.This case "Pulse On=0"Const POff as Byte = 1 'This
case "Pulse Off=1"
'simple testing
for n = 1 to 50'#1 Call PulseOut(M1, 0.002, POn ) 'M1=1 after NOR ( inverter) Call PulseOut(M2, 0.002, POff) 'M2=0 after NOR ( inverter) Call PulseOut(M4, 0.002, POn ) 'M4=1 after NOR ( inverter) '#2 Call PulseOut(M1, 0.002, POn ) 'M1=1 after NOR ( inverter) Call PulseOut(M2, 0.002, POff) 'M2=0 after NOR ( inverter) Call PulseOut(M4, 0.002, POff) 'M4=0 after NOR ( inverter) '#3 Call PulseOut(M1, 0.002, POn) 'M1=1 after NOR ( inverter) Call PulseOut(M2, 0.002, POn) 'M2=1 after NOR ( = inverter)
Call PulseOut(M4, 0.002, POff) 'M4=0 after NOR ( = inverter)'#4 Call
PulseOut(M1, 0.002, POff) 'M1=0 after NOR ( = inverter) Call
PulseOut(M2, 0.002, POn) 'M2=1 after NOR ( = inverter) Call
PulseOut(M4, 0.002, POff) 'M4=0 after NOR ( = inverter)'#5 Call
PulseOut(M1, 0.002, POff) 'M1=0 after NOR ( = inverter) Call
PulseOut(M2, 0.002, POn) 'M2=1 after NOR ( = inverter) Call
PulseOut(M4, 0.002, POn) 'M4=1 after NOR ( = inverter)'#6 Call
PulseOut(M1, 0.002, POff) 'M1=0 after NOR ( = inverter) Call
PulseOut(M2, 0.002, POff) 'M2=0 after NOR ( = inverter) Call
PulseOut(M4, 0.002, POn) 'M4=1 after NOR ( = inverter) Next
End Sub
-----------
Also the diagram for the stepper motor control circuit. As you can see,
there is enough pins available for more implementation.

http://i8.photobucket.com/albums/a10/ericksoares/swapeando/Schematic01.j
\
pg
jpg>

Thanks
Erick

Dear Richard Friedrich

both links have been deleted.......try them yourself.

Greetings from

Andy Mathison

Richard,

if you can find the code and share, I will appreciate, so I can use as base for my own development.

Thanks

--- In b..., "Richard Friedrich" wrote:
> I did this about 10 years ago
> It used a rc airplane servo
> It didn't use h-bridge
> Generated the 1000-3000
> Directly with chip
> Sent from my HTC on the Now Network from Sprint!
>
> From: "erick soares de oliveira"
> Date: Wed, Nov 24, 2010 6:22 pm
> Subject: [BasicX] Digest Number 3131
> Cc: "b..."
> Still fighting to write some efficient code for the needle move smoothly and
> find any position in the speedometer.
>
> if anyone may have any suggestion or idea, let me know
>
> On Wed, Nov 24, 2010 at 11:47 AM, wrote:
>
> > Discussion list for the BasicX family of microcontroller chips
> >
> > Messages In This Digest (1 Message)
> > 1a. Re: Help with Speedometer using stepper motor and BX24<#12c7e239131341c9_1a>From: Andrewdavid.mathison
> > View All Topics| Create
> > New Topic
> > Message
> > 1a. Re: Help with Speedometer using stepper motor and BX24
> > Posted
> > by: "Andrewdavid.mathison" andrewdavid.mathison@...
> > andrew.mathison
> > Tue Nov 23, 2010 6:50 am
> > (PST)
> >
> >
> > Dear Richard Friedrich
> >
> > both links have been deleted.......try them yourself.
> >
> > Greetings from
> >
> > Andy Mathison
> >
> >
> >
> > to group
> > via web post
> >
> > Messages in this topic
> > (3)
> > Recent Activity
> >
> > - 2
> > New Members
> >
> >
> > Give Back
> >
> > Yahoo! for Good
> >
> > Get inspired
> >
> > by a good cause.
> > Y! Toolbar
> >
> > Get it Free!
> >
> > easy 1-click access
> >
> > Yahoo! Groups
> >
> > Start a group
> >
> > in 3 easy steps.
> >
> > Connect with others.
> >
> > Click one of the "Reply" links to respond to a specific message in the
> > Daily Digest.
> > Create New Topic
> > | Visit
> > Your Group on the Web
> > Messages|
> > Files|
> > Photos
> > [image: Yahoo! Groups]
> > Change settings via the Web(Yahoo! ID required)
> > Change settings via email: Switch delivery to Individual| Switch
> > | Yahoo!
> >
> >
>
>
>

Hi guys,
this weekend I worked in this project and could finally do a good piece of software to control the needle in the dash properly.Via test and evaluation, all speeds are matching properly.

Now I will continue with a circuit and code to properly count speedo sensor pulses and convert to speed base.

I'm planning to use a regular clamping circuit with diodes and transistor to use as interface from the speed sensor to the BX-24 input. I expect to use the "CountTransitions" for that.

This is the software code I developed and worked fine:

Option Explicit

Const M1 as Byte = 12
Const M2 as Byte = 11
Const M4 as Byte = 10
Const POn as Byte = 0
Const POff as Byte = 1
'--------------------
Public Sub MoveNeedleUp ( ByRef NSpeed as Integer, ByRef NNeedlePos As Integer, ByRef NStep as Byte)

'--this section makes the needle move up
'--according current position and
'--desired speed target
'--each step is the necessary stepper motor control

LOOP_UP:
If (NStep=6) Then
'Step #1
NStep=1
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POn )
Call PulseOut(M2, 0.001, POff)
Call PulseOut(M4, 0.001, POn )
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=1) Then
'Step #2
NStep=2
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POn )
Call PulseOut(M2, 0.001, POff)
Call PulseOut(M4, 0.001, POff)
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=2) Then
'Step #3
NStep=3
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POn)
Call PulseOut(M2, 0.001, POn)
Call PulseOut(M4, 0.001, POff)
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=3) Then
'Step #4
NStep=4
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POff)
Call PulseOut(M2, 0.001, POn)
Call PulseOut(M4, 0.001, POff)
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=4) Then
'Step #5
NStep=5
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POff)
Call PulseOut(M2, 0.001, POn)
Call PulseOut(M4, 0.001, POn)
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=5) Then
'Step #6
NStep=6
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POff)
Call PulseOut(M2, 0.001, POff)
Call PulseOut(M4, 0.001, POn)
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
If (NNeedlePos<>NSpeed) Then
Goto LOOP_UP
End if
End If

LOOP_UP_END:
End Sub

'--------------------

Public Sub MoveNeedleDown ( ByRef NSpeed as Integer, ByRef NNeedlePos As Integer, ByRef NStep as Byte)

'--this section makes the needle move down
'--according current position and
'--desired speed target
'--each step is the necessary stepper motor control

LOOP_DOWN:
If (NStep=1) Then
'Step #6
NStep=6
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POff)
Call PulseOut(M2, 0.001, POff)
Call PulseOut(M4, 0.001, POn)
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End If

If (NStep=6) Then
'Step #5
NStep=5
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POff)
Call PulseOut(M2, 0.001, POn)
Call PulseOut(M4, 0.001, POn)
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End If

If (NStep=5) Then
'Step #4
NStep=4
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POff)
Call PulseOut(M2, 0.001, POn)
Call PulseOut(M4, 0.001, POff)
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End if

If (NStep=4) Then
'Step #3
NStep=3
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POn)
Call PulseOut(M2, 0.001, POn)
Call PulseOut(M4, 0.001, POff)
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End if

If (NStep=3) Then
'Step #2
NStep=2
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POn )
Call PulseOut(M2, 0.001, POff)
Call PulseOut(M4, 0.001, POff)
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End if

If (NStep=2) Then
'Step #1
NStep=1
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POn )
Call PulseOut(M2, 0.001, POff)
Call PulseOut(M4, 0.001, POn )
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
If (NNeedlePos<>NSpeed) Then
Goto LOOP_DOWN
End if
End if

LOOP_DOWN_END:

End Sub

'--------------------

Public Sub StartupDash ()
Dim n As Integer

'- this procedure makes the needle
'- go up to 220km/h then go back
'- down to 0km/h, similar to some
'- cars, such as Lexus and others

'START force to go to initial state --0
For n = 1 to 10
'#6
Call PulseOut(M1, 0.001, POff) 'M1=0 ap inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 ap inversor
Call PulseOut(M4, 0.001, POn) 'M3=1 ap inversor
'#5
Call PulseOut(M1, 0.001, POff) 'M1=0 ap inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 ap inversor
Call PulseOut(M4, 0.001, POn) 'M3=1 ap inversor
'#4
Call PulseOut(M1, 0.001, POff) 'M1=0 ap inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 ap inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 ap inversor
'#3
Call PulseOut(M1, 0.001, POn) 'M1=1 ap inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 ap inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 ap inversor
'#2
Call PulseOut(M1, 0.001, POn ) 'M1=1 ap inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 ap inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 ap inversor
'#1
Call PulseOut(M1, 0.001, POn ) 'M1=1 ap inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 ap inversor
Call PulseOut(M4, 0.001, POn ) 'M3=1 ap inversor
Next

'WAKE UP to 220km/h
for n = 1 to 106
'#1
Call PulseOut(M1, 0.001, POn ) 'M1=1 ap inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 ap inversor
Call PulseOut(M4, 0.001, POn ) 'M3=1 ap inversor
'#2
Call PulseOut(M1, 0.001, POn ) 'M1=1 ap inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 ap inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 ap inversor
'#3
Call PulseOut(M1, 0.001, POn) 'M1=1 ap inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 ap inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 ap inversor
'#4
Call PulseOut(M1, 0.001, POff) 'M1=0 ap inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 ap inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 ap inversor
'#5
Call PulseOut(M1, 0.001, POff) 'M1=0 ap inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 ap inversor
Call PulseOut(M4, 0.001, POn) 'M3=1 ap inversor
'#6
Call PulseOut(M1, 0.001, POff) 'M1=0 ap inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 ap inversor
Call PulseOut(M4, 0.001, POn) 'M3=1 ap inversor
Next

'WAKE UP DOWN to 0km/h
For n = 1 to 104

'#6
Call PulseOut(M1, 0.001, POff) 'M1=0 ap inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 ap inversor
Call PulseOut(M4, 0.001, POn) 'M3=1 ap inversor
'#5
Call PulseOut(M1, 0.001, POff) 'M1=0 ap inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 ap inversor
Call PulseOut(M4, 0.001, POn) 'M3=1 ap inversor
'#4
Call PulseOut(M1, 0.001, POff) 'M1=0 ap inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 ap inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 ap inversor
'#3
Call PulseOut(M1, 0.001, POn) 'M1=1 ap inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 ap inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 ap inversor
'#2
Call PulseOut(M1, 0.001, POn ) 'M1=1 ap inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 ap inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 ap inversor
'#1
Call PulseOut(M1, 0.001, POn ) 'M1=1 ap inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 ap inversor
Call PulseOut(M4, 0.001, POn ) 'M3=1 ap inversor
Next
End Sub
'--------------------
Public Sub Main()
Dim TargetSpeed as Integer 'speed value
Dim NeedlePos as Integer 'NeedlePos 0=0km/h to 612=220km/h
Dim CurrentStep as Byte 'Step 1 to 6
Dim TempSpeed as Single
Dim OnOffIgnition as Byte

Call StartupDash ()
TargetSpeed = 0
NeedlePos = 0
CurrentStep = 6

Call Delay (1.0)
Call PutPin (13, bxInputPullup)

POWER_LOOP:
OnOffIgnition = GetPin(13)
Do While ( OnOffIgnition=1 )
'TempSpeed = CSng(CountTransitions (15, 40.0 ))

TempSpeed = 95.0
'- this value is for test purpose in the
'- dashboard only. This should be removed
'- in final code once CountTransitions is done

'TargetSpeed = FixI(TempSpeed*2.836364)
'- total necessary steps = 624, from 0km/h
'- up to 220km/h. So this represents
'- a conversion factor of 624/220 = 2.836364
'- but in the real testing, for better
'- accuracy, was used just 2.88 as bellow

TargetSpeed = FixI(TempSpeed*2.88)
Debug.Print "speed= " ; CStr(TempSpeed)
If (TargetSpeed > NeedlePos) Then
Call MoveNeedleUp ( TargetSpeed , NeedlePos, CurrentStep)
'speed higher than needle position
'uses the sub procedure to make needle up
'NeddlePos = current needle position
'TargetSpeed = desired speed for needle position
End If
If (TargetSpeed < NeedlePos) Then
Call MoveNeedleDown ( TargetSpeed , NeedlePos, CurrentStep)
'speed lower than needle position
'uses the sub procedure to make needle down
'NeddlePos = current needle position
'TargetSpeed = desired speed for needle position
End If
OnOffIgnition = GetPin(13)
Loop

TempSpeed = 0.0
TargetSpeed = FixI(TempSpeed*2.88)
Debug.Print "speed= " ; CStr(TempSpeed)
If (TargetSpeed > NeedlePos) Then
Call MoveNeedleUp ( TargetSpeed , NeedlePos, CurrentStep)

End If
If (TargetSpeed < NeedlePos) Then
Call MoveNeedleDown ( TargetSpeed , NeedlePos, CurrentStep)
End If
Goto POWER_LOOP
End Sub

--- In b..., "Richard Friedrich" wrote:
>
> f/v are nice since it simplifies your programming. Also the LM2917 chip
> goes to zero with zero input - this saves hassle of dealing with
> overruns on very slow rotations.
>
>
>
>
>
> Richard
>
>
>
> From: b... [mailto:b...] On Behalf
> Of ericksoliveira
> Sent: Sunday, November 21, 2010 8:25 PM
> To: b...
> Subject: [BasicX] Help with Speedometer using stepper motor and BX24
>
>
>
>
>
> I would like to ask some help here.
> I have a personal car project (mix of track and street use) and would
> like to build my own dashboard.
> I know most of people would recommend to use a regular 7-segment display
> for speedometer . However I want to keep the traditional look of analog
> speedo with needle style. However the stepper motor offers high
> precision.
> I built a simple circuit with BX24 and Swisstec X25 stepper motor and
> started playing with. It works fine.
> Now I would like to ask for some help:
> - any suggestion on which kind of circuit should I use to read the
> gearbox electronic speedo sensor signal? I know it is a square wave
> which modulates frequency according the speed. I believe most cars are
> like this. I don't have any idea on how to connect the speedo signal and
> process that data. Should I do a frequency-to-voltage converter? Or any
> other idea? Or should I use just the BX24 to count pulses and make all
> data processing to convert to the speedo signal information into pulses
> for the stepper motor?
> - any suggestion on software code to properly move the stepper motor
> according the car speed? Should I do some internal register in software
> so I know exactly where the needle is in the dash? I mean, should I
> always know where the needle is exactly and how much up/down movement it
> is necessary as next step? Because I need to control clockwise and
> counter clockwise movements.
> Any suggestion on how to proceed with this project?
> Here is the simple code I did just to test the stepper motor and confirm
> that basic circuit is working fine.
>
> -----------Option Explicit
> Public Sub Main()
> Dim n as integerConst M1 as Byte = 12 'this is the pin to drive Motor
> Pin1Const M2 as Byte = 11 'this is the pin to drive Motor
> Pin2=Pin3Const M4 as Byte = 10 'this is the pin to drive Motor
> Pin4Const POn as Byte = 0 'NOR port working as inverter, so the logic
> should be inverted.This case "Pulse On=0"Const POff as Byte = 1 'This
> case "Pulse Off=1"
> 'simple testing
> for n = 1 to 50'#1 Call PulseOut(M1, 0.002, POn ) 'M1=1 after NOR ( =
> inverter) Call PulseOut(M2, 0.002, POff) 'M2=0 after NOR ( =
> inverter) Call PulseOut(M4, 0.002, POn ) 'M4=1 after NOR ( =
> inverter) '#2 Call PulseOut(M1, 0.002, POn ) 'M1=1 after NOR ( =
> inverter) Call PulseOut(M2, 0.002, POff) 'M2=0 after NOR ( =
> inverter) Call PulseOut(M4, 0.002, POff) 'M4=0 after NOR ( =
> inverter) '#3 Call PulseOut(M1, 0.002, POn) 'M1=1 after NOR ( =
> inverter) Call PulseOut(M2, 0.002, POn) 'M2=1 after NOR ( = inverter)
> Call PulseOut(M4, 0.002, POff) 'M4=0 after NOR ( = inverter)'#4 Call
> PulseOut(M1, 0.002, POff) 'M1=0 after NOR ( = inverter) Call
> PulseOut(M2, 0.002, POn) 'M2=1 after NOR ( = inverter) Call
> PulseOut(M4, 0.002, POff) 'M4=0 after NOR ( = inverter)'#5 Call
> PulseOut(M1, 0.002, POff) 'M1=0 after NOR ( = inverter) Call
> PulseOut(M2, 0.002, POn) 'M2=1 after NOR ( = inverter) Call
> PulseOut(M4, 0.002, POn) 'M4=1 after NOR ( = inverter)'#6 Call
> PulseOut(M1, 0.002, POff) 'M1=0 after NOR ( = inverter) Call
> PulseOut(M2, 0.002, POff) 'M2=0 after NOR ( = inverter) Call
> PulseOut(M4, 0.002, POn) 'M4=1 after NOR ( = inverter) Next
> End Sub
> -----------
> Also the diagram for the stepper motor control circuit. As you can see,
> there is enough pins available for more implementation.
>
> http://i8.photobucket.com/albums/a10/ericksoares/swapeando/Schematic01.j
> \
> pg
> > jpg>
>
> Thanks
> Erick
>
>
>
>
>
>
>
>
>

Here is an example of a motorcycle display replacement I did. I used a BX24
to read the pulses from both the speed sensor and tach. This was fed into a
Parallax Propeller to do the graphics display. I used a 5" LCD display to
display the composite signal the Propeller outputted.

Here's a video of it running.
http://www.livevideo.com/video/AE6FB4F6991C418F80CD27CF8EEA4034/ultimate-mot

Thanks,

Jim

From: b... [mailto:b...] On Behalf Of
ericksoliveira
Sent: Sunday, November 21, 2010 9:25 PM
To: b...
Subject: [BasicX] Help with Speedometer using stepper motor and BX24

I would like to ask some help here.
I have a personal car project (mix of track and street use) and would
like to build my own dashboard.
I know most of people would recommend to use a regular 7-segment display
for speedometer . However I want to keep the traditional look of analog
speedo with needle style. However the stepper motor offers high
precision.
I built a simple circuit with BX24 and Swisstec X25 stepper motor and
started playing with. It works fine.
Now I would like to ask for some help:
- any suggestion on which kind of circuit should I use to read the
gearbox electronic speedo sensor signal? I know it is a square wave
which modulates frequency according the speed. I believe most cars are
like this. I don't have any idea on how to connect the speedo signal and
process that data. Should I do a frequency-to-voltage converter? Or any
other idea? Or should I use just the BX24 to count pulses and make all
data processing to convert to the speedo signal information into pulses
for the stepper motor?
- any suggestion on software code to properly move the stepper motor
according the car speed? Should I do some internal register in software
so I know exactly where the needle is in the dash? I mean, should I
always know where the needle is exactly and how much up/down movement it
is necessary as next step? Because I need to control clockwise and
counter clockwise movements.
Any suggestion on how to proceed with this project?
Here is the simple code I did just to test the stepper motor and confirm
that basic circuit is working fine.

-----------Option Explicit
Public Sub Main()
Dim n as integerConst M1 as Byte = 12 'this is the pin to drive Motor
Pin1Const M2 as Byte = 11 'this is the pin to drive Motor
Pin2=Pin3Const M4 as Byte = 10 'this is the pin to drive Motor
Pin4Const POn as Byte = 0 'NOR port working as inverter, so the logic
should be inverted.This case "Pulse On=0"Const POff as Byte = 1 'This
case "Pulse Off=1"
'simple testing
for n = 1 to 50'#1 Call PulseOut(M1, 0.002, POn ) 'M1=1 after NOR ( inverter) Call PulseOut(M2, 0.002, POff) 'M2=0 after NOR ( inverter) Call PulseOut(M4, 0.002, POn ) 'M4=1 after NOR ( inverter) '#2 Call PulseOut(M1, 0.002, POn ) 'M1=1 after NOR ( inverter) Call PulseOut(M2, 0.002, POff) 'M2=0 after NOR ( inverter) Call PulseOut(M4, 0.002, POff) 'M4=0 after NOR ( inverter) '#3 Call PulseOut(M1, 0.002, POn) 'M1=1 after NOR ( inverter) Call PulseOut(M2, 0.002, POn) 'M2=1 after NOR ( = inverter)
Call PulseOut(M4, 0.002, POff) 'M4=0 after NOR ( = inverter)'#4 Call
PulseOut(M1, 0.002, POff) 'M1=0 after NOR ( = inverter) Call
PulseOut(M2, 0.002, POn) 'M2=1 after NOR ( = inverter) Call
PulseOut(M4, 0.002, POff) 'M4=0 after NOR ( = inverter)'#5 Call
PulseOut(M1, 0.002, POff) 'M1=0 after NOR ( = inverter) Call
PulseOut(M2, 0.002, POn) 'M2=1 after NOR ( = inverter) Call
PulseOut(M4, 0.002, POn) 'M4=1 after NOR ( = inverter)'#6 Call
PulseOut(M1, 0.002, POff) 'M1=0 after NOR ( = inverter) Call
PulseOut(M2, 0.002, POff) 'M2=0 after NOR ( = inverter) Call
PulseOut(M4, 0.002, POn) 'M4=1 after NOR ( = inverter) Next
End Sub
-----------
Also the diagram for the stepper motor control circuit. As you can see,
there is enough pins available for more implementation.

http://i8.photobucket.com/albums/a10/ericksoares/swapeando/Schematic01.j\

pg

Thanks
Erick

Jim,
thanks for sharing your project and information. That is a really nice project... I was planning to do something based in a LCD screen but I gave up since I had no experience with that and also with the fact that I would like to keep the original dash. So now I will just control the stepper motor in the original dash.

Can you share your experience in getting the speed and tacho signal from sensor? what kind of command did you use? I'm planning to use the CountTransitions, but not sure if that is a good idea.

My car is OBD2 compliant but since I removed the ABS for the rallye/track purpose, I now don't have the original speedo. that's why I 'm doing this project to enable speedo.

Thanks

Erick

--- In b..., "Jim Fouch" wrote:
>
> Here is an example of a motorcycle display replacement I did. I used a BX24
> to read the pulses from both the speed sensor and tach. This was fed into a
> Parallax Propeller to do the graphics display. I used a 5" LCD display to
> display the composite signal the Propeller outputted.
>
>
>
> Here's a video of it running.
> http://www.livevideo.com/video/AE6FB4F6991C418F80CD27CF8EEA4034/ultimate-mot
>
>
>
> Thanks,
>
>
>
> Jim
>
>
>
> From: b... [mailto:b...] On Behalf Of
> ericksoliveira
> Sent: Sunday, November 21, 2010 9:25 PM
> To: b...
> Subject: [BasicX] Help with Speedometer using stepper motor and BX24
>
>
>
>
>
> I would like to ask some help here.
> I have a personal car project (mix of track and street use) and would
> like to build my own dashboard.
> I know most of people would recommend to use a regular 7-segment display
> for speedometer . However I want to keep the traditional look of analog
> speedo with needle style. However the stepper motor offers high
> precision.
> I built a simple circuit with BX24 and Swisstec X25 stepper motor and
> started playing with. It works fine.
> Now I would like to ask for some help:
> - any suggestion on which kind of circuit should I use to read the
> gearbox electronic speedo sensor signal? I know it is a square wave
> which modulates frequency according the speed. I believe most cars are
> like this. I don't have any idea on how to connect the speedo signal and
> process that data. Should I do a frequency-to-voltage converter? Or any
> other idea? Or should I use just the BX24 to count pulses and make all
> data processing to convert to the speedo signal information into pulses
> for the stepper motor?
> - any suggestion on software code to properly move the stepper motor
> according the car speed? Should I do some internal register in software
> so I know exactly where the needle is in the dash? I mean, should I
> always know where the needle is exactly and how much up/down movement it
> is necessary as next step? Because I need to control clockwise and
> counter clockwise movements.
> Any suggestion on how to proceed with this project?
> Here is the simple code I did just to test the stepper motor and confirm
> that basic circuit is working fine.
>
> Thanks
> Erick

Erick,

I'll have to dig up the code I used to create the BX24 portion of that
project. I think I just read the Pulse Width of each signal. Depending on
the resolution of the PulseWidth command, and the output of the speed sensor
you're trying to read. If the pulse width of the signal is too small for
PulseIn to accurately read, then you will need to switch to
CountTransitions. Each method has it's tradeoffs. Either one will tie up the
processor for a period of time while it's measuring. Another idea is to use
an Interrupt and Increment a counter and at a specific time measure and
reset the counter to zero.

With the Tach, the PulseIn will normally work well, because if the engine is
running you will always have a good short pulse. However, with the
speedometer, things get quite a bit different. Your pulses can remain at
zero when the vehicle is not moving, or you will have very long pulses when
it's moving very slowly. But, you will have to calculate how many
transitions you will have at max speed. In my case, my bike has a top speed
of 186MPH, so the pulses are coming at a very fast pace. The PulseIn
function has a resolution of 1.085us. So lets say you have a signal that has
a pulse width down to 1us. At max speed, you would not be able to measure
the signal with much accuracy.

I'll try to see if I can find my old source for the speed / tach display I
did years ago. Also, once you measure these two sensors, you can calculate
the gear also.

Here is another video I did using the BX24 and a BOB3 video overlay module..

It read the both the speed & Tach and then calculated the gear based on the
ratio between the two.

Thanks,

Jim

From: b... [mailto:b...] On Behalf Of
ericksoliveira
Sent: Monday, December 13, 2010 6:23 PM
To: b...
Subject: [BasicX] Re: Help with Speedometer using stepper motor and BX24

Jim,
thanks for sharing your project and information. That is a really nice
project... I was planning to do something based in a LCD screen but I gave
up since I had no experience with that and also with the fact that I would
like to keep the original dash. So now I will just control the stepper motor
in the original dash.

Can you share your experience in getting the speed and tacho signal from
sensor? what kind of command did you use? I'm planning to use the
CountTransitions, but not sure if that is a good idea.

My car is OBD2 compliant but since I removed the ABS for the rallye/track
purpose, I now don't have the original speedo. that's why I 'm doing this
project to enable speedo.

Thanks

Erick

--- In b... , "Jim
Fouch" wrote:
>
> Here is an example of a motorcycle display replacement I did. I used a
BX24
> to read the pulses from both the speed sensor and tach. This was fed into
a
> Parallax Propeller to do the graphics display. I used a 5" LCD display to
> display the composite signal the Propeller outputted.
>
> Here's a video of it running.
>
http://www.livevideo.com/video/AE6FB4F6991C418F80CD27CF8EEA4034/ultimate-mot
>
> Thanks,
>
> Jim
>
> From: b...
[mailto:b... ] On Behalf
Of
> ericksoliveira
> Sent: Sunday, November 21, 2010 9:25 PM
> To: b...
> Subject: [BasicX] Help with Speedometer using stepper motor and BX24
>
> I would like to ask some help here.
> I have a personal car project (mix of track and street use) and would
> like to build my own dashboard.
> I know most of people would recommend to use a regular 7-segment display
> for speedometer . However I want to keep the traditional look of analog
> speedo with needle style. However the stepper motor offers high
> precision.
> I built a simple circuit with BX24 and Swisstec X25 stepper motor and
> started playing with. It works fine.
> Now I would like to ask for some help:
> - any suggestion on which kind of circuit should I use to read the
> gearbox electronic speedo sensor signal? I know it is a square wave
> which modulates frequency according the speed. I believe most cars are
> like this. I don't have any idea on how to connect the speedo signal and
> process that data. Should I do a frequency-to-voltage converter? Or any
> other idea? Or should I use just the BX24 to count pulses and make all
> data processing to convert to the speedo signal information into pulses
> for the stepper motor?
> - any suggestion on software code to properly move the stepper motor
> according the car speed? Should I do some internal register in software
> so I know exactly where the needle is in the dash? I mean, should I
> always know where the needle is exactly and how much up/down movement it
> is necessary as next step? Because I need to control clockwise and
> counter clockwise movements.
> Any suggestion on how to proceed with this project?
> Here is the simple code I did just to test the stepper motor and confirm
> that basic circuit is working fine.
>
> Thanks
> Erick

Thanks for everyone help so far.

I could build the circuit and install into my car. After some fine tuning into the constants, it is working with a good accuracy for speedo.

My only problem now:
The stepper motor is too fast and also the gearbox sensor reading... so if I let the BX24 to read the input signal from the gearbox sensor (either using PulseWidth or CountTransitions) the needle in the speedo is moving too fast back and forth. That happens because once the data comes, it is not being processed or filtered anyway. It just send to the stepper motor...

I believe I should process and filter the data somehow.

My original program was reading the sensor in a 0.1s basis, so 10 samples / second. I kept the rate, but was doing an average from 5 samples. So stepper motor went down to 2 samples/s ( 0.5seconds / interval).

My experience so far:
- if I let the software to read sensor signal and send to stepper motor, the needle is moving back and forth, with some big movements up and down. It is not a linear and smooth movement.
- I then tried reading 5 samples and making and average to send to the dashboard. Now at least the needle is not going up and down so quick and crazy... But the movement is not smooth yet.

Any suggestion about how I could process the data to have a linear and smooth needle movement?

Here is a link with the video for the final setup: it has my project running and by the end of the video I recorded another car as an example to show the smooth movement that I expect for the needle.

Video:

Here is the software code without the average for 5 samples :

Option Explicit

Const M1 as Byte = 12
Const M2 as Byte = 11
Const M4 as Byte = 10
Const POn as Byte = 0
Const POff as Byte = 1
'--------------------
Public Sub MoveNeedleUp ( ByRef NSpeed as Integer, ByRef NNeedlePos As Integer, ByRef NStep as Byte)

LOOP_UP:
If (NStep=6) Then
'Step #1
NStep=1
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POn ) 'M1=1 ap inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 ap inversor
Call PulseOut(M4, 0.001, POn ) 'M3=1 ap inversor
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=1) Then
'Step #2
NStep=2
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POn ) 'M1=1 ap inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 ap inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 ap inversor
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=2) Then
'Step #3
NStep=3
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POn) 'M1=1 ap inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 ap inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 ap inversor
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=3) Then
'Step #4
NStep=4
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POff) 'M1=0 ap inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 ap inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 ap inversor
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=4) Then
'Step #5
NStep=5
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POff) 'M1=0 ap inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 ap inversor
Call PulseOut(M4, 0.001, POn) 'M3=1 ap inversor
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=5) Then
'Step #6
NStep=6
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POff) 'M1=0 ap inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 ap inversor
Call PulseOut(M4, 0.001, POn) 'M3=1 ap inversor
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
If (NNeedlePos<>NSpeed) Then
Goto LOOP_UP
End if
End If

LOOP_UP_END:
End Sub

'--------------------

Public Sub MoveNeedleDown ( ByRef NSpeed as Integer, ByRef NNeedlePos As Integer, ByRef NStep as Byte)

LOOP_DOWN:
If (NStep=1) Then
'Step #6
NStep=6
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn) 'M3=1
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End If

If (NStep=6) Then
'Step #5
NStep=5
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POn) 'M3=1
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End If

If (NStep=5) Then
'Step #4
NStep=4
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End if

If (NStep=4) Then
'Step #3
NStep=3
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POn) 'M1=1
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End if

If (NStep=3) Then
'Step #2
NStep=2
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POff) 'M3=0
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End if

If (NStep=2) Then
'Step #1
NStep=1
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn ) 'M3=1
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
If (NNeedlePos<>NSpeed) Then
Goto LOOP_DOWN
End if
End if

LOOP_DOWN_END:

End Sub

'--------------------

Public Sub StartupDash ()
Dim n As Integer
'START force to go to initial state --0
For n = 1 to 10
'#6
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn) 'M3=1
'#5
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POn) 'M3=1
'#4
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
'#3
Call PulseOut(M1, 0.001, POn) 'M1=1
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
'#2
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POff) 'M3=0
'#1
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn ) 'M3=1
Next

'WAKE UP to 220km/h
for n = 1 to 106
'#1
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn ) 'M3=1
'#2
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POff) 'M3=0
'#3
Call PulseOut(M1, 0.001, POn) 'M1=1
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
'#4
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
'#5
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POn) 'M3=1
'#6
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn) 'M3=1
Next

'WAKE UP DOWN to 0km/h
For n = 1 to 104

'#6
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn) 'M3=1
'#5
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POn) 'M3=1
'#4
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
'#3
Call PulseOut(M1, 0.001, POn) 'M1=1
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
'#2
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POff) 'M3=0
'#1
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn ) 'M3=1
Next
End Sub
'--------------------
Public Sub Main()
Dim TargetSpeed as Integer 'speed value as target for needle
Dim NeedlePos as Integer 'NeedlePos 0=0km/h to 612=220km/h
Dim CurrentStep as Byte 'Step 1 to 6 for step motor/neddle
Dim TempSpeed as Single 'speed from sensor input
Dim OnOffLogic as Byte 'logic to enable main program loop
Dim PulseWidth as Single '
Dim T as Single
Dim PulsePerSec as Single
Dim TireCircunf as Single
Dim RevsPerKm as Single
Dim PPK as Single
Dim PulsePerREV as Single
Dim REVperSec as Single
Dim Space as Single

Call StartupDash ()
TargetSpeed = 0
NeedlePos = 0
CurrentStep = 6
Call PutPin (13, bxInputPullup) 'from here on values are for calibration
TireCircunf=1.8096 '195/50R15= 1.8096m or 205/40R17= 1.8718m
REVsPerKm = 1000.0/TireCircunf ' 1000m / tire circunference
PPK = 5478.0 'pulses per Km with 195/50R15 tire
PulsePerREV = PPK/REVsPerKm ' Pulses Per tire Revolution

POWER_LOOP:
Call PulseIn(13,1,PulseWidth) 'measure pulse width for tH
T= PulseWidth*2.0 'assumes tH=tL and T=th+tl
PulsePerSec = 1.0/T 'pulses qty = pulses frequency
REVperSec = PulsePerSec/PulsePerREV 'revolutions per second
Space = TireCircunf* REVperSec 'results in m/s
TempSpeed = Space * 3.6 ' results in km/h

TargetSpeed = FixI(TempSpeed*2.88)
If (TargetSpeed > NeedlePos) Then
Call MoveNeedleUp ( TargetSpeed , NeedlePos, CurrentStep)
'procedure to move needle up
'in case needle target speed is bigger than
'current needle position
'NeddlePos = current needle position
'TargetSpeed = desired needle position based on speed
End If
If (TargetSpeed < NeedlePos) Then
Call MoveNeedleDown ( TargetSpeed , NeedlePos, CurrentStep)
'procedure to move needle down
'in case needle target speed is lower than
'current needle position
'NeddlePos = current needle position
'TargetSpeed = desired needle position based on speed

End If

Goto POWER_LOOP
End Sub

Hi,
How do you read the speed from the gearbox? Are you using a magnetic pickup ? Did you check it for noises?
It is possible that the reading from the sensor is noisy that will make the reading like you described it. If you are reading the sensor from a pickup sensor is good idea to use a schmitt trigger like the 7414. It will square the signal coming from the sensor. Check the spec. for the 7414.

Regards,
rosarite

-----Original Message-----
From: ericksoliveira
To: basicx
Sent: Sat, Jan 8, 2011 9:31 pm
Subject: [BasicX] Re: Help with Speedometer using stepper motor and BX24

Thanks for everyone help so far.

I could build the circuit and install into my car. After some fine tuning into the constants, it is working with a good accuracy for speedo.

My only problem now:
The stepper motor is too fast and also the gearbox sensor reading... so if I let the BX24 to read the input signal from the gearbox sensor (either using PulseWidth or CountTransitions) the needle in the speedo is moving too fast back and forth. That happens because once the data comes, it is not being processed or filtered anyway. It just send to the stepper motor...

I believe I should process and filter the data somehow.

My original program was reading the sensor in a 0.1s basis, so 10 samples / second. I kept the rate, but was doing an average from 5 samples. So stepper motor went down to 2 samples/s ( 0.5seconds / interval).

My experience so far:
- if I let the software to read sensor signal and send to stepper motor, the needle is moving back and forth, with some big movements up and down. It is not a linear and smooth movement.
- I then tried reading 5 samples and making and average to send to the dashboard. Now at least the needle is not going up and down so quick and crazy... But the movement is not smooth yet.

Any suggestion about how I could process the data to have a linear and smooth needle movement?

Here is a link with the video for the final setup: it has my project running and by the end of the video I recorded another car as an example to show the smooth movement that I expect for the needle.

Video:

Here is the software code without the average for 5 samples :

Option Explicit

Const M1 as Byte = 12
Const M2 as Byte = 11
Const M4 as Byte = 10
Const POn as Byte = 0
Const POff as Byte = 1

'--------------------
Public Sub MoveNeedleUp ( ByRef NSpeed as Integer, ByRef NNeedlePos As Integer, ByRef NStep as Byte)

LOOP_UP:
If (NStep=6) Then
'Step #1
NStep=1
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POn ) 'M1=1 após inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 após inversor
Call PulseOut(M4, 0.001, POn ) 'M3=1 após inversor
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=1) Then
'Step #2
NStep=2
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POn ) 'M1=1 após inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 após inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 após inversor
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=2) Then
'Step #3
NStep=3
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POn) 'M1=1 após inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 após inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 após inversor
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=3) Then
'Step #4
NStep=4
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POff) 'M1=0 após inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 após inversor
Call PulseOut(M4, 0.001, POff) 'M3=0 após inversor
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=4) Then
'Step #5
NStep=5
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POff) 'M1=0 após inversor
Call PulseOut(M2, 0.001, POn) 'M2=1 após inversor
Call PulseOut(M4, 0.001, POn) 'M3=1 após inversor
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
End If

If(NStep=5) Then
'Step #6
NStep=6
NNeedlePos=NNeedlePos+1
Call PulseOut(M1, 0.001, POff) 'M1=0 após inversor
Call PulseOut(M2, 0.001, POff) 'M2=0 após inversor
Call PulseOut(M4, 0.001, POn) 'M3=1 após inversor
If (NNeedlePos=NSpeed) Then
Goto LOOP_UP_END
End if
If (NNeedlePos<>NSpeed) Then
Goto LOOP_UP
End if
End If

LOOP_UP_END:
End Sub

'--------------------

Public Sub MoveNeedleDown ( ByRef NSpeed as Integer, ByRef NNeedlePos As Integer, ByRef NStep as Byte)

LOOP_DOWN:
If (NStep=1) Then
'Step #6
NStep=6
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn) 'M3=1
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End If

If (NStep=6) Then
'Step #5
NStep=5
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POn) 'M3=1
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End If

If (NStep=5) Then
'Step #4
NStep=4
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End if

If (NStep=4) Then
'Step #3
NStep=3
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POn) 'M1=1
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End if

If (NStep=3) Then
'Step #2
NStep=2
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POff) 'M3=0
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
End if

If (NStep=2) Then
'Step #1
NStep=1
NNeedlePos=NNeedlePos-1
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn ) 'M3=1
If (NNeedlePos=NSpeed) Then
Goto LOOP_DOWN_END
End if
If (NNeedlePos<>NSpeed) Then
Goto LOOP_DOWN
End if
End if

LOOP_DOWN_END:

End Sub

'--------------------

Public Sub StartupDash ()
Dim n As Integer
'START force to go to initial state --0
For n = 1 to 10
'#6
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn) 'M3=1
'#5
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POn) 'M3=1
'#4
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
'#3
Call PulseOut(M1, 0.001, POn) 'M1=1
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
'#2
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POff) 'M3=0
'#1
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn ) 'M3=1
Next

'WAKE UP to 220km/h
for n = 1 to 106
'#1
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn ) 'M3=1
'#2
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POff) 'M3=0
'#3
Call PulseOut(M1, 0.001, POn) 'M1=1
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
'#4
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
'#5
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POn) 'M3=1
'#6
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn) 'M3=1
Next

'WAKE UP DOWN to 0km/h
For n = 1 to 104

'#6
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn) 'M3=1
'#5
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POn) 'M3=1
'#4
Call PulseOut(M1, 0.001, POff) 'M1=0
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
'#3
Call PulseOut(M1, 0.001, POn) 'M1=1
Call PulseOut(M2, 0.001, POn) 'M2=1
Call PulseOut(M4, 0.001, POff) 'M3=0
'#2
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POff) 'M3=0
'#1
Call PulseOut(M1, 0.001, POn ) 'M1=1
Call PulseOut(M2, 0.001, POff) 'M2=0
Call PulseOut(M4, 0.001, POn ) 'M3=1
Next
End Sub

'--------------------
Public Sub Main()
Dim TargetSpeed as Integer 'speed value as target for needle
Dim NeedlePos as Integer 'NeedlePos 0=0km/h to 612=220km/h
Dim CurrentStep as Byte 'Step 1 to 6 for step motor/neddle
Dim TempSpeed as Single 'speed from sensor input
Dim OnOffLogic as Byte 'logic to enable main program loop
Dim PulseWidth as Single '
Dim T as Single
Dim PulsePerSec as Single
Dim TireCircunf as Single
Dim RevsPerKm as Single
Dim PPK as Single
Dim PulsePerREV as Single
Dim REVperSec as Single
Dim Space as Single

Call StartupDash ()
TargetSpeed = 0
NeedlePos = 0
CurrentStep = 6
Call PutPin (13, bxInputPullup) 'from here on values are for calibration
TireCircunf=1.8096 '195/50R15= 1.8096m or 205/40R17= 1.8718m
REVsPerKm = 1000.0/TireCircunf ' 1000m / tire circunference
PPK = 5478.0 'pulses per Km with 195/50R15 tire
PulsePerREV = PPK/REVsPerKm ' Pulses Per tire Revolution

POWER_LOOP:
Call PulseIn(13,1,PulseWidth) 'measure pulse width for tH
T= PulseWidth*2.0 'assumes tH=tL and T=th+tl
PulsePerSec = 1.0/T 'pulses qty = pulses frequency
REVperSec = PulsePerSec/PulsePerREV 'revolutions per second
Space = TireCircunf* REVperSec 'results in m/s
TempSpeed = Space * 3.6 ' results in km/h

TargetSpeed = FixI(TempSpeed*2.88)
If (TargetSpeed > NeedlePos) Then
Call MoveNeedleUp ( TargetSpeed , NeedlePos, CurrentStep)
'procedure to move needle up
'in case needle target speed is bigger than
'current needle position
'NeddlePos = current needle position
'TargetSpeed = desired needle position based on speed
End If
If (TargetSpeed < NeedlePos) Then
Call MoveNeedleDown ( TargetSpeed , NeedlePos, CurrentStep)
'procedure to move needle down
'in case needle target speed is lower than
'current needle position
'NeddlePos = current needle position
'TargetSpeed = desired needle position based on speed

End If

Goto POWER_LOOP
End Sub