I found the math behind the Arduino map function and have replicated it in a subroutine in PBP:
Code:
PR2 = 62 ; For 16Mhz OSC the desired output freq of 15,873Hz is
; achieved with this PR2 value (8-bit resolution
; with 1:4 prescaler)
; PWM freq must be ~ 16-20kHz to reduce noise
MinDuty CON 100 ; Minimum speed to rotate motor for this application
MaxDuty VAR WORD ; According to Darrel:
; MaxDuty = (PR2 + 1) * 4
MaxDuty = (PR2 + 1) * 4 ; 252 but with prescaler resolution it's actually 250
MotorDuty VAR WORD ; Actual duty cycle for motor
MaxADCVal CON 255 ; 255 for 8-bit; 1023 for 10-bit
ADCInVal VAR BYTE ; stores ADCIN result read from trim pot
compVal VAR BYTE ; stores last-changed ADC value
Main:
gosub Do_ADC
pause 100
If ADCInVal <> compVal Then
#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR]
pause 5
HSEROUT ["new ADCInVal=", DEC ADCInVal, " ", 13, 10] ; Send text followed by carriage return and linefeed
#ENDIF
GOSUB Map_ADC_Val_to_PWM_Duty
gosub ChngMotorHPWM
compVal = ADCInVal
endif
GOTO Main
Do_ADC:
PAUSEUS 50 ' Wait for A/D channel acquisition time
ADCON0.1 = 1 ' Start conversion
WHILE ADCON0.1 = 1 ' Wait for it to complete
WEND
ADCInVal = ADRESH
return
Map_ADC_Val_to_PWM_Duty:
' Arduino Map function to emulate:
' ===============================
' map(value, fromLow, fromHigh, toLow, toHigh)
' long map(long x, long in_min, long in_max, long out_min, long out_max)
' {
' return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
' }
MotorDuty = (ADCInVal - 0) * (MaxDuty - MinDuty)/(MaxADCVal - 0) + MinDuty
#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR]
pause 5
HSEROUT ["MotorDuty=", DEC MotorDuty, " ", 13, 10] ; Send text followed by carriage return and linefeed
pause 1500
HSEROUT [LCD_INST, LCD_CLR]
#ENDIF
RETURN
It doesn't look like this is working as expected - any ideas?
Bookmarks