3
3

More than 1 year has passed since last update.

Raspberry Pi Pico Wを買ったのでスマホからQRコードを表示させてみた

Posted at

Qiitaさんの書き方なんも覚えてないけどとりあえずメモ
Raspberry Pi Pico Wを買ったので、スマホから入力した文字を電子ペーパーにQRコードを表示させてみた。

使ったのはこの電子ペーパー

参考にしたのは以下

無線LANに接続してブラウザでアクセスまで作ってくれてる神

uQRというライブラリを使ってQRコードをOLEディスプレイに表示してる人

電子ペーパー表示のサンプル

ファイルは
 main.py
 pWifi.py
 ePaperQr,py
 uQR.py
で動いてる

無線LANな部分をメインに改造

pWifi.py
import time
import network
import socket
import ePaperQr
import rp2

from machine import Pin
import machine

led = Pin("LED", machine.Pin.OUT)
ledState = 'LED State Unknown'

pIpStr = "255.255.255.255"

s = socket.socket()


def pConnect():

    led.value(1)
    time.sleep(1)
    led.value(0)
    time.sleep(1)
    led.value(1)
    time.sleep(1)
    led.value(0)
    time.sleep(1)
    
    #自宅Wi-FiのSSIDとパスワードを入力
    if rp2.bootsel_button() == 1:
        print("ie")
        ssid = '自宅SSID'
        password = '自宅パスワード'
    else:
        print("sumaho")
        ssid = 'スマホSSID'
        password = 'スマホパスワード'
    led.value(1)
    time.sleep(1)

    pIpStr="err"
    
    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...')
        time.sleep(1)
        
    # Handle connection error
    print("koko1")
    led.value(0)
    if wlan.status() != 3:
        raise RuntimeError('network connection failed')
    else:
        print('Connected')
        status = wlan.ifconfig()
        pIpStr=str(status[0])
        print( 'get_ip = ' + pIpStr )
        #if (pIpStr=="123"):
        ePaperQr.draw_init()
        print(f"test = http://{pIpStr}")
        ePaperQr.draw_qr(f"http://{pIpStr}", 20, 19)
        ePaperQr.draw_text(f"{pIpStr}", 0, 0)
        ePaperQr.draw_finish()

    try:
        # Open socket
        addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
        #s = socket.socket()
        s.bind(addr)
        s.listen(1)
        led.value(1)
        print('listening on', addr)
        print(f"s={str(s)}")
    except:
        print("er-----------")

    print(f"s={str(s)}")
    return pIpStr
    
def pStart():
    
    html = """<!DOCTYPE html><html>
    <head><meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" href="data:,">
    <style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}
    .buttonGreen { background-color: #4CAF50; border: 2px solid #000000;; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; }
    .buttonRed { background-color: #D11D53; border: 2px solid #000000;; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; }
    text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
    </style></head>
    <body><center><h1>Raspberry Pi Pico W</h1></center><br><br>
    <form><center>
    <input type="text" name="ppIpStr"><br>
    <input type="submit" value="set">
    </center></form>
    <br><br>
    <br><br>
    <p>%s<p></body></html>
    """

    # Listen for connections, serve client
    while True:
    #try:
        print(str(s))
        cl, addr = s.accept()
        print('client connected from', addr)
        request = cl.recv(1024)
        print("request:")
        print(request)
        request = str(request)
        
        TempStr = request[request.find('ppIpStr='):request.find('ppIpStr=')+100]
        WifiQrStr = TempStr[8:TempStr.find(' ')]
        WifiQrStr = WifiQrStr.replace("%3A",":").replace("%2F","/")
         
        
        # Create and send response
        #stateis = ledState
        stateis = "<br>QR: " + WifiQrStr
        response = html % stateis
        cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        cl.send(response)
        cl.close()
        
        print("WifiQrStr:" + str(WifiQrStr))
        if (str(WifiQrStr)==""):
            print("WifiQrStr:" + "space")
        else:
            ePaperQr.draw_init()
            ePaperQr.draw_qr(f"{WifiQrStr}", 20, 49)
            ePaperQr.draw_text(f"QR:{WifiQrStr}", 0, 0)
            ePaperQr.draw_finish()

if __name__=='__main__':
    print('test')

電子ペーパーのサンプルをQRコード表示するよう改造

ePaperQr.py
from machine import Pin, SPI
from time import sleep
import time
import framebuf
import utime
import math
from uQR import QRCode

qr = QRCode()

# Display resolution
EPD_WIDTH       = 152
EPD_HEIGHT      = 296

RST_PIN         = 12
DC_PIN          = 8
CS_PIN          = 9
BUSY_PIN        = 13


WF_PARTIAL_2IN66 =[
0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x0A,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x22,0x22,0x22,0x22,0x22,0x22,
0x00,0x00,0x00,0x22,0x17,0x41,0xB0,0x32,0x36,
]

bit2 =[
    0,0,0,0,0,0,0,0
    ]

class EPD_2in9_B:
    def __init__(self):
        self.reset_pin = Pin(RST_PIN, Pin.OUT)
        
        self.busy_pin = Pin(BUSY_PIN, Pin.IN, Pin.PULL_UP)
        self.cs_pin = Pin(CS_PIN, Pin.OUT)
        self.width = EPD_WIDTH
        self.height = EPD_HEIGHT
        self.lut = WF_PARTIAL_2IN66
        
        self.spi = SPI(1)
        self.spi.init(baudrate=4000_000)
        self.dc_pin = Pin(DC_PIN, Pin.OUT)
        
        self.buffer_balck = bytearray(self.height * self.width // 8)
        self.buffer_red = bytearray(self.height * self.width // 8)
        self.imageblack = framebuf.FrameBuffer(self.buffer_balck, self.width, self.height, framebuf.MONO_HLSB)
        self.imagered = framebuf.FrameBuffer(self.buffer_red, self.width, self.height, framebuf.MONO_HLSB)
        self.init()

    def digital_write(self, pin, value):
        pin.value(value)

    def digital_read(self, pin):
        return pin.value()

    def delay_ms(self, delaytime):
        utime.sleep(delaytime / 1000.0)

    def spi_writebyte(self, data):
        self.spi.write(bytearray(data))

    def module_exit(self):
        self.digital_write(self.reset_pin, 0)

    # Hardware reset
    def reset(self):
        self.digital_write(self.reset_pin, 1)
        self.delay_ms(50)
        self.digital_write(self.reset_pin, 0)
        self.delay_ms(2)
        self.digital_write(self.reset_pin, 1)
        self.delay_ms(50)


    def send_command(self, command):
        self.digital_write(self.dc_pin, 0)
        self.digital_write(self.cs_pin, 0)
        self.spi_writebyte([command])
        self.digital_write(self.cs_pin, 1)

    def send_data(self, data):
        self.digital_write(self.dc_pin, 1)
        self.digital_write(self.cs_pin, 0)
        self.spi_writebyte([data])
        self.digital_write(self.cs_pin, 1)
        
    def SetWindow(self, x_start, y_start, x_end, y_end):
        self.send_command(0x44)
        self.send_data((x_start>>3) & 0x1f)
        self.send_data((x_end>>3) & 0x1f)
        
        self.send_command(0x45)
        self.send_data(y_start&0xff)
        self.send_data((y_start&0x100)>>8)
        self.send_data((y_end&0xff))
        self.send_data((y_end&0x100)>>8)
        
    def SetCursor(self, x_start, y_start):
        self.send_command(0x4E)
        self.send_data(x_start & 0x1f)
        
        self.send_command(0x4f)
        self.send_data(y_start&0xff)
        self.send_data((y_start&0x100)>>8)
        
    def ReadBusy(self):
        #print('e-Paper busy')
        utime.sleep_ms(50)   
        while(self.busy_pin.value() == 1):      # 0: idle, 1: busy
            utime.sleep_ms(10)    
        #print('e-Paper busy release')
        utime.sleep_ms(50)  
        
    def TurnOnDisplay(self):
        self.send_command(0x20)
        self.ReadBusy()
        
    def init(self):
        print('init')
        self.reset()
        self.ReadBusy()
        self.send_command(0x12)  
        self.ReadBusy()#waiting for the electronic paper IC to release the idle signal

        self.send_command(0x11)
        self.send_data(0x03)

        self.SetWindow(0, 0, self.width-1, self.height-1)
        
        self.send_command(0x21)    #resolution setting
        self.send_data (0x00)  
        self.send_data (0x80)  
        
        
        self.SetCursor(0,0)
        self.ReadBusy()
    
        
    def display(self):
        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1
        self.send_command(0x24)
        for j in range(0, high):
            for i in range(0, wide):
                self.send_data(self.buffer_balck[i + j * wide])   
        self.send_command(0x26)
        for j in range(0, high):
            for i in range(0, wide):
                self.send_data(~self.buffer_red[i + j * wide])   

        self.TurnOnDisplay()

    
    def Clear(self, colorblack, colorred):
        high = self.height
        if( self.width % 8 == 0) :
            wide =  self.width // 8
        else :
            wide =  self.width // 8 + 1
        self.send_command(0x24)
        for j in range(0, high):
            for i in range(0, wide):
                self.send_data(colorblack)
        self.send_command(0x26)
        for j in range(0, high):
            for i in range(0, wide):
                self.send_data(~colorred)
                                
        self.TurnOnDisplay()

    def sleep(self):
        self.send_command(0X10) # deep sleep
        self.send_data(0x01)

def dec2bit(ddd):
    for VV in range(8, 0, -1):
        bit2[VV-1] = ddd % 2
        ddd = math.floor(ddd / 2)
    return bit2


def draw_init():
    epd.init()

    epd.imageblack.fill(0xff)
    epd.imagered.fill(0xff)

    print("datafile input")
    epd.imageblack.text(str(EPD_WIDTH) + "x" + str(EPD_HEIGHT), 0, EPD_HEIGHT-11, 0x00)
    
    
def draw_finish():
    
    print("display")
    epd.display()
    epd.delay_ms(2000)

    print("sleep")
    epd.sleep()
    print("end")
   
def draw_qr(qr_data, offset_x, offset_y):
    print("drow_qr " + str(qr_data))
    scale = 1
    qr.clear()
    qr.add_data(qr_data)
    matrix = qr.get_matrix()
    print("QR version:", qr.version)
    print("Matrix length", len(matrix))

    print("X:", len(matrix)*scale)
    print("X:", len(matrix[0])*scale)
    
    for y in range(len(matrix)*scale):
        for x in range(len(matrix[0])*scale):
            value = not matrix[int(y/scale)][int(x/scale)]
            if (value):
                epd.imageblack.fill_rect(x + offset_x, y + offset_y, 1, 1, 0xFF)
            else:
                epd.imageblack.fill_rect(x + offset_x, y + offset_y, 1, 1, 0x00)

def draw_text(qr_data, offset_x, offset_y):
    print("drow_text " + str(qr_data))
    epd.imageblack.text(str(qr_data), offset_x, offset_y, 0x00)
    

epd = EPD_2in9_B()

if __name__=='__main__':
    print("OS START")

uQR.pyは長いので省略。
数字だけ30文字ぐらい入れたらエラーになったのでその対策したんだけど、そのままでも動くよ。

電源入れると動くやつ

main.py
import pWifi

IpStr = "255.255.255.255"

try:
    IpStr = pWifi.pConnect()
    IpStr = pWifi.pStart()
except:
    print("er-----------")

使い方は以下
1.pWifi.pyのSSIDとパスワードを使っている無線LANのものに変更する
  (自宅の無線LANだけじゃなくテザリングしてるスマホでも動いたよ)
2.PiPicoWの電源入れたら勝手に無線LAN(スマホ用)に繋ぎに行くので成功したらQRコードが以下に更新される
  http://PiPicoのIPアドレス
  (電源いれて最初にLEDが光ってから4秒後にBOOTSELボタン押してると違う無線LAN(家用)に繋ぎにいく)
3.表示されたQRコードからPiPicoWにブラウザでアクセス(http://PiPicoのIPアドレス)
4.テキストボックスにテキストを入力してsetボタンを押すと電子ペーパーのQRコードが変化する
5.電源抜く
6.電子ペーパーなのでQR表示させたまま持ち運び可能

自分用メモなのでここまで

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3