将 ChatGPT API 集成到树莓派( Raspberry Pi )Pico W,成功驱动液晶屏打印结果

2023年开年以来,以OpenAI的ChatGPT为代表的人工智能 (AI)应用热度一直不减,有许多第三方的开发者,会将ChatGPT整合到各种有意思的产品中,这不,日本一位电子工程师就把ChatGPT带到了树莓派Pico W的世界,并成功驱动一块液晶屏将结果打印了出来。
图片[1] - 将 ChatGPT API 集成到树莓派( Raspberry Pi )Pico W,成功驱动液晶屏打印结果 - EVLIT

基础架构

图片[2] - 将 ChatGPT API 集成到树莓派( Raspberry Pi )Pico W,成功驱动液晶屏打印结果 - EVLIT

前期准备

  • 准备一个OpenAI账号,并生成API,后续在开发时需要用到,树莓派Pico W与ChatGPT进行沟通,需要使用OpenAI的API,并不是基于网页版的accessToken
  • 如果你在中国大陆等不受OpenAI支持的国家或地区,就要准备一个全局代理环境了
  • 准备一个电脑/笔记本电脑,用于基本的代码操作
  • 准备一个树莓派Pico W,今天的主角

开发环境

本文使用以下开发环境。

  • 微型计算机:Raspberry Pi Pico W(提前装好排针)
  • 编程语言:MicroPython
  • IDE:Thonny

部署 ChatGPT API 到树莓派

将下面的代码保存到您的 Pico W。要注意,要将 Wi-Fi SSID、密码和 API 密钥更改为您自己的。

import urequests as requests
import network
import utime
import json

#输入自己家里的Wi-Fi SSID和密码
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)

# Wait for connect or fail
max_wait = 10
while max_wait > 0:
    if wlan.status() < 0 or wlan.status() >= 3:
        break
    max_wait -= 1
    print('waiting for connection...')
    utime.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()
        utime.sleep(.2)
        led.off()
        utime.sleep(.2)

# Handle connection error
# Error meanings
# 0  Link Down
# 1  Link Join
# 2  Link NoIp
# 3  Link Up
# -1 Link Fail
# -2 Link NoNet
# -3 Link BadAuth

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])

# OpenAI API key
openai_api_key = "YOUR OpenAI API key"  # 输入前面保存下来的OpenAI API Key

# 设置 OpenAI Chat Completion API Endpoint
ENDPOINT = 'https://api.openai.com/v1/chat/completions'

# 构建Chatbot响应函数体
def get_chat_response(prompt):
    # 设置 API 请求头
    headers = {
        'Content-Type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + openai_api_key
    }

    # 设置API请求数据,这里使用gpt-3.5的模型
    data = {
        'model': 'gpt-3.5-turbo',
        'messages': [{'role': 'user', 'content': prompt }]
    }

    # 发送 API 请求
    json_data = json.dumps(data)
    encoded_data = bytes(json_data, 'utf-8')
    response = requests.post(ENDPOINT, headers=headers, data=encoded_data)

    # 解析 API 响应
    response_json = json.loads(response.text)
    message = response_json['choices'][0]['message']['content'].strip()
    return message

# 向Chatbot问好
prompt = "你是谁?"
print('User: ' + prompt)

# 获取聊天机器人响应
chat_response = get_chat_response(prompt)
print('Chatbot: ' + chat_response)

在 Thonny 上运行上面的代码将打印出“你是谁?”这个问题的答案(机翻)。
图片[3] - 将 ChatGPT API 集成到树莓派( Raspberry Pi )Pico W,成功驱动液晶屏打印结果 - EVLIT
通过更改 prompt=”Who are you?” 文本,就可以提出不同的问题。

代码解释

第 6-50 行是连接 Wi-Fi 的代码。

# OpenAI API key
openai_api_key = "YOUR OpenAI API key"  # 输入前面保存下来的OpenAI API Key

# 设置 OpenAI Chat Completion API Endpoint
ENDPOINT = 'https://api.openai.com/v1/chat/completions'

设置您的 OpenAI API 密钥和Chat Completion API 端点。这样就可以使用 Chat Completion API 从您的 Chatbot 获取响应。

# 构建Chatbot响应函数体
def get_chat_response(prompt):
    # 设置 API 请求头
    headers = {
        'Content-Type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + openai_api_key
    }

    # 设置API请求数据,这里使用gpt-3.5的模型
    data = {
        'model': 'gpt-3.5-turbo',
        'messages': [{'role': 'user', 'content': prompt }]
    }

    # 发送 API 请求
    json_data = json.dumps(data)
    encoded_data = bytes(json_data, 'utf-8')
    response = requests.post(ENDPOINT, headers=headers, data=encoded_data)

    # 解析 API 响应
    response_json = json.loads(response.text)
    message = response_json['choices'][0]['message']['content'].strip()
    return message

‘get_chat_response’ 函数体用于获取 OpenAI Chatbot 的响应。此函数设置 API 请求标头和数据,将 POST 请求发送到 OpenAI Chat Completion API 端点。 API 响应采用 JSON 格式,此代码使用 Python 的“json”模块来处理 JSON 数据。

# 向Chatbot问好
prompt = "你是谁?"
print('User: ' + prompt)

# 获取聊天机器人响应
chat_response = get_chat_response(prompt)
print('Chatbot: ' + chat_response)

最后,为 Chatbot 设置问候语(Prompt)并使用“get_chat_response”函数从 Chatbot 获取响应。将响应打印到控制台。

在小显示屏上显示 ChatGPT 响应

图片[4] - 将 ChatGPT API 集成到树莓派( Raspberry Pi )Pico W,成功驱动液晶屏打印结果 - EVLIT
在掌握了 ChatGPT API 的基本用法之后,让我们在显示屏上显示ChatGPT的响应。

有许多可以与 Pico 一起使用的显示屏都在销售,但是这次作者选择使用0.96 英寸 128 x 64 点 OLED 白色点阵字体显示屏

按如下方式连接 Pico 和显示屏。
图片[5] - 将 ChatGPT API 集成到树莓派( Raspberry Pi )Pico W,成功驱动液晶屏打印结果 - EVLIT

安装显示器的驱动

Pico需要将内容显示到显示屏,可以安装SSD1306的驱动,点击以下站点了解这个驱动的安装方法,非常容易理解。
[Raspberry Pi Pico]如何在 OLED 显示器(I2C)上绘制字符[MicroPython]

启用使用日语字体

作者使用Raspberry Pi Pico MicroPython 的 Misaki 字体库。如下所示创建一个名为misakifont的文件夹,并在其中放置4个文件。
图片[6] - 将 ChatGPT API 集成到树莓派( Raspberry Pi )Pico W,成功驱动液晶屏打印结果 - EVLIT

检查日语字体显示

import machine
import ssd1306
from misakifont import MisakiFont
import time

"""
 Misaki字体的位图显示
"""
def show_bitmap(oled, fd, x, y, color, size):
    for row in range(0, 7):
        for col in range(0, 7):
            if (0x80 >> col) & fd[row]:
                oled.fill_rect(int(x + col * size), int(y + row * size), size, size, color)
    oled.show()

sda = machine.Pin(0)
scl = machine.Pin(1)
i2c = machine.I2C(0, sda=sda, scl=scl, freq=400000)

oled = ssd1306.SSD1306_I2C(128, 64, i2c)

oled.fill(0)

mf = MisakiFont()

str = "私はChatGPTと呼ばれる人工知能の一種です。"

color = 1
size = 2  # 2倍字体大小

x = 0
y = 0
for c in str:
    d = mf.font(ord(c))
    show_bitmap(oled, d, x, y, color, size)
    x += 8 * size
    if x >= 128:
        x = 0
        y += 8 * size
    if y >= 64:
        y = 0
    time.sleep(0.02)

运行上述代码后,文本将显示如下。
图片[7] - 将 ChatGPT API 集成到树莓派( Raspberry Pi )Pico W,成功驱动液晶屏打印结果 - EVLIT

结合前面的Python,让显示屏能打印出ChatGPT的回答

import urequests as requests
import network
import utime
import json
import machine
import ssd1306
from misakifont import MisakiFont
import time


"""
 Misaki字体的位图显示
"""
def show_bitmap(oled, fd, x, y, color, size):
    for row in range(0, 7):
        for col in range(0, 7):
            if (0x80 >> col) & fd[row]:
                oled.fill_rect(int(x + col * size), int(y + row * size), size, size, color)
    oled.show()

sda = machine.Pin(0)
scl = machine.Pin(1)
i2c = machine.I2C(0, sda=sda, scl=scl, freq=400000)

oled = ssd1306.SSD1306_I2C(128, 64, i2c)

oled.fill(0)

mf = MisakiFont()

#输入自己家里的Wi-Fi SSID和密码
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)

# Wait for connect or fail
max_wait = 10
while max_wait > 0:
    if wlan.status() < 0 or wlan.status() >= 3:
        break
    max_wait -= 1
    print('waiting for connection...')
    utime.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()
        utime.sleep(.2)
        led.off()
        utime.sleep(.2)

# Handle connection error
# Error meanings
# 0  Link Down
# 1  Link Join
# 2  Link NoIp
# 3  Link Up
# -1 Link Fail
# -2 Link NoNet
# -3 Link BadAuth

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])

# OpenAI API key
openai_api_key = "YOUR OpenAI API key"   输入前面保存下来的OpenAI API Key

# 设置 OpenAI Chat Completion API Endpoint
ENDPOINT = 'https://api.openai.com/v1/chat/completions'

# 构建Chatbot响应函数体
def get_chat_response(prompt):
    # 设置 API 请求头
    headers = {
        'Content-Type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + openai_api_key
    }

    # 设置API请求数据,这里使用gpt-3.5的模型
    data = {
        'model': 'gpt-3.5-turbo',
        'messages': [{'role': 'user', 'content': prompt }]
    }

    # 发送 API 请求
    json_data = json.dumps(data)
    encoded_data = bytes(json_data, 'utf-8')
    response = requests.post(ENDPOINT, headers=headers, data=encoded_data)

    # 解析 API 响应
    response_json = json.loads(response.text)
    #print(response_json)
    #response = response_json.json()
    message = response_json['choices'][0]['message']['content'].strip()
    #print(message)
    return message

# 向Chatbot问好
prompt = "こんにちは!元気?"
print('User: ' + prompt)

# 获取聊天机器人响应
chat_response = get_chat_response(prompt)
print('Chatbot: ' + chat_response)

oled.fill(0)


str = chat_response
x = 0
y = 0
color = 1
size = 2  # 2倍字体大小
for c in str:
    d = mf.font(ord(c))
    show_bitmap(oled, d, x, y, color, size)
    x += 8 * size
    if x >= 128:
        x = 0
        y += 8 * size
    if y >= 64:
        y = 0
    time.sleep(0.02)

运行上述代码后,您将看到 Chatbot 响应如下。
图片[8] - 将 ChatGPT API 集成到树莓派( Raspberry Pi )Pico W,成功驱动液晶屏打印结果 - EVLIT

应用场景

作者解释了如何使用 ChatGPT API 显示 AI 如何生成响应内容文本的过程,基于此还可以应用此方法来制作更有趣的东西。

比如:

一种在人体传感器响应时打招呼的设备

比如可以在亚马逊购买一个人体感应器,然后引入进来
图片[9] - 将 ChatGPT API 集成到树莓派( Raspberry Pi )Pico W,成功驱动液晶屏打印结果 - EVLIT

代码如下:

import urequests as requests
import network
import utime
import json
import machine
import ssd1306
from misakifont import MisakiFont
from machine import Pin
import time
import ntptime

# 构建Chatbot响应函数体
def get_chat_response(prompt):
    # 设置 API 请求头
    headers = {
        'Content-Type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + openai_api_key
    }
    
    # 设置API请求数据,这里使用gpt-3.5的模型
    data = {
        'model': 'gpt-3.5-turbo',
        'messages': [{'role': 'user', 'content': prompt }]
    }
    
    # 发送 API 请求
    json_data = json.dumps(data)
    encoded_data = bytes(json_data, 'utf-8')
    response = requests.post(ENDPOINT, headers=headers, data=encoded_data)
    
    # 解析 API 响应
    response_json = json.loads(response.text)
    message = response_json['choices'][0]['message']['content'].strip()
    return message

"""
 Misaki字体的位图显示
"""
def show_bitmap(oled, fd, x, y, color, size):
    for row in range(0, 7):
        for col in range(0, 7):
            if (0x80 >> col) & fd[row]:
                oled.fill_rect(int(x + col * size), int(y + row * size), size, size, color)
    oled.show()

sda = machine.Pin(0)
scl = machine.Pin(1)
i2c = machine.I2C(0, sda=sda, scl=scl, freq=400000)

oled = ssd1306.SSD1306_I2C(128, 64, i2c)
oled.fill(0)

mf = MisakiFont()

str = "私はChatGPTです。だれか来ないかな?"
x = 0
y = 0
color = 1
size = 2  # 2倍字体大小
for c in str:
    d = mf.font(ord(c))
    show_bitmap(oled, d, x, y, color, size)
    x += 8 * size
    if x >= 128:
        x = 0
        y += 8 * size
    if y >= 64:
        y = 0
    time.sleep(0.02)


#输入自己家里的Wi-Fi SSID和密码
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)

# Wait for connect or fail
max_wait = 10
while max_wait > 0:
    if wlan.status() < 0 or wlan.status() >= 3:
        break
    max_wait -= 1
    print('waiting for connection...')
    utime.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()
        utime.sleep(.2)
        led.off()
        utime.sleep(.2)
        
# Handle connection error
# Error meanings
# 0  Link Down
# 1  Link Join
# 2  Link NoIp
# 3  Link Up
# -1 Link Fail
# -2 Link NoNet
# -3 Link BadAuth        
    
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])
    
# 设置gpio口
pir = Pin(2, Pin.IN, Pin.PULL_DOWN)
led = machine.Pin("LED", machine.Pin.OUT)

led.value(0)
utime.sleep(1)       

# 开始循环
while True:
    print(pir.value())
    if pir.value() == 0:
        led.value(0)
        utime.sleep(1)
    else:
        led.value(1)

        oled.fill(0)
        str = "!"
        x = 50
        y = 15
        color = 1
        size = 4  # 字体大小再加倍
        for c in str:
            d = mf.font(ord(c))
            show_bitmap(oled, d, x, y, color, size)
            x += 8 * size
            if x >= 128:
                x = 0
                y += 8 * size
            if y >= 64:
                y = 0
            time.sleep(0.02)
        
        timZone = 9
        ntptime.host = "ntp.nict.jp"
        ntptime.settime()
        t0 = machine.RTC().datetime()
        hour = t0[4] + timZone
        # 如果超过 24 小时,就减去 24
        if hour >= 24:
            hour -= 24
        minute = t0[5]
        current_time = "{0:02d}:{1:02d}".format(hour, minute)
        print(current_time)

        # OpenAI API key
        openai_api_key = "YOUR OpenAI API key"  # 输入前面保存下来的OpenAI API Key

        # 设置 OpenAI Chat Completion API Endpoint
        ENDPOINT = 'https://api.openai.com/v1/chat/completions'

        prompt = "現在時刻は"+current_time+"だよ。\
時刻に合った声かけをして。時刻は書かないでね。\
返事は20文字から30文字で書いてね。\
漢字をできるだけ使わないでね。絶対に30文字は超えないでね。\
文字数は書かないでね。"
        
        print('User: ' + prompt)

        # 获取聊天机器人响应
        chat_response = get_chat_response(prompt)
        print('Chatbot: ' + chat_response)
        
        oled.fill(0)
        
        str = chat_response
        x = 0
        y = 0
        color = 1
        size = 2  # 2倍字体大小
        for c in str:
            d = mf.font(ord(c))
            show_bitmap(oled, d, x, y, color, size)
            x += 8 * size
            if x >= 128:
                x = 0
                y += 8 * size
            if y >= 64:
                y = 0
            time.sleep(0.02)
        break

使用提示:诀窍是尽可能详细地编写说明(prompt)。
图片[10] - 将 ChatGPT API 集成到树莓派( Raspberry Pi )Pico W,成功驱动液晶屏打印结果 - EVLIT

本文为翻译稿,原文链接:AIと電子工作の融合!Raspberry Pi Pico WでChatGPT APIを使用する方法

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发
头像
说说你的看法!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容