Code:
define CODE_SIZE 32
define osc 20
Include "modedefs.bas" ' Mode definitions for Serout
INCLUDE "incPID.pbp" 'Include the PID routine.
ADValue VAR WORD '<---This is your variable.
SetPoint VAR WORD '<---This is your variable.
OnOff1 var PortE.1 'Input Signal from GPS to activate/deactivate row
OnOff2 var PortE.0 'Input Signal from GPS to activate/deactivate row
OnOff3 var PortA.5 'Input Signal from GPS to activate/deactivate row
OnOff4 var PortB.5 'Input Signal from GPS to activate/deactivate row
Switch1 var PortD.0 ''Output to 4066; activates Speed1
Switch2 var PortE.2 ''Output to 4066; activates Speed2
Switch3 var PortC.0 ''Output to 4066; activates Speed3
Switch4 var PortC.3 ''Output to 4066; activates Speed4
MotorSpeed var PortC.1 'Input from 4066
Population var PortC.2 'Input from GPS
Enable1 var PortD.1 ''Output Turns on Motor1 driver
Enable2 var PortD.2 ''Output Turns on Motor2 driver
Enable3 var PortD.3 ''Output Turns on Motor3 driver
Enable4 var PortD.4 ''Output Turns on Motor4 driver
SinglePair var PortD.7 'Input Determines code path
Input1 var PortB.0 'PWM0
Input2 var PortB.1 'PWM1
Input3 var PortB.2 'PWM2
Input4 var PortB.3 'PWM3
LCD var PortD.5
Duty1 Var Word
Duty2 Var Word
Duty3 Var Word
Duty4 Var Word
Duty1S data word 00300
Duty2S data word 00300
Duty3S data word 00300
Duty4S data word 00300
BCD1 var byte
BCD10 var byte
LowRate var word
HighRate var word
TotalRate var word
DisplayTenths var word
MotorCount var byte 'Tracks motorspeed input
Mod1 var byte 'Offset tracker to correct motorspeed
Mod2 Var Byte 'Offset tracker to correct motorspeed
Mod3 var byte 'Offset tracker to correct motorspeed
Mod4 Var byte 'Offset tracker to correct motorspeed
PosMin1 var bit
PosMin2 var bit
PosMin3 var bit
PosMin4 var bit
HighTime1 var word
LowTime1 var word
HighTime2 var word
LowTime2 var word
HighTime3 var word
LowTime3 var word
HighTime4 var word
LowTime4 var word
TotalTime1 var word
TotalTime2 var word
TotalTime3 var word
TotalTime4 var word
Freq var word
UpperLimit VAR WORD
LowerLimit VAR WORD
Gain var word
Subtract var bit
Prefix con $FE ' needed before each command
LcdCls CON $51 ' clear LCD (use PAUSE 5 after)
LcdLine1 CON $00 ' move cursor to line 1
LcdLine2 con $40 ' move curson to line 2
LcdLine3 con $14 ' move curson to line 3
lcdLine4 con $54 ' move curson to line 4
LcdCol1 con $00 ' move cursor to column 1
LcdCol2 con $07 ' move cursor to column 7
Backlight con $53 ' Backlighting 1-8
CursorPS con $45 'Cursor Position
CursorOn con $47 'Cursof On
CursorOff con $48 'Cursor Off
INTCON = 0 'Interrupts off for now
INTCON2.7 = 1 'Pull Ups disabled
ADCON0 = 0 'A/D OFF
ANSEL0 = %00000000 'All analogue channels to digital
ANSEL1 = %00000000 'All analogue channels to digital
TRISA = %111111 'PortA to inputs
TRISB = %00100000 'PortB to outputs, except B5
TRISC = %00000110 'PortC, Switch3 and Switch4 outputs; Motorspeed and Population inputs
TRISD = %00000000 'PortD, Switch 1 output; Enable1-4
TRISE = %011
PWMCON0=%01111111 'All odd PWMs enabled, all independent
SSPCON=%00000000 'Disables Serial Port
PTCON0 = %00001000 '8914 9140 2050
'PTCON0 = %00000010 back up
Freq=%11111111
PTPERL =Freq.LowByte '
PTPERH =Freq.HighByte ' PTPER = $0100 or 256d for ~19.45kHz
PWMCON1 = 1 ' updates enabled, overrides sync w/timebase
PTCON1 = %11000000 ' PWM time base is ON, counts up 500hz
FLTCONFIG = %00000010 ' enable fault A, cycle-by-cycle mode
'These variables are declared by the incPID routine but
'the user needs to assign values to them.
pid_Kp = $0700 'Set Kp to 7.0
pid_Ki = $0080 'Set Ki to 0.5
pid_Kd = $0225 'Set Kd to 2.14
pid_Ti = 4 'Update I-term every 8th call to PID
pid_I_Clamp = 10 'Clamp I-term to max ±100
pid_Out_Clamp = 10000 'Clamp the final output to ±511
Serout2 LCD, 84, [Prefix,LcdCLS]
'pause 1000
SEROUT2 LCD,84, [Prefix,CursorPS,0, "Graham Electric Planter Drive "]
pause 1000
Serout2 LCD, 84, [Prefix,LcdCLS]
High Enable1
High Enable2
High Enable3
High Enable4
MotorCount = 1
read 0,Duty1.LowByte
read 1,Duty1.HighByte
read 2,Duty2.LowByte
read 3,Duty2.HighByte
read 4,Duty3.LowByte
read 5,Duty3.HighByte
read 6,Duty4.LowByte
read 7,Duty4.HighByte
PDC0L = Duty1.LowByte
PDC0H = Duty1.HighByte
PDC1L = Duty3.LowByte
PDC1H = Duty3.HighByte
PDC2L = Duty2.LowByte
PDC2H = Duty2.HighByte
PDC3L = Duty4.LowByte
PDC3H = Duty4.HighByte
pause 2000
LowerLimit=200
UpperLimit=800
'Gain=10
RunAround:
Gosub BCD
'SEROUT2 LCD,84, [Prefix,CursorPS,84,#bcd1," ",dec5 pid_Error]
'SEROUT2 LCD,84, [Prefix,CursorPS,0, #BCD1, " ", #TotalRate, " ", #MotorCount]
If BCD1 = 0 then 'Tests row control with motor speed at 50%
Duty1=300
Duty2=300
Duty3=300
Duty4=300
PDC0L = Duty1.LowByte
PDC0H = Duty1.HighByte
PDC1L = Duty3.LowByte
PDC1H = Duty3.HighByte
PDC2L = Duty2.LowByte
PDC2H = Duty2.HighByte
PDC3L = Duty4.LowByte
PDC3H = Duty4.HighByte
gosub RowControl
GoSub MeasureRPM
'GosuB AdjustRPM
endif
If BCD1 = 1 then 'run time%" RunTime ", #MotorCount," ",
SEROUT2 LCD,84, [Prefix,CursorPS,0, #motorcount," ", #Duty1," ", #Duty2," ", #Duty3," ", #Duty4 ]
PDC0L = Duty1.LowByte
PDC0H = Duty1.HighByte
PDC1L = Duty3.LowByte
PDC1H = Duty3.HighByte
PDC2L = Duty2.LowByte
PDC2H = Duty2.HighByte
PDC3L = Duty4.LowByte
PDC3H = Duty4.HighByte
gosub RowControl
GoSub MeasureRPM
GosuB AdjustRPM
endif
'If BCD1 = 1 then
' GoSub MeasureRPM
' gosub Display1
' If MotorCount = 4 or Motorcount >4 then
' MotorCount = 1
' else
' MotorCount = MotorCount + 1
' endif
'endif
If BCD1 = 2 then
GoSub MeasureRPM
gosub Display2
If MotorCount = 4 or Motorcount >4 then
MotorCount = 1
else
MotorCount = MotorCount + 1
endif
endif
If BCD1 = 3 then
GoSub MeasureRPM
gosub Display3
If MotorCount = 4 or Motorcount >4 then
MotorCount = 1
else
MotorCount = MotorCount + 1
endif
endif
If BCD1 = 4 then
GoSub MeasureRPM
gosub Display4
If MotorCount = 4 or Motorcount >4 then
MotorCount = 1
else
MotorCount = MotorCount + 1
endif
endif
If BCD1 = 5 then
SEROUT2 LCD,84, [Prefix,CursorPS,0, "1 2 3 4 P"]
SEROUT2 LCD,84, [Prefix,CursorPS,64, #OnOff1," ", #OnOff2," ",#OnOff3," ",#OnOff4," ", #Population]
Low Switch1
Low Switch2
Low Switch3
Low Switch4
endif
If BCD1 = 15 then
endif
goto RunAround
AdjustRPM: '50286 15586 34700
If TotalRate = 0 then '2510 15586 52460 65536
Duty1 = 0
Duty2 = 0
Duty3 = 0
Duty4 = 0
else
Select case MotorCount
Case 1
If OnOff1 = 1 then ''''''''CHECK WHY NOT REDUCING DUTY
' If TotalRate>TotalTime1 then
pid_Error = TotalRate-TotalTime1 'Calculate the error
' Subtract = 0
' else
' pid_Error = TotalTime1-TotalRate 'Calculate the error
' Subtract = 1
' endif
Gosub PID
SEROUT2 LCD,84, [Prefix,CursorPS,84,#bcd1," ",#pid_Sign, " ",dec5 pid_Out," ", #pid_Out_Clamp]
pause 10000 'Result returned in pid_Drive
'If pid_Out.15 Then pid_Out = 0 '
Duty1 = pid_Out
endif
Case 2
If OnOff2 = 1 then
If TotalRate > TotalTime2 then
If Duty2>LowerLimit then
Duty2 = Duty2-Gain
endif
endif
If TotalRate < TotalTime2 then
If DUty2 < UpperLimit then
Duty2 = Duty2+Gain
endif
endif
endif
Case 3
If OnOff3=1 then
If TotalRate > TotalTime3 then
If Duty3>LowerLimit then
Duty3 = Duty3-Gain
endif
endif
If TotalRate < TotalTime3 then
If DUty3 < UpperLimit then
Duty3 = Duty3+Gain
endif
endif
endif
Case 4
If OnOff4=1 then
If TotalRate > TotalTime4 then
If Duty4>LowerLimit then
Duty4 = Duty4-Gain
endif
endif
If TotalRate < TotalTime4 then
If DUty4 < UpperLimit then
Duty4 = Duty4+Gain
endif
endif
endif
end select
endif
Return
MeasureRPM:
pulsin Population, 0, LowRate
pulsin Population, 1, HighRate
TotalRate= LowRate+HighRate
SEROUT2 LCD,84, [Prefix,CursorPS,20,#TotalRate," "]
If MotorCount = 1 then
If Onoff1 = 1 then
High Switch1
Low Switch2
Low Switch3
Low Switch4
PUlsin Motorspeed, 1, HighTime1
Pulsin Motorspeed, 0, LowTIme1
PUlsin Motorspeed, 1, HighTime1
Pulsin Motorspeed, 0, LowTIme1
If HighTime1>500 then
If LowTime1>500 then
TotalTime1 = HighTime1+LowTime1
'else
'TotalTime1 = 0
endif
endif
SEROUT2 LCD,84, [Prefix,CursorPS,64,Dec5 TotalTime1," ",Dec5 HighTime1," ",Dec5 LowTIme1, " " ]
'SEROUT2 LCD,84, [Prefix,CursorPS,10, #Duty1," " ]
endif
Endif
If MotorCount = 2 then
If Onoff2 = 1 then
Low Switch1
High Switch2
Low Switch3
Low Switch4
PUlsin Motorspeed, 1, HighTime2
Pulsin Motorspeed, 0, LowTIme2
PUlsin Motorspeed, 1, HighTime2
Pulsin Motorspeed, 0, LowTIme2
If HighTime2>500 then
If LowTime2>500 then
TotalTime2 = HighTime2+LowTime2
endif
endif
SEROUT2 LCD,84, [Prefix,CursorPS,64,Dec5 TotalTime2," ",Dec5 HighTime2," ",Dec5 LowTIme2, " "]
SEROUT2 LCD,84, [Prefix,CursorPS,10, #Duty2," " ]
endif
EndIf
If MotorCount = 3 then
If Onoff3 = 1 then
Low Switch1
Low Switch2
High Switch3
Low Switch4
PUlsin Motorspeed, 1, HighTime3
Pulsin Motorspeed, 0, LowTIme3
PUlsin Motorspeed, 1, HighTime3
Pulsin Motorspeed, 0, LowTIme3
If HighTime3>500 then
If LowTime3>500 then
TotalTime3 = HighTime3+LowTime3
endif
endif
SEROUT2 LCD,84, [Prefix,CursorPS,64,Dec5 TotalTime3," ",Dec5 HighTime3," ",Dec5 LowTIme3, " " ]
SEROUT2 LCD,84, [Prefix,CursorPS,10, #Duty3," " ]
endif
Endif
If MotorCount = 4 then
If Onoff4 = 1 then
Low Switch1
Low Switch2
Low Switch3
High Switch4
PUlsin Motorspeed, 1, HighTime4
Pulsin Motorspeed, 0, LowTIme4
PUlsin Motorspeed, 1, HighTime4
Pulsin Motorspeed, 0, LowTIme4
If HighTime4>500 then
If LowTime4>500 then
TotalTime4 = HighTime4+LowTime4
endif
endif
SEROUT2 LCD,84, [Prefix,CursorPS,64,Dec5 TotalTime4," ",Dec5 HighTime4," ",Dec5 LowTIme4, " " ]
SEROUT2 LCD,84, [Prefix,CursorPS,10, #Duty4," " ]
endif
endif
If MotorCount = 4 or Motorcount >4 then
MotorCount = 1
write 0,Duty1.LowByte
write 1,Duty1.HighByte
write 2,Duty2.LowByte
write 3,Duty2.HighByte
write 4,Duty3.LowByte
write 5,Duty3.HighByte
write 6,Duty4.LowByte
write 7,Duty4.HighByte
else
MotorCount = MotorCount + 1
endif
return
Display1:
If Motorcount = 1 then
SEROUT2 LCD,84, [Prefix,CursorPS,64,DEC5 LowTime1]
SEROUT2 LCD,84, [Prefix,CursorPS,20,DEC5 HighTime1 ]
SEROUT2 LCD,84, [Prefix,CursorPS,84, #TotalTime1]
endif
Return
Display2:
If Motorcount = 2 then
SEROUT2 LCD,84, [Prefix,CursorPS,64,DEC5 LowTime2]
SEROUT2 LCD,84, [Prefix,CursorPS,20, DEC5 HighTime2]
SEROUT2 LCD,84, [Prefix,CursorPS,84, #TotalTime2]
endif
Return
Display3:
If Motorcount = 3 then
SEROUT2 LCD,84, [Prefix,CursorPS,64,DEC5 LowTime3 ]
SEROUT2 LCD,84, [Prefix,CursorPS,20,DEC5 HighTime3]
SEROUT2 LCD,84, [Prefix,CursorPS,84, #TotalTime3]
endif
Return
Display4:
If Motorcount = 4 then
SEROUT2 LCD,84, [Prefix,CursorPS,64,DEC5 LowTime4 ]
SEROUT2 LCD,84, [Prefix,CursorPS,20,DEC5 HighTime4]
SEROUT2 LCD,84, [Prefix,CursorPS,84, DEC5 TotalTime4]
endif
Return
RowControl:
If Onoff1 = 1 then
high enable1
else
low enable1
endif
If Onoff2 = 1 then
high enable2
else
low enable2
endif
If Onoff3 = 1 then
high enable3
else
low enable3
endif
If Onoff4 = 1 then
high enable4
else
low enable4
endif
return
BCD:
BCD1=PORTA
BCD1=BCD1 & $0F
BCD1=BCD1^ $0F
'BCD10=PORTC
'BCD10=BCD10 & $F0
'BCD10=BCD10^ $F0
'BCD10 = BCD10 >>4
BCD10=PORTC
BCD10=BCD10 & $0F
BCD10=BCD10^ $0F
return
'On Start-Up
'Check SinglePair
' If High Then goto Single
' If Low then goto Paired
'Single
'If OnOff1 = 0 then Enable1 = 0 else Enable1=1
'If OnOff2 = 0 then Enable2 = 0 else Enable1=2
'If OnOff3 = 0 then Enable3 = 0 else Enable1=3
'If OnOff4 = 0 then Enable4 = 0 else Enable1=4
'Measure DutyCycle of Population
'Measure Motor1-4 rpm
'Adjust Input1-4 dutycycle to maintain speed requested from Population
'GOto Single
'Paired
'If OnOff1 = 0 then Enable1 = 0 else Enable1=1
'If OnOff2 = 0 then Enable2 = 0 else Enable1=2
'If OnOff3 = 0 then Enable3 = 0 else Enable1=3
'If OnOff4 = 0 then Enable4 = 0 else Enable1=4
'Measure DutyCycle of Population
'Calculate offset needed for requested Population
'Measure motor1 rpm
'Adjust Input1 dutycycle to maintain speed requested from Population
'Measure offset between motor1 and motor2
'Adjust Input2 dutycycle to get required offset
'Goto Paired
' Duty1 = (LowRate*10)/492 '10% 489
' Duty2 = (LowRate*10)/492 '20% 977
' Duty3 = (LowRate*10)/492 '50% 2461
' Duty4 = (LowRate*10)/492 '80% 3924
' Duty1 = Duty1*10
' Duty2 = Duty2*10
' Duty3 = Duty3*10
' Duty4 = Duty4*10
' PDC0L = Duty1.LowByte
' PDC0H = Duty1.HighByte
' PDC1L = Duty3.LowByte
' PDC1H = Duty3.HighByte
' PDC2L = Duty2.LowByte
' PDC2H = Duty2.HighByte
' PDC3L = Duty4.LowByte
' PDC3H = Duty4.HighByte
' DisplayTenths=Duty1-(Duty1/10*10)
'SEROUT2 LCD,84, [Prefix,CursorPS,10,#TotalRate]
Bookmarks