edo17982
07-12-2010, 06:58 AM
Edoardo
Excellent work and very impressive, especially with DC motors rather than servos
Well done
David
Thanks for your comment!
The easy part is about the motor itself as the gauge is already featuring small DC motors.
The hard part is to disassemble part of it and replace the syncros with pots which are not easy to find as for dimensions and shape. I found them on RS but are like more than 30€ each, luckily I got a lot over ebay for 60USD for 8 of them :)
The hard part of the code was about the barber pole as it is spring loaded to a position, so I needed to program the motor to stay in a given position applying the right force to it as a DC once reach a position is deactivaded and the spring woulded bring it back in a continuous loop.
Here is the code I made for AS indicator
Var 0000, Value 0
{
&ASControl = TIMER 999 ,0 ,2
&ASObj = 0
&ASMotor = 0
&SBControl = TIMER 999 ,0 ,2
&SBObj = 0
&SBMotor = 0
&BPControl = TIMER 999 ,0 ,2
&BPObj = 0
&BPMotor = 0
}
Var 0003, name ASMotor, static, Link USB_DCMOTOR, Device 2, Output 1 // motor control (0-127) 0=Left, +128 = Rig
Var 0006, name ASAd, static, Link USB_ANALOGIC, Device 2, Input 1, PosL 0, PosC 127, PosR 255 // Potentiometer value
Var 9001, name AirSpdOffst, Link FSUIPC_IN, Offset $02BC, Length 4
{
L0 = &AirSpdOffst / 128 // FSUIPC conversion, L0=AirSpd
&AirSpd = L0
L0 = ABS L0
L2 = L0
IF L0 <= 59 // First sector
{
L1 = 0 // pot 0
}
ELSE
{
L2 = L0 - 59
IF L0 <= 80 // Second sector
{
L1 = L2 / 1.25 // pot 17
L1 = L1 + 0
}
ELSE
{
L2 = L0 - 80
IF L0 <= 250 // Third Sector
{
L1 = L2 / 1.0119 // pot 185
L1 = L1 + 17
}
ELSE
{
L2 = L0 - 250
IF L0 <= 450 // Fourth Sector
{
L1 = L2 / 3.125 // pot 249
L1 = L1 + 185
}
ELSE // Out of range
{
IF L0 > 450 // Fourth Sector
{
L1 = 250
}
}
}
}
}
&ASObj = L1
}
Var 9002, name AirSpd
Var 9004, name ASControl, Link SUBRUTINE // Subrutine for Control (each 20ms)
{
L0 = &ASObj - &ASAd
L1 = 0
IF L0 < 0
{
L1 = 128
}
L0 = ABS L0
L2 = &ASVelMax + L1
IF L0 <= &ASAprox8
{
L2 = &ASVel8 + L1
}
IF L0 <= &ASAprox6
{
L2 = &ASVel6 + L1
}
IF L0 <= &ASAprox4
{
L2 = &ASVel4 + L1
}
IF L0 <= &ASAprox2
{
L2 = &ASVel2 + L1
}
IF L0 <= &ASAproxSlow
{
L2 = &ASVelMin + L1
}
IF L0 = &ASMargen
{
L2 = 0
}
&ASMotor = L2
}
Var 9006, name ASObj // objective position (fixed in the example)
Var 9007, name ASMargen, Value 0 // %error
Var 9008, name ASAprox8, Value 15
Var 9009, name ASAprox6, Value 12
Var 9010, name ASAprox4, Value 8
Var 9011, name ASAprox2, Value 4
Var 9012, name ASAproxSlow, Value 1
Var 9013, name ASVelMax, Value 24 // Speed for follow objective
Var 9014, name ASVel8, Value 20 // Speed for proximity obj
Var 9015, name ASVel6, Value 16
Var 9016, name ASVel4, Value 12
Var 9017, name ASVel2, Value 8
Var 9018, name ASVelMin, Value 4 // Speed approaching target
Var 0004, name SBMotor, static, Link USB_DCMOTOR, Device 2, Output 2 // motor control (0-127) 0=Left, +128 = Rig
Var 0007, name SBAd, static, Link USB_ANALOGIC, Device 2, Input 2, PosL 0, PosC 127, PosR 255 // Potentiometer value
Var 9101, name SpdBugOffst, Link FSUIPC_IN, Offset $07E2, Length 2
{
L0 = &SpdBugOffst / 128 // FSUIPC conversion, L0=SpdBug
&SpdBug = L0
L0 = ABS L0
L2 = L0
IF L0 <= 100 // First sector
{
L1 = 36 // pot 36
}
ELSE
{
L2 = L0 - 100
IF L0 <= 250 // Second sector
{
L1 = L2 / 1.0274 // pot 182
L1 = L1 + 36
}
ELSE
{
L2 = L0 - 250
IF L0 <= 450 // Third Sector
{
L1 = L2 / 3.125 // pot 246
L1 = L1 + 182
}
ELSE // Out of range
{
IF L0 > 450 // Third Sector
{
L1 = 250
}
}
}
}
&SBObj = L1
}
Var 9104, name SBControl, Link SUBRUTINE // Subrutine for Control (each 20ms)
{
L0 = &SBObj - &SBAd
L1 = 0
IF L0 < 0
{
L1 = 128
}
L0 = ABS L0
L2 = &SBVelMax + L1
IF L0 <= &SBAprox8
{
L2 = &SBVel8 + L1
}
IF L0 <= &SBAprox6
{
L2 = &SBVel6 + L1
}
IF L0 <= &SBAprox4
{
L2 = &SBVel4 + L1
}
IF L0 <= &SBAprox2
{
L2 = &SBVel2 + L1
}
IF L0 <= &SBAproxSlow
{
L2 = &SBVelMin + L1
}
IF L0 = &SBMargen
{
L2 = 0
}
&SBMotor = L2
}
Var 9102, name SpdBug
Var 9106, name SBObj // objective position
Var 9107, name SBMargen, Value 0 // %error
Var 9108, name SBAprox8, Value 6
Var 9109, name SBAprox6, Value 4
Var 9110, name SBAprox4, Value 3
Var 9111, name SBAprox2, Value 2
Var 9112, name SBAproxSlow, Value 1
Var 9113, name SBVelMax, Value 60 // Speed for follow objective
Var 9114, name SBVel8, Value 40 // Speed for proximity obj
Var 9115, name SBVel6, Value 20
Var 9116, name SBVel4, Value 15
Var 9117, name SBVel2, Value 10
Var 9118, name SBVelMin, Value 13 // Speed approaching target
Var 0005, name BPMotor, static, Link USB_DCMOTOR, Device 2, Output 3 // motor control (0-127) 0=Left, +128 = Rig
Var 0008, name BPAd, static, Link USB_ANALOGIC, Device 2, Input 3, PosL 0, PosC 127, PosR 255 // Potentiometer value
Var 9201, name BarPolOffst, Link FSUIPC_IN, Offset $02BC, Length 4
{
L0 = &BarPolOffst // FSUIPC conversion, L0=BarPol
&BarPol = L0
L0 = ABS L0
L2 = L0
IF L0 <= 255 // First sector
{
L1 = 147
}
ELSE
{
L2 = L0 - 255
IF L0 <= 387 // Second sector
{
L1 = L2 / 3.1667 // pot 189
L1 = L1 + 147
}
ELSE // Out of range
{
IF L0 > 388 // Fourth Sector
{
L1 = 147
}
}
}
&BPObj = L1
}
Var 9202, name BarPol
Var 9204, name BPControl, Link SUBRUTINE // Subrutine for Control (each 20ms)
{
L0 = &BPObj - &BPAd
L1 = 0
IF L0 < 0
{
L1 = -25
L0 = &BPObj - &BPAd
L0 = ABS L0
IF L0 = 3
{
L1 = -20
}
ELSE
{
IF L0 = 2
{
L1 = -15
}
ELSE
{
IF L0 = 1
{
L1 = -10
}
}
}
}
L0 = ABS L1
IF &BPObj <= 147 // 255Kts
{
&BPVelMax = 20
&BPVelMin = 0
}
ELSE
{
IF &BPObj <= 152 // 270Kts
{
&BPVelMax = 58 + L1
&BPVelMin = 55 + L1
}
ELSE
{
IF &BPObj <= 155 // 280Kts
{
&BPVelMax = 60 + L1
&BPVelMin = 60 + L1
}
ELSE
{
IF &BPObj <= 158 // 290Kts
{
&BPVelMax = 62 + L1
&BPVelMin = 60 + L1
}
ELSE
{
IF &BPObj <= 161 // 300Kts
{
&BPVelMax = 64 + L1
&BPVelMin = 63 + L1
}
ELSE
{
IF &BPObj <= 164 // 310Kts
{
&BPVelMax = 66 + L1
&BPVelMin = 65 + L1
}
ELSE
{
IF &BPObj <= 167 // 320Kts
{
&BPVelMax = 68 + L1
&BPVelMin = 67 + L1
}
ELSE
{
IF &BPObj <= 170 // 330Kts
{
&BPVelMax = 70 + L1
&BPVelMin = 69 + L1
}
ELSE
{
IF &BPObj <= 173 // 340Kts
{
&BPVelMax = 72 + L1
&BPVelMin = 71 + L1
}
ELSE
{
IF &BPObj <= 176 // 350Kts
{
&BPVelMax = 74 + L1
&BPVelMin = 73 + L1
}
ELSE
{
IF &BPObj <= 179 // 360Kts
{
&BPVelMax = 76 + L1
&BPVelMin = 75 + L1
}
ELSE
{
IF &BPObj <= 183 // 370Kts
{
&BPVelMax = 80 + L1
&BPVelMin = 79 + L1
}
}
}
}
}
}
}
}
}
}
}
}
IF L0 <= &BPAprox
{
L2 = &BPVelMin
}
ELSE
{
L2 = &BPVelMax
}
IF L0 = &BPMargen
{
L2 = &BPVelMin
}
&BPMotor = L2
}
Var 9206, name BPObj // objective position
Var 9207, name BPMargen, Value 1 // %error
Var 9212, name BPAprox, Value 2 // Proximity Value
Var 9213, name BPVelMax, Value 0 // Speed for follow objective
Var 9218, name BPVelMin, Value 0 // Speed approaching target
Var 9301, name MachOffst, Link FSUIPC_IN, Offset $11C6, Length 2
{
L0 = &MachOffst / 20480 // FSUIPC conversion, L0=Mach Number
&D_MACH_U = MOD L0 ,10 // Mach Units Number
L0 = DIV L0 ,10
&D_MACH_T = MOD L0 ,10 // Mach Tenth Number
L0 = DIV L0 ,10
&D_MACH_H = MOD L0 ,10 // Mach Hundreds Number
}
Var 9302, name D_MACH_H
{
IF &D_MACH_H = 0
{
&Mach_H_0 = 1
&Mach_H_0 = DELAY 0 100
}
ELSE
{
&Mach_H_0 = 0
}
IF &D_MACH_H = 1
{
&Mach_H_1 = 1
&Mach_H_1 = DELAY 0 100
}
ELSE
{
&Mach_H_1 = 0
}
IF &D_MACH_H = 2
{
&Mach_H_2 = 1
&Mach_H_2 = DELAY 0 100
}
ELSE
{
&Mach_H_2 = 0
}
IF &D_MACH_H = 3
{
&Mach_H_3 = 1
&Mach_H_3 = DELAY 0 100
}
ELSE
{
&Mach_H_3 = 0
}
IF &D_MACH_H = 4
{
&Mach_H_4 = 1
&Mach_H_4 = DELAY 0 100
}
ELSE
{
&Mach_H_4 = 0
}
IF &D_MACH_H = 5
{
&Mach_H_5 = 1
&Mach_H_5 = DELAY 0 100
}
ELSE
{
&Mach_H_5 = 0
}
IF &D_MACH_H = 6
{
&Mach_H_6 = 1
&Mach_H_6 = DELAY 0 100
}
ELSE
{
&Mach_H_7 = 0
}
IF &D_MACH_H = 7
{
&Mach_H_7 = 1
&Mach_H_7 = DELAY 0 100
}
ELSE
{
&Mach_H_7 = 0
}
IF &D_MACH_H = 8
{
&Mach_H_8 = 1
&Mach_H_8 = DELAY 0 100
}
ELSE
{
&Mach_H_8 = 0
}
IF &D_MACH_H = 9
{
&Mach_H_9 = 1
&Mach_H_9 = DELAY 0 100
}
ELSE
{
&Mach_H_9 = 0
}
}
Var 9303, name D_MACH_T
{
IF &D_MACH_T = 0
{
&Mach_T_0 = 1
&Mach_T_0 = DELAY 0 100
}
ELSE
{
&Mach_T_0 = 0
}
IF &D_MACH_T = 1
{
&Mach_T_1 = 1
&Mach_T_1 = DELAY 0 100
}
ELSE
{
&Mach_T_1 = 0
}
IF &D_MACH_T = 2
{
&Mach_T_2 = 1
&Mach_T_2 = DELAY 0 100
}
ELSE
{
&Mach_T_2 = 0
}
IF &D_MACH_T = 3
{
&Mach_T_3 = 1
&Mach_T_3 = DELAY 0 100
}
ELSE
{
&Mach_T_3 = 0
}
IF &D_MACH_T = 4
{
&Mach_T_4 = 1
&Mach_T_4 = DELAY 0 100
}
ELSE
{
&Mach_T_4 = 0
}
IF &D_MACH_T = 5
{
&Mach_T_5 = 1
&Mach_T_5 = DELAY 0 100
}
ELSE
{
&Mach_T_5 = 0
}
IF &D_MACH_T = 6
{
&Mach_T_6 = 1
&Mach_T_6 = DELAY 0 100
}
ELSE
{
&Mach_T_6 = 0
}
IF &D_MACH_T = 7
{
&Mach_T_7 = 1
&Mach_T_7 = DELAY 0 100
}
ELSE
{
&Mach_T_7 = 0
}
IF &D_MACH_T = 8
{
&Mach_T_8 = 1
&Mach_T_8 = DELAY 0 100
}
ELSE
{
&Mach_T_8 = 0
}
IF &D_MACH_T = 9
{
&Mach_T_9 = 1
&Mach_T_9 = DELAY 0 100
}
ELSE
{
&Mach_T_9 = 0
}
}
Var 9304, name D_MACH_U
{
IF &D_MACH_U = 0
{
&Mach_U_0 = 1
&Mach_U_0 = DELAY 0 300
}
ELSE
{
&Mach_U_0 = 0
}
IF &D_MACH_U = 2
{
&Mach_U_2 = 1
&Mach_U_2 = DELAY 0 300
}
ELSE
{
&Mach_U_2 = 0
}
IF &D_MACH_U = 4
{
&Mach_U_4 = 1
&Mach_U_4 = DELAY 0 300
}
ELSE
{
&Mach_U_4 = 0
}
IF &D_MACH_U = 6
{
&Mach_U_6 = 1
&Mach_U_6 = DELAY 0 300
}
ELSE
{
&Mach_U_6 = 0
}
IF &D_MACH_U = 8
{
&Mach_U_8 = 1
&Mach_U_8 = DELAY 0 300
}
ELSE
{
&Mach_U_8 = 0
}
}
Var 9400, name Mach_H_0, Link IOCARD_OUT, Output 0
Var 9401, name Mach_H_1, Link IOCARD_OUT, Output 1
Var 9402, name Mach_H_2, Link IOCARD_OUT, Output 2
Var 9403, name Mach_H_3, Link IOCARD_OUT, Output 3
Var 9404, name Mach_H_4, Link IOCARD_OUT, Output 4
Var 9405, name Mach_H_5, Link IOCARD_OUT, Output 5
Var 9406, name Mach_H_6, Link IOCARD_OUT, Output 6
Var 9407, name Mach_H_7, Link IOCARD_OUT, Output 7
Var 9408, name Mach_H_8, Link IOCARD_OUT, Output 8
Var 9409, name Mach_H_9, Link IOCARD_OUT, Output 9
Var 9410, name Mach_T_0, Link IOCARD_OUT, Output 10
Var 9411, name Mach_T_1, Link IOCARD_OUT, Output 11
Var 9412, name Mach_T_2, Link IOCARD_OUT, Output 12
Var 9413, name Mach_T_3, Link IOCARD_OUT, Output 13
Var 9414, name Mach_T_4, Link IOCARD_OUT, Output 14
Var 9415, name Mach_T_5, Link IOCARD_OUT, Output 15
Var 9416, name Mach_T_6, Link IOCARD_OUT, Output 16
Var 9417, name Mach_T_7, Link IOCARD_OUT, Output 17
Var 9418, name Mach_T_8, Link IOCARD_OUT, Output 18
Var 9419, name Mach_T_9, Link IOCARD_OUT, Output 19
Var 9420, name Mach_U_0, Link IOCARD_OUT, Output 20
Var 9422, name Mach_U_2, Link IOCARD_OUT, Output 21
Var 9424, name Mach_U_4, Link IOCARD_OUT, Output 22
Var 9426, name Mach_U_6, Link IOCARD_OUT, Output 23
Var 9428, name Mach_U_8, Link IOCARD_OUT, Output 24
As you can see it is a long one :P
Thanks
Edoardo
edo17982
08-12-2010, 09:52 AM
Just got my DC card today and try to understand the basics of siocing it...
I made a fsuipc var to read vertical speed. My target is a t the moment just to get the needle of my alt to move right when climb and left when descend.
from the example codes it seames that one must have a timer... never use those but... well at the moment it seames to move pritty much like it wants here's the code i use:
what am I undersanding wrong here ? the needle just turns and turns in one direction. Randomy or maybe the first impulse it get's at start off sioc ?
Gery
Hi Gery!
What I can suggest (I'm not a SIOC guru but I found a way to have my gauges workin) is 1st to divide variables for FSUIPC conversion and Motor control as I did.
In the FSUIPC conversion you will put the converion itself as you did and the various ranges of the VSI scale according to the pot positioning.
In the control variable you will define how the motor will act according to the pot position and the objective position it has to reach.
In your code I see that you forgot to insert the variable for the pot used for the positioning...remember also to correctly configure your IOCDCMOTOR.INI file to get everything workin properly.
Var 0000, Value 0
{
&VSControl = TIMER 999, 0, 2
&VSMotor = 0
&VSObj = 127
}
Var 0001, name VSMotor, static, Link USB_DCMOTOR, Device 2, Output 1 // motor control (0-127) 0=Left, +128 = Right
Var 0006, name VSAd, Link USB_ANALOGIC, Device 2, Input 1, PosL 0, PosC 127, PosR 255 Static // Potentiometer value
Var 9001, name VSOffst, link FSUIPC_IN, offset $02C8, Length 4
{
L0 = &VSOffst * 60 // FSUIPC conversion, L0=VS
L0 = L0 * 3.28084 // FSUIPC conversion, L0=VS
L0 = L0 / 256 // FSUIPC conversion, L0=VS
L0 = ROUND L0 // Let's round the decimal value
&VS = L0
L2 = L0 // Since now we'll calculate all the ranges of the scale
IF L0 <= -6000 // First sector, value greater than - 6000 ft/min
{
L1 = 0 // Pot 0: here you will type the value according to the pot position when needle is on the "6" in negative range
}
ELSE
{
L2 = L0 + 6000
IF L0 <= -2000 // Second sector, value between -6000 and -2000
{
L1 = L2 / 80 // pot 50
L1 = L1 + 0
L1 = ABS L1
}
ELSE
{
L2 = L0 + 2000
IF L0 <= -1000 // Third sector, value between -2000 and -1000
{
L1 = L2 / 50 // pot 70
L1 = L1 + 50
L1 = ABS L1
}
ELSE
{
L2 = L0 + 1000
IF L0 < 0 // Fourth sector. value between -1000 and 0
{
L1 = L2 / 17.85714 // pot 126
L1 = L1 + 70
L1 = ABS L1
}
ELSE
{
L2 = L0
IF L0 = 0 // Fifth sector, Value 0
{
L1 = 127
}
ELSE
{
L2 = L0
IF L0 <= 1000 // Sixth sector, value between 0 and 1000
{
L1 = L2 / 17.85714 // pot 184
L1 = L1 + 127
}
ELSE
{
L2 = L0 - 1000
IF L0 <= 2000 // Seventh sector, value between 1000 and 2000
{
L1 = L2 / 50 // pot 204
L1 = L1 + 183
}
ELSE
{
L2 = L0 - 2000
IF L0 <= 6000 // Sixth sector, value between 2000 and 6000
{
L1 = L2 / 80 // pot 254
L1 = L1 + 203
}
ELSE // Out of range
{
IF L0 > 6000 // Last sector, value greater than +6000 ft/min
{
L1 = 255 // Pot 255: here you will type the value according to the pot position when needle is on the "6" in positive range
}
}
}
}
}
}
}
}
}
&VSObj = L1
}
Var 9002, name VS
Var 9004, name VSControl, Link Subrutine // Subrutine for Control (each 20ms)
{
L0 = &VSobj - &VSAd
L1 = 0
IF L0 < 0
{
L1 = 128
}
L0 = ABS L0
L2 = &VSVelMax + L1
IF L0 <= &VSAprox8
{
L2 = &VSVel8 + L1
}
IF L0 <= &VSAprox6
{
L2 = &VSVel6 + L1
}
IF L0 <= &VSAprox4
{
L2 = &VSVel4 + L1
}
IF L0 <= &VSAprox2
{
L2 = &VSVel2 + L1
}
IF L0 <= &VSAproxSlow
{
L2 = &VSVelMin + L1
}
IF L0 = &VSMargen
{
L2 = 0
}
&VSMotor = L2
}
Var 9006, name VSObj // objective position
Var 9007, name VSMargen, Value 0 // %error
Var 9008, name VSAprox8, Value 6
Var 9009, name VSAprox6, Value 4
Var 9010, name VSAprox4, Value 3
Var 9011, name VSAprox2, Value 2
Var 9012, name VSAproxSlow, Value 1 // Value approaching target
Var 9013, name VSVelMax, Value 60 // Max Speed for follow objective
Var 9014, name VSVel8, Value 40
Var 9015, name VSVel6, Value 34
Var 9016, name VSVel4, Value 28
Var 9017, name VSVel2, Value 22
Var 9018, name VSVelMin, Value 13 // Speed approaching target