===== Инструкция набора «Малина» =====
Электронная версия книги из набора [[amp>collection/raspberry-pi-kits?utm_source=announce&utm_campaign=malina&utm_medium=wiki|«Малина»]].
Здесь собраны нужные ссылки, исходный код всех экспериментов, подсказки и хаки по прохождению набора.
{{ :malina:titile.png?nolink |}}
===== Обрати внимание! =====
Господа из Rasberry Foundation не устают радовать нас новыми версиями плат. Мы в свою очередь стремимся не отставать и обновляем наш набор согласно выходу новых железок. Проверь, какая версия досталась тебе! Для этого посмотри на обратную сторону обложки буклета. Если на ней **нет значка** с текстом «b1», «b2» или «b3» как на картинке снизу, то [[http://wiki.amperka.ru/malina-3b|тебе сюда]].
{{ :malina-3b:a9749f5e8e.png?nolink |}}
===== Видеообзор =====
{{youtube>CNW2KdwlanE?large}}
===== Ресурсы =====
* [[https://filezilla-project.org/download.php?show_all=1|FileZilla]] — FTP-клиент.
* [[https://www.realvnc.com/en/connect/download/viewer/|RealVNC]] — клиент для удаленного доступа к рабочему столу устройства.
* [[https://angryip.org/download|Angry IP Scanner]] — утилита для сканирования IP-адресов в подключенной сети.
===== Эксперименты =====
==== 3. Маячок ====
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. Выключатель ====
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)
Вместе с обработкой исключений, код будет выглядеть так:
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. Переключатель ====
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. Управление яркостью ====
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. Панель управления светом ====
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. Массивная оптимизация ====
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()
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-сервер ====
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-сервера.
[[http://amperka.github.io/malina_support/web-server.zip|web-server.zip]]
from flask import Flask, send_file
app = Flask('landingPage')
@app.route('/')
def index():
return send_file('landing.html')
@app.route('/images/')
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
В консоль выведется список запущенных процессов.
{{ :malina:ps.png?nolink |}}
Найди строку с файлом landing.py. Во второй колонке будет указан номер процесса. Отключи его командой
kill -9 2141
Где 2141 — номер процесса.
{{ :malina:kill.png?nolink |}}
Команда kill «убивает» процесс, иногда это называют «убить девяткой».
Запусти сервер заново.
==== 11. Интернет свет ====
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/')
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. Обратная связь ====
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/')
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. Погодный фиджет ====
API ключ OpenWeatherMap будет работать после 10 мин. после создания
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. Бот ВКонтакте ====
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.')
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. Карамба ====
[[https://github.com/amperka/malina_support/raw/master/whats_next.torrent|Ссылка на торрент-файл.]]
====18. Кинотеатр ====
[[https://amperka.github.io/malina_support/omx-web.zip|omx-web.zip]]
====19. Поставь торрент заранее ====
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()