===== Инструкция набора «Малина» ===== Электронная версия книги из набора [[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()