Буклет набора «Малина»

Электронная версия брошюры из набора «Малина». Здесь собраны нужные ссылки, исходный код всех экспериментов, подсказки и хаки по прохождению набора.

Обрати внимание!

Господа из Rasberry Foundation не устают радовать нас новыми версиями плат. Мы в свою очередь стремимся не отставать и обновляем наш набор согласно выходу новых железок. Проверь, какая версия досталась тебе! Для этого посмотри на обратную сторону обложки буклета. Если на ней нет значка с текстом «b1», «b2» или «b3» как на картинке снизу, то тебе сюда.

Видеообзор

Ресурсы

Windows OS

Mac OS

Эксперименты

3. Маячок

blink.py
import RPi.GPIO as GPIO
import time
 
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.OUT)
 
try:
    while True:
        time.sleep(0.5)
        GPIO.output(17, GPIO.HIGH)
        time.sleep(0.5)
        GPIO.output(17, GPIO.LOW)
except KeyboardInterrupt:
    print('The program was stopped by keyboard.')
finally:
    GPIO.cleanup()
    print('GPIO cleanup completed.')

4. Выключатель

toggle.py
import RPi.GPIO as GPIO
import time
 
GPIO.setmode(GPIO.BCM)
GPIO.setup(2, GPIO.IN)
 
while True:
    time.sleep(0.5)
    button = GPIO.input(2)
    print(button)

Передай переменную button в функцию output, чтобы управлять светодиодом.

while True:
    button = GPIO.input(2)
    GPIO.output(24, button)

Не забудь добавить строку инициализации пина на выход.

GPIO.setup(24, GPIO.OUT)

Вместе с обработкой исключений, код будет выглядеть так:

toggle.py
import RPi.GPIO as GPIO
import time
 
GPIO.setmode(GPIO.BCM)
GPIO.setup(2, GPIO.IN)
GPIO.setup(24, GPIO.OUT)
 
try:
    while True:
        button = GPIO.input(2)
        GPIO.output(24, button)
except KeyboardInterupt:
    print('The program was stopped by keyboard.')
finally:
    GPIO.cleanup()
    print('GPIO cleanup completed')

5. Переключатель

switch.py
import RPi.GPIO as GPIO
 
GPIO.setmode(GPIO.BCM)
GPIO.setup(8, GPIO.IN)
GPIO.setup(24, GPIO.OUT)
GPIO.setup(26, GPIO.OUT)
 
try:
    while True:
        button = GPIO.input(8)
        if button == False:
            GPIO.output(24, GPIO.HIGH)
            GPIO.output(26, GPIO.LOW)
        else:
            GPIO.output(24, GPIO.LOW)
            GPIO.output(26, GPIO.HIGH)
 
except KeyboardInterrupt:
    print('The program was stopped by keyboard.')
finally:
    GPIO.cleanup()
    print('GPIO cleanup completed.')

6. Управление яркостью

brightnessControl.py
import RPi.GPIO as GPIO
import time
 
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
pwm = GPIO.PWM(18, 1000)
dutyCycle = 50
pwm.start(dutyCycle)
 
try:
    while True:
        time.sleep(0.01)
        dutyCycle = dutyCycle + 1
        if dutyCycle > 100:
            dutyCycle = 0
        pwm.ChangeDutyCycle(dutyCycle)
 
except KeyboardInterrupt:
    print('The program was stopped by keyboard.')
finally:
    GPIO.cleanup()
    print('GPIO cleanup completed.')

7. Панель управления светом

function.py
import RPi.GPIO as GPIO
 
 
def isPressed(btn, led):
    if GPIO.input(btn) == False:
        GPIO.output(led, GPIO.HIGH)
    else:
        GPIO.output(led, GPIO.LOW)
 
 
button1 = 3
button2 = 4
led1 = 14
led2 = 15
 
GPIO.setmode(GPIO.BCM)
GPIO.setup(button1, GPIO.IN)
GPIO.setup(button2, GPIO.IN)
GPIO.setup(led1, GPIO.OUT)
GPIO.setup(led2, GPIO.OUT)
 
try:
    while True:
        isPressed(button1, led1)
        isPressed(button2, led2)
except KeyboardInterrupt:
    print('The program was stopped by keyboard.')
finally:
    GPIO.cleanup()
    print('GPIO cleanup completed.')

8. Массивная оптимизация

oneMassive.py
import RPi.GPIO as GPIO
import time
 
GPIO.setmode(GPIO.BCM)
leds = [12, 13, 14, 18]
 
for led in leds:
    GPIO.setup(led, GPIO.OUT)
    GPIO.output(led, GPIO.HIGH)
 
time.sleep(3)
 
for led in leds:
    GPIO.output(led, GPIO.LOW)
 
GPIO.cleanup()
twoMassive.py
import RPi.GPIO as GPIO
 
 
def isPressed(btn, led):
    state = 1 - GPIO.input(btn)
    GPIO.output(led, state)
 
 
leds = [12, 13, 14, 18]
buttons = [2, 3, 4, 8]
 
GPIO.setmode(GPIO.BCM)
for i in range(4):
    GPIO.setup(leds[i], GPIO.OUT)
    GPIO.setup(buttons[i], GPIO.IN)
 
try:
    while True:
        for i in range(4):
            isPressed(buttons[i], leds[i])
except KeyboardInterrupt:
    print('The program was stopped by keyboard.')
finally:
    GPIO.cleanup()
    print('GPIO cleanup completed.')

9. Web-сервер

simpleServer.py
from flask import Flask
 
app = Flask('simpleServer')
 
 
@app.route('/')
def index():
    return 'Hello, Amperka!'
 
 
app.run(port=3000, host='0.0.0.0')

10. Landing page

Ссылка на архив с файлами web-сервера.

web-server.zip

landing.py
from flask import Flask, send_file
 
app = Flask('landingPage')
 
@app.route('/')
def index():
    return send_file('landing.html')
 
@app.route('/images/<filename>')
def get_image(filename):
    return send_file('images/'+filename)
 
app.run(port=3000, host='0.0.0.0')

Если при перезапуске сервера консоль ответит сообщением «socket.error: [Errno 98] Address already in use», набери команду

ps -u

В консоль выведется список запущенных процессов. Найди строку с файлом landing.py. Во второй колонке будет указан номер процесса. Отключи его командой

kill -9 2141

Где 2141 — номер процесса. Команда kill «убивает» процесс, иногда это называют «убить девяткой».

Запусти сервер заново.

11. Интернет свет

light.py
from flask import Flask, send_file
import RPi.GPIO as GPIO
 
led = 18
 
GPIO.setmode(GPIO.BCM)
GPIO.setup(led, GPIO.OUT)
 
app = Flask('lightControl')
 
 
@app.route('/')
def index():
    return send_file('light.html')
 
 
@app.route('/images/<filename>')
def get_image(filename):
    return send_file('images/' + filename)
 
 
@app.route('/turnOn')
def turnOn():
    GPIO.output(led, GPIO.HIGH)
    return 'turnedOn'
 
 
@app.route('/turnOff')
def turnOff():
    GPIO.output(led, GPIO.LOW)
    return 'turnedOff'
 
try: 
    app.run(port=3000, host='0.0.0.0')
finally:
    GPIO.cleanup()
    print('GPIO cleanup completed.')

12. Обратная связь

feedback.py
from flask import Flask, send_file
from flask_socketio import SocketIO
import RPi.GPIO as GPIO
 
app = Flask('feedback')
socketio = SocketIO(app)
 
btn = 2
 
GPIO.setmode(GPIO.BCM)
GPIO.setup(btn, GPIO.IN)
 
 
@app.route('/')
def index():
    return send_file('feedback.html')
 
 
@app.route('/images/<filename>')
def get_image(filename):
    return send_file('images/' + filename)
 
 
@socketio.on('isPressed')
def checkButton(receivedData):
    if GPIO.input(btn) == False:
        socketio.emit('button', 'pressed')
    else:
        socketio.emit('button', 'released')
 
 
try: 
    socketio.run(app, port=3000, host='0.0.0.0')
finally:
    GPIO.cleanup()
    print('GPIO cleanup completed.')

13. Погодный фиджет

phidget.py
import requests, json
 
url = "http://api.openweathermap.org/data/2.5/forecast"
 
payload = {
    "lat": "широта_твоего_города",
    "lon": "долгота_твоего_города",
    "units": "metric",
    "appid": "твой_ключ",
}
 
res = requests.get(url, params=payload)
data = json.loads(res.text)
 
weather = data["list"][0]
 
 
def pars_weather(weatherType, timeRange, measurementUnits):
    if (weatherType in weather) and (
        timeRange in weather[weatherType].keys()
    ):
        print(
            weatherType,
            ": ",
            weather[weatherType][timeRange],
            measurementUnits,
        )
    else:
        print(weatherType, ": ", "none")
 
 
pars_weather("clouds", "all", "%")
pars_weather("rain", "3h", "mm")
pars_weather("snow", "3h", "mm")
print("temp:", weather["main"]["temp"], "C")

14. Бот ВКонтакте

vk.py
import time
import vk_api
 
vk = vk_api.VkApi(token = 'твой_ключ')
 
param = {
    'count': 1,
    'time_offset': 5,
    'filter': 'unread'
}
 
 
def write_msg(user_id, msg, random): 
    vk.method('messages.send', { 
        'user_id': user_id, 
        'message': msg,
        'random_id': random
    }) 
 
 
try:
    while True: 
        response = vk.method('messages.getConversations', param) 
        if response['items']: 
            item = response['items'][0] 
            last_mess = item['last_message'] 
            random = last_mess['random_id'] 
            my_id = last_mess['peer_id'] 
            text = last_mess['text'] 
            write_msg(my_id, text, random) 
        time.sleep(1) 
except KeyboardInterrupt:
    print('Keyboard interrupt detected.')
finally:
    print('The program was stopped.')
vk2.py
import time
import vk_api
import RPi.GPIO as GPIO
 
vk = vk_api.VkApi(token = 'твой_ключ') 
 
param = { 
    'count' : 1, 
    'time_offset' : 5, 
    'filter' : 'unread' 
}
 
led = 18
 
GPIO.setmode(GPIO.BCM) 
GPIO.setup(led, GPIO.OUT) 
 
 
def write_msg(user_id, msg, random): 
    vk.method('messages.send', { 
        'user_id': user_id, 
        'message': msg, 
        'random_id':random, 
    }) 
 
 
try: 
    while True: 
        response = vk.method('messages.getConversations', param) 
        if response['items']: 
            item = response['items'][0] 
            last_mess = item['last_message'] 
            random = last_mess['random_id'] 
            my_id = last_mess['peer_id'] 
            text = last_mess['text'] 
            if text == 'On': 
                GPIO.output(led, GPIO.HIGH) 
                write_msg(my_id, 'LED ' + text, random) 
            elif text == 'Off': 
                GPIO.output(led, GPIO.LOW) 
                write_msg(my_id, 'LED ' + text, random) 
            else: 
                err_msg = 'Send "On" or "Off"' 
                write_msg(my_id, err_msg, random) 
        time.sleep(1) 
except KeyboardInterrupt:
    print('The program was stopped by keyboard.')
finally:
    GPIO.cleanup()
    print('GPIO cleanup completed.')

17. Карамба

18. Кинотеатр

19. Поставь торрент заранее

deluge_vk.py
import time
import vk_api
 
from deluge_client import DelugeRPCClient
 
vk = vk_api.VkApi(token = 'твой_ключ')
 
values = {
    'count' : 1, 
    'time_offset' : 5, 
    'filter' : 'unread' 
}
 
client = DelugeRPCClient(
    '127.0.0.1',
    58846,
    'pi',
    'пароль_твоей_Raspberry'
)
 
client.connect()
 
def write_msg(user_id, msg , random):
    vk.method('messages.send', {
        'user_id': user_id,
        'message': msg,
        'random_id': random
    })
 
try:
    while True:
        response = vk.method('messages.getConversations', values)
        if response['items']:
            item = response['items'][0]
            last_mess = item['last_message']
            random = last_mess['random_id']
            my_id = last_mess['peer_id']
            text = last_mess['text'] 
            try:
                client.call('core.add_torrent_url', text, {
                    'download_location': '/home/pi/Torrents'
                })
            except Exception:
                write_msg(my_id, 'Link doesn\'t work', random)
            else: 	
                write_msg(my_id, 'Download started!', random)
        time.sleep(1)
except KeyboardInterrupt:
    print('Keyboard interrupt detected.')
finally:
    print('Program was stopped.')

Включить все светодиоды на Облаке

import RPi.GPIO as GPIO
import time
 
GPIO.setmode(GPIO.BCM)
leds = [10, 12, 13, 14, 15, 16, 17, 18, 19, 21, 24, 26]
 
for led in leds:
    GPIO.setup(led, GPIO.OUT)
    GPIO.output(led, GPIO.HIGH)
 
time.sleep(3)
 
for led in leds:
    GPIO.output(led, GPIO.LOW)
 
GPIO.cleanup()