Help with Speedometer using stepper motor and BX24

Started by ericksoliveira November 21, 2010
Thanks for your help.

I'm using the original speed sensor used by the car. It is installed at the gearbox and it has a gear which generates the signal for speed sensor. I didn't install any magnetic or additional sensor.

The original sensor sends the electric signal to the Built-In System Interface Box, which is in charge to control all peripherals and electronic signals. So I decided to use it instead of installing a new one.

I don't have any oscilloscope here. So I did the inverter amplifier circuit based in the information that the sensor generates a square wave.

I drove for 4km a few times and checked the CountTransitions, which in all cases were close to 5030 or 5033 transitions. So I know that noise was not creating such a disturbance.

Do you think that the schmitt trigger would help ?

If you have any suggestions, please let me know.

thanks

Erick

--- In b..., rosarite@... wrote:
>
> 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:
> http://s8.photobucket.com/albums/a10/ericksoares/swapeando/?action=view&current=painel307commotordepasso-editado.mp4
>
> 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)
> Debug.Print "velocidade= " ; CStr(TempSpeed)
> 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,
I think you can check for noisy sensor by running the car at a constant speed and see if the reading is steady. Repeat the test at different speeds. Normally the ecu of the car has some filter to clean it. Sometime they clean it with software filter or with a hardware filter. I know that your reading counts are constants. One suggestion is to try to save the last speed reading and find the difference from the new reading and then output the difference in steps.
Do not send immediately to the new display. Also when sending the steps command add a delay between steps so the needle do not jump. Adjust the delay as necessary. Can you explain how do you display the speed. Do you send to the stepper to display the new speed from zero or you send it from the difference of the last speed display?

I checked your video but I can not see which one is the speed display. You have two display. I noticed the one from the left is not moving steady but the one at the right is not moving too fast. Which is the speed display?
Regards,
rosarite






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



Thanks for your help.

I'm using the original speed sensor used by the car. It is installed at the gearbox and it has a gear which generates the signal for speed sensor. I didn't install any magnetic or additional sensor.

The original sensor sends the electric signal to the Built-In System Interface Box, which is in charge to control all peripherals and electronic signals. So I decided to use it instead of installing a new one.

I don't have any oscilloscope here. So I did the inverter amplifier circuit based in the information that the sensor generates a square wave.

I drove for 4km a few times and checked the CountTransitions, which in all cases were close to 5030 or 5033 transitions. So I know that noise was not creating such a disturbance.

Do you think that the schmitt trigger would help ?

If you have any suggestions, please let me know.

thanks

Erick

--- In b..., rosarite@... wrote:
>
> 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:
> http://s8.photobucket.com/albums/a10/ericksoares/swapeando/?action=view&current=painel307commotordepasso-editado.mp4
>
> 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)
> Debug.Print "velocidade= " ; CStr(TempSpeed)
> 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
>
>
>
>
>
>
>
>
>
>
>







I believe that you may have used the wrong actuator. A stepper motor is only able to resolve 1.8 degrees of resolution. That is one of the reasons that you see choppy movement. For example it jumps between 18 and 20 kph that looks like around 1.8 degrees. Also it looks exceptionally bad and choppy when the speed is changing slowly. The problem is much less prominent when the speed changes rapidly.



This is one reason that I suggested a servo instead of a stepper motor. Servos are very cheap and they have 180 degrees/1024 = .175 degrees resolution per position, this is 10 times better than 1.8 degrees.



Having said that I believe that some filtering (like a weighted moving average) would improve your display.





Richard







From: b... [mailto:b...] On Behalf Of ericksoliveira
Sent: Sunday, January 09, 2011 7:01 PM
To: b...
Subject: [BasicX] Re: Help with Speedometer using stepper motor and BX24





Thanks for your help.

I'm using the original speed sensor used by the car. It is installed at the gearbox and it has a gear which generates the signal for speed sensor. I didn't install any magnetic or additional sensor.

The original sensor sends the electric signal to the Built-In System Interface Box, which is in charge to control all peripherals and electronic signals. So I decided to use it instead of installing a new one.

I don't have any oscilloscope here. So I did the inverter amplifier circuit based in the information that the sensor generates a square wave.

I drove for 4km a few times and checked the CountTransitions, which in all cases were close to 5030 or 5033 transitions. So I know that noise was not creating such a disturbance.

Do you think that the schmitt trigger would help ?

If you have any suggestions, please let me know.

thanks

Erick

--- In b... , rosarite@... wrote:
>
> 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:
> http://s8.photobucket.com/albums/a10/ericksoares/swapeando/?action=view&current=painel307commotordepasso-editado.mp4
>
> 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)
> Debug.Print "velocidade= " ; CStr(TempSpeed)
> 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
>
>
>
>
>
>
>
>
>
>
>



O yes , I forgot. Another thing to try is to read the speed continuously, say 100-200 times a second then average it. Make updates to the needle positions 3 or 4 times a second.



Substitute a frequency generator or function generator for the transmission sensor while testing. One can be made out of a 555 chip .

You can then tweak your code without driving around.





richard





From: b... [mailto:b...] On Behalf Of Richard Friedrich
Sent: Monday, January 10, 2011 8:56 AM
To: b...
Subject: RE: [BasicX] Re: Help with Speedometer using stepper motor and BX24





I believe that you may have used the wrong actuator. A stepper motor is only able to resolve 1.8 degrees of resolution. That is one of the reasons that you see choppy movement. For example it jumps between 18 and 20 kph that looks like around 1.8 degrees. Also it looks exceptionally bad and choppy when the speed is changing slowly. The problem is much less prominent when the speed changes rapidly.

This is one reason that I suggested a servo instead of a stepper motor. Servos are very cheap and they have 180 degrees/1024 = .175 degrees resolution per position, this is 10 times better than 1.8 degrees.

Having said that I believe that some filtering (like a weighted moving average) would improve your display.

Richard

From: b... [mailto:basi... ] On Behalf Of ericksoliveira
Sent: Sunday, January 09, 2011 7:01 PM
To: b...
Subject: [BasicX] Re: Help with Speedometer using stepper motor and BX24

Thanks for your help.

I'm using the original speed sensor used by the car. It is installed at the gearbox and it has a gear which generates the signal for speed sensor. I didn't install any magnetic or additional sensor.

The original sensor sends the electric signal to the Built-In System Interface Box, which is in charge to control all peripherals and electronic signals. So I decided to use it instead of installing a new one.

I don't have any oscilloscope here. So I did the inverter amplifier circuit based in the information that the sensor generates a square wave.

I drove for 4km a few times and checked the CountTransitions, which in all cases were close to 5030 or 5033 transitions. So I know that noise was not creating such a disturbance.

Do you think that the schmitt trigger would help ?

If you have any suggestions, please let me know.

thanks

Erick

--- In b... , rosarite@... wrote:
>
> 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:
> http://s8.photobucket.com/albums/a10/ericksoares/swapeando/?action=view&current=painel307commotordepasso-editado.mp4
>
> 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)
> Debug.Print "velocidade= " ; CStr(TempSpeed)
> 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
>
>
>
>
>
>
>
>
>
>
>





Richard,

thanks for your suggestion. I will try to find a signal generator or build a simple one for the tests.

I'm building this project as a personal hobby at home, so I don't have all the tools that I should in order to test it properly (oscilloscope, signal generator).

For reference, the wider pulse width is close to 70ms for the speed signal coming from the sensor. So in the best case I could read close to 14 samples per second for the speed.

Erick

--- In b..., "Richard Friedrich" wrote:
>
> O yes , I forgot. Another thing to try is to read the speed continuously, say 100-200 times a second then average it. Make updates to the needle positions 3 or 4 times a second.
>
>
>
> Substitute a frequency generator or function generator for the transmission sensor while testing. One can be made out of a 555 chip .
>
> You can then tweak your code without driving around.
>
>
>
>
>
> richard
>
>
>
>
>
> From: b... [mailto:b...] On Behalf Of Richard Friedrich
> Sent: Monday, January 10, 2011 8:56 AM
> To: b...
> Subject: RE: [BasicX] Re: Help with Speedometer using stepper motor and BX24
>
>
>
>
>
> I believe that you may have used the wrong actuator. A stepper motor is only able to resolve 1.8 degrees of resolution. That is one of the reasons that you see choppy movement. For example it jumps between 18 and 20 kph that looks like around 1.8 degrees. Also it looks exceptionally bad and choppy when the speed is changing slowly. The problem is much less prominent when the speed changes rapidly.
>
> This is one reason that I suggested a servo instead of a stepper motor. Servos are very cheap and they have 180 degrees/1024 = .175 degrees resolution per position, this is 10 times better than 1.8 degrees.
>
> Having said that I believe that some filtering (like a weighted moving average) would improve your display.
>
> Richard
>
> From: b... [mailto:b... ] On Behalf Of ericksoliveira
> Sent: Sunday, January 09, 2011 7:01 PM
> To: b...
> Subject: [BasicX] Re: Help with Speedometer using stepper motor and BX24
>
> Thanks for your help.
>
> I'm using the original speed sensor used by the car. It is installed at the gearbox and it has a gear which generates the signal for speed sensor. I didn't install any magnetic or additional sensor.
>
> The original sensor sends the electric signal to the Built-In System Interface Box, which is in charge to control all peripherals and electronic signals. So I decided to use it instead of installing a new one.
>
> I don't have any oscilloscope here. So I did the inverter amplifier circuit based in the information that the sensor generates a square wave.
>
> I drove for 4km a few times and checked the CountTransitions, which in all cases were close to 5030 or 5033 transitions. So I know that noise was not creating such a disturbance.
>
> Do you think that the schmitt trigger would help ?
>
> If you have any suggestions, please let me know.
>
> thanks
>
> Erick
>
> --- In b... , rosarite@ wrote:
> >
> > 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
> >
> >
> >
> >
> >
> >
> >
> >
> >

Richard,

thanks for your comment. I got your point.

Let me give your further information: I used the same stepper motor as the original one used in the dashboard for RPM and speedo. That specific motor is a hi-precision:
- high 1/4-step resolution: 1/12 degree
- 1/3 degree step resolution

So it is capable of a good accuracy. I could test my software in a random test and it could go to the proper speed position with high precision.

Can you recommend any small servo motor which I could use for testing purposes if I can't make it better with the stepper motor ?

About your suggestion, where can I find further details about the filtering by using weighted moving average?

Thanks

Erick

--- In b..., "Richard Friedrich" wrote:
>
> I believe that you may have used the wrong actuator. A stepper motor is only able to resolve 1.8 degrees of resolution. That is one of the reasons that you see choppy movement. For example it jumps between 18 and 20 kph that looks like around 1.8 degrees. Also it looks exceptionally bad and choppy when the speed is changing slowly. The problem is much less prominent when the speed changes rapidly.
>
>
>
> This is one reason that I suggested a servo instead of a stepper motor. Servos are very cheap and they have 180 degrees/1024 = .175 degrees resolution per position, this is 10 times better than 1.8 degrees.
>
>
>
> Having said that I believe that some filtering (like a weighted moving average) would improve your display.
>
>
>
>
>
> Richard
>
>
>
>
>
>
>
> From: b... [mailto:b...] On Behalf Of ericksoliveira
> Sent: Sunday, January 09, 2011 7:01 PM
> To: b...
> Subject: [BasicX] Re: Help with Speedometer using stepper motor and BX24
>
>
>
>
>
> Thanks for your help.
>
> I'm using the original speed sensor used by the car. It is installed at the gearbox and it has a gear which generates the signal for speed sensor. I didn't install any magnetic or additional sensor.
>
> The original sensor sends the electric signal to the Built-In System Interface Box, which is in charge to control all peripherals and electronic signals. So I decided to use it instead of installing a new one.
>
> I don't have any oscilloscope here. So I did the inverter amplifier circuit based in the information that the sensor generates a square wave.
>
> I drove for 4km a few times and checked the CountTransitions, which in all cases were close to 5030 or 5033 transitions. So I know that noise was not creating such a disturbance.
>
> Do you think that the schmitt trigger would help ?
>
> If you have any suggestions, please let me know.
>
> thanks
>
> Erick
>
> --- In b... , rosarite@ wrote:
> >
> > 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:
> > http://s8.photobucket.com/albums/a10/ericksoares/swapeando/?action=view&current=painel307commotordepasso-editado.mp4
> >
> > 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)
> > Debug.Print "velocidade= " ; CStr(TempSpeed)
> > 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,
Thanks for your feedback and suggestions.

Very good suggestions . I will check it. Maybe I will be able to check if pulse count is steady or not. If not, I will be able to find how to filter it.

I believe that sending the speed as steps maybe an alternative solution. I will also try to improve delay. Current software I send the stepper motor changes every 0.001second. So the stepper motor is really quickly moving.

Regarding how I'm sending the stepper motor to display, I'm not sending from zero. I always read current speed (from speed sensor) and move the stepper from last position (not zero) to the current speed. So it always send from different of the last speed display.

Regarding the video:
- the right big gauge is the speedometer which I implemented with the stepper motor. The left one is the original RPM from the car dashboard. If you check the video, the initial section (dark place with lights turned on) is just the startup which makes the speedo needle move from 0 to 220km/h and then go back. After this, the video shows the moving needle. You may see it moving too quickly. Maybe if I increase the delay for the stepper motor control, it will be smoother, as you mentioned.

Erick
--- In b..., rosarite@... wrote:
> Hi,
> I think you can check for noisy sensor by running the car at a constant speed and see if the reading is steady. Repeat the test at different speeds. Normally the ecu of the car has some filter to clean it. Sometime they clean it with software filter or with a hardware filter. I know that your reading counts are constants. One suggestion is to try to save the last speed reading and find the difference from the new reading and then output the difference in steps.
> Do not send immediately to the new display. Also when sending the steps command add a delay between steps so the needle do not jump. Adjust the delay as necessary. Can you explain how do you display the speed. Do you send to the stepper to display the new speed from zero or you send it from the difference of the last speed display?
>
> I checked your video but I can not see which one is the speed display. You have two display. I noticed the one from the left is not moving steady but the one at the right is not moving too fast. Which is the speed display?
> Regards,
> rosarite
>
>
>
>
>
>
> -----Original Message-----
> From: ericksoliveira
> To: basicx
> Sent: Sun, Jan 9, 2011 8:19 pm
> Subject: [BasicX] Re: Help with Speedometer using stepper motor and BX24
>
>
>
> Thanks for your help.
>
> I'm using the original speed sensor used by the car. It is installed at the gearbox and it has a gear which generates the signal for speed sensor. I didn't install any magnetic or additional sensor.
>
> The original sensor sends the electric signal to the Built-In System Interface Box, which is in charge to control all peripherals and electronic signals. So I decided to use it instead of installing a new one.
>
> I don't have any oscilloscope here. So I did the inverter amplifier circuit based in the information that the sensor generates a square wave.
>
> I drove for 4km a few times and checked the CountTransitions, which in all cases were close to 5030 or 5033 transitions. So I know that noise was not creating such a disturbance.
>
> Do you think that the schmitt trigger would help ?
>
> If you have any suggestions, please let me know.
>
> thanks
>
> Erick
>
> --- In b..., rosarite@ wrote:
> >
> > 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
> >
> >
> >
> >
> >
> >
> >