Controlling the Speed of a DC Motor using a Potentiometer

' Program MOTOR_2.BAS
'
' Uses a potentiometer to control the speed of a DC motor.  This routine
' uses concepts presented in Motor_1.BAS (DACpin) and RCTime_2.BAS
' 
' Uses RCTime (as described in RCTime_2.Bas) on both the charge and 
' discharge to calculate determine time and thus the value of R.
'
' Note that the time (tm) using the charge - discharge technique is;
'
'    tm = RC (ln (5.0/V_thresh) + ln (5.0/(5.0-V_thresh))
' or tm = R * k
'
' where k is C * 1.601.  (Assuming V_thresh is 1.4 VDC).  If C is 0.1 
' uFd, k is 1.601e-7.  Note that a  mylar capacitor is recommended for 
' stability.
'
' Thus R is tm / k or R = tm * 6.24e+6.
'
' Asumming R consists of a 100 Ohm series resistor and a 10K Pot, R_pot
' is calculated as R - 100.0.
'
' An R_pot value of 0 is mapped to a Duty of 0 and 10K to a Duty of 255. 
' 
' Duty is then used to DACpin the DC motor.
'
' Copyright, Peter H. Anderson, Baltimore, Sept, 99
'

Public Const MOTOR as byte = 23	' Ouput to Motor Driver
Public Const P24 as byte = 24	' RCTime
Public Const P25 as byte = 25	' Used on Resistor side
				' 0 for discharge, 1 for charge

Sub Main()

   Dim tm as Single
   Dim R_pot as Single
   Dim DutyInt as Integer

   Call OpenSerialPort(2, 9600)		' For debugging

   Do
      Call MeasRCTime(tm)	' uses both charge and discharge

      R_pot = 6.24e+6 * tm - 100.0

      If (R_pot < 0.0) then		' be sure it is in bound
         R_pot = 0.0
      Elseif (R_pot > 10.0e+3) then
         R_pot = 10.0e+3
      End if

      DutyInt = CInt(R_pot * 254.0 / 10.0e3) ' map R_pot to a duty
      
      Call TurnMotor(DutyInt)
   Loop

End Sub    

Sub TurnMotor(ByVal DutyInt as Integer)

   Dim DutyByte as Byte
   Dim N as Byte
   Dim DACcounter as Byte

   DutyByte = CByte(DutyInt)	' cast Duty as byte

'  Call PutI (DutyInt)	' for debugging
'  Call NewLine()

   For N = 1 TO 25
      Call DACpin(MOTOR, DutyByte, DACcounter)
   Next  

End Sub    

Sub MeasRCTime(ByRef T_tot as Single)

   Dim T_rise as Single
   Dim T_fall as Single
  
      ' measure T_fall
   Call PutPin(P25, bxOutputLow)	' steady state val is ground
   Call PutPin(P24, bxOutputHigh)	' exert a one
   Call Sleep(0.01)			' give it time to charge to +5

   Call RCtime(P24, 1, T_fall)		' measure T_fall

   ' now measure T_rise
   Call PutPin(P25, bxOutputHigh)	' steady state val is +5
   Call PutPin(P24, bxOutputLow)	' exert a zero
   Call Sleep(0.01)			' give time for C to discharge

   Call RCtime(P24, 0, T_rise)		' measure T_rise

   T_tot = T_fall + T_rise

'   Call PutS(T_rise)			' display the results - for debugging
'   Call PutByte(32)
'   Call PutS(T_fall)
'   Call PutByte(32)
'   Call PUTS(T_tot)
'   Call NewLine()

End Sub