I found the math behind the Arduino map function and have replicated it in a subroutine in PBP:
It doesn't look like this is working as expected - any ideas?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




Bookmarks