Самоучитель по компонентам Raspberry Pi Pico W для начинающих

учебник по компонентам raspberry pi pico w

Этот самоучитель по компонентам Raspberry Pi Pico W для начинающих научит вас взаимодействовать с микроконтроллером для взаимодействия с простыми компонентами, такими как светодиоды, ультразвуковые датчики и многие другие предметы, которые можно найти в наборе для начинающих.

Если вы совсем новичок, этот учебник поможет вам понять MicroPython, чтобы вы могли читать, писать и изменять код. С этими знаниями вы сможете комбинировать код и компоненты, чтобы создать нечто, имеющее реальное применение.

Если вы используете Pico, это руководство научит вас управлять Pico W по беспроводной связи. Раньше вы могли взаимодействовать с Pico только с помощью переключателя, кнопки или какого-либо физического устройства взаимодействия. Теперь это не так! Теперь вы можете управлять компонентами с помощью телефона или настольного компьютера.

Учебный поток

Введение

  1. Пайка контактов заголовка
  2. Использование Thonny
  3. Обновление прошивки

Учебник Hello World для Pico W

  1. Отправьте веб-страницу с надписью "Hello World" на Pico
  2. Беспроводное управление светодиодом

На ступеньку выше

  1. Беспроводное управление RGB-светодиодами
  2. Работа зуммера на Pico W

Основные способы передачи данных с датчиков

  1. Ультразвуковой датчик Pico W и HC-SR04
  2. Передача веб-страницы с данными датчиков
  3. Уменьшение полезной нагрузки с помощью AJAX
  4. Pimoroni Phew для упрощения кодирования конечных точек

Подключение к веб-утилитам

  1. Регистрация климатических данных датчика DHT22 в Google Sheets с помощью IFTTT
  2. Создайте пульт дистанционного управления Spotify с функциями воспроизведения/паузы/пропуска

Управление GPIO без кода с помощью PiCockpit

  1. Суперпростая установка PiCockpit на Pico W
  2. Простое управление светодиодами с помощью PiCockpit и Pico W
  3. Pico W, вентилятор на 5 В и транзистор, управляемый PiCockpit

MQTT

  1. Отображение фоторезистора с помощью MQTT и Node-RED с Pico W

Оглавление

Содержание скрыть

Цели учебника в кратком изложении

  • Узнайте, как взаимодействовать с фундаментальными компонентами, из которых состоят большие проекты
  • Управляйте всем этим без проводов - никаких переключателей, кнопок или других устройств взаимодействия.
  • Получите лучшее представление о достоинствах Pico W

Важные ссылки

Репозиторий Github для обучающего кода (кроме secrets.py)

Документация по MicroPython

Ошибки, предложения, комментарии? Оставьте свой комментарий в поле для комментариев ниже, напишите мне или Напишите мне.

OSError: [Errno 98] EADDRINUSE

Если вы получили эту ошибку, просто отключите и подключите Raspberry Pi Pico.

Вы также можете сделать это, введя эти команды в оболочку Thonny:

import machine
machine.reset()

Результат:

Пайка контактов заголовка

Когда вы покупаете Raspberry Pi Pico W, в комплект поставки могут не входить разъемы, позволяющие подключать компоненты к Pico.

На момент написания статьи Pico WH (H для заголовков) еще не был выпущен. Наша мега-статья о Pico W следит за его выходом.

Однако если вам удастся найти Pico W с предварительно припаянными разъемами, я бы посоветовал вам купить именно его.

Тем не менее, для остальных припаивание заголовков к Pico W - дело нехитрое. Вам понадобятся:

  • Хлебная доска
  • Паяльник и припой
  • Заголовки

Когда вы будете покупать головки, убедитесь, что они предназначены для Pico W. В отличие от головок для Raspberry Pi серии Zero, головки на Pico W не расположены рядом друг с другом. Они находятся на противоположных концах платы.

Макетная плата, Pico W и 2×20 контактных разъемов

У штырьков есть длинная и короткая сторона. Длинные контакты должны быть на той стороне, где находятся метки GPIO (GP0, GP1, GND, VBUS, VSYS и т.д.).

Более длинные контакты должны находиться на стороне, противоположной USB-разъему.

Поэтому вставьте в макетную плату более длинные штырьки. Вам понадобятся четыре отверстия и расстояние между ними в один желоб. Если вы не уверены, протестируйте свой Pico W.

Паять очень просто. Убедитесь, что ваш паяльник горячий, и обязательно используйте кончик паяльника.

Наиболее эффективным мне показалось приблизить кончик паяльника к штырьку, нанести припой на кончик и увидеть, как он стекает по штырьку и создает соединение.

После пайки обязательно проверьте, нет ли постороннего припоя, который мог бы соединить два вывода GPIO вместе, или остатков отработанного припоя, который остался на вашей плате.

Используйте Thonny в качестве редактора кода

Тонни программирует Raspberry Pi Pico W

Thonny остается самым простым способом программирования Raspberry Pi Pico W.

Если вы используете ОС Raspberry Pi, то она уже установлена.

Однако если вы используете Windows или Mac, вам придется загрузить его и настроить.

Вот руководство, которое проведет вас по всем шагам.

Также убедитесь, что обратитесь к руководству по загрузке файлов на Pico W.

Обновите прошивку, загрузив последнюю версию UF2

Когда вы купили Pico W, у вас уже могла быть устаревшая прошивка.

В Pico W грядут многочисленные изменения, поэтому лучше всего обновить прошивку уже сейчас.

Некоторые изменения, которые я увидел со дня выпуска, - это улучшение функции точки доступа WLAN, а в будущих обновлениях может быть разблокирована функция Bluetooth на плате.

Обновляйтесь! Вот руководство в нашей мега-статье.


1. Отправьте веб-страницу с текстом "Hello World" на Pico

Проект "Hello World" для Raspberry Pi Pico W

Одним из самых фундаментальных проектов во всех учебниках по программированию является проект "Hello World".

"Hello World" микроконтроллера обычно сопровождается миганием светодиода. Это очень просто. Вот как.

Однако, поскольку Pico W может обслуживать веб-страницы, давайте начнем с того, как обслуживать веб-страницу с сообщением "Hello World".

Используемая здесь настройка станет основой для остальных уроков.

Подключиться к Pico W можно двумя способами. Вы можете заставить его присоединиться к сети WiFi или трансляция точки доступа SoftAP, подобно тому, как это делает ваш смартфон. Если вы хотите попробовать последний вариант, перейдите по ссылке. Однако для единообразия в этом руководстве мы всегда будем подключаться к сети WiFi, а не транслировать ее с Pico W.

Итак, в общих чертах шаги по обслуживанию веб-страницы включают в себя:

  • Подключение к WiFi
  • Написание кода, который будет обслуживать index.html всех, кто подключится к IP-адресу Pico W.

Давайте создадим несколько файлов. Сохраните их и загрузите на ваш Raspberry Pi Pico W. Вот как загружать файлы, если вы это пропустили.

wifi.py

wifi.py - это шаблон, призванный помочь вам подключиться к вашей сети WiFi. Создайте отдельный файл и импортируйте его в main.py файл в дальнейшем поможет уменьшить беспорядок в коде.

Обратите внимание, что код вашей страны следует изменить в строке rp2.country('DE') если ваша страна не Германия.

import rp2
import network
import ubinascii
import machine
import urequests as requests
import time
from secrets import secrets


def init_wifi():
    # Set country to avoid possible errors
    rp2.country('DE')

    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)

    # Load login data from different file for safety reasons
    ssid = secrets['ssid']
    pw = secrets['pw']

    wlan.connect(ssid, pw)

    # Wait for connection with 10 second timeout
    timeout = 10
    while timeout > 0:
        if wlan.status() < 0 or wlan.status() >= 3:
            break
        timeout -= 1
        print('Waiting for connection...')
        time.sleep(1)

    # Define blinking function for onboard LED to indicate error codes    
    def blink_onboard_led(num_blinks):
        led = machine.Pin('LED', machine.Pin.OUT)
        for i in range(num_blinks):
            led.on()
            time.sleep(.2)
            led.off()
            time.sleep(.2)

    wlan_status = wlan.status()
    blink_onboard_led(wlan_status)

    if wlan_status != 3:
        raise RuntimeError('Wi-Fi connection failed')
    else:
        print('Connected')
        status = wlan.ifconfig()
        print('ip = ' + status[0])

secrets.py

wifi.py импорт secrets.pyгде хранится информация о вашей сети WiFi.

secrets.py это простой JSON-файл, содержащий ваш идентификатор WiFi SSID и пароль.

secrets = {
    'ssid': 'SM-A520W9371',
    'pw': 'starting',
    }

serve_webpage.py

Как следует из названия, эта страница обслуживает веб-сайты пользователей, которые подключаются к Pico W.

Получив соединение, Pico W находит файл под названием index.html и отправляет его подключенному клиенту, как показано в строке response = get_html('index.html').

import socket

def serve_webpage():
    #Function to load in html page    
    def get_html(html_name):
        # open html_name (index.html), 'r' = read-only as variable 'file'
        with open(html_name, 'r') as file:
            html = file.read()
            
        return html

    # HTTP server with socket
    addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

    s = socket.socket()
    s.bind(addr)
    s.listen(1)

    print('Listening on', addr)

    # Listen for connections
    while True:
        try:
            cl, addr = s.accept()
            print('Client connected from', addr)
            response = get_html('index.html')
            cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
            cl.send(response)
            cl.close()
            
        except OSError as e:
            cl.close()
            print('Connection closed')

Наконец, нам нужно создать index.html файл, который будет отправлен подключенному клиенту.

<!DOCTYPE html>
<html>
    <head>
        <title>Pico W</title>
    </head>
    <body>
        <h1>Hello World</h1>
    </body>
</html>

Это простой HTML-шаблон с двумя изменениями: одно в <title>тег, который выводит "Pico W" в качестве заголовка, и тег <h1>, который говорит "Hello World".

main.py

Поскольку мы разместили весь код в другом месте, наш main.py файл просто должен импортировать и вызвать эти функции, чтобы обслуживать веб-страницу Hello World.

Как вы можете видеть, сначала мы инициализируем WiFi, а затем обслуживаем веб-страницу.

from wifi import init_wifi
from serve_webpage import serve_webpage

init_wifi()
serve_webpage()

Вы почти у цели!

Как показано на скриншоте ниже, убедитесь в этом:

  • Вы загрузили пять файлов в Raspberry Pi Pico W (см. левую нижнюю красную рамку).
  • Убедитесь, что ваш интерпретатор установлен на MicroPython (Raspberry Pi Pico) (см. правую нижнюю рамку)
  • Затем выделите main.py в редакторе кода и нажмите зеленую кнопку "Выполнить" (красная рамка слева вверху).
  • После запуска вы увидите свой IP-адрес в оболочке. Перейдите в браузер и введите этот адрес, и вы увидите веб-страницу Hello World.
  • Если оболочка не открыта, перейдите в меню Вид -> Оболочка.

Если все прошло успешно, вы увидите страницу ниже.


2. Беспроводное управление светодиодом

Теперь, когда вы разобрались с основами, давайте сделаем еще один шаг вперед.

Один из самых фундаментальных проектов Raspberry Pi включает в себя мигание светодиода.

Давайте повысим этот уровень, управляя светодиодом по беспроводному каналу. Мы хотим иметь возможность мигать, включать и выключать светодиод.

Для этого вам потребуется создать схему и веб-сервер с тремя кнопками - ON, OFF, BLINK.

Для этого проекта вам понадобится светодиод, резистор 330 Ом, один провод с перемычкой и макетная плата.

Мы будем использовать красный светодиод, потому что в большинстве наборов он есть. Обратите внимание, что если вы используете светодиод любого другого цвета, вам нужно будет отрегулировать резистор.

Вот как соединить компоненты

  • GPIO 2 -> длинная ножка светодиода (анод/позитив)
  • GND -> резистор 330 Ом -> короткая ножка светодиода (катод/отрицательный)

Код для управления светодиодом на Pico W

Давайте продолжим то, что мы сделали в предыдущем уроке. Единственные два файла, которые нам нужно будет изменить, это index.html чтобы добавить кнопки и main.py взаимодействовать со светодиодом на основе данных, полученных от index.html.

Жирным шрифтом выделены новые строки, которые были добавлены к index.html. Они добавляют три кнопки и пункт "Управление светодиодом".

<!DOCTYPE html>
<html>
    <head>
        <title>Pico W</title>
    </head>
    <body>
        <h1>Pico W</h1>
        <p>Control the LED</p>
        <a href=\"?led=on\"><button>ON</button></a>&nbsp;
        <a href=\"?led=off\"><button>OFF</button></a>
        <a href=\"?led=blink\"><button>BLINK</button></a>
    </body>
</html>

Обратите внимание, что при нажатии на кнопки к IP-адресу Pico W будет добавлен параметр (например. http://192.168.43.134/%22?led=blink\). Эти параметры перехватываются внутренним блоком Pico W и управляют светодиодом.

Мы собираемся переехать serve_webpage.pyкод в main.py файл.

Вот main.py:

from wifi import init_wifi
import socket
import machine
import time

init_wifi()


#LED controls
led = machine.Pin(2, machine.Pin.OUT)
      
def blink_led():
    led.on()
    time.sleep(0.2)
    led.off()
    time.sleep(0.2)

#Function to load in html page    
def get_html(html_name):
    # open html_name (index.html), 'r' = read-only as variable 'file'
    with open(html_name, 'r') as file:
        html = file.read()
        
    return html

# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

s = socket.socket()
s.bind(addr)
s.listen(1)

print('Listening on', addr)

# Listen for connections
while True:
    try:
        cl, addr = s.accept()
        print('Client connected from', addr)
        request = cl.recv(1024)
        print(request)
        
        request = str(request)
        led_on = request.find('?led=on')
        led_off = request.find('?led=off')
        led_blink = request.find('?led=blink')
        print('led_on = ', led_on)
        print('led_off = ', led_off)
        print('led_blink = ', led_blink)
        if led_on > -1:
            print('LED ON')
            led.on()
            
        if led_off > -1:
            print('LED OFF')
            led.off()
            
        if led_blink > -1:
            print('LED BLINK')
            blink_led()
            
        response = get_html('index.html')
        cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        cl.send(response)
        cl.close()
        
    except OSError as e:
        cl.close()
        print('Connection closed')

Первый и ключевой сегмент представлен ниже:

request = cl.recv(1024)
        print(request)
        
        request = str(request)
        led_on = request.find('?led=on')
        led_off = request.find('?led=off')
        led_blink = request.find('?led=blink')
        print('led_on = ', led_on)
        print('led_off = ', led_off)
        print('led_blink = ', led_blink)
        if led_on > -1:
            print('LED ON')
            led.on()
            
        if led_off > -1:
            print('LED OFF')
            led.off()
            
        if led_blink > -1:
            print('LED BLINK')
            blink_led()

Переменная "request" при печати выводит первый блок текста ниже. Последние три строки - это операторы печати, которые проверяют включение, выключение или мигание светодиода:

b'GET /%22?led=blink\\%22 HTTP/1.1\r\nHost: 192.168.43.134\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nReferer: http://192.168.43.134/%22?led=on\\%22\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: en-US,en;q=0.9,es;q=0.8,zh-TW;q=0.7,zh-CN;q=0.6,zh;q=0.5\r\n\r\n'
led_on =  456
led_off =  -1
led_blink =  10

Приведенный выше код попытается найти определенные строки, такие как "led=on". Если он существует, то его значение будет больше -1, что приведет к срабатыванию соответствующей функции если заявление.

Например, если в параметрах существует led=on, то переменная led_on будет больше, чем -1, поэтому если led_on > -1 запускает и выполняет оператор led.on();

Единственный сложный момент здесь - это led_blink функция, которая будет запускать функцию:

    def blink_led():
        led.on()
        time.sleep(0.2)
        led.off()
        time.sleep(0.2)

Наконец, вот как инициализировать GPIO 2 для управления светодиодом:

import machine
import time
    
#LED controls
led = machine.Pin(2, machine.Pin.OUT)

Мы импортируем машину, чтобы взаимодействовать с пином GPIO. Как вы можете видеть в переменной ledМы хотим, чтобы Pico W подавал питание на GPIO 2.

Мы импортируем время чтобы мы могли сделать паузу в 0,2 секунды в blink_led().


3. RGB-светодиод на Pico W

Чтобы зажечь RGB-светодиоды, вам понадобятся:

  • Три 330-омных резистора
  • Один светодиод RGB
  • Один провод-перемычка

На RGB-светодиоде вы найдете четыре ножки. Одна ножка будет самой длинной. Это либо катод (отрицательный), либо анод (положительный). У моего RGB-светодиода был общий катод, поэтому вот его подключение:

На изображении показаны ножки R, G, B на RGB-светодиоде с общим катодом. (Изображение из Raspberry Pi Foundation CC-BY-SA)
  • GPIO 15 -> 330-омный резистор -> красный светодиод
  • GPIO 17 -> резистор -> зеленый светодиод
  • GPIO 16 -> резистор -> синий светодиод

Вот код, чтобы проверить, правильно ли вы подключили его:

import machine

red_led = machine.PWM(machine.Pin(15))
green_led = machine.PWM(machine.Pin(17))
blue_led = machine.PWM(machine.Pin(16))

red_led.duty_u16(65534)
green_led.duty_u16(65534)
blue_led.duty_u16(65534)

В этом примере мы используем ШИМ, который позволяет изменять яркость светодиодов R, G, B.

Вы можете изменить значения, передаваемые в [color].duty_u16, на значения от 0 до 65534. Теоретически, вы должны иметь возможность передавать 65535, но у меня это почему-то не работает.

Считайте, что, передав "0", вы хотите получить ноль процентов яркости. Если вы передадите значение 65534, вы хотите получить 100-процентную яркость.

Если вы сделаете 65534 для одного цвета и ноль для остальных, вы сможете определить, подключили ли вы нужные пины GPIO к нужному цвету светодиода.

Почему же мы используем ШИМ? Потому что это поможет вам получить больше цветов. Если вы просто используете метод "включил-выключил", вы можете получить красный, зеленый, синий, беловатый и никакой свет. С помощью ШИМ можно варьировать интенсивность свечения светодиодов R, G, B и создавать столько цветов, сколько вы только можете себе представить.

Теперь давайте создадим что-то, чем можно управлять без проводов!

index.html

Основное изменение заключается в том, чтобы <form> который имеет три ползунка. Эти ползунки имеют значение от нуля до 100.

Использование значений от нуля до 100 помогает представить яркость в процентах. Это также уменьшает количество кода, необходимого для разбора значения из параметров (см. далее main.py)

Когда вы установите значения для светодиодов R, G, B, вы нажмете кнопку submit, и эти данные будут записаны Pico W.

<!DOCTYPE html>
<html>
    <head>
        <title>Pico W</title>
    </head>
      <body>
        <h1>Pico W RGB LED</h1>
        <form id="form">
            
            <input type="range" min="0" max="100" value="slider_value" name="red" id="red">
            <label for="red">R</p>
            
            <input type="range" min="0" max="100" value="slider_value" name="green" id="green">
             <label for="green">G</p>
            
            <input type="range" min="0" max="100" value="slider_value" name="blue" id="blue">
            <label for="blue">B</p>
            
            <input type="submit" id="submit">
        </form>
        <script>
        
            submit.addEventListener('click', function ()  {
                form.submit();
            }, false);
        
        </script>
</html>

main.py

from wifi import init_wifi
import socket
import machine
import time

init_wifi()

#LED controls
red_led = machine.PWM(machine.Pin(15))
green_led = machine.PWM(machine.Pin(17))
blue_led = machine.PWM(machine.Pin(16))

#Function to load in html page    
def get_html(html_name):
    # open html_name (index.html), 'r' = read-only as variable 'file'
    with open(html_name, 'r') as file:
        html = file.read()
    return html

def find_intensity(color, request_str):
    index = request_str.find(color) + len(color)
    offset = 0
    if request_str[index].isdigit():
        offset = 1
        if request_str[index+1].isdigit():
            offset = 2
            if request_str[index+2].isdigit():
                offset = 3

    intensity = int(request_str[index:index+offset])
    return intensity
    
    
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

s = socket.socket()
s.bind(addr)
s.listen(1)

print('Listening on', addr)

# Listen for connections
while True:
    try:
        cl, addr = s.accept()
        print('Client connected from', addr)
        request = cl.recv(1024)
        
        request_str = str(request)
       
        #find intensity ONLY if the params exist in request
        if request_str.find('red') > -1 :
            #int = get rid of decimal
            #/100*65534 = find_intensity returns something 0 to 100,
            # so x/100 = proportion of 65534 that you want to send to LED
            # 65534 = max number you can use for PWM
            red_intensity = int(find_intensity('red=', request_str) /100 * 65534)
            green_intensity = int(find_intensity('green=', request_str) /100 * 65534)
            blue_intensity = int(find_intensity('blue=', request_str) /100 * 65534)
            
            #print('r=' + str(red_intensity))
            #print('g=' + str(green_intensity))
            #print('b=' + str(blue_intensity))
            
            red_led.duty_u16(red_intensity)
            green_led.duty_u16(green_intensity)
            blue_led.duty_u16(blue_intensity)
                        
        response = get_html('index.html')
        cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        cl.send(response)
        cl.close()
        
    except OSError as e:
        cl.close()
        print('Connection closed')

Когда вы нажмете кнопку "Отправить" на index.html веб-страницу, Pico W примет параметры и обработает их.

Давайте рассмотрим некоторые ключевые моменты в коде, выделенные жирным шрифтом в блоке кода выше.

функция find_intensity

Эта функция принимает два параметра: цвет и request_str. цвет принимает значения "красный", "зеленый" или "синий" и находит значение после знака равенства (=).

Например, ваш URL после отправки формы будет "http://192.168.1.142/?red=89&green=50&blue=50".

Если передать в find_intensity значение "red", оно вернет 89.

анализатор интенсивности

Второй блок кода, выделенный жирным шрифтом, представляет собой код, который сообщает GPIO Pico W, какую яркость вы хотите получить от каждого светодиода.

Прежде всего, мы должны убедиться, что параметры существуют в URL. Это делается с помощью функции если заявление request_str.find('red') > -1. Я просто использовал 'красный' потому что в параметрах будет 100% строка 'red', если вы используете форму.

Если вы впервые обращаетесь к IP-адресу вашего Pico W (например, http://192.168.1.142/), у вас не будет параметров, поэтому программа завершится аварийно, если вы выполните команду найти_интенсивность.

Если параметры существуют, мы находим интенсивность для каждого светодиода в соответствии с заданными значениями. Давайте посмотрим на red_intensity.

red_intensity = int(find_intensity('red=', request_str) /100 * 65534)
...
red_led.duty_u16(red_intensity)

найти_интенсивность возвращает целое число от нуля до 100. Мы делим это число на 100, чтобы получить процент. Этот процент делит максимальное значение, которое duty_u16 метод может быть использован.

Однако нам нужен int функцию, чтобы обернуть это, потому что иногда вы можете получить float и duty_u16 нуждается в int. Например, допустим, вам нужна яркость 41% - 41% из 65534 это 26 868,94. Вы не можете передать этот float, так как программа завершится аварийно.


4. Работа зуммера на Pico W

Зуммер - это довольно важный компонент для базовых уведомлений. Подобно тому, как светодиод может рассказать вам о состоянии чего-либо, зуммер дает вам звуковое уведомление.

Подключите положительный вывод зуммера к GPIO 16, а заземление - к выводу GND на Pico W.

Вместо того чтобы реализовывать свой собственный код, я решил использовать Реализация Джузеппе Кассибба. Если вы запустили его код на Pico W, вы услышите звуковые сигналы на зуммере.

Но поскольку этот код предназначен для Pico, в нем не будет никаких беспроводных интерактивных функций.

Итак, давайте достанем вилку!

Для начала давайте изменим index.html для реализации кнопок. Пусть у нас есть кнопки "ON", "OFF", "SCALE", "MUSIC".

Первые две кнопки не требуют пояснений. Третья кнопка воспроизводит C-шкалу, а последняя - музыкальное произведение.

<!DOCTYPE html>
<html>
    <head>
        <title>Pico W</title>
    </head>
    <body>
        <h1>Pico W Buzzer</h1>
        <p>Control the buzzer</p>
        <a href=\"?buzzer=on\"><button>ON</button></a>&nbsp;
        <a href=\"?buzzer=off\"><button>OFF</button></a>
        <a href=\"?buzzer=scale\"><button>SCALE</button></a>
        <a href=\"?buzzer=music\"><button>MUSIC</button></a>
    </body>
</html>

Как и раньше, мы создаем несколько <button> метки с <a> теги, окружающие их. При нажатии на кнопки URL-адрес будет содержать такой параметр, как /buzzer=on. Pico W считывает это и включает зуммер.

Теперь давайте посмотрим на код Джузеппе для Pico:

from machine import Pin, PWM
from time import sleep

buzzerPIN=16
BuzzerObj=PWM(Pin(buzzerPIN))

def buzzer(buzzerPinObject,frequency,sound_duration,silence_duration):
    # Set duty cycle to a positive value to emit sound from buzzer
    buzzerPinObject.duty_u16(int(65536*0.2))
    # Set frequency
    buzzerPinObject.freq(frequency)
    # wait for sound duration
    sleep(sound_duration)
    # Set duty cycle to zero to stop sound
    buzzerPinObject.duty_u16(int(65536*0))
    # Wait for sound interrumption, if needed 
    sleep(silence_duration)


# Play following notes by changing frequency:
#C (DO)
buzzer(BuzzerObj,523,0.5,0.1)

#D (RE)
buzzer(BuzzerObj,587,0.5,0.1)

#E (MI)
buzzer(BuzzerObj,659,0.5,0.1)

#F (FA)
buzzer(BuzzerObj,698,0.5,0.1)

#G (SOL)
buzzer(BuzzerObj,784,0.5,0.1)

#A (LA)
buzzer(BuzzerObj,880,0.5,0.1)

#B (SI)
buzzer(BuzzerObj,987,0.5,0.1)

#Deactivates the buzzer
BuzzerObj.deinit()

Его код воспроизводит C-шкалу при запуске с помощью функции зуммер(), который принимает четыре параметра: Объект зуммера, частота в герцах, длительность звука и длительность паузы перед воспроизведением следующего звука.

Давайте изменим код так, чтобы активировать ON, OFF, SCALE и МУЗЫКА.

Вот как мы интегрируем код Джузеппе в наш main.py:

from wifi import init_wifi
import socket
import machine
import time

init_wifi()

# Buzzer
buzzerPIN = 16
BuzzerObj = machine.PWM(machine.Pin(buzzerPIN))


def buzzer(buzzerPinObject, frequency, sound_duration, silence_duration):
    # Set duty cycle to a positive value to emit sound from buzzer
    buzzerPinObject.duty_u16(int(65536*0.2))
    # Set frequency
    buzzerPinObject.freq(frequency)
    # wait for sound duration
    time.sleep(sound_duration)
    # Set duty cycle to zero to stop sound
    buzzerPinObject.duty_u16(int(65536*0))
    # Wait for sound interrumption, if needed
    time.sleep(silence_duration)

# Function to load in html page


def get_html(html_name):
    # open html_name (index.html), 'r' = read-only as variable 'file'
    with open(html_name, 'r') as file:
        html = file.read()

    return html


# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

s = socket.socket()
s.bind(addr)
s.listen(1)

print('Listening on', addr)

# Listen for connections
while True:
    try:
        cl, addr = s.accept()
        print('Client connected from', addr)
        request = cl.recv(1024)

        request = str(request)
        buzzer_on = request.find('?buzzer=on')
        buzzer_off = request.find('?buzzer=off')
        buzzer_scale = request.find('?buzzer=scale')
        buzzer_music = request.find('?buzzer=music')

        if buzzer_on > -1:
            BuzzerObj.duty_u16(int(65536*0.2))
            BuzzerObj.freq(440)

        if buzzer_off > -1:
            BuzzerObj.duty_u16(0)

        if buzzer_scale > -1:
            #C (DO)
            buzzer(BuzzerObj, 523, 0.5, 0.1)

            #D (RE)
            buzzer(BuzzerObj, 587, 0.5, 0.1)

            #E (MI)
            buzzer(BuzzerObj, 659, 0.5, 0.1)

            #F (FA)
            buzzer(BuzzerObj, 698, 0.5, 0.1)

            #G (SOL)
            buzzer(BuzzerObj, 784, 0.5, 0.1)

            #A (LA)
            buzzer(BuzzerObj, 880, 0.5, 0.1)

            #B (SI)
            buzzer(BuzzerObj, 987, 0.5, 0.1)

            BuzzerObj.deinit()

        if buzzer_music > -1:
            pass

        response = get_html('index.html')
        cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        cl.send(response)
        cl.close()

    except OSError as e:
        cl.close()
        print('Connection closed')

В приведенной выше реализации мы не написали код для МУЗЫКА.

Код очень похож на приведенный выше учебник по работе с красным светодиодом, где Pico W захватывает параметры после IP-адреса Pico W. Если параметры зуммер=ON, он будет воспроизводить звук частотой 440 Гц. Если зуммер=шкалаОн воспроизведет шкалу, взятую из кода Джузеппе.

Как реализовать музыку? Реализация музыки немного сложнее, поэтому мы должны создать новый файл под названием constants.py и добавьте несколько строк в наш main.py.

Этот код является развилкой из Код Arduino Роуэна Паккарда.

constants.py

A3F = 208  # 208 Hz
B3F = 233  # 233 Hz
B3 = 247  # 247 Hz
C4 = 261  # 261 Hz MIDDLE C
C4S = 277  # 277 Hz
E4F = 311  # 311 Hz
F4 = 349  # 349 Hz
A4F = 415  # 415 Hz
B4F = 466  # 466 Hz
B4 = 493  # 493 Hz
C5 = 523  # 523 Hz
C5S = 554  # 554 Hz
E5F = 622  # 622 Hz
F5 = 698  # 698 Hz
F5S = 740  # 740 Hz
A5F = 831  # 831 Hz

main.py (дополнения выделены жирным шрифтом)

from wifi import init_wifi
import socket
import machine
import time
from constants import *

init_wifi()

# Buzzer
buzzerPIN = 16
BuzzerObj = machine.PWM(machine.Pin(buzzerPIN))


def buzzer(buzzerPinObject, frequency, sound_duration, silence_duration):
    # Set duty cycle to a positive value to emit sound from buzzer
    buzzerPinObject.duty_u16(int(65536*0.2))
    # Set frequency
    buzzerPinObject.freq(frequency)
    # wait for sound duration
    time.sleep(sound_duration)
    # Set duty cycle to zero to stop sound
    buzzerPinObject.duty_u16(int(65536*0))
    # Wait for sound interrumption, if needed
    time.sleep(silence_duration)

# Function to load in html page


def get_html(html_name):
    # open html_name (index.html), 'r' = read-only as variable 'file'
    with open(html_name, 'r') as file:
        html = file.read()

    return html


# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

s = socket.socket()
s.bind(addr)
s.listen(1)

print('Listening on', addr)

# Listen for connections
while True:
    try:
        cl, addr = s.accept()
        print('Client connected from', addr)
        request = cl.recv(1024)

        request = str(request)
        buzzer_on = request.find('?buzzer=on')
        buzzer_off = request.find('?buzzer=off')
        buzzer_scale = request.find('?buzzer=scale')
        buzzer_music = request.find('?buzzer=music')

        if buzzer_on > -1:
            BuzzerObj.duty_u16(int(65536*0.2))
            BuzzerObj.freq(440)

        if buzzer_off > -1:
            BuzzerObj.duty_u16(0)

        if buzzer_scale > -1:
            #C (DO)
            buzzer(BuzzerObj, 523, 0.5, 0.1)

            #D (RE)
            buzzer(BuzzerObj, 587, 0.5, 0.1)

            #E (MI)
            buzzer(BuzzerObj, 659, 0.5, 0.1)

            #F (FA)
            buzzer(BuzzerObj, 698, 0.5, 0.1)

            #G (SOL)
            buzzer(BuzzerObj, 784, 0.5, 0.1)

            #A (LA)
            buzzer(BuzzerObj, 880, 0.5, 0.1)

            #B (SI)
            buzzer(BuzzerObj, 987, 0.5, 0.1)

            BuzzerObj.deinit()

        if buzzer_music > -1:
            pause = 0.05
            # pauses between notes
            t = 0.125
            # time that music note plays

            music_notes = [B4F, B4F, A4F, A4F,
                           F5, F5, E5F, B4F, B4F, A4F, A4F, E5F, E5F, C5S, C5, B4F,
                           C5S, C5S, C5S, C5S,
                           C5S, E5F, C5, B4F, A4F, A4F, A4F, E5F, C5S,
                           B4F, B4F, A4F, A4F,
                           F5, F5, E5F, B4F, B4F, A4F, A4F, A5F, C5, C5S, C5, B4F,
                           C5S, C5S, C5S, C5S,
                           C5S, E5F, C5, B4F, A4F, A4F, A4F, E5F, C5S, C5S]

            rhythm = [1, 1, 1, 1,
                      3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2,
                      1, 1, 1, 1,
                      3, 3, 3, 1, 2, 2, 2, 4, 8,
                      1, 1, 1, 1,
                      3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2,
                      1, 1, 1, 1,
                      3, 3, 3, 1, 2, 2, 2, 4, 8, 4]

            for i in range(len(music_notes)):
                buzzer(BuzzerObj, music_notes[i], rhythm[i]*t, pause)

        response = get_html('index.html')
        cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        cl.send(response)
        cl.close()

    except OSError as e:
        cl.close()
        print('Connection closed')

Как видите, здесь два массива, музыкальные_ноты и ритм. Затем вы запустите цикл for, чтобы поместить эти значения в зуммер() функция. Кроме того, в верхней части кода мы импортируем все переменные из constants.py.

Сайт зуммер() Функция также использует две новые переменные - t и пауза. Эти две переменные помогут вам настроить темп музыки. t Определяет длительность воспроизведения каждой ноты и пауза Определяет длительность паузы между нотами.


5. Ультразвуковой датчик Pico W и HC-SR04

pico-w-ultrasonic-sensor
`

В предыдущих уроках мы использовали Pico W для подачи команд на светодиоды и зуммеры.

Но что, если мы используем Pico W для получения информации?

В данном случае речь идет об ультразвуковом датчике расстояния HC-SR04.

Когда вы подключаете ультразвуковой датчик, обязательно узнайте, является ли он компонентом с напряжением 5 В или 3,3 В. Я подключил свою 5-вольтовую версию к контакту 3,3 В и не получил никакого ответа от программы, о которой я расскажу ниже. Как только я переместил источник питания на вывод 5 В, я сразу же получил ответ.

Судя по всему, некоторые новые версии HC-SR04 могут принимать как 3,3, так и 5 В. Возможно, лучше сначала попробовать контакт 3,3 В и посмотреть, будет ли результат. Если нет, попробуйте 5 В.

Вот схемы и программа, которую можно запустить в Thonny. Если вы получите ответ, значит, вы подключили все правильно, включая напряжение.

Проводка

Провода от маркированных контактов датчиков HC-SR04 подключаются следующим образом:

  • Вывод VCC на 3,3 В или 5 В (если сомневаетесь, сначала попробуйте 3,3 В)
  • TRIG на GPIO 16
  • ECHO на GPIO 15
  • GND - GND

Программа тестирования для HC-SR04

Чтобы проверить правильность подключения, попробуйте использовать этот код, который выведет расстояние на Thonny Shell.

from machine import Pin
import time
trigger = Pin(16, Pin.OUT)
echo = Pin(15, Pin.IN)
def ultrasonic():
   trigger.low()
   time.sleep_us(1)
   trigger.high()
   time.sleep_us(10)
   trigger.low()
   while echo.value() == 0:
       signaloff = time.ticks_us()
   while echo.value() == 1:
       signalon = time.ticks_us()
   timepassed = signalon - signaloff
   distance = (timepassed * 0.0340) / 2
   print("Distance = ",distance,"cm")
while True:
   ultrasonic()
   time.sleep(1)

Ваш вывод должен быть таким:

Distance =  9.707001 cm
Distance =  9.707001 cm
Distance =  8.619 cm
Distance =  8.415001 cm
Distance =  8.551001 cm
Distance =  8.551001 cm
Distance =  8.619 cm

Если программа запускается и завершается без какого-либо выхода, вероятно, вы что-то неправильно подключили. Когда я подключил датчик к выводу 3,3 В вместо 5 В, программа завершила работу без ответа.

Получение данных, отправленных в браузер

Давайте создадим файлы, которые мы использовали для обслуживания веб-страницы, и изменим их так, чтобы мы могли видеть значения расстояния.

Вот окончательный код:

main.py

from wifi import init_wifi
import socket
from machine import Pin
import time

init_wifi()

# ultrasonic sensor pins and functions
trigger = Pin(16, Pin.OUT)
echo = Pin(15, Pin.IN)


def ultrasonic():
    trigger.low()
    time.sleep_us(1)
    trigger.high()
    time.sleep_us(10)
    trigger.low()
    while echo.value() == 0:
        signaloff = time.ticks_us()
    while echo.value() == 1:
        signalon = time.ticks_us()
    timepassed = signalon - signaloff
    distance = (timepassed * 0.0340) / 2
    return distance

# Function to load in html page

def get_html(html_name, distance):
    # open html_name (index.html), 'r' = read-only as variable 'file'
    with open(html_name, 'r') as file:
        html = file.read()
    content = html.replace(
        "<h2 id=\"ultrasonic\"></h2>", f"<h2 id=\"ultrasonic\">{distance}cm</h2>")

    return content


# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

s = socket.socket()
s.bind(addr)
s.listen(1)

print('Listening on', addr)

# Listen for connections
while True:
    try:
        cl, addr = s.accept()
        print('Client connected from', addr)
        request = cl.recv(1024)
        print(ultrasonic())
        response = get_html('index.html', ultrasonic())
        cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        cl.send(response)
        cl.close()

    except OSError as e:
        cl.close()
        print('Connection closed')

index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Pico W</title>
    </head>
      <body>
        <h1>Pico W Ultrasonic Distance</h1>
        <h2 id="ultrasonic"></h2>
        <script>
            setInterval(() => location.reload(), 500)
        </script>
</html>

Давайте посмотрим на некоторые фрагменты кода, чтобы понять, что происходит.

Код для получения ультразвукового расстояния

def ultrasonic():
    trigger.low()
    time.sleep_us(1)
    trigger.high()
    time.sleep_us(10)
    trigger.low()
    while echo.value() == 0:
        signaloff = time.ticks_us()
    while echo.value() == 1:
        signalon = time.ticks_us()
    timepassed = signalon - signaloff
    distance = (timepassed * 0.0340) / 2
    return distance

Приведенный выше блок кода запускает излучение ультразвуковой волны. Сайт время.сон между минимумами и максимумами необходимы для работы ультразвукового датчика.

Чтобы измерить время, которое проходит с момента излучения ультразвуковой волны до момента возвращения звуковой волны, мы используем time.ticks_us для измерения времени излучения и времени обнаружения эха.

time.ticks_us это произвольное число, поэтому нам придется вычесть сигнон с сайта отключение сигнала чтобы засечь время.

Чтобы получить расстояние, воспользуемся формулой расстояние = (пройденное время * скорость звука) / 2. Скорость звука равна 340 м/с, следовательно, она равна 0,0340.

Причина, по которой нам приходится делить его на два, заключается в том, что звуковая волна проходит до объекта и возвращается обратно.

Код для отображения веб-страницы со значением расстояния

def get_html(html_name, distance):
    # open html_name (index.html), 'r' = read-only as variable 'file'
    with open(html_name, 'r') as file:
        html = file.read()
    content = html.replace(
        "<h2 id=\"ultrasonic\"></h2>", f"<h2 id=\"ultrasonic\">{distance}cm</h2>")

    return content

...

response = get_html('index.html', ultrasonic())

Эта функция была немного изменена по сравнению с предыдущими учебниками: в ней появился дополнительный параметр расстояние, который работает ultrasonic().

Функция открывает index.html файл обычно, но использует заменить метод, чтобы найти <h2> и вставляет расстояние переменная.

index.html пингует сервер каждые 500 мс, чтобы получить новое значение

index.html

Главная веб-страница получает функцию, которая перезагружает веб-страницу каждые 500 мс. При каждой перезагрузке Pico W получает новое значение ультразвукового расстояния.

    <script>
            setInterval(() => location.reload(), 500)
        </script>

6. Ультразвуковые данные, но давайте использовать AJAX для уменьшения полезной нагрузки

В предыдущем руководстве Raspberry Pi Pico W посылает совершенно новый index.html файл при каждом подключении.

Это работает, но невероятно неэффективно, потому что весь index.html отправляется повторно, когда необходимо обновить только данные ультразвукового расстояния.

Мы хотим получить те же результаты, что и в предыдущем руководстве, но без тяжелого груза предыдущего метода.

Итак, нам нужно сделать так, чтобы клиент (ваш телефон или компьютер) пинговал конечную точку, которая будет отвечать только ультразвуковыми данными.

Новая методика заключается в следующем: если люди заходят на корневой URL, например 192.168.1.119, им будет предоставлен файл index.html.

index.html будет JavaScript, который будет пинговать /data конечная точка, которая заставляет Pico W получать ультразвуковые данные о расстоянии и отвечать на них.

Затем, index.html получит эти данные и обновит веб-страницу.

Расщепление запроса от клиента

Помните, что в main.pyНо всегда есть строчка, в которой говорится запросы = cl.recv(1024). Объект запроса выглядит примерно так:

b'GET /data HTTP/1.1
Host: 192.168.1.119
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.1.119/data
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,es;q=0.8,zh-TW;q=0.7,zh-CN;q=0.6,zh;q=0.5

Прежде всего, нам нужно отфильтровать эту стену текста.

Мы используем найти() метод, позволяющий определить, является ли запрос переменная имеет значение "/data". Если есть, ответьте данными об ультразвуковом расстоянии. Если "/data" отсутствует, то ответьте на запрос index.html.

До

request = cl.recv(1024)
        print(ultrasonic())
        response = get_html('index.html', ultrasonic())

После

 request = cl.recv(1024)
        request = str(request)
        print (request.find('/data'))
        if (request.find('/data') > -1):
            #if string is found, respond with data.
            response = str(ultrasonic())
        else:
            response = get_html('index.html', ultrasonic())

Если вы посетили /data в браузере, вы увидите значение расстояния, как показано ниже.

Раньше бэкэнд обрабатывал практически все. Ультразвуковое расстояние было изменено, прежде чем оно было передано как index.html.

Сейчас, index.html получает данные с датчика Pico W, поэтому нам придется внести некоторые изменения в JavaScript, который находится внутри HTML-файла. Изменения выделены жирным шрифтом.

<!DOCTYPE html>
<html>
    <head>
        <title>Pico W</title>
    </head>
      <body>
        <h1>Pico W Ultrasonic Distance</h1>
        <h2 id="ultrasonic"></h2>
        <script>
            //instead of hardcoding, use address which browser accessed Pico W.
            const PicoAddress = window.location.href

            const getData = async () => {
                //there is a slash at the end of PicoAddress, so don't use "/data". use "data"
                const data = await fetch(`${PicoAddress}data`);
                //response is just a string, so use data.text() to decode the Response's body
                const distance = await data.text();
                //target ultrasonic id and change its inner HTML
                ultrasonic.innerHTML = `${distance} cm`;
                //run getData() again.
                setInterval(getData,100)
                //you can run getData() but it seems more optimized if you give it some time to breathe
            };

            getData();
           
        </script>
</html>

Центральное место в этом коде занимает Fetch API и последние асинхронный/ожидающий Синтаксис здесь.

Функция getData() пингует конечную точку /data Pico W, и Pico W отвечает. Мы следим за тем, чтобы программа не проскочила вперед, прежде чем мы получим полный ответ с просьбой ожидайте.

Fetch превращается в объект Response, который нужно использовать в методе Response.text(), чтобы получить тело ответа. Отсюда строки const distance = await data.text();

Получив ультразвуковые данные, мы изменяем <h2 id="”ultrasonic”"> Внутренний HTML элемента, который начинается с пустого места, с данными о расстоянии. Вы можете нацелить элемент с помощью id напрямую, без использования getElementById() или querySelector() методы.

Когда весь код будет выполнен, мы хотим снова запустить getData(). Почему я использовал setInterval чтобы установить интервал в 100 мс?

Я обнаружил, что если вызывать getData() без интервала, то между выводами будет больше пауз. Получается последовательность быстрых обновлений, а затем пауза. С интервалом в 100 мс Pico W работает немного лучше, и обновления выглядят более или менее в реальном времени.

Если вы хотите понять, что происходит под капотом, обратитесь к Документация по API Fetch и асинхронный/ожидающий документация.


7. Pimoroni Phew для более чистого кода

Pimoroni Phew используется для передачи ультразвуковых данных

В предыдущем разделе мы рассмотрели метод AJAX для обновления данных ультразвукового датчика.

Но есть ли еще лучший способ сделать это?

Pimoroni's Phew - это библиотека, которая поможет вам легко работать в сети, поскольку вы сможете избежать множества лекарств.

Цели одинаковы:

  • Получение ультразвуковых данных и их отображение на экране index.html
  • Держите полезную нагрузку как можно ниже.

Вот как main.py выглядит как.

from wifi import init_wifi
from phew import server
from phew.template import render_template
from machine import Pin
import time

init_wifi()

# ultrasonic sensor pins and functions
trigger = Pin(16, Pin.OUT)
echo = Pin(15, Pin.IN)


# Function to load in html page

@server.route("/data", methods=["GET"])
def ultrasonic(request):
    trigger.low()
    time.sleep_us(1)
    trigger.high()
    time.sleep_us(10)
    trigger.low()
    while echo.value() == 0:
        signaloff = time.ticks_us()
    while echo.value() == 1:
        signalon = time.ticks_us()
    timepassed = signalon - signaloff
    distance = (timepassed * 0.0340) / 2
    return str(distance), 200


@server.catchall()
def catchall(request):
    return render_template("index.html")


server.run()

Как видите, код стал гораздо более читабельным, поскольку вы можете задавать конечные точки и связывать их с функциями, возвращающими определенные данные.

Вместо того чтобы возиться с кодом для запуска сокетов, вы просто вызываете функцию из библиотеки Phew.

Некоторые вещи, которые нравятся в Phew, - это:

  • Больше не нужно использовать request.find() чтобы создать конечную точку
  • Не более get_html() чтобы открыть index.html файл, просто используйте Phew's render_template()
  • main.py читать гораздо легче, а дополнительные усилия минимальны!
  • В Phew также добавлена функция протоколирования, которая позволит вам легче отлаживать свой код.

Единственный минус - это то, что Phew все еще "очень новый проект, и его следует рассматривать в лучшем случае как альфа-стадию". Поэтому иногда на пути могут возникать неожиданные препятствия.

Проверьте.

В предыдущих руководствах рассказывалось о том, как взаимодействовать с Pico W с помощью компьютера/мобильного телефона.

Давайте сделаем шаг вперед и заставим Pico W взаимодействовать с облачным сервисом.

Для этого давайте сделаем регистратор температуры и влажности с датчиком DHT22, который будет отправлять данные в Google Sheets через IFTTT.


8. Настройка датчика температуры и влажности DHT22 на Pico W

Raspberry Pi Pico W в паре с регистратором температуры и влажности DHT22.

Все эти действия работают для DHT11 и DHT22. Основное различие между ними заключается в точности показаний. DHT11 имеет синий цвет, а DHT22 - белый.

Если у вас есть DHT11, обратите внимание, что ссылки на DHT22 в коде должны быть заменены на DHT11. Например,

import dht
#dht22 = dht.DHT22(Pin(16))
#should be
dht11 = dht.DHT11(Pin(16))
Штырьки DHT22

Если посмотреть на схему ниже, то сверху вниз DHT22 подключается к первому выводу 3,3 В.

Второй контакт - это контакт данных. Вам нужно подать на него питание. Поэтому подключите к нему резистор 10K Ом от шины питания, а затем подключите еще один провод-перемычку к GPIO 16 на Raspberry Pi Pico.

GND подключается к GND.

Чтобы проверить датчик, выполните следующее:

from machine import Pin
import dht

# ultrasonic sensor pins and functions
dht22 = dht.DHT22(Pin(16))

print(dht22.measure())
print(dht22.temperature())
print(dht22.humidity())

Если вы получите OSError: [Errno 110] ETIMEDOUT означает, что вы запускаете скрипт слишком рано. DHT22 требуется двухсекундный перерыв, прежде чем он сможет вернуть другое значение. DHT11 требуется одна секунда.

Соединение IFTTT и Google Sheets

Pico W регистрирует данные о времени, температуре и влажности в Google Sheets

Самый простой способ получить данные из Pico W в Google Sheets - это IFTTT.

Первый, зарегистрируйте учетную запись IFTTT.

Затем нажмите кнопку "Создать", чтобы создать апплет.

Вы увидите этот экран:

Нажмите "Если это" и найдите Webhooks. Нажмите на "Получить веб-запрос". Не выбирайте JSON. Назовите имя события "dht22". Имя события очень важно, потому что так IFTTT узнает, какой апплет запускать.

Выберите этот вариант, а не вариант с полезной нагрузкой JSON.

Здесь вы создаете конечную точку, которую можно пинговать данными датчика DHT22.

Затем нажмите "Затем это". Выберите "Таблицы Google". Затем выберите "Добавить строку в электронную таблицу". Вам придется связать свой аккаунт Google Sheets.

Измените "Имя электронной таблицы" и "Путь к папке на диске" так, как вам нужно. Единственное, что здесь важно, это "Строка форматирования", где вы хотите, чтобы она была

{{OccurredAt}} ||| {{Value1}} ||| {{Value2}}

Теперь вам нужно получить конечную точку, на которую Pico W может отправлять данные с датчиков.

Направляйтесь к https://ifttt.com/maker_webhooks и нажмите на "Документация".

В документации вы найдете ключ, конечную точку, куда нужно отправить данные, и как структурировать тело JSON.

Поскольку вы использовали "dht22" в качестве имени события, ваша конечная точка - это:

ttps://maker.ifttt.com/trigger/dht22/with/key/[your_key_here]

Вы также захотите структурировать тело JSON следующим образом:

{'value1': *** temperature data *** , value2': *** humidity data *** }

Кодирование Pico W для получения данных DHT22 и отправки их в IFTTT

Вот как.

from machine import Pin
from wifi import init_wifi
import urequests
import ujson
import dht
import time

init_wifi()

dht22 = dht.DHT22(Pin(16))


def send_data():
    #tell dht22 to take a reading
    dht22.measure()
    #find temp & humidity data and then jsonify data.
    dht_data = {'value1': str(dht22.temperature()),
                'value2': str(dht22.humidity())}
    post_data = ujson.dumps(dht_data)
    request_url = 'https://maker.ifttt.com/trigger/dht22/with/key/[your_key_here]'
    res = urequests.post(request_url, headers={
                         'content-type': 'application/json'}, data=post_data)
    #log response from IFTTT.
    print(res.text)
    #sleep for a minute before running send_data again
    time.sleep(1*60)
    send_data()


send_data()

Если вы собираетесь скопировать этот код, не забудьте заменить [your_key_here] гостиница request_url переменная.

Каждую минуту вы должны получать новые показания, которые будут записываться в Google Sheet, как показано ниже.

Pico W регистрирует данные о времени, температуре и влажности в Google Sheets

Обратите внимание, что температура регистрируется в градусах Цельсия. Если вам нужна температура в фаренгейтах, вот формула:

fahrenheit = dht22.temperature() * 1.8000 + 32.00

Если вы хотите, чтобы данные регистрировались чаще (или реже), измените значение в поле время.сон().

Используйте IFTTT для уведомления о возникновении ошибок

Конечно, этот код все еще довольно хрупок.

Допустим, что-то пошло не так. Например, ваша кошка потянула за провод перемычки 3,3 В, пока вы лежали на полу и регистрировали температуру.

Программа умрет, но вы не получите никакого уведомления, пока не заметите, что ваши данные не регистрируются.

Как вы решаете эту проблему?

Заставьте IFTTT присылать вам уведомления, когда это произойдет!

Вам понадобится приложение IFTTT на вашем телефоне. Поэтому скачайте его.

Затем создайте новый апплет.

Для "Если это" часть, Выбрать Webhooks -> Получение веб-запроса. Назовите свое мероприятие "ошибка".

Для "Тогда это". выберите "Уведомления" и "Отправить уведомление из приложения IFTTT"..

Я сделал сообщение простым

Error: {{Value1}}

Теперь давайте построим блоки try-error.

from machine import Pin
from wifi import init_wifi
import urequests
import ujson
import dht
import time

init_wifi()

dht22 = dht.DHT22(Pin(16))


def send_data():
    # tell dht22 to take a reading
    dht22.measure()
    # find temp & humidity data and then jsonify data.
    dht_data = {'value1': str(dht22.temperature()),
                'value2': str(dht22.humidity())}
    post_data = ujson.dumps(dht_data)
    request_url = 'https://maker.ifttt.com/trigger/dht22/with/key/[your-key-here]'
    res = urequests.post(request_url, headers={
                         'content-type': 'application/json'}, data=post_data)
    # log response from IFTTT.
    print(res.text)
    # sleep for a minute before running send_data again
    time.sleep(1*60)
    send_data()


try:
    send_data()
except Exception as e:
    print(e)
    request_url = 'https://maker.ifttt.com/trigger/error/with/key/[your-key-here]'
    post_data = ujson.dumps({"value1": str(e)})
    urequests.post(request_url, headers={
        'content-type': 'application/json'}, data=post_data)

Попробуйте. Отключите провод 3,3 В от DHT22, и вы получите соответствующее уведомление:


9. Постройте физический пульт дистанционного управления Spotify с помощью Raspberry Pi Pico W

Основываясь на предыдущем проекте, мы будем использовать IFTTT для управления Spotify.

Мы создадим устройство с кнопками воспроизведения, паузы и пропуска трека.

Главное преимущество использования IFTTT для управления Spotify заключается в том, насколько это просто.

Недостатком является то, что вам нужна платная учетная запись Spotify, а также медленный отклик. То есть если вы нажмете кнопку "Пропустить", вам придется подождать некоторое время, прежде чем вы увидите результат.

Прелесть специального пульта Spotify в том, что вы можете менять музыку, не нося с собой телефон и не открывая приложение Spotify.

Если вы когда-нибудь водили современный автомобиль, то знаете, как приятно иметь управление на рулевом колесе.

Подключение удаленного контроллера Spotify

Контроллер Spotify Raspberry Pi Pico W
Контроллер Spotify Raspberry Pi Pico W. Сверху вниз расположены кнопки: пауза, воспроизведение, пропуск трека.

Вам понадобится...

  • 7x проводов-перемычек
  • 3x кнопки
  • Raspberry Pi Pico W
  • Платный аккаунт Spotify

На изображении много перекрещивающихся проводов, так что вот вам текстовое объяснение.

Кнопки похожи на переключатели. К каждой из них нужно подключить вывод 3V3, что означает использование положительного столбца на макетной плате. Поэтому:

3V3 -> положительный столбик макетной платы -> кнопка (с одной стороны макетной платы) -> GPIO (с другой стороны)

Мой код будет использовать GPIO 16 для кнопки воспроизведения, GPIO 2 для кнопки паузы и GPIO 15 для кнопки пропуска трека.

Настройка IFTTT для управления Spotify

Мы создадим три апплета IFTTT для управления Spotify.

Нам нужно создать три апплета, по одному для функций воспроизведения, паузы и пропуска.

Если у вас есть премиум-версия IFTTT, вы, вероятно, могли бы использовать фильтры JavaScript, чтобы собрать все это в одном приложении. Но так как у нас их нет, нам нужен каждый апплет.

Войдя в систему, нажмите на кнопку "Создать" в правом верхнем углу главного меню.

На панели "Если это" нажмите на нее и найдите Webhooks.

Нажмите на "Если это" или "Тогда это" и выберите Webhooks и Spotify соответственно.

Затем нажмите на "Получить веб-запрос" (а не на другой вариант, где есть "с полезной нагрузкой JSON").

Для названия события введите spotify_skip.

Вам придется повторить этот шаг еще два раза, чтобы spotify_pause и spotify_play как только вы закончите создание этого апплета.

Как только это будет сделано, перейдите в раздел "Тогда это" и нажмите на нее. Найдите "Spotify".

Вам придется один раз авторизовать IFTTT для подключения к Spotify.

Если вы делаете spotify_skip действие, вы захотите нажать на "Пропустить дорожку". Но если вы делаете апплет для выполнения какого-то другого действия, изображение выше покажет вам, какой из них следует использовать.

После того как вы создали все три апплета, пришло время кодировать!

Кодирование пульта Spotify для Pico W

Прежде всего, вам нужно знать конечную точку, в которую нужно попасть.

Перейти на эту страницу и нажмите на кнопку Документация.

Вы увидите там свой ключ. Если вы выполнили все описанные выше шаги, разница между вашей конечной точкой и моей заключается в вашем ключе. Следовательно,

Конечная точка воспроизведения: https://maker.ifttt.com/trigger/spotify_play/with/key/[ваш_ключ_здесь]

Пауза: https://maker.ifttt.com/trigger/spotify_pause/with/key/[ваш_ключ_здесь]

Скип: https://maker.ifttt.com/trigger/spotify_skip/with/key/[ваш_ключ_здесь]

Код

from machine import Pin
from wifi import init_wifi
import urequests
import time

init_wifi()

play_btn = Pin(16, Pin.IN, Pin.PULL_DOWN)
pause_btn = Pin(2, Pin.IN, Pin.PULL_DOWN)
skip_btn = Pin(15, Pin.IN, Pin.PULL_DOWN)


def play():
    request_url = 'https://maker.ifttt.com/trigger/spotify_play/with/key/[your_key_here]'
    res = urequests.post(request_url)
    # print response from IFTTT.
    print(res.text)


def pause():
    request_url = 'https://maker.ifttt.com/trigger/spotify_pause/with/key/[your_key_here]'
    res = urequests.post(request_url)
    # print response from IFTTT.
    print(res.text)


def skip():
    request_url = 'https://maker.ifttt.com/trigger/spotify_skip/with/key/[your_key_here]'
    res = urequests.post(request_url)
    # print response from IFTTT.
    print(res.text)


try:
    while True:
        if play_btn():
            print('play btn')
            play()
            time.sleep(0.25)
        if pause_btn():
            print('pause btn')
            pause()
            time.sleep(0.25)
        if skip_btn():
            skip()
            print('skip')
            time.sleep(0.25)

except Exception as e:
    print(e)
    request_url = 'https://maker.ifttt.com/trigger/error/with/key/[your_key_here]'
    post_data = ujson.dumps({"value1": str(e)})
    urequests.post(request_url, headers={
        'content-type': 'application/json'}, data=post_data)

Давайте пройдемся по коду.

Обратите внимание, что вам нужно будет заменить [your_key_here] с вашим настоящим ключом, полученным через Документация ссылка.

Сначала мы объявим переменные для кнопок.

play_btn = Pin(16, Pin.IN, Pin.PULL_DOWN)
pause_btn = Pin(2, Pin.IN, Pin.PULL_DOWN)
skip_btn = Pin(15, Pin.IN, Pin.PULL_DOWN)

В настоящее время, если вы не нажмете на кнопку, ваша переменная будет иметь значение 0. Если нажать на нее, она станет 1. Это то, что мы будем использовать для запуска играть() , пауза() и пропустить() функции.

Затем мы создаем функции для конечных точек воспроизведения, паузы и пропуска. Общий шаблон выглядит следующим образом:

def play():
    request_url = 'https://maker.ifttt.com/trigger/spotify_play/with/key/[your_key_here]'
    res = urequests.post(request_url)
    # print response from IFTTT.
    print(res.text)

Все очень просто. Если запустить эту функцию, она отправит POST-запрос в IFTTT. Отправка GET-запроса не будет работать.

Затем у нас есть блок try/except.

try:
    while True:
        if play_btn():
            print('play btn')
            play()
            time.sleep(0.25)
        if pause_btn():
            print('pause btn')
            pause()
            time.sleep(0.25)
        if skip_btn():
            skip()
            print('skip')
            time.sleep(0.25)

except Exception as e:
    print(e)
    request_url = 'https://maker.ifttt.com/trigger/error/with/key/[your_key_here]'
    post_data = ujson.dumps({"value1": str(e)})
    urequests.post(request_url, headers={
        'content-type': 'application/json'}, data=post_data)

Если нажать кнопку, код запустит соответствующую функцию. Например, при нажатии кнопки пропуска будет запущена функция пропустить().

A time.sleep(0.25) приостановит выполнение функции на 250 мс. Без этого даже короткое нажатие может привести к перегрузке и выходу из строя Pico W.

Сайт кроме Блок необязателен, но я сделал его, потому что у меня уже был апплет "Ошибка" на IFTTT. Если вы следовали предыдущему руководству, вы могли использовать его.

По сути, он отправляет сообщение об ошибке, eв IFTTT, чтобы вы получали сообщение об ошибке в виде уведомления приложения на телефоне.

Почему он не работает?

Использовать IFTTT в качестве средства управления Spotify очень просто, но это имеет и некоторые недостатки.

Сначала вы должны запустить музыку обычным способом

Если вы пытались нажать кнопку воспроизведения на своем Pico W и ожидали, что музыка начнет играть... но ничего не произошло.

Решение заключается в том, чтобы запустить музыку на компьютере или телефоне обычным способом. Вам нужно зайти в приложение и нажать кнопку play.

Я думаю, что это объявляет, какое устройство является активным. После этого вы сможете использовать пульт Pico W Spotify.

Медленные ответы

Между нажатием кнопки и ответом проходит несколько секунд. К сожалению, так оно и есть.

Вы можете заплатить за обновление IFTTT, чтобы получить более высокую скорость реагирования. По крайней мере, это то, что они обещают за ваши деньги.

Есть ли прямой способ подключить Spotify?

Да! У Spotify есть API, к которому вы можете подключиться.

Это дает значительно больше возможностей для управления. Вы можете добавить поворотный энкодер для регулировки громкости. Можно добавить ЖК-экран для отображения воспроизводимой информации. Ознакомьтесь с консолью Spotify здесь.

Удивительно, но программировать гораздо сложнее, особенно на Pico W.

IFTTT делает все это легко, потому что они выполняют всю тяжелую работу. Если вы хотите быть тяжелым грузчиком, ознакомьтесь с потоком аутентификации.

Диаграмма потока кода авторизации от Spotify

Конечно, мы же энтузиасты Raspberry Pi. Кто-то обязательно сделает это. Может быть, это будете вы? Или я? Пишите в комментариях ниже.

Управляйте Pico W по беспроводной связи с помощью PiCockpit!

Вы можете управлять и получать данные с Pico W по беспроводной связи с помощью PiCockpit.

PiCockpit позволяет получать значения, управлять и использовать ШИМ через графический интерфейс с помощью апплета GPIO.

Вы также можете посмотреть статистику вашего Pico W с помощью апплета PiStats.

Интеграция PiCockpit в ваш Pico W очень проста.

Следуйте этому руководству.

Пишите еще меньше кода с помощью PiCockpit и Pico W

PiCockpit позволяет легко управлять пинами GPIO без необходимости написания кода.

Если вы посмотрите на учебник № 2Обратите внимание, как много кода необходимо для переключения светодиода.

С нашей новой интеграцией Pico W, PiCockpit делает это намного проще, поскольку вам не нужно ничего программировать. Даже конфигурация WiFi не требуется - это делается с помощью нашего мастера настройки.

10. Простое управление светодиодами с помощью PiCockpit и Pico W

Если вы настроили свой светодиод точно так, как я сделал это в руководстве № 2, то все, что осталось, это настроить его на PiCockpit.

Если вы кодируете его, вы объявите, на каком выводе находится ваш светодиод, используя led = machine.Pin(2, machine.Pin.OUT)

В PiCockpit перейдите к апплету GPIO и выберите пункт "GPIO Output (On/Off)".

Выберите BCM02 из выпадающего меню, так как ваш светодиод находится на GPIO 2.

Затем в колонке "Управление" переключите переключатель, чтобы включить светодиод.

Вы также можете легко использовать раздел Software PWM ниже для управления яркостью вашего светодиода.

Обратите внимание, что вам нужно удалить предыдущую настройку, потому что вы не можете иметь два выхода на одном GPIO.

При переключении ползунка "Управление" вы заметите, как меняется яркость светодиода.

пульт дистанционного управления picockpit gpio pwm

11. Pico W, вентилятор на 5 В и транзистор, управляемый PiCockpit

Давайте попробуем сделать что-то более комплексное, но с использованием того же переключателя GPIO Output.

Чтобы проиллюстрировать некоторые реальные случаи использования, я запитаю вентилятор от 5 В с помощью PiCockpit.

Это маломощный вентилятор на 5 В, взятый из моего Raspberry Pi 4, поэтому он вполне соответствует выходным возможностям Raspberry Pi Pico W.

При этом, поскольку это вентилятор на 5 В, я не могу использовать вывод GPIO. В менее энергоемких компонентах, таких как светодиод, GPIO может выполнять двойную функцию: подавать питание на компонент и быть "переключателем", который включает и выключает его.

Но для вентилятора на 5 В потребуется слишком высокое напряжение. Поэтому следующий лучший способ - поставить транзистор посередине.

Это позволяет мне подавать 5 В на вентилятор, обеспечивая при этом возможность его включения и выключения.

И снова, благодаря PiCockpit, я не занимался программированием. Я сделал только аппаратную часть, которая подключена следующим образом:

Вентилятор представляет собой вентилятор 5В/0,12А, подключенный к 5В на положительном конце (красный провод), а отрицательный провод идет к эмиттерной ножке транзистора.

Транзистор представляет собой транзистор PN2222 (NPN), что означает, что он включается, когда получает высокий сигнал.

Слева направо, с полукруглой частью, направленной от вас, ноги - это излучатель, основание и коллектор.

Базовая ножка подключается к резистору 1K, затем подключается к GPIO 15.

Ножка коллектора подключена к земле.

Настройка PiCockpit для работы с транзистором

И снова все очень просто.

Перейдите в выпадающее меню в разделе GPIO Output и добавьте BCM15.

После того, как он установлен, вы можете нажать стрелку вниз и изменить имена состояний на "вентилятор выключен" и "вентилятор включен".

Переключите переключатель управления, и вы увидите, что вентилятор включился.

Вы также можете использовать PiStats, чтобы увидеть снижение температуры на вашей плате.

Отображение фоторезистора с помощью MQTT и Node-RED с Pico W.

Основная цель этого урока - познакомить вас с MQTT.

В предыдущих уроках я показал вам, как можно использовать Pico W для передачи данных, но что если вам нужно центральное хранилище данных в облаке?

HiveMQ Cloud - это бесплатный сервис, который мы можем использовать для достижения этой цели. Используя чужие компьютеры, мы также сможем снизить нагрузку на Pico W.

Кроме того, MQTT обладает значительными преимуществами по сравнению с предыдущими методами. Во-первых, он гораздо эффективнее при отправке небольших данных. Размер заголовков протокола MQTT составляет 2 байта. HTTP примерно в 4000 раз больше.

Снижение нагрузки на локальную обработку данных и сеть означает более длительное время автономной работы Pico W, что идеально подходит для проектов с питанием от аккумуляторов или солнечных батарей.

Подключение фоторезистора к Pico W

Фоторезистор (фотоэлемент) очень легко подключить.

Поместите фоторезистор через центральный желоб макетной платы.

Затем подключите вывод 3V3 к одной из сторон фоторезистора.

Вы захотите подключить вывод АЦП к другой стороне фоторезистора, поэтому подключите GPIO 26.

Наконец, подключите резистор 10 К Ом от земли к фотоэлементу.

Облако HiveMQ и кодирование Pico W

Первый, Зарегистрируйтесь на HiveMQ Cloud здесь.

Перейдите к настройке и создайте кластер. Вам будет предложено выбрать AWS или Azure. Для наших целей разницы нет.

Затем нажмите "Управление кластером".

Главное меню кластера. Обратите внимание на два оранжевых прямоугольника.

Запишите URL-адрес вашего кластера и нажмите на Управление доступом, чтобы создать нового пользователя. Выполните все шаги и создайте нового пользователя.

Теперь, получив эти данные, вы можете запрограммировать Pico W на отправку данных туда.

Кодирование Pico W для приема данных фотоэлементов и MQTTClient

from machine import Pin, ADC
from wifi import init_wifi
import time
from umqtt.simple import MQTTClient

init_wifi()

photoresistor = ADC(Pin(26))


def readLight():
    light = photoresistor.read_u16()
    return light


# Connect MQTT

def connectMQTT():
    client = MQTTClient(client_id=b"[your_client_id]",
                        server=b"[your-host-name]",
                        port=0,
                        user=b"[your-user]",
                        password=b"[your-pw]",
                        keepalive=7200,
                        ssl=True,
                        ssl_params={
                            'server_hostname': '[your-host-name]'}
                        )

    client.connect()
    return client


client = connectMQTT()


def publish(topic, value):
    print(topic)
    print(value)
    client.publish(topic, value)
    print("data published")


while True:
    brightness = str(readLight()) #to publish, must send string

    print(brightness)

    publish('picow/brightness', brightness)

    time.sleep(0.1)

Для начала давайте наведем порядок в импорте.

from machine import Pin, ADC
from wifi import init_wifi
import time
from umqtt.simple import MQTTClient

Сайт wifi Импорт происходит из предыдущих уроков.

Вам понадобится библиотека umqtt.simple, которая можно скачать здесь.

После загрузки вы можете загрузить его на свою доску (руководство здесь).

Эти файлы должны быть у вас на Pico W.

Затем создайте функцию для получения показаний с фоторезистора:

photoresistor = ADC(Pin(26))

def readLight():
    light = photoresistor.read_u16()
    return light

Возвращает значение до 65535. Чем ярче, тем выше значение.

Подключение к HiveMQ

Чтобы подключиться к HiveMQ, вам нужно передать классу MQTTClient некоторые параметры.

# Connect MQTT

def connectMQTT():
    client = MQTTClient(client_id=b"[your_client_id]",
                        server=b"[your-host-name]",
                        port=0,
                        user=b"[your-user]",
                        password=b"[your-pw]",
                        keepalive=7200,
                        ssl=True,
                        ssl_params={
                            'server_hostname': '[your-host-name]'}
                        )

    client.connect()
    return client


client = connectMQTT()

Замените [your-host-name] на адрес, указанный на вашей приборной панели. Вам придется сделать это дважды, один раз для server и еще один для server_hostname. Также замените [your_client_id] на имя вашего устройства, например "your_picow".

Затем замените [your-user] и [your-pw] с пользователем, которого вы создали на странице управления доступом (снимок страницы управления доступом ниже).

Для справки, эта функция отправляет данные в HiveMQ:

def publish(topic, value):
    print(topic)
    print(value)
    client.publish(topic, value)
    print("data published")

Давайте назовем его в нашем while петля:

while True:
    brightness = str(readLight()) #to publish, must send string

    print(brightness)

    publish('picow/brightness', brightness)

    time.sleep(0.1)

При публикации необходимо отправлять строки, поэтому brightness = str(readLight()) там.

Если вы отправите целые числа или плавающие, программа умрет.

В функции публикации дайте название своей теме. Скажем, picow/brightness, затем добавьте значение, которое вы хотите отправить. В данном случае мы хотим отправить строчное значение освещенности, brightness.

Вы должны увидеть публикуемые данные при входе на вкладку Web Client.

Веб-клиент HiveMQ (слева) показывает опубликованные данные.

Node-RED

Это просто цифры в Интернете, которые могут показаться тарабарщиной. Что, если вы хотите получить доступ к данным в HiveMQ Cloud и представить их в графическом виде?

Вместо того чтобы создавать свой собственный, вы можете просто использовать Node-RED.

Node-RED позволяет очень просто получать данные из HiveMQ и представлять их в графическом виде.

Мы собираемся создать датчик с помощью Node-RED.

Чтобы начать, вам потребуется nodejs. Ознакомьтесь с документацией HiveMQ чтобы узнать, какая версия рекомендуется.

После установки Node вам нужно будет открыть командную строку/терминал и выполнить эти команды (исключите sudo, если вы работаете в Windows):

sudo npm install -g --unsafe-perm node-red

Это позволит использовать менеджер пакетов node (npm) для глобальной установки Node-RED.

Затем запустите Node-RED, набрав node-red в терминале/командной строке.

Откройте браузер и перейдите по ссылке http://127.0.0.1:1880 или любой другой адрес, указанный в вашем Терминале.

Давайте создадим поток. Перетащите "mqtt in" на холст. Вы можете найти его на вкладке "Сеть" на левой боковой панели.

Нам нужно настроить вкладку, поэтому дважды щелкните на прямоугольнике и выполните следующие действия:

В поле "Тема" обязательно добавьте picow/brightnessпоскольку именно это вы опубликовали с Pico W.

В разделе "Сервер" добавьте новый, нажав на значок карандаша, и вы попадете в следующее меню.

Вставьте новый адрес сервера и измените порт на 8883. Отметьте "Использовать TLS", но не добавляйте новый tls-config.

Затем перейдите на вкладку "Безопасность" и введите свои учетные данные для входа в систему.

Все эти детали можно найти в вашем коде, когда вы инициализируете MQTTClient.

Добавление манометра

Чтобы добавить манометр, вы должны иметь node-red-dashboard.

На левой боковой панели, если вы их не видите:

Затем перейдите в меню (правая верхняя кнопка) -> Управление палитрой. Затем перейдите на вкладку "Установить" и найдите node-red-dashboard. Нажмите на кнопку "Установить".

Перетащите "калибр" в правую часть экрана. mqtt в прямоугольник, и соедините их, перетащив линию из mqtt в к манометру.

Дважды щелкните на прямоугольнике измерителя и измените метку на "яркость", а "диапазон" - на 65535.

Отлично. Теперь давайте нажмем "Развернуть".

Если настройки были верными, вы увидите зеленый круг и надпись "connected" под прямоугольником. Если нет, ваш терминал предоставит вам более подробную информацию об ошибке.

Теперь, когда ваш Pico W передает данные в облако HiveMQ, самое время проверить приборную панель. Посетите http://127.0.0.1:1880/ui и вы увидите, что индикатор часто обновляется.


Ваши предложения приветствуются.

Оставьте свой комментарий в поле для комментариев ниже!

6 комментариев

  1. Quang Январь 10, 2023 в 2:21 пп

    Здравствуйте,
    Спасибо, что поделились с нами своими знаниями.
    Не могли бы вы подсказать, предназначены ли упражнения по WiFi только для работы в сети? Я не смог получить доступ к Pico W, если я нахожусь в другой сети WiFi. Если да, то есть ли у вас примеры для доступа вне сети?
    Спасибо.

    • raspi berry Февраль 4, 2023 в 11:52 дп

      Да, из-за природы сетей, маршрутизаторов и брандмауэров эти упражнения работают только в пределах одной сети WiFi.
      PiCockpit сам по себе является сетевым решением - вы можете получить доступ к своему Pico W из любой точки Интернета.
      Мы работаем над тем, чтобы привнести в платформу больше возможностей.

      Если вы хотите воссоздать нечто подобное самостоятельно, вам понадобится какое-то решение для туннелирования в вашей сети, или сервер ретрансляции, или что-то подобное.
      Мы предлагаем консультационные услуги, если вы хотите углубиться в эту тему.

  2. Peter Mayr Март 29, 2023 в 10:44 дп

    Спасибо за этот замечательный учебник.
    К сожалению, это не работает.
    Я застрял в конце части "1. Создайте веб-страницу с надписью "Hello World" на Pico".

    Мои веб-браузеры Firefox и Chrome сообщают мне только "Ошибка соединения прервана".
    В Тонни я вижу

    Подключено
    ip = 192.168.188.198
    Прослушивание на ('0.0.0.0', 80)
    Клиент подключился с ('192.168.188.100', 54025)
    Соединение закрыто

    Соединение закрывается пару раз.
    Что можно изменить, чтобы мой Pico W работал?
    Заранее благодарю вас за помощь.
    С уважением, Пит

  3. mokcp Май 3, 2023 в 10:58 дп

    При запуске файла main.py появляется сообщение об ошибке, как ее решить.

    Файл "", строка 1, в
    ImportError: нет модуля с именем 'wifi'

    Заранее спасибо.

    • PiCaptain Май 10, 2023 в 12:31 пп

      Вы должны создать и добавить файл wifi.py, который показан чуть выше на странице. Без wifi.py код не будет работать.

  4. màn hình led Август 26, 2023 в 2:18 пп

    Самоучитель по компонентам Raspberry Pi Pico W для начинающих" - это фантастическое руководство для тех, кто только начинает осваивать платформу Raspberry Pi Pico W. Учебник хорошо структурирован и прост в освоении, что делает его идеальным для новичков. Оно охватывает основные компоненты и содержит четкие инструкции, что делает его отличной отправной точкой для тех, кто хочет изучить эту технологию. Включение подробных объяснений и изображений улучшает процесс обучения, гарантируя, что читатели смогут быстро понять концепции. В целом, это руководство является ценным ресурсом для тех, кто хочет начать работу с Raspberry Pi Pico W и его компонентами.

Комментировать