├── LICENSE ├── PiBakery └── headless_blink.xml ├── README.md ├── arduino ├── ch_17_web_switch │ └── ch_17_web_switch.ino ├── ch_18_ardu_flash.py │ └── ch_18_ardu_servo.py └── ch_18_serial_test │ └── ch_18_serial_test.ino ├── long_commands.txt ├── node_red ├── recipe_17_02.json ├── recipe_17_05.json ├── recipe_17_07_A.json ├── recipe_17_07_B.json ├── recipe_17_08.json └── recipe_17_10.json ├── ocr_test.tiff └── python ├── FreeSansBold.ttf ├── ch_07_bottle_test.py ├── ch_07_cmdline.py ├── ch_07_example_file.json ├── ch_07_guizero.py ├── ch_07_minecraft_stairs.py ├── ch_07_parse_json.py ├── ch_07_parse_json_file.py ├── ch_07_parse_json_url.py ├── ch_07_random.py ├── ch_07_regex_email.py ├── ch_07_regex_find.py ├── ch_07_regex_scraping.py ├── ch_07_sleep_test.py ├── ch_07_thread_test.py ├── ch_08_coin_count.py ├── ch_08_coin_count_test.py ├── ch_08_detect_motion.py ├── ch_08_faces.py ├── ch_09_button_test.py ├── ch_09_explorer_hat_blink.py ├── ch_09_squid_test.py ├── ch_10_bluedot.py ├── ch_10_gui_slider.py ├── ch_10_gui_slider_RGB.py ├── ch_10_gui_switch.py ├── ch_10_led_blink.py ├── ch_10_led_blink_2.py ├── ch_10_led_brightness.py ├── ch_10_pwm_f_test.py ├── ch_11_motor_control.py ├── ch_11_rover.py ├── ch_11_servo.py ├── ch_11_servo_adafruit.py ├── ch_11_servo_blaster.py ├── ch_11_stepper.py ├── ch_11_stepper_rrb.py ├── ch_12_gps_test.py ├── ch_12_key_sys.py ├── ch_12_keypad.py ├── ch_12_keys_pygame.py ├── ch_12_mouse_pygame.py ├── ch_12_pir.py ├── ch_12_rotary_encoder.py ├── ch_12_switch.py ├── ch_12_switch_2.py ├── ch_12_switch_3_pos.py ├── ch_12_switch_on_off.py ├── ch_13_adc_scaled.py ├── ch_13_adc_test.py ├── ch_13_adc_tmp36.py ├── ch_13_co2.py ├── ch_13_cpu_temp.py ├── ch_13_cpu_temp_float.py ├── ch_13_gui_sensor_reading.py ├── ch_13_i2c_acc.py ├── ch_13_i2c_acc_tilt.py ├── ch_13_ranger.py ├── ch_13_resistance_meter.py ├── ch_13_sense_hat_compass.py ├── ch_13_sense_hat_magnet.py ├── ch_13_sense_hat_orientation.py ├── ch_13_sense_hat_thp.py ├── ch_13_temp_DS18B20.py ├── ch_13_temp_log.py ├── ch_13_thermistor.py ├── ch_13_tof.py ├── ch_13_touch.py ├── ch_14_displayotron_ip.py ├── ch_14_neopixel.py ├── ch_14_oled_clock.py ├── ch_14_phat.py ├── ch_14_sense_hat_clock.py ├── ch_14_unicorn.py ├── ch_15_buzzer.py ├── ch_15_play_sound.py ├── ch_15_play_sound_pygame.py ├── ch_16_cheerlights.py ├── ch_16_ifttt_cpu_temp.py ├── ch_16_send_tweet.py ├── ch_16_thingspeak_data.py ├── ch_16_twitter_trigger.py ├── ch_16_web_control.py ├── ch_16_web_sensor ├── justgage.1.0.1.min.js ├── main.html ├── raphael.2.1.0.min.js └── web_sensor.py ├── ch_18_ardu_adc.py ├── ch_18_ardu_flash.py ├── ch_18_ardu_flash_ser.py ├── ch_18_ardu_gui_slider.py ├── ch_18_ardu_gui_switch.py ├── ch_18_ardu_pwm.py ├── ch_18_ardu_switch.py ├── faces.jpg ├── school_bell.mp3 └── school_bell.wav /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Simon Monk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PiBakery/headless_blink.xml: -------------------------------------------------------------------------------- 1 | piZeronetwork namepasswordWPA/WPA2GBhttps://raw.githubusercontent.com/simonmonk/raspberrypi_cookbook_ed3/master/python/led_blink.py/home/pi/led_blink.py/home/pi/led_blink.pypi -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # raspberrypi_cookbook_ed3 2 | The source code to accompany the THIRD EDITION of the book 'The Raspberry Pi Cookbook' by SImon Monk. 3 | -------------------------------------------------------------------------------- /arduino/ch_17_web_switch/ch_17_web_switch.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const char* ssid = "your wifi access point name"; 5 | const char* password = "your wifi password"; 6 | const char* mqtt_server = "your MQTT IP address"; 7 | const int buttonPin = D6; 8 | const char* topic = "button_1"; 9 | const char* message = "Button 1 pressed"; 10 | 11 | WiFiClient espClient; 12 | PubSubClient client(espClient); 13 | 14 | void setup() { 15 | pinMode(buttonPin, INPUT_PULLUP); 16 | Serial.begin(9600); 17 | setup_wifi(); 18 | randomSeed(micros()); 19 | client.setServer(mqtt_server, 1883); 20 | } 21 | 22 | void loop() { 23 | if (!client.connected()) { 24 | reconnect(); 25 | } 26 | client.loop(); 27 | if (digitalRead(buttonPin) == LOW) { 28 | Serial.println("Publish button pressed "); 29 | client.publish(topic, message); 30 | delay(100); 31 | while (digitalRead(buttonPin) == LOW) {}; 32 | delay(100); 33 | } 34 | } 35 | 36 | void setup_wifi() { 37 | Serial.println(); 38 | Serial.print("Connecting to "); 39 | Serial.println(ssid); 40 | WiFi.begin(ssid, password); 41 | while (WiFi.status() != WL_CONNECTED) { 42 | delay(500); 43 | Serial.print("."); 44 | } 45 | Serial.println(""); 46 | Serial.println("WiFi connected"); 47 | Serial.println("IP address: "); 48 | Serial.println(WiFi.localIP()); 49 | } 50 | 51 | void reconnect() { 52 | // Loop until we're reconnected 53 | while (!client.connected()) { 54 | Serial.print("Attempting MQTT connection..."); 55 | // Create a random client ID 56 | String clientId = "ESP8266Client-"; 57 | clientId += String(random(0xffff), HEX); 58 | // Attempt to connect 59 | if (client.connect(clientId.c_str())) { 60 | Serial.println("MQTT connected"); 61 | } else { 62 | Serial.print("failed, rc="); 63 | Serial.print(client.state()); 64 | Serial.println(" try again in 5 seconds"); 65 | // Wait 5 seconds before retrying 66 | delay(5000); 67 | } 68 | } 69 | } 70 | 71 | 72 | -------------------------------------------------------------------------------- /arduino/ch_18_ardu_flash.py/ch_18_ardu_servo.py: -------------------------------------------------------------------------------- 1 | import pyfirmata 2 | 3 | board = pyfirmata.Arduino('/dev/ttyACM0') 4 | servo_pin = board.get_pin('d:11:s') 5 | 6 | while True: 7 | angle_s = input("Enter Angle (0 to 180):") 8 | angle = int(angle_s) 9 | servo_pin.write(angle) 10 | -------------------------------------------------------------------------------- /arduino/ch_18_serial_test/ch_18_serial_test.ino: -------------------------------------------------------------------------------- 1 | void setup() 2 | { 3 | Serial.begin(9600); 4 | } 5 | 6 | void loop() 7 | { 8 | Serial.println("Hello Raspberry Pi"); 9 | delay(1000); 10 | } 11 | -------------------------------------------------------------------------------- /long_commands.txt: -------------------------------------------------------------------------------- 1 | Long linux commands from the book The Raspberry Pi Cookbook 2 | 3 | This is where you can find long commands used in the book and paste them into a terminal. 4 | 5 | - something thats a bit tricky with a paper book. 6 | 7 | 8 | Chapter 2 9 | ========= 10 | 11 | Recipe 2.10 - File Sharing on a Mac Network 12 | ------------ 13 | 14 | 15 | 16 | 17 | %h 18 | 19 | _afpovertcp._tcp 20 | 548 21 | 22 | 23 | 24 | 25 | Chapter 3 26 | ========= 27 | 28 | Recipe 3.23 - Running a Program or Script Automatically as a Service 29 | ------------ 30 | 31 | ### BEGIN INIT INFO 32 | # Provides: my_server 33 | # Required-Start: $remote_fs $syslog $network 34 | # Required-Stop: $remote_fs $syslog $network 35 | # Default-Start: 2 3 4 5 36 | # Default-Stop: 0 1 6 37 | # Short-Description: Simple Web Server 38 | # Description: Simple Web Server 39 | ### END INIT INFO 40 | 41 | #! /bin/sh 42 | # /etc/init.d/my_server 43 | 44 | export HOME 45 | case "$1" in 46 | start) 47 | echo "Starting My Server" 48 | sudo /usr/bin/python /home/pi/myserver.py 2>&1 & 49 | ;; 50 | stop) 51 | echo "Stopping My Server" 52 | PID=`ps auxwww | grep myserver.py | head -1 | awk '{print $2}'` 53 | kill -9 $PID 54 | ;; 55 | *) 56 | echo "Usage: /etc/init.d/my_server {start|stop}" 57 | exit 1 58 | ;; 59 | esac 60 | exit 0 61 | 62 | 63 | 64 | 65 | 66 | # Chapter 8 67 | 68 | Recipe XX 69 | Installing Simple CV 70 | $ sudo apt-get update 71 | $ sudo apt-get install ipython python-opencv python-scipy 72 | $ sudo apt-get install python-numpy python-setuptools python-pip 73 | $ sudo pip install svgwrite 74 | 75 | $ sudo pip install https://github.com/sightmachine/SimpleCV/zipball/master --no-cache-dir 76 | $ pip install 'IPython==4' --force-reinstall 77 | 78 | 79 | 80 | 81 | Recipe XX 82 | Installing Tesseract 83 | $ sudo apt install tesseract-ocr 84 | $ sudo apt install libtesseract-dev 85 | -------------------------------------------------------------------------------- /node_red/recipe_17_02.json: -------------------------------------------------------------------------------- 1 | [{"id":"88bfcd8c.7111d","type":"tab","label":"Recipe 17_02","disabled":false,"info":""},{"id":"7d320ab0.1f2964","type":"mqtt in","z":"88bfcd8c.7111d","name":"Kitchen Lights Subscription","topic":"kitchen_lights","qos":"2","broker":"6ad68786.938028","x":210,"y":120,"wires":[["abb8c6bc.bf3db8"]]},{"id":"abb8c6bc.bf3db8","type":"rpi-gpio out","z":"88bfcd8c.7111d","name":"Kitchen Light Using GPIO 18","pin":"12","set":"","level":"0","freq":"","out":"out","x":520,"y":220,"wires":[]},{"id":"6ad68786.938028","type":"mqtt-broker","z":"","name":"MyHomeAutomation","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}] 2 | -------------------------------------------------------------------------------- /node_red/recipe_17_05.json: -------------------------------------------------------------------------------- 1 | [{"id":"8eeb0a4b.a07598","type":"tab","label":"Recipe 17_05","disabled":false,"info":""},{"id":"cca21868.eb4b68","type":"mqtt out","z":"8eeb0a4b.a07598","name":"Sonoff_1","topic":"cmnd/sonoff_1/power","qos":"2","retain":"","broker":"6ad68786.938028","x":460,"y":220,"wires":[]},{"id":"2b4d33fc.c9810c","type":"trigger","z":"8eeb0a4b.a07598","op1":"1","op2":"","op1type":"str","op2type":"nul","duration":"250","extend":false,"units":"ms","reset":"","bytopic":"all","name":"On trigger","x":280,"y":300,"wires":[["cca21868.eb4b68"]]},{"id":"4326d512.66ad8c","type":"trigger","z":"8eeb0a4b.a07598","op1":"","op2":"0","op1type":"nul","op2type":"num","duration":"10","extend":false,"units":"s","reset":"","bytopic":"all","name":"Off trigger","x":280,"y":140,"wires":[["cca21868.eb4b68"]]},{"id":"f24180a3.be996","type":"rpi-gpio in","z":"8eeb0a4b.a07598","name":"Push Button","pin":"22","intype":"up","debounce":"25","read":false,"x":80,"y":220,"wires":[["4326d512.66ad8c","2b4d33fc.c9810c"]]},{"id":"6ad68786.938028","type":"mqtt-broker","z":"","name":"MyHomeAutomation","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}] 2 | -------------------------------------------------------------------------------- /node_red/recipe_17_07_A.json: -------------------------------------------------------------------------------- 1 | [{"id":"9e401e48.aa631","type":"tab","label":"Recipe 17_07_A","disabled":false,"info":""},{"id":"86951f6d.1a459","type":"mqtt out","z":"9e401e48.aa631","name":"Sonoff_1","topic":"cmnd/sonoff_1/power","qos":"2","retain":"","broker":"6ad68786.938028","x":560,"y":260,"wires":[]},{"id":"9befcecc.7eab1","type":"trigger","z":"9e401e48.aa631","op1":"","op2":"0","op1type":"nul","op2type":"num","duration":"10","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":350,"y":120,"wires":[["86951f6d.1a459"]]},{"id":"a812b4b9.2bd1a8","type":"ui_button","z":"9e401e48.aa631","name":"Lights On Button","group":"fb12146.d1a6be8","order":1,"width":0,"height":0,"passthru":false,"label":"Lights","tooltip":"","color":"","bgcolor":"","icon":"","payload":"1","payloadType":"num","topic":"","x":130,"y":260,"wires":[["86951f6d.1a459","9befcecc.7eab1"]]},{"id":"6ad68786.938028","type":"mqtt-broker","z":"","name":"MyHomeAutomation","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"fb12146.d1a6be8","type":"ui_group","z":"","name":"Lights","tab":"1043f1d0.f532ce","disp":true,"width":"6","collapse":false},{"id":"1043f1d0.f532ce","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}] 2 | -------------------------------------------------------------------------------- /node_red/recipe_17_07_B.json: -------------------------------------------------------------------------------- 1 | [{"id":"b295b123.d8c2d","type":"tab","label":"Recipe 17_07_B","disabled":false,"info":""},{"id":"c87d7a1.a64bb88","type":"mqtt out","z":"b295b123.d8c2d","name":"Sonoff_1","topic":"cmnd/sonoff_1/power","qos":"2","retain":"","broker":"6ad68786.938028","x":540,"y":220,"wires":[]},{"id":"87e759ca.cfd508","type":"trigger","z":"b295b123.d8c2d","op1":"","op2":"0","op1type":"nul","op2type":"num","duration":"10","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":330,"y":80,"wires":[["c87d7a1.a64bb88"]]},{"id":"796829e4.985c08","type":"ui_button","z":"b295b123.d8c2d","name":"Lights On Button","group":"fb12146.d1a6be8","order":1,"width":0,"height":0,"passthru":false,"label":"Lights","tooltip":"","color":"","bgcolor":"","icon":"","payload":"1","payloadType":"num","topic":"","x":110,"y":220,"wires":[["c87d7a1.a64bb88","87e759ca.cfd508"]]},{"id":"80d98b9f.e70338","type":"ui_switch","z":"b295b123.d8c2d","name":"Lights On/Off","label":"Lights On/Off","tooltip":"","group":"fb12146.d1a6be8","order":3,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":110,"y":280,"wires":[["c87d7a1.a64bb88"]]},{"id":"6ad68786.938028","type":"mqtt-broker","z":"","name":"MyHomeAutomation","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"fb12146.d1a6be8","type":"ui_group","z":"","name":"Lights","tab":"1043f1d0.f532ce","disp":true,"width":"6","collapse":false},{"id":"1043f1d0.f532ce","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}] 2 | -------------------------------------------------------------------------------- /node_red/recipe_17_08.json: -------------------------------------------------------------------------------- 1 | [{"id":"bb19c3a5.5ac5e","type":"tab","label":"Recipe 17_08","disabled":false,"info":""},{"id":"f42c4a18.1f14c8","type":"mqtt out","z":"bb19c3a5.5ac5e","name":"Sonoff_1","topic":"cmnd/sonoff_1/power","qos":"2","retain":"","broker":"6ad68786.938028","x":440,"y":240,"wires":[]},{"id":"cb73e998.494a08","type":"ui_switch","z":"bb19c3a5.5ac5e","name":"Lights","label":"switch","tooltip":"","group":"fb12146.d1a6be8","order":0,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"sonoff_1","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":220,"y":240,"wires":[["f42c4a18.1f14c8"]]},{"id":"42b33c29.a010c4","type":"inject","z":"bb19c3a5.5ac5e","name":"Auto Off","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"00 01 * * *","once":false,"onceDelay":0.1,"x":220,"y":300,"wires":[["f42c4a18.1f14c8"]]},{"id":"6ad68786.938028","type":"mqtt-broker","z":"","name":"MyHomeAutomation","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"fb12146.d1a6be8","type":"ui_group","z":"","name":"Lights","tab":"1043f1d0.f532ce","disp":true,"width":"6","collapse":false},{"id":"1043f1d0.f532ce","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}] 2 | -------------------------------------------------------------------------------- /node_red/recipe_17_10.json: -------------------------------------------------------------------------------- 1 | [{"id":"e4f6800b.8652c","type":"tab","label":"Recipe 17_10","disabled":false,"info":""},{"id":"90c04193.7aa31","type":"mqtt out","z":"e4f6800b.8652c","name":"Sonoff_1","topic":"cmnd/sonoff_1/power","qos":"2","retain":"","broker":"6ad68786.938028","x":400,"y":340,"wires":[]},{"id":"7eb1eea8.07183","type":"mqtt in","z":"e4f6800b.8652c","name":"Button 1","topic":"button_1","qos":"2","broker":"6ad68786.938028","x":120,"y":200,"wires":[["2a527589.1d08ba"]]},{"id":"2a527589.1d08ba","type":"trigger","z":"e4f6800b.8652c","op1":"1","op2":"","op1type":"str","op2type":"nul","duration":"250","extend":false,"units":"ms","reset":"","bytopic":"all","name":"Trigger","x":150,"y":280,"wires":[["706be249.a03a4c"]]},{"id":"706be249.a03a4c","type":"function","z":"e4f6800b.8652c","name":"Toggle","func":"var i=context.get('i') || 0;\nvar payload=msg.payload;\ncontext.set(\"i\",Math.abs(i-payload));\nvar payload=msg.payload;\nmsg.payload=i;\nreturn msg;","outputs":1,"noerr":0,"x":290,"y":280,"wires":[["90c04193.7aa31"]]},{"id":"6ad68786.938028","type":"mqtt-broker","z":"","name":"MyHomeAutomation","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}] 2 | -------------------------------------------------------------------------------- /ocr_test.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonmonk/raspberrypi_cookbook_ed3/34da8ee7d4e1f5743eded358c9f4864f774d5599/ocr_test.tiff -------------------------------------------------------------------------------- /python/FreeSansBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonmonk/raspberrypi_cookbook_ed3/34da8ee7d4e1f5743eded358c9f4864f774d5599/python/FreeSansBold.ttf -------------------------------------------------------------------------------- /python/ch_07_bottle_test.py: -------------------------------------------------------------------------------- 1 | from bottle import route, run, template 2 | from datetime import datetime 3 | 4 | @route('/') 5 | def index(name='time'): 6 | dt = datetime.now() 7 | time = "{:%Y-%m-%d %H:%M:%S}".format(dt) 8 | return template('Pi thinks the date/time is: {{t}}', t=time) 9 | 10 | run(host='0.0.0.0', port=80) 11 | -------------------------------------------------------------------------------- /python/ch_07_cmdline.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | for (i, value) in enumerate(sys.argv): 4 | print("arg: %d %s " % (i, value)) 5 | -------------------------------------------------------------------------------- /python/ch_07_example_file.json: -------------------------------------------------------------------------------- 1 | {"books" : [ 2 | {"title" : "Programnming Arduino", "price" : 10.95}, 3 | {"title" : "Pi Cookbook", "price" : 19.95} 4 | ]} 5 | 6 | -------------------------------------------------------------------------------- /python/ch_07_guizero.py: -------------------------------------------------------------------------------- 1 | from guizero import * 2 | 3 | def say_hello(): 4 | info("An Alert", "Please don't press this button again") 5 | 6 | app = App(title="Pi Cookbook Example", height=200) 7 | button = PushButton(app, text="Don't Press Me", command=say_hello) 8 | 9 | app.display() 10 | -------------------------------------------------------------------------------- /python/ch_07_minecraft_stairs.py: -------------------------------------------------------------------------------- 1 | from mcpi import minecraft, block 2 | mc = minecraft.Minecraft.create() 3 | 4 | mc.postToChat("Lets Build a Staircase!") 5 | 6 | x, y, z = mc.player.getPos() 7 | 8 | for xy in range(1, 50): 9 | mc.setBlock(x + xy, y + xy, z, block.STONE) 10 | -------------------------------------------------------------------------------- /python/ch_07_parse_json.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | s = '{"books" : [{"title" : "Programnming Arduino", "price" : 10.95}, {"title" : "Pi Cookbook", "price" : 19.95}]}'' 4 | j = json.loads(s) 5 | print(j['books'][1]['title']) 6 | -------------------------------------------------------------------------------- /python/ch_07_parse_json_file.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | file_name = 'ch_07_example_file.json' 4 | 5 | json_file = open(file_name) 6 | j = json.load(json_file) 7 | json_file.close() 8 | 9 | print(j['books'][1]['title']) 10 | -------------------------------------------------------------------------------- /python/ch_07_parse_json_url.py: -------------------------------------------------------------------------------- 1 | import json 2 | import urllib.request 3 | 4 | key = 'paste_your_key_here' 5 | 6 | response = urllib.request.urlopen('http://api.weatherstack.com/current?access_key=' + key + '&query=Paris') 7 | j = json.load(response) 8 | 9 | print(j['current']['weather_descriptions'][0]) 10 | -------------------------------------------------------------------------------- /python/ch_07_random.py: -------------------------------------------------------------------------------- 1 | import random 2 | from copy import copy 3 | 4 | list = ['a', 'b', 'c'] 5 | 6 | working_list = copy(list) 7 | while len(working_list) > 0 : 8 | x = random.choice(working_list) 9 | print(x) 10 | working_list.remove(x) 11 | -------------------------------------------------------------------------------- /python/ch_07_regex_email.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | regex = '^[\w_\.+-]+@[\w_\.-]+\.[\w_-]+$' 4 | 5 | while True: 6 | text = input("Enter an email address: ") 7 | if re.search(regex, text): 8 | print("valid") 9 | else: 10 | print("invalid") 11 | -------------------------------------------------------------------------------- /python/ch_07_regex_find.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | text = "looking forward to finding the word for" 4 | x = re.search("(^|\s)for($|\s)", text) 5 | 6 | print(x.span()) -------------------------------------------------------------------------------- /python/ch_07_regex_scraping.py: -------------------------------------------------------------------------------- 1 | import re 2 | import urllib.request 3 | 4 | regex = '#([\d,]+) in Books' 5 | url = 'https://www.amazon.com/Raspberry-Pi-Cookbook-Software-Solutions/dp/1492043222/' 6 | 7 | print("The Amazon rank is.....") 8 | 9 | text = urllib.request.urlopen(url).read().decode('utf-8') 10 | 11 | print(re.search(regex, text).group()) -------------------------------------------------------------------------------- /python/ch_07_sleep_test.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | x = 0 4 | while True: 5 | print(x) 6 | time.sleep(1) 7 | x += 1 8 | -------------------------------------------------------------------------------- /python/ch_07_thread_test.py: -------------------------------------------------------------------------------- 1 | import threading, time, random 2 | 3 | def annoy(message): 4 | while True: 5 | time.sleep(random.randint(1, 3)) 6 | print(message) 7 | 8 | t = threading.Thread(target=annoy, args=('BOO !!',)) 9 | t.start() 10 | 11 | x = 0 12 | while True: 13 | print(x) 14 | x += 1 15 | time.sleep(1) 16 | -------------------------------------------------------------------------------- /python/ch_08_coin_count.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | from imutils.video import VideoStream 3 | from imutils import resize 4 | 5 | vs = VideoStream(src=0).start() 6 | old_count = 0 7 | 8 | while True: 9 | try: 10 | img = vs.read() 11 | img = resize(img, width=800) 12 | img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 13 | img = cv2.blur(img, (3, 3)) 14 | 15 | detected_circles = cv2.HoughCircles(img, 16 | cv2.HOUGH_GRADIENT, 1, 20, param1 = 50, 17 | param2 = 30, minRadius = 15, maxRadius = 100) 18 | 19 | count = len(detected_circles[0] ) 20 | if count != old_count: 21 | print(count) 22 | old_count = count 23 | except: 24 | vs.stop() 25 | -------------------------------------------------------------------------------- /python/ch_08_coin_count_test.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | from imutils.video import VideoStream 3 | from imutils import resize 4 | 5 | vs = VideoStream(src=0).start() 6 | 7 | while True: 8 | img = vs.read() 9 | img = resize(img, width=800) 10 | img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 11 | img = cv2.blur(img, (3, 3)) 12 | 13 | detected_circles = cv2.HoughCircles(img, 14 | cv2.HOUGH_GRADIENT, 1, 20, param1 = 50, 15 | param2 = 30, minRadius = 15, maxRadius = 100) 16 | 17 | print(detected_circles) 18 | 19 | for pt in detected_circles[0]: 20 | a, b, r = pt[0], pt[1], pt[2] 21 | cv2.circle(img, (a, b), r, (0, 0, 0), 2) 22 | 23 | cv2.imshow('image', img) 24 | key = cv2.waitKey(0) 25 | cv2.destroyAllWindows() 26 | if key == ord('x'): 27 | break 28 | 29 | vs.stop() 30 | -------------------------------------------------------------------------------- /python/ch_08_detect_motion.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | from imutils.video import VideoStream 4 | from imutils import resize 5 | 6 | diff_threshold = 1000000 7 | 8 | vs = VideoStream(src=0).start() 9 | 10 | def getImage(): 11 | im = vs.read() 12 | im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) 13 | im = cv2.blur(im, (20, 20)) 14 | return im 15 | 16 | old_image = getImage() 17 | 18 | while True: 19 | new_image = getImage() 20 | diff = cv2.absdiff(old_image, new_image) 21 | diff_score = np.sum(diff) 22 | # print(diff_score) 23 | if diff_score > diff_threshold: 24 | print("Movement detected") 25 | old_image = new_image 26 | -------------------------------------------------------------------------------- /python/ch_08_faces.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | 3 | cv2_data_dir = '/usr/local/lib/python3.7/dist-packages/cv2/data/' 4 | face_cascade = cv2.CascadeClassifier(cv2_data_dir + 'haarcascade_frontalface_default.xml') 5 | 6 | img = cv2.imread('faces.jpg', cv2.IMREAD_GRAYSCALE) 7 | 8 | scale_factor = 1.4 9 | min_neighbours = 5 10 | 11 | faces = face_cascade.detectMultiScale(img, scale_factor, min_neighbours) 12 | print(faces) 13 | 14 | for (x,y,w,h) in faces: 15 | img = cv2.rectangle(img, (x,y), (x+w,y+h), (255, 255, 255), 2) 16 | 17 | cv2.imshow('image',img) 18 | cv2.waitKey(0) 19 | cv2.destroyAllWindows() 20 | -------------------------------------------------------------------------------- /python/ch_09_button_test.py: -------------------------------------------------------------------------------- 1 | from gpiozero import Button 2 | import time 3 | 4 | button = Button(7) 5 | 6 | while True: 7 | if button.is_pressed: 8 | print(time.time()) 9 | -------------------------------------------------------------------------------- /python/ch_09_explorer_hat_blink.py: -------------------------------------------------------------------------------- 1 | import explorerhat, time 2 | 3 | while True: 4 | explorerhat.light.red.on() 5 | time.sleep(0.5) 6 | explorerhat.light.red.off() 7 | time.sleep(0.5) 8 | -------------------------------------------------------------------------------- /python/ch_09_squid_test.py: -------------------------------------------------------------------------------- 1 | from gpiozero import RGBLED 2 | from time import sleep 3 | from colorzero import Color 4 | 5 | led = RGBLED(18, 23, 24) 6 | led.color = Color('red') 7 | sleep(2) 8 | led.color = Color('green') 9 | sleep(2) 10 | led.color = Color('blue') 11 | sleep(2) 12 | led.color = Color('white') 13 | sleep(2) 14 | 15 | -------------------------------------------------------------------------------- /python/ch_10_bluedot.py: -------------------------------------------------------------------------------- 1 | from bluedot import BlueDot 2 | bd = BlueDot() 3 | while True: 4 | bd.wait_for_press() 5 | print("You pressed the blue dot!") 6 | -------------------------------------------------------------------------------- /python/ch_10_gui_slider.py: -------------------------------------------------------------------------------- 1 | from gpiozero import PWMOutputDevice 2 | from guizero import App, Slider 3 | 4 | pin = PWMOutputDevice(18) 5 | 6 | def slider_changed(percent): 7 | pin.value = int(percent) / 100 8 | 9 | app = App(title='PWM', width=500, height=150) 10 | slider = Slider(app, command=slider_changed, width='fill', height=50) 11 | slider.text_size = 30 12 | app.display() 13 | -------------------------------------------------------------------------------- /python/ch_10_gui_slider_RGB.py: -------------------------------------------------------------------------------- 1 | from gpiozero import RGBLED 2 | from guizero import App, Slider 3 | from colorzero import Color 4 | 5 | rgb_led = RGBLED(18, 23, 24) 6 | 7 | red = 0 8 | green = 0 9 | blue = 0 10 | 11 | def red_changed(value): 12 | global red 13 | red = int(value) 14 | rgb_led.color = Color(red, green, blue) 15 | 16 | def green_changed(value): 17 | global green 18 | green = int(value) 19 | rgb_led.color = Color(red, green, blue) 20 | 21 | def blue_changed(value): 22 | global blue 23 | blue = int(value) 24 | rgb_led.color = Color(red, green, blue) 25 | 26 | app = App(title='RGB LED', width=500, height=400) 27 | 28 | Slider(app, command=red_changed, end=255, width='fill', height=50).text_size = 30 29 | Slider(app, command=green_changed, end=255, width='fill', height=50).text_size = 30 30 | Slider(app, command=blue_changed, end=255, width='fill', height=50).text_size = 30 31 | 32 | app.display() 33 | -------------------------------------------------------------------------------- /python/ch_10_gui_switch.py: -------------------------------------------------------------------------------- 1 | from gpiozero import DigitalOutputDevice 2 | from guizero import App, PushButton 3 | 4 | pin = DigitalOutputDevice(18) 5 | 6 | def start(): 7 | start_button.disable() 8 | stop_button.enable() 9 | pin.on() 10 | 11 | def stop(): 12 | start_button.enable() 13 | stop_button.disable() 14 | pin.off() 15 | 16 | app = App(width=100, height=150) 17 | start_button = PushButton(app, command=start, text="On") 18 | start_button.text_size = 30 19 | stop_button = PushButton(app, command=stop, text="Off", enabled=False) 20 | stop_button.text_size = 30 21 | app.display() 22 | -------------------------------------------------------------------------------- /python/ch_10_led_blink.py: -------------------------------------------------------------------------------- 1 | from gpiozero import LED 2 | from time import sleep 3 | 4 | led = LED(18) 5 | 6 | while True: 7 | led.on() 8 | sleep(0.5) 9 | led.off() 10 | sleep(0.5) 11 | -------------------------------------------------------------------------------- /python/ch_10_led_blink_2.py: -------------------------------------------------------------------------------- 1 | from gpiozero import LED 2 | 3 | led = LED(18) 4 | 5 | led.blink(0.5, 0.5, background=True) 6 | 7 | print("Notice that control has moved away - hit Enter to continue") 8 | input() 9 | print("Control is now back") 10 | led.off() 11 | input() 12 | -------------------------------------------------------------------------------- /python/ch_10_led_brightness.py: -------------------------------------------------------------------------------- 1 | from gpiozero import PWMLED 2 | 3 | led = PWMLED(18) 4 | 5 | while True: 6 | brightness_s = input("Enter Brightness (0.0 to 1.0):") 7 | brightness = float(brightness_s) 8 | led.value = brightness 9 | -------------------------------------------------------------------------------- /python/ch_10_pwm_f_test.py: -------------------------------------------------------------------------------- 1 | from gpiozero import PWMLED 2 | 3 | led = PWMLED(18) 4 | 5 | while True: 6 | f_s = input("Enter Frequncy in Hz:") 7 | f = int(f_s) 8 | led.close() 9 | led = PWMLED(18, frequency=f) 10 | led.value = 0.5 11 | -------------------------------------------------------------------------------- /python/ch_11_motor_control.py: -------------------------------------------------------------------------------- 1 | from gpiozero import Motor 2 | 3 | motor = Motor(forward=23, backward=24) 4 | 5 | while True: 6 | cmd = input("Command, f/r 0..9, E.g. f5 :") 7 | direction = cmd[0] 8 | speed = float(cmd[1]) / 10.0 9 | if direction == "f": 10 | motor.forward(speed=speed) 11 | else: 12 | motor.backward(speed=speed) 13 | 14 | -------------------------------------------------------------------------------- /python/ch_11_rover.py: -------------------------------------------------------------------------------- 1 | # Use the arrow keys to direct the robot 2 | 3 | from rrb4 import * 4 | import sys 5 | import tty 6 | import termios 7 | 8 | rr = RRB4(6.0, 6.0) # battery, motor 9 | 10 | UP = 0 11 | DOWN = 1 12 | RIGHT = 2 13 | LEFT = 3 14 | 15 | print("Use the arrow keys to move the robot") 16 | print("Press CTRL-c to quit the program") 17 | 18 | # These functions allow the program to read your keyboard 19 | def readchar(): 20 | fd = sys.stdin.fileno() 21 | old_settings = termios.tcgetattr(fd) 22 | try: 23 | tty.setraw(sys.stdin.fileno()) 24 | ch = sys.stdin.read(1) 25 | finally: 26 | termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) 27 | if ch == '0x03': 28 | raise KeyboardInterrupt 29 | return ch 30 | 31 | def readkey(getchar_fn=None): 32 | getchar = getchar_fn or readchar 33 | c1 = getchar() 34 | if ord(c1) != 0x1b: 35 | return c1 36 | c2 = getchar() 37 | if ord(c2) != 0x5b: 38 | return c1 39 | c3 = getchar() 40 | return ord(c3) - 65 # 0=Up, 1=Down, 2=Right, 3=Left arrows 41 | 42 | # This will control the movement of your robot and display on your screen 43 | try: 44 | while True: 45 | keyp = readkey() 46 | if keyp == UP: 47 | rr.forward(1) 48 | print('forward') 49 | elif keyp == DOWN: 50 | rr.reverse(1) 51 | print('backward') 52 | elif keyp == RIGHT: 53 | rr.right(1) 54 | print('clockwise') 55 | elif keyp == LEFT: 56 | rr.left(1) 57 | print('anti clockwise') 58 | elif keyp == LEFT: 59 | rr.left(1) 60 | print('anti clockwise') 61 | elif ord(keyp) == 3: 62 | break 63 | 64 | except KeyboardInterrupt: 65 | GPIO.cleanup() 66 | 67 | -------------------------------------------------------------------------------- /python/ch_11_servo.py: -------------------------------------------------------------------------------- 1 | from gpiozero import AngularServo 2 | from guizero import App, Slider 3 | 4 | servo = AngularServo(18, min_pulse_width=0.5/1000, max_pulse_width=2.5/1000) 5 | 6 | def slider_changed(angle): 7 | servo.angle = int(angle) 8 | 9 | app = App(title='Servo Angle', width=500, height=150) 10 | slider = Slider(app, start=-90, end=90, command=slider_changed, width='fill', height=50) 11 | slider.text_size = 30 12 | app.display() 13 | -------------------------------------------------------------------------------- /python/ch_11_servo_adafruit.py: -------------------------------------------------------------------------------- 1 | from adafruit_servokit import ServoKit 2 | from guizero import App, Slider 3 | 4 | servo_kit = ServoKit(channels=16) 5 | 6 | def slider_changed(angle): 7 | servo_kit.servo[0].angle = int(angle) + 90 8 | 9 | app = App(title='Servo Angle', width=500, height=150) 10 | slider = Slider(app, start=-90, end=90, command=slider_changed, width='fill', height=50) 11 | slider.text_size = 30 12 | app.display() 13 | -------------------------------------------------------------------------------- /python/ch_11_servo_blaster.py: -------------------------------------------------------------------------------- 1 | import os 2 | from guizero import App, Slider 3 | 4 | servo_min = 500 # uS 5 | servo_max = 2500 # uS 6 | servo = 2 # GPIO 18 7 | 8 | def map(value, from_low, from_high, to_low, to_high): 9 | from_range = from_high - from_low 10 | to_range = to_high - to_low 11 | scale_factor = float(from_range) / float(to_range) 12 | return to_low + (value / scale_factor) 13 | 14 | def set_angle(angle): 15 | pulse = int(map(angle+90, 0, 180, servo_min, servo_max)) 16 | command = "echo {}={}us > /dev/servoblaster".format(servo, pulse) 17 | os.system(command) 18 | 19 | def slider_changed(angle): 20 | set_angle(int(angle)) 21 | 22 | app = App(title='Servo Angle', width=500, height=150) 23 | slider = Slider(app, start=-90, end=90, command=slider_changed, width='fill', height=50) 24 | slider.text_size = 30 25 | app.display() 26 | -------------------------------------------------------------------------------- /python/ch_11_stepper.py: -------------------------------------------------------------------------------- 1 | from gpiozero import Motor 2 | import time 3 | 4 | coil1 = Motor(forward=18, backward=23, pwm=False) 5 | coil2 = Motor(forward=24, backward=17, pwm=False) 6 | 7 | forward_seq = ['FF', 'BF', 'BB', 'FB'] 8 | reverse_seq = list(forward_seq) # to copy the list 9 | reverse_seq.reverse() 10 | 11 | def forward(delay, steps): 12 | for i in range(steps): 13 | for step in forward_seq: 14 | set_step(step) 15 | time.sleep(delay) 16 | 17 | def backwards(delay, steps): 18 | for i in range(steps): 19 | for step in reverse_seq: 20 | set_step(step) 21 | time.sleep(delay) 22 | 23 | def set_step(step): 24 | if step == 'S': 25 | coil1.stop() 26 | coil2.stop() 27 | else: 28 | if step[0] == 'F': 29 | coil1.forward() 30 | else: 31 | coil1.backward() 32 | if step[1] == 'F': 33 | coil2.forward() 34 | else: 35 | coil2.backward() 36 | 37 | 38 | while True: 39 | set_step('S') 40 | delay = input("Delay between steps (milliseconds)?") 41 | steps = input("How many steps forward? ") 42 | forward(int(delay) / 1000.0, int(steps)) 43 | set_step('S') 44 | steps = input("How many steps backwards? ") 45 | backwards(int(delay) / 1000.0, int(steps)) 46 | -------------------------------------------------------------------------------- /python/ch_11_stepper_rrb.py: -------------------------------------------------------------------------------- 1 | from rrb4 import * 2 | import time 3 | 4 | rr = RRB4(12.0, 12.0) # battery, motor 5 | 6 | try: 7 | while True: 8 | delay = input("Delay between steps (milliseconds)?") 9 | steps = input("How many steps forward? ") 10 | rr.step_forward(int(delay) / 1000.0, int(steps)) 11 | steps = input("How many steps backwards? ") 12 | rr.step_reverse(int(delay) / 1000.0, int(steps)) 13 | 14 | finally: 15 | GPIO.cleanup() 16 | -------------------------------------------------------------------------------- /python/ch_12_gps_test.py: -------------------------------------------------------------------------------- 1 | from gps import * 2 | session = gps() 3 | session.stream(WATCH_ENABLE|WATCH_NEWSTYLE) 4 | 5 | while True: 6 | report = session.next() 7 | if report.keys()[0] == 'epx' : 8 | lat = float(report['lat']) 9 | lon = float(report['lon']) 10 | print("lat=%f\tlon=%f\ttime=%s" % (lat, lon, report['time'])) 11 | time.sleep(0.5) 12 | -------------------------------------------------------------------------------- /python/ch_12_key_sys.py: -------------------------------------------------------------------------------- 1 | import sys, tty, termios 2 | 3 | def read_ch(): 4 | fd = sys.stdin.fileno() 5 | old_settings = termios.tcgetattr(fd) 6 | try: 7 | tty.setraw(sys.stdin.fileno()) 8 | ch = sys.stdin.read(1) 9 | finally: 10 | termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) 11 | return ch 12 | 13 | while True: 14 | ch = read_ch() 15 | if ch == 'x': 16 | break 17 | print("key is: " + ch) 18 | -------------------------------------------------------------------------------- /python/ch_12_keypad.py: -------------------------------------------------------------------------------- 1 | from gpiozero import Button, DigitalOutputDevice 2 | import time 3 | 4 | rows = [Button(17), Button(25), Button(24), Button(23)] 5 | cols = [DigitalOutputDevice(27), DigitalOutputDevice(18), DigitalOutputDevice(22)] 6 | keys = [ 7 | ['1', '2', '3'], 8 | ['4', '5', '6'], 9 | ['7', '8', '9'], 10 | ['*', '0', '#']] 11 | 12 | def get_key(): 13 | key = 0 14 | for col_num, col_pin in enumerate(cols): 15 | col_pin.off() 16 | for row_num, row_pin in enumerate(rows): 17 | if row_pin.is_pressed: 18 | key = keys[row_num][col_num] 19 | col_pin.on() 20 | return key 21 | 22 | while True: 23 | key = get_key() 24 | if key : 25 | print(key) 26 | time.sleep(0.3) 27 | -------------------------------------------------------------------------------- /python/ch_12_keys_pygame.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import sys 3 | from pygame.locals import * 4 | 5 | pygame.init() 6 | screen = pygame.display.set_mode((640, 480)) 7 | pygame.mouse.set_visible(0) 8 | 9 | while True: 10 | for event in pygame.event.get(): 11 | if event.type == QUIT: 12 | sys.exit() 13 | if event.type == KEYDOWN: 14 | print("Code: " + str(event.key) + " Char: " + chr(event.key)) 15 | -------------------------------------------------------------------------------- /python/ch_12_mouse_pygame.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import sys 3 | from pygame.locals import * 4 | 5 | pygame.init() 6 | screen = pygame.display.set_mode((640, 480)) 7 | pygame.mouse.set_visible(0) 8 | 9 | while True: 10 | for event in pygame.event.get(): 11 | if event.type == QUIT: 12 | sys.exit() 13 | if event.type == MOUSEMOTION: 14 | print("Mouse: (%d, %d)" % event.pos) 15 | -------------------------------------------------------------------------------- /python/ch_12_pir.py: -------------------------------------------------------------------------------- 1 | from gpiozero import MotionSensor 2 | 3 | pir = MotionSensor(18) 4 | 5 | while True: 6 | pir.wait_for_motion() 7 | print("Motion detected!") 8 | -------------------------------------------------------------------------------- /python/ch_12_rotary_encoder.py: -------------------------------------------------------------------------------- 1 | from gpiozero import Button 2 | import time 3 | 4 | input_A = Button(18) 5 | input_B = Button(23) 6 | 7 | old_a = True 8 | old_b = True 9 | 10 | def get_encoder_turn(): 11 | # return -1, 0, or +1 12 | global old_a, old_b 13 | result = 0 14 | new_a = input_A.is_pressed 15 | new_b = input_B.is_pressed 16 | if new_a != old_a or new_b != old_b : 17 | if old_a == 0 and new_a == 1 : 18 | result = (old_b * 2 - 1) 19 | elif old_b == 0 and new_b == 1 : 20 | result = -(old_a * 2 - 1) 21 | old_a, old_b = new_a, new_b 22 | time.sleep(0.001) 23 | return result 24 | 25 | x = 0 26 | 27 | while True: 28 | change = get_encoder_turn() 29 | if change != 0 : 30 | x = x + change 31 | print(x) 32 | -------------------------------------------------------------------------------- /python/ch_12_switch.py: -------------------------------------------------------------------------------- 1 | from gpiozero import Button 2 | 3 | button = Button(18) 4 | 5 | while True: 6 | if button.is_pressed: 7 | print("Button Pressed") 8 | -------------------------------------------------------------------------------- /python/ch_12_switch_2.py: -------------------------------------------------------------------------------- 1 | from gpiozero import Button 2 | from time import sleep 3 | 4 | def do_stuff(): 5 | print("Button Pressed") 6 | 7 | button = Button(18) 8 | button.when_pressed = do_stuff 9 | 10 | while True: 11 | print("Busy doing other stuff") 12 | sleep(2) 13 | -------------------------------------------------------------------------------- /python/ch_12_switch_3_pos.py: -------------------------------------------------------------------------------- 1 | from gpiozero import Button 2 | 3 | switch_top = Button(18) 4 | switch_bottom = Button(23) 5 | 6 | switch_position = "unknown" 7 | 8 | while True: 9 | new_switch_position = "unknown" 10 | if switch_top.is_pressed: 11 | new_switch_position = "top" 12 | elif switch_bottom.is_pressed: 13 | new_switch_position = "bottom" 14 | else: 15 | new_switch_position = "center" 16 | 17 | if new_switch_position != switch_position: 18 | switch_position = new_switch_position 19 | print(switch_position) 20 | -------------------------------------------------------------------------------- /python/ch_12_switch_on_off.py: -------------------------------------------------------------------------------- 1 | from gpiozero import Button, LED 2 | from time import sleep 3 | 4 | led = LED(23) 5 | 6 | def toggle_led(): 7 | print("toggling") 8 | led.toggle() 9 | 10 | button = Button(18) 11 | button.when_pressed = toggle_led 12 | 13 | 14 | while True: 15 | print("Busy doing other stuff") 16 | sleep(2) 17 | -------------------------------------------------------------------------------- /python/ch_13_adc_scaled.py: -------------------------------------------------------------------------------- 1 | from gpiozero import MCP3008 2 | import time 3 | 4 | R1 = 10000.0 5 | R2 = 3300.0 6 | analog_input = MCP3008(channel=0) 7 | 8 | while True: 9 | reading = analog_input.value 10 | voltage_adc = reading * 3.3 11 | voltage_actual = voltage_adc / (R2 / (R1 + R2)) 12 | print("Battery Voltage=" + str(voltage_actual)) 13 | time.sleep(1) 14 | -------------------------------------------------------------------------------- /python/ch_13_adc_test.py: -------------------------------------------------------------------------------- 1 | from gpiozero import MCP3008 2 | import time 3 | 4 | analog_input = MCP3008(channel=0) 5 | 6 | while True: 7 | reading = analog_input.value 8 | voltage = reading * 3.3 9 | print("Reading={:.2f}\tVoltage={:.2f}".format(reading, voltage)) 10 | time.sleep(1) 11 | -------------------------------------------------------------------------------- /python/ch_13_adc_tmp36.py: -------------------------------------------------------------------------------- 1 | from gpiozero import MCP3008 2 | import time 3 | 4 | analog_input = MCP3008(channel=0) 5 | 6 | while True: 7 | reading = analog_input.value 8 | voltage = reading * 3.3 9 | temp_c = voltage * 100 - 50 10 | temp_f = temp_c * 9.0 / 5.0 + 32 11 | print("Temp C={:.2f}\tTemp F={:.2f}".format(temp_c, temp_f)) 12 | time.sleep(1) 13 | -------------------------------------------------------------------------------- /python/ch_13_co2.py: -------------------------------------------------------------------------------- 1 | import serial, time 2 | 3 | request_reading = bytes([0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79]) 4 | 5 | def read_co2(): 6 | sensor.write(request_reading) 7 | time.sleep(0.1) 8 | raw_data = sensor.read(9) 9 | high = raw_data[2] 10 | low = raw_data[3] 11 | return high * 256 + low; 12 | 13 | sensor = serial.Serial('/dev/ttyS0') 14 | print(sensor.name) 15 | if sensor.is_open: 16 | print("Open") 17 | 18 | while True: 19 | print("CO2 (ppm):" + str(read_co2())) 20 | time.sleep(1) 21 | -------------------------------------------------------------------------------- /python/ch_13_cpu_temp.py: -------------------------------------------------------------------------------- 1 | import os, time 2 | 3 | while True: 4 | dev = os.popen('/opt/vc/bin/vcgencmd measure_temp') 5 | cpu_temp = dev.read() 6 | print(cpu_temp) 7 | time.sleep(1) 8 | -------------------------------------------------------------------------------- /python/ch_13_cpu_temp_float.py: -------------------------------------------------------------------------------- 1 | import os, time 2 | 3 | while True: 4 | dev = os.popen('/opt/vc/bin/vcgencmd measure_temp') 5 | cpu_temp_s = dev.read()[5:-3] # top and tail string 6 | cpu_temp = float(cpu_temp_s) 7 | print(cpu_temp) 8 | time.sleep(1) 9 | -------------------------------------------------------------------------------- /python/ch_13_gui_sensor_reading.py: -------------------------------------------------------------------------------- 1 | import VL53L1X, time 2 | from guizero import App, Text 3 | 4 | tof = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29) 5 | tof.open() 6 | tof.start_ranging(1) 7 | 8 | def update_reading(): 9 | mm = tof.get_distance() 10 | reading_text.value = str(mm) 11 | 12 | app = App(width=300, height=150) 13 | reading_text = Text(app, size=100) 14 | reading_text.repeat(1000, update_reading) 15 | app.display() 16 | -------------------------------------------------------------------------------- /python/ch_13_i2c_acc.py: -------------------------------------------------------------------------------- 1 | import smbus 2 | import time 3 | 4 | bus = smbus.SMBus(1) 5 | 6 | i2c_address = 0x1D 7 | control_reg = 0x2A 8 | 9 | bus.write_byte_data(i2c_address, control_reg, 0x01) # Start 10 | bus.write_byte_data(i2c_address, 0x0E, 0x00) # 2g range 11 | 12 | time.sleep(0.5) 13 | 14 | def read_acc(): 15 | data = bus.read_i2c_block_data(i2c_address, 0x00, 7) 16 | x = (data[1] * 256 + data[2]) / 16 17 | if x > 2047 : 18 | x -= 4096 19 | y = (data[3] * 256 + data[4]) / 16 20 | if y > 2047 : 21 | y -= 4096 22 | z = (data[5] * 256 + data[6]) / 16 23 | if z > 2047 : 24 | z -= 4096 25 | return (x, y, z) 26 | 27 | while True: 28 | x, y, z = read_acc() 29 | print("x={:.2f}\ty={:.2f}\tz={:.2f}".format(x, y, z)) 30 | time.sleep(0.5) 31 | -------------------------------------------------------------------------------- /python/ch_13_i2c_acc_tilt.py: -------------------------------------------------------------------------------- 1 | import smbus 2 | import time 3 | 4 | bus = smbus.SMBus(1) 5 | 6 | i2c_address = 0x1D 7 | control_reg = 0x2A 8 | 9 | bus.write_byte_data(i2c_address, control_reg, 0x01) # Start 10 | bus.write_byte_data(i2c_address, 0x0E, 0x00) # 2g range 11 | 12 | time.sleep(0.5) 13 | 14 | def read_acc(): 15 | data = bus.read_i2c_block_data(i2c_address, 0x00, 7) 16 | x = (data[1] * 256 + data[2]) / 16 17 | if x > 2047 : 18 | x -= 4096 19 | y = (data[3] * 256 + data[4]) / 16 20 | if y > 2047 : 21 | y -= 4096 22 | z = (data[5] * 256 + data[6]) / 16 23 | if z > 2047 : 24 | z -= 4096 25 | return (x, y, z) 26 | 27 | while True: 28 | x, y, z = read_acc() 29 | if x > 400: 30 | print("Left") 31 | elif x < -400: 32 | print("Right") 33 | elif y > 400: 34 | print("Back") 35 | elif y < -400: 36 | print("Forward") 37 | time.sleep(0.2) 38 | -------------------------------------------------------------------------------- /python/ch_13_ranger.py: -------------------------------------------------------------------------------- 1 | from gpiozero import DistanceSensor 2 | from time import sleep 3 | 4 | sensor = DistanceSensor(echo=18, trigger=17) 5 | while True: 6 | cm = sensor.distance * 100 7 | inch = cm / 2.5 8 | print("cm={:.1f}\tinches={:.1f}".format(cm, inch)) 9 | sleep(0.5) 10 | -------------------------------------------------------------------------------- /python/ch_13_resistance_meter.py: -------------------------------------------------------------------------------- 1 | from PiAnalog import * 2 | import time 3 | 4 | p = PiAnalog() 5 | 6 | while True: 7 | print(p.read_resistance()) 8 | time.sleep(1) 9 | -------------------------------------------------------------------------------- /python/ch_13_sense_hat_compass.py: -------------------------------------------------------------------------------- 1 | from sense_hat import SenseHat 2 | import time 3 | 4 | sense = SenseHat() 5 | 6 | while True: 7 | bearing = sense.get_compass() 8 | print('Bearing: {:.0f} to North'.format(bearing)) 9 | time.sleep(0.5) 10 | -------------------------------------------------------------------------------- /python/ch_13_sense_hat_magnet.py: -------------------------------------------------------------------------------- 1 | from sense_hat import SenseHat 2 | import time 3 | 4 | hat = SenseHat() 5 | fill = (255, 0, 0) 6 | 7 | while True: 8 | reading = int(hat.get_compass_raw()['z']) 9 | if reading > 200: 10 | hat.clear(fill) 11 | time.sleep(0.2) 12 | else: 13 | hat.clear() 14 | -------------------------------------------------------------------------------- /python/ch_13_sense_hat_orientation.py: -------------------------------------------------------------------------------- 1 | from sense_hat import SenseHat 2 | 3 | sense = SenseHat() 4 | sense.set_imu_config(True, True, True) 5 | 6 | while True: 7 | o = sense.get_orientation() 8 | print("p: {:.0f}, r: {:.0f}, y: {:.0f}".format(o['pitch'], o['roll'], o['yaw'])) 9 | -------------------------------------------------------------------------------- /python/ch_13_sense_hat_thp.py: -------------------------------------------------------------------------------- 1 | from sense_hat import SenseHat 2 | import time 3 | 4 | hat = SenseHat() 5 | 6 | while True: 7 | t = hat.get_temperature() 8 | h = hat.get_humidity() 9 | p = hat.get_pressure() 10 | print('Temp C:{:.2f} Hum:{:.0f} Pres:{:.0f}'.format(t, h, p)) 11 | time.sleep(1) 12 | -------------------------------------------------------------------------------- /python/ch_13_temp_DS18B20.py: -------------------------------------------------------------------------------- 1 | import glob, time 2 | 3 | base_dir = '/sys/bus/w1/devices/' 4 | device_folder = glob.glob(base_dir + '28*')[0] 5 | device_file = device_folder + '/w1_slave' 6 | 7 | def read_temp_raw(): 8 | f = open(device_file, 'r') 9 | lines = f.readlines() 10 | f.close() 11 | return lines 12 | 13 | def read_temp(): 14 | lines = read_temp_raw() 15 | while lines[0].strip()[-3:] != 'YES': 16 | time.sleep(0.2) 17 | lines = read_temp_raw() 18 | equals_pos = lines[1].find('t=') 19 | if equals_pos != -1: 20 | temp_string = lines[1][equals_pos+2:] 21 | temp_c = float(temp_string) / 1000.0 22 | temp_f = temp_c * 9.0 / 5.0 + 32.0 23 | return temp_c, temp_f 24 | 25 | while True: 26 | temp_c, temp_f = read_temp() 27 | print('Temp C={:.2f}\ttemp F={:.2f}'.format(temp_c, temp_f)) 28 | time.sleep(1) 29 | -------------------------------------------------------------------------------- /python/ch_13_temp_log.py: -------------------------------------------------------------------------------- 1 | import os, glob, time, datetime 2 | 3 | log_period = 60 # seconds 4 | 5 | logging_folder = glob.glob('/media/*')[0] 6 | dt = datetime.datetime.now() 7 | file_name = "temp_log_{:%Y_%m_%d}.csv".format(dt) 8 | logging_file = logging_folder + '/' + file_name 9 | 10 | def read_temp(): 11 | dev = os.popen('/opt/vc/bin/vcgencmd measure_temp') 12 | cpu_temp = cpu_temp_s = dev.read()[5:-3] # top and tail string 13 | return cpu_temp 14 | 15 | def log_temp(): 16 | temp_c = read_temp() 17 | dt = datetime.datetime.now() 18 | f = open(logging_file, 'a') 19 | line = '\n"{:%H:%M:%S}","{}"'.format(dt, temp_c) 20 | f.write(line) 21 | print(line) 22 | f.close() 23 | 24 | print("Logging to: " + logging_file) 25 | while True: 26 | log_temp() 27 | time.sleep(log_period) 28 | -------------------------------------------------------------------------------- /python/ch_13_thermistor.py: -------------------------------------------------------------------------------- 1 | from PiAnalog import * 2 | import time 3 | 4 | p = PiAnalog() 5 | 6 | while True: 7 | print(p.read_temp_c()) 8 | time.sleep(1) 9 | -------------------------------------------------------------------------------- /python/ch_13_tof.py: -------------------------------------------------------------------------------- 1 | import VL53L1X, time 2 | 3 | tof = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29) 4 | tof.open() 5 | tof.start_ranging(1) # Start range1=Short 2=Medium 3=Long 6 | 7 | while True: 8 | mm = tof.get_distance() # Grab the range in mm 9 | print("mm=" + str(mm)) 10 | time.sleep(1) 11 | -------------------------------------------------------------------------------- /python/ch_13_touch.py: -------------------------------------------------------------------------------- 1 | import time 2 | import board 3 | import busio 4 | import adafruit_mpr121 5 | i2c = busio.I2C(board.SCL, board.SDA) 6 | mpr121 = adafruit_mpr121.MPR121(i2c) 7 | 8 | while True: 9 | if mpr121[0].value: 10 | print("Pin 0 touched!") 11 | -------------------------------------------------------------------------------- /python/ch_14_displayotron_ip.py: -------------------------------------------------------------------------------- 1 | import dothat.lcd as lcd 2 | import dothat.backlight as backlight 3 | import time 4 | from datetime import datetime 5 | import subprocess 6 | 7 | while True: 8 | lcd.clear() 9 | backlight.rgb(0, 255, 0) 10 | try: 11 | hostname = subprocess.check_output(['hostname']).split()[0] 12 | ip = subprocess.check_output(['hostname', '-I']).split()[0] 13 | t = '{:%H:%M:%S}'.format(datetime.now()) 14 | lcd.write(hostname) 15 | lcd.set_cursor_position(0, 1) 16 | lcd.write(ip) 17 | lcd.set_cursor_position(0, 2) 18 | lcd.write(t) 19 | except: 20 | backlight.rgb(255, 0, 0) 21 | time.sleep(1) 22 | -------------------------------------------------------------------------------- /python/ch_14_neopixel.py: -------------------------------------------------------------------------------- 1 | import time 2 | import board 3 | from neopixel import NeoPixel 4 | 5 | led_count = 5 6 | red = (100, 0, 0) 7 | no_color = (0, 0, 0) 8 | 9 | strip = NeoPixel(board.D18, led_count, auto_write=False) 10 | 11 | def clear(): 12 | for i in range(0, led_count): 13 | strip[i] = no_color 14 | strip.show() 15 | 16 | 17 | i = 0 18 | while True: 19 | clear() 20 | strip[i] = red 21 | strip.show() 22 | time.sleep(1) 23 | i += 1 24 | if i >= led_count: 25 | i = 0 26 | -------------------------------------------------------------------------------- /python/ch_14_oled_clock.py: -------------------------------------------------------------------------------- 1 | import Adafruit_SSD1306 2 | from PIL import Image, ImageDraw, ImageFont 3 | import time 4 | from datetime import datetime 5 | 6 | # Set up display 7 | disp = Adafruit_SSD1306.SSD1306_128_64(rst=None, i2c_address=0x3C) 8 | small_font = ImageFont.truetype('FreeSans.ttf', 12) 9 | large_font = ImageFont.truetype('FreeSans.ttf', 33) 10 | disp.begin() 11 | disp.clear() 12 | disp.display() 13 | # Make an image to draw on in 1-bit color. 14 | width = disp.width 15 | height = disp.height 16 | image = Image.new('1', (width, height)) 17 | draw = ImageDraw.Draw(image) 18 | 19 | # Display a message on 3 lines, first line big font 20 | def display_message(top_line, line_2): 21 | draw.rectangle((0,0,width,height), outline=0, fill=0) 22 | draw.text((0, 0), top_line, font=large_font, fill=255) 23 | draw.text((0, 50), line_2, font=small_font, fill=255) 24 | disp.image(image) 25 | disp.display() 26 | 27 | while True: 28 | now = datetime.now() 29 | date_message = '{:%d %B %Y}'.format(now) 30 | time_message = '{:%H:%M:%S}'.format(now) 31 | display_message(time_message, date_message) 32 | time.sleep(0.1) 33 | -------------------------------------------------------------------------------- /python/ch_14_phat.py: -------------------------------------------------------------------------------- 1 | from inky import InkyPHAT 2 | from PIL import Image, ImageFont, ImageDraw 3 | from font_fredoka_one import FredokaOne 4 | import subprocess 5 | 6 | inky_display = InkyPHAT("red") 7 | inky_display.set_border(inky_display.WHITE) 8 | 9 | img = Image.new("P", (inky_display.WIDTH, inky_display.HEIGHT)) 10 | draw = ImageDraw.Draw(img) 11 | font = ImageFont.truetype(FredokaOne, 22) 12 | 13 | message = str(subprocess.check_output(['hostname', '-I'])).split()[0][2:] 14 | print(message) 15 | 16 | w, h = font.getsize(message) 17 | x = (inky_display.WIDTH / 2) - (w / 2) 18 | y = (inky_display.HEIGHT / 2) - (h / 2) 19 | 20 | draw.text((x, y), message, inky_display.RED, font) 21 | inky_display.set_image(img) 22 | inky_display.show() 23 | -------------------------------------------------------------------------------- /python/ch_14_sense_hat_clock.py: -------------------------------------------------------------------------------- 1 | from sense_hat import SenseHat 2 | from datetime import datetime 3 | import time 4 | 5 | hat = SenseHat() 6 | time_color = (0, 255, 0) 7 | date_color = (255, 0, 0) 8 | 9 | while True: 10 | now = datetime.now() 11 | date_message = '{:%d %B %Y}'.format(now) 12 | time_message = '{:%H:%M:%S}'.format(now) 13 | 14 | hat.show_message(date_message, text_colour=date_color) 15 | hat.show_message(time_message, text_colour=time_color) 16 | -------------------------------------------------------------------------------- /python/ch_14_unicorn.py: -------------------------------------------------------------------------------- 1 | import time 2 | import unicornhat as unicorn 3 | from random import randint 4 | 5 | unicorn.set_layout(unicorn.AUTO) 6 | unicorn.rotation(0) 7 | unicorn.brightness(1) 8 | width, height = unicorn.get_shape() 9 | 10 | while True: 11 | x = randint(0, width) 12 | y = randint(0, height) 13 | r, g, b = (randint(0, 255), randint(0, 255), randint(0, 255)) 14 | unicorn.set_pixel(x, y, r, g, b) 15 | unicorn.show() 16 | time.sleep(0.01) 17 | 18 | time.sleep(1) 19 | -------------------------------------------------------------------------------- /python/ch_15_buzzer.py: -------------------------------------------------------------------------------- 1 | from gpiozero import Buzzer 2 | 3 | buzzer = Buzzer(18) 4 | 5 | def buzz(pitch, duration): 6 | period = 1.0 / pitch 7 | delay = period / 2 8 | cycles = int(duration * pitch) 9 | buzzer.beep(on_time=period, off_time=period, n=int(cycles/2)) 10 | 11 | while True: 12 | pitch_s = input("Enter Pitch (200 to 2000): ") 13 | pitch = float(pitch_s) 14 | duration_s = input("Enter Duration (seconds): ") 15 | duration = float(duration_s) 16 | buzz(pitch, duration) 17 | -------------------------------------------------------------------------------- /python/ch_15_play_sound.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | sound_file = '/home/pi/raspberrypi_cookbook_ed3/python/school_bell.mp3' 4 | sound_out = 'local' 5 | 6 | subprocess.run(['omxplayer', '-o', sound_out, sound_file]) 7 | -------------------------------------------------------------------------------- /python/ch_15_play_sound_pygame.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | 3 | sound_file = '/home/pi/raspberrypi_cookbook_ed3/python/school_bell.wav' 4 | 5 | pygame.mixer.init() 6 | pygame.mixer.music.load(sound_file) 7 | pygame.mixer.music.play() 8 | 9 | while pygame.mixer.music.get_busy() == True: 10 | continue 11 | -------------------------------------------------------------------------------- /python/ch_16_cheerlights.py: -------------------------------------------------------------------------------- 1 | from gpiozero import RGBLED 2 | from colorzero import Color 3 | import time, requests 4 | 5 | led = RGBLED(18, 23, 24) 6 | cheerlights_url = "http://api.thingspeak.com/channels/1417/field/2/last.txt" 7 | 8 | while True: 9 | try: 10 | cheerlights = requests.get(cheerlights_url) 11 | c = cheerlights.content 12 | print(c) 13 | led.color = Color(c) 14 | except Exception as e: 15 | print(e) 16 | time.sleep(2) 17 | -------------------------------------------------------------------------------- /python/ch_16_ifttt_cpu_temp.py: -------------------------------------------------------------------------------- 1 | import time, os 2 | import requests 3 | 4 | MAX_TEMP = 37.0 5 | MIN_T_BETWEEN_WARNINGS = 60 # Minutes 6 | 7 | EVENT = 'cpu_too_hot' 8 | BASE_URL = 'https://maker.ifttt.com/trigger/' 9 | KEY = 'your_key_here' 10 | 11 | def send_notification(temp): 12 | data = {'value1' : temp} 13 | url = BASE_URL + EVENT + '/with/key/' + KEY 14 | response = requests.post(url, json=data) 15 | print(response.status_code) 16 | 17 | def cpu_temp(): 18 | dev = os.popen('/opt/vc/bin/vcgencmd measure_temp') 19 | cpu_temp = dev.read()[5:-3] 20 | return float(cpu_temp) 21 | 22 | while True: 23 | temp = cpu_temp() 24 | print("CPU Temp (C): " + str(temp)) 25 | if temp > MAX_TEMP: 26 | print("CPU TOO HOT!") 27 | send_notification(temp) 28 | print("No more notifications for: " + str(MIN_T_BETWEEN_WARNINGS) + " mins") 29 | time.sleep(MIN_T_BETWEEN_WARNINGS * 60) 30 | time.sleep(1) 31 | 32 | -------------------------------------------------------------------------------- /python/ch_16_send_tweet.py: -------------------------------------------------------------------------------- 1 | import time, os 2 | import requests 3 | 4 | MAX_TEMP = 37.0 5 | MIN_T_BETWEEN_WARNINGS = 60 # Minutes 6 | 7 | BASE_URL = 'https://api.thingspeak.com/apps/thingtweet/1/statuses/update/' 8 | KEY = 'your_key_here' 9 | 10 | def send_notification(temp): 11 | status = 'Thingtweet: Raspberry Pi getting hot. CPU temp=' + str(temp) 12 | data = {'api_key' : KEY, 'status' : status} 13 | response = requests.post(BASE_URL, json=data) 14 | print(response.status_code) 15 | 16 | def cpu_temp(): 17 | dev = os.popen('/opt/vc/bin/vcgencmd measure_temp') 18 | cpu_temp = dev.read()[5:-3] 19 | return float(cpu_temp) 20 | 21 | while True: 22 | temp = cpu_temp() 23 | print("CPU Temp (C): " + str(temp)) 24 | if temp > MAX_TEMP: 25 | print("CPU TOO HOT!") 26 | send_notification(temp) 27 | print("No more notifications for: " + str(MIN_T_BETWEEN_WARNINGS) + " mins") 28 | time.sleep(MIN_T_BETWEEN_WARNINGS * 60) 29 | time.sleep(1) 30 | 31 | -------------------------------------------------------------------------------- /python/ch_16_thingspeak_data.py: -------------------------------------------------------------------------------- 1 | import time, os 2 | import requests 3 | 4 | 5 | PERIOD = 60 # seconds 6 | BASE_URL = 'https://api.thingspeak.com/update.json' 7 | KEY = 'your key goes here' 8 | 9 | def send_data(temp): 10 | data = {'api_key' : KEY, 'field1' : temp} 11 | response = requests.post(BASE_URL, json=data) 12 | 13 | def cpu_temp(): 14 | dev = os.popen('/opt/vc/bin/vcgencmd measure_temp') 15 | cpu_temp = dev.read()[5:-3] 16 | return float(cpu_temp) 17 | 18 | while True: 19 | temp = cpu_temp() 20 | print("CPU Temp (C): " + str(temp)) 21 | send_data(temp) 22 | time.sleep(PERIOD) 23 | -------------------------------------------------------------------------------- /python/ch_16_twitter_trigger.py: -------------------------------------------------------------------------------- 1 | import time 2 | import dweepy 3 | from gpiozero import LED 4 | 5 | KEY = 'tweet_about_me' 6 | led = LED(18) 7 | 8 | while True: 9 | try: 10 | for dweet in dweepy.listen_for_dweets_from(KEY): 11 | print('Tweet: ' + dweet['content']['text']) 12 | led.on() 13 | time.sleep(10) 14 | led.off() 15 | except Exception: 16 | pass 17 | -------------------------------------------------------------------------------- /python/ch_16_web_control.py: -------------------------------------------------------------------------------- 1 | from bottle import route, run 2 | from gpiozero import LED, Button 3 | 4 | leds = [LED(18), LED(23), LED(24)] 5 | switch = Button(25) 6 | 7 | def switch_status(): 8 | if switch.is_pressed: 9 | return 'Down' 10 | else: 11 | return 'Up' 12 | 13 | def html_for_led(led_number): 14 | i = str(led_number) 15 | result = " " 16 | return result 17 | 18 | @route('/') 19 | @route('/') 20 | def index(led_number="n"): 21 | if led_number != "n": 22 | leds[int(led_number)].toggle() 23 | response = "" 29 | 30 | response += '

GPIO Control

' 31 | response += '

Button=' + switch_status() + '

' 32 | response += '

LEDs

' 33 | response += html_for_led(0) 34 | response += html_for_led(1) 35 | response += html_for_led(2) 36 | return response 37 | 38 | run(host='0.0.0.0', port=80) 39 | -------------------------------------------------------------------------------- /python/ch_16_web_sensor/justgage.1.0.1.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * JustGage - a handy JavaScript plugin for generating and animating nice & clean dashboard gauges. 3 | * Copyright (c) 2012 Bojan Djuricic - pindjur(at)gmail(dot)com | http://www.madcog.com 4 | * Licensed under MIT. 5 | * Date: 31/07/2012 6 | * @author Bojan Djuricic (@Toorshia) 7 | * @version 1.0 8 | * 9 | * http://www.justgage.com 10 | */ 11 | 12 | JustGage=function(x){if(!x.id){alert("Missing id parameter for gauge!");return false}if(!document.getElementById(x.id)){alert('No element with id: "'+x.id+'" found!');return false}this.config={id:x.id,title:(x.title)?x.title:"Title",titleFontColor:(x.titleFontColor)?x.titleFontColor:"#999999",value:(x.value)?x.value:0,valueFontColor:(x.valueFontColor)?x.valueFontColor:"#010101",min:(x.min)?x.min:0,max:(x.max)?x.max:100,showMinMax:(x.showMinMax!=null)?x.showMinMax:true,gaugeWidthScale:(x.gaugeWidthScale)?x.gaugeWidthScale:1,gaugeColor:(x.gaugeColor)?x.gaugeColor:"#edebeb",label:(x.label)?x.label:"",showInnerShadow:(x.showInnerShadow!=null)?x.showInnerShadow:true,shadowOpacity:(x.shadowOpacity)?x.shadowOpacity:0.2,shadowSize:(x.shadowSize)?x.shadowSize:5,shadowVerticalOffset:(x.shadowVerticalOffset)?x.shadowVerticalOffset:3,levelColors:(x.levelColors)?x.levelColors:percentColors,levelColorsGradient:(x.levelColorsGradient!=null)?x.levelColorsGradient:true,labelFontColor:(x.labelFontColor)?x.labelFontColor:"#b3b3b3",startAnimationTime:(x.startAnimationTime)?x.startAnimationTime:700,startAnimationType:(x.startAnimationType)?x.startAnimationType:">",refreshAnimationTime:(x.refreshAnimationTime)?x.refreshAnimationTime:700,refreshAnimationType:(x.refreshAnimationType)?x.refreshAnimationType:">"};if(x.value>this.config.max){this.config.value=this.config.max}if(x.value1.25){c=1.25*q;l=q}else{c=d;l=d/1.25}var i=(d-c)/2;var g=(q-l)/2;var s=((l/8)>10)?(l/10):10;var n=i+c/2;var m=g+l/6.5;var k=((l/6.4)>16)?(l/6.4):16;var r=i+c/2;var p=g+l/1.4;var b=((l/16)>10)?(l/16):10;var f=i+c/2;var e=p+k/2+6;var j=((l/16)>10)?(l/16):10;var w=i+(c/10)+(c/6.666666666666667*this.config.gaugeWidthScale)/2;var v=g+l/1.126760563380282;var h=((l/16)>10)?(l/16):10;var u=i+c-(c/10)-(c/6.666666666666667*this.config.gaugeWidthScale)/2;var t=g+l/1.126760563380282;this.params={canvasW:d,canvasH:q,widgetW:c,widgetH:l,dx:i,dy:g,titleFontSize:s,titleX:n,titleY:m,valueFontSize:k,valueX:r,valueY:p,labelFontSize:b,labelX:f,labelY:e,minFontSize:j,minX:w,minY:v,maxFontSize:h,maxX:u,maxY:t};this.canvas.customAttributes.pki=function(K,L,N,E,O,F,D,y){var B=(1-(K-L)/(N-L))*Math.PI,G=E/2-E/10,J=G-E/6.666666666666667*y,C=E/2+F,A=O/1.25+D,H=E/2+F+G*Math.cos(B),P=O-(O-A)+D-G*Math.sin(B),M=E/2+F+J*Math.cos(B),z=O-(O-A)+D-J*Math.sin(B),I;I+="M"+(C-J)+","+A+" ";I+="L"+(C-G)+","+A+" ";I+="A"+G+","+G+" 0 0,1 "+H+","+P+" ";I+="L"+M+","+z+" ";I+="A"+J+","+J+" 0 0,0 "+(C-J)+","+A+" ";I+="z ";return{path:I}};this.gauge=this.canvas.path().attr({stroke:"none",fill:this.config.gaugeColor,pki:[this.config.max,this.config.min,this.config.max,this.params.widgetW,this.params.widgetH,this.params.dx,this.params.dy,this.config.gaugeWidthScale]});this.gauge.id=this.config.id+"-gauge";this.level=this.canvas.path().attr({stroke:"none",fill:getColorForPercentage((this.config.value-this.config.min)/(this.config.max-this.config.min),this.config.levelColors,this.config.levelColorsGradient),pki:[this.config.min,this.config.min,this.config.max,this.params.widgetW,this.params.widgetH,this.params.dx,this.params.dy,this.config.gaugeWidthScale]});this.level.id=this.config.id+"-level";this.txtTitle=this.canvas.text(this.params.titleX,this.params.titleY,this.config.title);this.txtTitle.attr({"font-size":this.params.titleFontSize,"font-weight":"bold","font-family":"Arial",fill:this.config.titleFontColor,"fill-opacity":"1"});this.txtTitle.id=this.config.id+"-txttitle";this.txtValue=this.canvas.text(this.params.valueX,this.params.valueY,this.originalValue);this.txtValue.attr({"font-size":this.params.valueFontSize,"font-weight":"bold","font-family":"Arial",fill:this.config.valueFontColor,"fill-opacity":"0"});this.txtValue.id=this.config.id+"-txtvalue";this.txtLabel=this.canvas.text(this.params.labelX,this.params.labelY,this.config.label);this.txtLabel.attr({"font-size":this.params.labelFontSize,"font-weight":"normal","font-family":"Arial",fill:this.config.labelFontColor,"fill-opacity":"0"});this.txtLabel.id=this.config.id+"-txtlabel";this.txtMin=this.canvas.text(this.params.minX,this.params.minY,this.config.min);this.txtMin.attr({"font-size":this.params.minFontSize,"font-weight":"normal","font-family":"Arial",fill:this.config.labelFontColor,"fill-opacity":(this.config.showMinMax==true)?"1":"0"});this.txtMin.id=this.config.id+"-txtmin";this.txtMax=this.canvas.text(this.params.maxX,this.params.maxY,this.config.max);this.txtMax.attr({"font-size":this.params.maxFontSize,"font-weight":"normal","font-family":"Arial",fill:this.config.labelFontColor,"fill-opacity":(this.config.showMinMax==true)?"1":"0"});this.txtMax.id=this.config.id+"-txtmax";var a=this.canvas.canvas.childNodes[1];var o="http://www.w3.org/2000/svg";if(ie<9){onCreateElementNsReady(function(){this.generateShadow()})}else{this.generateShadow(o,a)}this.level.animate({pki:[this.config.value,this.config.min,this.config.max,this.params.widgetW,this.params.widgetH,this.params.dx,this.params.dy,this.config.gaugeWidthScale]},this.config.startAnimationTime,this.config.startAnimationType);this.txtValue.animate({"fill-opacity":"1"},this.config.startAnimationTime,this.config.startAnimationType);this.txtLabel.animate({"fill-opacity":"1"},this.config.startAnimationTime,this.config.startAnimationType)};JustGage.prototype.refresh=function(b){originalVal=b;if(b>this.config.max){b=this.config.max}if(b",b[0]){}return a>4?a:c}()); -------------------------------------------------------------------------------- /python/ch_16_web_sensor/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 23 | 24 | 25 | 26 |
27 | 28 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /python/ch_16_web_sensor/raphael.2.1.0.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonmonk/raspberrypi_cookbook_ed3/34da8ee7d4e1f5743eded358c9f4864f774d5599/python/ch_16_web_sensor/raphael.2.1.0.min.js -------------------------------------------------------------------------------- /python/ch_16_web_sensor/web_sensor.py: -------------------------------------------------------------------------------- 1 | import os, time 2 | from bottle import route, run, template 3 | 4 | def cpu_temp(): 5 | dev = os.popen('/opt/vc/bin/vcgencmd measure_temp') 6 | cpu_temp = dev.read()[5:-3] 7 | return cpu_temp 8 | 9 | @route('/temp') 10 | def temp(): 11 | return cpu_temp() 12 | 13 | @route('/') 14 | def index(): 15 | return template('main.html') 16 | 17 | @route('/raphael') 18 | def index(): 19 | return template('raphael.2.1.0.min.js') 20 | 21 | @route('/justgage') 22 | def index(): 23 | return template('justgage.1.0.1.min.js') 24 | 25 | run(host='0.0.0.0', port=80) -------------------------------------------------------------------------------- /python/ch_18_ardu_adc.py: -------------------------------------------------------------------------------- 1 | import pyfirmata 2 | import time 3 | 4 | board = pyfirmata.Arduino('/dev/ttyACM0') 5 | analog_pin = board.get_pin('a:0:i') 6 | it = pyfirmata.util.Iterator(board) 7 | it.start() 8 | analog_pin.enable_reporting() 9 | 10 | while True: 11 | reading = analog_pin.read() 12 | if reading != None: 13 | voltage = reading * 5.0 14 | print("Reading=%f\tVoltage=%f" % (reading, voltage)) 15 | time.sleep(1) 16 | -------------------------------------------------------------------------------- /python/ch_18_ardu_flash.py: -------------------------------------------------------------------------------- 1 | import pyfirmata 2 | import time 3 | 4 | board = pyfirmata.Arduino('/dev/ttyACM0') 5 | led_pin = board.get_pin('d:10:o') 6 | 7 | while True: 8 | led_pin.write(1) 9 | time.sleep(0.5) 10 | led_pin.write(0) 11 | time.sleep(0.5) 12 | -------------------------------------------------------------------------------- /python/ch_18_ardu_flash_ser.py: -------------------------------------------------------------------------------- 1 | import pyfirmata 2 | import time 3 | 4 | board = pyfirmata.Arduino('/dev/ttyS0') 5 | led_pin = board.get_pin('d:13:o') 6 | 7 | while True: 8 | led_pin.write(1) 9 | time.sleep(0.5) 10 | led_pin.write(0) 11 | time.sleep(0.5) 12 | -------------------------------------------------------------------------------- /python/ch_18_ardu_gui_slider.py: -------------------------------------------------------------------------------- 1 | import pyfirmata 2 | from guizero import App, Slider 3 | 4 | board = pyfirmata.Arduino('/dev/ttyACM0') 5 | pin = board.get_pin('d:10:p') 6 | 7 | def slider_changed(percent): 8 | pin.write(int(percent) / 100.0) 9 | 10 | app = App(title='PWM', width=500, height=150) 11 | slider = Slider(app, command=slider_changed, width='fill', height=50) 12 | slider.text_size = 30 13 | app.display() 14 | -------------------------------------------------------------------------------- /python/ch_18_ardu_gui_switch.py: -------------------------------------------------------------------------------- 1 | import pyfirmata 2 | from guizero import App, PushButton 3 | 4 | board = pyfirmata.Arduino('/dev/ttyACM0') 5 | pin = board.get_pin('d:10:o') 6 | 7 | def start(): 8 | start_button.disable() 9 | stop_button.enable() 10 | pin.write(1) 11 | 12 | def stop(): 13 | start_button.enable() 14 | stop_button.disable() 15 | pin.write(0) 16 | 17 | app = App(width=100, height=150) 18 | start_button = PushButton(app, command=start, text="On") 19 | start_button.text_size = 30 20 | stop_button = PushButton(app, command=stop, text="Off", enabled=False) 21 | stop_button.text_size = 30 22 | app.display() 23 | -------------------------------------------------------------------------------- /python/ch_18_ardu_pwm.py: -------------------------------------------------------------------------------- 1 | import pyfirmata 2 | 3 | board = pyfirmata.Arduino('/dev/ttyACM0') 4 | led_pin = board.get_pin('d:10:p') 5 | 6 | while True: 7 | duty_s = input("Enter Brightness (0 to 100):") 8 | duty = int(duty_s) 9 | led_pin.write(duty / 100.0) 10 | -------------------------------------------------------------------------------- /python/ch_18_ardu_switch.py: -------------------------------------------------------------------------------- 1 | import pyfirmata 2 | import time 3 | 4 | board = pyfirmata.Arduino('/dev/ttyACM0') 5 | switch_pin = board.get_pin('d:4:i') 6 | it = pyfirmata.util.Iterator(board) 7 | it.start() 8 | switch_pin.enable_reporting() 9 | 10 | while True: 11 | input_state = switch_pin.read() 12 | if input_state == False: 13 | print('Button Pressed') 14 | time.sleep(0.2) 15 | -------------------------------------------------------------------------------- /python/faces.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonmonk/raspberrypi_cookbook_ed3/34da8ee7d4e1f5743eded358c9f4864f774d5599/python/faces.jpg -------------------------------------------------------------------------------- /python/school_bell.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonmonk/raspberrypi_cookbook_ed3/34da8ee7d4e1f5743eded358c9f4864f774d5599/python/school_bell.mp3 -------------------------------------------------------------------------------- /python/school_bell.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonmonk/raspberrypi_cookbook_ed3/34da8ee7d4e1f5743eded358c9f4864f774d5599/python/school_bell.wav --------------------------------------------------------------------------------