Skip to content

Commit c24d8f0

Browse files
committed
master initial
1 parent 16b3628 commit c24d8f0

File tree

7 files changed

+206
-0
lines changed

7 files changed

+206
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,5 @@ venv.bak/
102102

103103
# mypy
104104
.mypy_cache/
105+
106+
.idea/

fishfeed/PCA9685.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/usr/bin/python
2+
3+
import time
4+
import math
5+
import smbus
6+
7+
8+
# ============================================================================
9+
# Raspi PCA9685 16-Channel PWM Servo Driver
10+
# ============================================================================
11+
12+
class PCA9685:
13+
# Registers/etc.
14+
__SUBADR1 = 0x02
15+
__SUBADR2 = 0x03
16+
__SUBADR3 = 0x04
17+
__MODE1 = 0x00
18+
__PRESCALE = 0xFE
19+
__LED0_ON_L = 0x06
20+
__LED0_ON_H = 0x07
21+
__LED0_OFF_L = 0x08
22+
__LED0_OFF_H = 0x09
23+
__ALLLED_ON_L = 0xFA
24+
__ALLLED_ON_H = 0xFB
25+
__ALLLED_OFF_L = 0xFC
26+
__ALLLED_OFF_H = 0xFD
27+
28+
def __init__(self, address=0x40, debug=False):
29+
self.bus = smbus.SMBus(1)
30+
self.address = address
31+
self.debug = debug
32+
if (self.debug):
33+
print("Reseting PCA9685")
34+
self.write(self.__MODE1, 0x00)
35+
36+
def write(self, reg, value):
37+
"Writes an 8-bit value to the specified register/address"
38+
self.bus.write_byte_data(self.address, reg, value)
39+
if (self.debug):
40+
print("I2C: Write 0x%02X to register 0x%02X" % (value, reg))
41+
42+
def read(self, reg):
43+
"Read an unsigned byte from the I2C device"
44+
result = self.bus.read_byte_data(self.address, reg)
45+
if (self.debug):
46+
print("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" % (self.address, result & 0xFF, reg))
47+
return result
48+
49+
def setPWMFreq(self, freq):
50+
"Sets the PWM frequency"
51+
prescaleval = 25000000.0 # 25MHz
52+
prescaleval /= 4096.0 # 12-bit
53+
prescaleval /= float(freq)
54+
prescaleval -= 1.0
55+
if (self.debug):
56+
print("Setting PWM frequency to %d Hz" % freq)
57+
print("Estimated pre-scale: %d" % prescaleval)
58+
prescale = math.floor(prescaleval + 0.5)
59+
if (self.debug):
60+
print("Final pre-scale: %d" % prescale)
61+
62+
oldmode = self.read(self.__MODE1);
63+
newmode = (oldmode & 0x7F) | 0x10 # sleep
64+
self.write(self.__MODE1, newmode) # go to sleep
65+
self.write(self.__PRESCALE, int(math.floor(prescale)))
66+
self.write(self.__MODE1, oldmode)
67+
time.sleep(0.005)
68+
self.write(self.__MODE1, oldmode | 0x80)
69+
70+
def setPWM(self, channel, on, off):
71+
"Sets a single PWM channel"
72+
self.write(self.__LED0_ON_L + 4 * channel, on & 0xFF)
73+
self.write(self.__LED0_ON_H + 4 * channel, on >> 8)
74+
self.write(self.__LED0_OFF_L + 4 * channel, off & 0xFF)
75+
self.write(self.__LED0_OFF_H + 4 * channel, off >> 8)
76+
if (self.debug):
77+
print("channel: %d LED_ON: %d LED_OFF: %d" % (channel, on, off))
78+
79+
def setServoPulse(self, channel, pulse):
80+
"Sets the Servo Pulse,The PWM frequency must be 50HZ"
81+
pulse = pulse * 4096 / 20000 # PWM frequency is 50HZ,the period is 20000us
82+
self.setPWM(channel, 0, int(pulse))
83+
84+
85+
if __name__ == '__main__':
86+
87+
pwm = PCA9685(0x40, debug=False)
88+
pwm.setPWMFreq(50)
89+
while True:
90+
# setServoPulse(2,2500)
91+
for i in range(500, 2500, 10):
92+
pwm.setServoPulse(0, i)
93+
time.sleep(0.02)
94+
95+
for i in range(2500, 500, -10):
96+
pwm.setServoPulse(0, i)
97+
time.sleep(0.02)

fishfeed/__init__.py

Whitespace-only changes.

fishfeed/cli.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import click
2+
3+
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
4+
5+
6+
@click.group(invoke_without_command=True, context_settings=CONTEXT_SETTINGS)
7+
@click.version_option(version='0.1')
8+
def fishfeed():
9+
pass
10+
11+
12+
@fishfeed.command()
13+
def run(**kwargs):
14+
fishfeed.run()
15+
16+
17+
@fishfeed.command()
18+
def last5(**kwargs):
19+
click.echo(5)
20+
21+
22+
@fishfeed.command()
23+
def last50(**kwargs):
24+
click.echo(50)
25+
26+
27+
if __name__ == '__main__':
28+
fishfeed()

fishfeed/ctx.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from picamera import PiCamera
2+
3+
from PCA9685 import PCA9685
4+
5+
6+
class Singleton(type):
7+
_instances = {}
8+
9+
def __call__(cls, *args, **kwargs):
10+
if cls not in cls._instances:
11+
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
12+
return cls._instances[cls]
13+
14+
15+
class Ctx(object):
16+
__metaclass__ = Singleton
17+
camera = PiCamera()
18+
pwm = PCA9685(0x40, debug=False)
19+
20+
DAY = None
21+
TIME = None
22+
STATUS = None

fishfeed/fishfeed.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import datetime
2+
from time import sleep
3+
4+
5+
6+
def initialize():
7+
Ctx.DAY, Ctx.TIME = datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S').split()
8+
Ctx.pwm.setPWMFreq(50)
9+
10+
def prepare():
11+
# put food
12+
13+
# put water
14+
15+
def stream():
16+
pass
17+
18+
def clean():
19+
for _ in range(2):
20+
# put water
21+
22+
# thrash water
23+
24+
25+
def finalize():
26+
print Ctx.DAY, Ctx.TIME, Ctx.STATUS
27+
28+
29+
def run():
30+
# initialize ports
31+
initialize()
32+
33+
# prepare food
34+
prepare()
35+
36+
# stream
37+
stream()
38+
39+
# clean
40+
clean()
41+
42+
# finalize
43+
finalize()

setup.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from setuptools import setup
2+
3+
setup(
4+
name='fishfeed',
5+
version='0.1',
6+
py_modules=['fishfeed'],
7+
install_requires=[
8+
'Click', 'smbus'
9+
],
10+
entry_points='''
11+
[console_scripts]
12+
fishfeed=fishfeed.cli:fishfeed
13+
''',
14+
)

0 commit comments

Comments
 (0)