Reply by ericksoliveira January 10, 20112011-01-10
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
> >
> >
> >
> >
> >
> >
> >

Reply by ericksoliveira January 10, 20112011-01-10
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
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
>
>
>
>
>
>
>

Reply by ericksoliveira January 10, 20112011-01-10
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
> >
> >
> >
> >
> >
> >
> >
> >
> >

Reply by Richard Friedrich January 10, 20112011-01-10
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
>
>
>
>
>
>
>
>
>
>
>





Reply by Richard Friedrich January 10, 20112011-01-10
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
>
>
>
>
>
>
>
>
>
>
>



Reply by rosa...@aol.com January 10, 20112011-01-10
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
>
>
>
>
>
>
>
>
>
>
>







Reply by ericksoliveira January 9, 20112011-01-09
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
>
>
>
>
>
>
>
>
>
>
>

Reply by rosa...@aol.com January 9, 20112011-01-09
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







Reply by ericksoliveira January 8, 20112011-01-08
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 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)
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

Reply by Jim Fouch December 14, 20102010-12-14
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..
http://www.youtube.com/watch?v=x9RgtJbmpMo

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
> orcycle-gadget-ho.aspx
>
> 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