shownb / shownb.github.com

shownb.github.io
shownb.github.io
5 stars 1 forks source link

esp32 micropython #48

Open shownb opened 4 years ago

shownb commented 4 years ago

显示系统已经内置那些模块 help('modules')

sh1107的驱动

from machine import SPI, Pin
import ssd1306
rst = Pin(33) 
dc = Pin(27)
cs = Pin(14)
sck = Pin(18)
miso = Pin(19)
mosi = Pin(23)
oled = ssd1306.SSD1306_SPI(128, 64, SPI(1,sck=sck,mosi=mosi,miso=miso), dc, rst, cs,False)
oled.fill(0)
oled.text("Hello World", 0, 0)
oled.show()
import framebuf

'''
from machine import Pin, SPI
vspi = SPI(2, baudrate=1000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=Pin(18), mosi=Pin(23))
import sh1107
oled = sh1107.SH1107(64, 128, vspi, Pin(27), Pin(33), Pin(14))
oled.text('hello', 0, 0, 1)
oled.show()
'''

class SH1107(framebuf.FrameBuffer):
    def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
        self.rate = 2000000
        dc.init(dc.OUT, value=0)
        res.init(res.OUT, value=0)
        cs.init(cs.OUT, value=1)
        self.spi = spi
        self.dc = dc
        self.res = res
        self.cs = cs
        import time
        self.res(1)
        time.sleep_ms(100)
        self.res(0)
        time.sleep_ms(100)
        self.res(1)
        self.width = width
        self.height = height
        self.external_vcc = external_vcc
        self.pages = self.height // 8
        self.buffer = bytearray(self.pages * self.width)
        super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
        self.init_display()

    def init_display(self):
        print('init display')
        self.write_cmd([
            0xae,
            0xdc, 0x00,
            0x81, 0x2f,
            0x20,
            0xa0,
            0xc0,
            0xa8, 0x7f,
            0xd3, 0x60,
            0xd5, 0x51,
            0xd9, 0x22,
            0xdb, 0x35,
            0xb0,
            0xda, 0x12,
            0xa4,
            0xa6,
        ])
        self.fill(0)
        self.show()
        self.poweron()

    def show(self):
        self.spi.init(baudrate=self.rate, polarity=0, phase=0)
        self.cs(1)
        self.cs(0)
        for page in range(self.pages):
            buffer_i = page*64
            self.dc(0)
            self.spi.write(bytearray([0x10, 0x00, 0xb0 | page]))
            self.dc(1)
            self.spi.write(self.buffer[buffer_i:buffer_i+64])
        self.cs(1)

    def poweroff(self):
        self.write_cmd([0xae])

    def poweron(self):
        self.write_cmd([0xaf])

    def contrast(self, contrast):
        self.write_cmd([0x81, contrast])

    def invert(self, invert):
        self.write_cmd([0xa6 | (invert & 1)])

    def write_cmd(self, cmd):
        self.spi.init(baudrate=self.rate, polarity=0, phase=0)
        self.cs(1)
        self.dc(0)
        self.cs(0)
        self.spi.write(bytearray(cmd))
        self.cs(1)
res = curl.get("http://192.168.178.50:8000/test.py")
f = open('test.py','w')
f.write(res[2])
f.close()
execfile('test.py')
import webrepl_setup
import network
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect('abc','cdf_')

st7789 240*240

import machine
spi = machine.SPI(baudrate=40000000, polarity=1, phase=0, sck=machine.Pin(21), mosi=machine.Pin(19), miso=machine.Pin(22))
display = st7789py.ST7789(spi, 240, 240,reset=machine.Pin(2, machine.Pin.OUT),cs=machine.Pin(12, machine.Pin.OUT),dc=machine.Pin(15, machine.Pin.O
UT))
display.init()                                                                                                                                    
display.pixel(120, 120, st7789py.YELLOW)

下载模块

import upip
upip.install('micropython-uasyncio')

mqtt服务器 mosquitto

中断程序,满足条件的时候调用。 什么是中断?

在程序运行过程中,系统出现了一个必须由CPU立即处理的情况,此时,CPU暂时中止程序的执行转而处理这个新的情况的过程就叫做中断。 在出现需要时,CPU必须暂停现在的事情,处理别的事情,处理完了再回去执行暂停的事情。

from mpython import *
def abc(_):
rgb.fill((128,0,0))
rgb.write()
button_a.irq(trigger=Pin.IRQ_FALLING, handler=abc)#设置按键 A 中断,下降沿触发

定时器

class GSENSOR(object):
    def __init__(self,mqttc,pin):
        self.c = mqttc
        self.pin = pin
        self.x1 = accelerometer.get_x()
        self.y1 = accelerometer.get_y()
        self.z1 = accelerometer.get_z()
        ##print(self.x1,self.y1,self.z1)
        self.tim = Timer(4)
        #timer.init(period=2000, mode=Timer.PERIODIC, callback=self.cb_timer)
        self.tim.init(mode=Timer.PERIODIC, period=20,callback=self.gsensor_cb)
    def gsensor_cb(self, tim):
        self.x1 = accelerometer.get_x()
        self.y1 = accelerometer.get_y()
        self.z1 = accelerometer.get_z()
        self.c.publish("/zkb/device/sensors/gsensor/"+self.pin,json.dumps((self.x1,self.y1,self.z1)))
    def stop(self):
        self.tim.deinit()

ov2640的驱动 https://github.com/cj667113/micropython-ov2640

2.13电子纸关注 https://forum.micropython.org/viewtopic.php?f=15&t=7683 https://github.com/mcauser/micropython-waveshare-epaper/issues/5 https://github.com/micropython/micropython/pull/5626 解决反转问题。 https://forum.micropython.org/viewtopic.php?f=18&t=7547&p=46928#p46928

shownb commented 4 years ago

我用的是这个驱动 https://github.com/espressif/esp32-camera 然后,micropython调用c部分是这样写的。 https://gist.github.com/shownb/50610a081dc89657d2ebc47c8ae1fdd7 你看看有什么不对的么?

除了引脚io13没拉高外。 后来我又在micropython里面先把引脚拉高。 再camera.init() 还是出错。

Pin(13,mode=Pin.IN,pull=Pin.PULL_UP) Pin(13) import camera camera.init() I (209870) sccb: pin_sda 18 pin_scl 23

E (209870) sccb: SCCB_Write Failed addr:0x30, reg:0xff, data:0x01, ret:263 E (209870) sccb: SCCB_Write Failed addr:0x30, reg:0x12, data:0x80, ret:263 E (209930) camera: Detected camera not supported. E (209930) camera: Camera probe failed with error 0x20004 E (209930) camera: Camera Init Failed

shownb commented 4 years ago

文件名 epaper2in13.py

from micropython import const
from machine import SPI, Pin
from time import sleep_ms
import ustruct

# Display resolution
EPD_WIDTH  = const(128)
EPD_HEIGHT = const(250)
# datasheet says 250x122 (increased to 128 to be multiples of 8)

# Display commands
DRIVER_OUTPUT_CONTROL                = const(0x01)
# Gate Driving Voltage Control       0x03
# Source Driving voltage Control     0x04
BOOSTER_SOFT_START_CONTROL           = const(0x0C) # not in datasheet
#GATE_SCAN_START_POSITION             = const(0x0F) # not in datasheet
DEEP_SLEEP_MODE                      = const(0x10)
DATA_ENTRY_MODE_SETTING              = const(0x11)
#SW_RESET                             = const(0x12)
#TEMPERATURE_SENSOR_CONTROL           = const(0x1A)
MASTER_ACTIVATION                    = const(0x20)
#DISPLAY_UPDATE_CONTROL_1             = const(0x21)
DISPLAY_UPDATE_CONTROL_2             = const(0x22)
# Panel Break Detection              0x23
WRITE_RAM                            = const(0x24)
WRITE_VCOM_REGISTER                  = const(0x2C)
# Status Bit Read                    0x2F
WRITE_LUT_REGISTER                   = const(0x32)
SET_DUMMY_LINE_PERIOD                = const(0x3A)
SET_GATE_TIME                        = const(0x3B)
#BORDER_WAVEFORM_CONTROL              = const(0x3C)
SET_RAM_X_ADDRESS_START_END_POSITION = const(0x44)
SET_RAM_Y_ADDRESS_START_END_POSITION = const(0x45)
SET_RAM_X_ADDRESS_COUNTER            = const(0x4E)
SET_RAM_Y_ADDRESS_COUNTER            = const(0x4F)
TERMINATE_FRAME_READ_WRITE           = const(0xFF) # not in datasheet, aka NOOP

class EPD:
    def __init__(self):
        self.spi = SPI(2, baudrate=20000000, polarity=0, phase=0, sck=Pin(18), mosi=Pin(23), miso=Pin(12))
        #self.spi = SPI(1, 10000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
        self.spi.init()

        dc = Pin(17)
        cs = Pin(5)
        rst = Pin(16)

        self.cs = cs
        self.dc = dc
        self.rst = rst
        #self.busy = busy
        self.cs.init(self.cs.OUT, value=1)
        self.dc.init(self.dc.OUT, value=0)
        self.rst.init(self.rst.OUT, value=0)
        self.width = EPD_WIDTH
        self.height = EPD_HEIGHT

        self.size = self.width * self.height // 8
        self.buf = bytearray(self.size)

    LUT_FULL_UPDATE    = bytearray(b'\x80\x60\x40\x00\x00\x00\x00\x10\x60\x20\x00\x00\x00\x00\x80\x60\x40\x00\x00\x00\x00\x10\x60\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x03\x00\x00\x02\x09\x09\x00\x00\x02\x03\x03\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x41\xA8\x32\x30\x0A')
    LUT_PARTIAL_UPDATE = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x41\xA8\x32\x30\x0A')

    def clearBuffer(self):
        self._command(b'\x24')
        for i in range(0, len(self.buf)):
            self.buf[i] = 255
            self._data(bytearray([self.buf[i]]))

    def displayBuffer(self, buf):
        self._command(b'\x24')
        for i in range(0, len(buf)):
            self._data(bytearray([buf[i]]))
        self._command(b'\x22')
        self._command(b'\xC7')
        self._command(b'\x20')
        self._command(bytearray([TERMINATE_FRAME_READ_WRITE]))
        self.wait_until_idle()

    def _command(self, command, data=None):
        self.cs(1) # according to LOLIN_EPD
        self.dc(0)
        self.cs(0)
        self.spi.write(command)
        self.cs(1)
        if data is not None:
            self._data(data)

    def _data(self, data):
        self.cs(1) # according to LOLIN_EPD
        self.dc(1)
        self.cs(0)
        self.spi.write(data)
        self.cs(1)

    def init(self):
        self.reset()

        self.wait_until_idle();
        self._command(b'\x12'); # soft reset
        self.wait_until_idle();

        self._command(b'\x74', b'\x54'); #set analog block control
        self._command(b'\x7E', b'\x3B'); #set digital block control
        self._command(b'\x0f', b'\x00'); #set gate scan start position
        self._command(b'\x01', b'\xF9\x00\x00'); #Driver output control  ### CHANGED x00 to x01 ###
        self._command(b'\x11', b'\x03'); #data entry mode    ### CHANGED x01 to x00 ###
        #set Ram-X address start/end position
        self._command(b'\x44', b'\x00\x0F'); #0x0C-->(15+1)*8=128
        #set Ram-Y address start/end position
        self._command(b'\x45', b'\x00\x00\xF9\x00'); # 0xF9-->(249+1)=250   ### CHANGED xF9 to x00 ###

        self._command(b'\x3C', b'\x03'); # BorderWavefrom
        self._command(b'\x2C', b'\x55'); # VCOM Voltage

        self._command(b'\x03', bytes([self.LUT_FULL_UPDATE[70]])); # ??

        self._command(b'\x04')
        self._data(bytes([self.LUT_FULL_UPDATE[71]])); # ??
        self._data(bytes([self.LUT_FULL_UPDATE[72]])); # ??
        self._data(bytes([self.LUT_FULL_UPDATE[73]])); # ??

        self._command(b'\x3A', bytes([self.LUT_FULL_UPDATE[74]])); # Dummy Line
        self._command(b'\x3B', bytes([self.LUT_FULL_UPDATE[75]])); # Gate time

        self.set_lut(self.LUT_FULL_UPDATE)

        self._command(b'\x4E', b'\x00'); # set RAM x address count to 0;
        self._command(b'\x4F', b'\x00\x00'); # set RAM y address count to 0X127;
        self.wait_until_idle()

    def wait_until_idle(self):
        sleep_ms(1000)

    def reset(self):
        self.rst(1)
        sleep_ms(1)

        self.rst(0)
        sleep_ms(10)

        self.rst(1)

    def set_lut(self, lut):
        self._command(bytearray([WRITE_LUT_REGISTER]), lut)

    # put an image in the frame memory
    def set_frame_memory(self, image, x, y, w, h):
        # x point must be the multiple of 8 or the last 3 bits will be ignored
        x = x & 0xF8
        w = w & 0xF8

        if (x + w >= self.width):
            x_end = self.width - 1
        else:
            x_end = x + w - 1

        if (y + h >= self.height):
            y_end = self.height - 1
        else:
            y_end = y + h - 1

        self.set_memory_area(x, y, x_end, y_end)
        self.set_memory_pointer(x, y)
        self._command(bytearray([WRITE_RAM]), image)

    # replace the frame memory with the specified color
    def clear_frame_memory(self, color):
        self.set_memory_area(0, 0, self.width - 1, self.height - 1)
        self.set_memory_pointer(0, 0)
        self._command(bytearray([WRITE_RAM]))
        # send the color data
        for i in range(0, (self.width * self.height)//8):
            self._data(bytearray([color]))

    # draw the current frame memory and switch to the next memory area
    def display_frame(self):
        self._command(bytearray([DISPLAY_UPDATE_CONTROL_2]), b'\xC7')
        self._command(bytearray([MASTER_ACTIVATION]))
        self._command(bytearray([TERMINATE_FRAME_READ_WRITE]))
        self.wait_until_idle()

    # specify the memory area for data R/W
    def set_memory_area(self, x_start, y_start, x_end, y_end):
        self._command(bytearray([SET_RAM_X_ADDRESS_START_END_POSITION]))
        # x point must be the multiple of 8 or the last 3 bits will be ignored
        self._data(bytearray([(x_start >> 3) & 0xFF]))
        self._data(bytearray([(x_end >> 3) & 0xFF]))
        self._command(bytearray([SET_RAM_Y_ADDRESS_START_END_POSITION]), ustruct.pack("<HH", y_start, y_end))

    # specify the start point for data R/W
    def set_memory_pointer(self, x, y):
        self._command(bytearray([SET_RAM_X_ADDRESS_COUNTER]))
        # x point must be the multiple of 8 or the last 3 bits will be ignored
        self._data(bytearray([(x >> 3) & 0xFF]))
        self._command(bytearray([SET_RAM_Y_ADDRESS_COUNTER]), ustruct.pack("<H", y))
        self.wait_until_idle()

    # to wake call reset() or init()
    def sleep(self):
        self._command(bytearray([DEEP_SLEEP_MODE]))
        self.wait_until_idle()

引用 demo

import epaper2in13
e = epaper2in13.EPD()
e.init()
e.clearBuffer()

import framebuf
buf = bytearray(128 * 250 // 8)
fb = framebuf.FrameBuffer(buf, 128, 250, framebuf.MONO_HLSB)
black = 0
white = 1
fb.fill(white)
fb.text('Hello World',30,30,black)
e.displayBuffer(buf)
shownb commented 3 years ago

ttgo的2.13电子纸 https://github.com/thomasklingbeil/esphome/tree/ttgo-epaper-b73

https://github.com/waveshare/e-Paper/blob/master/RaspberryPi%26JetsonNano/c/lib/e-Paper/EPD_2in13_V2.c

https://github.com/awkinley/esp32-epaper-clock/tree/710dd1b6a5d8d82406ddef914cf59f7002acb663