kopia lustrzana https://github.com/jamesgao/kiln_controller
update nonblocking stepper, damn is bootstrap sexy
rodzic
7d72bfb803
commit
9da90d8c98
|
@ -6,16 +6,7 @@ import Queue
|
|||
from RPi import GPIO
|
||||
|
||||
class Stepper(threading.Thread):
|
||||
#half-steppipng pattern, also possible to skip every other for full-stepping
|
||||
pattern = [
|
||||
#[1,0,0,0],
|
||||
#[1,0,1,0],
|
||||
#[0,0,1,0],
|
||||
#[0,1,1,0],
|
||||
#[0,1,0,0],
|
||||
#[0,1,0,1],
|
||||
#[0,0,0,1],
|
||||
#[1,0,0,1]]
|
||||
[1,1,0,0],
|
||||
[0,1,1,0],
|
||||
[0,0,1,1],
|
||||
|
@ -38,7 +29,7 @@ class Stepper(threading.Thread):
|
|||
self.daemon = True
|
||||
|
||||
def stop(self):
|
||||
self.queue.put((None, None))
|
||||
self.queue.put((None, None, None))
|
||||
|
||||
def step(self, num, speed=10, block=False):
|
||||
"""Step the stepper motor
|
||||
|
@ -53,18 +44,22 @@ class Stepper(threading.Thread):
|
|||
Block while stepping?
|
||||
"""
|
||||
self.finished.clear()
|
||||
self.queue.put((num, speed))
|
||||
if block:
|
||||
self.finished.wait()
|
||||
self.queue.put((num, speed, block))
|
||||
self.finished.wait()
|
||||
|
||||
def run(self):
|
||||
step, speed = self.queue.get()
|
||||
target = 0
|
||||
step, speed, block = self.queue.get()
|
||||
while step is not None:
|
||||
for pin, out in zip(self.pins, self.pattern[self.phase%len(self.pattern)]):
|
||||
GPIO.output(pin, out)
|
||||
|
||||
self._step(step, speed)
|
||||
self.finished.set()
|
||||
if block:
|
||||
self._step(step, speed)
|
||||
self.finished.set()
|
||||
else:
|
||||
self.finished.set()
|
||||
self._step_noblock(step, speed)
|
||||
|
||||
try:
|
||||
step, speed = self.queue.get(True, self.timeout)
|
||||
|
@ -78,6 +73,29 @@ class Stepper(threading.Thread):
|
|||
GPIO.output(pin, False)
|
||||
GPIO.cleanup()
|
||||
|
||||
def _step_noblock(self, step, speed):
|
||||
ispeed = 1. / (2.*speed)
|
||||
target = self.phase + step
|
||||
while self.phase != target:
|
||||
now = time.time()
|
||||
self.phase += 1 if target > self.phase else 1
|
||||
output = self.pattern[self.phase%len(self.pattern)]
|
||||
for pin, out in zip(self.pins, output):
|
||||
GPIO.output(pin, out)
|
||||
|
||||
if not self.queue.empty():
|
||||
step, speed, block = self.queue.get()
|
||||
ispeed = 1. / (2.*speed)
|
||||
target += step
|
||||
if block:
|
||||
self._step(target - self.phase, speed)
|
||||
|
||||
diff = ispeed - (time.time() - now)
|
||||
if (diff) > 0:
|
||||
time.sleep(diff)
|
||||
else:
|
||||
warnings.warn("Step rate too high, stepping as fast as possible")
|
||||
|
||||
def _step(self, step, speed):
|
||||
print "Stepping %d steps at %d steps / second"%(step, speed)
|
||||
if step < 0:
|
||||
|
@ -144,7 +162,7 @@ class Regulator(object):
|
|||
self.stepper.step(-self.current, self.speed, block=block)
|
||||
self.current = 0
|
||||
|
||||
def set(self, value, block=True):
|
||||
def set(self, value, block=False):
|
||||
if not 0 < value < 1:
|
||||
raise ValueError("Must give fraction between 0 and 1")
|
||||
target = int(value * (self.max - self.min) + self.min)
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Kiln Controller</title>
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<!-- Latest compiled and minified CSS -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
|
||||
|
||||
<!-- Optional theme -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding-top: 70px;
|
||||
}
|
||||
.row-space {
|
||||
margin-bottom:15px;
|
||||
}
|
||||
.output-slider {
|
||||
width:7% !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#">Kiln Controller</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="active"><a href="#">Control</a></li>
|
||||
<li><a href="designer.html">Designer</a></li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="#" class="dropdown-toggle" data-toggle="dropdown"><div id="current_temp">Temperature</div></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li class="active"><a href="#">°F</a></li>
|
||||
<li><a href="#">°C</a></li>
|
||||
<li><a href="#">Δ</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#" id="current_time">Time</a></li>
|
||||
<li><a href="#" id="current_output">0%</a></li>
|
||||
<li><button id="stop-button" class="btn btn-primary navbar-btn hidden" href="#">Stop</button></li>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-8 col-md-8 row-space">
|
||||
<img src="http://placehold.it/1024x500/" class="img-responsive row-space" alt="Graph" />
|
||||
|
||||
<div class="btn-group btn-group-justified row-space">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary disabled">Off</button>
|
||||
</div>
|
||||
<div class="btn-group output-slider">
|
||||
<input type="range" min=0 max=1000 class="btn btn-default" />
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-danger">Ignite</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 col-md-4">
|
||||
<div class="input-group input-group-lg row-space">
|
||||
<input type="text" disabled="disabled" class="form-control" placeholder="Load profile">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
|
||||
<ul class="dropdown-menu dropdown-menu-right" role="menu">
|
||||
<li><a href="#">...</a></li>
|
||||
</ul>
|
||||
</div><!-- /btn-group -->
|
||||
</div><!-- /input-group -->
|
||||
<div class='btn-group btn-group-justified row-space'>
|
||||
<a href="#" class="btn btn-primary disabled"> Start <span class="glyphicon glyphicon-play"></span></a>
|
||||
<a href="#" class="btn btn-default disabled"> Pause <span class="glyphicon glyphicon-pause"></span></a>
|
||||
<a href="#" class="btn btn-success disabled"> Save <span class="glyphicon glyphicon-floppy-disk"></span></a>
|
||||
</div>
|
||||
<img src="http://placehold.it/640x480/" class="img-responsive" alt="webcam" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- /container -->
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -21,7 +21,7 @@ def temp_to_cone(temp):
|
|||
class Monitor(threading.Thread):
|
||||
def __init__(self, name="3b-000000182b57"):
|
||||
self.device = "/sys/bus/w1/devices/%s/w1_slave"%name
|
||||
self.history = deque(maxlen=1024)
|
||||
self.history = deque(maxlen=1048576)
|
||||
|
||||
try:
|
||||
from Adafruit_alphanumeric import AlphaScroller
|
||||
|
|
Ładowanie…
Reference in New Issue