kopia lustrzana https://github.com/GuyCarver/MicroPython
Add JYMCU, IRDistance, Relay and SR04Distance
Bunch of driver and code format changesmaster
rodzic
e2842f1754
commit
54babcede8
|
@ -0,0 +1,122 @@
|
||||||
|
#Display distance in inches on ST7734 LCD.
|
||||||
|
#Distance is taken from the given distance sensor.
|
||||||
|
|
||||||
|
import pyb
|
||||||
|
import terminalfont
|
||||||
|
|
||||||
|
ZeroPoint = (0, 0)
|
||||||
|
DISPLAY_DELAY = 100
|
||||||
|
FONT_HEIGHT = terminalfont.terminalfont["Height"]
|
||||||
|
NUM_DISTANCES = 4 #The number of _distances to use for throwing away anomalies
|
||||||
|
THRESHOLD = 0.5
|
||||||
|
|
||||||
|
#100-15 = blue
|
||||||
|
#15-10 = green
|
||||||
|
#10-5 = yellow
|
||||||
|
#5-0 = red
|
||||||
|
|
||||||
|
COLORS = [(0, 255, 0, 0),
|
||||||
|
(.35, 255, 255, 0),
|
||||||
|
(.50, 0, 255, 0),
|
||||||
|
(.75, 0, 255, 255),
|
||||||
|
(1.0, 0, 0, 255)
|
||||||
|
]
|
||||||
|
|
||||||
|
def round( aValue ) :
|
||||||
|
'''Round float value to 2 decimal places'''
|
||||||
|
return (aValue - (aValue % 0.01))
|
||||||
|
|
||||||
|
def getrgb( aDisplay, aDistance, maxdist ) :
|
||||||
|
'''Get an interpolated color based on distance.
|
||||||
|
Uses the COLORS list.'''
|
||||||
|
clr = aDisplay.NAVY
|
||||||
|
|
||||||
|
def interp( l, v0, v1 ) :
|
||||||
|
return int(v0 * (1.0 - l) + (v1 * l))
|
||||||
|
|
||||||
|
for i in range(1, len(COLORS)) :
|
||||||
|
c = COLORS[i]
|
||||||
|
if c[0] * maxdist >= aDistance:
|
||||||
|
rng0, r0, g0, b0 = COLORS[i - 1]
|
||||||
|
rng1, r1, g1, b1 = c
|
||||||
|
rng0 *= maxdist
|
||||||
|
rng1 *= maxdist
|
||||||
|
#interpolate between rng0 and rng1
|
||||||
|
l = (aDistance - rng0) / float(rng1 - rng0)
|
||||||
|
r = interp(l, r0, r1)
|
||||||
|
g = interp(l, g0, g1)
|
||||||
|
b = interp(l, b0, b1)
|
||||||
|
clr = aDisplay.color(r,g,b)
|
||||||
|
break
|
||||||
|
return clr
|
||||||
|
|
||||||
|
class RangePoint(object):
|
||||||
|
"""Display a point on the screen"""
|
||||||
|
|
||||||
|
def __init__( self, size, maxrange ) :
|
||||||
|
self._size = (50, size)
|
||||||
|
self._pos = (-1, 0)
|
||||||
|
self._prevdistance = -1
|
||||||
|
self._maxrange = maxrange
|
||||||
|
|
||||||
|
def update( self, aDisplay, aDistance, aTime ) :
|
||||||
|
if (self._prevdistance != aDistance):
|
||||||
|
self._draw(aDisplay, 0)
|
||||||
|
clr = getrgb(aDisplay, aDistance, self._maxrange)
|
||||||
|
y = min(1.0, aDistance / self._maxrange)
|
||||||
|
self._pos = (int((aDisplay.size()[0] / 2) - (self._size[0] / 2)), int(y * aDisplay.size()[1] - self._size[1]))
|
||||||
|
self._draw(aDisplay, clr)
|
||||||
|
self._prevdistance = aDistance
|
||||||
|
|
||||||
|
def _draw( self, aDisplay, aColor ) :
|
||||||
|
if self._pos[0] >= 0:
|
||||||
|
aDisplay.fillrect(self._pos, self._size, aColor)
|
||||||
|
|
||||||
|
def wrap( aVal, aMax ) : return aVal if aVal < aMax else 0
|
||||||
|
|
||||||
|
class Display(object):
|
||||||
|
"""Display distance on ST7735 LCD with text and a box"""
|
||||||
|
def __init__( self, display, ranger ):
|
||||||
|
self._display = display
|
||||||
|
self._ranger = ranger
|
||||||
|
self._rangepoint = RangePoint(4, ranger.maxinches)
|
||||||
|
self._curdistance = 0.0
|
||||||
|
self._distances = [0.0] * NUM_DISTANCES
|
||||||
|
self._distindex = 0
|
||||||
|
|
||||||
|
def printdistance( self, aDistance ) :
|
||||||
|
s = "I:" + str(round(aDistance))
|
||||||
|
self._display.fillrect(ZeroPoint, (self._display.size()[0], FONT_HEIGHT * 2), 0)
|
||||||
|
self._display.text(ZeroPoint, s, self._display.CYAN, terminalfont.terminalfont, 2)
|
||||||
|
|
||||||
|
def _getdistance( self ) :
|
||||||
|
'''Throw away changes that are not averaged. This introduces
|
||||||
|
a slight delay in update but gets rid of most bad _distances'''
|
||||||
|
|
||||||
|
d = self._ranger.inches
|
||||||
|
# self._curdistance = d
|
||||||
|
good = 0
|
||||||
|
for c in self._distances :
|
||||||
|
if abs(c - d) < THRESHOLD:
|
||||||
|
good += 1
|
||||||
|
if good > 2:
|
||||||
|
self._curdistance = d
|
||||||
|
break
|
||||||
|
|
||||||
|
self._distances[self._distindex] = d
|
||||||
|
self._distindex = wrap(self._distindex + 1, NUM_DISTANCES)
|
||||||
|
return self._curdistance
|
||||||
|
|
||||||
|
def run( self ) :
|
||||||
|
self._display.fill(0)
|
||||||
|
sw = pyb.Switch()
|
||||||
|
lasttime = pyb.millis()
|
||||||
|
while sw() == False :
|
||||||
|
pyb.delay(DISPLAY_DELAY)
|
||||||
|
distance = self._getdistance()
|
||||||
|
|
||||||
|
thistime = pyb.millis()
|
||||||
|
t = thistime - lasttime
|
||||||
|
self.printdistance(distance)
|
||||||
|
self._rangepoint.update(self._display, distance, t / 1000.0)
|
||||||
|
lasttime = thistime
|
|
@ -0,0 +1,33 @@
|
||||||
|
|
||||||
|
from pyb import Pin, ADC
|
||||||
|
|
||||||
|
class IRDistance(object):
|
||||||
|
""" Driver for Sharp Gp2y0a IR distance sensor. The distance
|
||||||
|
range is around 3 to 40 inches. """
|
||||||
|
|
||||||
|
maxinches = 31.5 #Maximun range of IR board in inches.
|
||||||
|
_v2i = -1.02 #Voltage to inches power.
|
||||||
|
|
||||||
|
def __init__( self, pin ) :
|
||||||
|
"""pin may be name or pin object. It must be able to handle ADC input."""
|
||||||
|
|
||||||
|
if type(pin) == str:
|
||||||
|
p = Pin(pin)
|
||||||
|
elif type(pin) == Pin:
|
||||||
|
p = pin
|
||||||
|
else:
|
||||||
|
raise Exception("pin must be pin name or pyb.Pin able to support ADC")
|
||||||
|
|
||||||
|
self._adc = ADC(p)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def distance( self ) : return self._adc.read()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def inches( self ) :
|
||||||
|
volts = self.distance * 0.0048828125
|
||||||
|
return 65.0 * pow(volts, IRDistance._v2i)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def centimeters( self ) : return self.inches * 2.54
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
|
||||||
|
from pyb import UART, repl_uart, udelay
|
||||||
|
|
||||||
|
# JY-MCU Bluetooth board ----------------------------------------
|
||||||
|
|
||||||
|
# This opens connection with Bluetooth module connected to Y1, Y2 (UART 6)
|
||||||
|
# Then it sets the repl output to this UART.
|
||||||
|
#COMMANDS AT - does nothing but get an ok.
|
||||||
|
# The posible baudrates are:
|
||||||
|
# AT+BAUD1-------1200
|
||||||
|
# AT+BAUD2-------2400
|
||||||
|
# AT+BAUD3-------4800
|
||||||
|
# AT+BAUD4-------9600 - Default for hc-06
|
||||||
|
# AT+BAUD5------19200
|
||||||
|
# AT+BAUD6------38400
|
||||||
|
# AT+BAUD7------57600 - Johnny-five speed
|
||||||
|
# AT+BAUD8-----115200
|
||||||
|
# AT+BAUD9-----230400
|
||||||
|
# AT+BAUDA-----460800
|
||||||
|
# AT+BAUDB-----921600
|
||||||
|
# AT+BAUDC----1382400
|
||||||
|
# AT+VERSION
|
||||||
|
# AT+NAMEnewname This is the name that will show up in windows.
|
||||||
|
# AT+PIN???? set 4 digit pairing pin.
|
||||||
|
|
||||||
|
class JYMCU(object):
|
||||||
|
"""JY-MCU Bluetooth serial device driver. This is simply a light UART wrapper
|
||||||
|
with addition AT command methods to customize the device."""
|
||||||
|
|
||||||
|
def __init__( self, uart, baudrate ):
|
||||||
|
""" uart = uart #1-6, baudrate must match what is set on the JY-MCU.
|
||||||
|
Needs to be a #1-C. """
|
||||||
|
self._uart = UART(uart, baudrate)
|
||||||
|
|
||||||
|
def __del__( self ) : self._uart.deinit()
|
||||||
|
|
||||||
|
def any( self ) : return self._uart.any()
|
||||||
|
|
||||||
|
def write( self, astring ) : return self._uart.write(astring)
|
||||||
|
def writechar( self, achar ) : self._uart.writechar(achar)
|
||||||
|
|
||||||
|
def read( self, num = None ) : return self._uart.read(num)
|
||||||
|
def readline( self ) : return self._uart.readline()
|
||||||
|
def readchar( self ) : return self._uart.readchar()
|
||||||
|
def readall( self ) : return self._uart.readall()
|
||||||
|
def readinto( self, buf, count = None ) : return self._uart.readinto(buf, count)
|
||||||
|
|
||||||
|
def _cmd( self, cmd ) :
|
||||||
|
""" Send AT command, wait a bit then return result string. """
|
||||||
|
self._uart.write("AT+" + cmd)
|
||||||
|
udelay(500)
|
||||||
|
return self.readline()
|
||||||
|
|
||||||
|
def baudrate( self, rate ) :
|
||||||
|
""" Set the baud rate. Needs to be #1-C. """
|
||||||
|
return self._cmd("BAUD" + str(rate))
|
||||||
|
|
||||||
|
def name( self, name ) :
|
||||||
|
""" Set the name to show up on the connecting device. """
|
||||||
|
return self._cmd("NAME" + name)
|
||||||
|
|
||||||
|
def pin( self, pin ) :
|
||||||
|
""" Set the given 4 digit numeric pin. """
|
||||||
|
return self._cmd("PIN" + str(pin))
|
||||||
|
|
||||||
|
def version( self ) : return self._cmd("VERSION")
|
||||||
|
|
||||||
|
def setrepl( self ) : repl_uart(self._uart)
|
||||||
|
|
29
Lib/L298N.py
29
Lib/L298N.py
|
@ -1,28 +1,26 @@
|
||||||
#Driver for the L298N Dual HBridge motor controller.
|
#Driver for the L298N Dual HBridge motor controller.
|
||||||
|
|
||||||
from PWM import PWM
|
from PWM import PWM
|
||||||
from pyb import Pin
|
from pyb import Pin, delay
|
||||||
|
|
||||||
#motordata
|
|
||||||
#Forward pin
|
|
||||||
#Back pin
|
|
||||||
#Speed pin (PWM)
|
|
||||||
|
|
||||||
class Motor( ):
|
class Motor( ):
|
||||||
"""docstring for Motor"""
|
"""Control a motor connected to the L298N Dual motor controller."""
|
||||||
|
|
||||||
def __init__(self, forward, backward, speed):
|
def __init__( self, forward, backward, speed ) :
|
||||||
"""Speed = (pin name, timer#)"""
|
"""forward pin name, backward pin name, speed = (pin name, timer#)
|
||||||
|
Need to make sure the given timer # is associated with the speed
|
||||||
|
pin or an exception will be raised. The speed pin must support
|
||||||
|
PWM."""
|
||||||
self._forward = Pin(forward, Pin.OUT_PP)
|
self._forward = Pin(forward, Pin.OUT_PP)
|
||||||
self._backward = Pin(backward, Pin.OUT_PP)
|
self._backward = Pin(backward, Pin.OUT_PP)
|
||||||
self._speedControl = PWM(speed[0], speed[1])
|
self._speedControl = PWM(speed[0], speed[1])
|
||||||
self._speed = 0
|
self._speed = 0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def speed(self): return self._speed
|
def speed( self ) : return self._speed
|
||||||
|
|
||||||
@speed.setter
|
@speed.setter
|
||||||
def speed(self, value):
|
def speed( self, value ) :
|
||||||
self._speed = value
|
self._speed = value
|
||||||
if (value == 0):
|
if (value == 0):
|
||||||
self._forward.low()
|
self._forward.low()
|
||||||
|
@ -34,11 +32,12 @@ class Motor( ):
|
||||||
self._forward.high()
|
self._forward.high()
|
||||||
self._backward.low()
|
self._backward.low()
|
||||||
|
|
||||||
self._speedControl.pulse_width_percent = abs(value)
|
self._speedControl.pulse_width_percent = min(100, abs(value))
|
||||||
|
|
||||||
def brake( self ) :
|
def brake( self ) :
|
||||||
""" """
|
""" Brake the motor by sending power both directions. """
|
||||||
self._forward.high()
|
self._forward.high()
|
||||||
self._backward.high()
|
self._backward.high()
|
||||||
self._speedControl.pulse_width_percent(1.0)
|
self._speedControl.pulse_width_percent = 100
|
||||||
|
delay(1000)
|
||||||
|
self.speed = 0
|
||||||
|
|
16
Lib/PIR.py
16
Lib/PIR.py
|
@ -32,38 +32,38 @@ class PIR(object):
|
||||||
self._power.low()
|
self._power.low()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def power(self): return True if (self._power == None) else self._power.value()
|
def power( self ) : return True if (self._power == None) else self._power.value()
|
||||||
|
|
||||||
@power.setter
|
@power.setter
|
||||||
def power(self, value): self._onoff(value)
|
def power( self, value ) : self._onoff(value)
|
||||||
|
|
||||||
def on( self ) : self.power = True
|
def on( self ) : self.power = True
|
||||||
def off( self ) : self.power = False
|
def off( self ) : self.power = False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def trigger(self): return self._trigger.value()
|
def trigger( self ) : return self._trigger.value()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def interrupt(self): return self._interrupt
|
def interrupt( self ) : return self._interrupt
|
||||||
|
|
||||||
@interrupt.setter
|
@interrupt.setter
|
||||||
def interrupt(self, func):
|
def interrupt( self, func ) :
|
||||||
self._interrupt = None;
|
self._interrupt = None;
|
||||||
self._func = func
|
self._func = func
|
||||||
if (func != None):
|
if (func != None):
|
||||||
self._interrupt = pyb.ExtInt(self._trigger, pyb.ExtInt.IRQ_RISING_FALLING, pyb.Pin.PULL_DOWN, self._inthandler)
|
self._interrupt = pyb.ExtInt(self._trigger, pyb.ExtInt.IRQ_RISING_FALLING, pyb.Pin.PULL_DOWN, self._inthandler)
|
||||||
self._inton = True
|
self._inton = True
|
||||||
|
|
||||||
def _inthandler(self, line):
|
def _inthandler( self, line ) :
|
||||||
'''Function to handle interrupts and pass on to callback with on/off trigger state.'''
|
'''Function to handle interrupts and pass on to callback with on/off trigger state.'''
|
||||||
if (self._func != None):
|
if (self._func != None):
|
||||||
self._func(self.trigger)
|
self._func(self.trigger)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def inton(self): return self._inton
|
def inton( self ) : return self._inton
|
||||||
|
|
||||||
@inton.setter
|
@inton.setter
|
||||||
def inton(self, value):
|
def inton( self, value ) :
|
||||||
self._inton = value
|
self._inton = value
|
||||||
if self._interrupt != None:
|
if self._interrupt != None:
|
||||||
if value :
|
if value :
|
||||||
|
|
20
Lib/PWM.py
20
Lib/PWM.py
|
@ -30,11 +30,11 @@ class PWM(object):
|
||||||
}
|
}
|
||||||
|
|
||||||
class PWMException(Exception):
|
class PWMException(Exception):
|
||||||
def __init__(self, msg):
|
def __init__( self, msg ) :
|
||||||
self.msg = msg
|
self.msg = msg
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def timerandchannel( pinname, timernum ):
|
def timerandchannel( pinname, timernum ) :
|
||||||
try:
|
try:
|
||||||
a = PWM.PinChannels[pinname]
|
a = PWM.PinChannels[pinname]
|
||||||
if timernum <= 0:
|
if timernum <= 0:
|
||||||
|
@ -48,7 +48,7 @@ class PWM(object):
|
||||||
|
|
||||||
raise PWM.PWMException("Pin {} cannot use timer {}".format(pinname, timernum))
|
raise PWM.PWMException("Pin {} cannot use timer {}".format(pinname, timernum))
|
||||||
|
|
||||||
def __init__( self, p, timernum, afreq = 100 ):
|
def __init__( self, p, timernum, afreq = 100 ) :
|
||||||
isname = type(p) == str
|
isname = type(p) == str
|
||||||
pinname = p if isname else p.name()
|
pinname = p if isname else p.name()
|
||||||
timernum, channel = PWM.timerandchannel(pinname, timernum)
|
timernum, channel = PWM.timerandchannel(pinname, timernum)
|
||||||
|
@ -59,23 +59,23 @@ class PWM(object):
|
||||||
self._channel = self._timer.channel(channel, Timer.PWM, pin = p)
|
self._channel = self._timer.channel(channel, Timer.PWM, pin = p)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pulse_width(self): return self._channel.pulse_width()
|
def pulse_width( self ) : return self._channel.pulse_width()
|
||||||
|
|
||||||
@pulse_width.setter
|
@pulse_width.setter
|
||||||
def pulse_width(self, value): self._channel.pulse_width(value)
|
def pulse_width( self, value ) : self._channel.pulse_width(value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pulse_width_percent(self): return self._channel.pulse_width_percent()
|
def pulse_width_percent( self ) : return self._channel.pulse_width_percent()
|
||||||
|
|
||||||
@pulse_width_percent.setter
|
@pulse_width_percent.setter
|
||||||
def pulse_width_percent(self, value): self._channel.pulse_width_percent(value)
|
def pulse_width_percent( self, value ) : self._channel.pulse_width_percent(value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def freq(self): return self._timer.freq()
|
def freq( self ) : return self._timer.freq()
|
||||||
|
|
||||||
@freq.setter
|
@freq.setter
|
||||||
def freq(self, value): self._timer.freq(value)
|
def freq( self, value ) : self._timer.freq(value)
|
||||||
|
|
||||||
def callback(self, value):
|
def callback( self, value ) :
|
||||||
self._channel.callback(value)
|
self._channel.callback(value)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
#Control a relay board.
|
||||||
|
|
||||||
|
from pyb import Pin
|
||||||
|
|
||||||
|
class Relay(object):
|
||||||
|
"""Control a relay board with an output pin. Set on to True to drive the relay pin low
|
||||||
|
which turns the relay on."""
|
||||||
|
|
||||||
|
def __init__( self, pin ) :
|
||||||
|
"""Pin may be a pin name or pyb.Pin object set for output."""
|
||||||
|
|
||||||
|
if type(pin) == str:
|
||||||
|
self._pin = Pin(pin, Pin.OUT_PP, Pin.PULL_DOWN)
|
||||||
|
elif type(pin) == Pin:
|
||||||
|
self._pin = pin
|
||||||
|
else:
|
||||||
|
raise Exception("pin must be pin name or pyb.Pin")
|
||||||
|
|
||||||
|
self.on = False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def on( self ) : return self._pin.value()
|
||||||
|
|
||||||
|
@on.setter
|
||||||
|
def on( self, value ) :
|
||||||
|
if value:
|
||||||
|
self._pin.low()
|
||||||
|
else:
|
||||||
|
self._pin.high()
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
|
||||||
|
from pyb import Pin, Timer, udelay
|
||||||
|
|
||||||
|
# WARNING: Do not use PA4-X5 or PA5-X6 as the echo pin without a 1k resistor.
|
||||||
|
|
||||||
|
class SR04Distance(object):
|
||||||
|
""" """
|
||||||
|
|
||||||
|
maxinches = 20 #maximum range of SR04.
|
||||||
|
|
||||||
|
def __init__( self, tpin, epin, timer=2 ) :
|
||||||
|
""" """
|
||||||
|
|
||||||
|
if type(tpin) == str:
|
||||||
|
self._tpin = Pin(tpin, Pin.OUT_PP, Pin.PULL_NONE)
|
||||||
|
elif type(tpin) == Pin:
|
||||||
|
self._tpin = tpin
|
||||||
|
else:
|
||||||
|
raise Exception("trigger pin must be pin name or pyb.Pin configured for output.")
|
||||||
|
|
||||||
|
self._tpin.low()
|
||||||
|
|
||||||
|
if type(epin) == str:
|
||||||
|
self._epin = Pin(epin, Pin.IN, Pin.PULL_NONE)
|
||||||
|
elif type(epin) == Pin:
|
||||||
|
self._epin = epin
|
||||||
|
else:
|
||||||
|
raise Exception("echo pin must be pin name or pyb.Pin configured for input.")
|
||||||
|
|
||||||
|
# Create a microseconds counter.
|
||||||
|
self._micros = Timer(timer, prescaler=83, period=0x3fffffff)
|
||||||
|
|
||||||
|
def __del__( self ) :
|
||||||
|
self._micros.deinit()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def counter( self ) : return self._micros.counter()
|
||||||
|
|
||||||
|
@counter.setter
|
||||||
|
def counter( self, value ) : self._micros.counter(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def centimeters( self ) :
|
||||||
|
start = 0
|
||||||
|
end = 0
|
||||||
|
|
||||||
|
self.counter = 0
|
||||||
|
|
||||||
|
#Send 10us pulse.
|
||||||
|
self._tpin.high()
|
||||||
|
udelay(10)
|
||||||
|
self._tpin.low()
|
||||||
|
|
||||||
|
while not self._epin.value():
|
||||||
|
start = self.counter
|
||||||
|
|
||||||
|
j = 0
|
||||||
|
|
||||||
|
# Wait 'till the pulse is gone.
|
||||||
|
while self._epin.value() and j < 1000:
|
||||||
|
j += 1
|
||||||
|
end = self.counter
|
||||||
|
|
||||||
|
# Calc the duration of the recieved pulse, divide the result by
|
||||||
|
# 2 (round-trip) and divide it by 29 (the speed of sound is
|
||||||
|
# 340 m/s and that is 29 us/cm).
|
||||||
|
return (end - start) / 58
|
||||||
|
|
||||||
|
@property
|
||||||
|
def inches( self ) : return self.centimeters * 0.3937
|
||||||
|
|
|
@ -95,11 +95,11 @@ class TFT(object) :
|
||||||
GRAY = TFTColor(0x80, 0x80, 0x80)
|
GRAY = TFTColor(0x80, 0x80, 0x80)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def color(aR, aG, aB):
|
def color( aR, aG, aB ) :
|
||||||
'''Create a 565 rgb TFTColor value'''
|
'''Create a 565 rgb TFTColor value'''
|
||||||
return TFTColor(aR, aG, aB)
|
return TFTColor(aR, aG, aB)
|
||||||
|
|
||||||
def __init__(self, aLoc, aDC, aReset) :
|
def __init__( self, aLoc, aDC, aReset ) :
|
||||||
"""aLoc SPI pin location is either 1 for 'X' or 2 for 'Y'.
|
"""aLoc SPI pin location is either 1 for 'X' or 2 for 'Y'.
|
||||||
aDC is the DC pin and aReset is the reset pin."""
|
aDC is the DC pin and aReset is the reset pin."""
|
||||||
self._size = ScreenSize
|
self._size = ScreenSize
|
||||||
|
@ -115,7 +115,7 @@ class TFT(object) :
|
||||||
self.colorData = bytearray(2)
|
self.colorData = bytearray(2)
|
||||||
self.windowLocData = bytearray(4)
|
self.windowLocData = bytearray(4)
|
||||||
|
|
||||||
def size( self ):
|
def size( self ) :
|
||||||
return self._size
|
return self._size
|
||||||
|
|
||||||
# @micropython.native
|
# @micropython.native
|
||||||
|
@ -448,7 +448,7 @@ class TFT(object) :
|
||||||
self._writedata(TFTRotations[self.rotate] | rgb)
|
self._writedata(TFTRotations[self.rotate] | rgb)
|
||||||
|
|
||||||
@micropython.native
|
@micropython.native
|
||||||
def _reset(self):
|
def _reset( self ) :
|
||||||
'''Reset the device.'''
|
'''Reset the device.'''
|
||||||
self.dc.low()
|
self.dc.low()
|
||||||
self.reset.high()
|
self.reset.high()
|
||||||
|
@ -458,7 +458,7 @@ class TFT(object) :
|
||||||
self.reset.high()
|
self.reset.high()
|
||||||
pyb.delay(500)
|
pyb.delay(500)
|
||||||
|
|
||||||
def initb(self):
|
def initb( self ) :
|
||||||
'''Initialize blue tab version.'''
|
'''Initialize blue tab version.'''
|
||||||
self._size = (ScreenSize[0] + 2, ScreenSize[1] + 1)
|
self._size = (ScreenSize[0] + 2, ScreenSize[1] + 1)
|
||||||
self._reset()
|
self._reset()
|
||||||
|
@ -556,7 +556,7 @@ class TFT(object) :
|
||||||
self.cs.high()
|
self.cs.high()
|
||||||
pyb.delay(500)
|
pyb.delay(500)
|
||||||
|
|
||||||
def initr(self):
|
def initr( self ) :
|
||||||
'''Initialize a red tab version.'''
|
'''Initialize a red tab version.'''
|
||||||
self._reset()
|
self._reset()
|
||||||
|
|
||||||
|
@ -653,7 +653,7 @@ class TFT(object) :
|
||||||
self.cs.high()
|
self.cs.high()
|
||||||
|
|
||||||
@micropython.native
|
@micropython.native
|
||||||
def initg(self):
|
def initg( self ) :
|
||||||
'''Initialize a green tab version.'''
|
'''Initialize a green tab version.'''
|
||||||
self._reset()
|
self._reset()
|
||||||
|
|
||||||
|
@ -741,21 +741,21 @@ class TFT(object) :
|
||||||
|
|
||||||
self.cs.high()
|
self.cs.high()
|
||||||
|
|
||||||
def maker():
|
def maker( ) :
|
||||||
t = TFT(1, "X1", "X2")
|
t = TFT(1, "X1", "X2")
|
||||||
print("Initializing")
|
print("Initializing")
|
||||||
t.initr()
|
t.initr()
|
||||||
t.fill(0)
|
t.fill(0)
|
||||||
return t
|
return t
|
||||||
|
|
||||||
def makeb( ):
|
def makeb( ) :
|
||||||
t = TFT(1, "X1", "X2")
|
t = TFT(1, "X1", "X2")
|
||||||
print("Initializing")
|
print("Initializing")
|
||||||
t.initb()
|
t.initb()
|
||||||
t.fill(0)
|
t.fill(0)
|
||||||
return t
|
return t
|
||||||
|
|
||||||
def makeg( ):
|
def makeg( ) :
|
||||||
t = TFT(1, "X1", "X2")
|
t = TFT(1, "X1", "X2")
|
||||||
print("Initializing")
|
print("Initializing")
|
||||||
t.initg()
|
t.initg()
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
##
|
|
||||||
# Ultrasonic library for MicroPython's pyboard.
|
|
||||||
# Compatible with HC-SR04 and SRF04.
|
|
||||||
#
|
|
||||||
# Copyright 2014 - Sergio Conde Gómez <skgsergio@gmail.com>
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
##
|
|
||||||
|
|
||||||
import pyb
|
|
||||||
|
|
||||||
# Pin configuration.
|
|
||||||
# WARNING: Do not use PA4-X5 or PA5-X6 as the echo pin without a 1k resistor.
|
|
||||||
|
|
||||||
def wait( aCount ):
|
|
||||||
j = 0;
|
|
||||||
for i in range(aCount):
|
|
||||||
j += i
|
|
||||||
|
|
||||||
class Ultrasonic:
|
|
||||||
def __init__(self, tPin, ePin):
|
|
||||||
self.triggerPin = tPin
|
|
||||||
self.echoPin = ePin
|
|
||||||
|
|
||||||
# Init trigger pin (out)
|
|
||||||
self.trigger = pyb.Pin(self.triggerPin)
|
|
||||||
self.trigger.init(pyb.Pin.OUT_PP, pyb.Pin.PULL_NONE)
|
|
||||||
self.trigger.low()
|
|
||||||
|
|
||||||
# Init echo pin (in)
|
|
||||||
self.echo = pyb.Pin(self.echoPin)
|
|
||||||
self.echo.init(pyb.Pin.IN, pyb.Pin.PULL_NONE)
|
|
||||||
|
|
||||||
def distance_in_inches(self):
|
|
||||||
return (self.distance_in_cm() * 0.3937)
|
|
||||||
|
|
||||||
def distance_in_cm(self):
|
|
||||||
start = 0
|
|
||||||
end = 0
|
|
||||||
|
|
||||||
# Create a microseconds counter.
|
|
||||||
micros = pyb.Timer(2, prescaler=83, period=0x3fffffff)
|
|
||||||
micros.counter(0)
|
|
||||||
|
|
||||||
# Send a 10us pulse.
|
|
||||||
self.trigger.high()
|
|
||||||
pyb.udelay(10)
|
|
||||||
self.trigger.low()
|
|
||||||
|
|
||||||
# Wait 'till whe pulse starts.
|
|
||||||
while self.echo.value() == 0:
|
|
||||||
start = micros.counter()
|
|
||||||
|
|
||||||
j = 0
|
|
||||||
|
|
||||||
# Wait 'till the pulse is gone.
|
|
||||||
while self.echo.value() == 1 and j < 1000:
|
|
||||||
# print("wait end")
|
|
||||||
# wait(1000)
|
|
||||||
j += 1
|
|
||||||
end = micros.counter()
|
|
||||||
|
|
||||||
# Deinit the microseconds counter
|
|
||||||
micros.deinit()
|
|
||||||
|
|
||||||
# Calc the duration of the recieved pulse, divide the result by
|
|
||||||
# 2 (round-trip) and divide it by 29 (the speed of sound is
|
|
||||||
# 340 m/s and that is 29 us/cm).
|
|
||||||
dist_in_cm = ((end - start) / 2) / 29
|
|
||||||
|
|
||||||
return dist_in_cm
|
|
144
SonarDisplay.py
144
SonarDisplay.py
|
@ -1,144 +0,0 @@
|
||||||
#Display distance reported by the HC-SR04 on the ST7735 LCD.
|
|
||||||
|
|
||||||
import ultrasonic
|
|
||||||
import pyb
|
|
||||||
import terminalfont
|
|
||||||
|
|
||||||
ZeroPoint = (0, 0)
|
|
||||||
SONAR_DELAY = 100
|
|
||||||
MAX_RANGE = 25.0
|
|
||||||
FONT_HEIGHT = terminalfont.terminalfont["Height"]
|
|
||||||
NUM_DISTANCES = 4 #The number of distances to use for throwing away anomalies
|
|
||||||
THRESHOLD = 1.0
|
|
||||||
|
|
||||||
#100-15 = blue
|
|
||||||
#15-10 = green
|
|
||||||
#10-5 = yellow
|
|
||||||
#5-0 = red
|
|
||||||
|
|
||||||
COLORS = [(0, 255, 0, 0),
|
|
||||||
(5, 255, 255, 0),
|
|
||||||
(10, 0, 255, 0),
|
|
||||||
(15, 0, 255, 255),
|
|
||||||
(20, 0, 0, 255)
|
|
||||||
]
|
|
||||||
|
|
||||||
def round( aValue ) :
|
|
||||||
'''Round float value to 2 decimal places'''
|
|
||||||
return (aValue - (aValue % 0.01))
|
|
||||||
|
|
||||||
def getrgb( aDisplay, aDistance ) :
|
|
||||||
'''Get an interpolated color based on distance.
|
|
||||||
Uses the COLORS list.'''
|
|
||||||
clr = aDisplay.NAVY
|
|
||||||
|
|
||||||
def interp(l, v0, v1):
|
|
||||||
return int(v0 * (1.0 - l) + (v1 * l))
|
|
||||||
|
|
||||||
for i in range(1, len(COLORS)) :
|
|
||||||
c = COLORS[i]
|
|
||||||
if c[0] >= aDistance:
|
|
||||||
rng0, r0, g0, b0 = COLORS[i - 1]
|
|
||||||
rng1, r1, g1, b1 = c
|
|
||||||
#interpolate between rng0 and rng1
|
|
||||||
l = (aDistance - rng0) / float(rng1 - rng0)
|
|
||||||
r = interp(l, r0, r1)
|
|
||||||
g = interp(l, g0, g1)
|
|
||||||
b = interp(l, b0, b1)
|
|
||||||
clr = aDisplay.color(r,g,b)
|
|
||||||
break
|
|
||||||
|
|
||||||
return clr
|
|
||||||
|
|
||||||
class RangePoint(object):
|
|
||||||
"""Display a point on the screen"""
|
|
||||||
|
|
||||||
def __init__(self, aSize):
|
|
||||||
self.size = (50, aSize)
|
|
||||||
self.pos = (-1, 0)
|
|
||||||
self.prevdistance = -1
|
|
||||||
|
|
||||||
def update( self, aDisplay, aDistance, aTime ) :
|
|
||||||
if (self.prevdistance != aDistance):
|
|
||||||
self._draw(aDisplay, 0)
|
|
||||||
clr = getrgb(aDistance)
|
|
||||||
y = min(1.0, aDistance / MAX_RANGE)
|
|
||||||
self.pos = (int((aDisplay.size[0] / 2) - (self.size[0] / 2)), int(y * aDisplay.size[1] - self.size[1]))
|
|
||||||
self._draw(aDisplay, clr)
|
|
||||||
self.prevdistance = aDistance
|
|
||||||
|
|
||||||
def _draw( self, aDisplay, aColor ) :
|
|
||||||
if self.pos[0] >= 0:
|
|
||||||
aDisplay.fillrect(self.pos, self.size, aColor)
|
|
||||||
|
|
||||||
def wrap( aVal, aMax ) :
|
|
||||||
return aVal if aVal < aMax else 0
|
|
||||||
|
|
||||||
class SonarDisplay(object):
|
|
||||||
"""Display HC-SR04 distance on ST7735 LCD with text and a box"""
|
|
||||||
def __init__( self, aDisplay, aTrigger, aEcho ):
|
|
||||||
self.display = aDisplay
|
|
||||||
self.triggerpin = aTrigger
|
|
||||||
self.echopin = aEcho
|
|
||||||
self.rangepoint = RangePoint(4)
|
|
||||||
self.curdistance = 0.0
|
|
||||||
self.distances = [0.0] * NUM_DISTANCES
|
|
||||||
self.distindex = 0
|
|
||||||
self.hc = ultrasonic.Ultrasonic(self.triggerpin, self.echopin)
|
|
||||||
|
|
||||||
def printdistance( self, aDistance ) :
|
|
||||||
s = "I:" + str(round(aDistance))
|
|
||||||
self.display.fillrect(ZeroPoint, (self.display.size[0], FONT_HEIGHT), 0)
|
|
||||||
self.display.text(ZeroPoint, s, CYAN, terminalfont.terminalfont)
|
|
||||||
|
|
||||||
def _getdistance( self ) :
|
|
||||||
'''Throw away changes that are not averaged. This introduces
|
|
||||||
a slight delay in update but gets rid of most bad distances'''
|
|
||||||
|
|
||||||
d = self.hc.distance_in_inches()
|
|
||||||
good = 0
|
|
||||||
for c in self.distances :
|
|
||||||
if abs(c - d) < THRESHOLD:
|
|
||||||
good += 1
|
|
||||||
if good > 2:
|
|
||||||
self.curdistance = d
|
|
||||||
break
|
|
||||||
|
|
||||||
self.distances[self.distindex] = d
|
|
||||||
self.distindex = wrap(self.distindex + 1, NUM_DISTANCES)
|
|
||||||
return self.curdistance
|
|
||||||
|
|
||||||
def run( self ):
|
|
||||||
self.display.fill(0)
|
|
||||||
sw = pyb.Switch()
|
|
||||||
lasttime = pyb.millis()
|
|
||||||
while sw() == False :
|
|
||||||
pyb.delay(SONAR_DELAY)
|
|
||||||
distance = self._getdistance()
|
|
||||||
|
|
||||||
thistime = pyb.millis()
|
|
||||||
t = thistime - lasttime
|
|
||||||
self.printdistance(distance)
|
|
||||||
self.rangepoint.update(self.display, distance, t / 1000.0)
|
|
||||||
lasttime = thistime
|
|
||||||
|
|
||||||
# sensor1_trigPin = pyb.Pin.board.X8
|
|
||||||
# sensor1_echoPin = pyb.Pin.board.X7
|
|
||||||
|
|
||||||
# sensor1 = ultrasonic.Ultrasonic(sensor1_trigPin, sensor1_echoPin)
|
|
||||||
|
|
||||||
# switch = pyb.Switch()
|
|
||||||
|
|
||||||
# # function that prints each sensor's distance
|
|
||||||
# def print_sensor_values():
|
|
||||||
# # get sensor1's distance in cm
|
|
||||||
# distance1 = sensor1.distance_in_inches()
|
|
||||||
|
|
||||||
# print("Sensor1", distance1, "inches")
|
|
||||||
|
|
||||||
# # prints values every second
|
|
||||||
# while True:
|
|
||||||
# print("Sensing")
|
|
||||||
# print_sensor_values()
|
|
||||||
# # ultrasonic.wait(10000)
|
|
||||||
# pyb.delay(100)
|
|
|
@ -12,7 +12,7 @@ class TreatThrower(object):
|
||||||
servoTime = 1450
|
servoTime = 1450
|
||||||
ledNum = 3
|
ledNum = 3
|
||||||
|
|
||||||
def __init__(self, sensor, servonum = 3):
|
def __init__( self, sensor, servonum = 3 ) :
|
||||||
self._sensor = sensor
|
self._sensor = sensor
|
||||||
self._servo = pyb.Servo(servonum)
|
self._servo = pyb.Servo(servonum)
|
||||||
mn, mx, _, a, s = self._servo.calibration()
|
mn, mx, _, a, s = self._servo.calibration()
|
||||||
|
|
Plik binarny nie jest wyświetlany.
4
bombs.py
4
bombs.py
|
@ -7,7 +7,7 @@ import time
|
||||||
|
|
||||||
class bomb(object):
|
class bomb(object):
|
||||||
"""Animate a circle on the screen."""
|
"""Animate a circle on the screen."""
|
||||||
def __init__(self, aPos, aRadius, aColor, aSpeed):
|
def __init__( self, aPos, aRadius, aColor, aSpeed ) :
|
||||||
self.pos = aPos
|
self.pos = aPos
|
||||||
self.radius = aRadius
|
self.radius = aRadius
|
||||||
self.color = aColor
|
self.color = aColor
|
||||||
|
@ -35,7 +35,7 @@ def randval( aVal ) :
|
||||||
|
|
||||||
class bomber(object):
|
class bomber(object):
|
||||||
"""Control a bunch of bombs."""
|
"""Control a bunch of bombs."""
|
||||||
def __init__(self, aDisplay):
|
def __init__( self, aDisplay ) :
|
||||||
self.display = aDisplay
|
self.display = aDisplay
|
||||||
self.ds = self.display.size()
|
self.ds = self.display.size()
|
||||||
self.numbombs = 4
|
self.numbombs = 4
|
||||||
|
|
4
level.py
4
level.py
|
@ -8,7 +8,7 @@ ZeroPoint = (0, 0)
|
||||||
class Bubble(object):
|
class Bubble(object):
|
||||||
"""Circle simulating the level bubble."""
|
"""Circle simulating the level bubble."""
|
||||||
|
|
||||||
def __init__(self, aCenter, aSpeed, aRadius, aColor):
|
def __init__( self, aCenter, aSpeed, aRadius, aColor ) :
|
||||||
self.center = aCenter
|
self.center = aCenter
|
||||||
self.pos = aCenter
|
self.pos = aCenter
|
||||||
self.oldpos = self.pos
|
self.oldpos = self.pos
|
||||||
|
@ -52,7 +52,7 @@ class Bubble(object):
|
||||||
class Level(object):
|
class Level(object):
|
||||||
"""Simulate a level by controlling a bubble on the aDisplay
|
"""Simulate a level by controlling a bubble on the aDisplay
|
||||||
controlled by the accelerometer."""
|
controlled by the accelerometer."""
|
||||||
def __init__(self, aDisplay):
|
def __init__( self, aDisplay ) :
|
||||||
self.display = aDisplay
|
self.display = aDisplay
|
||||||
cx, cy = aDisplay.size()
|
cx, cy = aDisplay.size()
|
||||||
cx /= 2
|
cx /= 2
|
||||||
|
|
64
main.py
64
main.py
|
@ -1,16 +1,9 @@
|
||||||
# main.py -- put your code here!
|
# main.py -- put your code here!
|
||||||
|
|
||||||
# import Balance
|
|
||||||
|
|
||||||
# Balance.main()
|
|
||||||
|
|
||||||
# from seriffont import *
|
# from seriffont import *
|
||||||
# from sysfont import *
|
# from sysfont import *
|
||||||
from terminalfont import *
|
# from terminalfont import *
|
||||||
# from SonarDisplay import SonarDisplay
|
|
||||||
|
|
||||||
pyt = 0
|
pyt = 0
|
||||||
|
|
||||||
if pyt :
|
if pyt :
|
||||||
from ST7735 import makeg
|
from ST7735 import makeg
|
||||||
t = makeg()
|
t = makeg()
|
||||||
|
@ -18,42 +11,65 @@ else:
|
||||||
t = pyb.TFT("x", "X1", "X2")
|
t = pyb.TFT("x", "X1", "X2")
|
||||||
t.initg()
|
t.initg()
|
||||||
|
|
||||||
t.fill(0)
|
# t.fill(0)
|
||||||
|
|
||||||
# import TFT
|
# import TFT
|
||||||
# TFT.run(t)
|
# TFT.run(t)
|
||||||
|
|
||||||
def tst( aColor ):
|
# Display animated circle on TFT -------------------------
|
||||||
s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=_+[]{}l;'<>?,./!@#$%^&*():"
|
|
||||||
# t.text(Point(0, 0), s, aColor, basicfont)
|
|
||||||
# t.text(Point(0, 40), s, aColor, seriffont)
|
|
||||||
t.text((0, 40), s, aColor, terminalfont)
|
|
||||||
|
|
||||||
# tst(BLUE)
|
|
||||||
|
|
||||||
def s(aRot, aColor):
|
|
||||||
t.rotation(aRot)
|
|
||||||
tst(aColor)
|
|
||||||
|
|
||||||
# from bombs import bomber
|
# from bombs import bomber
|
||||||
# t.rotation(2)
|
# t.rotation(2)
|
||||||
# b = bomber(t)
|
# b = bomber(t)
|
||||||
# b.run()
|
# b.run()
|
||||||
|
|
||||||
|
# Accelerometer display ----------------------------------
|
||||||
|
|
||||||
|
# import Balance
|
||||||
|
# Balance.main()
|
||||||
|
|
||||||
|
# Carpenter level display using accelerometer ------------
|
||||||
|
|
||||||
# from level import Level
|
# from level import Level
|
||||||
# l = Level(t)
|
# l = Level(t)
|
||||||
# l.run()
|
# l.run()
|
||||||
|
|
||||||
# sd = SonarDisplay(t, "X3", "X4")
|
# PIR motion sensor --------------------------------------
|
||||||
# sd.run()
|
|
||||||
|
|
||||||
# import motion
|
# import motion
|
||||||
# m = motion.motion(t)
|
# m = motion.motion(t)
|
||||||
# # m.run()
|
# # m.run()
|
||||||
|
|
||||||
|
# Cat Treat Thrower --------------------------------------
|
||||||
|
|
||||||
# import TreatThrower
|
# import TreatThrower
|
||||||
# tt = TreatThrower.TreatThrower(m)
|
# tt = TreatThrower.TreatThrower(m)
|
||||||
# tt.run()
|
# tt.run()
|
||||||
|
|
||||||
from L298N import Motor
|
# L2082 Motor control ------------------------------------
|
||||||
m = Motor('Y2', 'Y1', ('Y3', 10))
|
|
||||||
|
# from L298N import Motor
|
||||||
|
# m1 = Motor('Y1', 'Y2', ('Y3', 4))
|
||||||
|
# m2 = Motor('Y5', 'Y6', ('Y4', 4))
|
||||||
|
|
||||||
|
# IR or SR04 distance display ----------------------------
|
||||||
|
|
||||||
|
# from IRDistance import IRDistance
|
||||||
|
# r = IRDistance("X12")
|
||||||
|
|
||||||
|
# from SR04Distance import SR04Distance
|
||||||
|
# r = SR04Distance("Y2", "Y1")
|
||||||
|
|
||||||
|
# t.rotation(2)
|
||||||
|
# from DistanceDisplay import Display
|
||||||
|
# d = Display(t, r)
|
||||||
|
# d.run()
|
||||||
|
|
||||||
|
# Bluetooth board ----------------------------------------
|
||||||
|
|
||||||
|
from JYMCU import JYMCU
|
||||||
|
|
||||||
|
u = JYMCU(6, 57600)
|
||||||
|
u.write("Testing.")
|
||||||
|
u.readline()
|
||||||
|
u.setrepl()
|
||||||
|
|
|
@ -12,7 +12,7 @@ class motion(PIR.PIR):
|
||||||
processdelay = 100
|
processdelay = 100
|
||||||
|
|
||||||
"""detect motion and print msg on TFT"""
|
"""detect motion and print msg on TFT"""
|
||||||
def __init__(self, display):
|
def __init__( self, display ) :
|
||||||
super(motion, self).__init__(None, "X12", self.msg)
|
super(motion, self).__init__(None, "X12", self.msg)
|
||||||
self._extpower = pyb.Pin("X11", pyb.Pin.OUT_PP)
|
self._extpower = pyb.Pin("X11", pyb.Pin.OUT_PP)
|
||||||
self._extpower.high()
|
self._extpower.high()
|
||||||
|
|
Ładowanie…
Reference in New Issue