├── README.TXT
├── RPiSPi
├── Asteroids
│ ├── Asteroids.py
│ ├── Asteroids.pyc
│ ├── AstroRock.py
│ ├── AstroRock.pyc
│ ├── AstroShip.py
│ ├── AstroShip.pyc
│ ├── AstroShot.py
│ ├── AstroShot.pyc
│ ├── AstroUFO.py
│ ├── AstroUFO.pyc
│ ├── Common.py
│ ├── Common.pyc
│ ├── GNU-GeneralPublicLicense.txt
│ ├── Number.py
│ ├── Number.pyc
│ ├── Sounds
│ │ ├── Belt.wav
│ │ ├── Credit.wav
│ │ ├── HyperSpace.wav
│ │ ├── Rock.wav
│ │ ├── Shot.wav
│ │ ├── Thrust.wav
│ │ ├── UFO.wav
│ │ └── UFOShot.wav
│ ├── Text.py
│ └── Text.pyc
├── RPiSPi_MCP23S17.py
├── RPiSPi_MCP3002.py
├── RPiSPi_MCP3004.py
├── RPiSPi_MCP3008.py
├── RPiSPi_RAW.py
├── RPiSPi_SSD1306.py
├── RPiSPi_SSD1306_AnalogClock.py
├── RPiSPi_SSD1306_DateTime.py
├── RPiSPi_SSD1306_Image.py
├── RPiSPi_SSD1306_ScrollMessage.py
├── RPiTempSensor
│ ├── CalValues.txt
│ ├── CalValues.txt.BAK
│ ├── Device.cfg
│ └── RPi_MCP3002_TempSense.py
├── TestImage1.gif
└── TestImage2.gif
├── RPi_GPIO_Input.py
└── RPi_GPIO_Output.py
/README.TXT:
--------------------------------------------------------------------------------
1 | Python code examples for interfacing with the Raspberry Pi.
2 |
3 | REF Projects:
4 |
5 | Multiple SPI Device Python Examples:
6 | http://www.newsdownload.co.uk/pages/RPiSPiDev.html
7 |
8 | Temperature Sensor SPI Device Python Example:
9 | http://www.newsdownload.co.uk/pages/RPiTempSense.html
10 |
11 | GPIO Input Python Example:
12 | https://www.youtube.com/watch?v=KmqflzVvChI&index=6&list=PLOg9LCcUxRqMKrTMSAahDPh6knwIIUWV1
13 |
14 | GPIO Output Python Example:
15 | https://www.youtube.com/watch?v=59aaKSWH0gY&index=7&list=PLOg9LCcUxRqMKrTMSAahDPh6knwIIUWV1
16 |
17 |
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Asteroids.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | # AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO
4 | # Copyright (C) 2015 Jason Birch
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | #/****************************************************************************/
20 | #/* AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* V1.00 - 2016-11-03 - Jason Birch */
23 | #/* ------------------------------------------------------------------------ */
24 | #/* Conversion of Asteroids example game programming on multiple platforms, */
25 | #/* for Python on the Raspberry Pi using a 128x64 OLED SPI display and SPI */
26 | #/* GPIO port extender. The RPiSPiDev device driver is used to interface the */
27 | #/* Python code with the SPI hardware. */
28 | #/****************************************************************************/
29 |
30 |
31 | import time
32 | import random
33 | import pygame
34 | import Common
35 | import Text
36 | import Number
37 | import AstroShot
38 | import AstroShip
39 | import AstroUFO
40 | import AstroRock
41 |
42 |
43 | # /*********************/
44 | # /* Define constants. */
45 | #/*********************/
46 | EVENT_TIMER = pygame.USEREVENT + 1
47 |
48 | START_ROCKS = 2
49 | MAX_ROCKS = 100
50 | HISCORE_XOFFSET = 90
51 | HISCORE_YOFFSET = 0
52 | GAMEOVER_XOFFSET = 34
53 | GAMEOVER_YOFFSET = 5
54 | INSERTCOIN_XOFFSET = 45
55 | INSERTCOIN_YOFFSET = 5
56 | HISCORE_SCALE = 2
57 |
58 | GPIO_KEY_ESC = 0b0001000000000000
59 | GPIO_KEY_START = 0b0010000000000000
60 | GPIO_KEY_SHOOT = 0b1000000000000000
61 | GPIO_KEY_LEFT = 0b0000000000000100
62 | GPIO_KEY_RIGHT = 0b0000000000001000
63 | GPIO_KEY_THRUST = 0b0100000000000000
64 |
65 | GPIO_KEY_HYPER = 0b0010000000000000
66 |
67 |
68 | # /********************/
69 | # /* Set random seed. */
70 | #/********************/
71 | random.seed(time.gmtime())
72 |
73 | # /*******************************/
74 | # /* Initialise game components. */
75 | #/*******************************/
76 | pygame.init()
77 | pygame.mixer.init()
78 |
79 | Common.InitSPI()
80 |
81 | # /*****************/
82 | # /* Game objects. */
83 | #/*****************/
84 | Ship = AstroShip.AstroShip()
85 | UFO = AstroUFO.AstroUFO()
86 | Rock = [AstroRock.AstroRock() for X in range(MAX_ROCKS)]
87 | HiScore = Number.Number()
88 | GameOver = Text.Text()
89 | InsertCoin = Text.Text()
90 |
91 | BeltWav = pygame.mixer.Sound("Sounds/Belt.wav")
92 |
93 | # /***************/
94 | # /* Game flags. */
95 | #/***************/
96 | Exit = False
97 | SetFlag = False
98 | ThrustFlag = False
99 | RotateLeftFlag = False
100 | RotateRightFlag = False
101 |
102 |
103 |
104 | def DrawGraphics():
105 | # /*******************************/
106 | # /* Draw ship and rock objects. */
107 | #/*******************************/
108 | InsertCoin.Draw()
109 | GameOver.Draw()
110 | HiScore.Draw()
111 | Ship.Draw()
112 | UFO.Draw()
113 | for Count in range(MAX_ROCKS):
114 | Rock[Count].Draw()
115 |
116 | Common.DrawUpdate()
117 |
118 |
119 |
120 | def Timer():
121 | global FirstRock
122 | global NextRock
123 |
124 | if ThrustFlag:
125 | Ship.Thrust()
126 | elif RotateLeftFlag:
127 | Ship.IncAngle(False)
128 | Ship.IncAngle(False)
129 | elif RotateRightFlag:
130 | Ship.IncAngle(True)
131 | Ship.IncAngle(True)
132 |
133 | Ship.Move()
134 | UFO.Move()
135 | RockFound = False
136 | for Count in range(MAX_ROCKS):
137 | if Rock[Count].GetSize() != AstroRock.AstroRock.INACTIVE:
138 | RockFound = True
139 |
140 | Rock[Count].Move()
141 |
142 | # /*****************************/
143 | # /* Check for ship collision. */
144 | #/*****************************/
145 | if Ship.GetCrash() == False and UFO.Collide(Ship.GetXOffset(), Ship.GetYOffset(), Ship.GetWidth(), Ship.GetHeight()) == True:
146 | Ship.SetCrash(True)
147 | if UFO.GetShot().Active() == True and Ship.Collide(UFO.GetShot().GetXOffset(), UFO.GetShot().GetYOffset(), 2, 2) == True:
148 | Ship.SetCrash(True)
149 | if Ship.GetCrash() == False and Rock[Count].Collide(Ship.GetXOffset(), Ship.GetYOffset(), Ship.GetWidth(), Ship.GetHeight()) == True:
150 | Ship.SetCrash(True)
151 | NextRock += 1
152 | Rock[NextRock].SetArea(Common.Desktop, Ship.GetXOffset(), Ship.GetYOffset(), Rock[Count].GetSize())
153 |
154 | # /*************************/
155 | # /* Check for shot rocks. */
156 | #/*************************/
157 | for ShotCount in range(Ship.GetShotCount()):
158 | if Ship.GetShot(ShotCount).Active() != False:
159 | if UFO.Collide(Ship.GetShot(ShotCount).GetXOffset(), Ship.GetShot(ShotCount).GetYOffset(), 2, 2) == True:
160 | Ship.SetScore(Ship.GetScore() + 10)
161 | Ship.GetShot(ShotCount).Destroy()
162 | if Rock[Count].Collide(Ship.GetShot(ShotCount).GetXOffset(), Ship.GetShot(ShotCount).GetYOffset(), 2, 2) == True:
163 | Ship.SetScore(Ship.GetScore() + 1 * Rock[Count].GetSize())
164 | Ship.GetShot(ShotCount).Destroy()
165 | if NextRock + 1 < MAX_ROCKS:
166 | NextRock += 1
167 | Rock[NextRock].SetArea(Common.Desktop, Rock[Count].GetXOffset(), Rock[Count].GetYOffset(), Rock[Count].GetSize())
168 |
169 | if RockFound == False:
170 | BeltWav.play()
171 | FirstRock += 1
172 | NextRock = FirstRock
173 | for Count in range(FirstRock):
174 | Rock[Count].SetArea(Common.Desktop, AstroRock.AstroRock.NEW_POSITION, AstroRock.AstroRock.NEW_POSITION, 0)
175 |
176 | GameOver.SetVisible(Ship.GetLives() == False)
177 | InsertCoin.SetVisible(GameOver.GetVisible() == False and Ship.GetLives() == False)
178 |
179 | DrawGraphics()
180 |
181 |
182 |
183 | # /*****************************/
184 | # /* Configure game variables. */
185 | #/*****************************/
186 | GameOver = Text.Text()
187 | GameOver.SetLocation((Common.Desktop.width - Common.Desktop.x) / 2 - GAMEOVER_XOFFSET, (Common.Desktop.height - Common.Desktop.y) / 2 - GAMEOVER_YOFFSET, 2, 200, False, "GAME OVER", 1)
188 |
189 | InsertCoin = Text.Text()
190 | InsertCoin.SetLocation((Common.Desktop.width - Common.Desktop.x) / 2 - INSERTCOIN_XOFFSET, (Common.Desktop.height - Common.Desktop.y) / 2 - INSERTCOIN_YOFFSET, 2, 15, True, "INSERT COIN", 1)
191 |
192 | HiScore = Number.Number()
193 | HiScore.SetLocation(HISCORE_XOFFSET, HISCORE_YOFFSET, HISCORE_SCALE, 1)
194 |
195 | Ship = AstroShip.AstroShip()
196 | Ship.SetArea(Common.Desktop, 1)
197 |
198 | UFO = AstroUFO.AstroUFO()
199 | UFO.SetArea(Common.Desktop)
200 |
201 | FirstRock = START_ROCKS
202 | NextRock = FirstRock
203 | for Count in range(FirstRock):
204 | Rock[Count].SetArea(Common.Desktop, AstroRock.AstroRock.NEW_POSITION, AstroRock.AstroRock.NEW_POSITION, 0)
205 |
206 | # /**************************************************************/
207 | # /* Process application messages until the ESC key is pressed. */
208 | #/**************************************************************/
209 | pygame.time.set_timer(EVENT_TIMER, 100)
210 | ShotKeyFlag = False
211 | LastShotKeyFlag = False
212 | ExitFlag = False
213 | while ExitFlag == False:
214 | # /*************************************/
215 | # /* Yeald for other processes to run. */
216 | #/*************************************/
217 | pygame.time.wait(25)
218 |
219 | # /************************************/
220 | # /* Process application event queue. */
221 | #/************************************/
222 | for ThisEvent in pygame.event.get():
223 | # /******************************************************************/
224 | # /* If ptyhon has posted a QUIT message, flag to exit applicaiton. */
225 | #/******************************************************************/
226 | if ThisEvent.type == pygame.QUIT:
227 | ExitFlag = True
228 | break
229 |
230 | # /*********************************************************/
231 | # /* On timer period perform one frame of the application. */
232 | #/*********************************************************/
233 | elif ThisEvent.type == EVENT_TIMER:
234 |
235 | Timer()
236 |
237 | # /*************************/
238 | # /* Update display frame. */
239 | #/*************************/
240 | DrawGraphics()
241 |
242 | # /****************************************************************/
243 | # /* Check for ESC key press, and exit application when detected. */
244 | #/****************************************************************/
245 | KeysPressed = Common.GetGpioKeys()
246 |
247 | # /****************************/
248 | # /* Handle key press events. */
249 | #/****************************/
250 | if KeysPressed & GPIO_KEY_ESC:
251 | ExitFlag = True
252 | break
253 |
254 | # /****************************/
255 | # /* 'Ctrl' key press, shoot. */
256 | #/****************************/
257 | if KeysPressed & GPIO_KEY_SHOOT:
258 | ShotKeyFlag = True
259 | else:
260 | ShotKeyFlag = False
261 | if ShotKeyFlag != LastShotKeyFlag:
262 | Ship.Shoot()
263 | LastShotKeyFlag = ShotKeyFlag
264 |
265 | # /***************************/
266 | # /* 'up' key press, thrust. */
267 | #/***************************/
268 | if KeysPressed & GPIO_KEY_THRUST:
269 | ThrustFlag = True
270 | else:
271 | ThrustFlag = False
272 |
273 | # /**********************************/
274 | # /* 'left' key press, rotate left. */
275 | #/**********************************/
276 | if KeysPressed & GPIO_KEY_LEFT:
277 | RotateLeftFlag = True
278 | else:
279 | RotateLeftFlag = False
280 |
281 | # /************************************/
282 | # /* 'right' key press, rotate right. */
283 | #/************************************/
284 | if KeysPressed & GPIO_KEY_RIGHT:
285 | RotateRightFlag = True
286 | else:
287 | RotateRightFlag = False
288 |
289 | # /*********************************/
290 | # /* 'down' key press, hyperspace. */
291 | #/*********************************/
292 | if KeysPressed & GPIO_KEY_HYPER:
293 | Ship.Hyperspace()
294 |
295 | # /*****************************/
296 | # /* 'F1' key press, new game. */
297 | #/*****************************/
298 | if KeysPressed & GPIO_KEY_START:
299 | if Ship.GetLives() == False:
300 | if Ship.GetScore() > HiScore.GetNumber():
301 | HiScore.SetNumber(Ship.GetScore())
302 | Ship.Reset()
303 | UFO.Destroy()
304 | UFO.GetShot().Destroy()
305 | FirstRock = START_ROCKS
306 | NextRock = FirstRock
307 | for Count in range(MAX_ROCKS):
308 | Rock[Count].Destroy()
309 | for Count in range(FirstRock):
310 | Rock[Count].SetArea(Common.Desktop, AstroRock.AstroRock.NEW_POSITION, AstroRock.AstroRock.NEW_POSITION, 0)
311 |
312 | # /*****************/
313 | # /* Stop threads. */
314 | #/*****************/
315 | ExitFlag = True
316 |
317 | # /*********************************/
318 | # /* Application clean up and end. */
319 | #/*********************************/
320 | Common.CloseSPI()
321 |
322 | pygame.time.set_timer(EVENT_TIMER, 0)
323 | pygame.mouse.set_visible(True)
324 |
325 |
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Asteroids.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/Asteroids.pyc
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/AstroRock.py:
--------------------------------------------------------------------------------
1 | # AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO
2 | # Copyright (C) 2015 Jason Birch
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 |
17 | #/****************************************************************************/
18 | #/* AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO */
19 | #/* ------------------------------------------------------------------------ */
20 | #/* V1.00 - 2016-11-03 - Jason Birch */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* Conversion of Asteroids example game programming on multiple platforms, */
23 | #/* for Python on the Raspberry Pi using a 128x64 OLED SPI display and SPI */
24 | #/* GPIO port extender. The RPiSPiDev device driver is used to interface the */
25 | #/* Python code with the SPI hardware. */
26 | #/****************************************************************************/
27 |
28 |
29 | import random
30 | import pygame
31 | import Common
32 |
33 |
34 | class AstroRock:
35 | SCALE = 0.25
36 | FRAMES = 3
37 | FRAME_POINTS = 9
38 | ROCK_WIDTH = 12
39 | ROCK_HEIGHT = 12
40 | ERASE = 3
41 | INACTIVE = 4
42 | NEW_POSITION = -1
43 | HYPERSPACE = -500
44 |
45 |
46 | def __init__(self):
47 | self.Scale = self.SCALE
48 | self.xMax = 0
49 | self.yMax = 0
50 | self.xOffset = self.HYPERSPACE
51 | self.yOffset = self.HYPERSPACE
52 | self.xVelocity = 0
53 | self.yVelocity = 0
54 | self.Frame = [[Common.XPoint() for X in range(self.FRAME_POINTS)] for Y in range(self.FRAMES)]
55 | self.DisplayFrame = [Common.XPoint() for X in range(self.FRAME_POINTS)]
56 | self.OldFrame = [Common.XPoint() for X in range(self.FRAME_POINTS)]
57 |
58 | self.RockWav = pygame.mixer.Sound("Sounds/Rock.wav")
59 |
60 | for self.Size in range(self.FRAMES):
61 | self.Frame[self.Size][0].x = self.Scale * -30 / (self.Size * self.Size + 1)
62 | self.Frame[self.Size][0].y = self.Scale * -22 / (self.Size * self.Size + 1)
63 | self.Frame[self.Size][1].x = self.Scale * -5 / (self.Size * self.Size + 1)
64 | self.Frame[self.Size][1].y = self.Scale * -32 / (self.Size * self.Size + 1)
65 | self.Frame[self.Size][2].x = self.Scale * +35 / (self.Size * self.Size + 1)
66 | self.Frame[self.Size][2].y = self.Scale * -17 / (self.Size * self.Size + 1)
67 | self.Frame[self.Size][3].x = self.Scale * +25 / (self.Size * self.Size + 1)
68 | self.Frame[self.Size][3].y = self.Scale * +28 / (self.Size * self.Size + 1)
69 | self.Frame[self.Size][4].x = self.Scale * +12 / (self.Size * self.Size + 1)
70 | self.Frame[self.Size][4].y = self.Scale * -2 / (self.Size * self.Size + 1)
71 | self.Frame[self.Size][5].x = self.Scale * +10 / (self.Size * self.Size + 1)
72 | self.Frame[self.Size][5].y = self.Scale * +28 / (self.Size * self.Size + 1)
73 | self.Frame[self.Size][6].x = self.Scale * -20 / (self.Size * self.Size + 1)
74 | self.Frame[self.Size][6].y = self.Scale * +33 / (self.Size * self.Size + 1)
75 | self.Frame[self.Size][7].x = self.Scale * -37 / (self.Size * self.Size + 1)
76 | self.Frame[self.Size][7].y = self.Scale * +5 / (self.Size * self.Size + 1)
77 | self.Frame[self.Size][8].x = self.Scale * -30 / (self.Size * self.Size + 1)
78 | self.Frame[self.Size][8].y = self.Scale * -22 / (self.Size * self.Size + 1)
79 |
80 | self.Size = self.INACTIVE
81 |
82 |
83 |
84 | def Draw(self):
85 | if self.Size < self.INACTIVE:
86 | Common.DrawLines(self.OldFrame, self.FRAME_POINTS, 0)
87 |
88 | if self.Size == self.ERASE:
89 | self.Size = self.INACTIVE
90 |
91 | if self.Size < self.INACTIVE:
92 | for self.Count in range(self.FRAME_POINTS):
93 | self.DisplayFrame[self.Count].x = self.Frame[self.Size][self.Count].x + self.xOffset
94 | self.DisplayFrame[self.Count].y = self.Frame[self.Size][self.Count].y + self.yOffset
95 |
96 | Common.DrawLines(self.DisplayFrame, self.FRAME_POINTS, 1)
97 |
98 | for self.Count in range(self.FRAME_POINTS):
99 | self.OldFrame[self.Count].x = self.DisplayFrame[self.Count].x
100 | self.OldFrame[self.Count].y = self.DisplayFrame[self.Count].y
101 |
102 |
103 |
104 | def Move(self):
105 | if self.Size < self.INACTIVE:
106 | if self.xOffset < 0 - self.ROCK_WIDTH:
107 | self.xOffset = self.xMax + self.ROCK_WIDTH
108 | elif self.xOffset > self.xMax + self.ROCK_WIDTH:
109 | self.xOffset = 0 - self.ROCK_WIDTH
110 | if self.yOffset < 0 - self.ROCK_HEIGHT:
111 | self.yOffset = self.yMax + self.ROCK_HEIGHT
112 | elif self.yOffset > self.yMax + self.ROCK_HEIGHT:
113 | self.yOffset = 0 - self.ROCK_HEIGHT
114 | self.xOffset += self.xVelocity
115 | self.yOffset += self.yVelocity
116 |
117 |
118 |
119 | def SetArea(self, Desktop, NewxOffset, NewyOffset, NewSize):
120 | self.xMax = Desktop.width - Desktop.x
121 | self.yMax = Desktop.height - Desktop.y
122 | if NewxOffset == self.NEW_POSITION:
123 | self.Size = 0
124 | if random.randrange(2) == False:
125 | self.xOffset = random.randrange(self.xMax)
126 | self.yOffset = self.yMax * random.randrange(2)
127 | else:
128 | self.yOffset = random.randrange(self.yMax)
129 | self.xOffset = self.xMax * random.randrange(2)
130 | else:
131 | self.Size = NewSize
132 | self.xOffset = NewxOffset
133 | self.yOffset = NewyOffset
134 |
135 | self.xVelocity = 0
136 | self.yVelocity = 0
137 | while self.xVelocity == 0 or self.yVelocity == 0:
138 | self.xVelocity = random.randrange(3 * (self.Size + 1)) - 1 * (self.Size + 1)
139 | self.yVelocity = random.randrange(3 * (self.Size + 1)) - 1 * (self.Size + 1)
140 |
141 |
142 |
143 | def Collide(self, xPos, yPos, Width, Height):
144 | self.Collision = False
145 |
146 | if self.Size < self.INACTIVE:
147 | self.Collision = xPos + Width / 2 > self.xOffset - self.ROCK_WIDTH / (self.Size * self.Size + 1) and xPos - Width / 2 < self.xOffset + self.ROCK_WIDTH / (self.Size * self.Size + 1) and yPos + Height / 2 > self.yOffset - self.ROCK_HEIGHT / (self.Size * self.Size + 1) and yPos - Height / 2 < self.yOffset + self.ROCK_HEIGHT / (self.Size * self.Size + 1)
148 | if self.Collision == True:
149 | self.RockWav.play()
150 | self.Size += 1
151 |
152 | self.xVelocity = 0
153 | self.yVelocity = 0
154 | while self.xVelocity == 0 or self.yVelocity == 0:
155 | self.xVelocity = random.randrange(7 * (self.Size + 1)) - 3 * (self.Size + 1)
156 | self.yVelocity = random.randrange(7 * (self.Size + 1)) - 3 * (self.Size + 1)
157 |
158 | return self.Collision
159 |
160 |
161 |
162 | def Destroy(self):
163 | self.Size = self.ERASE
164 | self.xOffset = self.HYPERSPACE
165 | self.yOffset = self.HYPERSPACE
166 |
167 |
168 |
169 | def GetSize(self):
170 | return self.Size
171 |
172 |
173 |
174 | def GetXOffset(self):
175 | return self.xOffset
176 |
177 |
178 |
179 | def GetYOffset(self):
180 | return self.yOffset
181 |
182 |
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/AstroRock.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/AstroRock.pyc
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/AstroShip.py:
--------------------------------------------------------------------------------
1 | # AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO
2 | # Copyright (C) 2015 Jason Birch
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 |
17 | #/****************************************************************************/
18 | #/* AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO */
19 | #/* ------------------------------------------------------------------------ */
20 | #/* V1.00 - 2016-11-03 - Jason Birch */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* Conversion of Asteroids example game programming on multiple platforms, */
23 | #/* for Python on the Raspberry Pi using a 128x64 OLED SPI display and SPI */
24 | #/* GPIO port extender. The RPiSPiDev device driver is used to interface the */
25 | #/* Python code with the SPI hardware. */
26 | #/****************************************************************************/
27 |
28 |
29 | import math
30 | import random
31 | import pygame
32 | import Common
33 | import Number
34 | import AstroShot
35 |
36 |
37 | class AstroShip:
38 | SCALE = 0.4
39 | FRAMES = 63
40 | ERASE_FRAME = FRAMES + 1
41 | FRAME_POINTS = 5
42 | THRUST_POINTS = 8
43 | MAX_X_VELOCITY = 3
44 | MAX_Y_VELOCITY = 3
45 | SHIP_WIDTH = 10
46 | SHIP_HEIGHT = 8
47 | SHIP_START_ANGLE = 31
48 | MAX_EXPLODE_FRAME = 45
49 | LIFE_XGAP = 8
50 | LIFE_XOFFSET = 48
51 | LIFE_YOFFSET = 5
52 | LIVES_SCALE = 0.5
53 | MAX_LIVES = 3
54 | SCORE_XOFFSET = 0
55 | SCORE_YOFFSET = 0
56 | SCORE_SCALE = 2
57 | MAX_SHOTS = 10
58 | HYPERSPACE = -500
59 | HYPER_FRAMES = 20
60 |
61 |
62 |
63 | def __init__(self):
64 | self.Scale = self.SCALE
65 | self.OneDegree = 6.3 / 360
66 | self.FrameStep = 0.1
67 | self.xMax = 0
68 | self.yMax = 0
69 | self.xOffset = self.HYPERSPACE
70 | self.yOffset = self.HYPERSPACE
71 | self.xVelocity = 0
72 | self.yVelocity = 0
73 | self.Crash = False
74 | self.ThrustFlag = False
75 | self.Fade = 0
76 | self.Lives = self.MAX_LIVES
77 | self.ExplodeFrame = 0
78 | self.ShotIndex = 0
79 | self.HyperCount = False
80 |
81 | self.PlayerScore = Number.Number()
82 |
83 | self.Shots = [AstroShot.AstroShot() for X in range(self.MAX_SHOTS)]
84 | self.LifeFrame = [Common.XPoint() for X in range(self.FRAME_POINTS)]
85 | self.LifeDisplayFrame = [Common.XPoint() for X in range(self.FRAME_POINTS)]
86 | self.Frame = [[Common.XPoint() for X in range(self.FRAME_POINTS)] for Y in range(self.FRAMES)]
87 | self.DisplayFrame = [Common.XPoint() for X in range(self.FRAME_POINTS * 2)]
88 | self.OldFrame = [Common.XPoint() for X in range(self.FRAME_POINTS * 2)]
89 | self.ExplodeDirection = [Common.XPoint() for X in range(self.FRAME_POINTS * 2)]
90 | self.ThrustTrail = [Common.XPoint() for X in range(self.THRUST_POINTS)]
91 |
92 | self.ShotWav = pygame.mixer.Sound("Sounds/Shot.wav")
93 | self.ThrustWav = pygame.mixer.Sound("Sounds/Thrust.wav")
94 | self.ShipBlow = pygame.mixer.Sound("Sounds/ShipBlow.wav")
95 | self.HyperSpaceWav = pygame.mixer.Sound("Sounds/HyperSpace.wav")
96 |
97 | self.Angle = self.SHIP_START_ANGLE
98 | self.LifeFrame[0].x = self.Scale * 19 * math.sin(self.FrameStep * self.Angle + self.OneDegree * 0)
99 | self.LifeFrame[0].y = self.Scale * 19 * math.cos(self.FrameStep * self.Angle + self.OneDegree * 0)
100 | self.LifeFrame[1].x = self.Scale * 16 * math.sin(self.FrameStep * self.Angle + self.OneDegree * 140)
101 | self.LifeFrame[1].y = self.Scale * 16 * math.cos(self.FrameStep * self.Angle + self.OneDegree * 140)
102 | self.LifeFrame[2].x = self.Scale * 8 * math.sin(self.FrameStep * self.Angle + self.OneDegree * 180)
103 | self.LifeFrame[2].y = self.Scale * 8 * math.cos(self.FrameStep * self.Angle + self.OneDegree * 180)
104 | self.LifeFrame[3].x = self.Scale * 16 * math.sin(self.FrameStep * self.Angle + self.OneDegree * 220)
105 | self.LifeFrame[3].y = self.Scale * 16 * math.cos(self.FrameStep * self.Angle + self.OneDegree * 220)
106 | self.LifeFrame[4].x = self.Scale * 19 * math.sin(self.FrameStep * self.Angle + self.OneDegree * 0)
107 | self.LifeFrame[4].y = self.Scale * 19 * math.cos(self.FrameStep * self.Angle + self.OneDegree * 0)
108 |
109 | for self.Angle in range(self.FRAMES):
110 | self.Frame[self.Angle][0].x = self.Scale * 16 * math.sin(self.FrameStep * self.Angle + self.OneDegree * 0)
111 | self.Frame[self.Angle][0].y = self.Scale * 16 * math.cos(self.FrameStep * self.Angle + self.OneDegree * 0)
112 | self.Frame[self.Angle][1].x = self.Scale * 13 * math.sin(self.FrameStep * self.Angle + self.OneDegree * 140)
113 | self.Frame[self.Angle][1].y = self.Scale * 13 * math.cos(self.FrameStep * self.Angle + self.OneDegree * 140)
114 | self.Frame[self.Angle][2].x = self.Scale * 5 * math.sin(self.FrameStep * self.Angle + self.OneDegree * 180)
115 | self.Frame[self.Angle][2].y = self.Scale * 5 * math.cos(self.FrameStep * self.Angle + self.OneDegree * 180)
116 | self.Frame[self.Angle][3].x = self.Scale * 13 * math.sin(self.FrameStep * self.Angle + self.OneDegree * 220)
117 | self.Frame[self.Angle][3].y = self.Scale * 13 * math.cos(self.FrameStep * self.Angle + self.OneDegree * 220)
118 | self.Frame[self.Angle][4].x = self.Scale * 16 * math.sin(self.FrameStep * self.Angle + self.OneDegree * 0)
119 | self.Frame[self.Angle][4].y = self.Scale * 16 * math.cos(self.FrameStep * self.Angle + self.OneDegree * 0)
120 |
121 | self.Angle = self.SHIP_START_ANGLE
122 |
123 |
124 |
125 | def Draw(self):
126 | for self.Count in range(self.MAX_SHOTS):
127 | self.Shots[self.Count].Draw()
128 |
129 | if self.Lives != False or self.ExplodeFrame != self.MAX_EXPLODE_FRAME:
130 | # /*********************/
131 | # /* Draw intact ship. */
132 | #/*********************/
133 | if self.Crash == False:
134 | # /********************************/
135 | # /* Plot ships current position. */
136 | #/********************************/
137 | for self.Count in range(self.FRAME_POINTS):
138 | self.DisplayFrame[self.Count].x = self.Frame[self.Angle][self.Count].x + self.xOffset
139 | self.DisplayFrame[self.Count].y = self.Frame[self.Angle][self.Count].y + self.yOffset
140 |
141 | if self.ExplodeFrame >= self.ERASE_FRAME:
142 | self.ExplodeFrame = False
143 |
144 | # /************************************/
145 | # /* Erase previous position of ship. */
146 | #/************************************/
147 | for self.Count in range(0, self.FRAME_POINTS * 2, 2):
148 | Common.DrawLine(self.OldFrame[self.Count].x, self.OldFrame[self.Count].y, self.OldFrame[self.Count+1].x, self.OldFrame[self.Count+1].y, 0)
149 |
150 | # /************************************/
151 | # /* Erase previous position of ship. */
152 | #/************************************/
153 | Common.DrawLines(self.OldFrame, self.FRAME_POINTS, 0)
154 |
155 | # /******************************************/
156 | # /* Draw the ship in the current position. */
157 | #/******************************************/
158 | Common.DrawLines(self.DisplayFrame, self.FRAME_POINTS, 1)
159 |
160 | # /******************/
161 | # /* Remove thrust. */
162 | #/******************/
163 | for self.Count in range(self.THRUST_POINTS):
164 | Common.DrawLine(self.ThrustTrail[self.Count].x, self.ThrustTrail[self.Count].y, self.ThrustTrail[self.Count].x + 1, self.ThrustTrail[self.Count].y + 1, 0)
165 |
166 | # /*****************************************/
167 | # /* Add thrust point if currently active. */
168 | #/*****************************************/
169 | if self.ThrustFlag == True:
170 | for self.Count in range(self.THRUST_POINTS):
171 | self.ThrustTrail[self.Count].x = self.xOffset + random.randrange(5) - 2 + (9 * math.sin(self.FrameStep * self.Angle + self.OneDegree * 180))
172 | self.ThrustTrail[self.Count].y = self.yOffset + random.randrange(5) - 2 + (9 * math.cos(self.FrameStep * self.Angle + self.OneDegree * 180))
173 | Common.DrawLine(self.ThrustTrail[self.Count].x, self.ThrustTrail[self.Count].y, self.ThrustTrail[self.Count].x + 1, self.ThrustTrail[self.Count].y + 1, 1)
174 |
175 | self.ThrustFlag = False
176 |
177 | # /******************************************/
178 | # /* Plot ships current position, */
179 | # /* next time it will be the old position. */
180 | #/******************************************/
181 | for self.Count in range(self.FRAME_POINTS):
182 | self.OldFrame[self.Count].x = self.DisplayFrame[self.Count].x
183 | self.OldFrame[self.Count].y = self.DisplayFrame[self.Count].y
184 | else:
185 | if self.ExplodeFrame == False:
186 | self.Lives -= 1
187 |
188 | # /************************************/
189 | # /* Erase previous position of ship. */
190 | #/************************************/
191 | Common.DrawLines(self.OldFrame, self.FRAME_POINTS, 0)
192 |
193 | # /******************/
194 | # /* Remove thrust. */
195 | #/******************/
196 | for self.Count in range(self.THRUST_POINTS):
197 | Common.DrawLine(self.ThrustTrail[self.Count].x, self.ThrustTrail[self.Count].y, self.ThrustTrail[self.Count].x + 1, self.ThrustTrail[self.Count].y + 1, 0)
198 |
199 | # /**************************************************/
200 | # /* Set direction of individual lines of the ship. */
201 | #/**************************************************/
202 | for self.Count in range(0, self.FRAME_POINTS * 2, 2):
203 | self.ExplodeDirection[self.Count].x = 0
204 | while self.ExplodeDirection[self.Count].x == 0:
205 | self.ExplodeDirection[self.Count].x = random.randrange(10) - 5
206 |
207 | self.ExplodeDirection[self.Count].y = 0
208 | while self.ExplodeDirection[self.Count].y == 0:
209 | self.ExplodeDirection[self.Count].y = random.randrange(10) - 5
210 |
211 | self.ExplodeDirection[self.Count + 1].x = self.ExplodeDirection[self.Count].x
212 | self.ExplodeDirection[self.Count + 1].y = self.ExplodeDirection[self.Count].y
213 |
214 | # /********************************************/
215 | # /* Split polygon shape into seperate lines. */
216 | #/********************************************/
217 | self.DisplayFrame[0].x = self.Frame[self.Angle][self.FRAME_POINTS - 1].x + self.xOffset
218 | self.DisplayFrame[0].y = self.Frame[self.Angle][self.FRAME_POINTS - 1].y + self.yOffset
219 | self.OldFrame[0].x = self.Frame[self.Angle][self.FRAME_POINTS - 1].x + self.xOffset
220 | self.OldFrame[0].y = self.Frame[self.Angle][self.FRAME_POINTS - 1].y + self.yOffset
221 | self.DisplayFrame[self.FRAME_POINTS * 2 - 1].x = self.Frame[self.Angle][self.FRAME_POINTS - 1].x + self.xOffset
222 | self.DisplayFrame[self.FRAME_POINTS * 2 - 1].y = self.Frame[self.Angle][self.FRAME_POINTS - 1].y + self.yOffset
223 | self.OldFrame[self.FRAME_POINTS * 2 - 1].x = self.Frame[self.Angle][self.FRAME_POINTS - 1].x + self.xOffset
224 | self.OldFrame[self.FRAME_POINTS * 2 - 1].y = self.Frame[self.Angle][self.FRAME_POINTS - 1].y + self.yOffset
225 | for self.Count in range(self.FRAME_POINTS - 1):
226 | self.DisplayFrame[self.Count * 2 + 1].x = self.Frame[self.Angle][self.Count].x + self.xOffset
227 | self.DisplayFrame[self.Count * 2 + 1].y = self.Frame[self.Angle][self.Count].y + self.yOffset
228 | self.DisplayFrame[self.Count * 2 + 2].x = self.Frame[self.Angle][self.Count].x + self.xOffset
229 | self.DisplayFrame[self.Count * 2 + 2].y = self.Frame[self.Angle][self.Count].y + self.yOffset
230 | self.OldFrame[self.Count * 2 + 1].x = self.Frame[self.Angle][self.Count].x + self.xOffset
231 | self.OldFrame[self.Count * 2 + 1].y = self.Frame[self.Angle][self.Count].y + self.yOffset
232 | self.OldFrame[self.Count * 2 + 2].x = self.Frame[self.Angle][self.Count].x + self.xOffset
233 | self.OldFrame[self.Count * 2 + 2].y = self.Frame[self.Angle][self.Count].y + self.yOffset
234 |
235 | # /************************************/
236 | # /* Erase previous position of ship. */
237 | #/************************************/
238 | for self.Count in range(0, self.FRAME_POINTS * 2, 2):
239 | Common.DrawLine(self.OldFrame[self.Count].x, self.OldFrame[self.Count].y, self.OldFrame[self.Count + 1].x, self.OldFrame[self.Count + 1].y, 0)
240 |
241 | # /******************************************/
242 | # /* Draw the ship in the current position. */
243 | #/******************************************/
244 | if self.ExplodeFrame < self.MAX_EXPLODE_FRAME - 1:
245 | for self.Count in range(0, self.FRAME_POINTS * 2, 2):
246 | self.DisplayFrame[self.Count].x += self.ExplodeDirection[self.Count].x
247 | self.DisplayFrame[self.Count].y += self.ExplodeDirection[self.Count].y
248 | self.DisplayFrame[self.Count + 1].x += self.ExplodeDirection[self.Count + 1].x
249 | self.DisplayFrame[self.Count + 1].y += self.ExplodeDirection[self.Count + 1].y
250 | Common.DrawLine(self.DisplayFrame[self.Count].x, self.DisplayFrame[self.Count].y, self.DisplayFrame[self.Count + 1].x, self.DisplayFrame[self.Count + 1].y, 1)
251 |
252 | # /******************************************/
253 | # /* Plot ships current position, */
254 | # /* next time it will be the old position. */
255 | #/******************************************/
256 | for self.Count in range(self.FRAME_POINTS * 2):
257 | self.OldFrame[self.Count].x = self.DisplayFrame[self.Count].x
258 | self.OldFrame[self.Count].y = self.DisplayFrame[self.Count].y
259 |
260 | # /************************/
261 | # /* Reset for next life. */
262 | #/************************/
263 | self.ExplodeFrame += 1
264 | if self.Lives != False and self.ExplodeFrame == self.MAX_EXPLODE_FRAME:
265 | self.ExplodeFrame = False
266 | self.Crash = False
267 | self.ThrustFlag = False
268 | self.Angle = self.SHIP_START_ANGLE
269 | self.xOffset = self.xMax / 2
270 | self.yOffset = self.yMax / 2
271 | self.xVelocity = 0
272 | self.yVelocity = 0
273 |
274 | # /****************************/
275 | # /* Display remaining lives. */
276 | #/****************************/
277 | for self.LifeCount in range(self.MAX_LIVES):
278 | # /********************************/
279 | # /* Plot ships current position. */
280 | #/********************************/
281 | for self.Count in range(self.FRAME_POINTS):
282 | self.LifeDisplayFrame[self.Count].x = self.LIVES_SCALE * self.LifeFrame[self.Count].x + self.LIFE_XOFFSET + (self.LifeCount + 1) * self.LIFE_XGAP
283 | self.LifeDisplayFrame[self.Count].y = self.LIVES_SCALE * self.LifeFrame[self.Count].y + self.LIFE_YOFFSET
284 |
285 | # /************************************/
286 | # /* Erase previous position of ship. */
287 | #/************************************/
288 | Common.DrawLines(self.LifeDisplayFrame, self.FRAME_POINTS, 0)
289 |
290 | # /******************************************/
291 | # /* Draw the ship in the current position. */
292 | #/******************************************/
293 | if self.Lives > self.LifeCount:
294 | Common.DrawLines(self.LifeDisplayFrame, self.FRAME_POINTS, 1)
295 |
296 | # /******************/
297 | # /* Redraw scores. */
298 | #/******************/
299 | self.PlayerScore.Draw()
300 |
301 |
302 |
303 | def IncAngle(self, Direction):
304 | if self.Crash == False:
305 | if Direction == False:
306 | self.Angle += 2
307 | if self.Angle >= self.FRAMES:
308 | self.Angle = 0
309 | else:
310 | self.Angle -= 2
311 | if self.Angle < 0:
312 | self.Angle = self.FRAMES - 1
313 |
314 |
315 |
316 | def Thrust(self):
317 | self.ThrustWav.play()
318 | self.ThrustFlag = True
319 | self.xVelocity += math.sin(self.FrameStep * self.Angle + self.OneDegree * 0)
320 | self.yVelocity += math.cos(self.FrameStep * self.Angle + self.OneDegree * 0)
321 | if self.xVelocity > self.MAX_X_VELOCITY:
322 | self.xVelocity = self.MAX_X_VELOCITY
323 | elif self.xVelocity < -self.MAX_X_VELOCITY:
324 | self.xVelocity = -self.MAX_X_VELOCITY
325 | if self.yVelocity > self.MAX_Y_VELOCITY:
326 | self.yVelocity = self.MAX_Y_VELOCITY
327 | elif self.yVelocity < -self.MAX_Y_VELOCITY:
328 | self.yVelocity = -self.MAX_Y_VELOCITY
329 |
330 |
331 |
332 | def Shoot(self):
333 | if self.Crash == False:
334 | self.ShotWav.play()
335 | self.Shots[self.ShotIndex].SetArea(self.xMax, self.yMax, self.xOffset, self.yOffset, self.xVelocity + 10 * math.sin(self.FrameStep * self.Angle + self.OneDegree * 0), self.yVelocity + 10 * math.cos(self.FrameStep * self.Angle + self.OneDegree * 0), AstroShot.AstroShot.SMALL_SHOT)
336 | self.ShotIndex += 1
337 | if self.ShotIndex == self.MAX_SHOTS:
338 | self.ShotIndex = 0
339 |
340 |
341 |
342 | def Move(self):
343 | if self.HyperCount != False:
344 | self.HyperCount -= 1
345 | if self.HyperCount == False:
346 | self.xOffset = random.randrange(self.xMax - 2 * self.SHIP_WIDTH)
347 | self.yOffset = random.randrange(self.yMax - 2 * self.SHIP_HEIGHT)
348 |
349 | for self.Count in range(self.MAX_SHOTS):
350 | self.Shots[self.Count].Move()
351 |
352 | if self.Crash == False:
353 | if self.xOffset < 0 - self.SHIP_WIDTH:
354 | self.xOffset = self.xMax + self.SHIP_WIDTH
355 | elif self.xOffset > self.xMax + self.SHIP_WIDTH:
356 | self.xOffset = 0 - self.SHIP_WIDTH
357 | if self.yOffset < 0 - self.SHIP_HEIGHT:
358 | self.yOffset = self.yMax + self.SHIP_HEIGHT
359 | elif self.yOffset > self.yMax + self.SHIP_HEIGHT:
360 | self.yOffset = 0 - self.SHIP_HEIGHT
361 | self.xOffset += self.xVelocity
362 | self.yOffset += self.yVelocity
363 |
364 |
365 |
366 | def Reset(self):
367 | if self.Lives == False:
368 | self.ExplodeFrame = self.ERASE_FRAME
369 | self.Crash = False
370 | self.ThrustFlag = False
371 | self.Fade = 0
372 | self.Angle = self.SHIP_START_ANGLE
373 | self.xOffset = self.xMax / 2
374 | self.yOffset = self.yMax / 2
375 | self.xVelocity = 0
376 | self.yVelocity = 0
377 | self.Lives = self.MAX_LIVES
378 | self.PlayerScore.SetNumber(0)
379 |
380 |
381 |
382 | def SetArea(self, Desktop, NewTextColour):
383 | self.xMax = Desktop.width - Desktop.x
384 | self.yMax = Desktop.height - Desktop.y
385 | self.xOffset = self.xMax / 2
386 | self.yOffset = self.yMax / 2
387 | self.PlayerScore.SetLocation(self.SCORE_XOFFSET, self.SCORE_YOFFSET, self.SCORE_SCALE, NewTextColour)
388 |
389 |
390 |
391 | def Hyperspace(self):
392 | if self.Crash == False and self.HyperCount == False:
393 | self.HyperSpaceWav.play()
394 | self.HyperCount = self.HYPER_FRAMES
395 | self.xOffset = self.HYPERSPACE
396 | self.yOffset = self.HYPERSPACE
397 | self.xVelocity = 0
398 | self.yVelocity = 0
399 |
400 |
401 |
402 | def Collide(self, xPos, yPos, Width, Height):
403 | self.Collision = False
404 |
405 | if self.Crash == False:
406 | self.Collision = xPos + Width / 2 > self.xOffset - self.SHIP_WIDTH and xPos - Width / 2 < self.xOffset + self.SHIP_WIDTH and yPos + Height / 2 > self.yOffset - self.SHIP_HEIGHT and yPos - Height / 2 < self.yOffset + self.SHIP_HEIGHT
407 | if self.Collision == True:
408 | self.Crash = True
409 |
410 | return self.Collision
411 |
412 |
413 |
414 | def SetCrash(self, NewCrash):
415 | if self.Crash == False and NewCrash == True:
416 | self.ShipBlow.play()
417 | self.Crash = NewCrash
418 |
419 |
420 |
421 | def GetCrash(self):
422 | return self.Crash
423 |
424 |
425 |
426 | def GetXOffset(self):
427 | return self.xOffset
428 |
429 |
430 |
431 | def GetYOffset(self):
432 | return self.yOffset
433 |
434 |
435 |
436 | def GetWidth(self):
437 | return self.SHIP_WIDTH
438 |
439 |
440 |
441 | def GetHeight(self):
442 | return self.SHIP_HEIGHT
443 |
444 |
445 |
446 | def GetScore(self):
447 | return self.PlayerScore.GetNumber()
448 |
449 |
450 |
451 | def SetScore(self, NewScore):
452 | self.PlayerScore.SetNumber(NewScore)
453 |
454 |
455 |
456 | def GetLives(self):
457 | return self.Lives
458 |
459 |
460 |
461 | def GetShot(self, ShotCount):
462 | return self.Shots[ShotCount]
463 |
464 |
465 |
466 | def GetShotCount(self):
467 | return self.MAX_SHOTS
468 |
469 |
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/AstroShip.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/AstroShip.pyc
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/AstroShot.py:
--------------------------------------------------------------------------------
1 | # AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO
2 | # Copyright (C) 2015 Jason Birch
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 |
17 | #/****************************************************************************/
18 | #/* AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO */
19 | #/* ------------------------------------------------------------------------ */
20 | #/* V1.00 - 2016-11-03 - Jason Birch */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* Conversion of Asteroids example game programming on multiple platforms, */
23 | #/* for Python on the Raspberry Pi using a 128x64 OLED SPI display and SPI */
24 | #/* GPIO port extender. The RPiSPiDev device driver is used to interface the */
25 | #/* Python code with the SPI hardware. */
26 | #/****************************************************************************/
27 |
28 |
29 | import Common
30 |
31 |
32 | class AstroShot:
33 | SMALL_SHOT = 0
34 | LARGE_SHOT = 1
35 | SMALL_SHOT_FRAMES = 10
36 | LARGE_SHOT_FRAMES = 5
37 | ERASE_FRAME = 1
38 | HYPERSPACE = -500
39 |
40 |
41 | def __init__(self):
42 | self.xMax = 0
43 | self.yMax = 0
44 | self.xOffset = self.HYPERSPACE
45 | self.yOffset = self.HYPERSPACE
46 | self.OldxOffset = self.HYPERSPACE
47 | self.OldyOffset = self.HYPERSPACE
48 | self.xVelocity = 0
49 | self.yVelocity = 0
50 | self.Size = self.SMALL_SHOT
51 | self.FrameCount = 0
52 |
53 |
54 |
55 | def Draw(self):
56 | if self.FrameCount != False:
57 | if self.FrameCount == self.ERASE_FRAME:
58 | self.FrameCount = False
59 |
60 | if self.Size == self.SMALL_SHOT:
61 | Common.FillRectangle(self.OldxOffset, self.OldyOffset, 1, 1, 0)
62 |
63 | if self.FrameCount != False:
64 | Common.FillRectangle(self.xOffset, self.yOffset, 1, 1, 1)
65 |
66 | self.OldxOffset = self.xOffset
67 | self.OldyOffset = self.yOffset
68 | else:
69 | Common.FillRectangle(self.OldxOffset, self.OldyOffset, 2, 2, 0)
70 |
71 | if self.FrameCount != False:
72 | Common.FillRectangle(self.xOffset, self.yOffset, 2, 2, 1)
73 |
74 | self.OldxOffset = self.xOffset
75 | self.OldyOffset = self.yOffset
76 |
77 |
78 |
79 | def Move(self):
80 | if self.FrameCount > self.ERASE_FRAME:
81 | if self.xOffset < 0:
82 | self.xOffset = self.xMax
83 | elif self.xOffset > self.xMax:
84 | self.xOffset = 0
85 | if self.yOffset < 0:
86 | self.yOffset = self.yMax
87 | elif self.yOffset > self.yMax:
88 | self.yOffset = 0
89 | self.xOffset += self.xVelocity
90 | self.yOffset += self.yVelocity
91 | self.FrameCount -= 1
92 |
93 |
94 |
95 | def SetArea(self, NewxMax, NewyMax, NewxOffset, NewyOffset, NewxVelocity, NewyVelocity, NewSize):
96 | self.xMax = NewxMax
97 | self.yMax = NewyMax
98 | self.xOffset = NewxOffset
99 | self.yOffset = NewyOffset
100 | self.xVelocity = NewxVelocity
101 | self.yVelocity = NewyVelocity
102 | self.Size = NewSize
103 | if self.Size == self.LARGE_SHOT:
104 | self.FrameCount = self.LARGE_SHOT_FRAMES
105 | else:
106 | self.FrameCount = self.SMALL_SHOT_FRAMES
107 |
108 |
109 |
110 | def GetXOffset(self):
111 | return self.xOffset
112 |
113 |
114 |
115 | def GetYOffset(self):
116 | return self.yOffset
117 |
118 |
119 |
120 | def Destroy(self):
121 | self.FrameCount = self.ERASE_FRAME
122 | self.xOffset = self.HYPERSPACE
123 | self.yOffset = self.HYPERSPACE
124 |
125 |
126 |
127 | def Active(self):
128 | return (self.FrameCount != False)
129 |
130 |
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/AstroShot.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/AstroShot.pyc
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/AstroUFO.py:
--------------------------------------------------------------------------------
1 | # AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO
2 | # Copyright (C) 2015 Jason Birch
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 |
17 | #/****************************************************************************/
18 | #/* AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO */
19 | #/* ------------------------------------------------------------------------ */
20 | #/* V1.00 - 2016-11-03 - Jason Birch */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* Conversion of Asteroids example game programming on multiple platforms, */
23 | #/* for Python on the Raspberry Pi using a 128x64 OLED SPI display and SPI */
24 | #/* GPIO port extender. The RPiSPiDev device driver is used to interface the */
25 | #/* Python code with the SPI hardware. */
26 | #/****************************************************************************/
27 |
28 |
29 | import pygame
30 | import random
31 | import Common
32 | import AstroShot
33 |
34 |
35 | class AstroUFO:
36 | SCALE = 0.25
37 | FRAMES = 2
38 | FRAME_POINTS = 12
39 | UFO_WIDTH = 16
40 | UFO_HEIGHT = 6
41 | INACTIVE = 3
42 | ERASE = 4
43 | HYPERSPACE = -500
44 |
45 |
46 | def __init__(self):
47 | self.Scale = self.SCALE
48 | self.xMax = 0
49 | self.yMax = 0
50 | self.xOffset = self.HYPERSPACE
51 | self.yOffset = self.HYPERSPACE
52 | self.xVelocity = 0
53 | self.yVelocity = 0
54 |
55 | self.Shot = AstroShot.AstroShot()
56 | self.Frame = [[Common.XPoint() for X in range(self.FRAME_POINTS)] for Y in range(self.FRAMES)]
57 | self.DisplayFrame = [Common.XPoint() for X in range(self.FRAME_POINTS)]
58 | self.OldFrame = [Common.XPoint() for X in range(self.FRAME_POINTS)]
59 |
60 | self.UFOWav = pygame.mixer.Sound("Sounds/UFO.wav")
61 | self.UFOShotWav = pygame.mixer.Sound("Sounds/UFOShot.wav")
62 |
63 | for self.Size in range(self.FRAMES):
64 | self.Frame[self.Size][0].x = self.Scale * -(8 + (self.Size + 1) * 3)
65 | self.Frame[self.Size][0].y = self.Scale * -(0 + (self.Size + 1))
66 | self.Frame[self.Size][1].x = self.Scale * -(0 + (self.Size + 1))
67 | self.Frame[self.Size][1].y = self.Scale * -(3 + (self.Size + 1) * 3)
68 | self.Frame[self.Size][2].x = self.Scale * +(0 + (self.Size + 1))
69 | self.Frame[self.Size][2].y = self.Scale * -(3 + (self.Size + 1) * 3)
70 | self.Frame[self.Size][3].x = self.Scale * +(8 + (self.Size + 1) * 3)
71 | self.Frame[self.Size][3].y = self.Scale * -(0 + (self.Size + 1))
72 | self.Frame[self.Size][4].x = self.Scale * -(8 + (self.Size + 1) * 3)
73 | self.Frame[self.Size][4].y = self.Scale * -(0 + (self.Size + 1))
74 | self.Frame[self.Size][5].x = self.Scale * -(8 + (self.Size + 1) * 3)
75 | self.Frame[self.Size][5].y = self.Scale * +(0 + (self.Size + 1))
76 | self.Frame[self.Size][6].x = self.Scale * +(8 + (self.Size + 1) * 3)
77 | self.Frame[self.Size][6].y = self.Scale * +(0 + (self.Size + 1))
78 | self.Frame[self.Size][7].x = self.Scale * +(8 + (self.Size + 1) * 3)
79 | self.Frame[self.Size][7].y = self.Scale * -(0 + (self.Size + 1))
80 | self.Frame[self.Size][8].x = self.Scale * +(8 + (self.Size + 1) * 3)
81 | self.Frame[self.Size][8].y = self.Scale * +(0 + (self.Size + 1))
82 | self.Frame[self.Size][9].x = self.Scale * +(0 + (self.Size + 1))
83 | self.Frame[self.Size][9].y = self.Scale * +(3 + (self.Size + 1) * 3)
84 | self.Frame[self.Size][10].x = self.Scale * -(0 + (self.Size + 1))
85 | self.Frame[self.Size][10].y = self.Scale * +(3 + (self.Size + 1) * 3)
86 | self.Frame[self.Size][11].x = self.Scale * -(8 + (self.Size + 1) * 3)
87 | self.Frame[self.Size][11].y = self.Scale * +(0 + (self.Size + 1))
88 |
89 | self.Size = self.INACTIVE
90 |
91 |
92 |
93 | def Draw(self):
94 | self.Shot.Draw()
95 | if self.Size != self.INACTIVE:
96 | Common.DrawLines(self.OldFrame, self.FRAME_POINTS, 0)
97 |
98 | if self.Size == self.ERASE:
99 | self.Size = self.INACTIVE
100 |
101 | if self.Size < self.INACTIVE:
102 | for self.Count in range(self.FRAME_POINTS):
103 | self.DisplayFrame[self.Count].x = self.Frame[self.Size][self.Count].x + self.xOffset
104 | self.DisplayFrame[self.Count].y = self.Frame[self.Size][self.Count].y + self.yOffset
105 |
106 | Common.DrawLines(self.DisplayFrame, self.FRAME_POINTS, 1)
107 |
108 | for self.Count in range(self.FRAME_POINTS):
109 | self.OldFrame[self.Count].x = self.DisplayFrame[self.Count].x
110 | self.OldFrame[self.Count].y = self.DisplayFrame[self.Count].y
111 |
112 |
113 |
114 | def Move(self):
115 | if self.Shot.Active() == True:
116 | self.Shot.Move()
117 |
118 | if self.Size != self.INACTIVE:
119 | if self.Shot.Active() == False:
120 | self.UFOWav.play()
121 | self.ShotDirection = random.randrange(4)
122 |
123 | if self.ShotDirection == 0:
124 | self.Shot.SetArea(self.xMax, self.yMax, self.xOffset, self.yOffset, -8, -8, AstroShot.AstroShot.LARGE_SHOT)
125 | elif self.ShotDirection == 1:
126 | self.Shot.SetArea(self.xMax, self.yMax, self.xOffset, self.yOffset, -8, +8, AstroShot.AstroShot.LARGE_SHOT)
127 | elif self.ShotDirection == 2:
128 | self.Shot.SetArea(self.xMax, self.yMax, self.xOffset, self.yOffset, +8, -8, AstroShot.AstroShot.LARGE_SHOT)
129 | elif self.ShotDirection == 3:
130 | self.Shot.SetArea(self.xMax, self.yMax, self.xOffset, self.yOffset, +8, +8, AstroShot.AstroShot.LARGE_SHOT)
131 |
132 | if random.randrange(10) == 0:
133 | self.yVelocity = random.randrange((self.Size + 2) * 4) - ((self.Size + 2) * 2)
134 | if self.xOffset < 0 - self.UFO_WIDTH:
135 | self.Size = self.INACTIVE
136 | elif self.xOffset > self.xMax + self.UFO_WIDTH:
137 | self.Size = self.INACTIVE
138 | if self.yOffset < 0:
139 | self.yOffset = 0
140 | elif self.yOffset > self.yMax:
141 | self.yOffset = self.yMax
142 | self.xOffset += self.xVelocity
143 | self.yOffset += self.yVelocity
144 | elif random.randrange(1000) == 0:
145 | self.Size = random.randrange(self.FRAMES)
146 | self.yOffset = random.randrange(self.yMax)
147 | if random.randrange(2) == 0:
148 | self.xOffset = 0 - self.UFO_WIDTH
149 | self.xVelocity = 3 * (2 - self.Size + 1)
150 | else:
151 | self.xOffset = self.xMax + self.UFO_WIDTH
152 | self.xVelocity = -3 * (2 - self.Size + 1)
153 | self.yVelocity = random.randrange(2) - 1
154 |
155 |
156 |
157 | def SetArea(self, Desktop):
158 | self.xMax = Desktop.width - Desktop.x
159 | self.yMax = Desktop.height - Desktop.y
160 |
161 |
162 |
163 | def Collide(self, xPos, yPos, Width, Height):
164 | self.Collision = False
165 |
166 | if self.Size < self.INACTIVE:
167 | self.Collision = xPos + Width / 2 > self.xOffset - self.UFO_WIDTH / (self.Size * self.Size + 1) and xPos - Width / 2 < self.xOffset + self.UFO_WIDTH / (self.Size * self.Size + 1) and yPos + Height / 2 > self.yOffset - self.UFO_HEIGHT / (self.Size * self.Size + 1) and yPos - Height / 2 < self.yOffset + self.UFO_HEIGHT / (self.Size * self.Size + 1)
168 | if self.Collision == True:
169 | self.Destroy()
170 |
171 | return self.Collision
172 |
173 |
174 |
175 | def Destroy(self):
176 | self.Size = self.ERASE
177 | self.xOffset = self.HYPERSPACE
178 | self.yOffset = self.HYPERSPACE
179 |
180 |
181 |
182 | def GetSize(self):
183 | return self.Size
184 |
185 |
186 |
187 | def GetXOffset(self):
188 | return self.xOffset
189 |
190 |
191 |
192 | def GetYOffset(self):
193 | return self.yOffset
194 |
195 |
196 |
197 | def GetShot(self):
198 | return self.Shot
199 |
200 |
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/AstroUFO.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/AstroUFO.pyc
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Common.py:
--------------------------------------------------------------------------------
1 | # AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO
2 | # Copyright (C) 2015 Jason Birch
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 |
17 | #/****************************************************************************/
18 | #/* AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO */
19 | #/* ------------------------------------------------------------------------ */
20 | #/* V1.00 - 2016-11-03 - Jason Birch */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* Conversion of Asteroids example game programming on multiple platforms, */
23 | #/* for Python on the Raspberry Pi using a 128x64 OLED SPI display and SPI */
24 | #/* GPIO port extender. The RPiSPiDev device driver is used to interface the */
25 | #/* Python code with the SPI hardware. */
26 | #/****************************************************************************/
27 |
28 |
29 | import struct
30 | import Common
31 |
32 |
33 | SPI_DEV_CMD_SSD1306_INIT = 0
34 | SPI_DEV_CMD_SSD1306_WRITE = 1
35 | SPI_DEV_CMD_SSD1306_CURSOR_POS = 2
36 | SPI_DEV_CMD_SSD1306_ON = 3
37 | SPI_DEV_CMD_SSD1306_OFF = 4
38 | SPI_DEV_CMD_SSD1306_INVERSE = 5
39 | SPI_DEV_CMD_SSD1306_NON_INVERSE = 6
40 | SPI_DEV_CMD_SSD1306_CONTRAST = 7
41 | SPI_DEV_PRC_SSD1306_CLS = 8
42 | SPI_DEV_PRC_SSD1306_FILL_RANDOM = 9
43 | SPI_DEV_PRC_SSD1306_PRINT = 10
44 | SPI_DEV_PRC_SSD1306_PLOT = 11
45 | SPI_DEV_PRC_SSD1306_LINE = 12
46 | SPI_DEV_PRC_SSD1306_BOX = 13
47 | SPI_DEV_PRC_SSD1306_BOX_FILL = 14
48 | SPI_DEV_PRC_SSD1306_CIRCLE = 15
49 | SPI_DEV_PRC_SSD1306_CIRCLE_FILL = 16
50 | SPI_DEV_PRC_SSD1306_UPDATE = 17
51 |
52 | SPI_DEV_CMD_MCP23S17_INIT = 0
53 | SPI_DEV_CMD_MCP23S17_WRITE = 1
54 | SPI_DEV_CMD_MCP23S17_READ = 2
55 | # IODIR - I/O DIRECTION REGISTER - 0=OUTPUT, 1=INPUT
56 | SPI_DEV_CMD_MCP23S17_IODIR = 3
57 | # IPOL - INPUT POLARITY PORT REGISTER
58 | SPI_DEV_CMD_MCP23S17_IPOL = 4
59 | # GPINTEN - INTERRUPT-ON-CHANGE PINS
60 | SPI_DEV_CMD_MCP23S17_GPINTEN = 5
61 | # DEFVAL - DEFAULT VALUE REGISTER
62 | SPI_DEV_CMD_MCP23S17_DEFVAL = 6
63 | # INTCON - INTERRUPT-ON-CHANGE CONTROL REGISTER
64 | SPI_DEV_CMD_MCP23S17_INTCON = 7
65 | # GPPU - GPIO PULL-UP RESISTOR REGISTER
66 | SPI_DEV_CMD_MCP23S17_GPPU = 8
67 | # INTF - INTERRUPT FLAG REGISTER
68 | SPI_DEV_CMD_MCP23S17_INTF = 9
69 | # INTCAP - INTERRUPT CAPTURED VALUE FOR PORT REGISTER
70 | SPI_DEV_CMD_MCP23S17_INTCAP = 10
71 |
72 |
73 |
74 | SPiDisplayFile = file
75 |
76 |
77 |
78 | # /***************************/
79 | # /* Set the play area size. */
80 | #/***************************/
81 | class DesktopType:
82 | DISPLAY_X = 0
83 | DISPLAY_Y = 0
84 | DISPLAY_WIDTH = 128
85 | DISPLAY_HEIGHT = 64
86 |
87 | def __init__(self):
88 | self.x = self.DISPLAY_X
89 | self.y = self.DISPLAY_Y
90 | self.width = self.DISPLAY_WIDTH
91 | self.height = self.DISPLAY_HEIGHT
92 |
93 |
94 | class XPoint:
95 | def __init__(self):
96 | self.x = 0
97 | self.y = 0
98 |
99 |
100 | Desktop = DesktopType()
101 |
102 |
103 |
104 | def ReadGPIO(DevFile):
105 | File = open(DevFile, 'rb', 0)
106 | Data = File.read(4)
107 | File.close()
108 | return struct.unpack("<%dI" % (len(Data) // 4), Data)[0]
109 |
110 |
111 |
112 | def WriteGPIO(DevFile, *Args):
113 | Message = ""
114 | for Count in range(len(Args)):
115 | if isinstance(Args[Count], str):
116 | Message += Args[Count]
117 | else:
118 | Message += struct.pack('I', Args[Count])
119 | File = open(DevFile, 'wb', 0)
120 | File.write(Message)
121 | File.close()
122 |
123 |
124 |
125 | def DoDisplay(*Args):
126 | global SPiDisplayFile
127 |
128 | Message = ""
129 | for Count in range(len(Args)):
130 | if isinstance(Args[Count], str):
131 | Message += Args[Count]
132 | else:
133 | Message += struct.pack('I', Args[Count])
134 | SPiDisplayFile.write(Message)
135 |
136 |
137 |
138 | def InitSPI():
139 | global SPiDisplayFile
140 |
141 | WriteGPIO("/dev/RPiSPi_00011_001_4_0_MCP23S17_INIT", SPI_DEV_CMD_MCP23S17_INIT)
142 | WriteGPIO("/dev/RPiSPi_00011_001_4_3_MCP23S17_IODIR", 0xFFFF)
143 | WriteGPIO("/dev/RPiSPi_00011_001_4_4_MCP23S17_IPOL", 0xF00F)
144 | WriteGPIO("/dev/RPiSPi_00011_001_4_5_MCP23S17_GPINTEN", 0x0000)
145 | WriteGPIO("/dev/RPiSPi_00011_001_4_6_MCP23S17_DEFVAL", 0x0000)
146 | WriteGPIO("/dev/RPiSPi_00011_001_4_7_MCP23S17_INTCON", 0x0000)
147 | WriteGPIO("/dev/RPiSPi_00011_001_4_8_MCP23S17_GPPU", 0xF00F)
148 |
149 | WriteGPIO("/dev/RPiSPi_10011_000_8_0_SSD1306_INIT", SPI_DEV_CMD_SSD1306_INIT)
150 | SPiDisplayFile = open("/dev/RPiSPi_10011_000_8_1_SSD1306_WRITE", 'wb', 0)
151 |
152 | DoDisplay(SPI_DEV_CMD_SSD1306_ON)
153 | DoDisplay(SPI_DEV_CMD_SSD1306_CONTRAST, 127)
154 | DoDisplay(SPI_DEV_PRC_SSD1306_CLS)
155 |
156 |
157 |
158 | def CloseSPI():
159 | global SPiDisplayFile
160 |
161 | DoDisplay(SPI_DEV_CMD_SSD1306_OFF)
162 | SPiDisplayFile.close()
163 |
164 |
165 |
166 | def GetGpioKeys():
167 | return ReadGPIO("/dev/RPiSPi_00011_001_4_2_MCP23S17_READ")
168 |
169 |
170 |
171 | def DrawLine(X1, Y1, X2, Y2, Colour):
172 | if not (X1 < 0 and X2 < 0 or Y2 < 0 and Y2 < 0):
173 | if X1 < 0:
174 | X1 = 0
175 | if X2 < 0:
176 | X2 = 0
177 | if Y1 < 0:
178 | Y1 = 0
179 | if Y2 < 0:
180 | Y2 = 0
181 | DoDisplay(SPI_DEV_PRC_SSD1306_LINE, X1, Y1, X2, Y2, Colour)
182 |
183 |
184 |
185 | def DrawLines(Points, PointCount, Colour):
186 | for Count in range(PointCount - 1):
187 | DrawLine(Points[Count].x, Points[Count].y, Points[Count + 1].x, Points[Count + 1].y, Colour)
188 |
189 |
190 |
191 | def FillRectangle(X, Y, SizeX, SizeY, Colour):
192 | if X < 0:
193 | X = 0
194 | if Y < 0:
195 | Y = 0
196 | DoDisplay(SPI_DEV_PRC_SSD1306_BOX_FILL, X, Y, X + SizeX, Y + SizeY, Colour)
197 |
198 |
199 |
200 | def DrawUpdate():
201 | DoDisplay(SPI_DEV_PRC_SSD1306_UPDATE)
202 |
203 |
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Common.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/Common.pyc
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/GNU-GeneralPublicLicense.txt:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Number.py:
--------------------------------------------------------------------------------
1 | # AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO
2 | # Copyright (C) 2015 Jason Birch
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 |
17 | #/****************************************************************************/
18 | #/* AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO */
19 | #/* ------------------------------------------------------------------------ */
20 | #/* V1.00 - 2016-11-03 - Jason Birch */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* Conversion of Asteroids example game programming on multiple platforms, */
23 | #/* for Python on the Raspberry Pi using a 128x64 OLED SPI display and SPI */
24 | #/* GPIO port extender. The RPiSPiDev device driver is used to interface the */
25 | #/* Python code with the SPI hardware. */
26 | #/****************************************************************************/
27 |
28 |
29 | import Common
30 |
31 |
32 | class Number:
33 | DIGITS = 10
34 | MAX_POINTS = 10
35 |
36 |
37 | def __init__(self):
38 | self.NumberValue = 0
39 | self.xOffset = 0
40 | self.yOffset = 0
41 | self.Scale = 0
42 | self.TextColour = 0
43 |
44 | self.Decimal = [[Common.XPoint() for X in range(self.MAX_POINTS + 1)] for Y in range(self.DIGITS)]
45 | self.DisplayFrame = [[Common.XPoint() for X in range(self.MAX_POINTS + 1)] for Y in range(self.DIGITS)]
46 | self.OldFrame = [[Common.XPoint() for X in range(self.MAX_POINTS + 1)] for Y in range(self.DIGITS)]
47 |
48 |
49 |
50 | def Draw(self):
51 | # /*****************************/
52 | # /* Plot score current value. */
53 | #/*****************************/
54 | self.TempValue = self.NumberValue
55 | for self.Digit in range(5):
56 | self.Divide = self.TempValue % 10
57 | for self.Count in range(self.Decimal[self.Divide][self.MAX_POINTS].x):
58 | self.DisplayFrame[self.Digit][self.Count].x = self.Decimal[self.Divide][self.Count].x + self.xOffset + (5 - self.Digit) * 3 * self.Scale
59 | self.DisplayFrame[self.Digit][self.Count].y = self.Decimal[self.Divide][self.Count].y + self.yOffset
60 |
61 | self.DisplayFrame[self.Digit][self.MAX_POINTS].x = self.Decimal[self.Divide][self.MAX_POINTS].x
62 | self.TempValue /= 10
63 |
64 | # /*************************/
65 | # /* Erase previous score. */
66 | #/*************************/
67 | Common.DrawLines(self.OldFrame[self.Digit], self.OldFrame[self.Digit][self.MAX_POINTS].x, 0)
68 |
69 | # /***************************/
70 | # /* Draw the current score. */
71 | #/***************************/
72 | Common.DrawLines(self.DisplayFrame[self.Digit], self.DisplayFrame[self.Digit][self.MAX_POINTS].x, 1)
73 |
74 | # /***************************************/
75 | # /* Plot current score, */
76 | # /* next time it will be the old score. */
77 | #/***************************************/
78 | for self.Count in range(self.DisplayFrame[self.Digit][self.MAX_POINTS].x):
79 | self.OldFrame[self.Digit][self.Count].x = self.DisplayFrame[self.Digit][self.Count].x
80 | self.OldFrame[self.Digit][self.Count].y = self.DisplayFrame[self.Digit][self.Count].y
81 |
82 | self.OldFrame[self.Digit][self.MAX_POINTS].x = self.DisplayFrame[self.Digit][self.MAX_POINTS].x
83 |
84 |
85 |
86 | def SetLocation(self, NewxOffset, NewyOffset, NewScale, NewTextColour):
87 | self.xOffset = NewxOffset
88 | self.yOffset = NewyOffset
89 | self.Scale = NewScale
90 | self.TextColour = NewTextColour
91 |
92 | self.Decimal[0][self.MAX_POINTS].x = 6
93 | self.Decimal[0][0].x = 2 * self.Scale
94 | self.Decimal[0][0].y = 0 * self.Scale
95 | self.Decimal[0][1].x = 0 * self.Scale
96 | self.Decimal[0][1].y = 0 * self.Scale
97 | self.Decimal[0][2].x = 0 * self.Scale
98 | self.Decimal[0][2].y = 4 * self.Scale
99 | self.Decimal[0][3].x = 2 * self.Scale
100 | self.Decimal[0][3].y = 4 * self.Scale
101 | self.Decimal[0][4].x = 2 * self.Scale
102 | self.Decimal[0][4].y = 0 * self.Scale
103 | self.Decimal[0][5].x = 0 * self.Scale
104 | self.Decimal[0][5].y = 4 * self.Scale
105 |
106 | self.Decimal[1][self.MAX_POINTS].x = 2
107 | self.Decimal[1][0].x = 1 * self.Scale
108 | self.Decimal[1][0].y = 0 * self.Scale
109 | self.Decimal[1][1].x = 1 * self.Scale
110 | self.Decimal[1][1].y = 4 * self.Scale
111 |
112 | self.Decimal[2][self.MAX_POINTS].x = 6
113 | self.Decimal[2][0].x = 0 * self.Scale
114 | self.Decimal[2][0].y = 0 * self.Scale
115 | self.Decimal[2][1].x = 2 * self.Scale
116 | self.Decimal[2][1].y = 0 * self.Scale
117 | self.Decimal[2][2].x = 2 * self.Scale
118 | self.Decimal[2][2].y = 2 * self.Scale
119 | self.Decimal[2][3].x = 0 * self.Scale
120 | self.Decimal[2][3].y = 2 * self.Scale
121 | self.Decimal[2][4].x = 0 * self.Scale
122 | self.Decimal[2][4].y = 4 * self.Scale
123 | self.Decimal[2][5].x = 2 * self.Scale
124 | self.Decimal[2][5].y = 4 * self.Scale
125 |
126 | self.Decimal[3][self.MAX_POINTS].x = 7
127 | self.Decimal[3][0].x = 0 * self.Scale
128 | self.Decimal[3][0].y = 0 * self.Scale
129 | self.Decimal[3][1].x = 2 * self.Scale
130 | self.Decimal[3][1].y = 0 * self.Scale
131 | self.Decimal[3][2].x = 2 * self.Scale
132 | self.Decimal[3][2].y = 2 * self.Scale
133 | self.Decimal[3][3].x = 0 * self.Scale
134 | self.Decimal[3][3].y = 2 * self.Scale
135 | self.Decimal[3][4].x = 2 * self.Scale
136 | self.Decimal[3][4].y = 2 * self.Scale
137 | self.Decimal[3][5].x = 2 * self.Scale
138 | self.Decimal[3][5].y = 4 * self.Scale
139 | self.Decimal[3][6].x = 0 * self.Scale
140 | self.Decimal[3][6].y = 4 * self.Scale
141 |
142 | self.Decimal[4][self.MAX_POINTS].x = 5
143 | self.Decimal[4][0].x = 0 * self.Scale
144 | self.Decimal[4][0].y = 0 * self.Scale
145 | self.Decimal[4][1].x = 0 * self.Scale
146 | self.Decimal[4][1].y = 2 * self.Scale
147 | self.Decimal[4][2].x = 2 * self.Scale
148 | self.Decimal[4][2].y = 2 * self.Scale
149 | self.Decimal[4][3].x = 2 * self.Scale
150 | self.Decimal[4][3].y = 0 * self.Scale
151 | self.Decimal[4][4].x = 2 * self.Scale
152 | self.Decimal[4][4].y = 4 * self.Scale
153 |
154 | self.Decimal[5][self.MAX_POINTS].x = 6
155 | self.Decimal[5][0].x = 2 * self.Scale
156 | self.Decimal[5][0].y = 0 * self.Scale
157 | self.Decimal[5][1].x = 0 * self.Scale
158 | self.Decimal[5][1].y = 0 * self.Scale
159 | self.Decimal[5][2].x = 0 * self.Scale
160 | self.Decimal[5][2].y = 2 * self.Scale
161 | self.Decimal[5][3].x = 2 * self.Scale
162 | self.Decimal[5][3].y = 2 * self.Scale
163 | self.Decimal[5][4].x = 2 * self.Scale
164 | self.Decimal[5][4].y = 4 * self.Scale
165 | self.Decimal[5][5].x = 0 * self.Scale
166 | self.Decimal[5][5].y = 4 * self.Scale
167 |
168 | self.Decimal[6][self.MAX_POINTS].x = 6
169 | self.Decimal[6][0].x = 2 * self.Scale
170 | self.Decimal[6][0].y = 0 * self.Scale
171 | self.Decimal[6][1].x = 0 * self.Scale
172 | self.Decimal[6][1].y = 0 * self.Scale
173 | self.Decimal[6][2].x = 0 * self.Scale
174 | self.Decimal[6][2].y = 4 * self.Scale
175 | self.Decimal[6][3].x = 2 * self.Scale
176 | self.Decimal[6][3].y = 4 * self.Scale
177 | self.Decimal[6][4].x = 2 * self.Scale
178 | self.Decimal[6][4].y = 2 * self.Scale
179 | self.Decimal[6][5].x = 0 * self.Scale
180 | self.Decimal[6][5].y = 2 * self.Scale
181 |
182 | self.Decimal[7][self.MAX_POINTS].x = 3
183 | self.Decimal[7][0].x = 0 * self.Scale
184 | self.Decimal[7][0].y = 0 * self.Scale
185 | self.Decimal[7][1].x = 2 * self.Scale
186 | self.Decimal[7][1].y = 0 * self.Scale
187 | self.Decimal[7][2].x = 2 * self.Scale
188 | self.Decimal[7][2].y = 4 * self.Scale
189 |
190 | self.Decimal[8][self.MAX_POINTS].x = 7
191 | self.Decimal[8][0].x = 0 * self.Scale
192 | self.Decimal[8][0].y = 0 * self.Scale
193 | self.Decimal[8][1].x = 2 * self.Scale
194 | self.Decimal[8][1].y = 0 * self.Scale
195 | self.Decimal[8][2].x = 2 * self.Scale
196 | self.Decimal[8][2].y = 4 * self.Scale
197 | self.Decimal[8][3].x = 0 * self.Scale
198 | self.Decimal[8][3].y = 4 * self.Scale
199 | self.Decimal[8][4].x = 0 * self.Scale
200 | self.Decimal[8][4].y = 0 * self.Scale
201 | self.Decimal[8][5].x = 0 * self.Scale
202 | self.Decimal[8][5].y = 2 * self.Scale
203 | self.Decimal[8][6].x = 2 * self.Scale
204 | self.Decimal[8][6].y = 2 * self.Scale
205 |
206 | self.Decimal[9][self.MAX_POINTS].x = 6
207 | self.Decimal[9][0].x = 0 * self.Scale
208 | self.Decimal[9][0].y = 4 * self.Scale
209 | self.Decimal[9][1].x = 2 * self.Scale
210 | self.Decimal[9][1].y = 4 * self.Scale
211 | self.Decimal[9][2].x = 2 * self.Scale
212 | self.Decimal[9][2].y = 0 * self.Scale
213 | self.Decimal[9][3].x = 0 * self.Scale
214 | self.Decimal[9][3].y = 0 * self.Scale
215 | self.Decimal[9][4].x = 0 * self.Scale
216 | self.Decimal[9][4].y = 2 * self.Scale
217 | self.Decimal[9][5].x = 2 * self.Scale
218 | self.Decimal[9][5].y = 2 * self.Scale
219 |
220 |
221 |
222 | def GetNumber(self):
223 | return self.NumberValue
224 |
225 |
226 |
227 | def SetNumber(self, NewNumber):
228 | self.NumberValue = NewNumber
229 |
230 |
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Number.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/Number.pyc
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Sounds/Belt.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/Sounds/Belt.wav
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Sounds/Credit.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/Sounds/Credit.wav
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Sounds/HyperSpace.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/Sounds/HyperSpace.wav
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Sounds/Rock.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/Sounds/Rock.wav
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Sounds/Shot.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/Sounds/Shot.wav
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Sounds/Thrust.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/Sounds/Thrust.wav
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Sounds/UFO.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/Sounds/UFO.wav
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Sounds/UFOShot.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/Sounds/UFOShot.wav
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Text.py:
--------------------------------------------------------------------------------
1 | # AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO
2 | # Copyright (C) 2015 Jason Birch
3 | #
4 | # This program is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
16 |
17 | #/****************************************************************************/
18 | #/* AsteroidsSPI - Raspberry Pi Asteroids Using SPI Display and SPI GPIO */
19 | #/* ------------------------------------------------------------------------ */
20 | #/* V1.00 - 2016-11-03 - Jason Birch */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* Conversion of Asteroids example game programming on multiple platforms, */
23 | #/* for Python on the Raspberry Pi using a 128x64 OLED SPI display and SPI */
24 | #/* GPIO port extender. The RPiSPiDev device driver is used to interface the */
25 | #/* Python code with the SPI hardware. */
26 | #/****************************************************************************/
27 |
28 |
29 | import Common
30 |
31 |
32 | class Text:
33 | MAX_LETTERS = 58
34 | MAX_POINTS = 12
35 | MAX_TEXT = 2048
36 | INFINATE_FRAMES = -1
37 |
38 |
39 | def __init__(self):
40 | self.TextString = ""
41 | self.xOffset = 0
42 | self.yOffset = 0
43 | self.Scale = 0
44 | self.TextColour = 0
45 | self.Visible = False
46 | self.LastVisible = False
47 | self.FlashVisible = False
48 | self.Active = False
49 | self.Frames = self.INFINATE_FRAMES
50 | self.FrameCount = 0
51 | self.Flash = False
52 |
53 | self.Letter = [[Common.XPoint() for X in range(self.MAX_POINTS + 1)] for Y in range(self.MAX_LETTERS + 1)]
54 | self.DisplayFrame = [[Common.XPoint() for X in range(self.MAX_POINTS + 1)] for Y in range(self.MAX_TEXT + 1)]
55 |
56 |
57 |
58 | def Draw(self):
59 | if self.Active == True:
60 | # /********************************************/
61 | # /* Display only for given number of frames. */
62 | #/********************************************/
63 | if self.FrameCount != self.INFINATE_FRAMES:
64 | self.FrameCount -= 1
65 | if self.FrameCount == False and self.Flash == True:
66 | self.FrameCount = self.Frames
67 | self.FlashVisible = not self.FlashVisible
68 | elif self.FrameCount == False:
69 | self.Active = False
70 |
71 | # /****************************/
72 | # /* Plot Text current value. */
73 | #/****************************/
74 | for self.Digit in range(self.MAX_TEXT):
75 | if self.Digit >= len(self.TextString):
76 | break
77 | if self.TextString[self.Digit] >= '!' and self.TextString[self.Digit] <= 'Z':
78 | # /************************/
79 | # /* Erase previous Text. */
80 | #/************************/
81 | if self.Active == False or self.Visible == False or self.FlashVisible == False:
82 | Common.DrawLines(self.DisplayFrame[self.Digit], self.DisplayFrame[self.Digit][self.MAX_POINTS].x, 0)
83 | else:
84 | # /**************************/
85 | # /* Draw the current Text. */
86 | #/**************************/
87 | Common.DrawLines(self.DisplayFrame[self.Digit], self.DisplayFrame[self.Digit][self.MAX_POINTS].x, 1)
88 |
89 |
90 |
91 | def SetLocation(self, NewxOffset, NewyOffset, NewScale, NewFrames, NewFlash, NewText, NewTextColour):
92 | self.xOffsetOrig = NewxOffset
93 | self.xOffset = NewxOffset
94 | self.yOffset = NewyOffset
95 | self.Scale = NewScale
96 | self.TextColour = NewTextColour
97 | self.Frames = NewFrames
98 | self.Flash = NewFlash
99 | self.TextString = NewText
100 | self.Length = len(self.TextString)
101 | self.TextString = self.TextString.upper()
102 |
103 | # !
104 | self.Letter[0][self.MAX_POINTS].x = 2
105 | self.Letter[0][0].x = 2 * self.Scale
106 | self.Letter[0][0].y = 0 * self.Scale
107 | self.Letter[0][1].x = 2 * self.Scale
108 | self.Letter[0][1].y = 3 * self.Scale
109 | # "
110 | self.Letter[1][self.MAX_POINTS].x = 4
111 | self.Letter[1][0].x = 1 * self.Scale
112 | self.Letter[1][0].y = 1 * self.Scale
113 | self.Letter[1][1].x = 1 * self.Scale
114 | self.Letter[1][1].y = 0 * self.Scale
115 | self.Letter[1][2].x = 2 * self.Scale
116 | self.Letter[1][2].y = 0 * self.Scale
117 | self.Letter[1][3].x = 2 * self.Scale
118 | self.Letter[1][3].y = 1 * self.Scale
119 | # #
120 | self.Letter[2][self.MAX_POINTS].x = 11
121 | self.Letter[2][0].x = 1 * self.Scale
122 | self.Letter[2][0].y = 0 * self.Scale
123 | self.Letter[2][1].x = 1 * self.Scale
124 | self.Letter[2][1].y = 4 * self.Scale
125 | self.Letter[2][2].x = 1 * self.Scale
126 | self.Letter[2][2].y = 3 * self.Scale
127 | self.Letter[2][3].x = 0 * self.Scale
128 | self.Letter[2][3].y = 3 * self.Scale
129 | self.Letter[2][4].x = 3 * self.Scale
130 | self.Letter[2][4].y = 3 * self.Scale
131 | self.Letter[2][5].x = 2 * self.Scale
132 | self.Letter[2][5].y = 3 * self.Scale
133 | self.Letter[2][6].x = 2 * self.Scale
134 | self.Letter[2][6].y = 4 * self.Scale
135 | self.Letter[2][7].x = 2 * self.Scale
136 | self.Letter[2][7].y = 0 * self.Scale
137 | self.Letter[2][8].x = 2 * self.Scale
138 | self.Letter[2][8].y = 1 * self.Scale
139 | self.Letter[2][9].x = 3 * self.Scale
140 | self.Letter[2][9].y = 1 * self.Scale
141 | self.Letter[2][10].x = 0 * self.Scale
142 | self.Letter[2][10].y = 1 * self.Scale
143 | # $
144 | self.Letter[3][self.MAX_POINTS].x = 9
145 | self.Letter[3][0].x = 3 * self.Scale
146 | self.Letter[3][0].y = 1 * self.Scale
147 | self.Letter[3][1].x = 1 * self.Scale
148 | self.Letter[3][1].y = 1 * self.Scale
149 | self.Letter[3][2].x = 0 * self.Scale
150 | self.Letter[3][2].y = 2 * self.Scale
151 | self.Letter[3][3].x = 3 * self.Scale
152 | self.Letter[3][3].y = 2 * self.Scale
153 | self.Letter[3][4].x = 2 * self.Scale
154 | self.Letter[3][4].y = 3 * self.Scale
155 | self.Letter[3][5].x = 0 * self.Scale
156 | self.Letter[3][5].y = 3 * self.Scale
157 | self.Letter[3][6].x = 1 * self.Scale
158 | self.Letter[3][6].y = 3 * self.Scale
159 | self.Letter[3][7].x = 0 * self.Scale
160 | self.Letter[3][7].y = 4 * self.Scale
161 | self.Letter[3][8].x = 3 * self.Scale
162 | self.Letter[3][8].y = 0 * self.Scale
163 | # %
164 | self.Letter[4][self.MAX_POINTS].x = 11
165 | self.Letter[4][0].x = 0 * self.Scale
166 | self.Letter[4][0].y = 0 * self.Scale
167 | self.Letter[4][1].x = 0 * self.Scale
168 | self.Letter[4][1].y = 1 * self.Scale
169 | self.Letter[4][2].x = 1 * self.Scale
170 | self.Letter[4][2].y = 1 * self.Scale
171 | self.Letter[4][3].x = 1 * self.Scale
172 | self.Letter[4][3].y = 0 * self.Scale
173 | self.Letter[4][4].x = 0 * self.Scale
174 | self.Letter[4][4].y = 0 * self.Scale
175 | self.Letter[4][5].x = 3 * self.Scale
176 | self.Letter[4][5].y = 0 * self.Scale
177 | self.Letter[4][6].x = 0 * self.Scale
178 | self.Letter[4][6].y = 4 * self.Scale
179 | self.Letter[4][7].x = 3 * self.Scale
180 | self.Letter[4][7].y = 4 * self.Scale
181 | self.Letter[4][8].x = 3 * self.Scale
182 | self.Letter[4][8].y = 3 * self.Scale
183 | self.Letter[4][9].x = 2 * self.Scale
184 | self.Letter[4][9].y = 3 * self.Scale
185 | self.Letter[4][10].x = 2 * self.Scale
186 | self.Letter[4][10].y = 4 * self.Scale
187 | # &
188 | self.Letter[5][self.MAX_POINTS].x = 7
189 | self.Letter[5][0].x = 3 * self.Scale
190 | self.Letter[5][0].y = 4 * self.Scale
191 | self.Letter[5][1].x = 0 * self.Scale
192 | self.Letter[5][1].y = 1 * self.Scale
193 | self.Letter[5][2].x = 1 * self.Scale
194 | self.Letter[5][2].y = 0 * self.Scale
195 | self.Letter[5][3].x = 2 * self.Scale
196 | self.Letter[5][3].y = 1 * self.Scale
197 | self.Letter[5][4].x = 0 * self.Scale
198 | self.Letter[5][4].y = 3 * self.Scale
199 | self.Letter[5][5].x = 1 * self.Scale
200 | self.Letter[5][5].y = 4 * self.Scale
201 | self.Letter[5][6].x = 3 * self.Scale
202 | self.Letter[5][6].y = 2 * self.Scale
203 | # '
204 | self.Letter[6][self.MAX_POINTS].x = 2
205 | self.Letter[6][0].x = 2 * self.Scale
206 | self.Letter[6][0].y = 0 * self.Scale
207 | self.Letter[6][1].x = 1 * self.Scale
208 | self.Letter[6][1].y = 1 * self.Scale
209 | # (
210 | self.Letter[7][self.MAX_POINTS].x = 6
211 | self.Letter[7][0].x = 2 * self.Scale
212 | self.Letter[7][0].y = 0 * self.Scale
213 | self.Letter[7][1].x = 1 * self.Scale
214 | self.Letter[7][1].y = 0 * self.Scale
215 | self.Letter[7][2].x = 0 * self.Scale
216 | self.Letter[7][2].y = 1 * self.Scale
217 | self.Letter[7][3].x = 0 * self.Scale
218 | self.Letter[7][3].y = 3 * self.Scale
219 | self.Letter[7][4].x = 1 * self.Scale
220 | self.Letter[7][4].y = 4 * self.Scale
221 | self.Letter[7][5].x = 2 * self.Scale
222 | self.Letter[7][5].y = 4 * self.Scale
223 | # )
224 | self.Letter[8][self.MAX_POINTS].x = 6
225 | self.Letter[8][0].x = 1 * self.Scale
226 | self.Letter[8][0].y = 0 * self.Scale
227 | self.Letter[8][1].x = 2 * self.Scale
228 | self.Letter[8][1].y = 0 * self.Scale
229 | self.Letter[8][2].x = 3 * self.Scale
230 | self.Letter[8][2].y = 1 * self.Scale
231 | self.Letter[8][3].x = 3 * self.Scale
232 | self.Letter[8][3].y = 3 * self.Scale
233 | self.Letter[8][4].x = 2 * self.Scale
234 | self.Letter[8][4].y = 4 * self.Scale
235 | self.Letter[8][5].x = 1 * self.Scale
236 | self.Letter[8][5].y = 4 * self.Scale
237 | # *
238 | self.Letter[9][self.MAX_POINTS].x = 11
239 | self.Letter[9][0].x = 0 * self.Scale
240 | self.Letter[9][0].y = 1 * self.Scale
241 | self.Letter[9][1].x = 2 * self.Scale
242 | self.Letter[9][1].y = 3 * self.Scale
243 | self.Letter[9][2].x = 1 * self.Scale
244 | self.Letter[9][2].y = 2 * self.Scale
245 | self.Letter[9][3].x = 0 * self.Scale
246 | self.Letter[9][3].y = 3 * self.Scale
247 | self.Letter[9][4].x = 2 * self.Scale
248 | self.Letter[9][4].y = 1 * self.Scale
249 | self.Letter[9][5].x = 1 * self.Scale
250 | self.Letter[9][5].y = 2 * self.Scale
251 | self.Letter[9][6].x = 0 * self.Scale
252 | self.Letter[9][6].y = 2 * self.Scale
253 | self.Letter[9][7].x = 2 * self.Scale
254 | self.Letter[9][7].y = 2 * self.Scale
255 | self.Letter[9][8].x = 1 * self.Scale
256 | self.Letter[9][8].y = 2 * self.Scale
257 | self.Letter[9][9].x = 1 * self.Scale
258 | self.Letter[9][9].y = 1 * self.Scale
259 | self.Letter[9][10].x = 1 * self.Scale
260 | self.Letter[9][10].y = 3 * self.Scale
261 | # +
262 | self.Letter[10][self.MAX_POINTS].x = 5
263 | self.Letter[10][0].x = 1 * self.Scale
264 | self.Letter[10][0].y = 1 * self.Scale
265 | self.Letter[10][1].x = 1 * self.Scale
266 | self.Letter[10][1].y = 3 * self.Scale
267 | self.Letter[10][2].x = 1 * self.Scale
268 | self.Letter[10][2].y = 2 * self.Scale
269 | self.Letter[10][3].x = 0 * self.Scale
270 | self.Letter[10][3].y = 2 * self.Scale
271 | self.Letter[10][4].x = 2 * self.Scale
272 | self.Letter[10][4].y = 2 * self.Scale
273 | # ,
274 | self.Letter[11][self.MAX_POINTS].x = 2
275 | self.Letter[11][0].x = 2 * self.Scale
276 | self.Letter[11][0].y = 3 * self.Scale
277 | self.Letter[11][1].x = 1 * self.Scale
278 | self.Letter[11][1].y = 4 * self.Scale
279 | # -
280 | self.Letter[12][self.MAX_POINTS].x = 2
281 | self.Letter[12][0].x = 0 * self.Scale
282 | self.Letter[12][0].y = 2 * self.Scale
283 | self.Letter[12][1].x = 2 * self.Scale
284 | self.Letter[12][1].y = 2 * self.Scale
285 | # .
286 | self.Letter[13][self.MAX_POINTS].x = 2
287 | self.Letter[13][0].x = 2 * self.Scale
288 | self.Letter[13][0].y = 4 * self.Scale
289 | self.Letter[13][1].x = 2 * self.Scale
290 | self.Letter[13][1].y = 4 * self.Scale
291 | # /
292 | self.Letter[14][self.MAX_POINTS].x = 2
293 | self.Letter[14][0].x = 0 * self.Scale
294 | self.Letter[14][0].y = 4 * self.Scale
295 | self.Letter[14][1].x = 3 * self.Scale
296 | self.Letter[14][1].y = 0 * self.Scale
297 | # 0
298 | self.Letter[15][self.MAX_POINTS].x = 9
299 | self.Letter[15][0].x = 1 * self.Scale
300 | self.Letter[15][0].y = 0 * self.Scale
301 | self.Letter[15][1].x = 2 * self.Scale
302 | self.Letter[15][1].y = 0 * self.Scale
303 | self.Letter[15][2].x = 3 * self.Scale
304 | self.Letter[15][2].y = 1 * self.Scale
305 | self.Letter[15][3].x = 3 * self.Scale
306 | self.Letter[15][3].y = 3 * self.Scale
307 | self.Letter[15][4].x = 2 * self.Scale
308 | self.Letter[15][4].y = 4 * self.Scale
309 | self.Letter[15][5].x = 1 * self.Scale
310 | self.Letter[15][5].y = 4 * self.Scale
311 | self.Letter[15][6].x = 0 * self.Scale
312 | self.Letter[15][6].y = 3 * self.Scale
313 | self.Letter[15][7].x = 0 * self.Scale
314 | self.Letter[15][7].y = 1 * self.Scale
315 | self.Letter[15][8].x = 1 * self.Scale
316 | self.Letter[15][8].y = 0 * self.Scale
317 | # 1
318 | self.Letter[16][self.MAX_POINTS].x = 2
319 | self.Letter[16][0].x = 2 * self.Scale
320 | self.Letter[16][0].y = 0 * self.Scale
321 | self.Letter[16][1].x = 2 * self.Scale
322 | self.Letter[16][1].y = 4 * self.Scale
323 | # 2
324 | self.Letter[17][self.MAX_POINTS].x = 9
325 | self.Letter[17][0].x = 0 * self.Scale
326 | self.Letter[17][0].y = 1 * self.Scale
327 | self.Letter[17][1].x = 1 * self.Scale
328 | self.Letter[17][1].y = 0 * self.Scale
329 | self.Letter[17][2].x = 2 * self.Scale
330 | self.Letter[17][2].y = 0 * self.Scale
331 | self.Letter[17][3].x = 3 * self.Scale
332 | self.Letter[17][3].y = 1 * self.Scale
333 | self.Letter[17][4].x = 2 * self.Scale
334 | self.Letter[17][4].y = 2 * self.Scale
335 | self.Letter[17][5].x = 1 * self.Scale
336 | self.Letter[17][5].y = 2 * self.Scale
337 | self.Letter[17][6].x = 0 * self.Scale
338 | self.Letter[17][6].y = 3 * self.Scale
339 | self.Letter[17][7].x = 0 * self.Scale
340 | self.Letter[17][7].y = 4 * self.Scale
341 | self.Letter[17][8].x = 3 * self.Scale
342 | self.Letter[17][8].y = 4 * self.Scale
343 | # 3
344 | self.Letter[18][self.MAX_POINTS].x = 9
345 | self.Letter[18][0].x = 0 * self.Scale
346 | self.Letter[18][0].y = 0 * self.Scale
347 | self.Letter[18][1].x = 2 * self.Scale
348 | self.Letter[18][1].y = 0 * self.Scale
349 | self.Letter[18][2].x = 3 * self.Scale
350 | self.Letter[18][2].y = 1 * self.Scale
351 | self.Letter[18][3].x = 2 * self.Scale
352 | self.Letter[18][3].y = 2 * self.Scale
353 | self.Letter[18][4].x = 1 * self.Scale
354 | self.Letter[18][4].y = 2 * self.Scale
355 | self.Letter[18][5].x = 2 * self.Scale
356 | self.Letter[18][5].y = 2 * self.Scale
357 | self.Letter[18][6].x = 3 * self.Scale
358 | self.Letter[18][6].y = 3 * self.Scale
359 | self.Letter[18][7].x = 2 * self.Scale
360 | self.Letter[18][7].y = 4 * self.Scale
361 | self.Letter[18][8].x = 0 * self.Scale
362 | self.Letter[18][8].y = 4 * self.Scale
363 | # 4
364 | self.Letter[19][self.MAX_POINTS].x = 4
365 | self.Letter[19][0].x = 2 * self.Scale
366 | self.Letter[19][0].y = 4 * self.Scale
367 | self.Letter[19][1].x = 2 * self.Scale
368 | self.Letter[19][1].y = 0 * self.Scale
369 | self.Letter[19][2].x = 0 * self.Scale
370 | self.Letter[19][2].y = 3 * self.Scale
371 | self.Letter[19][3].x = 3 * self.Scale
372 | self.Letter[19][3].y = 3 * self.Scale
373 | # 5
374 | self.Letter[20][self.MAX_POINTS].x = 7
375 | self.Letter[20][0].x = 3 * self.Scale
376 | self.Letter[20][0].y = 0 * self.Scale
377 | self.Letter[20][1].x = 0 * self.Scale
378 | self.Letter[20][1].y = 0 * self.Scale
379 | self.Letter[20][2].x = 0 * self.Scale
380 | self.Letter[20][2].y = 2 * self.Scale
381 | self.Letter[20][3].x = 2 * self.Scale
382 | self.Letter[20][3].y = 2 * self.Scale
383 | self.Letter[20][4].x = 3 * self.Scale
384 | self.Letter[20][4].y = 3 * self.Scale
385 | self.Letter[20][5].x = 2 * self.Scale
386 | self.Letter[20][5].y = 4 * self.Scale
387 | self.Letter[20][6].x = 0 * self.Scale
388 | self.Letter[20][6].y = 4 * self.Scale
389 | # 6
390 | self.Letter[21][self.MAX_POINTS].x = 9
391 | self.Letter[21][0].x = 3 * self.Scale
392 | self.Letter[21][0].y = 0 * self.Scale
393 | self.Letter[21][1].x = 1 * self.Scale
394 | self.Letter[21][1].y = 0 * self.Scale
395 | self.Letter[21][2].x = 0 * self.Scale
396 | self.Letter[21][2].y = 1 * self.Scale
397 | self.Letter[21][3].x = 0 * self.Scale
398 | self.Letter[21][3].y = 3 * self.Scale
399 | self.Letter[21][4].x = 1 * self.Scale
400 | self.Letter[21][4].y = 4 * self.Scale
401 | self.Letter[21][5].x = 2 * self.Scale
402 | self.Letter[21][5].y = 4 * self.Scale
403 | self.Letter[21][6].x = 3 * self.Scale
404 | self.Letter[21][6].y = 3 * self.Scale
405 | self.Letter[21][7].x = 3 * self.Scale
406 | self.Letter[21][7].y = 2 * self.Scale
407 | self.Letter[21][8].x = 0 * self.Scale
408 | self.Letter[21][8].y = 2 * self.Scale
409 | # 7
410 | self.Letter[22][self.MAX_POINTS].x = 3
411 | self.Letter[22][0].x = 0 * self.Scale
412 | self.Letter[22][0].y = 0 * self.Scale
413 | self.Letter[22][1].x = 3 * self.Scale
414 | self.Letter[22][1].y = 0 * self.Scale
415 | self.Letter[22][2].x = 0 * self.Scale
416 | self.Letter[22][2].y = 4 * self.Scale
417 | # 8
418 | self.Letter[23][self.MAX_POINTS].x = 9
419 | self.Letter[23][0].x = 0 * self.Scale
420 | self.Letter[23][0].y = 1 * self.Scale
421 | self.Letter[23][1].x = 1 * self.Scale
422 | self.Letter[23][1].y = 0 * self.Scale
423 | self.Letter[23][2].x = 2 * self.Scale
424 | self.Letter[23][2].y = 0 * self.Scale
425 | self.Letter[23][3].x = 3 * self.Scale
426 | self.Letter[23][3].y = 1 * self.Scale
427 | self.Letter[23][4].x = 0 * self.Scale
428 | self.Letter[23][4].y = 3 * self.Scale
429 | self.Letter[23][5].x = 1 * self.Scale
430 | self.Letter[23][5].y = 4 * self.Scale
431 | self.Letter[23][6].x = 2 * self.Scale
432 | self.Letter[23][6].y = 4 * self.Scale
433 | self.Letter[23][7].x = 3 * self.Scale
434 | self.Letter[23][7].y = 3 * self.Scale
435 | self.Letter[23][8].x = 0 * self.Scale
436 | self.Letter[23][8].y = 1 * self.Scale
437 | # 9
438 | self.Letter[24][self.MAX_POINTS].x = 9
439 | self.Letter[24][0].x = 0 * self.Scale
440 | self.Letter[24][0].y = 4 * self.Scale
441 | self.Letter[24][1].x = 2 * self.Scale
442 | self.Letter[24][1].y = 4 * self.Scale
443 | self.Letter[24][2].x = 3 * self.Scale
444 | self.Letter[24][2].y = 3 * self.Scale
445 | self.Letter[24][3].x = 3 * self.Scale
446 | self.Letter[24][3].y = 1 * self.Scale
447 | self.Letter[24][4].x = 2 * self.Scale
448 | self.Letter[24][4].y = 0 * self.Scale
449 | self.Letter[24][5].x = 1 * self.Scale
450 | self.Letter[24][5].y = 0 * self.Scale
451 | self.Letter[24][6].x = 0 * self.Scale
452 | self.Letter[24][6].y = 1 * self.Scale
453 | self.Letter[24][7].x = 0 * self.Scale
454 | self.Letter[24][7].y = 2 * self.Scale
455 | self.Letter[24][8].x = 3 * self.Scale
456 | self.Letter[24][8].y = 2 * self.Scale
457 | # :
458 | self.Letter[25][self.MAX_POINTS].x = 2
459 | self.Letter[25][0].x = 2 * self.Scale
460 | self.Letter[25][0].y = 1 * self.Scale
461 | self.Letter[25][1].x = 2 * self.Scale
462 | self.Letter[25][1].y = 3 * self.Scale
463 | # ;
464 | self.Letter[26][self.MAX_POINTS].x = 3
465 | self.Letter[26][0].x = 2 * self.Scale
466 | self.Letter[26][0].y = 1 * self.Scale
467 | self.Letter[26][1].x = 2 * self.Scale
468 | self.Letter[26][1].y = 3 * self.Scale
469 | self.Letter[26][2].x = 1 * self.Scale
470 | self.Letter[26][2].y = 4 * self.Scale
471 | # <
472 | self.Letter[27][self.MAX_POINTS].x = 3
473 | self.Letter[27][0].x = 3 * self.Scale
474 | self.Letter[27][0].y = 1 * self.Scale
475 | self.Letter[27][1].x = 0 * self.Scale
476 | self.Letter[27][1].y = 2 * self.Scale
477 | self.Letter[27][2].x = 3 * self.Scale
478 | self.Letter[27][2].y = 3 * self.Scale
479 | # =
480 | self.Letter[28][self.MAX_POINTS].x = 4
481 | self.Letter[28][0].x = 3 * self.Scale
482 | self.Letter[28][0].y = 1 * self.Scale
483 | self.Letter[28][1].x = 0 * self.Scale
484 | self.Letter[28][1].y = 1 * self.Scale
485 | self.Letter[28][2].x = 0 * self.Scale
486 | self.Letter[28][2].y = 3 * self.Scale
487 | self.Letter[28][3].x = 3 * self.Scale
488 | self.Letter[28][3].y = 3 * self.Scale
489 | # >
490 | self.Letter[29][self.MAX_POINTS].x = 3
491 | self.Letter[29][0].x = 0 * self.Scale
492 | self.Letter[29][0].y = 1 * self.Scale
493 | self.Letter[29][1].x = 3 * self.Scale
494 | self.Letter[29][1].y = 2 * self.Scale
495 | self.Letter[29][2].x = 0 * self.Scale
496 | self.Letter[29][2].y = 3 * self.Scale
497 | # ?
498 | self.Letter[30][self.MAX_POINTS].x = 7
499 | self.Letter[30][0].x = 0 * self.Scale
500 | self.Letter[30][0].y = 1 * self.Scale
501 | self.Letter[30][1].x = 1 * self.Scale
502 | self.Letter[30][1].y = 0 * self.Scale
503 | self.Letter[30][2].x = 2 * self.Scale
504 | self.Letter[30][2].y = 0 * self.Scale
505 | self.Letter[30][3].x = 3 * self.Scale
506 | self.Letter[30][3].y = 1 * self.Scale
507 | self.Letter[30][4].x = 3 * self.Scale
508 | self.Letter[30][4].y = 2 * self.Scale
509 | self.Letter[30][5].x = 2 * self.Scale
510 | self.Letter[30][5].y = 3 * self.Scale
511 | self.Letter[30][6].x = 2 * self.Scale
512 | self.Letter[30][6].y = 4 * self.Scale
513 | # @
514 | self.Letter[31][self.MAX_POINTS].x = 12
515 | self.Letter[31][0].x = 3 * self.Scale
516 | self.Letter[31][0].y = 4 * self.Scale
517 | self.Letter[31][1].x = 1 * self.Scale
518 | self.Letter[31][1].y = 4 * self.Scale
519 | self.Letter[31][2].x = 0 * self.Scale
520 | self.Letter[31][2].y = 3 * self.Scale
521 | self.Letter[31][3].x = 0 * self.Scale
522 | self.Letter[31][3].y = 1 * self.Scale
523 | self.Letter[31][4].x = 1 * self.Scale
524 | self.Letter[31][4].y = 0 * self.Scale
525 | self.Letter[31][5].x = 2 * self.Scale
526 | self.Letter[31][5].y = 0 * self.Scale
527 | self.Letter[31][6].x = 3 * self.Scale
528 | self.Letter[31][6].y = 1 * self.Scale
529 | self.Letter[31][7].x = 3 * self.Scale
530 | self.Letter[31][7].y = 2 * self.Scale
531 | self.Letter[31][8].x = 2 * self.Scale
532 | self.Letter[31][8].y = 3 * self.Scale
533 | self.Letter[31][9].x = 1 * self.Scale
534 | self.Letter[31][9].y = 2 * self.Scale
535 | self.Letter[31][10].x = 2 * self.Scale
536 | self.Letter[31][10].y = 1 * self.Scale
537 | self.Letter[31][11].x = 3 * self.Scale
538 | self.Letter[31][11].y = 1 * self.Scale
539 | # A
540 | self.Letter[32][self.MAX_POINTS].x = 6
541 | self.Letter[32][0].x = 0 * self.Scale
542 | self.Letter[32][0].y = 4 * self.Scale
543 | self.Letter[32][1].x = 0 * self.Scale
544 | self.Letter[32][1].y = 0 * self.Scale
545 | self.Letter[32][2].x = 3 * self.Scale
546 | self.Letter[32][2].y = 0 * self.Scale
547 | self.Letter[32][3].x = 3 * self.Scale
548 | self.Letter[32][3].y = 4 * self.Scale
549 | self.Letter[32][4].x = 3 * self.Scale
550 | self.Letter[32][4].y = 2 * self.Scale
551 | self.Letter[32][5].x = 0 * self.Scale
552 | self.Letter[32][5].y = 2 * self.Scale
553 | # B
554 | self.Letter[33][self.MAX_POINTS].x = 8
555 | self.Letter[33][0].x = 0 * self.Scale
556 | self.Letter[33][0].y = 0 * self.Scale
557 | self.Letter[33][1].x = 0 * self.Scale
558 | self.Letter[33][1].y = 4 * self.Scale
559 | self.Letter[33][2].x = 3 * self.Scale
560 | self.Letter[33][2].y = 4 * self.Scale
561 | self.Letter[33][3].x = 3 * self.Scale
562 | self.Letter[33][3].y = 3 * self.Scale
563 | self.Letter[33][4].x = 0 * self.Scale
564 | self.Letter[33][4].y = 2 * self.Scale
565 | self.Letter[33][5].x = 3 * self.Scale
566 | self.Letter[33][5].y = 1 * self.Scale
567 | self.Letter[33][6].x = 3 * self.Scale
568 | self.Letter[33][6].y = 0 * self.Scale
569 | self.Letter[33][7].x = 0 * self.Scale
570 | self.Letter[33][7].y = 0 * self.Scale
571 | # C
572 | self.Letter[34][self.MAX_POINTS].x = 6
573 | self.Letter[34][0].x = 3 * self.Scale
574 | self.Letter[34][0].y = 0 * self.Scale
575 | self.Letter[34][1].x = 1 * self.Scale
576 | self.Letter[34][1].y = 0 * self.Scale
577 | self.Letter[34][2].x = 0 * self.Scale
578 | self.Letter[34][2].y = 1 * self.Scale
579 | self.Letter[34][3].x = 0 * self.Scale
580 | self.Letter[34][3].y = 3 * self.Scale
581 | self.Letter[34][4].x = 1 * self.Scale
582 | self.Letter[34][4].y = 4 * self.Scale
583 | self.Letter[34][5].x = 3 * self.Scale
584 | self.Letter[34][5].y = 4 * self.Scale
585 | # D
586 | self.Letter[35][self.MAX_POINTS].x = 6
587 | self.Letter[35][0].x = 0 * self.Scale
588 | self.Letter[35][0].y = 0 * self.Scale
589 | self.Letter[35][1].x = 0 * self.Scale
590 | self.Letter[35][1].y = 4 * self.Scale
591 | self.Letter[35][2].x = 1 * self.Scale
592 | self.Letter[35][2].y = 4 * self.Scale
593 | self.Letter[35][3].x = 3 * self.Scale
594 | self.Letter[35][3].y = 2 * self.Scale
595 | self.Letter[35][4].x = 1 * self.Scale
596 | self.Letter[35][4].y = 0 * self.Scale
597 | self.Letter[35][5].x = 0 * self.Scale
598 | self.Letter[35][5].y = 0 * self.Scale
599 | # E
600 | self.Letter[36][self.MAX_POINTS].x = 7
601 | self.Letter[36][0].x = 3 * self.Scale
602 | self.Letter[36][0].y = 0 * self.Scale
603 | self.Letter[36][1].x = 0 * self.Scale
604 | self.Letter[36][1].y = 0 * self.Scale
605 | self.Letter[36][2].x = 0 * self.Scale
606 | self.Letter[36][2].y = 2 * self.Scale
607 | self.Letter[36][3].x = 2 * self.Scale
608 | self.Letter[36][3].y = 2 * self.Scale
609 | self.Letter[36][4].x = 0 * self.Scale
610 | self.Letter[36][4].y = 2 * self.Scale
611 | self.Letter[36][5].x = 0 * self.Scale
612 | self.Letter[36][5].y = 4 * self.Scale
613 | self.Letter[36][6].x = 3 * self.Scale
614 | self.Letter[36][6].y = 4 * self.Scale
615 | # F
616 | self.Letter[37][self.MAX_POINTS].x = 6
617 | self.Letter[37][0].x = 3 * self.Scale
618 | self.Letter[37][0].y = 0 * self.Scale
619 | self.Letter[37][1].x = 0 * self.Scale
620 | self.Letter[37][1].y = 0 * self.Scale
621 | self.Letter[37][2].x = 0 * self.Scale
622 | self.Letter[37][2].y = 2 * self.Scale
623 | self.Letter[37][3].x = 2 * self.Scale
624 | self.Letter[37][3].y = 2 * self.Scale
625 | self.Letter[37][4].x = 0 * self.Scale
626 | self.Letter[37][4].y = 2 * self.Scale
627 | self.Letter[37][5].x = 0 * self.Scale
628 | self.Letter[37][5].y = 4 * self.Scale
629 | # G
630 | self.Letter[38][self.MAX_POINTS].x = 6
631 | self.Letter[38][0].x = 3 * self.Scale
632 | self.Letter[38][0].y = 0 * self.Scale
633 | self.Letter[38][1].x = 0 * self.Scale
634 | self.Letter[38][1].y = 0 * self.Scale
635 | self.Letter[38][2].x = 0 * self.Scale
636 | self.Letter[38][2].y = 4 * self.Scale
637 | self.Letter[38][3].x = 3 * self.Scale
638 | self.Letter[38][3].y = 4 * self.Scale
639 | self.Letter[38][4].x = 3 * self.Scale
640 | self.Letter[38][4].y = 2 * self.Scale
641 | self.Letter[38][5].x = 1 * self.Scale
642 | self.Letter[38][5].y = 2 * self.Scale
643 | # H
644 | self.Letter[39][self.MAX_POINTS].x = 6
645 | self.Letter[39][0].x = 0 * self.Scale
646 | self.Letter[39][0].y = 0 * self.Scale
647 | self.Letter[39][1].x = 0 * self.Scale
648 | self.Letter[39][1].y = 4 * self.Scale
649 | self.Letter[39][2].x = 0 * self.Scale
650 | self.Letter[39][2].y = 2 * self.Scale
651 | self.Letter[39][3].x = 3 * self.Scale
652 | self.Letter[39][3].y = 2 * self.Scale
653 | self.Letter[39][4].x = 3 * self.Scale
654 | self.Letter[39][4].y = 0 * self.Scale
655 | self.Letter[39][5].x = 3 * self.Scale
656 | self.Letter[39][5].y = 4 * self.Scale
657 | # I
658 | self.Letter[40][self.MAX_POINTS].x = 6
659 | self.Letter[40][0].x = 1 * self.Scale
660 | self.Letter[40][0].y = 0 * self.Scale
661 | self.Letter[40][1].x = 3 * self.Scale
662 | self.Letter[40][1].y = 0 * self.Scale
663 | self.Letter[40][2].x = 2 * self.Scale
664 | self.Letter[40][2].y = 0 * self.Scale
665 | self.Letter[40][3].x = 2 * self.Scale
666 | self.Letter[40][3].y = 4 * self.Scale
667 | self.Letter[40][4].x = 1 * self.Scale
668 | self.Letter[40][4].y = 4 * self.Scale
669 | self.Letter[40][5].x = 3 * self.Scale
670 | self.Letter[40][5].y = 4 * self.Scale
671 | # J
672 | self.Letter[41][self.MAX_POINTS].x = 6
673 | self.Letter[41][0].x = 1 * self.Scale
674 | self.Letter[41][0].y = 0 * self.Scale
675 | self.Letter[41][1].x = 3 * self.Scale
676 | self.Letter[41][1].y = 0 * self.Scale
677 | self.Letter[41][2].x = 2 * self.Scale
678 | self.Letter[41][2].y = 0 * self.Scale
679 | self.Letter[41][3].x = 2 * self.Scale
680 | self.Letter[41][3].y = 4 * self.Scale
681 | self.Letter[41][4].x = 0 * self.Scale
682 | self.Letter[41][4].y = 4 * self.Scale
683 | self.Letter[41][5].x = 0 * self.Scale
684 | self.Letter[41][5].y = 3 * self.Scale
685 | # K
686 | self.Letter[42][self.MAX_POINTS].x = 6
687 | self.Letter[42][0].x = 0 * self.Scale
688 | self.Letter[42][0].y = 0 * self.Scale
689 | self.Letter[42][1].x = 0 * self.Scale
690 | self.Letter[42][1].y = 4 * self.Scale
691 | self.Letter[42][2].x = 0 * self.Scale
692 | self.Letter[42][2].y = 2 * self.Scale
693 | self.Letter[42][3].x = 3 * self.Scale
694 | self.Letter[42][3].y = 0 * self.Scale
695 | self.Letter[42][4].x = 0 * self.Scale
696 | self.Letter[42][4].y = 2 * self.Scale
697 | self.Letter[42][5].x = 3 * self.Scale
698 | self.Letter[42][5].y = 4 * self.Scale
699 | # L
700 | self.Letter[43][self.MAX_POINTS].x = 3
701 | self.Letter[43][0].x = 0 * self.Scale
702 | self.Letter[43][0].y = 0 * self.Scale
703 | self.Letter[43][1].x = 0 * self.Scale
704 | self.Letter[43][1].y = 4 * self.Scale
705 | self.Letter[43][2].x = 3 * self.Scale
706 | self.Letter[43][2].y = 4 * self.Scale
707 | # M
708 | self.Letter[44][self.MAX_POINTS].x = 6
709 | self.Letter[44][0].x = 0 * self.Scale
710 | self.Letter[44][0].y = 4 * self.Scale
711 | self.Letter[44][1].x = 0 * self.Scale
712 | self.Letter[44][1].y = 0 * self.Scale
713 | self.Letter[44][2].x = 1 * self.Scale
714 | self.Letter[44][2].y = 2 * self.Scale
715 | self.Letter[44][3].x = 2 * self.Scale
716 | self.Letter[44][3].y = 2 * self.Scale
717 | self.Letter[44][4].x = 3 * self.Scale
718 | self.Letter[44][4].y = 0 * self.Scale
719 | self.Letter[44][5].x = 3 * self.Scale
720 | self.Letter[44][5].y = 4 * self.Scale
721 | # N
722 | self.Letter[45][self.MAX_POINTS].x = 4
723 | self.Letter[45][0].x = 0 * self.Scale
724 | self.Letter[45][0].y = 4 * self.Scale
725 | self.Letter[45][1].x = 0 * self.Scale
726 | self.Letter[45][1].y = 0 * self.Scale
727 | self.Letter[45][2].x = 3 * self.Scale
728 | self.Letter[45][2].y = 4 * self.Scale
729 | self.Letter[45][3].x = 3 * self.Scale
730 | self.Letter[45][3].y = 0 * self.Scale
731 | # O
732 | self.Letter[46][self.MAX_POINTS].x = 9
733 | self.Letter[46][0].x = 0 * self.Scale
734 | self.Letter[46][0].y = 1 * self.Scale
735 | self.Letter[46][1].x = 0 * self.Scale
736 | self.Letter[46][1].y = 3 * self.Scale
737 | self.Letter[46][2].x = 1 * self.Scale
738 | self.Letter[46][2].y = 4 * self.Scale
739 | self.Letter[46][3].x = 2 * self.Scale
740 | self.Letter[46][3].y = 4 * self.Scale
741 | self.Letter[46][4].x = 3 * self.Scale
742 | self.Letter[46][4].y = 3 * self.Scale
743 | self.Letter[46][5].x = 3 * self.Scale
744 | self.Letter[46][5].y = 1 * self.Scale
745 | self.Letter[46][6].x = 2 * self.Scale
746 | self.Letter[46][6].y = 0 * self.Scale
747 | self.Letter[46][7].x = 1 * self.Scale
748 | self.Letter[46][7].y = 0 * self.Scale
749 | self.Letter[46][8].x = 0 * self.Scale
750 | self.Letter[46][8].y = 1 * self.Scale
751 | # P
752 | self.Letter[47][self.MAX_POINTS].x = 5
753 | self.Letter[47][0].x = 0 * self.Scale
754 | self.Letter[47][0].y = 4 * self.Scale
755 | self.Letter[47][1].x = 0 * self.Scale
756 | self.Letter[47][1].y = 0 * self.Scale
757 | self.Letter[47][2].x = 3 * self.Scale
758 | self.Letter[47][2].y = 0 * self.Scale
759 | self.Letter[47][3].x = 3 * self.Scale
760 | self.Letter[47][3].y = 2 * self.Scale
761 | self.Letter[47][4].x = 0 * self.Scale
762 | self.Letter[47][4].y = 2 * self.Scale
763 | # Q
764 | self.Letter[48][self.MAX_POINTS].x = 6
765 | self.Letter[48][0].x = 2 * self.Scale
766 | self.Letter[48][0].y = 3 * self.Scale
767 | self.Letter[48][1].x = 3 * self.Scale
768 | self.Letter[48][1].y = 4 * self.Scale
769 | self.Letter[48][2].x = 0 * self.Scale
770 | self.Letter[48][2].y = 4 * self.Scale
771 | self.Letter[48][3].x = 0 * self.Scale
772 | self.Letter[48][3].y = 0 * self.Scale
773 | self.Letter[48][4].x = 3 * self.Scale
774 | self.Letter[48][4].y = 0 * self.Scale
775 | self.Letter[48][5].x = 3 * self.Scale
776 | self.Letter[48][5].y = 4 * self.Scale
777 | # R
778 | self.Letter[49][self.MAX_POINTS].x = 6
779 | self.Letter[49][0].x = 0 * self.Scale
780 | self.Letter[49][0].y = 4 * self.Scale
781 | self.Letter[49][1].x = 0 * self.Scale
782 | self.Letter[49][1].y = 0 * self.Scale
783 | self.Letter[49][2].x = 3 * self.Scale
784 | self.Letter[49][2].y = 0 * self.Scale
785 | self.Letter[49][3].x = 3 * self.Scale
786 | self.Letter[49][3].y = 2 * self.Scale
787 | self.Letter[49][4].x = 0 * self.Scale
788 | self.Letter[49][4].y = 2 * self.Scale
789 | self.Letter[49][5].x = 3 * self.Scale
790 | self.Letter[49][5].y = 4 * self.Scale
791 | # S
792 | self.Letter[50][self.MAX_POINTS].x = 8
793 | self.Letter[50][0].x = 3 * self.Scale
794 | self.Letter[50][0].y = 0 * self.Scale
795 | self.Letter[50][1].x = 1 * self.Scale
796 | self.Letter[50][1].y = 0 * self.Scale
797 | self.Letter[50][2].x = 0 * self.Scale
798 | self.Letter[50][2].y = 1 * self.Scale
799 | self.Letter[50][3].x = 1 * self.Scale
800 | self.Letter[50][3].y = 2 * self.Scale
801 | self.Letter[50][4].x = 2 * self.Scale
802 | self.Letter[50][4].y = 2 * self.Scale
803 | self.Letter[50][5].x = 3 * self.Scale
804 | self.Letter[50][5].y = 3 * self.Scale
805 | self.Letter[50][6].x = 2 * self.Scale
806 | self.Letter[50][6].y = 4 * self.Scale
807 | self.Letter[50][7].x = 0 * self.Scale
808 | self.Letter[50][7].y = 4 * self.Scale
809 | # T
810 | self.Letter[51][self.MAX_POINTS].x = 4
811 | self.Letter[51][0].x = 1 * self.Scale
812 | self.Letter[51][0].y = 0 * self.Scale
813 | self.Letter[51][1].x = 3 * self.Scale
814 | self.Letter[51][1].y = 0 * self.Scale
815 | self.Letter[51][2].x = 2 * self.Scale
816 | self.Letter[51][2].y = 0 * self.Scale
817 | self.Letter[51][3].x = 2 * self.Scale
818 | self.Letter[51][3].y = 4 * self.Scale
819 | # U
820 | self.Letter[52][self.MAX_POINTS].x = 6
821 | self.Letter[52][0].x = 0 * self.Scale
822 | self.Letter[52][0].y = 0 * self.Scale
823 | self.Letter[52][1].x = 0 * self.Scale
824 | self.Letter[52][1].y = 3 * self.Scale
825 | self.Letter[52][2].x = 1 * self.Scale
826 | self.Letter[52][2].y = 4 * self.Scale
827 | self.Letter[52][3].x = 2 * self.Scale
828 | self.Letter[52][3].y = 4 * self.Scale
829 | self.Letter[52][4].x = 3 * self.Scale
830 | self.Letter[52][4].y = 3 * self.Scale
831 | self.Letter[52][5].x = 3 * self.Scale
832 | self.Letter[52][5].y = 0 * self.Scale
833 | # V
834 | self.Letter[53][self.MAX_POINTS].x = 4
835 | self.Letter[53][0].x = 0 * self.Scale
836 | self.Letter[53][0].y = 0 * self.Scale
837 | self.Letter[53][1].x = 1 * self.Scale
838 | self.Letter[53][1].y = 4 * self.Scale
839 | self.Letter[53][2].x = 2 * self.Scale
840 | self.Letter[53][2].y = 4 * self.Scale
841 | self.Letter[53][3].x = 3 * self.Scale
842 | self.Letter[53][3].y = 0 * self.Scale
843 | # W
844 | self.Letter[54][self.MAX_POINTS].x = 6
845 | self.Letter[54][0].x = 0 * self.Scale
846 | self.Letter[54][0].y = 0 * self.Scale
847 | self.Letter[54][1].x = 0 * self.Scale
848 | self.Letter[54][1].y = 4 * self.Scale
849 | self.Letter[54][2].x = 1 * self.Scale
850 | self.Letter[54][2].y = 3 * self.Scale
851 | self.Letter[54][3].x = 2 * self.Scale
852 | self.Letter[54][3].y = 3 * self.Scale
853 | self.Letter[54][4].x = 3 * self.Scale
854 | self.Letter[54][4].y = 4 * self.Scale
855 | self.Letter[54][5].x = 3 * self.Scale
856 | self.Letter[54][5].y = 0 * self.Scale
857 | # X
858 | self.Letter[55][self.MAX_POINTS].x = 7
859 | self.Letter[55][0].x = 1 * self.Scale
860 | self.Letter[55][0].y = 0 * self.Scale
861 | self.Letter[55][1].x = 2 * self.Scale
862 | self.Letter[55][1].y = 2 * self.Scale
863 | self.Letter[55][2].x = 3 * self.Scale
864 | self.Letter[55][2].y = 0 * self.Scale
865 | self.Letter[55][3].x = 2 * self.Scale
866 | self.Letter[55][3].y = 2 * self.Scale
867 | self.Letter[55][4].x = 1 * self.Scale
868 | self.Letter[55][4].y = 4 * self.Scale
869 | self.Letter[55][5].x = 2 * self.Scale
870 | self.Letter[55][5].y = 2 * self.Scale
871 | self.Letter[55][6].x = 3 * self.Scale
872 | self.Letter[55][6].y = 4 * self.Scale
873 | # Y
874 | self.Letter[56][self.MAX_POINTS].x = 5
875 | self.Letter[56][0].x = 1 * self.Scale
876 | self.Letter[56][0].y = 0 * self.Scale
877 | self.Letter[56][1].x = 2 * self.Scale
878 | self.Letter[56][1].y = 2 * self.Scale
879 | self.Letter[56][2].x = 3 * self.Scale
880 | self.Letter[56][2].y = 0 * self.Scale
881 | self.Letter[56][3].x = 2 * self.Scale
882 | self.Letter[56][3].y = 2 * self.Scale
883 | self.Letter[56][4].x = 2 * self.Scale
884 | self.Letter[56][4].y = 4 * self.Scale
885 | # Z
886 | self.Letter[57][self.MAX_POINTS].x = 4
887 | self.Letter[57][0].x = 0 * self.Scale
888 | self.Letter[57][0].y = 0 * self.Scale
889 | self.Letter[57][1].x = 3 * self.Scale
890 | self.Letter[57][1].y = 0 * self.Scale
891 | self.Letter[57][2].x = 0 * self.Scale
892 | self.Letter[57][2].y = 4 * self.Scale
893 | self.Letter[57][3].x = 3 * self.Scale
894 | self.Letter[57][3].y = 4 * self.Scale
895 |
896 | for self.Digit in range(self.MAX_TEXT):
897 | if self.Digit >= len(self.TextString):
898 | break
899 | if self.TextString[self.Digit] == '\n':
900 | self.xOffset = self.xOffsetOrig
901 | self.yOffset += 5 * self.Scale + 2
902 | elif self.TextString[self.Digit] >= '!' and self.TextString[self.Digit] <= 'Z':
903 | for self.Count in range(self.Letter[ord(self.TextString[self.Digit]) - ord('!')][self.MAX_POINTS].x):
904 | self.DisplayFrame[self.Digit][self.Count].x = self.Letter[ord(self.TextString[self.Digit]) - ord('!')][self.Count].x + self.xOffset
905 | self.DisplayFrame[self.Digit][self.Count].y = self.Letter[ord(self.TextString[self.Digit]) - ord('!')][self.Count].y + self.yOffset
906 | self.DisplayFrame[self.Digit][self.MAX_POINTS].x = self.Letter[ord(self.TextString[self.Digit]) - ord('!')][self.MAX_POINTS].x
907 | self.xOffset += 4 * self.Scale
908 | else:
909 | self.xOffset += 4 * self.Scale
910 |
911 |
912 |
913 | def SetVisible(self, NewVisible):
914 | if NewVisible != self.LastVisible:
915 | self.Visible = NewVisible
916 | self.LastVisible = self.Visible
917 | self.FlashVisible = self.Visible
918 | self.Active = True
919 | self.FrameCount = self.Frames
920 |
921 |
922 |
923 | def GetVisible(self):
924 | return self.Active
925 |
926 |
--------------------------------------------------------------------------------
/RPiSPi/Asteroids/Text.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/Asteroids/Text.pyc
--------------------------------------------------------------------------------
/RPiSPi/RPiSPi_MCP23S17.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | # RPiSPi_MCP23S17 - Python Example For RPiSPi Driver For MCP23S17 GPIO Expander
4 | # Copyright (C) 2016 Jason Birch
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | #/****************************************************************************/
20 | #/* RPiSPi_MCP23S17 */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* V1.00 - 2016-11-02 - Jason Birch */
23 | #/* ------------------------------------------------------------------------ */
24 | #/* Python Example For RPiSPi Driver Using MCP23S17 GPIO Expander. */
25 | #/****************************************************************************/
26 |
27 |
28 | import sys
29 | import time
30 | import datetime
31 | import curses
32 | import struct
33 |
34 | MCP23S17_INIT_0 = "/dev/RPiSPi_00011_000_3_0_MCP23S17_INIT"
35 | MCP23S17_WRITE_0 = "/dev/RPiSPi_00011_000_3_1_MCP23S17_WRITE"
36 | MCP23S17_READ_0 = "/dev/RPiSPi_00011_000_3_2_MCP23S17_READ"
37 | MCP23S17_IODIR_0 = "/dev/RPiSPi_00011_000_3_3_MCP23S17_IODIR"
38 | MCP23S17_IPOL_0 = "/dev/RPiSPi_00011_000_3_4_MCP23S17_IPOL"
39 | MCP23S17_GPINTEN_0 = "/dev/RPiSPi_00011_000_3_5_MCP23S17_GPINTEN"
40 | MCP23S17_DEFVAL_0 = "/dev/RPiSPi_00011_000_3_6_MCP23S17_DEFVAL"
41 | MCP23S17_INTCON_0 = "/dev/RPiSPi_00011_000_3_7_MCP23S17_INTCON"
42 | MCP23S17_GPPU_0 = "/dev/RPiSPi_00011_000_3_8_MCP23S17_GPPU"
43 |
44 | MCP23S17_INIT_1 = "/dev/RPiSPi_00011_001_4_0_MCP23S17_INIT"
45 | MCP23S17_READ_1 = "/dev/RPiSPi_00011_001_4_2_MCP23S17_READ"
46 | MCP23S17_IODIR_1 = "/dev/RPiSPi_00011_001_4_3_MCP23S17_IODIR"
47 | MCP23S17_IPOL_1 = "/dev/RPiSPi_00011_001_4_4_MCP23S17_IPOL"
48 | MCP23S17_GPINTEN_1 = "/dev/RPiSPi_00011_001_4_5_MCP23S17_GPINTEN"
49 | MCP23S17_DEFVAL_1 = "/dev/RPiSPi_00011_001_4_6_MCP23S17_DEFVAL"
50 | MCP23S17_INTCON_1 = "/dev/RPiSPi_00011_001_4_7_MCP23S17_INTCON"
51 | MCP23S17_GPPU_1 = "/dev/RPiSPi_00011_001_4_8_MCP23S17_GPPU"
52 |
53 |
54 |
55 | SPI_DEV_CMD_MCP23S17_INIT = 0
56 | SPI_DEV_CMD_MCP23S17_WRITE = 1
57 | SPI_DEV_CMD_MCP23S17_READ = 2
58 | # IODIR - I/O DIRECTION REGISTER - 0=OUTPUT, 1=INPUT
59 | SPI_DEV_CMD_MCP23S17_IODIR = 3
60 | # IPOL - INPUT POLARITY PORT REGISTER
61 | SPI_DEV_CMD_MCP23S17_IPOL = 4
62 | # GPINTEN - INTERRUPT-ON-CHANGE PINS
63 | SPI_DEV_CMD_MCP23S17_GPINTEN = 5
64 | # DEFVAL - DEFAULT VALUE REGISTER
65 | SPI_DEV_CMD_MCP23S17_DEFVAL = 6
66 | # INTCON - INTERRUPT-ON-CHANGE CONTROL REGISTER
67 | SPI_DEV_CMD_MCP23S17_INTCON = 7
68 | # GPPU - GPIO PULL-UP RESISTOR REGISTER
69 | SPI_DEV_CMD_MCP23S17_GPPU = 8
70 | # INTF - INTERRUPT FLAG REGISTER
71 | SPI_DEV_CMD_MCP23S17_INTF = 9
72 | # INTCAP - INTERRUPT CAPTURED VALUE FOR PORT REGISTER
73 | SPI_DEV_CMD_MCP23S17_INTCAP = 10
74 |
75 |
76 |
77 | def ReadGPIO(DevFile):
78 | File = open(DevFile, 'rb', 0)
79 | Data = File.read(4)
80 | File.close()
81 | return struct.unpack("<%dI" % (len(Data) // 4), Data)[0]
82 |
83 |
84 | def WriteGPIO(DevFile, *Args):
85 | Message = ""
86 | for Count in range(len(Args)):
87 | if isinstance(Args[Count], str):
88 | Message += Args[Count]
89 | else:
90 | Message += struct.pack('I', Args[Count])
91 | File = open(DevFile, 'wb', 0)
92 | File.write(Message)
93 | File.close()
94 |
95 |
96 |
97 | # /*********************************************************/
98 | # /* Configure the console so key presses can be captured. */
99 | #/*********************************************************/
100 | curses.initscr()
101 | curses.noecho()
102 | window = curses.newwin(80, 25)
103 | window.nodelay(1)
104 | window.timeout(0)
105 |
106 | WriteGPIO(MCP23S17_INIT_0, SPI_DEV_CMD_MCP23S17_INIT)
107 | WriteGPIO(MCP23S17_IODIR_0, 0xFF00)
108 | WriteGPIO(MCP23S17_IPOL_0, 0xFF00)
109 | WriteGPIO(MCP23S17_GPINTEN_0, 0x0000)
110 | WriteGPIO(MCP23S17_DEFVAL_0, 0x0000)
111 | WriteGPIO(MCP23S17_INTCON_0, 0x0000)
112 | WriteGPIO(MCP23S17_GPPU_0, 0xFF00)
113 |
114 | WriteGPIO(MCP23S17_INIT_1, SPI_DEV_CMD_MCP23S17_INIT)
115 | WriteGPIO(MCP23S17_IODIR_1, 0xFFFF)
116 | WriteGPIO(MCP23S17_IPOL_1, 0x0000)
117 | WriteGPIO(MCP23S17_GPINTEN_1, 0x0000)
118 | WriteGPIO(MCP23S17_DEFVAL_1, 0x0000)
119 | WriteGPIO(MCP23S17_INTCON_1, 0x0000)
120 | WriteGPIO(MCP23S17_GPPU_1, 0xF00F)
121 |
122 | OutValue = 0;
123 | ExitFlag = False
124 | while ExitFlag == False:
125 | # /**********************************************/
126 | # /* Process main application loop every 200ms. */
127 | #/**********************************************/
128 | curses.napms(200)
129 |
130 | # /*************************/
131 | # /* Get a user key press. */
132 | #/*************************/
133 | ThisKey = window.getch()
134 |
135 | # /****************************************************/
136 | # /* If a key has been pressed, exit the application. */
137 | #/****************************************************/
138 | if ThisKey > -1:
139 | ExitFlag = True
140 |
141 | OutValue /= 2
142 | if OutValue == 0:
143 | OutValue = 0x80;
144 |
145 | WriteGPIO(MCP23S17_WRITE_0, (~OutValue) & 0xFF)
146 |
147 | Now = datetime.datetime.now()
148 | Value0 = ReadGPIO(MCP23S17_READ_0)
149 | Value1 = ReadGPIO(MCP23S17_READ_1)
150 | print(Now.strftime("%Y-%m-%d %H:%M:%S") + " GPIO0: " + format(Value0, '016b') + " - GPIO1: " + format(Value1, '016b') + "\r")
151 |
152 |
153 |
154 | # /*********************/
155 | # /* Exit application. */
156 | #/*********************/
157 | curses.endwin()
158 |
159 |
--------------------------------------------------------------------------------
/RPiSPi/RPiSPi_MCP3002.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | # RPiSPi_MCP3002 - Python Example For RPiSPi Driver Using MCP3002 A-D Converter
4 | # Copyright (C) 2016 Jason Birch
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | #/****************************************************************************/
20 | #/* RPiSPi_MCP3002 */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* V1.00 - 2016-11-02 - Jason Birch */
23 | #/* ------------------------------------------------------------------------ */
24 | #/* Python Example For RPiSPi Driver Using MCP3002 A-D Converter. */
25 | #/****************************************************************************/
26 |
27 |
28 | import sys
29 | import time
30 | import datetime
31 | import curses
32 | import struct
33 |
34 |
35 | MCP3002_READ0 = "/dev/RPiSPi_00000_000_0_2_MCP3002_READ0"
36 | MCP3002_READ1 = "/dev/RPiSPi_00000_000_0_3_MCP3002_READ1"
37 |
38 |
39 |
40 | def ReadAD(DevFile):
41 | File = open(DevFile, 'rb', 0)
42 | Data = File.read(4)
43 | File.close()
44 | return struct.unpack("<%dI" % (len(Data) // 4), Data)[0]
45 |
46 |
47 |
48 | # /*********************************************************/
49 | # /* Configure the console so key presses can be captured. */
50 | #/*********************************************************/
51 | curses.initscr()
52 | curses.noecho()
53 | window = curses.newwin(80, 25)
54 | window.nodelay(1)
55 | window.timeout(0)
56 |
57 |
58 | ExitFlag = False
59 | while ExitFlag == False:
60 | # /**********************************************/
61 | # /* Process main application loop every 200ms. */
62 | #/**********************************************/
63 | curses.napms(200)
64 |
65 | # /*************************/
66 | # /* Get a user key press. */
67 | #/*************************/
68 | ThisKey = window.getch()
69 |
70 | # /****************************************************/
71 | # /* If a key has been pressed, exit the application. */
72 | #/****************************************************/
73 | if ThisKey > -1:
74 | ExitFlag = True
75 |
76 | Value0 = ReadAD(MCP3002_READ0)
77 | Value1 = ReadAD(MCP3002_READ1)
78 |
79 | Now = datetime.datetime.now()
80 | print(Now.strftime("%Y-%m-%d %H:%M:%S") + " A-D_[0]=" + str(Value0) + " A-D_[1]=" + str(Value1) + "\r")
81 |
82 |
83 | # /*********************/
84 | # /* Exit application. */
85 | #/*********************/
86 | curses.endwin()
87 |
88 |
--------------------------------------------------------------------------------
/RPiSPi/RPiSPi_MCP3004.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | # RPiSPi_MCP3004 - Python Example For RPiSPi Driver Using MCP3004 A-D Converter
4 | # Copyright (C) 2016 Jason Birch
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | #/****************************************************************************/
20 | #/* RPiSPi_MCP3004 */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* V1.00 - 2016-11-02 - Jason Birch */
23 | #/* ------------------------------------------------------------------------ */
24 | #/* Python Example For RPiSPi Driver Using MCP3004 A-D Converter. */
25 | #/****************************************************************************/
26 |
27 |
28 | import sys
29 | import time
30 | import datetime
31 | import curses
32 | import struct
33 |
34 |
35 | MCP3004_READ0 = "/dev/RPiSPi_00000_000_0_2_MCP3004_READ0"
36 | MCP3004_READ1 = "/dev/RPiSPi_00000_000_0_3_MCP3004_READ1"
37 | MCP3004_READ2 = "/dev/RPiSPi_00000_000_0_4_MCP3004_READ2"
38 | MCP3004_READ3 = "/dev/RPiSPi_00000_000_0_5_MCP3004_READ3"
39 |
40 |
41 |
42 | def ReadAD(DevFile):
43 | File = open(DevFile, 'rb', 0)
44 | Data = File.read(4)
45 | File.close()
46 | return struct.unpack("<%dI" % (len(Data) // 4), Data)[0]
47 |
48 |
49 |
50 | # /*********************************************************/
51 | # /* Configure the console so key presses can be captured. */
52 | #/*********************************************************/
53 | curses.initscr()
54 | curses.noecho()
55 | window = curses.newwin(80, 25)
56 | window.nodelay(1)
57 | window.timeout(0)
58 |
59 |
60 | ExitFlag = False
61 | while ExitFlag == False:
62 | # /**********************************************/
63 | # /* Process main application loop every 200ms. */
64 | #/**********************************************/
65 | curses.napms(200)
66 |
67 | # /*************************/
68 | # /* Get a user key press. */
69 | #/*************************/
70 | ThisKey = window.getch()
71 |
72 | # /****************************************************/
73 | # /* If a key has been pressed, exit the application. */
74 | #/****************************************************/
75 | if ThisKey > -1:
76 | ExitFlag = True
77 |
78 | Value0 = ReadAD(MCP3004_READ0)
79 | Value1 = ReadAD(MCP3004_READ1)
80 | Value2 = ReadAD(MCP3004_READ2)
81 | Value3 = ReadAD(MCP3004_READ3)
82 |
83 | Now = datetime.datetime.now()
84 | print(Now.strftime("%Y-%m-%d %H:%M:%S") + " A-D_[0]=" + str(Value0) + " A-D_[1]=" + str(Value1) + " A-D_[2]=" + str(Value2) + " A-D_[3]=" + str(Value3) + "\r")
85 |
86 |
87 | # /*********************/
88 | # /* Exit application. */
89 | #/*********************/
90 | curses.endwin()
91 |
92 |
--------------------------------------------------------------------------------
/RPiSPi/RPiSPi_MCP3008.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | # RPiSPi_MCP3008 - Python Example For RPiSPi Driver Using MCP3008 A-D Converter
4 | # Copyright (C) 2016 Jason Birch
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | #/****************************************************************************/
20 | #/* RPiSPi_MCP3008 */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* V1.00 - 2016-11-02 - Jason Birch */
23 | #/* ------------------------------------------------------------------------ */
24 | #/* Python Example For RPiSPi Driver Using MCP3008 A-D Converter. */
25 | #/****************************************************************************/
26 |
27 |
28 | import sys
29 | import time
30 | import datetime
31 | import curses
32 | import struct
33 |
34 |
35 | MCP3008_READ0 = "/dev/RPiSPi_00000_000_0_2_MCP3008_READ0"
36 | MCP3008_READ1 = "/dev/RPiSPi_00000_000_0_3_MCP3008_READ1"
37 | MCP3008_READ2 = "/dev/RPiSPi_00000_000_0_4_MCP3008_READ2"
38 | MCP3008_READ3 = "/dev/RPiSPi_00000_000_0_5_MCP3008_READ3"
39 | MCP3008_READ4 = "/dev/RPiSPi_00000_000_0_6_MCP3008_READ4"
40 | MCP3008_READ5 = "/dev/RPiSPi_00000_000_0_7_MCP3008_READ5"
41 | MCP3008_READ6 = "/dev/RPiSPi_00000_000_0_8_MCP3008_READ6"
42 | MCP3008_READ7 = "/dev/RPiSPi_00000_000_0_9_MCP3008_READ7"
43 |
44 |
45 |
46 | def ReadAD(DevFile):
47 | File = open(DevFile, 'rb', 0)
48 | Data = File.read(4)
49 | File.close()
50 | return struct.unpack("<%dI" % (len(Data) // 4), Data)[0]
51 |
52 |
53 |
54 | # /*********************************************************/
55 | # /* Configure the console so key presses can be captured. */
56 | #/*********************************************************/
57 | curses.initscr()
58 | curses.noecho()
59 | window = curses.newwin(80, 25)
60 | window.nodelay(1)
61 | window.timeout(0)
62 |
63 |
64 | ExitFlag = False
65 | while ExitFlag == False:
66 | # /**********************************************/
67 | # /* Process main application loop every 200ms. */
68 | #/**********************************************/
69 | curses.napms(200)
70 |
71 | # /*************************/
72 | # /* Get a user key press. */
73 | #/*************************/
74 | ThisKey = window.getch()
75 |
76 | # /****************************************************/
77 | # /* If a key has been pressed, exit the application. */
78 | #/****************************************************/
79 | if ThisKey > -1:
80 | ExitFlag = True
81 |
82 | Value0 = ReadAD(MCP3008_READ0)
83 | Value1 = ReadAD(MCP3008_READ1)
84 | Value2 = ReadAD(MCP3008_READ2)
85 | Value3 = ReadAD(MCP3008_READ3)
86 | Value4 = ReadAD(MCP3008_READ4)
87 | Value5 = ReadAD(MCP3008_READ5)
88 | Value6 = ReadAD(MCP3008_READ6)
89 | Value7 = ReadAD(MCP3008_READ7)
90 |
91 | Now = datetime.datetime.now()
92 | print(Now.strftime("%Y-%m-%d %H:%M:%S") + " A-D_[0]=" + str(Value0) + " A-D_[1]=" + str(Value1) + " A-D_[2]=" + str(Value2) + " A-D_[3]=" + str(Value3) + "\r")
93 | print(Now.strftime("%Y-%m-%d %H:%M:%S") + " A-D_[4]=" + str(Value4) + " A-D_[5]=" + str(Value5) + " A-D_[6]=" + str(Value6) + " A-D_[7]=" + str(Value7) + "\r")
94 |
95 |
96 |
97 | # /*********************/
98 | # /* Exit application. */
99 | #/*********************/
100 | curses.endwin()
101 |
102 |
--------------------------------------------------------------------------------
/RPiSPi/RPiSPi_RAW.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | # RPiSPi_RAW - Python Example For RPiSPi Driver Using RAW SPI Device Mode
4 | # Copyright (C) 2016 Jason Birch
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | #/****************************************************************************/
20 | #/* RPiSPi_RAW */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* V1.00 - 2016-11-02 - Jason Birch */
23 | #/* ------------------------------------------------------------------------ */
24 | #/* Python Example For RPiSPi Driver Using RAW SPI Device Mode to */
25 | #/* communicate with an MCP3008 A-D Converter. */
26 | #/****************************************************************************/
27 |
28 |
29 | import sys
30 | import time
31 | import datetime
32 | import curses
33 | import struct
34 |
35 |
36 | SPI_RAW_REG_RAW = "/dev/RPiSPi_00001_000_1_0_SPI_RAW_REG_RAW"
37 |
38 |
39 |
40 | def ReadRAW(DevFile):
41 | File = open(DevFile, 'rb', 0)
42 | Data = File.read(256 * 4)
43 | File.close()
44 | return list(struct.unpack("<%dI" % (len(Data) // 4), Data))
45 |
46 |
47 | def WriteRAW(DevFile, *Args):
48 | Message = ""
49 | for Count in range(len(Args)):
50 | if isinstance(Args[Count], str):
51 | Message += Args[Count]
52 | else:
53 | Message += struct.pack('I', Args[Count])
54 | File = open(DevFile, 'wb', 0)
55 | File.write(Message)
56 | File.close()
57 |
58 |
59 |
60 | # /*********************************************************/
61 | # /* Configure the console so key presses can be captured. */
62 | #/*********************************************************/
63 | curses.initscr()
64 | curses.noecho()
65 | window = curses.newwin(80, 25)
66 | window.nodelay(1)
67 | window.timeout(0)
68 |
69 |
70 | ExitFlag = False
71 | while ExitFlag == False:
72 | # /**********************************************/
73 | # /* Process main application loop every 200ms. */
74 | #/**********************************************/
75 | curses.napms(200)
76 |
77 | # /*************************/
78 | # /* Get a user key press. */
79 | #/*************************/
80 | ThisKey = window.getch()
81 |
82 | # /****************************************************/
83 | # /* If a key has been pressed, exit the application. */
84 | #/****************************************************/
85 | if ThisKey > -1:
86 | ExitFlag = True
87 |
88 | WriteRAW(SPI_RAW_REG_RAW, 0x01, 0x80, 0x00)
89 | Values = ReadRAW(SPI_RAW_REG_RAW)
90 | Value0 = 256 * (Values[1] & 0x03) + Values[2]
91 |
92 | WriteRAW(SPI_RAW_REG_RAW, 0x01, 0x90, 0x00)
93 | Values = ReadRAW(SPI_RAW_REG_RAW)
94 | Value1 = 256 * (Values[1] & 0x03) + Values[2]
95 |
96 | WriteRAW(SPI_RAW_REG_RAW, 0x01, 0xA0, 0x00)
97 | Values = ReadRAW(SPI_RAW_REG_RAW)
98 | Value2 = 256 * (Values[1] & 0x03) + Values[2]
99 |
100 | WriteRAW(SPI_RAW_REG_RAW, 0x01, 0xB0, 0x00)
101 | Values = ReadRAW(SPI_RAW_REG_RAW)
102 | Value3 = 256 * (Values[1] & 0x03) + Values[2]
103 |
104 | WriteRAW(SPI_RAW_REG_RAW, 0x01, 0xC0, 0x00)
105 | Values = ReadRAW(SPI_RAW_REG_RAW)
106 | Value4 = 256 * (Values[1] & 0x03) + Values[2]
107 |
108 | WriteRAW(SPI_RAW_REG_RAW, 0x01, 0xD0, 0x00)
109 | Values = ReadRAW(SPI_RAW_REG_RAW)
110 | Value5 = 256 * (Values[1] & 0x03) + Values[2]
111 |
112 | WriteRAW(SPI_RAW_REG_RAW, 0x01, 0xE0, 0x00)
113 | Values = ReadRAW(SPI_RAW_REG_RAW)
114 | Value6 = 256 * (Values[1] & 0x03) + Values[2]
115 |
116 | WriteRAW(SPI_RAW_REG_RAW, 0x01, 0xF0, 0x00)
117 | Values = ReadRAW(SPI_RAW_REG_RAW)
118 | Value7 = 256 * (Values[1] & 0x03) + Values[2]
119 |
120 | Now = datetime.datetime.now()
121 | print(Now.strftime("%Y-%m-%d %H:%M:%S") + " A-D_[0]=" + str(Value0) + " A-D_[1]=" + str(Value1) + " A-D_[2]=" + str(Value2) + " A-D_[3]=" + str(Value3) + "\r")
122 | print(Now.strftime("%Y-%m-%d %H:%M:%S") + " A-D_[4]=" + str(Value4) + " A-D_[5]=" + str(Value5) + " A-D_[6]=" + str(Value6) + " A-D_[7]=" + str(Value7) + "\r")
123 |
124 |
125 |
126 | # /*********************/
127 | # /* Exit application. */
128 | #/*********************/
129 | curses.endwin()
130 |
131 |
--------------------------------------------------------------------------------
/RPiSPi/RPiSPi_SSD1306.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | # RPiSPi_SSD1306 - Python Example For RPiSPi Driver Using SSD1306 Display
4 | # Copyright (C) 2016 Jason Birch
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | #/****************************************************************************/
20 | #/* RPiSPi_SSD1306 */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* V1.00 - 2016-11-02 - Jason Birch */
23 | #/* ------------------------------------------------------------------------ */
24 | #/* Python Example For RPiSPi Driver Using SSD1306 Display. */
25 | #/****************************************************************************/
26 |
27 |
28 | import time
29 | import datetime
30 | import curses
31 | import struct
32 |
33 |
34 | SSD1306_INIT = "/dev/RPiSPi_10001_000_6_0_SSD1306_INIT"
35 | SSD1306_WRITE = "/dev/RPiSPi_10001_000_6_1_SSD1306_WRITE"
36 |
37 | SPI_DEV_CMD_SSD1306_INIT = 0
38 | SPI_DEV_CMD_SSD1306_WRITE = 1
39 | SPI_DEV_CMD_SSD1306_CURSOR_POS = 2
40 | SPI_DEV_CMD_SSD1306_ON = 3
41 | SPI_DEV_CMD_SSD1306_OFF = 4
42 | SPI_DEV_CMD_SSD1306_INVERSE = 5
43 | SPI_DEV_CMD_SSD1306_NON_INVERSE = 6
44 | SPI_DEV_CMD_SSD1306_CONTRAST = 7
45 | SPI_DEV_PRC_SSD1306_CLS = 8
46 | SPI_DEV_PRC_SSD1306_FILL_RANDOM = 9
47 | SPI_DEV_PRC_SSD1306_PRINT = 10
48 | SPI_DEV_PRC_SSD1306_PLOT = 11
49 | SPI_DEV_PRC_SSD1306_LINE = 12
50 | SPI_DEV_PRC_SSD1306_BOX = 13
51 | SPI_DEV_PRC_SSD1306_BOX_FILL = 14
52 | SPI_DEV_PRC_SSD1306_CIRCLE = 15
53 | SPI_DEV_PRC_SSD1306_CIRCLE_FILL = 16
54 | SPI_DEV_PRC_SSD1306_UPDATE = 17
55 |
56 |
57 |
58 | def DoDisplay(*Args):
59 | Message = ""
60 | for Count in range(len(Args)):
61 | if isinstance(Args[Count], str):
62 | Message += Args[Count]
63 | else:
64 | Message += struct.pack('I', Args[Count])
65 | File.write(Message)
66 |
67 |
68 | def WriteGPIO(DevFile, *Args):
69 | Message = ""
70 | for Count in range(len(Args)):
71 | if isinstance(Args[Count], str):
72 | Message += Args[Count]
73 | else:
74 | Message += struct.pack('I', Args[Count])
75 | File = open(DevFile, 'wb', 0)
76 | File.write(Message)
77 | File.close()
78 |
79 |
80 |
81 | # /*********************************************************/
82 | # /* Configure the console so key presses can be captured. */
83 | #/*********************************************************/
84 | curses.initscr()
85 | curses.noecho()
86 | window = curses.newwin(80, 25)
87 | window.nodelay(1)
88 | window.timeout(0)
89 |
90 | WriteGPIO(SSD1306_INIT, SPI_DEV_CMD_SSD1306_INIT)
91 | File = open(SSD1306_WRITE, 'wb', 0)
92 |
93 | DoDisplay(SPI_DEV_CMD_SSD1306_ON)
94 | DoDisplay(SPI_DEV_CMD_SSD1306_CONTRAST, 127)
95 | DoDisplay(SPI_DEV_PRC_SSD1306_FILL_RANDOM)
96 | time.sleep(1)
97 | DoDisplay(SPI_DEV_CMD_SSD1306_INVERSE)
98 | time.sleep(1)
99 | DoDisplay(SPI_DEV_CMD_SSD1306_NON_INVERSE)
100 | DoDisplay(SPI_DEV_PRC_SSD1306_CLS)
101 |
102 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, 0, 20, 1, 1, "Size 1")
103 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, 0, 47, 3, 3, "Size 3")
104 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, 0, 30, 2, 2, "Size 2")
105 |
106 | DoDisplay(SPI_DEV_PRC_SSD1306_LINE, 12, 15, 30, 24, 1)
107 | DoDisplay(SPI_DEV_PRC_SSD1306_LINE, 30, 24, 12, 35, 1)
108 | DoDisplay(SPI_DEV_PRC_SSD1306_LINE, 12, 35, 5, 24, 1)
109 | DoDisplay(SPI_DEV_PRC_SSD1306_LINE, 5, 24, 12, 15, 1)
110 |
111 | DoDisplay(SPI_DEV_PRC_SSD1306_PLOT, 42, 22, 1)
112 | DoDisplay(SPI_DEV_PRC_SSD1306_BOX, 60, 20, 80, 40, 1)
113 | DoDisplay(SPI_DEV_PRC_SSD1306_BOX_FILL, 65, 25, 75, 35, 1)
114 | DoDisplay(SPI_DEV_PRC_SSD1306_CIRCLE, 105, 25, 15, 1)
115 | DoDisplay(SPI_DEV_PRC_SSD1306_CIRCLE_FILL, 105, 25, 10, 1)
116 |
117 | ExitFlag = False
118 | while ExitFlag == False:
119 | # /**********************************************/
120 | # /* Process main application loop every 200ms. */
121 | #/**********************************************/
122 | curses.napms(200)
123 |
124 | # /*************************/
125 | # /* Get a user key press. */
126 | #/*************************/
127 | ThisKey = window.getch()
128 |
129 | # /****************************************************/
130 | # /* If a key has been pressed, exit the application. */
131 | #/****************************************************/
132 | if ThisKey > -1:
133 | ExitFlag = True
134 |
135 | Now = datetime.datetime.now()
136 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, 8, 5, 1, 1, Now.strftime("%Y-%m-%d %H:%M:%S"))
137 |
138 | DoDisplay(SPI_DEV_PRC_SSD1306_UPDATE)
139 |
140 |
141 | DoDisplay(SPI_DEV_CMD_SSD1306_OFF)
142 |
143 | File.close()
144 |
145 | # /*********************/
146 | # /* Exit application. */
147 | #/*********************/
148 | curses.endwin()
149 |
150 |
--------------------------------------------------------------------------------
/RPiSPi/RPiSPi_SSD1306_AnalogClock.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | # RPiSPi_SSD1306_AnalogClock - Python Example For RPiSPi Driver Using SSD1306
4 | # Copyright (C) 2016 Jason Birch
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | #/****************************************************************************/
20 | #/* RPiSPi_SSD1306_AnalogClock */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* V1.00 - 2016-12-20 - Jason Birch */
23 | #/* ------------------------------------------------------------------------ */
24 | #/* Python Example For RPiSPi Driver Using SSD1306 Display. */
25 | #/****************************************************************************/
26 |
27 |
28 | import time
29 | import math
30 | import datetime
31 | import curses
32 | import struct
33 |
34 |
35 | SSD1306_INIT = "/dev/RPiSPi_10010_000_7_0_SSD1306_INIT"
36 | SSD1306_WRITE = "/dev/RPiSPi_10010_000_7_1_SSD1306_WRITE"
37 |
38 | SPI_DEV_CMD_SSD1306_INIT = 0
39 | SPI_DEV_CMD_SSD1306_WRITE = 1
40 | SPI_DEV_CMD_SSD1306_CURSOR_POS = 2
41 | SPI_DEV_CMD_SSD1306_ON = 3
42 | SPI_DEV_CMD_SSD1306_OFF = 4
43 | SPI_DEV_CMD_SSD1306_INVERSE = 5
44 | SPI_DEV_CMD_SSD1306_NON_INVERSE = 6
45 | SPI_DEV_CMD_SSD1306_CONTRAST = 7
46 | SPI_DEV_PRC_SSD1306_CLS = 8
47 | SPI_DEV_PRC_SSD1306_FILL_RANDOM = 9
48 | SPI_DEV_PRC_SSD1306_PRINT = 10
49 | SPI_DEV_PRC_SSD1306_PLOT = 11
50 | SPI_DEV_PRC_SSD1306_LINE = 12
51 | SPI_DEV_PRC_SSD1306_BOX = 13
52 | SPI_DEV_PRC_SSD1306_BOX_FILL = 14
53 | SPI_DEV_PRC_SSD1306_CIRCLE = 15
54 | SPI_DEV_PRC_SSD1306_CIRCLE_FILL = 16
55 | SPI_DEV_PRC_SSD1306_UPDATE = 17
56 |
57 |
58 |
59 | def DoDisplay(*Args):
60 | Message = ""
61 | for Count in range(len(Args)):
62 | if isinstance(Args[Count], str):
63 | Message += Args[Count]
64 | else:
65 | Message += struct.pack('I', Args[Count])
66 | File.write(Message)
67 |
68 |
69 | def WriteGPIO(DevFile, *Args):
70 | Message = ""
71 | for Count in range(len(Args)):
72 | if isinstance(Args[Count], str):
73 | Message += Args[Count]
74 | else:
75 | Message += struct.pack('I', Args[Count])
76 | File = open(DevFile, 'wb', 0)
77 | File.write(Message)
78 | File.close()
79 |
80 |
81 |
82 | # /*********************************************************/
83 | # /* Configure the console so key presses can be captured. */
84 | #/*********************************************************/
85 | curses.initscr()
86 | curses.noecho()
87 | window = curses.newwin(80, 25)
88 | window.nodelay(1)
89 | window.timeout(0)
90 |
91 | WriteGPIO(SSD1306_INIT, SPI_DEV_CMD_SSD1306_INIT)
92 | File = open(SSD1306_WRITE, 'wb', 0)
93 |
94 | DoDisplay(SPI_DEV_CMD_SSD1306_ON)
95 | DoDisplay(SPI_DEV_CMD_SSD1306_CONTRAST, 127)
96 | DoDisplay(SPI_DEV_PRC_SSD1306_CLS)
97 |
98 | LastHour = 0
99 | LastMinute = 0
100 | LastSecond = 0
101 | LastMicrosecond = 0
102 | ExitFlag = False
103 | while ExitFlag == False:
104 | # /**********************************************/
105 | # /* Process main application loop every 200ms. */
106 | #/**********************************************/
107 | curses.napms(200)
108 |
109 | # /*************************/
110 | # /* Get a user key press. */
111 | #/*************************/
112 | ThisKey = window.getch()
113 |
114 | # /****************************************************/
115 | # /* If a key has been pressed, exit the application. */
116 | #/****************************************************/
117 | if ThisKey > -1:
118 | ExitFlag = True
119 |
120 | # /******************************/
121 | # /* Get current time and date. */
122 | #/******************************/
123 | Now = datetime.datetime.now()
124 |
125 | # /********************/
126 | # /* Erase last time. */
127 | #/********************/
128 | DoDisplay(SPI_DEV_PRC_SSD1306_LINE, 32, 32, 32 + math.cos((2 * 3.142 * (LastHour + LastMinute / 60.0) / 12) - 3.142 / 2) * 18, 32 + math.sin((2 * 3.142 * (LastHour + LastMinute / 60.0) / 12) - 3.142 / 2) * 18, 0)
129 | DoDisplay(SPI_DEV_PRC_SSD1306_LINE, 32, 32, 32 + math.cos((2 * 3.142 * (LastMinute + LastSecond / 60.0) / 60) - 3.142 / 2) * 27, 32 + math.sin((2 * 3.142 * (LastMinute + LastSecond / 60.0) / 60) - 3.142 / 2) * 27, 0)
130 | DoDisplay(SPI_DEV_PRC_SSD1306_LINE, 32, 32, 32 + math.cos((2 * 3.142 * (LastSecond + LastMicrosecond / 1000000.0) / 60) - 3.142 / 2) * 30, 32 + math.sin((2 * 3.142 * (LastSecond + LastMicrosecond / 1000000.0) / 60) - 3.142 / 2) * 30, 0)
131 |
132 | # /**************************/
133 | # /* Remember current time. */
134 | #/**************************/
135 | LastHour = Now.hour
136 | LastMinute = Now.minute
137 | LastSecond = Now.second
138 | LastMicrosecond = Now.microsecond
139 |
140 | # /*************************/
141 | # /* Display current time. */
142 | #/*************************/
143 | DoDisplay(SPI_DEV_PRC_SSD1306_LINE, 32, 32, 32 + math.cos((2 * 3.142 * (LastHour + LastMinute / 60.0) / 12) - 3.142 / 2) * 18, 32 + math.sin((2 * 3.142 * (LastHour + LastMinute / 60.0) / 12) - 3.142 / 2) * 18, 1)
144 | DoDisplay(SPI_DEV_PRC_SSD1306_LINE, 32, 32, 32 + math.cos((2 * 3.142 * (LastMinute + LastSecond / 60.0) / 60) - 3.142 / 2) * 27, 32 + math.sin((2 * 3.142 * (LastMinute + LastSecond / 60.0) / 60) - 3.142 / 2) * 27, 1)
145 | DoDisplay(SPI_DEV_PRC_SSD1306_LINE, 32, 32, 32 + math.cos((2 * 3.142 * (LastSecond + LastMicrosecond / 1000000.0) / 60) - 3.142 / 2) * 30, 32 + math.sin((2 * 3.142 * (LastSecond + LastMicrosecond / 1000000.0) / 60) - 3.142 / 2) * 30, 1)
146 |
147 | # /*****************/
148 | # /* Display date. */
149 | #/*****************/
150 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, 81, 6, 2, 1, Now.strftime("%a").upper())
151 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, 87, 20, 2, 1, Now.strftime("%d"))
152 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, 81, 35, 2, 1, Now.strftime("%b").upper())
153 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, 76, 50, 2, 1, Now.strftime("%Y"))
154 |
155 | # /********************/
156 | # /* Display borders. */
157 | #/********************/
158 | for Count in range(0, 60, 5):
159 | DoDisplay(SPI_DEV_PRC_SSD1306_CIRCLE, 32 + math.cos(2 * 3.142 * Count / 60) * 25, 32 + math.sin(2 * 3.142 * Count / 60) * 25, 2, 1)
160 |
161 | DoDisplay(SPI_DEV_PRC_SSD1306_CIRCLE, 32, 32, 31, 1)
162 | DoDisplay(SPI_DEV_PRC_SSD1306_BOX, 70, 0, 127, 63, 1)
163 |
164 | # /*******************/
165 | # /* Update display. */
166 | #/*******************/
167 | DoDisplay(SPI_DEV_PRC_SSD1306_UPDATE)
168 |
169 |
170 | DoDisplay(SPI_DEV_CMD_SSD1306_OFF)
171 |
172 | File.close()
173 |
174 | # /*********************/
175 | # /* Exit application. */
176 | #/*********************/
177 | curses.endwin()
178 |
179 |
--------------------------------------------------------------------------------
/RPiSPi/RPiSPi_SSD1306_DateTime.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | # RPiSPi_SSD1306 - Python Example For RPiSPi Driver Using SSD1306 Display
4 | # Copyright (C) 2016 Jason Birch
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | #/****************************************************************************/
20 | #/* RPiSPi_SSD1306 */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* V1.00 - 2016-11-02 - Jason Birch */
23 | #/* ------------------------------------------------------------------------ */
24 | #/* Python Example For RPiSPi Driver Using SSD1306 Display. */
25 | #/****************************************************************************/
26 |
27 |
28 | import time
29 | import datetime
30 | import socket
31 | import curses
32 | import struct
33 |
34 |
35 | SSD1306_INIT = "/dev/RPiSPi_00010_000_2_0_SSD1306_INIT"
36 | SSD1306_WRITE = "/dev/RPiSPi_00010_000_2_1_SSD1306_WRITE"
37 |
38 | SPI_DEV_CMD_SSD1306_INIT = 0
39 | SPI_DEV_CMD_SSD1306_WRITE = 1
40 | SPI_DEV_CMD_SSD1306_CURSOR_POS = 2
41 | SPI_DEV_CMD_SSD1306_ON = 3
42 | SPI_DEV_CMD_SSD1306_OFF = 4
43 | SPI_DEV_CMD_SSD1306_INVERSE = 5
44 | SPI_DEV_CMD_SSD1306_NON_INVERSE = 6
45 | SPI_DEV_CMD_SSD1306_CONTRAST = 7
46 | SPI_DEV_PRC_SSD1306_CLS = 8
47 | SPI_DEV_PRC_SSD1306_FILL_RANDOM = 9
48 | SPI_DEV_PRC_SSD1306_PRINT = 10
49 | SPI_DEV_PRC_SSD1306_PLOT = 11
50 | SPI_DEV_PRC_SSD1306_LINE = 12
51 | SPI_DEV_PRC_SSD1306_BOX = 13
52 | SPI_DEV_PRC_SSD1306_BOX_FILL = 14
53 | SPI_DEV_PRC_SSD1306_CIRCLE = 15
54 | SPI_DEV_PRC_SSD1306_CIRCLE_FILL = 16
55 | SPI_DEV_PRC_SSD1306_UPDATE = 17
56 |
57 |
58 |
59 | def DoDisplay(*Args):
60 | Message = ""
61 | for Count in range(len(Args)):
62 | if isinstance(Args[Count], str):
63 | Message += Args[Count]
64 | else:
65 | Message += struct.pack('I', Args[Count])
66 | File.write(Message)
67 |
68 |
69 | def WriteGPIO(DevFile, *Args):
70 | Message = ""
71 | for Count in range(len(Args)):
72 | if isinstance(Args[Count], str):
73 | Message += Args[Count]
74 | else:
75 | Message += struct.pack('I', Args[Count])
76 | File = open(DevFile, 'wb', 0)
77 | File.write(Message)
78 | File.close()
79 |
80 |
81 |
82 | # /*********************************************************/
83 | # /* Configure the console so key presses can be captured. */
84 | #/*********************************************************/
85 | curses.initscr()
86 | curses.noecho()
87 | window = curses.newwin(80, 25)
88 | window.nodelay(1)
89 | window.timeout(0)
90 |
91 | WriteGPIO(SSD1306_INIT, SPI_DEV_CMD_SSD1306_INIT)
92 | File = open(SSD1306_WRITE, 'wb', 0)
93 |
94 | DoDisplay(SPI_DEV_CMD_SSD1306_ON)
95 | DoDisplay(SPI_DEV_CMD_SSD1306_CONTRAST, 127)
96 | DoDisplay(SPI_DEV_PRC_SSD1306_CLS)
97 |
98 | ThisSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
99 | ThisSocket.connect(('192.168.0.1', 0))
100 |
101 | ExitFlag = False
102 | while ExitFlag == False:
103 | # /**********************************************/
104 | # /* Process main application loop every 200ms. */
105 | #/**********************************************/
106 | curses.napms(200)
107 |
108 | # /*************************/
109 | # /* Get a user key press. */
110 | #/*************************/
111 | ThisKey = window.getch()
112 |
113 | # /****************************************************/
114 | # /* If a key has been pressed, exit the application. */
115 | #/****************************************************/
116 | if ThisKey > -1:
117 | ExitFlag = True
118 |
119 | Now = datetime.datetime.now()
120 | if Now.microsecond > 500000:
121 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, 18, 0, 2, 3, Now.strftime("%H %M %S"))
122 | else:
123 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, 18, 0, 2, 3, Now.strftime("%H:%M:%S"))
124 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, 5, 28, 2, 2, Now.strftime("%Y-%m-%d"))
125 |
126 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, 64 - len(ThisSocket.getsockname()[0]) * 6 / 2, 48, 1, 2, ThisSocket.getsockname()[0])
127 |
128 | DoDisplay(SPI_DEV_PRC_SSD1306_UPDATE)
129 |
130 |
131 | DoDisplay(SPI_DEV_CMD_SSD1306_OFF)
132 |
133 | File.close()
134 |
135 | # /*********************/
136 | # /* Exit application. */
137 | #/*********************/
138 | curses.endwin()
139 |
140 |
--------------------------------------------------------------------------------
/RPiSPi/RPiSPi_SSD1306_Image.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | # RPiSPi_SSD1306 - Python Example For RPiSPi Driver Using SSD1306 Display
4 | # Copyright (C) 2016 Jason Birch
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | #/****************************************************************************/
20 | #/* RPiSPi_SSD1306 */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* V1.00 - 2016-11-02 - Jason Birch */
23 | #/* ------------------------------------------------------------------------ */
24 | #/* Python Example For RPiSPi Driver Using SSD1306 Display. */
25 | #/****************************************************************************/
26 |
27 |
28 | import curses
29 | import struct
30 | import pygame
31 |
32 |
33 | SSD1306_INIT = "/dev/RPiSPi_10000_000_5_0_SSD1306_INIT"
34 | SSD1306_WRITE = "/dev/RPiSPi_10000_000_5_1_SSD1306_WRITE"
35 |
36 | SPI_DEV_CMD_SSD1306_INIT = 0
37 | SPI_DEV_CMD_SSD1306_WRITE = 1
38 | SPI_DEV_CMD_SSD1306_CURSOR_POS = 2
39 | SPI_DEV_CMD_SSD1306_ON = 3
40 | SPI_DEV_CMD_SSD1306_OFF = 4
41 | SPI_DEV_CMD_SSD1306_INVERSE = 5
42 | SPI_DEV_CMD_SSD1306_NON_INVERSE = 6
43 | SPI_DEV_CMD_SSD1306_CONTRAST = 7
44 | SPI_DEV_PRC_SSD1306_CLS = 8
45 | SPI_DEV_PRC_SSD1306_FILL_RANDOM = 9
46 | SPI_DEV_PRC_SSD1306_PRINT = 10
47 | SPI_DEV_PRC_SSD1306_PLOT = 11
48 | SPI_DEV_PRC_SSD1306_LINE = 12
49 | SPI_DEV_PRC_SSD1306_BOX = 13
50 | SPI_DEV_PRC_SSD1306_BOX_FILL = 14
51 | SPI_DEV_PRC_SSD1306_CIRCLE = 15
52 | SPI_DEV_PRC_SSD1306_CIRCLE_FILL = 16
53 | SPI_DEV_PRC_SSD1306_UPDATE = 17
54 |
55 |
56 |
57 | def DoDisplay(*Args):
58 | Message = ""
59 | for Count in range(len(Args)):
60 | if isinstance(Args[Count], str):
61 | Message += Args[Count]
62 | else:
63 | Message += struct.pack('I', Args[Count])
64 | File.write(Message)
65 |
66 |
67 | def WriteGPIO(DevFile, *Args):
68 | Message = ""
69 | for Count in range(len(Args)):
70 | if isinstance(Args[Count], str):
71 | Message += Args[Count]
72 | else:
73 | Message += struct.pack('I', Args[Count])
74 | File = open(DevFile, 'wb', 0)
75 | File.write(Message)
76 | File.close()
77 |
78 |
79 | def DisplayImage128x64(ImageSurface):
80 | LastColourValue = 0
81 | for XPos in range(128):
82 | for YPos in range(64):
83 | ColourValue = sum(ImageSurface.get_at((XPos, YPos))) / 3;
84 | Colour = 0
85 | if ColourValue > 240:
86 | Colour = 1
87 | elif ColourValue > 32 and abs(LastColourValue - ColourValue) > 16:
88 | Colour = 1
89 | LastColourValue = ColourValue
90 |
91 | DoDisplay(SPI_DEV_PRC_SSD1306_PLOT, XPos, YPos, Colour)
92 |
93 |
94 |
95 | # /*********************************************************/
96 | # /* Configure the console so key presses can be captured. */
97 | #/*********************************************************/
98 | curses.initscr()
99 | curses.noecho()
100 | window = curses.newwin(80, 25)
101 | window.nodelay(1)
102 | window.timeout(0)
103 |
104 | pygame.init()
105 | ThisImage1 = pygame.image.load("TestImage1.gif")
106 | ThisImage2 = pygame.image.load("TestImage2.gif")
107 |
108 | WriteGPIO(SSD1306_INIT, SPI_DEV_CMD_SSD1306_INIT)
109 | File = open(SSD1306_WRITE, 'wb', 0)
110 |
111 | DoDisplay(SPI_DEV_CMD_SSD1306_ON)
112 | DoDisplay(SPI_DEV_CMD_SSD1306_CONTRAST, 127)
113 | DoDisplay(SPI_DEV_PRC_SSD1306_CLS)
114 |
115 |
116 | ImageDelay = 0
117 | ImageDisplay = 1
118 | ExitFlag = False
119 | while ExitFlag == False:
120 | # /**********************************************/
121 | # /* Process main application loop every 200ms. */
122 | #/**********************************************/
123 | curses.napms(200)
124 |
125 | # /*************************/
126 | # /* Get a user key press. */
127 | #/*************************/
128 | ThisKey = window.getch()
129 |
130 | # /****************************************************/
131 | # /* If a key has been pressed, exit the application. */
132 | #/****************************************************/
133 | if ThisKey > -1:
134 | ExitFlag = True
135 |
136 | ImageDelay -= 1
137 | if ImageDelay < 0:
138 | ImageDelay = 10
139 | if ImageDisplay == 1:
140 | DisplayImage128x64(ThisImage1)
141 | DoDisplay(SPI_DEV_PRC_SSD1306_UPDATE)
142 | ImageDisplay = 2
143 | elif ImageDisplay == 2:
144 | DisplayImage128x64(ThisImage2)
145 | DoDisplay(SPI_DEV_PRC_SSD1306_UPDATE)
146 | ImageDisplay = 1
147 |
148 |
149 | DoDisplay(SPI_DEV_CMD_SSD1306_OFF)
150 |
151 | File.close()
152 |
153 | # /*********************/
154 | # /* Exit application. */
155 | #/*********************/
156 | curses.endwin()
157 |
158 |
--------------------------------------------------------------------------------
/RPiSPi/RPiSPi_SSD1306_ScrollMessage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | # RPiSPi_SSD1306 - Python Example For RPiSPi Driver Using SSD1306 Display
4 | # Copyright (C) 2016 Jason Birch
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | #/****************************************************************************/
20 | #/* RPiSPi_SSD1306 */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* V1.00 - 2016-11-02 - Jason Birch */
23 | #/* ------------------------------------------------------------------------ */
24 | #/* Python Example For RPiSPi Driver Using SSD1306 Display. */
25 | #/****************************************************************************/
26 |
27 |
28 | import time
29 | import datetime
30 | import curses
31 | import struct
32 |
33 |
34 | SSD1306_INIT = "/dev/RPiSPi_10001_000_6_0_SSD1306_INIT"
35 | SSD1306_WRITE = "/dev/RPiSPi_10001_000_6_1_SSD1306_WRITE"
36 |
37 | SPI_DEV_CMD_SSD1306_INIT = 0
38 | SPI_DEV_CMD_SSD1306_WRITE = 1
39 | SPI_DEV_CMD_SSD1306_CURSOR_POS = 2
40 | SPI_DEV_CMD_SSD1306_ON = 3
41 | SPI_DEV_CMD_SSD1306_OFF = 4
42 | SPI_DEV_CMD_SSD1306_INVERSE = 5
43 | SPI_DEV_CMD_SSD1306_NON_INVERSE = 6
44 | SPI_DEV_CMD_SSD1306_CONTRAST = 7
45 | SPI_DEV_PRC_SSD1306_CLS = 8
46 | SPI_DEV_PRC_SSD1306_FILL_RANDOM = 9
47 | SPI_DEV_PRC_SSD1306_PRINT = 10
48 | SPI_DEV_PRC_SSD1306_PLOT = 11
49 | SPI_DEV_PRC_SSD1306_LINE = 12
50 | SPI_DEV_PRC_SSD1306_BOX = 13
51 | SPI_DEV_PRC_SSD1306_BOX_FILL = 14
52 | SPI_DEV_PRC_SSD1306_CIRCLE = 15
53 | SPI_DEV_PRC_SSD1306_CIRCLE_FILL = 16
54 | SPI_DEV_PRC_SSD1306_UPDATE = 17
55 |
56 |
57 |
58 | def DoDisplay(*Args):
59 | Message = ""
60 | for Count in range(len(Args)):
61 | if isinstance(Args[Count], str):
62 | Message += Args[Count]
63 | else:
64 | Message += struct.pack('I', Args[Count])
65 | File.write(Message)
66 |
67 |
68 | def WriteGPIO(DevFile, *Args):
69 | Message = ""
70 | for Count in range(len(Args)):
71 | if isinstance(Args[Count], str):
72 | Message += Args[Count]
73 | else:
74 | Message += struct.pack('I', Args[Count])
75 | File = open(DevFile, 'wb', 0)
76 | File.write(Message)
77 | File.close()
78 |
79 |
80 | def ScrollMessage(XPos, YPos, XSize, YSize, Message):
81 | DoDisplay(SPI_DEV_PRC_SSD1306_BOX_FILL, 0, YPos, XSize * 6, YPos + YSize * 8, 0)
82 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, XPos, YPos, XSize, YSize, Message)
83 | WrapMessage = Message[int(((len(Message) + 1) * 6 * XSize - XPos) / (XSize * 6)):]
84 | DoDisplay(SPI_DEV_PRC_SSD1306_PRINT, (XPos - 1) % (XSize * 6), YPos, XSize, YSize, WrapMessage)
85 |
86 |
87 | # /*********************************************************/
88 | # /* Configure the console so key presses can be captured. */
89 | #/*********************************************************/
90 | curses.initscr()
91 | curses.noecho()
92 | window = curses.newwin(80, 25)
93 | window.nodelay(1)
94 | window.timeout(0)
95 |
96 | WriteGPIO(SSD1306_INIT, SPI_DEV_CMD_SSD1306_INIT)
97 | File = open(SSD1306_WRITE, 'wb', 0)
98 |
99 | DoDisplay(SPI_DEV_CMD_SSD1306_ON)
100 | DoDisplay(SPI_DEV_CMD_SSD1306_CONTRAST, 127)
101 | DoDisplay(SPI_DEV_PRC_SSD1306_CLS)
102 |
103 | Pos1 = 0
104 | Pos2 = 0
105 | Message2 = " <<<<< Scroll Message Left <<<<< "
106 | Pos3 = 0
107 | Message3 = " >>>>> Scroll Message Right >>>>> "
108 |
109 | ExitFlag = False
110 | while ExitFlag == False:
111 | # /**********************************************/
112 | # /* Process main application loop every 200ms. */
113 | #/**********************************************/
114 | curses.napms(100)
115 |
116 | # /*************************/
117 | # /* Get a user key press. */
118 | #/*************************/
119 | ThisKey = window.getch()
120 |
121 | # /****************************************************/
122 | # /* If a key has been pressed, exit the application. */
123 | #/****************************************************/
124 | if ThisKey > -1:
125 | ExitFlag = True
126 |
127 | Now = datetime.datetime.now()
128 | Message1 = Now.strftime(" %Y-%m-%d %H:%M:%S ")
129 |
130 | ScrollMessage(Pos1, 0, 1, 2, Message1)
131 | ScrollMessage(Pos2, 25, 2, 2, Message2)
132 | ScrollMessage(Pos3, 50, 2, 2, Message3)
133 |
134 | DoDisplay(SPI_DEV_PRC_SSD1306_UPDATE)
135 |
136 | Pos1 += 2
137 | if Pos1 >= len(Message1) * 6 * 1:
138 | Pos1 = 0
139 |
140 | Pos2 -= 2
141 | if Pos2 <= 0:
142 | Pos2 = len(Message2) * 6 * 2
143 |
144 | Pos3 += 2
145 | if Pos3 >= len(Message3) * 6 * 2:
146 | Pos3 = 0
147 |
148 |
149 |
150 | DoDisplay(SPI_DEV_CMD_SSD1306_OFF)
151 |
152 | File.close()
153 |
154 | # /*********************/
155 | # /* Exit application. */
156 | #/*********************/
157 | curses.endwin()
158 |
159 |
--------------------------------------------------------------------------------
/RPiSPi/RPiTempSensor/CalValues.txt:
--------------------------------------------------------------------------------
1 | 0,124,251
2 | 1,131,254
3 | 2,137,258
4 | 3,143,265
5 | 4,150,271
6 | 5,155,284
7 | 6,161,295
8 | 7,167,300
9 | 8,173,307
10 | 9,179,313
11 | 10,185,321
12 | 11,191,335
13 | 12,197,350
14 | 13,203,356
15 | 14,209,371
16 | 15,220,435
17 | 16,225,441
18 | 17,228,452
19 | 18,239,463
20 | 19,244,472
21 | 20,251,494
22 | 21,257,499
23 | 22,263,521
24 | 23,269,530
25 | 24,273,537
26 | 25,281,569
27 | 26,287,585
28 | 27,292,598
29 | 28,299,609
30 | 29,305,611
31 | 30,310,620
32 | 31,316,627
33 | 32,322,638
34 | 33,329,641
35 | 34,335,646
36 | 35,339,649
37 | 36,348,665
38 | 37,354,664
39 | 38,358,665
40 | 39,364,671
41 | 40,369,681
42 | 41,377,686
43 | 42,382,688
44 | 43,387,691
45 | 44,396,697
46 | 45,400,679
47 | 46,408,713
48 | 47,409,691
49 | 48,420,716
50 | 49,425,718
51 | 50,432,721
52 | 51,436,729
53 | 52,441,718
54 | 53,448,719
55 | 54,454,734
56 | 55,462,745
57 | 56,467,745
58 | 57,473,755
59 | 58,481,753
60 | 59,487,760
61 | 60,492,761
62 | 61,499,777
63 | 62,505,775
64 | 63,510,777
65 | 64,516,775
66 | 65,523,786
67 | 66,529,792
68 | 67,534,793
69 | 68,540,796
70 | 69,546,796
71 | 70,553,809
72 | 71,559,812
73 | 72,563,824
74 | 73,569,825
75 | 74,577,835
76 | 75,583,839
77 | 76,588,850
78 | 77,595,851
79 | 78,601,857
80 | 79,608,867
81 | 80,612,871
82 | 81,620,873
83 | 82,624,878
84 | 83,632,883
85 | 84,636,889
86 | 85,644,945
87 | 86,649,924
88 | 87,656,951
89 | 88,659,952
90 | 89,664,935
91 | 90,673,945
92 | 91,679,953
93 | 92,684,947
94 | 93,688,952
95 | 94,0,0
96 | 95,0,0
97 | 96,0,0
98 | 97,0,0
99 | 98,0,0
100 | 99,0,0
101 | 100,0,0
102 |
--------------------------------------------------------------------------------
/RPiSPi/RPiTempSensor/CalValues.txt.BAK:
--------------------------------------------------------------------------------
1 | 0,124,251
2 | 1,131,254
3 | 2,137,258
4 | 3,143,265
5 | 4,150,271
6 | 5,155,284
7 | 6,161,295
8 | 7,167,300
9 | 8,173,307
10 | 9,179,313
11 | 10,185,321
12 | 11,191,335
13 | 12,197,350
14 | 13,203,356
15 | 14,209,371
16 | 15,220,435
17 | 16,225,441
18 | 17,228,452
19 | 18,239,463
20 | 19,244,472
21 | 20,251,494
22 | 21,257,499
23 | 22,263,521
24 | 23,269,530
25 | 24,273,537
26 | 25,281,569
27 | 26,287,585
28 | 27,292,598
29 | 28,299,609
30 | 29,305,611
31 | 30,310,620
32 | 31,316,627
33 | 32,322,638
34 | 33,329,641
35 | 34,335,646
36 | 35,339,649
37 | 36,348,665
38 | 37,354,664
39 | 38,358,665
40 | 39,364,671
41 | 40,369,681
42 | 41,377,686
43 | 42,382,688
44 | 43,387,691
45 | 44,396,697
46 | 45,400,679
47 | 46,408,713
48 | 47,409,691
49 | 48,420,716
50 | 49,425,718
51 | 50,432,721
52 | 51,436,729
53 | 52,441,718
54 | 53,448,719
55 | 54,454,734
56 | 55,462,745
57 | 56,467,745
58 | 57,473,755
59 | 58,481,753
60 | 59,487,760
61 | 60,492,761
62 | 61,499,777
63 | 62,505,775
64 | 63,510,777
65 | 64,516,775
66 | 65,523,786
67 | 66,529,792
68 | 67,534,793
69 | 68,540,796
70 | 69,546,796
71 | 70,553,809
72 | 71,559,812
73 | 72,563,824
74 | 73,569,825
75 | 74,577,835
76 | 75,583,839
77 | 76,588,850
78 | 77,595,851
79 | 78,601,857
80 | 79,608,867
81 | 80,612,871
82 | 81,620,873
83 | 82,624,878
84 | 83,632,883
85 | 84,636,889
86 | 85,644,945
87 | 86,649,924
88 | 87,656,951
89 | 88,659,952
90 | 89,664,935
91 | 90,673,945
92 | 91,679,953
93 | 92,684,947
94 | 93,688,952
95 | 94,0,0
96 | 95,0,0
97 | 96,0,0
98 | 97,0,0
99 | 98,0,0
100 | 99,0,0
101 | 100,0,0
102 |
--------------------------------------------------------------------------------
/RPiSPi/RPiTempSensor/Device.cfg:
--------------------------------------------------------------------------------
1 | 0001,000,MCP3002
2 |
3 |
--------------------------------------------------------------------------------
/RPiSPi/RPiTempSensor/RPi_MCP3002_TempSense.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | # RPi_MCP3002_TempSense - Python Example Using RPiSPi Driver and MCP3002
4 | # Copyright (C) 2016 Jason Birch
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | #/****************************************************************************/
20 | #/* RPiSPi_MCP3002 */
21 | #/* ------------------------------------------------------------------------ */
22 | #/* V1.00 - 2016-11-02 - Jason Birch */
23 | #/* ------------------------------------------------------------------------ */
24 | #/* Python Example Using RPiSPi Driver and MCP3002 A-D Converter to read */
25 | #/* temprature sensors. */
26 | #/* cat Device.cfg >/dev/RPiSPi */
27 | #/* cat /proc/RPiSPi */
28 | #/****************************************************************************/
29 |
30 |
31 | import sys
32 | import time
33 | import math
34 | import datetime
35 | import struct
36 | import pygame
37 |
38 |
39 | # /*********************/
40 | # /* Define constants. */
41 | #/*********************/
42 | PLOT_HOURS = 0.05
43 | # PLOT_HOURS = 0.25
44 | # PLOT_HOURS = 24.0
45 |
46 | # PLOT_CELCIUS = 30.0
47 | PLOT_CELCIUS = 100.0
48 |
49 | AD_REF_VOLTAGE = 3.3
50 | AD_RESOLUTION = 1024.0
51 | CAL_VALUES = 101
52 | WINDOW_WIDTH = 640
53 | WINDOW_HEIGHT = 480
54 | GRAPH_TOP = 20.0
55 | GRAPH_LEFT = 40.0
56 | GRAPH_HEIGHT = 400.0
57 | GRAPH_WIDTH = 590.0
58 | SUB_GRAPH_TOP = 20.0
59 | SUB_GRAPH_LEFT = 530.0
60 | SUB_GRAPH_HEIGHT = 100.0
61 | SUB_GRAPH_SCALE_X = 1.0
62 | SUB_GRAPH_SCALE_Y = 0.1
63 |
64 | WHITE_COLOUR = (0xFF, 0xFF, 0xFF)
65 | GREY_COLOUR = (0x7F, 0x7F, 0x7F)
66 | DIM_GREY_COLOUR = (0x50, 0x50, 0x50)
67 | BLACK_COLOUR = (0x00, 0x00, 0x00)
68 | MCP9701A_CAL_COLOUR = (0x00, 0x7F, 0x00)
69 | MCP9701A_TEMPRATURE_COLOUR = (0x50, 0xFF, 0x50)
70 | THERMISTOR_CAL_ADJ_COLOUR = (0x7F, 0x00, 0x00)
71 | THERMISTOR_CAL_OFFSET_COLOUR = (0x7F, 0x00, 0x00)
72 | THERMISTOR_CAL_COLOUR = (0x00, 0x00, 0x7F)
73 | THERMISTOR_TEMPRATURE_COLOUR = (0x00, 0x00, 0x7F)
74 | THERMISTOR_TEMPRATURE_COLOUR_ADJ = (0x50, 0x50, 0xFF)
75 |
76 | EVENT_TIMER = pygame.USEREVENT + 1
77 |
78 |
79 |
80 | def ReadAD(DevFile):
81 | File = open(DevFile, 'rb', 0)
82 | Data = File.read(4)
83 | File.close()
84 | return struct.unpack("<%dI" % (len(Data) // 4), Data)[0]
85 |
86 |
87 | def Timer():
88 | global X
89 | global Y0
90 | global Y1
91 | global Y1Adjusted
92 |
93 | # /***************************************************/
94 | # /* Read A-D channel 0, MCP9701A temprature sensor. */
95 | #/***************************************************/
96 | Value0 = ReadAD("/dev/RPiSPi_0001_000_0_2_MCP3002_READ0")
97 | # Calculate the voltage value, 3V3 maximum scale, 1024 reading maximum scale.
98 | ValueVolt0 = AD_REF_VOLTAGE * Value0 / AD_RESOLUTION
99 | # Calculate the temprature, 0C = 0.4V, each 1C = 19.5mV, from data sheet.
100 | Value0C = (ValueVolt0 - 0.4) / 0.0195
101 |
102 | # /****************************************/
103 | # /* Read A-D channel 1, 100K Thermister. */
104 | #/****************************************/
105 | Value1 = ReadAD("/dev/RPiSPi_0001_000_0_3_MCP3002_READ1")
106 | # Calculate the voltage value, 3V3 maximum scale, 1024 reading maximum scale.
107 | ValueVolt1 = AD_REF_VOLTAGE * Value1 / AD_RESOLUTION
108 | # From calibrating with ice water, 0C = 250 A-D reading.
109 | Value1Zero = 260.0
110 | # From calibrating with hot water and MCP9701A reading, 50C = 745 A-D reading.
111 | Value1Fifty = 670.0
112 | # From calibrating with boiling water, 100C = 1200 A-D reading.
113 | Value1Hundred = 1070.0
114 | # Calculate 50C reading as a value in the range 0 - 1 (equivelent 0C - 100C).
115 | Value1MidPoint = (Value1Fifty - Value1Zero) / (Value1Hundred - Value1Zero) * 100
116 | # Calculate unadjusted read value in the range 0 - 1 (equivelent 0C - 100C).
117 | Value1C = (Value1 - Value1Zero) / (Value1Hundred - Value1Zero) * 100
118 | # Look up adjusted value on a sin curve of points calibration.
119 | CurveY = 200.0 + (math.cos(1.0 + Value1C / 65.0) + 0.0175 * Value1C) * Value1Hundred
120 | Value1CAdjusted = (CurveY - Value1Zero) / (Value1Hundred - Value1Zero) * 250 - 167
121 |
122 | # /*****************************************/
123 | # /* If a new calibration value is found, */
124 | # /* add it and save the calibration data. */
125 | #/*****************************************/
126 | if int(Value0C) >= 0 and int(Value0C) <= 100 and (MCP9701A_Values[int(Value0C)][1] == 0 or Thermister_Values[int(Value0C)][1] == 0):
127 | MCP9701A_Values[int(Value0C)] = (int(Value0C), Value0)
128 | Thermister_Values[int(Value0C)] = (int(Value0C), Value1)
129 |
130 | try:
131 | File = open("CalValues.txt", 'w', 0)
132 | for Count in range(CAL_VALUES):
133 | File.write(str(Count) + ",")
134 | File.write(str(MCP9701A_Values[Count][1]) + ",")
135 | File.write(str(Thermister_Values[Count][1]) + "\n")
136 | File.close()
137 | except:
138 | print("")
139 |
140 | # /******************/
141 | # /* Clear display. */
142 | #/******************/
143 | ThisSurface.fill(BLACK_COLOUR)
144 |
145 | # /*********************************************/
146 | # /* Draw MCP9701A collected calibration data. */
147 | #/*********************************************/
148 | LastY = 0
149 | LastCurveY = 0
150 | LastYAdjusted = 0
151 | for Count in range(CAL_VALUES - 1):
152 | # MCP9701A calibration data.
153 | if MCP9701A_Values[Count][1] > 0 and MCP9701A_Values[Count + 1][1] > 0:
154 | pygame.draw.line(ThisSurface, MCP9701A_CAL_COLOUR, (SUB_GRAPH_LEFT + SUB_GRAPH_SCALE_X * MCP9701A_Values[Count][0], SUB_GRAPH_TOP + SUB_GRAPH_HEIGHT - MCP9701A_Values[Count][1] * SUB_GRAPH_SCALE_Y), (SUB_GRAPH_LEFT + SUB_GRAPH_SCALE_X * MCP9701A_Values[Count + 1][0], SUB_GRAPH_TOP + SUB_GRAPH_HEIGHT - MCP9701A_Values[Count + 1][1] * SUB_GRAPH_SCALE_Y), 1)
155 | # Thermistor calibration data.
156 | if Thermister_Values[Count][1] > 0 and Thermister_Values[Count + 1][1] > 0:
157 | pygame.draw.line(ThisSurface, THERMISTOR_CAL_COLOUR, (SUB_GRAPH_LEFT + SUB_GRAPH_SCALE_X * Thermister_Values[Count][0], SUB_GRAPH_TOP + SUB_GRAPH_HEIGHT - Thermister_Values[Count][1] * SUB_GRAPH_SCALE_Y), (SUB_GRAPH_LEFT + SUB_GRAPH_SCALE_X * Thermister_Values[Count + 1][0], SUB_GRAPH_TOP + SUB_GRAPH_HEIGHT - Thermister_Values[Count + 1][1] * SUB_GRAPH_SCALE_Y), 1)
158 |
159 | # Calibration adjustment to convert 100K Thermistor to approx MCP9701A values.
160 | # Manipulate sin wav to cancel out inaccuracies.
161 |
162 | # Thermistor calibration approximated curve.
163 | CurveY = 200.0 + (math.cos(1.0 + Count / 65.0) + 0.0175 * Count) * Value1Hundred
164 | if Count > 0:
165 | pygame.draw.line(ThisSurface, THERMISTOR_CAL_ADJ_COLOUR, (SUB_GRAPH_LEFT + SUB_GRAPH_SCALE_X * Count, SUB_GRAPH_TOP + SUB_GRAPH_HEIGHT - LastCurveY * SUB_GRAPH_SCALE_Y), (SUB_GRAPH_LEFT + SUB_GRAPH_SCALE_X * (Count + 1), SUB_GRAPH_TOP + SUB_GRAPH_HEIGHT - CurveY * SUB_GRAPH_SCALE_Y), 1)
166 |
167 | # Thermistor calibration adjutment offsets.
168 | if Thermister_Values[Count][1] == 0:
169 | Y = Thermister_Values[Count][1]
170 | else:
171 | Y = CurveY - Thermister_Values[Count][1]
172 | if Count > 0:
173 | pygame.draw.line(ThisSurface, THERMISTOR_CAL_OFFSET_COLOUR, (SUB_GRAPH_LEFT + SUB_GRAPH_SCALE_X * Count, SUB_GRAPH_TOP + SUB_GRAPH_HEIGHT - LastY * SUB_GRAPH_SCALE_Y), (SUB_GRAPH_LEFT + SUB_GRAPH_SCALE_X * (Count + 1), SUB_GRAPH_TOP + SUB_GRAPH_HEIGHT - Y * SUB_GRAPH_SCALE_Y), 1)
174 |
175 | # Adjusted thermistor calibrated data.
176 | YAdjusted = (Thermister_Values[Count][1] + CurveY) / 2 - 100
177 | if Count > 0:
178 | pygame.draw.line(ThisSurface, WHITE_COLOUR, (SUB_GRAPH_LEFT + SUB_GRAPH_SCALE_X * Count, SUB_GRAPH_TOP + SUB_GRAPH_HEIGHT - LastYAdjusted * SUB_GRAPH_SCALE_Y), (SUB_GRAPH_LEFT + SUB_GRAPH_SCALE_X * (Count + 1), SUB_GRAPH_TOP + SUB_GRAPH_HEIGHT - YAdjusted * SUB_GRAPH_SCALE_Y), 1)
179 |
180 | LastY = Y
181 | LastCurveY = CurveY
182 | LastYAdjusted = YAdjusted
183 |
184 | # /***************************************************/
185 | # /* Draw A-D channel 0, MCP9701A temprature sensor. */
186 | #/***************************************************/
187 | Y0[X] = ((GRAPH_LEFT + X, GRAPH_TOP + GRAPH_HEIGHT - Value0C / PLOT_CELCIUS * GRAPH_HEIGHT))
188 | pygame.draw.lines(ThisSurface, MCP9701A_TEMPRATURE_COLOUR, False, Y0, 1)
189 |
190 | # /****************************************/
191 | # /* Draw A-D channel 1, 100K Thermister. */
192 | #/****************************************/
193 | Y1[X] = ((GRAPH_LEFT + X, GRAPH_TOP + GRAPH_HEIGHT - Value1C / PLOT_CELCIUS * GRAPH_HEIGHT))
194 | Y1Adjusted[X] = ((GRAPH_LEFT + X, GRAPH_TOP + GRAPH_HEIGHT - Value1CAdjusted / PLOT_CELCIUS * GRAPH_HEIGHT))
195 | pygame.draw.lines(ThisSurface, THERMISTOR_TEMPRATURE_COLOUR, False, Y1, 1)
196 | pygame.draw.lines(ThisSurface, THERMISTOR_TEMPRATURE_COLOUR_ADJ, False, Y1Adjusted, 1)
197 |
198 | # /************************/
199 | # /* Display graph title. */
200 | #/************************/
201 | DisplayText = "MCP9701A TEMPRATURE SENSOR"
202 | FontText = SmallFont.render(DisplayText, True, MCP9701A_TEMPRATURE_COLOUR)
203 | ThisSurface.blit(FontText, (110, 0))
204 |
205 | DisplayText = "vs"
206 | FontText = SmallFont.render(DisplayText, True, GREY_COLOUR)
207 | ThisSurface.blit(FontText, (380, 0))
208 |
209 | DisplayText = "100K THERMISTOR"
210 | FontText = SmallFont.render(DisplayText, True, THERMISTOR_TEMPRATURE_COLOUR)
211 | ThisSurface.blit(FontText, (410, 0))
212 |
213 | # /*****************************/
214 | # /* Display current readings. */
215 | #/*****************************/
216 | Now = datetime.datetime.now()
217 | DisplayText = Now.strftime("%Y-%m-%d %H:%M:%S")
218 | # print(DisplayText)
219 | FontText = SmallFont.render(DisplayText, True, WHITE_COLOUR)
220 | ThisSurface.blit(FontText, (10, 450))
221 |
222 | DisplayText = "AD0=" + "{0:4}".format(Value0) + " " + "{0:7.4}".format(ValueVolt0) + "V, " + "{0:6.3}".format(Value0C) + "C"
223 | # print(DisplayText)
224 | FontText = SmallFont.render(DisplayText, True, MCP9701A_TEMPRATURE_COLOUR)
225 | ThisSurface.blit(FontText, (170, 450))
226 |
227 | DisplayText = "AD1=" + "{0:4}".format(Value1) + " " + "{0:7.4}".format(ValueVolt1) + "V, " + "{0:6.3}".format(Value1C) + "C [" + "{0:6.3}".format(Value1CAdjusted) + "C]"
228 | # print(DisplayText)
229 | FontText = SmallFont.render(DisplayText, True, THERMISTOR_TEMPRATURE_COLOUR_ADJ)
230 | ThisSurface.blit(FontText, (380, 450))
231 |
232 | # /********************/
233 | # /* Draw graph axis. */
234 | #/********************/
235 | pygame.draw.line(ThisSurface, GREY_COLOUR, (GRAPH_LEFT, GRAPH_TOP), (GRAPH_LEFT, GRAPH_TOP + GRAPH_HEIGHT), 1)
236 | pygame.draw.line(ThisSurface, GREY_COLOUR, (GRAPH_LEFT, GRAPH_TOP + GRAPH_HEIGHT), (GRAPH_LEFT + GRAPH_WIDTH, GRAPH_TOP + GRAPH_HEIGHT), 1)
237 | pygame.draw.line(ThisSurface, WHITE_COLOUR, (GRAPH_LEFT + 1 + X, GRAPH_TOP), (GRAPH_LEFT + 1 + X, GRAPH_TOP + GRAPH_HEIGHT), 1)
238 | pygame.draw.line(ThisSurface, DIM_GREY_COLOUR, (SUB_GRAPH_LEFT + SUB_GRAPH_SCALE_X * Value1C, SUB_GRAPH_TOP), (SUB_GRAPH_LEFT + SUB_GRAPH_SCALE_X * Value1C, SUB_GRAPH_TOP + SUB_GRAPH_HEIGHT), 1)
239 |
240 | # /*****************/
241 | # /* Draw Y scale. */
242 | #/*****************/
243 | XStep = PLOT_CELCIUS / 10.0
244 | Count = 0.0
245 | while Count <= PLOT_CELCIUS + PLOT_CELCIUS / 10.0:
246 | Ypos = GRAPH_TOP + GRAPH_HEIGHT - Count / PLOT_CELCIUS * GRAPH_HEIGHT
247 | pygame.draw.line(ThisSurface, GREY_COLOUR, (GRAPH_LEFT - 5, Ypos), (GRAPH_LEFT, Ypos), 1)
248 | FontText = SmallFont.render("{0:3.4}".format(Count), True, GREY_COLOUR)
249 | ThisSurface.blit(FontText, (5, Ypos - 10))
250 | Count += XStep
251 |
252 | # /*****************/
253 | # /* Draw X scale. */
254 | #/*****************/
255 | XStep = PLOT_HOURS / 6.0
256 | Count = 0.0
257 | while Count <= PLOT_HOURS + PLOT_HOURS / 6.0:
258 | Xpos = GRAPH_LEFT + Count * GRAPH_WIDTH / PLOT_HOURS
259 | pygame.draw.line(ThisSurface, GREY_COLOUR, (Xpos, GRAPH_TOP + GRAPH_HEIGHT), (Xpos, GRAPH_TOP + GRAPH_HEIGHT + 5), 1)
260 | FontText = SmallFont.render("{0:3.3}".format(Count), True, GREY_COLOUR)
261 | ThisSurface.blit(FontText, (Xpos - 20, GRAPH_TOP + GRAPH_HEIGHT + 10))
262 | Count += XStep
263 |
264 | # /*******************/
265 | # /* Update display. */
266 | #/*******************/
267 | pygame.display.flip()
268 | X += 1
269 | if X > GRAPH_WIDTH:
270 | X = 0
271 |
272 |
273 |
274 | # /***************/
275 | # /* Initialize. */
276 | #/***************/
277 | pygame.init()
278 | ThisSurface = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.HWSURFACE | pygame.DOUBLEBUF)
279 | SmallFont = pygame.font.Font(None, 22)
280 | ThisSurface.fill(BLACK_COLOUR)
281 | pygame.display.flip()
282 |
283 | X = 0
284 | Y0 = [(GRAPH_LEFT + Value, GRAPH_TOP + GRAPH_HEIGHT) for Value in range(int(GRAPH_WIDTH) + 1)]
285 | Y1 = [(GRAPH_LEFT + Value, GRAPH_TOP + GRAPH_HEIGHT) for Value in range(int(GRAPH_WIDTH) + 1)]
286 | Y1Adjusted = [(GRAPH_LEFT + Value, GRAPH_TOP + GRAPH_HEIGHT) for Value in range(int(GRAPH_WIDTH) + 1)]
287 | Thermister_Values = [(GRAPH_LEFT + Value, 0) for Value in range(CAL_VALUES)]
288 | MCP9701A_Values = [(GRAPH_LEFT + Value, 0) for Value in range(CAL_VALUES)]
289 |
290 | # /***************************************/
291 | # /* Load last saved calibration values. */
292 | #/***************************************/
293 | try:
294 | File = open("CalValues.txt", 'r', 0)
295 | for Count in range(CAL_VALUES):
296 | TextLine = File.readline()
297 | if not TextLine:
298 | break
299 | Values = TextLine.split(",")
300 | MCP9701A_Values[int(Values[0])] = (int(Values[0]), int(Values[1]))
301 | Thermister_Values[int(Values[0])] = (int(Values[0]), int(Values[2]))
302 | File.close()
303 | except:
304 | print("")
305 |
306 | # /**************************************************************/
307 | # /* Process application messages until the ESC key is pressed. */
308 | #/**************************************************************/
309 | ExitFlag = False
310 | Timer()
311 | pygame.time.set_timer(EVENT_TIMER, int(PLOT_HOURS * 6125.0))
312 | while ExitFlag == False:
313 | # /*************************************/
314 | # /* Yeald for other processes to run. */
315 | #/*************************************/
316 | pygame.time.wait(100)
317 |
318 | # /************************************/
319 | # /* Process application event queue. */
320 | #/************************************/
321 | for ThisEvent in pygame.event.get():
322 | # /******************************************************************/
323 | # /* If ptyhon has posted a QUIT message, flag to exit applicaiton. */
324 | #/******************************************************************/
325 | if ThisEvent.type == pygame.QUIT:
326 | ExitFlag = True
327 | break
328 | # /*********************************************************/
329 | # /* On timer period perform one frame of the application. */
330 | #/*********************************************************/
331 | elif ThisEvent.type == EVENT_TIMER:
332 | Timer()
333 |
334 | # /****************************************************************/
335 | # /* Check for ESC key press, and exit application when detected. */
336 | #/****************************************************************/
337 | KeysPressed = pygame.key.get_pressed()
338 | if KeysPressed[pygame.K_ESCAPE]:
339 | ExitFlag = True
340 |
341 |
342 | # /*********************************/
343 | # /* Application clean up and end. */
344 | #/*********************************/
345 | pygame.time.set_timer(EVENT_TIMER, 0)
346 |
347 |
--------------------------------------------------------------------------------
/RPiSPi/TestImage1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/TestImage1.gif
--------------------------------------------------------------------------------
/RPiSPi/TestImage2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BirchJD/Raspberry-Pi-Python-Interfacing/a310530916e9ef9bd8969fec948b8c4eaae3e63e/RPiSPi/TestImage2.gif
--------------------------------------------------------------------------------
/RPi_GPIO_Input.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | #/**********************************************/
4 | #/* Raspberry Pi GPIO Input Example in Python. */
5 | #/* 2016-07-31 - Version 1.00 - Jason Birch. */
6 | #/**********************************************/
7 |
8 | import sys
9 | import time
10 | import datetime
11 | import RPi.GPIO
12 |
13 |
14 | #/****************************/
15 | #/* USER DEFINABLE CONSTANTS */
16 | #/****************************/
17 | GPIO_INPUT_PIN = 14
18 |
19 |
20 | # /*******************************************/
21 | # /* Configure Raspberry Pi GPIO interfaces. */
22 | #/*******************************************/
23 | def InitGPIO():
24 | RPi.GPIO.setmode(RPi.GPIO.BCM)
25 | RPi.GPIO.setup(GPIO_INPUT_PIN, RPi.GPIO.IN, pull_up_down=RPi.GPIO.PUD_UP)
26 | RPi.GPIO.add_event_detect(GPIO_INPUT_PIN, RPi.GPIO.RISING, callback=InputCallback, bouncetime=200)
27 | # RPi.GPIO.add_event_detect(GPIO_INPUT_PIN, RPi.GPIO.FALLING, callback=InputCallback, bouncetime=200)
28 |
29 |
30 | # /**************************************/
31 | # /* Raspberry Pi GPIO interupt routine. */
32 | #/**************************************/
33 | def InputCallback(GpioPin):
34 | Now = datetime.datetime.now()
35 | print(Now.strftime("%Y-%m-%d %H:%M:%S") + " - GPIO: " + format(GpioPin, "00d"))
36 |
37 |
38 |
39 | # /**************************/
40 | # /* Main application loop. */
41 | #/**************************/
42 | InitGPIO()
43 | Key = 0
44 | while Key == 0:
45 | time.sleep(1)
46 | Key = sys.stdin.read(1)
47 |
48 |
49 | # /*************************************************/
50 | # /* Close Raspberry Pi GPIO use before finishing. */
51 | #/*************************************************/
52 | RPi.GPIO.cleanup()
53 |
54 |
--------------------------------------------------------------------------------
/RPi_GPIO_Output.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | #/***********************************************/
4 | #/* Raspberry Pi GPIO Output Example in Python. */
5 | #/* 2016-07-31 - Version 1.00 - Jason Birch. */
6 | #/***********************************************/
7 |
8 | import sys
9 | import time
10 | import datetime
11 | import threading
12 | import RPi.GPIO
13 |
14 |
15 | #/****************************/
16 | #/* USER DEFINABLE CONSTANTS */
17 | #/****************************/
18 | GPIO_OUTPUT_PIN = 14
19 |
20 |
21 | # /*******************************************/
22 | # /* Configure Raspberry Pi GPIO interfaces. */
23 | #/*******************************************/
24 | def InitGPIO():
25 | RPi.GPIO.setmode(RPi.GPIO.BCM)
26 | RPi.GPIO.setup(GPIO_OUTPUT_PIN, RPi.GPIO.OUT, initial=0)
27 |
28 |
29 | # /****************************************/
30 | # /* Procedure to execute every 1 second. */
31 | #/****************************************/
32 | def OutputTimer():
33 | global OutValue
34 | global TimerThread
35 |
36 | OutValue = OutValue ^ 1
37 |
38 | RPi.GPIO.output(GPIO_OUTPUT_PIN, OutValue)
39 | Now = datetime.datetime.now()
40 | print(Now.strftime("%Y-%m-%d %H:%M:%S") + " - GPIO: " + format(GPIO_OUTPUT_PIN, "00d") + " = " + format(OutValue, "0d"))
41 |
42 | TimerThread = threading.Timer(1, OutputTimer)
43 | TimerThread.start()
44 |
45 |
46 | # /**************************/
47 | # /* Main application loop. */
48 | #/**************************/
49 | Key = 0
50 | OutValue = 0
51 | TimerThread = None
52 |
53 | InitGPIO()
54 | OutputTimer()
55 | while Key == 0:
56 | time.sleep(1)
57 | Key = sys.stdin.read(1)
58 |
59 |
60 | # /*************************************************************************/
61 | # /* Stop the timer so GPIO is not used by mistake after it is cleaned up. */
62 | #/*************************************************************************/
63 | TimerThread.cancel()
64 |
65 | # /*************************************************/
66 | # /* Close Raspberry Pi GPIO use before finishing. */
67 | #/*************************************************/
68 | RPi.GPIO.cleanup()
69 |
70 |
--------------------------------------------------------------------------------