Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 63 additions & 55 deletions syspwm.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,61 +22,69 @@ class SysPWMException(Exception):
# /sys/ pwm interface described here: http://www.jumpnowtek.com/rpi/Using-the-Raspberry-Pi-Hardware-PWM-timers.html
class SysPWM(object):

chippath = "/sys/class/pwm/pwmchip0"

def __init__(self,pwm):
self.pwm=pwm
self.pwmdir="{chippath}/pwm{pwm}".format(chippath=self.chippath,pwm=self.pwm)
if not self.overlay_loaded():
raise SysPWMException("Need to add 'dtoverlay=pwm-2chan' to /boot/config.txt and reboot")
if not self.export_writable():
raise SysPWMException("Need write access to files in '{chippath}'".format(chippath=self.chippath))
if not self.pwmX_exists():
self.create_pwmX()
return

def overlay_loaded(self):
return os.path.isdir(self.chippath)

def export_writable(self):
return os.access("{chippath}/export".format(chippath=self.chippath), os.W_OK)

def pwmX_exists(self):
return os.path.isdir(self.pwmdir)

def echo(self,m,fil):
#print "echo {m} > {fil}".format(m=m,fil=fil)
with open(fil,'w') as f:
f.write("{m}\n".format(m=m))

def create_pwmX(self):
pwmexport = "{chippath}/export".format(chippath=self.chippath)
self.echo(self.pwm,pwmexport)

def enable(self,disable=False):
enable = "{pwmdir}/enable".format(pwmdir=self.pwmdir)
num = 1
if disable:
num = 0
self.echo(num,enable)

def disable(self):
return self.enable(disable=True)

def set_duty_cycle(self,milliseconds):
# /sys/ iface, 2ms is 2000000
# gpio cmd, 2ms is 200
dc = int(milliseconds * 1000000)
duty_cycle = "{pwmdir}/duty_cycle".format(pwmdir=self.pwmdir)
self.echo(dc,duty_cycle)

def set_frequency(self,hz):
per = (1 / float(hz))
per *= 1000 # now in milliseconds
per *= 1000000 # now in.. whatever
per = int(per)
period = "{pwmdir}/period".format(pwmdir=self.pwmdir)
self.echo(per,period)
__chippath = "/sys/class/pwm/pwmchip0"
__pwm = None
__pwmdir = None
__period_ns = 0
__frequency_hz = 0
__duty_cycle = 0

def __init__(self,pwm,frequency):
self.__pwm=pwm
self.__pwmdir="{chippath}/pwm{pwm}".format(chippath=self.__chippath,pwm=self.__pwm)
if not self.overlay_loaded():
raise SysPWMException("Need to add 'dtoverlay=pwm-2chan' to /boot/config.txt and reboot")
if not self.export_writable():
raise SysPWMException("Need write access to files in '{chippath}'".format(chippath=self.__chippath))
if not self.pwmX_exists():
self.create_pwmX()
self.set_frequency(frequency)
return

def overlay_loaded(self):
return os.path.isdir(self.__chippath)

def export_writable(self):
return os.access("{chippath}/export".format(chippath=self.__chippath), os.W_OK)

def pwmX_exists(self):
return os.path.isdir(self.__pwmdir)

def echo(self,m,fil):
#print "echo {m} > {fil}".format(m=m,fil=fil)
with open(fil,'w') as f:
f.write("{m}\n".format(m=m))

def create_pwmX(self):
pwmexport = "{chippath}/export".format(chippath=self.__chippath)
self.echo(self.__pwm,pwmexport)

def enable(self,disable=False):
enable = "{pwmdir}/enable".format(pwmdir=self.__pwmdir)
num = 1
if disable:
num = 0
self.echo(num,enable)

def disable(self):
return self.enable(disable=True)

def set_duty_cycle(self,duty_cycle):
self.__duty_cycle = max(0, min(1, duty_cycle))
duty_cycle_ns = int(self.__duty_cycle*self.__period_ns)
path = "{pwmdir}/duty_cycle".format(pwmdir=self.__pwmdir)
self.echo(duty_cycle_ns, path)

def set_frequency(self,frequency):
old_dc = self.__duty_cycle
self.set_duty_cycle(0)

self.__frequency = int(frequency)
self.__period_ns = int((1.0/self.__frequency)*1e9)

self.set_duty_cycle(old_dc)
path = "{pwmdir}/period".format(pwmdir=self.__pwmdir)
self.echo(self.__period_ns,path)

if __name__ == "__main__":
from time import sleep
Expand Down