Scaling PWM Duty Cycles

Here you can share completed projects or parts of projects that may be useful to others. You may post files relevant to ZBasic - source code, schematics, etc.
Post Reply
Don_Kirby
Posts: 341
Joined: 15 October 2006, 3:48 AM
Location: Long Island, New York

Scaling PWM Duty Cycles

Post by Don_Kirby »

Here's a bit of code that might be useful to new users, or those who's math skills are as poor as mine.

I had the need to generate a PWM output that followed the value read from an ADC input. I also needed to define minimum and maximum limits for the duty cycle of the PWM output. The code below is what I came up with.

Code: Select all

Public Sub PWM_OUT()
	Const PWM_PIN 			as Byte = D.5 'PWM Output Pin
	Const ADC_PIN 			as Byte = A.6 'ADC Input Pin
	Const UPDATE_RATE 		as Single = 0.5 'Seconds between updates
	Const MIN_DUTY_CYCLE 	as Single = 25.0 '%
	Const MAX_DUTY_CYCLE 	as Single = 95.0 '%
	Dim DUTY_CYCLE 			as Single 'PWM Duty Cycle
	Dim	I 					as Single 'ADC Input
	
	'Open the pin as an input.
	Call PutPin(ADC_PIN, zxInputTriState)

	'Initialize the PWM output
	Call OpenPWM(1, 1000.0, zxCorrectPWM)
	
	Do 
		'Read the ADC
		Call GetADC(ADC_PIN, I)
		'And Scale the ADC value to the min/max settings defined above
		DUTY_CYCLE = ((((MAX_DUTY_CYCLE - MIN_DUTY_CYCLE) / 100.0) * I) * 100.0 + MIN_DUTY_CYCLE)
		
		Call PWM(1, DUTY_CYCLE) 'update the PWM output...
		Call Sleep(UPDATE_RATE) 'But not real often
	Loop
End Sub
Given an ADC value of 0.0 (tied to ground), and a MIN_DUTY_CYCLE of 25.0 (25%), the DUTY_CYCLE is 25%. Conversly, an ADC value of 1.0 (tied to Vcc) and a MAX_DUTY_CYCLE of 90.0 (90%) the DUTY_CYCLE is 90.0 (90%). ADC values in between are scaled appropriately.

Of course, the specifics of the OpenPWM call will depend on your particular application.

Apologies if this is common knowledge, but I didn't find anything similar while searching the forum.

-Don
Post Reply