Skip to content

Commit b2ae1dc

Browse files
author
Thomas Preston
committed
Merge branch 'master' of oscar:/data/gitrepos/codebug/codebug_tether
2 parents 784a238 + 35d1a13 commit b2ae1dc

File tree

9 files changed

+154
-102
lines changed

9 files changed

+154
-102
lines changed

CHANGELOG

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
Change Log
22
==========
33

4+
v0.9.0
5+
------
6+
- Added `scroll_sprite` method.
7+
- Moved platform checking code to its own module.
8+
9+
v0.8.6
10+
------
11+
- Fixed bug with vertical sprites not allocating the correct amount of
12+
sprite space.
13+
14+
v0.8.5
15+
------
16+
- Fixed timing issue with servos and USB response.
17+
418
v0.8.4
519
------
620
- Default serial port is set to blank on error and added 'requires' to

codebug_tether/core.py

Lines changed: 52 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,13 @@
11
from __future__ import print_function
2-
import os
3-
import sys
4-
import glob
52
import time
63
import serial
74
import struct
8-
from codebug_tether.i2c import *
9-
from codebug_tether.serial_channel_device import SerialChannelDevice
10-
11-
12-
########################################################################
13-
# setup DEFAULT_SERIAL_PORT which is different on Windows, MacOS,
14-
# Raspberry Pi 2 and Raspberry Pi 3
15-
if sys.platform.startswith('win') or sys.platform.startswith('darwin'):
16-
# On Windows or OSX take the first serial port we can find
17-
def serial_ports():
18-
""" Lists serial port names
19-
20-
:raises EnvironmentError:
21-
On unsupported or unknown platforms
22-
:returns:
23-
A list of the serial ports available on the system
24-
"""
25-
if sys.platform.startswith('win'):
26-
ports = ['COM%s' % (i + 1) for i in range(256)]
27-
elif (sys.platform.startswith('linux') or
28-
sys.platform.startswith('cygwin')):
29-
# this excludes your current terminal "/dev/tty"
30-
ports = glob.glob('/dev/tty[A-Za-z0-9]*')
31-
elif sys.platform.startswith('darwin'):
32-
ports = glob.glob('/dev/tty.*')
33-
else:
34-
raise EnvironmentError('Unsupported platform')
35-
36-
result = []
37-
for port in ports:
38-
try:
39-
s = serial.Serial(port)
40-
s.close()
41-
result.append(port)
42-
except (OSError, serial.SerialException):
43-
pass
44-
return result
45-
# use the first one
46-
try:
47-
DEFAULT_SERIAL_PORT = serial_ports()[0]
48-
except IndexError:
49-
print('ERROR: Could not find any serial ports.', file=sys.stderr)
50-
DEFAULT_SERIAL_PORT = ''
51-
else:
52-
# otherwise assume we're on Raspberry Pi/Linux
53-
def get_rpi_revision():
54-
"""Returns the version number from the revision line."""
55-
for line in open("/proc/cpuinfo"):
56-
if "Revision" in line:
57-
import re
58-
return re.sub('Revision\t: ([a-z0-9]+)\n', r'\1', line)
59-
60-
rpi_revision = get_rpi_revision()
61-
if (rpi_revision and
62-
(rpi_revision != 'Beta') and
63-
(int('0x'+rpi_revision, 16) >= 0xa02082)):
64-
# RPi 3 and above
65-
DEFAULT_SERIAL_PORT = '/dev/ttyS0'
66-
else:
67-
# RPi 2 and below
68-
DEFAULT_SERIAL_PORT = '/dev/ttyACM0'
69-
########################################################################
5+
from .i2c import *
6+
from .serial_channel_device import SerialChannelDevice
7+
from .platform import get_platform_serial_port
8+
9+
10+
DEFAULT_SERIAL_PORT = get_platform_serial_port()
7011

7112
IO_DIGITAL_OUTPUT = 0
7213
IO_DIGITAL_INPUT = 1
@@ -231,19 +172,19 @@ def set_leg_io(self, leg_index, direction):
231172
def pwm_on(self, t2_prescale, full_period, on_period):
232173
"""Turns on the PWM generator with the given settings.
233174
234-
:param t2_prescale: One of T2_PS_1_1, T2_PS_1_4, T2_PS_1_16
235-
Scales down the 12MHz instruction clock by
236-
1, 4 or 16.
237-
:param full_period: 8-bit value - which is scaled up to 10-bits
238-
(<< 2) - to which timer 2 will count up to
239-
before resetting PWM output to 1.
240-
:param on_period: 10-bit value to which timer 2 will count up to
241-
before setting PWM output to 0. Use this with
242-
full_period to control duty cycle. For
243-
example:
175+
Args:
176+
t2_prescale: One of T2_PS_1_1, T2_PS_1_4, T2_PS_1_16
177+
Scales down the 12MHz instruction clock by
178+
1, 4 or 16.
179+
full_period: 8-bit value - which is scaled up to 10-bits
180+
(<< 2) - to which timer 2 will count up to
181+
before resetting PWM output to 1.
182+
on_period: 10-bit value to which timer 2 will count up to
183+
before setting PWM output to 0. Use this with
184+
full_period to control duty cycle. For example:
244185
245-
# 12MHz / 16 with 50% duty cycle
246-
codebug.pwm_on(T2_PS_1_16, 0xff, 0x200)
186+
# 12MHz / 16 with 50% duty cycle
187+
codebug.pwm_on(T2_PS_1_16, 0xff, 0x200)
247188
248189
"""
249190
# full period
@@ -394,6 +335,34 @@ def draw_sprite(self, x, y, sprite, clear_first=True):
394335
for i, row in enumerate(cb_rows):
395336
self.or_mask(i, bytes(row))
396337

338+
def scroll_sprite(self, sprite, interval=0.1, direction='L'):
339+
"""Scrolls a sprite.
340+
341+
Args:
342+
sprite: The sprite to scroll.
343+
interval: The time delay between each movement in seconds.
344+
(optional)
345+
direction: The direction of the scroll ('L', 'R', 'U', 'D').
346+
347+
"""
348+
direction = direction.upper()[0] # only take the first char
349+
if direction == 'L':
350+
for i in range(sprite.width+5):
351+
self.draw_sprite(5-i, 0, sprite)
352+
time.sleep(interval)
353+
elif direction == 'D':
354+
for i in range(sprite.height+5):
355+
self.draw_sprite(0, 5-i, sprite)
356+
time.sleep(interval)
357+
elif direction == 'R':
358+
for i in reversed(range(sprite.width+5)):
359+
self.draw_sprite(5-i, 0, sprite)
360+
time.sleep(interval)
361+
elif direction == 'U':
362+
for i in reversed(range(sprite.height+5)):
363+
self.draw_sprite(0, 5-i, sprite)
364+
time.sleep(interval)
365+
397366
def config_extension_io(self):
398367
self.set(CHANNEL_INDEX_EXT_CONF, EXTENSION_CONF_IO)
399368

@@ -449,10 +418,12 @@ def i2c_transaction(self,
449418
"""Run an I2C transaction using the extensions pins. Be sure to
450419
configure the extension pins first.
451420
452-
:param add_stop_last_message: Adds stop flag to the last I2CMessage.
453-
:type add_stop_last_message: boolean
454-
:param interval: Adds delay of `interval` seconds between I2C messages.
455-
:type interval: interger
421+
Args:
422+
messages: The I2C messages.
423+
add_stop_last_message: Adds stop flag to the last
424+
I2CMessage.
425+
interval: Adds delay of `interval` seconds between I2C
426+
messages.
456427
457428
Example:
458429

codebug_tether/platform.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""Functions for figuring out specific things about the current platform."""
2+
import re
3+
import os
4+
import sys
5+
import glob
6+
import serial
7+
8+
9+
def get_platform_serial_port():
10+
# setup DEFAULT_SERIAL_PORT which is different on Windows, MacOS,
11+
# Raspberry Pi 2 and Raspberry Pi 3
12+
if sys.platform.startswith('win') or sys.platform.startswith('darwin'):
13+
# On Windows or OSX take the first serial port we can find
14+
def serial_ports():
15+
""" Lists serial port names
16+
17+
:raises EnvironmentError:
18+
On unsupported or unknown platforms
19+
:returns:
20+
A list of the serial ports available on the system
21+
"""
22+
if sys.platform.startswith('win'):
23+
ports = ['COM%s' % (i + 1) for i in range(256)]
24+
elif (sys.platform.startswith('linux') or
25+
sys.platform.startswith('cygwin')):
26+
# this excludes your current terminal "/dev/tty"
27+
ports = glob.glob('/dev/tty[A-Za-z0-9]*')
28+
elif sys.platform.startswith('darwin'):
29+
ports = glob.glob('/dev/tty.*')
30+
else:
31+
raise EnvironmentError('Unsupported platform')
32+
33+
result = []
34+
for port in ports:
35+
try:
36+
s = serial.Serial(port)
37+
s.close()
38+
result.append(port)
39+
except (OSError, serial.SerialException):
40+
pass
41+
return result
42+
# use the first one
43+
try:
44+
return serial_ports()[0]
45+
except IndexError:
46+
print('ERROR: Could not find any serial ports.', file=sys.stderr)
47+
return ''
48+
else:
49+
# otherwise assume we're on Raspberry Pi/Linux
50+
def get_rpi_revision():
51+
"""Returns the version number from the revision line."""
52+
for line in open("/proc/cpuinfo"):
53+
if "Revision" in line:
54+
return re.sub('Revision\t: ([a-z0-9]+)\n', r'\1', line)
55+
56+
rpi_revision = get_rpi_revision()
57+
if (rpi_revision and
58+
(rpi_revision != 'Beta') and
59+
(int('0x'+rpi_revision, 16) >= 0xa02082)):
60+
# RPi 3 and above
61+
return '/dev/ttyS0'
62+
else:
63+
# RPi 2 and below
64+
return '/dev/ttyACM0'

codebug_tether/sprites.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ def __init__(self, string, direction='R', font=FourByFiveFont()):
184184
H" !"
185185
"""
186186
spr_width = font.char_width
187-
spr_height = font.char_height + 1 * len(string)
187+
spr_height = (font.char_height + 1) * len(string)
188188

189189
super().__init__(spr_width, spr_height)
190190

codebug_tether/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.8.4'
1+
__version__ = '0.9.0'

docs/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@
5252
# The short X.Y version.
5353
# NOTE: this is the version of the firmware download too so don't change
5454
# this with minor changes in the software if the firmware hasn't changed!
55-
version = '0.8.0'
55+
version = '0.8.5'
5656
# The full version, including alpha/beta/rc tags.
57-
release = '0.8.0'
57+
release = '0.8.5'
5858

5959
# The language for content autogenerated by Sphinx. Refer to documentation
6060
# for a list of supported languages.

docs/example.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ You can use the sprites library to quickly draw things on CodeBug's display.
6969
>>> codebug.draw_sprite(0, 0, message)
7070
>>> # move it along
7171
>>> codebug.draw_sprite(-2, 0, message)
72+
>>> # scroll a sprite
73+
>>> codebug.scroll_sprite(message)
7274

7375
You can do some more interesting things with Sprites::
7476

docs/installation.rst

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -93,40 +93,30 @@ See :ref:`examples-label` for more ways to use codebug_tether.
9393

9494
Install codebug_tether on Linux
9595
===============================
96-
Disable Serial Port Login Shell
97-
-------------------------------
98-
CodeBug uses the serial port which is configured to output the login
99-
shell by default. You must disable this before CodeBug will work. To do
100-
so, run:
101-
102-
sudo raspi-config
103-
104-
Navigate to `Advanced Options` > `Serial`, disable the login shell and
105-
then reboot.
106-
107-
10896
Install Python
10997
--------------
110-
Python should already be installed but for good measure::
98+
Python 3 and pip should already be installed but for good measure run::
11199

100+
sudo apt-get update
101+
sudo apt-get upgrade
112102
sudo apt-get install python3
113103

114-
To install pip, securely download `get-pip.py <https://bootstrap.pypa.io/get-pip.py>`_.
104+
If `pip` isn't installed you can securely download it from here `get-pip.py <https://bootstrap.pypa.io/get-pip.py>`_.
115105

116106
Then run the following::
117107

118-
python get-pip.py
108+
sudo python3 get-pip.py
119109

120110

121111
Install codebug_tether
122112
----------------------
123113
To install codebug_tether, open up a terminal and type::
124114

125-
pip install codebug_tether
115+
sudo pip3 install codebug_tether
126116

127117
To test it has worked, plug in CodeBug and open a Python shell by typing::
128118

129-
python
119+
python3
130120

131121
Your command prompt should have changed to::
132122

@@ -141,3 +131,14 @@ Now type::
141131
The middle pixel on your CodeBug should light up.
142132

143133
See :ref:`examples-label` for more ways to use codebug_tether.
134+
135+
136+
Troubleshooting
137+
===============
138+
Raspberry Pi - Disable Serial Port Login Shell
139+
----------------------------------------------
140+
CodeBug uses the USB serial port which (on older Raspberry Pi models) is configured to output the login shell by default. You must disable this before CodeBug will work. To do so, run::
141+
142+
sudo raspi-config
143+
144+
Navigate to `Advanced Options` > `Serial`, disable the login shell and then reboot.

firmware/codebug_tether_v0.8.5.cbg

18.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)