Pwnagotchi_waveshare_V3适配(海南大学)(上)

简介: Pwnagotchi_waveshare_V3适配(海南大学)(上)

所需物料


  1. 树莓派(RPI-zero-w),记得得是w型号,不然无法扫描周围Wi-Fi
  2. waveshare_V3
  3. 移动电池(可选,用充电宝也行)
  4. 老式USB数据线
  5. 内存不少于16G的SD卡


image.jpeg


软件准备


微信图片_20220429232731.jpg



image.png



操作步骤


  1. 烧录镜像到SD卡中,注意烧录好不要插入树莓派中,只拔出即可
  2. 在电脑编辑器打开下载好的源代码,并按照以下修改添加


# pwnagotchi/ui/display.py
import os
import logging
import threading
import pwnagotchi.plugins as plugins
import pwnagotchi.ui.hw as hw
from pwnagotchi.ui.view import View
class Display(View):
    def __init__(self, config, state={}):
        super(Display, self).__init__(config, hw.display_for(config), state)
        config = config['ui']['display']
        self._enabled = config['enabled']
        self._rotation = config['rotation']
        self.init_display()
        self._canvas_next_event = threading.Event()
        self._canvas_next = None
        self._render_thread_instance = threading.Thread(
            target=self._render_thread,
            daemon=True
        )
        self._render_thread_instance.start()
    def is_inky(self):
        return self._implementation.name == 'inky'
    def is_papirus(self):
        return self._implementation.name == 'papirus'
    def is_waveshare_v1(self):
        return self._implementation.name == 'waveshare_1'
    def is_waveshare_v2(self):
        return self._implementation.name == 'waveshare_2'
    def is_waveshare_v3(self):
        return self._implementation.name == 'waveshare_3'
    def is_waveshare27inch(self):
        return self._implementation.name == 'waveshare27inch'
    def is_waveshare29inch(self):
        return self._implementation.name == 'waveshare29inch'
    def is_oledhat(self):
        return self._implementation.name == 'oledhat'
    def is_lcdhat(self):
        return self._implementation.name == 'lcdhat'
    def is_dfrobot_v1(self):
        return self._implementation.name == 'dfrobot_v1'
    def is_dfrobot_v2(self):
        return self._implementation.name == 'dfrobot_v2'
    def is_waveshare144lcd(self):
        return self._implementation.name == 'waveshare144lcd'
    def is_waveshare154inch(self):
        return self._implementation.name == 'waveshare154inch'
    def is_waveshare213d(self):
        return self._implementation.name == 'waveshare213d'
    def is_waveshare213bc(self):
        return self._implementation.name == 'waveshare213bc'
    def is_spotpear24inch(self):
        return self._implementation.name == 'spotpear24inch'
    def is_waveshare_any(self):
        return self.is_waveshare_v1() or self.is_waveshare_v2()
    def init_display(self):
        if self._enabled:
            self._implementation.initialize()
            plugins.on('display_setup', self._implementation)
        else:
            logging.warning("display module is disabled")
        self.on_render(self._on_view_rendered)
    def clear(self):
        self._implementation.clear()
    def image(self):
        img = None
        if self._canvas is not None:
            img = self._canvas if self._rotation == 0 else self._canvas.rotate(-self._rotation)
        return img
    def _render_thread(self):
        """Used for non-blocking screen updating."""
        while True:
            self._canvas_next_event.wait()
            self._canvas_next_event.clear()
            self._implementation.render(self._canvas_next)
    def _on_view_rendered(self, img):
        try:
            if self._config['ui']['web']['on_frame'] != '':
                os.system(self._config['ui']['web']['on_frame'])
        except Exception as e:
            logging.error("%s" % e)
        if self._enabled:
            self._canvas = (img if self._rotation == 0 else img.rotate(self._rotation))
            if self._implementation is not None:
                self._canvas_next = self._canvas
                self._canvas_next_event.set()


# pwnagotchi/ui/hw/__init__.py
from pwnagotchi.ui.hw.inky import Inky
from pwnagotchi.ui.hw.papirus import Papirus
from pwnagotchi.ui.hw.oledhat import OledHat
from pwnagotchi.ui.hw.lcdhat import LcdHat
from pwnagotchi.ui.hw.dfrobot1 import DFRobotV1
from pwnagotchi.ui.hw.dfrobot2 import DFRobotV2
from pwnagotchi.ui.hw.waveshare1 import WaveshareV1
from pwnagotchi.ui.hw.waveshare2 import WaveshareV2
from pwnagotchi.ui.hw.waveshare3 import WaveshareV3
from pwnagotchi.ui.hw.waveshare27inch import Waveshare27inch
from pwnagotchi.ui.hw.waveshare29inch import Waveshare29inch
from pwnagotchi.ui.hw.waveshare144lcd import Waveshare144lcd
from pwnagotchi.ui.hw.waveshare154inch import Waveshare154inch
from pwnagotchi.ui.hw.waveshare213d import Waveshare213d
from pwnagotchi.ui.hw.waveshare213bc import Waveshare213bc
from pwnagotchi.ui.hw.spotpear24inch import Spotpear24inch
def display_for(config):
    # config has been normalized already in utils.load_config
    if config['ui']['display']['type'] == 'inky':
        return Inky(config)
    elif config['ui']['display']['type'] == 'papirus':
        return Papirus(config)
    if config['ui']['display']['type'] == 'oledhat':
        return OledHat(config)
    if config['ui']['display']['type'] == 'lcdhat':
        return LcdHat(config)
    if config['ui']['display']['type'] == 'dfrobot_1':
        return DFRobotV1(config)
    if config['ui']['display']['type'] == 'dfrobot_2':
        return DFRobotV2(config)
    elif config['ui']['display']['type'] == 'waveshare_1':
        return WaveshareV1(config)
    elif config['ui']['display']['type'] == 'waveshare_2':
        return WaveshareV2(config)
    elif config['ui']['display']['type'] == 'waveshare_3':
        return WaveshareV3(config)
    elif config['ui']['display']['type'] == 'waveshare27inch':
        return Waveshare27inch(config)
    elif config['ui']['display']['type'] == 'waveshare29inch':
        return Waveshare29inch(config)
    elif config['ui']['display']['type'] == 'waveshare144lcd':
        return Waveshare144lcd(config)
    elif config['ui']['display']['type'] == 'waveshare154inch':
        return Waveshare154inch(config)
    elif config['ui']['display']['type'] == 'waveshare213d':
        return Waveshare213d(config)
    elif config['ui']['display']['type'] == 'waveshare213bc':
        return Waveshare213bc(config)
    elif config['ui']['display']['type'] == 'spotpear24inch':
        return Spotpear24inch(config)


# pwnagotchi/ui/hw/libs/waveshare/v3/epd2in13_V3.py
import logging
from . import epdconfig
import numpy as np
# Display resolution
EPD_WIDTH       = 122
EPD_HEIGHT      = 250
logger = logging.getLogger(__name__)
class EPD:
    def __init__(self):
        self.reset_pin = epdconfig.RST_PIN
        self.dc_pin = epdconfig.DC_PIN
        self.busy_pin = epdconfig.BUSY_PIN
        self.cs_pin = epdconfig.CS_PIN
        self.width = EPD_WIDTH
        self.height = EPD_HEIGHT
    lut_partial_update= [
        0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x14,0x0,0x0,0x0,0x0,0x0,0x0,  
        0x1,0x0,0x0,0x0,0x0,0x0,0x0,
        0x1,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0,
        0x22,0x17,0x41,0x00,0x32,0x36,
    ]
    lut_full_update = [ 
        0x80,0x4A,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x40,0x4A,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x80,0x4A,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x40,0x4A,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0xF,0x0,0x0,0x0,0x0,0x0,0x0,
        0xF,0x0,0x0,0xF,0x0,0x0,0x2,
        0xF,0x0,0x0,0x0,0x0,0x0,0x0,
        0x1,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0,
        0x22,0x17,0x41,0x0,0x32,0x36,
    ]
    '''
    function :Hardware reset
    parameter:
    '''
    def reset(self):
        epdconfig.digital_write(self.reset_pin, 1)
        epdconfig.delay_ms(20) 
        epdconfig.digital_write(self.reset_pin, 0)
        epdconfig.delay_ms(2)
        epdconfig.digital_write(self.reset_pin, 1)
        epdconfig.delay_ms(20)   
    '''
    function :send command
    parameter:
     command : Command register
    '''
    def send_command(self, command):
        epdconfig.digital_write(self.dc_pin, 0)
        epdconfig.digital_write(self.cs_pin, 0)
        epdconfig.spi_writebyte([command])
        epdconfig.digital_write(self.cs_pin, 1)
    '''
    function :send data
    parameter:
     data : Write data
    '''
    def send_data(self, data):
        epdconfig.digital_write(self.dc_pin, 1)
        epdconfig.digital_write(self.cs_pin, 0)
        epdconfig.spi_writebyte([data])
        epdconfig.digital_write(self.cs_pin, 1)
    '''
    function :Wait until the busy_pin goes LOW
    parameter:
    '''
    def ReadBusy(self):
        logger.debug("e-Paper busy")
        while(epdconfig.digital_read(self.busy_pin) == 1):      # 0: idle, 1: busy
            epdconfig.delay_ms(10)  
        logger.debug("e-Paper busy release")
    '''
    function : Turn On Display
    parameter:
    '''
    def TurnOnDisplay(self):
        self.send_command(0x22) # Display Update Control
        self.send_data(0xC7)
        self.send_command(0x20) # Activate Display Update Sequence
        self.ReadBusy()
    '''
    function : Turn On Display Part
    parameter:
    '''
    def TurnOnDisplayPart(self):
        self.send_command(0x22) # Display Update Control
        self.send_data(0x0f)    # fast:0x0c, quality:0x0f, 0xcf
        self.send_command(0x20) # Activate Display Update Sequence
        self.ReadBusy()
    '''
    function : Set lut
    parameter:
        lut : lut data
    '''    
    def Lut(self, lut):
        self.send_command(0x32)
        for i in range(0, 153):
            self.send_data(lut[i])
        self.ReadBusy()
    '''
    function : Send lut data and configuration
    parameter:
        lut : lut data 
    '''
    def SetLut(self, lut):
        self.Lut(lut)
        self.send_command(0x3f)
        self.send_data(lut[153])
        self.send_command(0x03)     # gate voltage
        self.send_data(lut[154])
        self.send_command(0x04)     # source voltage
        self.send_data(lut[155])    # VSH
        self.send_data(lut[156])    # VSH2
        self.send_data(lut[157])    # VSL
        self.send_command(0x2c)     # VCOM
        self.send_data(lut[158])
    '''
    function : Setting the display window
    parameter:
        xstart : X-axis starting position
        ystart : Y-axis starting position
        xend : End position of X-axis
        yend : End position of Y-axis
    '''
    def SetWindow(self, x_start, y_start, x_end, y_end):
        self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION
        # x point must be the multiple of 8 or the last 3 bits will be ignored
        self.send_data((x_start>>3) & 0xFF)
        self.send_data((x_end>>3) & 0xFF)
        self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION
        self.send_data(y_start & 0xFF)
        self.send_data((y_start >> 8) & 0xFF)
        self.send_data(y_end & 0xFF)
        self.send_data((y_end >> 8) & 0xFF)
    '''
    function : Set Cursor
    parameter:
        x : X-axis starting position
        y : Y-axis starting position
    '''
    def SetCursor(self, x, y):
        self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER
        # x point must be the multiple of 8 or the last 3 bits will be ignored
        self.send_data(x & 0xFF)
        self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER
        self.send_data(y & 0xFF)
        self.send_data((y >> 8) & 0xFF)
    '''
    function : Initialize the e-Paper register
    parameter:
    '''
    def init(self):
        if (epdconfig.module_init() != 0):
            return -1
        # EPD hardware init start
        self.reset()
        self.ReadBusy()
        self.send_command(0x12)  #SWRESET
        self.ReadBusy() 
        self.send_command(0x01) #Driver output control      
        self.send_data(0xf9)
        self.send_data(0x00)
        self.send_data(0x00)
        self.send_command(0x11) #data entry mode       
        self.send_data(0x03)
        self.SetWindow(0, 0, self.width-1, self.height-1)
        self.SetCursor(0, 0)
        self.send_command(0x3c)
        self.send_data(0x05)
        self.send_command(0x21) #  Display update control
        self.send_data(0x00)
        self.send_data(0x80)
        self.send_command(0x18)
        self.send_data(0x80)
        self.ReadBusy()
        self.SetLut(self.lut_full_update)
        return 0
    '''
    function : Display images
    parameter:
        image : Image data
    '''
    def getbuffer(self, image):
        img = image
        imwidth, imheight = img.size
        if(imwidth == self.width and imheight == self.height):
            img = img.convert('1')
        elif(imwidth == self.height and imheight == self.width):
            # image has correct dimensions, but needs to be rotated
            img = img.rotate(90, expand=True).convert('1')
        else:
            logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height))
            # return a blank buffer
            return [0x00] * (int(self.width/8) * self.height)
        buf = bytearray(img.tobytes('raw'))
        return buf
    '''
    function : Sends the image buffer in RAM to e-Paper and displays
    parameter:
        image : Image data
    '''
    def display(self, image):
        if self.width%8 == 0:
            linewidth = int(self.width/8)
        else:
            linewidth = int(self.width/8) + 1
        self.send_command(0x24)
        for j in range(0, self.height):
            for i in range(0, linewidth):
                self.send_data(image[i + j * linewidth])   
        self.TurnOnDisplay()
    '''
    function : Sends the image buffer in RAM to e-Paper and partial refresh
    parameter:
        image : Image data
    '''
    def displayPartial(self, image):
        if self.width%8 == 0:
            linewidth = int(self.width/8)
        else:
            linewidth = int(self.width/8) + 1
        epdconfig.digital_write(self.reset_pin, 0)
        epdconfig.delay_ms(1)
        epdconfig.digital_write(self.reset_pin, 1)  
        self.SetLut(self.lut_partial_update)
        self.send_command(0x37)
        self.send_data(0x00)
        self.send_data(0x00)
        self.send_data(0x00)
        self.send_data(0x00)
        self.send_data(0x00)
        self.send_data(0x40)
        self.send_data(0x00)
        self.send_data(0x00)
        self.send_data(0x00)  
        self.send_data(0x00)
        self.send_command(0x3C) #BorderWavefrom
        self.send_data(0x80)
        self.send_command(0x22) 
        self.send_data(0xC0)
        self.send_command(0x20)
        self.ReadBusy()
        self.SetWindow(0, 0, self.width - 1, self.height - 1)
        self.SetCursor(0, 0)
        self.send_command(0x24) # WRITE_RAM
        for j in range(0, self.height):
            for i in range(0, linewidth):
                self.send_data(image[i + j * linewidth])   
        self.TurnOnDisplayPart()
    '''
    function : Refresh a base image
    parameter:
        image : Image data
    '''
    def displayPartBaseImage(self, image):
        if self.width%8 == 0:
            linewidth = int(self.width/8)
        else:
            linewidth = int(self.width/8) + 1
        self.send_command(0x24)
        for j in range(0, self.height):
            for i in range(0, linewidth):
                self.send_data(image[i + j * linewidth])   
        self.send_command(0x26)
        for j in range(0, self.height):
            for i in range(0, linewidth):
                self.send_data(image[i + j * linewidth])  
        self.TurnOnDisplay()
    '''
    function : Clear screen
    parameter:
    '''
    def Clear(self, color):
        if self.width%8 == 0:
            linewidth = int(self.width/8)
        else:
            linewidth = int(self.width/8) + 1
        # logger.debug(linewidth)
        self.send_command(0x24)
        for j in range(0, self.height):
            for i in range(0, linewidth):
                self.send_data(color)
        self.TurnOnDisplay()
    '''
    function : Enter sleep mode
    parameter:
    '''
    def sleep(self):
        self.send_command(0x10) #enter deep sleep
        self.send_data(0x01)
        epdconfig.delay_ms(2000)
        epdconfig.module_exit()
### END OF FILE ###



相关文章
|
4月前
|
小程序 存储 UED
如何实现一次搭建 多平台适配的小程序
【6月更文挑战第3天】如何实现一次搭建 多平台适配的小程序
|
4月前
|
容器
代码适配性问题怎么解决,如何快速创建左右布局
代码适配性问题怎么解决,如何快速创建左右布局
|
5月前
|
iOS开发
iPad适配
iPad适配
51 0
|
5月前
|
JSON iOS开发 数据格式
iPhont X适配
iPhont X适配
33 0
|
5月前
|
编解码 前端开发
什么是适配?
什么是适配?
|
12月前
|
设计模式 Java
JAVA设计模式7:适配者模式,彻底解决两不兼容接口之间的问题
JAVA设计模式7:适配者模式,彻底解决两不兼容接口之间的问题
138 0
|
SQL 消息中间件 缓存
12种接口优化的通用方案
12种接口优化的通用方案
221 0
|
前端开发 开发者 容器
总结适配方案|学习笔记
快速学习 总结适配方案
|
存储 测试技术 数据安全/隐私保护
RobotFrameWork接口项目分层及通用控制方式
RobotFrameWork接口项目分层及通用控制方式
1000 0
RobotFrameWork接口项目分层及通用控制方式
|
网络安全 开发工具 数据安全/隐私保护
Pwnagotchi_waveshare_V5适配(海南大学)(下)
Pwnagotchi_waveshare_V5适配(海南大学)(下)
341 0
Pwnagotchi_waveshare_V5适配(海南大学)(下)