├── README.md ├── TutorialPrj ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png ├── 9.png ├── ch2_factorial_test.py ├── ch3_Snowflake.py ├── ch3_yinyang.py ├── ch4_AmazeBalls_1 │ ├── My_amazeballs1.py │ ├── amazeballs1.py │ └── images │ │ ├── ball0.png │ │ ├── ball1.png │ │ ├── ball2.png │ │ ├── ball3.png │ │ ├── ball4.png │ │ ├── ball5.png │ │ ├── ball6.png │ │ ├── ball7.png │ │ ├── map1.png │ │ ├── map1a.png │ │ ├── map1b.png │ │ ├── map1c.png │ │ ├── map2.png │ │ ├── map2a.png │ │ ├── map2b.png │ │ ├── map2c.png │ │ ├── map3c.png │ │ └── title.png ├── ch4_freds_bad_day │ ├── assets │ │ ├── Barrel.png │ │ ├── Barrel_break.png │ │ ├── Fred-Left-Hit.png │ │ ├── Fred-Left.png │ │ ├── Fred-Right-Hit.png │ │ ├── Fred-Right.png │ │ ├── background.png │ │ ├── gameover.png │ │ └── startgame.png │ ├── freds_bad_day.py │ └── objects.py ├── ch4_rpg.py ├── ch4_snake.py ├── ch5_serial │ ├── serialPC.py │ └── serialRAS.py ├── ch5_socket │ ├── multiconn-clientM.py │ └── multiconn-serverM.py ├── ch6_pongGame.py ├── ch6_senHatSliderRGB.py ├── ch6_senHatTraffic.py ├── ch6_webControlSenseHat.py ├── ch7_Sense_Acc.py ├── ch7_guiOrientationDemo.py ├── ch7_pitchFileLog │ ├── pitchFileLog.py │ └── write_data.txt ├── ch7_weather_station.py ├── ch8_surveillance_system.py ├── ch8_test_OpenCV │ ├── CMakeLists.txt │ ├── lena.jpg │ └── sample1.cpp └── darknet_202204 │ ├── readme.txt │ └── test_darknet.sh ├── 必备软件 ├── SDCardFormatterv5_WinEN.zip ├── WinSCP-5.17.10-Setup.exe ├── imager_1.6.2.exe ├── putty-64bit-0.76-installer.msi ├── sscom32.exe ├── thonny-3.2.7.exe └── 注意.txt ├── 树莓派编程实用教程.pdf └── 重要参考书 ├── BeginnersGuide-4thEd-Eng_v2.zip ├── Essentials_Games_v1.zip ├── Python Crash Course 2nd Edition-2019.pdf ├── Python GUI Programming Cookbook 2nd - 2017.pdf ├── Raspberry Pi User Guide 4th Edition.zip ├── Raspberry_Pi_Wikipedia.pdf ├── Retro Gaming with Raspberry Pi.zip ├── Sense Hat.zip ├── python3.10.4docs-pdf英文2022.4.zip ├── raspberrypi_cookbook_ed2_ed3_program.zip ├── socket-programming-in-python-cn.zip ├── 免责声明.txt └── 鸟哥的linux私房菜第四版.pdf /README.md: -------------------------------------------------------------------------------- 1 | # raspberry_tutorial 2 | 这本《树莓派编程实用教程》全书共31000字,提供20多个树莓派应用实例,都在入门到中级之间,非常适合想 3 | 在树莓派开发项目的工程师和学生参考学习,涵盖了Python,Linux命令,C/C++,OpenCV,Darknet。全部程序 4 | 在树莓派官方发布的32位Raspberry Pi OS(2021.10.30)系统调试通过,可运行在树莓派400个人电脑,4B或3B+上。以下是全书目录: 5 | 6 | 第一章 树莓派系统搭建 6 7 | 8 | 1.1 树莓派市场分析 6 9 | 10 | 1.1.1 树莓派成功的关键 6 11 | 12 | 1.1.2 树莓派的竞争者 7 13 | 14 | 1.1.3 购买树莓派的建议 9 15 | 16 | 1.2 系统安装及更新 11 17 | 18 | 1.2.1 最新Raspberry Pi OS系统下载及烧录 11 19 | 20 | 1.2.2 系统基本设置 16 21 | 22 | 1.2.3 系统更新 19 23 | 24 | 1.3 常用开发软件安装 22 25 | 26 | 1.3.1 树莓派SSH配置 22 27 | 28 | 1.3.2 树莓派的tty模式 24 29 | 30 | 1.3.3 WinSCP 25 31 | 32 | 1.3.4 安装Python解释器 26 33 | 34 | 1.4 树莓派的学习和使用 28 35 | 36 | 1.4.1 学习建议 28 37 | 38 | 1.4.2树莓派的用途 30 39 | 40 | 第二章 初探树莓派 32 41 | 42 | 2.1 测评例程及性能比较 32 43 | 44 | 2.2 使用Octane 2.0测评树莓派性能 34 45 | 46 | 2.3 Linux学习使用初步 35 47 | 48 | 第三章 海龟绘图 37 49 | 50 | 3.1 画雪花 37 51 | 52 | 3.2 画太极符号 38 53 | 54 | 第四章 开发游戏 40 55 | 56 | 4.1 简单RPG游戏 40 57 | 58 | 4.2 贪吃蛇游戏 42 59 | 60 | 4.3 3D迷宫游戏 43 61 | 62 | 4.4 倒霉的Fred游戏 48 63 | 64 | 第五章 数据传输 55 65 | 66 | 5.1 简单的通信协议 55 67 | 68 | 5.2 串口通信 55 69 | 70 | 5.3 网络通信 61 71 | 72 | 5.4 其他接口通信 62 73 | 74 | 5.5 树莓派用作无线路由器 62 75 | 76 | 第六章 Sense Hat应用 63 77 | 78 | 6.1 树莓派的硬件生态——Hat 63 79 | 80 | 6.2 Sense Hat介绍 64 81 | 82 | 6.3 Sense Hat交通灯 65 83 | 84 | 6.4 Sense Hat调色板 66 85 | 86 | 6.5 Sense Hat乒乓游戏 68 87 | 88 | 6.6 远程控制树莓派 71 89 | 90 | 第七章 Sense Hat传感器 76 91 | 92 | 7.1 显示板子方位 76 93 | 94 | 7.2 保存方位数据到文件 77 95 | 96 | 7.3 树莓派气象站 79 97 | 98 | 7.4 加速度检测仪 80 99 | 100 | 第八章 计算机视觉初步 85 101 | 102 | 8.1 摄像头监控 85 103 | 104 | 8.2 CMake及简要入门 86 105 | 106 | 8.3 OpenCV的安装、验证和学习建议 92 107 | 108 | 8.3.1 在树莓派安装OpenCV 92 109 | 110 | 8.3.2 验证OpenCV的安装 93 111 | 112 | 8.3.3 OpenCV的学习建议 95 113 | 114 | 8.4 使用darknet做物体检测 96 115 | 116 | 后记 101 117 | 118 | 参考文献 102 119 | 120 | 121 | 122 | 以下贴几张程序运行的美图,同时也是教程的一部分: 123 | 124 | ![image](https://github.com/wxlscm/raspberry_tutorial/blob/main/TutorialPrj/1.png) 125 | ![image](https://github.com/wxlscm/raspberry_tutorial/blob/main/TutorialPrj/2.png) 126 | ![image](https://github.com/wxlscm/raspberry_tutorial/blob/main/TutorialPrj/3.png) 127 | ![image](https://github.com/wxlscm/raspberry_tutorial/blob/main/TutorialPrj/4.png) 128 | ![image](https://github.com/wxlscm/raspberry_tutorial/blob/main/TutorialPrj/5.png) 129 | 130 | 还有darknet在树莓派上的移植,做物体检测呢: 131 | 132 | ![image](https://github.com/wxlscm/raspberry_tutorial/blob/main/TutorialPrj/6.png) 133 | 134 | 本人在书中都会详细解说程序,如下图所示: 135 | 136 | ![image](https://github.com/wxlscm/raspberry_tutorial/blob/main/TutorialPrj/7.png) 137 | 138 | 本人还教大家如何省钱买树莓派,选择了两款性价比最高的——树莓派400和PICO,可以省下几百块钱。 139 | 140 | ![image](https://github.com/wxlscm/raspberry_tutorial/blob/main/TutorialPrj/8.png) 141 | 142 | 全部资料简洁精炼,非常实用,全都是应用实例,很适合学习了一些python知识,急切想在树莓派上开发项目的 143 | 工程师或学生使用。看了本教程,实际上相当于看了不少于10本书,很值得下载看看。另外,本人是工程师, 144 | 希望能得到读者的反馈,如果你使用时出现兼容性问题,如:程序运行中出现错误,安装软件失败等问题,可以 145 | 通过下面的微信联系我,本人争取在1天内回复。 146 | 147 | ![image](https://github.com/wxlscm/raspberry_tutorial/blob/main/TutorialPrj/9.png) 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /TutorialPrj/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/1.png -------------------------------------------------------------------------------- /TutorialPrj/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/2.png -------------------------------------------------------------------------------- /TutorialPrj/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/3.png -------------------------------------------------------------------------------- /TutorialPrj/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/4.png -------------------------------------------------------------------------------- /TutorialPrj/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/5.png -------------------------------------------------------------------------------- /TutorialPrj/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/6.png -------------------------------------------------------------------------------- /TutorialPrj/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/7.png -------------------------------------------------------------------------------- /TutorialPrj/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/8.png -------------------------------------------------------------------------------- /TutorialPrj/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/9.png -------------------------------------------------------------------------------- /TutorialPrj/ch2_factorial_test.py: -------------------------------------------------------------------------------- 1 | import time 2 | def factorial(n): 3 | if n == 0: 4 | return 1 5 | else: 6 | return n * factorial(n-1) 7 | before_time = time.perf_counter() 8 | for i in range(1, 10000): 9 | factorial(200) 10 | after_time = time.perf_counter() 11 | print(after_time - before_time) 12 | -------------------------------------------------------------------------------- /TutorialPrj/ch3_Snowflake.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | import random 3 | pat = turtle.Turtle() 4 | turtle.Screen().bgcolor("grey") 5 | #turtle.speed(5) 6 | #turtle.Turtle().screen.delay(0) 7 | 8 | colours = ["cyan", "purple", "white", "blue"] 9 | 10 | 11 | 12 | pat.penup() 13 | pat.forward(90) 14 | pat.left(45) 15 | pat.pendown() 16 | 17 | def branch(): 18 | for i in range(3): 19 | for i in range(3): 20 | pat.forward(30) 21 | pat.backward(30) 22 | pat.right(45) 23 | pat.left(90) 24 | pat.backward(30) 25 | pat.left(45) 26 | pat.right(90) 27 | pat.forward(90) 28 | 29 | 30 | for i in range(8): 31 | branch() 32 | pat.left(45) 33 | 34 | 35 | -------------------------------------------------------------------------------- /TutorialPrj/ch3_yinyang.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ turtle-example-suite: 3 | 4 | tdemo_yinyang.py 5 | 6 | Another drawing suitable as a beginner's 7 | programming example. 8 | 9 | The small circles are drawn by the circle 10 | command. 11 | 12 | """ 13 | 14 | from turtle import * 15 | 16 | def yin(radius, color1, color2): 17 | width(3) 18 | color("black", color1) 19 | begin_fill() 20 | circle(radius/2., 180) 21 | circle(radius, 180) 22 | left(180) 23 | circle(-radius/2., 180) 24 | end_fill() 25 | left(90) 26 | up() #pen up 27 | forward(radius*0.35) 28 | right(90) 29 | down() 30 | color(color1, color2) #color2 is color of small circle 31 | begin_fill() 32 | circle(radius*0.15) 33 | end_fill() 34 | left(90) 35 | up() 36 | backward(radius*0.35) 37 | down() 38 | left(90) 39 | 40 | def main(): 41 | reset() 42 | # speed(0) 43 | # hideturtle() 44 | # getscreen().delay(0) 45 | # getscreen().tracer(0) 46 | yin(200, "black", "white") 47 | yin(200, "white", "black") 48 | ht() 49 | return "Done!" 50 | 51 | if __name__ == '__main__': 52 | main() 53 | mainloop() -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/My_amazeballs1.py: -------------------------------------------------------------------------------- 1 | import pygame,sys 2 | import pygame.event as GAME_EVENTS 3 | import pygame.locals as GAME_GLOBALS 4 | 5 | windowWidth = 800 6 | windowHeight = 700 7 | 8 | OFFSETX = 368 9 | OFFSETY = 250 10 | 11 | player = {"x":0, "y":3, "frame":0, "sx":0, "sy":0, 12 | "moveX":0, "moveY":0, "queueX":0, "queueY":0, 13 | "moveDone":True, "movingNow":False, "animCounter":0} 14 | 15 | mazeSolved = False 16 | 17 | mapData = [[1,1,1,0,1,1,1,1,1,1,1,1], #[1,1,1,0,1,1,1,1,1,1,1,1], 18 | [1,0,0,0,0,0,0,0,0,0,0,1], 19 | [1,1,1,1,1,1,1,0,1,1,1,1], 20 | [1,0,0,0,0,0,0,0,0,0,0,1], 21 | [1,1,1,1,1,1,1,1,0,0,0,1], 22 | [1,0,0,0,0,0,0,1,0,1,1,1], 23 | [1,0,1,0,1,1,0,1,0,0,0,1], 24 | [1,0,1,0,1,0,0,1,1,1,0,1], 25 | [1,0,1,0,1,0,0,0,0,0,0,1], 26 | [1,1,1,0,1,1,1,1,1,1,1,1], 27 | [1,0,0,0,0,0,0,0,0,0,0,1], 28 | [1,1,1,1,1,1,1,1,0,1,1,1]] 29 | mapInfo = {"width":12, "height":12} 30 | 31 | mapHeight = [0,32] 32 | 33 | BallImages=[] 34 | 35 | pygame.init() 36 | pygame.font.init() 37 | surface = pygame.display.set_mode((windowWidth, windowHeight) ) 38 | pygame.display.set_caption('3D Maze game part 1') 39 | textFont = pygame.font.SysFont("monospace", 25) 40 | title_image = pygame.image.load("images/title.png") 41 | map1c_image=pygame.image.load("images/map1c.png") 42 | map2c_image=pygame.image.load("images/map2c.png") 43 | for i in range(8): 44 | BallImages.append( pygame.image.load("images/ball%01d.png" % i) ) 45 | 46 | mapBlocks = [map1c_image, map2c_image] 47 | 48 | def draw(): # Pygame Zero draw function 49 | surface.fill((0, 0, 0)) 50 | drawMap() 51 | surface.blit(title_image, (200, 0)) 52 | if mazeSolved : 53 | renderedText = textFont.render("MAZE SOLVED!", 1, (0,255,0)) #1 54 | surface.blit(renderedText, (400, 310)) # 495, 430 55 | # surface.draw.text("MAZE SOLVED!" , center=(400, 300), owidth=0.5, 56 | # ocolor=(0,0,0), color=(0,255,0) , fontsize=60) 57 | 58 | def drawMap(): 59 | for x in range(0, 12): 60 | for y in range(0, 12): 61 | surface.blit(mapBlocks[mapData[x][y]], ((x*32)-(y*32)+OFFSETX, 62 | (y*16)+(x*16)+OFFSETY - mapHeight[mapData[x][y]])) 63 | if x == player["x"] and y == player["y"]: 64 | if player["sx"] == 0: 65 | player["sx"] = (x*32)-(y*32)+OFFSETX 66 | player["sy"] = (y*16)+(x*16)+OFFSETY-32 67 | surface.blit( BallImages[ player["frame"] ], 68 | (player["sx"], player["sy"])) 69 | 70 | def doMove(p, x, y): 71 | if 0 <= (p["x"]+x) < mapInfo["width"] and 0 <= (p["y"]+y) < mapInfo["height"]: 72 | if mapData[p["x"]+x][p["y"]+y] == 0: 73 | p.update({"queueX":x, "queueY":y, "moveDone":False}) 74 | 75 | def moveP(p,x,y): 76 | p["sx"] += x 77 | p["sy"] += y 78 | 79 | def quitGame(): 80 | pygame.quit() 81 | sys.exit() 82 | 83 | def updateBall(p): 84 | global mazeSolved 85 | if p["movingNow"]: 86 | if p["moveX"] == -1: moveP(p,-1,-0.5) 87 | if p["moveX"] == 1: moveP(p,1,0.5) 88 | if p["moveY"] == -1: moveP(p,1,-0.5) 89 | if p["moveY"] == 1: moveP(p,-1,0.5) 90 | p["animCounter"] += 1 91 | if p["animCounter"] == 4: 92 | p["animCounter"] = 0 93 | p["frame"] += 1 94 | if p["frame"] > 7: 95 | p["frame"] = 0 96 | if p["frame"] == 4: 97 | if p["moveDone"] == False: 98 | if p["queueX"] != 0 or p["queueY"] !=0: 99 | p.update({"moveX":p["queueX"], "moveY":p["queueY"], 100 | "queueX":0, "queueY":0, "movingNow": True}) 101 | else: 102 | p.update({"moveX":0, "moveY":0, "movingNow":False}) 103 | if p["x"] == 11 and p["y"] == 8: mazeSolved = True 104 | 105 | if p["frame"] == 7 and p["moveDone"] == False and p["movingNow"] == True: 106 | p["x"] += p["moveX"] 107 | p["y"] += p["moveY"] 108 | p["moveDone"] = True 109 | 110 | 111 | 112 | while True: 113 | draw() 114 | for event in GAME_EVENTS.get(): 115 | if event.type == pygame.KEYDOWN: 116 | if event.key == pygame.K_ESCAPE: 117 | quitGame() 118 | elif event.key == pygame.K_LEFT: 119 | doMove(player, -1, 0) 120 | elif event.key == pygame.K_RIGHT: 121 | doMove(player, 1, 0) 122 | elif event.key == pygame.K_UP: 123 | doMove(player, 0, -1) 124 | elif event.key == pygame.K_DOWN: 125 | doMove(player, 0, 1) 126 | updateBall(player) 127 | pygame.display.update() 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/amazeballs1.py: -------------------------------------------------------------------------------- 1 | import pgzrun 2 | 3 | player = {"x":0, "y":3, "frame":0, "sx":0, "sy":0, 4 | "moveX":0, "moveY":0, "queueX":0, "queueY":0, 5 | "moveDone":True, "movingNow":False, "animCounter":0} 6 | OFFSETX = 368 7 | OFFSETY = 200 8 | 9 | mapData = [[1,1,1,0,1,1,1,1,1,1,1,1], 10 | [1,0,0,0,0,0,0,0,0,0,0,1], 11 | [1,1,1,1,1,1,1,0,1,1,1,1], 12 | [1,0,0,0,0,0,0,0,0,0,0,1], 13 | [1,1,1,1,1,1,1,1,0,0,0,1], 14 | [1,0,0,0,0,0,0,1,0,1,1,1], 15 | [1,0,1,0,1,1,0,1,0,0,0,1], 16 | [1,0,1,0,1,0,0,1,1,1,0,1], 17 | [1,0,1,0,1,0,0,0,0,0,0,1], 18 | [1,1,1,0,1,1,1,1,1,1,1,1], 19 | [1,0,0,0,0,0,0,0,0,0,0,1], 20 | [1,1,1,1,1,1,1,1,0,1,1,1]] 21 | mapInfo = {"width":12, "height":12} 22 | mapBlocks = ["map1c","map2c"] 23 | 24 | mapHeight = [0,32] 25 | mazeSolved = False 26 | 27 | def draw(): # Pygame Zero draw function 28 | screen.fill((0, 0, 0)) 29 | drawMap() 30 | screen.blit('title', (200, 0)) 31 | if mazeSolved : 32 | screen.draw.text("MAZE SOLVED!" , center=(400, 300), owidth=0.5, ocolor=(0,0,0), color=(0,255,0) , fontsize=60) 33 | 34 | def update(): # Pygame Zero update function 35 | global player 36 | if player["moveDone"] == True: 37 | if keyboard.left: doMove(player, -1, 0) 38 | if keyboard.right: doMove(player, 1, 0) 39 | if keyboard.up: doMove(player, 0, -1) 40 | if keyboard.down: doMove(player, 0, 1) 41 | updateBall(player) 42 | 43 | def drawMap(): 44 | for x in range(0, 12): 45 | for y in range(0, 12): 46 | screen.blit(mapBlocks[mapData[x][y]], ((x*32)-(y*32)+OFFSETX, 47 | (y*16)+(x*16)+OFFSETY - mapHeight[mapData[x][y]])) 48 | if x == player["x"] and y == player["y"]: 49 | if player["sx"] == 0: 50 | player["sx"] = (x*32)-(y*32)+OFFSETX 51 | player["sy"] = (y*16)+(x*16)+OFFSETY-32 52 | screen.blit("ball"+str(player["frame"]), (player["sx"], player["sy"])) 53 | 54 | def doMove(p, x, y): 55 | if 0 <= (p["x"]+x) < mapInfo["width"] and 0 <= (p["y"]+y) < mapInfo["height"]: 56 | if mapData[p["x"]+x][p["y"]+y] == 0: 57 | p.update({"queueX":x, "queueY":y, "moveDone":False}) 58 | 59 | def updateBall(p): 60 | global mazeSolved 61 | if p["movingNow"]: 62 | if p["moveX"] == -1: moveP(p,-1,-0.5) 63 | if p["moveX"] == 1: moveP(p,1,0.5) 64 | if p["moveY"] == -1: moveP(p,1,-0.5) 65 | if p["moveY"] == 1: moveP(p,-1,0.5) 66 | p["animCounter"] += 1 67 | if p["animCounter"] == 4: 68 | p["animCounter"] = 0 69 | p["frame"] += 1 70 | if p["frame"] > 7: 71 | p["frame"] = 0 72 | if p["frame"] == 4: 73 | if p["moveDone"] == False: 74 | if p["queueX"] != 0 or p["queueY"] !=0: 75 | p.update({"moveX":p["queueX"], "moveY":p["queueY"], 76 | "queueX":0, "queueY":0, "movingNow": True}) 77 | else: 78 | p.update({"moveX":0, "moveY":0, "movingNow":False}) 79 | if p["x"] == 11 and p["y"] == 8: mazeSolved = True 80 | 81 | if p["frame"] == 7 and p["moveDone"] == False and p["movingNow"] == True: 82 | p["x"] += p["moveX"] 83 | p["y"] += p["moveY"] 84 | p["moveDone"] = True 85 | 86 | def moveP(p,x,y): 87 | p["sx"] += x 88 | p["sy"] += y 89 | 90 | pgzrun.go() 91 | -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/ball0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/ball0.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/ball1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/ball1.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/ball2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/ball2.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/ball3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/ball3.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/ball4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/ball4.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/ball5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/ball5.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/ball6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/ball6.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/ball7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/ball7.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/map1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/map1.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/map1a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/map1a.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/map1b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/map1b.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/map1c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/map1c.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/map2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/map2.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/map2a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/map2a.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/map2b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/map2b.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/map2c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/map2c.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/map3c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/map3c.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_AmazeBalls_1/images/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_AmazeBalls_1/images/title.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_freds_bad_day/assets/Barrel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_freds_bad_day/assets/Barrel.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_freds_bad_day/assets/Barrel_break.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_freds_bad_day/assets/Barrel_break.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_freds_bad_day/assets/Fred-Left-Hit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_freds_bad_day/assets/Fred-Left-Hit.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_freds_bad_day/assets/Fred-Left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_freds_bad_day/assets/Fred-Left.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_freds_bad_day/assets/Fred-Right-Hit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_freds_bad_day/assets/Fred-Right-Hit.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_freds_bad_day/assets/Fred-Right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_freds_bad_day/assets/Fred-Right.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_freds_bad_day/assets/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_freds_bad_day/assets/background.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_freds_bad_day/assets/gameover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_freds_bad_day/assets/gameover.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_freds_bad_day/assets/startgame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch4_freds_bad_day/assets/startgame.png -------------------------------------------------------------------------------- /TutorialPrj/ch4_freds_bad_day/freds_bad_day.py: -------------------------------------------------------------------------------- 1 | import pygame, sys, random, math 2 | import pygame.locals as GAME_GLOBALS 3 | import pygame.event as GAME_EVENTS 4 | import pygame.time as GAME_TIME 5 | import objects 6 | 7 | windowWidth = 1000 8 | windowHeight = 768 9 | 10 | pygame.init() 11 | pygame.font.init() 12 | clock = pygame.time.Clock() 13 | surface = pygame.display.set_mode((windowWidth, windowHeight) ) #pygame.FULLSCREEN 14 | 15 | pygame.display.set_caption('Fred\'s Bad Day') 16 | textFont = pygame.font.SysFont("monospace", 25) 17 | 18 | gameStarted = False 19 | gameOver = False 20 | gameStartedTime = 0 21 | gameFinishedTime = 0 22 | 23 | startScreen = pygame.image.load("assets/startgame.png") 24 | endScreen = pygame.image.load("assets/gameover.png") 25 | background = pygame.image.load("assets/background.png") 26 | Barrels = [] 27 | lastBarrel = 0 28 | lastBarrelSlot = 0 29 | barrelInterval = 1500 30 | 31 | goLeft = False 32 | goRight = False 33 | 34 | def quitGame(): 35 | pygame.quit() 36 | sys.exit() 37 | 38 | def newBarrel(): 39 | global Barrels, lastBarrel, lastBarrelSlot 40 | 41 | slot = random.randint(0, 12) #包括12 42 | 43 | while slot == lastBarrelSlot: 44 | slot = random.randint(0, 12) 45 | 46 | theBarrel = objects.Barrel(slot) 47 | theBarrel.loadImages(pygame) 48 | 49 | Barrels.append(theBarrel) 50 | lastBarrel = GAME_TIME.get_ticks() 51 | lastBarrelSlot = slot 52 | 53 | Fred = objects.Fred(windowWidth / 2) 54 | Fred.loadImages(pygame) 55 | 56 | # 'main' loop 57 | while True: 58 | timeTick = GAME_TIME.get_ticks() 59 | if gameStarted is True and gameOver is False: 60 | surface.blit(background, (0, 0)) 61 | Fred.draw(surface, timeTick) 62 | barrelsToRemove = [] 63 | for idx, barrel in enumerate(Barrels): 64 | barrel.move(windowHeight) 65 | barrel.draw(surface, pygame) 66 | 67 | if barrel.isBroken is False: 68 | 69 | hasCollided = barrel.checkForCollision(Fred) 70 | 71 | if hasCollided is True: 72 | barrel.split(timeTick) 73 | Fred.isHit = True 74 | Fred.timeHit = timeTick 75 | if Fred.health >= 10: 76 | Fred.health -= 10 77 | else : 78 | gameOver = True 79 | gameFinishedTime = timeTick 80 | # elif timeTick - barrel.timeBroken > 1000: 81 | # barrelsToRemove.append(idx) 82 | # continue 83 | if barrel.needsRemoving is True: 84 | barrelsToRemove.append(idx) 85 | continue 86 | #(175,59,59) 画生命条 87 | pygame.draw.rect(surface, (175,59,59), 88 | (0, windowHeight - 10, (windowWidth / 100) * Fred.health , 10)) 89 | 90 | for index in barrelsToRemove: 91 | del Barrels[index] 92 | 93 | if goLeft is True: 94 | Fred.moveLeft(0) 95 | if goRight is True: 96 | Fred.moveRight(windowWidth) 97 | 98 | elif gameStarted is False and gameOver is False: 99 | surface.blit(startScreen, (0, 0)) 100 | 101 | elif gameStarted is True and gameOver is True: 102 | surface.blit(endScreen, (0, 0)) 103 | timeLasted = (gameFinishedTime - gameStartedTime) / 1000 104 | 105 | if timeLasted < 10: 106 | timeLasted = "0" + str(timeLasted) 107 | else : 108 | timeLasted = str(timeLasted) 109 | renderedText = textFont.render(timeLasted, 1, (175,59,59)) #1 110 | surface.blit(renderedText, (495, 442)) # 495, 430 111 | 112 | # Handle user and system events 113 | for event in GAME_EVENTS.get(): 114 | if event.type == pygame.KEYDOWN: 115 | if event.key == pygame.K_ESCAPE: 116 | quitGame() 117 | elif event.key == pygame.K_LEFT: 118 | goLeft = True 119 | goRight = False 120 | elif event.key == pygame.K_RIGHT: 121 | goLeft = False 122 | goRight = True 123 | elif event.key == pygame.K_RETURN: 124 | if gameStarted is False and gameOver is False: 125 | gameStarted = True 126 | gameStartedTime = timeTick 127 | elif gameStarted is True and gameOver is True: 128 | Fred.reset(windowWidth / 2) 129 | Barrels = [] 130 | barrelInterval = 1500 131 | gameOver = False 132 | if event.type == pygame.KEYUP: 133 | if event.key == pygame.K_LEFT: 134 | goLeft = False 135 | if event.key == pygame.K_RIGHT: 136 | goRight = False 137 | if event.type == GAME_GLOBALS.QUIT: 138 | quitGame() 139 | 140 | clock.tick(60) #60 每秒60次 141 | pygame.display.update() 142 | if GAME_TIME.get_ticks() - lastBarrel > barrelInterval and gameStarted is True: 143 | newBarrel() 144 | if barrelInterval > 150: 145 | barrelInterval -= 50 146 | -------------------------------------------------------------------------------- /TutorialPrj/ch4_freds_bad_day/objects.py: -------------------------------------------------------------------------------- 1 | class Fred(): 2 | 3 | x = 0 4 | y = 625 5 | 6 | isHit = False 7 | timeHit = 0 8 | health = 100 9 | 10 | leftImage = None 11 | rightImage = None 12 | leftImageHit = None 13 | rightImageHit = None 14 | 15 | direction = 1 16 | speed = 8 17 | #pygame = None 18 | 19 | def reset(self, x): 20 | self.x = x 21 | self.y = 625 22 | 23 | self.isHit = False 24 | self.timeHit = 0 25 | self.health = 100 26 | 27 | self.direction = 1 28 | self.speed = 8 29 | # self.pygame = None 30 | 31 | def moveLeft(self, leftBound): 32 | 33 | if self.direction is not 0: 34 | self.direction = 0 35 | 36 | if((self.x - self.speed) > leftBound): 37 | self.x -= self.speed 38 | 39 | def moveRight(self, rightBound): 40 | 41 | if self.direction is not 1: 42 | self.direction = 1 43 | 44 | if((self.x + self.speed) + 58 < rightBound): 45 | self.x += self.speed 46 | 47 | def loadImages(self, pygame): 48 | self.leftImage = pygame.image.load("assets/Fred-Left.png") 49 | self.rightImage = pygame.image.load("assets/Fred-Right.png") 50 | self.leftImageHit = pygame.image.load("assets/Fred-Left-Hit.png") 51 | self.rightImageHit = pygame.image.load("assets/Fred-Right-Hit.png") 52 | 53 | def draw(self, surface, time): 54 | 55 | if time - self.timeHit > 800: #判定炮管是否碰上Fred 56 | self.timeHit = 0 57 | self.isHit = False 58 | 59 | if self.direction is 1: #朝向右邊 60 | if self.isHit is False: 61 | surface.blit(self.rightImage, (self.x, self.y)) 62 | else : 63 | surface.blit(self.rightImageHit, (self.x, self.y)) 64 | else : 65 | if self.isHit is False: 66 | surface.blit(self.leftImage, (self.x, self.y)) 67 | else : 68 | surface.blit(self.leftImageHit, (self.x, self.y)) 69 | 70 | def __init__(self, x): 71 | self.x = x 72 | 73 | class Barrel(): 74 | 75 | slots = [(4, 103), (82, 27), 76 | (157, 104), (234, 27), 77 | (310, 104), (388, 27), 78 | (463, 104), (539, 27), 79 | (615, 104), (691, 27), 80 | (768, 104), (845, 27), 81 | (920, 104)] 82 | slot = 0 83 | x = 0 84 | y = 0 85 | image = None 86 | brokenImage = None 87 | isBroken = False 88 | timeBroken = 0 89 | needsRemoving = False 90 | # size = [33,22] 91 | # ratio = 0.66 92 | vy = 1.5 93 | gravity = 1.05 94 | maxY = 20 95 | 96 | def split(self, time): 97 | self.isBroken = True 98 | self.timeBroken = time 99 | self.vy = 5 100 | self.x -= 10 101 | 102 | def checkForCollision(self, fred): 103 | 104 | hitX = False 105 | hitY = False 106 | if fred.x > self.x and fred.x < self.x + 75: #炮管砸在Fred的左边 107 | hitX = True 108 | elif fred.x + 57 > self.x and fred.x + 57 < self.x + 75: #炮管砸在Fred的右边 109 | hitX = True 110 | if fred.y + 120 > self.y and fred.y < self.y: 111 | hitY = True 112 | elif fred.y < self.y + 48: 113 | hitY = True 114 | if hitX is True and hitY is True: 115 | return True 116 | 117 | def loadImages(self, pygame): 118 | self.image = pygame.image.load("assets/Barrel.png") 119 | self.brokenImage = pygame.image.load("assets/Barrel_break.png") 120 | 121 | def move(self, windowHeight): 122 | 123 | if self.vy < self.maxY: 124 | self.vy = self.vy * self.gravity 125 | self.y += self.vy 126 | 127 | if self.y > windowHeight: 128 | self.needsRemoving = True 129 | 130 | def draw(self, surface, pygame): 131 | if self.isBroken is True: 132 | surface.blit(self.brokenImage, (self.x, self.y)) 133 | else : 134 | surface.blit(self.image, (self.x, self.y)) 135 | 136 | def __init__(self, slot): 137 | self.slot = slot 138 | self.x = self.slots[slot][0] 139 | self.y = self.slots[slot][1] + 24 140 | -------------------------------------------------------------------------------- /TutorialPrj/ch4_rpg.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | 3 | # Replace RPG starter project with this code when new instructions are live 4 | 5 | def showInstructions(): 6 | #print a main menu and the commands 7 | print(''' 8 | RPG Game 9 | ======== 10 | Get to the Garden with a key and a potion 11 | Avoid the monsters! 12 | 13 | Commands: 14 | go [direction] 15 | get [item] 16 | ''') 17 | 18 | def showStatus(): 19 | #print the player's current status 20 | print('---------------------------') 21 | print('You are in the ' + currentRoom) 22 | #print the current inventory 23 | print('Inventory : ' + str(inventory)) 24 | #print an item if there is one 25 | if "item" in rooms[currentRoom]: 26 | print('You see a ' + rooms[currentRoom]['item']) 27 | print("---------------------------") 28 | 29 | #an inventory, which is initially empty 30 | inventory = [] 31 | 32 | #a dictionary linking a room to other rooms 33 | rooms = { 34 | 'Hall' : { 35 | 'south' : 'Kitchen', 36 | 'east' : 'Dining Room', 37 | 'item' : 'key' 38 | }, 39 | 'Kitchen' : { 40 | 'north' : 'Hall', 41 | 'item' : 'monster' 42 | }, 43 | 'Dining Room' : { 44 | 'west' : 'Hall', 45 | 'south' : 'Garden', 46 | 'item' : 'potion' 47 | }, 48 | 'Garden' : { 49 | 'north' : 'Dining Room' 50 | } 51 | } 52 | 53 | #start the player in the Hall 54 | currentRoom = 'Hall' 55 | showInstructions() 56 | 57 | #loop forever 58 | while True: 59 | 60 | showStatus() 61 | #get the player's next 'move' 62 | #.split() breaks it up into an list array 63 | #eg typing 'go east' would give the list: 64 | #['go','east'] 65 | move = '' 66 | while move == '': 67 | move = input('>') 68 | 69 | move = move.lower().split() 70 | 71 | #if they type 'go' first 72 | if move[0] == 'go': 73 | #check that they are allowed wherever they want to go 74 | if move[1] in rooms[currentRoom]: 75 | #set the current room to the new room 76 | currentRoom = rooms[currentRoom][move[1]] 77 | #there is no door (link) to the new room 78 | else: 79 | print('You can\'t go that way!') 80 | 81 | #if they type 'get' first 82 | if move[0] == 'get' : 83 | #if the room contains an item, and the item is the one they want to get 84 | if "item" in rooms[currentRoom] and move[1] in rooms[currentRoom]['item']: 85 | #add the item to their inventory 86 | inventory += [move[1]] 87 | #display a helpful message 88 | print(move[1] + ' got!') 89 | #delete the item from the room 90 | del rooms[currentRoom]['item'] 91 | #otherwise, if the item isn't there to get 92 | else: 93 | #tell them they can't get it 94 | print('Can\'t get ' + move[1] + '!') 95 | 96 | # player loses if they enter a room with a monster 97 | if 'item' in rooms[currentRoom] and 'monster' in rooms[currentRoom]['item']: 98 | print('A monster has got you... GAME OVER!') 99 | break 100 | # inindentation is very important!! wx 101 | # player wins if they get to the garden with a key and a potion 102 | if currentRoom == 'Garden' and 'key' in inventory and 'potion' in inventory: 103 | print('You escaped the house... YOU WIN!') 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /TutorialPrj/ch4_snake.py: -------------------------------------------------------------------------------- 1 | import pygame, sys, time, random 2 | from pygame.locals import * 3 | pygame.init() 4 | fpsClock = pygame.time.Clock() 5 | playSurface = pygame.display.set_mode((640, 480)) 6 | pygame.display.set_caption('Raspberry Snake') 7 | 8 | redColour = pygame.Color(255, 0, 0) 9 | blackColour = pygame.Color(0, 0, 0) 10 | whiteColour = pygame.Color(255, 255, 255) 11 | greyColour = pygame.Color(150, 150, 150) 12 | 13 | snakePosition = [100,100] #x,y position 14 | snakeSegments = [[100,100],[80,100],[60,100]] 15 | raspberryPosition = [300,300] 16 | raspberrySpawned = 1 17 | direction = 'right' 18 | changeDirection = direction 19 | 20 | def gameOver(): 21 | gameOverFont = pygame.font.Font('freesansbold.ttf', 72) 22 | gameOverSurf = gameOverFont.render('Game Over', True, greyColour) 23 | gameOverRect = gameOverSurf.get_rect() 24 | gameOverRect.midtop = (320, 10) 25 | playSurface.blit(gameOverSurf, gameOverRect) 26 | pygame.display.flip() 27 | time.sleep(5) 28 | pygame.quit() 29 | sys.exit() 30 | 31 | while True: 32 | for event in pygame.event.get(): 33 | if event.type == QUIT: 34 | pygame.quit() 35 | sys.exit() 36 | elif event.type == KEYDOWN: 37 | if event.key == K_RIGHT or event.key == ord('d'): 38 | changeDirection = 'right' 39 | if event.key == K_LEFT or event.key == ord('a'): 40 | changeDirection = 'left' 41 | if event.key == K_UP or event.key == ord('w'): 42 | changeDirection = 'up' 43 | if event.key == K_DOWN or event.key == ord('s'): 44 | changeDirection = 'down' 45 | if event.key == K_ESCAPE: 46 | pygame.event.post(pygame.event.Event(QUIT)) 47 | if changeDirection == 'right' and not direction == 'left': 48 | direction = changeDirection 49 | if changeDirection == 'left' and not direction == 'right': 50 | direction = changeDirection 51 | if changeDirection == 'up' and not direction == 'down': 52 | direction = changeDirection 53 | if changeDirection == 'down' and not direction == 'up': 54 | direction = changeDirection 55 | if direction == 'right': 56 | snakePosition[0] += 20 57 | if direction == 'left': 58 | snakePosition[0] -= 20 59 | if direction == 'up': 60 | snakePosition[1] -= 20 61 | if direction == 'down': 62 | snakePosition[1] += 20 63 | snakeSegments.insert(0,list(snakePosition)) 64 | if snakePosition[0] == raspberryPosition[0] and \ 65 | snakePosition[1] == raspberryPosition[1]: 66 | raspberrySpawned = 0 67 | else: 68 | snakeSegments.pop() 69 | if raspberrySpawned == 0: 70 | x = random.randrange(1,32) 71 | y = random.randrange(1,24) 72 | raspberryPosition = [x*20,y*20] 73 | raspberrySpawned = 1 74 | playSurface.fill(blackColour) 75 | for position in snakeSegments: 76 | pygame.draw.rect(playSurface,whiteColour,Rect(position[0], position[1], 20, 20) ) 77 | pygame.draw.rect(playSurface,redColour,Rect(raspberryPosition[0], \ 78 | raspberryPosition[1], 20, 20)) 79 | pygame.display.flip() 80 | if snakePosition[0] > 620 or snakePosition[0] < 0: 81 | gameOver() 82 | if snakePosition[1] > 460 or snakePosition[1] < 0: 83 | gameOver() 84 | for snakeBody in snakeSegments[1:]: 85 | if snakePosition[0] == snakeBody[0] and snakePosition[1] == snakeBody[1]: 86 | gameOver() 87 | fpsClock.tick(10) 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /TutorialPrj/ch5_serial/serialPC.py: -------------------------------------------------------------------------------- 1 | import serial 2 | import sys 3 | sendBuf=b'\xA0\x03\x01\x72\xE0' 4 | ser=serial.Serial('COM5',115200) 5 | 6 | while True: 7 | try: 8 | recvBuf=bytearray(b'') 9 | if not ser.is_open: 10 | ser.open() 11 | while(input("Please input 'version' to send:")!='version' ): 12 | pass 13 | ser.write(sendBuf) 14 | recvBuf+=ser.read(size=2) 15 | if recvBuf[0]==0xA0 : 16 | recvBuf+=ser.read(size=recvBuf[1]) 17 | if recvBuf[recvBuf[1]+1]==0xE0 and recvBuf[3]==0x72: 18 | print("Firmware version is ", repr(recvBuf[4]),".", 19 | repr(recvBuf[5]) ) 20 | except KeyboardInterrupt: 21 | print("caught keyboard interrupt, exiting") 22 | sys.exit(1) 23 | finally: 24 | print("exit finally") 25 | ser.close() -------------------------------------------------------------------------------- /TutorialPrj/ch5_serial/serialRAS.py: -------------------------------------------------------------------------------- 1 | import serial 2 | import sys 3 | 4 | recvBuf=b'' 5 | recvBufindex=0 6 | sendBuf=b'\xA0\x05\x01\x72\x01\x00\xE0' 7 | ser=serial.Serial('/dev/ttyS0',115200) 8 | 9 | 10 | while True: 11 | try: 12 | if not ser.is_open: 13 | ser.open() 14 | recvBufindex=0 15 | recvBuf+=ser.read(size=2) 16 | recvBufindex+=2 17 | if recvBuf[0]==0xA0 : 18 | recvBuf+=ser.read(size=recvBuf[1]) 19 | recvBufindex=0 20 | if recvBuf[recvBuf[1]+1]==0xE0 and recvBuf[3]==0x72: 21 | print("received firmware version command!") 22 | ser.write(sendBuf) 23 | except KeyboardInterrupt: 24 | print("caught keyboard interrupt") 25 | sys.exit(1) 26 | finally: 27 | print("exit finally") 28 | ser.close() 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /TutorialPrj/ch5_socket/multiconn-clientM.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import socket 5 | import selectors 6 | import types 7 | 8 | sel = selectors.DefaultSelector() 9 | sendBuf=b'\xA0\x03\x01\x72\xE0' 10 | RecvBuf=[] 11 | sendFlag=False 12 | 13 | def start_connections(host, port): 14 | server_addr = (host, port) 15 | print("starting connection to ", server_addr) 16 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 17 | sock.setblocking(False) 18 | sock.connect_ex(server_addr) 19 | events = selectors.EVENT_READ | selectors.EVENT_WRITE 20 | data = types.SimpleNamespace( 21 | outb=b"", 22 | ) 23 | sel.register(sock, events,data=data) 24 | 25 | 26 | def service_connection(key, mask): 27 | 28 | sock = key.fileobj 29 | data = key.data 30 | if mask & selectors.EVENT_READ: 31 | recv_data = sock.recv(1024) # Should be ready to read 32 | if recv_data: 33 | print("received", repr(recv_data) ) 34 | if recv_data[0]==0xA0 and recv_data[recv_data[1]+1]==0xE0 and recv_data[3]==0x72: 35 | print("Firmware version is ", repr(recv_data[4]),".", repr(recv_data[5]) ) 36 | print("closing connection") 37 | sel.unregister(sock) 38 | sock.close() 39 | 40 | elif not recv_data: 41 | print("closing connection") 42 | sel.unregister(sock) 43 | sock.close() 44 | if mask & selectors.EVENT_WRITE: 45 | global sendFlag 46 | if sendFlag==True: 47 | data.outb = sendBuf 48 | print("sending", repr(data.outb), "to connection", host, port) 49 | sent = sock.send(data.outb) # Should be ready to write 50 | sendFlag=False 51 | 52 | 53 | if len(sys.argv) != 3: 54 | print("usage:", sys.argv[0], " ") 55 | sys.exit(1) 56 | 57 | host, port = sys.argv[1:3] 58 | 59 | 60 | while True: 61 | try: 62 | while(input("Please input 'version' to send:")!='version' ): 63 | pass 64 | start_connections(host, int(port)) 65 | sendFlag=True 66 | while True: 67 | events = sel.select(timeout=1) 68 | if events: 69 | for key, mask in events: 70 | service_connection(key, mask) 71 | # Check for a socket being monitored to continue. 72 | if not sel.get_map(): 73 | break 74 | except KeyboardInterrupt: 75 | print("caught keyboard interrupt, exiting") 76 | sys.exit(1) 77 | finally: 78 | sel.close() 79 | -------------------------------------------------------------------------------- /TutorialPrj/ch5_socket/multiconn-serverM.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import socket 5 | import selectors 6 | import types 7 | 8 | sel = selectors.DefaultSelector() 9 | sendBuf=b'\xA0\x05\x01\x72\x01\x00\xE0' 10 | RecvBuf=[] 11 | 12 | def accept_wrapper(sock): 13 | conn, addr = sock.accept() # Should be ready to read 14 | print("accepted connection from", addr) 15 | conn.setblocking(False) 16 | data = types.SimpleNamespace(addr=addr, inb=b"", outb=b"") 17 | events = selectors.EVENT_READ | selectors.EVENT_WRITE 18 | sel.register(conn, events, data=data) 19 | 20 | 21 | def service_connection(key, mask): 22 | sock = key.fileobj 23 | data = key.data 24 | if mask & selectors.EVENT_READ: 25 | recv_data = sock.recv(1024) # Should be ready to read 26 | if recv_data: 27 | if recv_data[0]==0xA0 and recv_data[recv_data[1]+1]==0xE0 and recv_data[3]==0x72: 28 | print("received firmware version command!") 29 | data.outb=sendBuf 30 | else: 31 | print("closing connection to", data.addr) 32 | sel.unregister(sock) 33 | sock.close() 34 | if mask & selectors.EVENT_WRITE: 35 | if data.outb: 36 | print("sending", repr(data.outb), "to", data.addr) 37 | sent = sock.send(data.outb) # Should be ready to write 38 | data.outb=b""; 39 | 40 | 41 | if len(sys.argv) != 3: 42 | print("usage:", sys.argv[0], " ") 43 | sys.exit(1) 44 | 45 | host, port = sys.argv[1], int(sys.argv[2]) 46 | lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 47 | lsock.bind((host, port)) 48 | lsock.listen() 49 | print("listening on", (host, port)) 50 | lsock.setblocking(False) 51 | sel.register(lsock, selectors.EVENT_READ, data=None) 52 | 53 | try: 54 | while True: 55 | events = sel.select(timeout=None) 56 | for key, mask in events: 57 | if key.data is None: 58 | accept_wrapper(key.fileobj) 59 | else: 60 | service_connection(key, mask) 61 | except KeyboardInterrupt: 62 | print("caught keyboard interrupt, exiting") 63 | finally: 64 | sel.close() 65 | -------------------------------------------------------------------------------- /TutorialPrj/ch6_pongGame.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | from time import sleep 3 | from sense_hat import SenseHat 4 | 5 | sense = SenseHat() 6 | 7 | #set bat position, random ball position, and velocity 8 | y = 4 9 | ball_position = [int(randint(2,6)), int(randint(1,6))] 10 | ball_velocity = [1, 1] 11 | 12 | #red color 13 | X = [255, 0, 0] 14 | #no color 15 | N = [0, 0, 0] 16 | 17 | #sad face array 18 | sad_face = [ 19 | N, N, X, X, X, X, N, N, 20 | N, X, N, N, N, N, X, N, 21 | X, N, X, N, N, X, N, X, 22 | X, N, N, X, N, N, N, X, 23 | X, N, N, X, N, N, N, X, 24 | X, N, X, N, N, X, N, X, 25 | N, X, N, N, N, N, X, N, 26 | N, N, X, X, X, X, N, N 27 | ] 28 | 29 | #draws bat at y position 30 | def draw_bat(): 31 | sense.set_pixel(0, y, 0, 255, 0) 32 | sense.set_pixel(0, y+1, 0, 255, 0) 33 | sense.set_pixel(0, y+2, 0, 255, 0) 34 | sense.set_pixel(0, y-1, 0, 255, 0) 35 | 36 | #move bat up 37 | def move_up(event): 38 | global y 39 | if y > 1 and (event.action=='pressed' or event.action=='held'): 40 | y -= 1 41 | 42 | #move bat down 43 | def move_down(event): 44 | global y 45 | if y < 5 and (event.action=='pressed' or event.action=='held'): 46 | y += 1 47 | 48 | #when joystick moves up or down, trigger corresponding function 49 | sense.stick.direction_up = move_up 50 | sense.stick.direction_down = move_down 51 | 52 | #move ball to the next position 53 | def draw_ball(): 54 | #ball displayed on current position 55 | sense.set_pixel(ball_position[0], ball_position[1], 75, 0, 255) 56 | #next ball position 57 | ball_position[0] += ball_velocity[0] 58 | ball_position[1] += ball_velocity[1] 59 | #if ball hits ceiling, calculate next position 60 | if ball_position[0] == 7: 61 | ball_velocity[0] = -ball_velocity[0] 62 | #if ball hits wall, calculate next position 63 | if ball_position[1] == 0 or ball_position[1] == 7: 64 | ball_velocity[1] = -ball_velocity[1] 65 | #if ball reaches 0 position, player loses and quits game 66 | if ball_position[0] == 0: 67 | sleep(0.25) 68 | sense.set_pixels(sad_face) 69 | quit() 70 | #if ball hits bat, calculate next ball position 71 | if ball_position[0] == 1 and y - 1 <= ball_position[1] <= y+2: 72 | ball_velocity[0] = -ball_velocity[0] 73 | 74 | #run the game 75 | while True: 76 | sense.clear() 77 | draw_bat() 78 | draw_ball() 79 | sleep(0.25) 80 | -------------------------------------------------------------------------------- /TutorialPrj/ch6_senHatSliderRGB.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from sense_hat import SenseHat 3 | from time import sleep 4 | 5 | sense = SenseHat() 6 | 7 | redValue=0 8 | greenValue=0 9 | blueValue=0 10 | 11 | class App: 12 | 13 | def __init__(self, master): 14 | frame = Frame(master) 15 | frame.pack() 16 | Label(frame, text='Red').grid(row=0, column=0) 17 | Label(frame, text='Green').grid(row=1, column=0) 18 | Label(frame, text='Blue').grid(row=2, column=0) 19 | scaleRed = Scale(frame, from_=0, to=255, 20 | orient=HORIZONTAL, command=self.updateRed) 21 | scaleRed.grid(row=0, column=1) 22 | scaleGreen = Scale(frame, from_=0, to=255, 23 | orient=HORIZONTAL, command=self.updateGreen) 24 | scaleGreen.grid(row=1, column=1) 25 | scaleBlue = Scale(frame, from_=0, to=255, 26 | orient=HORIZONTAL, command=self.updateBlue) 27 | scaleBlue.grid(row=2, column=1) 28 | 29 | 30 | def updateRed(self, duty): 31 | global redValue 32 | global greenValue 33 | global blueValue 34 | redValue=duty 35 | sense.clear(int(redValue), int(greenValue), int(blueValue) ) 36 | 37 | def updateGreen(self, duty): 38 | global redValue 39 | global greenValue 40 | global blueValue 41 | greenValue=duty 42 | sense.clear(int(redValue), int(greenValue), int(blueValue) ) 43 | 44 | def updateBlue(self, duty): 45 | global redValue 46 | global greenValue 47 | global blueValue 48 | blueValue=duty 49 | sense.clear(int(redValue), int(greenValue), int(blueValue) ) 50 | 51 | root = Tk() 52 | root.wm_title('Sense Hat RGB Control') 53 | app = App(root) 54 | root.geometry("200x150+0+0") 55 | root.mainloop() -------------------------------------------------------------------------------- /TutorialPrj/ch6_senHatTraffic.py: -------------------------------------------------------------------------------- 1 | from sense_hat import SenseHat 2 | from time import sleep 3 | 4 | upPushed=0 5 | sense = SenseHat() 6 | sense.clear() 7 | 8 | 9 | def processUp(event): 10 | global upPushed 11 | if event.direction=="up" and event.action=="pressed" : 12 | print("UP press event!") 13 | upPushed=1 14 | # elif event.direction=="up" and event.action=="held" : 15 | # print("UP held event!") 16 | 17 | 18 | 19 | sense.stick.direction_up = processUp 20 | 21 | while True: 22 | if upPushed==0: 23 | sense.set_pixel(0, 2, (255, 0, 0)) #red 24 | sleep(5) 25 | sense.set_pixel(0, 4, (255, 255, 0)) #yellow 26 | sleep(2) 27 | sense.set_pixel(0, 2, (0, 0, 0)) #set blank 28 | sense.set_pixel(0, 4, (0, 0, 0)) #set blank 29 | sense.set_pixel(0, 6, (0, 255, 0)) #green 30 | sleep(5) 31 | sense.set_pixel(0, 6, (0, 0, 0)) #green 32 | else: 33 | sense.set_pixel(0, 2, (255, 0, 0)) #red 34 | for i in range(10): 35 | sense.set_pixel(0, 7, (255, 255, 255)) #white 36 | sleep(0.2) 37 | sense.set_pixel(0, 7, (0, 0, 0)) 38 | sleep(0.2) 39 | sense.set_pixel(0, 2, (0, 0, 0)) #red 40 | sleep(1) #add 41 | upPushed=0 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /TutorialPrj/ch6_webControlSenseHat.py: -------------------------------------------------------------------------------- 1 | from bottle import route,run 2 | from sense_hat import SenseHat 3 | import sys 4 | sense = SenseHat() 5 | 6 | flag1=0 7 | if len(sys.argv) != 2: 8 | print("usage:", sys.argv[0], "") 9 | sys.exit(1) 10 | host= sys.argv[1] 11 | 12 | def flagup(): 13 | print('key pressed!') 14 | global flag1 15 | flag1=1 16 | sense.stick.direction_up = flagup 17 | 18 | led_states = [0, 0, 0] 19 | def joystick_status(): 20 | global flag1 21 | x=flag1 22 | if x==1: 23 | flag1=0 24 | return 'Down' 25 | else: 26 | return 'UP' 27 | 28 | def html_for_led(led): 29 | l = str(led) 30 | result = " " 31 | return result 32 | 33 | def update_leds(): 34 | sense.clear() 35 | for i, value in enumerate(led_states): 36 | if(value !=0): 37 | sense.set_pixel(i, 2+i, (255, 0, 0)) 38 | 39 | @route('/') 40 | @route('/') 41 | def index(led="n"): 42 | print(led) 43 | if led != "n": 44 | led_num = int(led) 45 | led_states[led_num] = not led_states[led_num] 46 | update_leds() 47 | response = "" 53 | 54 | response += '

Sense Hat LED

' 55 | response += '

Button=' + joystick_status() + '

' 56 | response += '

LEDs

' 57 | response += html_for_led(0) 58 | response += html_for_led(1) 59 | response += html_for_led(2) 60 | return response 61 | 62 | run(host=host, port=80) 63 | -------------------------------------------------------------------------------- /TutorialPrj/ch7_Sense_Acc.py: -------------------------------------------------------------------------------- 1 | from sense_hat import SenseHat 2 | from collections import deque 3 | import pygame,sys 4 | import pygame.event as GAME_EVENTS 5 | import pygame.locals as GAME_GLOBALS 6 | 7 | windowWidth = 720 8 | windowHeight = 400 9 | offsetX=10 10 | offsetY=windowHeight/2 11 | 12 | sense = SenseHat() 13 | sense.clear() 14 | pygame.init() 15 | pygame.font.init() 16 | surface = pygame.display.set_mode((windowWidth, windowHeight) ) #pygame.FULLSCREEN 17 | pygame.display.set_caption('Accelerometer Demo') 18 | textFont = pygame.font.SysFont("kalinga", 12) 19 | xqueue=deque() 20 | yqueue=deque() 21 | zqueue=deque() 22 | 23 | def draw_Coord_Sys(): 24 | pygame.draw.line(surface, (255,255,255),(offsetX,0), (offsetX,windowHeight) , 3) 25 | pygame.draw.line(surface, (255,255,255),(offsetX,offsetY), 26 | (windowWidth,offsetY) , 3) 27 | renderedText = textFont.render("(g)", 0, (255,255,255)) #1 28 | surface.blit(renderedText, (offsetX+9, 10)) 29 | #画刻度 30 | kedu_up=-1.5 31 | kedu_down=0.5 32 | for i in range(1,4): 33 | pygame.draw.line(surface, (255,255,255),(offsetX+2,50*i), 34 | (offsetX+6,50*i) , 2) 35 | pygame.draw.line(surface, (255,255,255),(offsetX+2,50*i+offsetY), 36 | (offsetX+6,50*i+offsetY) , 2) 37 | renderedText = textFont.render(str(kedu_up), 0, (255,255,255)) #1 38 | surface.blit(renderedText, (offsetX+9, 50*i-7)) 39 | renderedText = textFont.render(str(kedu_down), 0, (255,255,255)) #1 40 | surface.blit(renderedText, (offsetX+9, 50*i-7+offsetY)) 41 | kedu_up+=0.5 42 | kedu_down+=0.5 43 | 44 | 45 | def quitGame(): 46 | pygame.quit() 47 | sys.exit() 48 | 49 | while True: 50 | surface.fill((0,0,0)) 51 | draw_Coord_Sys() 52 | acceleration = sense.get_accelerometer_raw() 53 | xqueue.append(int(acceleration['x']*100) ) 54 | yqueue.append(int(acceleration['y']*100) ) 55 | zqueue.append(int(acceleration['z']*100) ) 56 | if len(xqueue)>=windowWidth-offsetX: 57 | xqueue.popleft() 58 | yqueue.popleft() 59 | zqueue.popleft() 60 | 61 | for i in range(len(xqueue)-1): 62 | pygame.draw.line(surface, (255,0,0), 63 | (offsetX+i,offsetY+xqueue[i]), 64 | (offsetX+i+1,offsetY+xqueue[i+1]), 65 | 1) 66 | pygame.draw.line(surface, (255,255,0), 67 | (offsetX+i,offsetY+yqueue[i]), 68 | (offsetX+i+1,offsetY+yqueue[i+1]), 69 | 1) 70 | pygame.draw.line(surface, (0,255,0), 71 | (offsetX+i,offsetY+zqueue[i]), 72 | (offsetX+i+1,offsetY+zqueue[i+1]), 73 | 1) 74 | 75 | for event in GAME_EVENTS.get(): 76 | if event.type == pygame.KEYDOWN: 77 | if event.key == pygame.K_ESCAPE: 78 | quitGame() 79 | pygame.display.update() 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /TutorialPrj/ch7_guiOrientationDemo.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from sense_hat import SenseHat 3 | import time 4 | 5 | sense = SenseHat() 6 | 7 | class App: 8 | 9 | def __init__(self, master): 10 | self.master = master 11 | frame = Frame(master) 12 | frame.pack() 13 | label = Label(frame, text='Pitch Direction', font=("Helvetica", 32)) 14 | label.grid(row=0) 15 | self.reading_label = Label(frame, text='12.34', font=("Helvetica", 110)) 16 | self.reading_label.grid(row=1) 17 | self.update_reading() 18 | 19 | def update_reading(self): 20 | o = sense.get_orientation() 21 | reading_str = str( int(o['pitch'] ) ) 22 | self.reading_label.configure(text=reading_str) 23 | self.master.after(500, self.update_reading) 24 | 25 | root = Tk() 26 | root.wm_title('Board orientation Demo') 27 | app = App(root) 28 | root.geometry("400x300+0+0") 29 | root.mainloop() 30 | 31 | -------------------------------------------------------------------------------- /TutorialPrj/ch7_pitchFileLog/pitchFileLog.py: -------------------------------------------------------------------------------- 1 | import os, time, datetime 2 | from sense_hat import SenseHat 3 | 4 | def log_temp(): 5 | o = sense.get_orientation() 6 | reading_str = str( int(o['pitch'] ) ) 7 | 8 | dt = datetime.datetime.now() 9 | with open(filename,'a') as f: 10 | f.write('"{:%H:%M:%S}",'.format(dt)) 11 | f.write(reading_str+"\n") 12 | print('"{:%H:%M:%S}",'.format(dt)+reading_str) 13 | f.close() 14 | 15 | running = True 16 | log_period = 5 # seconds 17 | dt = datetime.datetime.now() 18 | sense = SenseHat() 19 | filename = 'write_data.txt' 20 | print("Logging to: " + filename) 21 | 22 | while running: 23 | try: 24 | log_temp() 25 | time.sleep(log_period) 26 | except KeyboardInterrupt: 27 | print ('Program stopped') 28 | running = False 29 | # file.close() -------------------------------------------------------------------------------- /TutorialPrj/ch7_pitchFileLog/write_data.txt: -------------------------------------------------------------------------------- 1 | "20:21:46",1 2 | "20:21:51",6 3 | "20:21:56",352 4 | "20:22:01",346 5 | "20:22:06",358 6 | "20:22:11",0 7 | "20:22:16",304 8 | "20:22:21",315 9 | -------------------------------------------------------------------------------- /TutorialPrj/ch7_weather_station.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from tkinter import ttk 3 | import time 4 | from sense_hat import SenseHat 5 | 6 | #create an object called sense 7 | sense = SenseHat() 8 | 9 | #create window 10 | window = Tk() 11 | window.title('Local Weather Station') 12 | window.geometry('200x480') 13 | 14 | #create humidity label for title and value 15 | humidity_label = Label(window, text = 'Humidity', font = ('Helvetica', 18), pady = 3) 16 | humidity_label.pack() 17 | 18 | humidity = StringVar() 19 | humidity_value=Label(window, textvariable = humidity, 20 | font = ('Courier', 20), fg = 'blue', anchor = N, width = 200) 21 | humidity_value.pack() 22 | 23 | #create humidity canvas 24 | humidity_canvas = Canvas(window, width = 200, height = 200) 25 | humidity_canvas.pack() 26 | 27 | #create humidity progress bar 28 | humidity_bar = DoubleVar() 29 | progressbar_humidity = ttk.Progressbar(humidity_canvas, variable = humidity_bar, 30 | orient = VERTICAL, length = 150, maximum = 100) 31 | progressbar_humidity.pack(fill=X, expand=1) 32 | 33 | #create temperature label for title and value 34 | temperature_label = Label(window, text = 'Temperature', font = ('Helvetica', 18), 35 | anchor = S, width = 200, height = 2) 36 | temperature_label.pack() 37 | 38 | temperature=StringVar() 39 | temperature_value = Label(window, textvariable = temperature, font = ('Courier', 20), 40 | fg = 'red', anchor = N, width = 200) 41 | temperature_value.pack() 42 | 43 | #create pressure label for title and value 44 | pressure_label = Label(window, text = 'Pressure', font = ('Helvetica', 18), 45 | anchor = S, width = 200, height = 2) 46 | pressure_label.pack() 47 | 48 | pressure = StringVar() 49 | pressure_value = Label(window, textvariable = pressure, 50 | font = ('Courier', 20), fg = 'green', anchor = N, width = 200) 51 | pressure_value.pack() 52 | 53 | def update_readings(): 54 | humidity.set(str(round(sense.humidity, 2)) + '%') 55 | humidity_bar.set(sense.humidity) 56 | temperature.set(str(round(sense.temperature, 2)) + 'ºC') 57 | #temperature.set(str(round(sense.temperature*(9/5)+32, 2)) + 'ºF') 58 | pressure.set(str(round(sense.pressure)) + 'hPa') 59 | window.update_idletasks() 60 | window.after(3000, update_readings) 61 | 62 | update_readings() 63 | window.mainloop() 64 | -------------------------------------------------------------------------------- /TutorialPrj/ch8_surveillance_system.py: -------------------------------------------------------------------------------- 1 | #based on the Web Streaming example at: http://picamera.readthedocs.io/en/latest/recipes2.html 2 | import io 3 | import picamera 4 | import logging 5 | import socketserver 6 | from threading import Condition 7 | from http import server 8 | 9 | PAGE="""\ 10 | 11 | 12 | Raspberry Pi - Camera 13 | 14 | 15 |

Raspberry Pi - Surveillance Camera

16 |
17 | 18 | 19 | """ 20 | 21 | class StreamingOutput(object): 22 | def __init__(self): 23 | self.frame = None 24 | self.buffer = io.BytesIO() 25 | self.condition = Condition() 26 | 27 | def write(self, buf): 28 | if buf.startswith(b'\xff\xd8'): 29 | #new frame, copy the existing buffer's content and notify all 30 | #clients it's available 31 | self.buffer.truncate() 32 | with self.condition: 33 | self.frame = self.buffer.getvalue() 34 | self.condition.notify_all() 35 | self.buffer.seek(0) 36 | return self.buffer.write(buf) 37 | 38 | class StreamingHandler(server.BaseHTTPRequestHandler): 39 | def do_GET(self): 40 | if self.path == '/': 41 | self.send_response(301) 42 | self.send_header('Location', '/index.html') 43 | self.end_headers() 44 | elif self.path == '/index.html': 45 | content = PAGE.encode('utf-8') 46 | self.send_response(200) 47 | self.send_header('Content-Type', 'text/html') 48 | self.send_header('Content-Length', len(content)) 49 | self.end_headers() 50 | self.wfile.write(content) 51 | elif self.path == '/stream.mjpg': 52 | self.send_response(200) 53 | self.send_header('Age', 0) 54 | self.send_header('Cache-Control', 'no-cache, private') 55 | self.send_header('Pragma', 'no-cache') 56 | self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=FRAME') 57 | self.end_headers() 58 | try: 59 | while True: 60 | with output.condition: 61 | output.condition.wait() 62 | frame = output.frame 63 | self.wfile.write(b'--FRAME\r\n') 64 | self.send_header('Content-Type', 'image/jpeg') 65 | self.send_header('Content-Length', len(frame)) 66 | self.end_headers() 67 | self.wfile.write(frame) 68 | self.wfile.write(b'\r\n') 69 | except Exception as e: 70 | logging.warning( 71 | 'Removed streaming client %s: %s', 72 | self.client_address, str(e)) 73 | else: 74 | self.send_error(404) 75 | self.end_headers() 76 | 77 | class StreamingServer(socketserver.ThreadingMixIn, server.HTTPServer): 78 | allow_reuse_address = True 79 | daemon_threads = True 80 | 81 | with picamera.PiCamera(resolution='640x480', framerate=24) as camera: 82 | output = StreamingOutput() 83 | camera.start_recording(output, format='mjpeg') 84 | try: 85 | address = ('', 8000) 86 | server = StreamingServer(address, StreamingHandler) 87 | server.serve_forever() 88 | finally: 89 | camera.stop_recording() 90 | -------------------------------------------------------------------------------- /TutorialPrj/ch8_test_OpenCV/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.0) 2 | cmake_policy(SET CMP0012 NEW) 3 | PROJECT(Ch2_1) 4 | 5 | find_package(OpenCV REQUIRED) 6 | message(" opencv version: ${OpenCV_VERSION}") 7 | include_directories(${OpenCV_INCLUDE_DIRS}) # Not needed for CMake >= 2.8.11 8 | 9 | ADD_EXECUTABLE( sample1 sample1.cpp ) 10 | TARGET_LINK_LIBRARIES(sample1 ${OpenCV_LIBS}) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /TutorialPrj/ch8_test_OpenCV/lena.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/TutorialPrj/ch8_test_OpenCV/lena.jpg -------------------------------------------------------------------------------- /TutorialPrj/ch8_test_OpenCV/sample1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | // OpenCV includes 7 | #include "opencv2/core.hpp" 8 | #include "opencv2/highgui.hpp" 9 | using namespace cv; 10 | 11 | int main( int argc, const char** argv ) 12 | { 13 | // Read images 14 | Mat color= imread("../lena.jpg"); 15 | Mat gray= imread("../lena.jpg", IMREAD_GRAYSCALE); 16 | 17 | if(! color.data ) // Check for invalid input 18 | { 19 | cout << "Could not open or find the image" << std::endl ; 20 | return -1; 21 | } 22 | 23 | // Write images 24 | imwrite("lenaGray.jpg", gray); 25 | 26 | // Get same pixel with opencv function 27 | int myRow=color.cols-1; 28 | int myCol=color.rows-1; 29 | auto pixel= color.at(myRow, myCol); 30 | cout << "Pixel value (B,G,R): (" << (int)pixel[0] << "," << (int)pixel[1] << "," << (int)pixel[2] << ")" << endl; 31 | 32 | // show images 33 | imshow("Lena BGR", color); 34 | imshow("Lena Gray", gray); 35 | // wait for any key press 36 | waitKey(0); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /TutorialPrj/darknet_202204/readme.txt: -------------------------------------------------------------------------------- 1 | 请大家根据8.4节的步骤用git命令下载darknet。再把test_darknet.sh复制到darknet主目录下,最后运行程序。 2 | 3 | -------------------------------------------------------------------------------- /TutorialPrj/darknet_202204/test_darknet.sh: -------------------------------------------------------------------------------- 1 | #./darknet detector test cfg/coco.data cfg/yolov3-tiny.cfg weights/yolov3-tiny.weights data/dog.jpg 2 | 3 | ./darknet detector test cfg/coco.data cfg/yolov3-tiny.cfg weights/yolov3-tiny.weights data/person.jpg 4 | -------------------------------------------------------------------------------- /必备软件/SDCardFormatterv5_WinEN.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/必备软件/SDCardFormatterv5_WinEN.zip -------------------------------------------------------------------------------- /必备软件/WinSCP-5.17.10-Setup.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/必备软件/WinSCP-5.17.10-Setup.exe -------------------------------------------------------------------------------- /必备软件/imager_1.6.2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/必备软件/imager_1.6.2.exe -------------------------------------------------------------------------------- /必备软件/putty-64bit-0.76-installer.msi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/必备软件/putty-64bit-0.76-installer.msi -------------------------------------------------------------------------------- /必备软件/sscom32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/必备软件/sscom32.exe -------------------------------------------------------------------------------- /必备软件/thonny-3.2.7.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/必备软件/thonny-3.2.7.exe -------------------------------------------------------------------------------- /必备软件/注意.txt: -------------------------------------------------------------------------------- 1 | 由于git限制,本文件夹删除了2021-10-30-raspios-bullseye-armhf.zip这个1.1G的大文件,大家可以下载最新的Raspberry PI OS -------------------------------------------------------------------------------- /树莓派编程实用教程.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/树莓派编程实用教程.pdf -------------------------------------------------------------------------------- /重要参考书/BeginnersGuide-4thEd-Eng_v2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/BeginnersGuide-4thEd-Eng_v2.zip -------------------------------------------------------------------------------- /重要参考书/Essentials_Games_v1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/Essentials_Games_v1.zip -------------------------------------------------------------------------------- /重要参考书/Python Crash Course 2nd Edition-2019.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/Python Crash Course 2nd Edition-2019.pdf -------------------------------------------------------------------------------- /重要参考书/Python GUI Programming Cookbook 2nd - 2017.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/Python GUI Programming Cookbook 2nd - 2017.pdf -------------------------------------------------------------------------------- /重要参考书/Raspberry Pi User Guide 4th Edition.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/Raspberry Pi User Guide 4th Edition.zip -------------------------------------------------------------------------------- /重要参考书/Raspberry_Pi_Wikipedia.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/Raspberry_Pi_Wikipedia.pdf -------------------------------------------------------------------------------- /重要参考书/Retro Gaming with Raspberry Pi.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/Retro Gaming with Raspberry Pi.zip -------------------------------------------------------------------------------- /重要参考书/Sense Hat.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/Sense Hat.zip -------------------------------------------------------------------------------- /重要参考书/python3.10.4docs-pdf英文2022.4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/python3.10.4docs-pdf英文2022.4.zip -------------------------------------------------------------------------------- /重要参考书/raspberrypi_cookbook_ed2_ed3_program.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/raspberrypi_cookbook_ed2_ed3_program.zip -------------------------------------------------------------------------------- /重要参考书/socket-programming-in-python-cn.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/socket-programming-in-python-cn.zip -------------------------------------------------------------------------------- /重要参考书/免责声明.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/免责声明.txt -------------------------------------------------------------------------------- /重要参考书/鸟哥的linux私房菜第四版.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wxlscm/raspberry_tutorial/75b19cae03288c754785706044a9fc963033e544/重要参考书/鸟哥的linux私房菜第四版.pdf --------------------------------------------------------------------------------