PyBmini开发板:最终文件

文件夹的组织
模块的一些学习过程
在这里插入图片描述
一共修改了两个文件:

main.py

# main.py -- put your code here!
import pyb
from pyb import Pin, ADC, Timer, ExtInt,I2C,SPI,Accel,UART,Switch,LED
from ssd1306 import SSD1306
import _thread
import time,onewire,ds18x20
from machine import Pin
import dht
from pyb import UART


sw = Switch()
global tem1
global tem2
global hum
tem1=0
tem2=0
hum=0
global layout
layout=0
global update_flag_up
global update_flag_down
global update_mode
global mode_num 
global tem1_d
global tem2_d
global hum_d
global last_check_time
global step
step=0
# 因为显示的两种模式,曲线需要记录一下历史的数据,或者直接绘制,如果切换显示就清屏
# 而绘制方块不需要,只需要现在的数据即可

#应该修改为读取EEPROM的值
tem1_d=0
tem2_d=0
hum_d=0 
# 初始化检测变量
last_check_time = time.ticks_ms()
alarm_interval=500
update_flag_up=False
update_flag_down=False
update_mode=False
mode_num = 0#0,1,2
display = SSD1306(pinout={'sda': 'PB7','scl': 'PB6'},height=64,external_vcc=False)#OLED 初始化
ow=onewire.OneWire(Pin('PB0'))#初始化 onewire
ds=ds18x20.DS18X20(ow)#初始化 18B20
dht = dht.DHT11(Pin("PB1"))#dht11 初始化
accel = Accel()
i2c = I2C(1, I2C.MASTER, baudrate=100000)
u = UART(2)
u.init(9600)
#蜂鸣器的初始化
buzzer = Pin('PA1')
tim = Timer(2, freq=1000)
ch = tim.channel(2, Timer.PWM, pin=buzzer)

#使用定时器来进行oled的刷新。
tim1 = Timer(1, freq=1)  # 定时器1,频率为1Hz


# i2c = I2C(1, I2C.MASTER, baudrate=100000)
# u = UART(2)
# u.init(9600)
# 如果传入了数值,就初始化,否则,就读取eeprom的值
def init_threshold(default=None):
    global tem1_d
    global tem2_d
    global hum_d 
    if default != None:
        b_default=default.to_bytes(1, 'big')
        i2c.mem_write(b_default, 80, 0x10)#b'\x1e' 两种输入初值的方式
        #睡眠一段时间,使设备正常工作
        time.sleep_ms(50)
        i2c.mem_write(b_default, 80, 0x20)
        time.sleep_ms(50)
        i2c.mem_write(b_default, 80, 0x30)
        tem1_d=tem2_d=hum_d=default
    else:
        # 读取EEPROM数据
        data = i2c.mem_read(1, 80, 0x10)
        tem1_d = int.from_bytes(data, 'big')
        data = i2c.mem_read(1, 80, 0x20)
        tem2_d = int.from_bytes(data, 'big')
        data = i2c.mem_read(1, 80, 0x30)
        hum_d = int.from_bytes(data, 'big')
        print("tem1_d:", tem1_d)
        print("tem2_d:", tem2_d)
        print("hum_d:", hum_d)

def callback1(line):
    global update_flag_up
    update_flag_up = True
def callback2(line):
    global update_flag_down
    update_flag_down = True
def callback3():
    global update_mode
    update_mode = True 
#合并两个信号检测的代码
def detect_sign1(sec):
    time.sleep(sec)
    global update_flag_up, update_flag_down
    global tem1_d, tem2_d, hum_d
    
    while True:
        if update_flag_up or update_flag_down:
            time.sleep_ms(200)
            
            # 确定当前模式对应的地址和变量
            mode_map = {
                0: (0x10, 'tem1_d'),
                1: (0x20, 'tem2_d'),
                2: (0x30, 'hum_d')
            }
            
            if mode_num in mode_map:
                addr, var_name = mode_map[mode_num]
                
                # 根据标志决定是加一还是减一
                delta = 1 if update_flag_up else -1
                
                # 更新对应的全局变量
                if var_name == 'tem1_d':
                    tem1_d += delta
                elif var_name == 'tem2_d':
                    tem2_d += delta
                else:  # var_name == 'hum_d'
                    hum_d += delta
                # 读取EEPROM数据
                data = i2c.mem_read(1, 80, addr)
                x = int.from_bytes(data, 'big') + delta

                # 写回EEPROM
                b = x.to_bytes(1, 'big')
                i2c.mem_write(b, 80, addr)
                
                print("Updated value:", x)
            # 重置标志
            update_flag_up = False
            update_flag_down = False
        time.sleep_ms(200)

def detect_sign2(sec):
    time.sleep(sec)
    global update_mode
    global mode_num
    while True:
        if update_mode:
		    # 重置标志
            update_mode = False
            mode_num = (mode_num + 1)%3
            print("mode:", mode_num)

def is_within_range(x, y, z, target=(0, 20, 0), tolerance=9):
    #直方图绘图状态
    if (
        target[0] - tolerance <= x <= target[0] + tolerance and
        target[1] - tolerance <= y <= target[1] + tolerance and
        target[2] - tolerance <= z <= target[2] + tolerance
    ):
        return 0
    else:
        return 1

def sensor_data():
    global tem1
    global tem2
    global hum
    global layout
    while True:
        try:
            x = accel.x()  # 获取 x 轴加速度
            y = accel.y()  # 获取 y 轴加速度
            z = accel.z()  # 获取 z 轴加速度
            layout=is_within_range(x, y, z)
            print(x,y,z,layout)
        except :
            print("accel lose")
        try:
            roms = ds.scan()#扫描总线上的设备
            ds.convert_temp()#获取采样温度
            for rom in roms:
                tem1=ds.read_temp(rom)
            # print("tem1:", tem1)
        except :
            print("DS18B20 lose")
        try:
            dht.measure()
            tem2 = dht.temperature()
            hum = dht.humidity()
            # print("tem2:", tem2)
            # print("hum:", hum)
        except :
            print("DHT11 lose")
        time.sleep_ms(1000)
        # if tem1>tem1_d:

            
        
        # #尝试绘图
        # try:
        # #     display.
        #     time.sleep(1)
    # def display_mod(mod=1,tem1,tem2,hum):
        
# def paint_show():
#     global tem1
#     global tem2
#     global hum
#     global layout
#     # while True:

#     # print("paint_show")
#     # print("tem1:", tem1)
#     # print("tem2:", tem2)
#     # print("hum:", hum)
#     # print("layout:", layout)
#     display.draw_axes_1(Tem=tem1,tem= tem2,hum =hum, layout=layout)
#     # time.sleep_ms(1000)


# 报警检查函数,非阻塞
def alarm_check():
    global last_check_time
    while True:
        current_time = time.ticks_ms()
        
        if time.ticks_diff(current_time, last_check_time) >= alarm_interval:
            # 温度1报警
            if tem1 > tem1_d:
                LED(1).toggle() 
            # 温度2报警
            if tem2 > tem2_d:
                LED(2).toggle()
            # 湿度报警
            if hum > hum_d:
                LED(3).toggle()
            # 更新上一次检测时间
            last_check_time = current_time
            

        # 非阻塞延时
        time.sleep_ms(400)  # 设置短暂休眠避免CPU负担过重



if __name__ == '__main__':#程序入口
    init_threshold(50)
    display = SSD1306(pinout={'sda': 'PB7','scl': 'PB6'},height=64,external_vcc=False)#OLED 初始化
    display.poweron()#OLED 开启
    display.init_display()#OLED 初始化显示
    ext = ExtInt(Pin('PB9'), ExtInt.IRQ_RISING, Pin.PULL_NONE, callback1)
    ext = ExtInt(Pin('PB8'), ExtInt.IRQ_RISING, Pin.PULL_NONE, callback2)
    sw.callback(callback3)
    
    _thread.start_new_thread(sensor_data, ())
    _thread.start_new_thread(detect_sign1, (1,))
    _thread.start_new_thread(detect_sign2, (1,))
    _thread.start_new_thread(alarm_check, ())
    # _thread.start_new_thread(paint_show, ())

    last_layout=layout=0
    step=0
    while True:
        print("painting")
        if step==0:
            display.clear()
        if layout!=last_layout:
            step=0
            display.clear()
        last_layout=layout
        display.draw_axes_1(step,Tem=tem1,tem=tem2,hum=hum, layout=layout)
        step= step+1  
        if step==90:
            step=0
            display.clear()
        time.sleep_ms(1000)
 



重构后的main

# main.py -- put your code here!
import pyb
from pyb import Pin, ADC, Timer, ExtInt,I2C,SPI,Accel,UART,Switch,LED
from ssd1306 import SSD1306
import _thread
import time,onewire,ds18x20
from machine import Pin
import dht
from pyb import UART

class SensorManager:
    def __init__(self):
        self.tem1 = 0
        self.tem2 = 0
        self.hum = 0
        self.layout = 0
        self.last_check_time = time.ticks_ms()
        self.alarm_interval = 500
        
        # Initialize sensors
        self.sw = Switch()
        self.display = SSD1306(pinout={'sda': 'PB7', 'scl': 'PB6'}, height=64, external_vcc=False)
        self.display.poweron()
        self.display.init_display()
        self.ow = onewire.OneWire(Pin('PB0'))
        self.ds = ds18x20.DS18X20(self.ow)
        self.dht_sensor = dht.DHT11(Pin("PB1"))
        self.accel = Accel()
        self.i2c = I2C(1, I2C.MASTER, baudrate=100000)
        self.uart = UART(2)
        self.uart.init(9600)
        
        # Beeper initialization
        self.buzzer = Pin('PA1')
        self.tim = Timer(2, freq=1000)
        self.ch = self.tim.channel(2, Timer.PWM, pin=self.buzzer)
        
        # Thresholds
        self.tem1_d = 0
        self.tem2_d = 0
        self.hum_d = 0
        self.mode_num = 0
        self.update_flag_up = False
        self.update_flag_down = False
        self.update_mode = False
        self.step = 0
        self.last_layout = 0
        
        # Initialize thresholds
        self.init_threshold(default=50)
        
        # External interrupts
        ext_up = ExtInt(Pin('PB9'), ExtInt.IRQ_RISING, Pin.PULL_NONE, self.callback1)
        ext_down = ExtInt(Pin('PB8'), ExtInt.IRQ_RISING, Pin.PULL_NONE, self.callback2)
        self.sw.callback(self.callback3)

    def callback1(self, line):
        self.update_flag_up = True

    def callback2(self, line):
        self.update_flag_down = True

    def callback3(self):
        self.update_mode = True

    def init_threshold(self, default=None):
        if default is not None:
            b_default = default.to_bytes(1, 'big')
            self.i2c.mem_write(b_default, 80, 0x10)
            time.sleep_ms(50)
            self.i2c.mem_write(b_default, 80, 0x20)
            time.sleep_ms(50)
            self.i2c.mem_write(b_default, 80, 0x30)
            self.tem1_d = self.tem2_d = self.hum_d = default
        else:
            self.tem1_d = int.from_bytes(self.i2c.mem_read(1, 80, 0x10), 'big')
            self.tem2_d = int.from_bytes(self.i2c.mem_read(1, 80, 0x20), 'big')
            self.hum_d = int.from_bytes(self.i2c.mem_read(1, 80, 0x30), 'big')

    def detect_sign1(self, sec):
        time.sleep(sec)
    
        while True:
            if self.update_flag_up or self.update_flag_down:
                # Determine the current mode's address and variable name
                mode_map = {
                    0: (0x10, 'tem1_d'),
                    1: (0x20, 'tem2_d'),
                    2: (0x30, 'hum_d')
                }
            
                if self.mode_num in mode_map:
                    addr, var_name = mode_map[self.mode_num]
                
                    # Determine whether to increment or decrement
                    delta = 1 if self.update_flag_up else -1
                
                    # Update the corresponding attribute
                    new_value = getattr(self, var_name) + delta
                    setattr(self, var_name, new_value)
                
                    # Read EEPROM data
                    data = self.i2c.mem_read(1, 80, addr)
                    current_value = int.from_bytes(data, 'big')
                
                    # Calculate new value
                    x = current_value + delta
                
                    # Write back to EEPROM
                    b = x.to_bytes(1, 'big')
                    self.i2c.mem_write(b, 80, addr)
                
                    print("Updated %s:" % var_name)
            
                # Reset flags
                self.update_flag_up = False
                self.update_flag_down = False
        
            time.sleep_ms(200)

    def detect_sign2(self):
        while True:
            if self.update_mode:
                self.update_mode = False
                self.mode_num = (self.mode_num + 1) % 3
                print("mode:", self.mode_num)
            
            time.sleep_ms(200)

    def is_within_range(self, x, y, z, target=(0, 20, 0), tolerance=9):
        return not (
            target[0] - tolerance <= x <= target[0] + tolerance and
            target[1] - tolerance <= y <= target[1] + tolerance and
            target[2] - tolerance <= z <= target[2] + tolerance
        )

    def read_sensors(self):
        while True:
            try:
                x = self.accel.x()
                y = self.accel.y()
                z = self.accel.z()
                self.layout = self.is_within_range(x, y, z)
                print(x, y, z, self.layout)
            except Exception as e:
                print("Accelerometer error:", e)
            
            try:
                roms = self.ds.scan()
                self.ds.convert_temp()
                for rom in roms:
                    self.tem1 = self.ds.read_temp(rom)
                print("tem1:", self.tem1)
            except Exception as e:
                print("DS18B20 error:", e)
            
            try:
                self.dht_sensor.measure()
                self.tem2 = self.dht_sensor.temperature()
                self.hum = self.dht_sensor.humidity()
                print("tem2:", self.tem2)
                print("hum:", self.hum)
            except Exception as e:
                print("DHT11 error:", e)
            
            time.sleep_ms(1000)

    def paint_show(self):
        while True:
            if self.step == 0:
                self.display.clear()
            if self.layout != self.last_layout or self.step == 0:
                self.step = 0
                self.display.clear()

            self.display.draw_axes_1(step=self.step, Tem=self.tem1, tem=self.tem2, hum=self.hum, layout=self.layout)
            self.last_layout = self.layout
            self.step = (self.step + 1)
            if self.step == 90:
                self.step = 0
                self.display.clear()
            time.sleep_ms(1000)

    def alarm_check(self):
        while True:
            current_time = time.ticks_ms()
            if time.ticks_diff(current_time, self.last_check_time) >= self.alarm_interval:
                if self.tem1 > self.tem1_d:
                    LED(1).toggle()
                if self.tem2 > self.tem2_d:
                    LED(2).toggle()
                if self.hum > self.hum_d:
                    LED(3).toggle()
                self.last_check_time = current_time
            
            time.sleep_ms(400)

if __name__ == '__main__':
    sensor_manager = SensorManager()
    
    _thread.start_new_thread(sensor_manager.read_sensors, ())
    _thread.start_new_thread(sensor_manager.detect_sign1, (1,))  # 传递参数 1
    _thread.start_new_thread(sensor_manager.detect_sign2, ())
    _thread.start_new_thread(sensor_manager.alarm_check, ())
    _thread.start_new_thread(sensor_manager.paint_show, ())

ssd1306.py

# The MIT License (MIT)
#
# Copyright (c) 2014 Kenneth Henderick
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import pyb
import dht
import font
import math
from machine import Pin#引用引脚
from pyb import Accel, delay

# Constants
DISPLAYOFF          = 0xAE
SETCONTRAST         = 0x81
DISPLAYALLON_RESUME = 0xA4
DISPLAYALLON        = 0xA5
NORMALDISPLAY       = 0xA6
INVERTDISPLAY       = 0xA7
DISPLAYON           = 0xAF
SETDISPLAYOFFSET    = 0xD3
SETCOMPINS          = 0xDA
SETVCOMDETECT       = 0xDB
SETDISPLAYCLOCKDIV  = 0xD5
SETPRECHARGE        = 0xD9
SETMULTIPLEX        = 0xA8
SETLOWCOLUMN        = 0x00
SETHIGHCOLUMN       = 0x10
SETSTARTLINE        = 0x40
MEMORYMODE          = 0x20
COLUMNADDR          = 0x21
PAGEADDR            = 0x22
COMSCANINC          = 0xC0
COMSCANDEC          = 0xC8
SEGREMAP            = 0xA0
CHARGEPUMP          = 0x8D
EXTERNALVCC         = 0x10
SWITCHCAPVCC        = 0x20
SETPAGEADDR         = 0xB0
SETCOLADDR_LOW      = 0x00
SETCOLADDR_HIGH     = 0x10
ACTIVATE_SCROLL                      = 0x2F
DEACTIVATE_SCROLL                    = 0x2E
SET_VERTICAL_SCROLL_AREA             = 0xA3
RIGHT_HORIZONTAL_SCROLL              = 0x26
LEFT_HORIZONTAL_SCROLL               = 0x27
VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL = 0x29
VERTICAL_AND_LEFT_HORIZONTAL_SCROLL  = 0x2A

# I2C devices are accessed through a Device ID. This is a 7-bit
# value but is sometimes expressed left-shifted by 1 as an 8-bit value.
# A pin on SSD1306 allows it to respond to ID 0x3C or 0x3D. The board
# I bought from ebay used a 0-ohm resistor to select between "0x78"
# (0x3c << 1) or "0x7a" (0x3d << 1). The default was set to "0x78"
DEVID = 0x3c

# I2C communication here is either <DEVID> <CTL_CMD> <command byte>
# or <DEVID> <CTL_DAT> <display buffer bytes> <> <> <> <>...
# These two values encode the Co (Continuation) bit as b7 and the
# D/C# (Data/Command Selection) bit as b6.
CTL_CMD = 0x80
CTL_DAT = 0x40

class SSD1306(object):

  def __init__(self, pinout, height=32, external_vcc=True, i2c_devid=DEVID):
    self.external_vcc = external_vcc
    self.height       = 32 if height == 32 else 64
    
    self.pages   = int(self.height / 8) 
    self.columns  = 128
    self.i2c = pyb.I2C(1)
    self.i2c.init(pyb.I2C.MASTER, baudrate=400000) # 400kHz
    self.devid = i2c_devid

    self.offset = 1
    self.cbuffer = bytearray(2)
    self.cbuffer[0] = CTL_CMD

  def clear(self):
    self.buffer = bytearray(self.offset + self.pages * self.columns)
    if self.offset == 1:
      self.buffer[0] = CTL_DAT

  def write_command(self, command_byte):
    self.cbuffer[1] = command_byte
    self.i2c.send(self.cbuffer, addr=self.devid, timeout=5000)

  def invert_display(self, invert):
    self.write_command(INVERTDISPLAY if invert else NORMALDISPLAY)

  def display(self):
    self.write_command(COLUMNADDR)
    self.write_command(0)
    self.write_command(self.columns - 1)
    self.write_command(PAGEADDR)
    self.write_command(0)
    self.write_command(self.pages - 1)
    if self.offset == 1:
      self.i2c.send(self.buffer, addr=self.devid, timeout=5000)
    else:
      self.dc.high()
      self.spi.send(self.buffer)

  def set_pixel(self, x, y, state):
    index = x + (int(y / 8) * self.columns)
    if state:
      self.buffer[self.offset + index] |= (1 << (y & 7))
    else:
      self.buffer[self.offset + index] &= ~(1 << (y & 7))

  def init_display(self):
    chargepump = 0x10 if self.external_vcc else 0x14
    precharge  = 0x22 if self.external_vcc else 0xf1
    multiplex  = 0x1f if self.height == 32 else 0x3f
    compins    = 0x02 if self.height == 32 else 0x12
    contrast   = 0xff # 0x8f if self.height == 32 else (0x9f if self.external_vcc else 0x9f)
    data = [DISPLAYOFF,
            SETDISPLAYCLOCKDIV, 0x80,
            SETMULTIPLEX, multiplex,
            SETDISPLAYOFFSET, 0x00,
            SETSTARTLINE | 0x00,
            CHARGEPUMP, chargepump,
            MEMORYMODE, 0x00,
            SEGREMAP | 0x10,
            COMSCANDEC,
            SETCOMPINS, compins,
            SETCONTRAST, contrast,
            SETPRECHARGE, precharge,
            SETVCOMDETECT, 0x40,
            DISPLAYALLON_RESUME,
            NORMALDISPLAY,
            DISPLAYON]
    for item in data:
      self.write_command(item)
    self.clear()
    self.display()
  def poweron(self):
    if self.offset == 1:
      pyb.delay(10)
    else:
      self.res.high()
      pyb.delay(1)
      self.res.low()
      pyb.delay(10)
      self.res.high()
      pyb.delay(10)
  def poweroff(self):
    self.write_command(DISPLAYOFF)

  def contrast(self, contrast):
    self.write_command(SETCONTRAST)
    self.write_command(contrast)
#设置了字符是8行5列
#产生x的坐标
  def draw_text(self, x, y, string, size=1, space=1):
    def pixel_x(char_number, char_column, point_row):
      char_offset = x + char_number * size * font.cols + space * char_number
      pixel_offset = char_offset + char_column * size + point_row
      return self.columns - pixel_offset
      # return pixel_offset
    def pixel_y(char_row, point_column):
      # char_offset = y + char_row * size
      #另一种布局,修改一下坐标
      #原来的布局
      char_offset=y+char_row*size
      # char_offset = y + (font.rows - 1 - char_row) * size
      #y垂直方向不设置间隔
      # return char_offset + point_column
      return  char_offset + point_column

    def pixel_mask(char, char_column, char_row):
      char_index_offset = ord(char) * font.cols
      return font.bytes[char_index_offset + char_column] >> char_row & 0x1

    pixels = ( 
      (pixel_x(char_number, char_column, point_row),
       pixel_y(char_row, point_column),
       pixel_mask(char, char_column, char_row))
      for char_number, char in enumerate(string)
      for char_column in range(font.cols)
      for char_row in range(font.rows)
      for point_column in range(size)
      for point_row in range(1, size + 1))

    for pixel in pixels:
      self.set_pixel(*pixel)     
  def draw_axes_1(self,step,Tem,tem,hum,origin_x= 38, origin_y= 10,length_x=None, length_y=None,layout=1):
     #默认从小的坐标到大的进行延申,只设置两种布局,
     #0是以[0,0]为参照点作为原点的,绘制曲线
     #1是以[128,0]为参照点,绘制直方图的

      if length_x is None:
          length_x = self.columns
      if length_y is None:
          length_y = self.height

      if layout == 1:
          print("step:",step)
          if step == 0:
            self.clear()
          for x in range(origin_x, length_x):
            self.set_pixel(x, origin_y, 1)

          for y in range(origin_y,length_y):
            self.set_pixel(origin_x, y, 1)
          #此处偷懒,不进行越界的判断
          self.draw_text_hi(length_x-20 ,origin_y-9,"X/s")
          self.draw_text_hi(origin_x-20, length_y-10, "Y/d")
          self.draw_text_hi(0 ,40,"Tem")
          self.draw_text_hi(0 ,30,"tem")
          self.draw_text_hi(0 ,20,"hum")
          #绘制正方向
          # self.draw_triangle(0,54,5,1)#x轴      
          self.draw_triangle(origin_x,length_y,5,3)
          self.draw_triangle(length_x,origin_y,5, 1)    
          print(Tem)
          self.paint(step,Tem,tem,hum,layout)    

      else:
          self.clear()
          print("clear")
          origin_x = 128
          origin_y = 0
          for x in range(origin_x-9, length_x-origin_x,-1):
            self.set_pixel(x, origin_y+5, 1)

          for y in range(origin_y+5,length_y):
            self.set_pixel(origin_x-9, y, 1)
          #此处偷懒,不进行越界的判断
          self.draw_ylayout(length_x-9 ,length_y-25,"X/s")
          self.draw_ylayout(0, origin_y+8, "Y/d")
      
          self.draw_ylayout(9 ,length_y-40,"Tem")
          self.draw_ylayout(18 ,length_y-40,"tem")
          self.draw_ylayout(27 ,length_y-40,"hum")
          #绘制正方向
          self.draw_triangle(origin_x-9,length_y,5,3)
          self.draw_triangle(0,origin_y+5, 5, 2)
          print(layout)
          self.paint(step,Tem,tem,hum,layout)
          #绘制直方图的函数,绘制三个
          # x和数值有关,y和布局有关,128-9是x轴的位置
          #data是传入的数值
  def paint(self,step,Tem,tem,hum,layout):
    #不放在循环里,而是使用定时器,每秒调用一次
    print(layout)
    if layout == 1:
        print("layout 1")
        #每次都从新开始绘制
        self.draw_text_hi(18,40,str(int(Tem)))
        self.draw_text_hi(18,30,str(tem))
        self.draw_text_hi(18,20,str(hum))
        # if 
        mapped_hum = 10+int(hum*0.54)
        mapped_Tem = 10+int(int(Tem)*0.54)
        print(mapped_Tem)
        mapped_tem = 10+int(tem*0.54)
        #一共是128,有90个,判断小于90绘制,否则不绘制
        if step < 90:
          self.set_pixel(38+step, int(mapped_Tem), 1)
          self.set_pixel(38+step, int(mapped_tem), 1)
          self.set_pixel(38+step, int(mapped_hum), 1)

        self.display()
    if layout == 0:
        print("layout 0")
        
        self.draw_ylayout(9 ,64-22,str(int(Tem)))
        self.draw_ylayout(18 ,64-22,str(tem))
        self.draw_ylayout(27 ,64-22,str(hum))
        self.draw_rectangle(self.columns-9-int(Tem),15,Tem,5)
        self.draw_rectangle(self.columns-9-tem,30,tem,5)
        self.draw_rectangle(self.columns-9-hum,45,hum,5)
        self.display()
      
  def draw_triangle(self, x, y, size=2,direction=1):
      if 1 == direction:
        for i in range(1, size + 1):
            self.set_pixel(x - i, y, 1)
            self.set_pixel(x - i, y - i, 1)
            self.set_pixel(x - i, y + i, 1) 
      
      if 2 == direction:
        for i in range(1, size + 1):
            self.set_pixel(x + i, y, 1)
            self.set_pixel(x + i, y - i, 1)
            self.set_pixel(x + i, y + i, 1)
      if 3 == direction:
        for i in range(1, size + 1):
            self.set_pixel(x, y - i, 1)
            self.set_pixel(x - i, y - i, 1)
            self.set_pixel(x + i, y - i, 1)
      if 4 == direction:
        for i in range(1, size + 1):
            self.set_pixel(x, y + i, 1)
            self.set_pixel(x - i, y + i, 1)
            self.set_pixel(x + i, y + i, 1)      
  def draw_rectangle(self, x, y, width, height, filled=True):
    """
    绘制一个方块或矩形
    :param x: 方块左上角的 X 坐标
    :param y: 方块左上角的 Y 坐标
    :param width: 方块的宽度
    :param height: 方块的高度
    :param filled: 是否填充方块(True 为填充,False 为仅绘制边框)
    """
    # 绘制填充的方块
    if filled:
        for i in range(x, x + width):
            for j in range(y, y + height):
                self.set_pixel(i, j, 1)
    else:
        # 绘制空心方块(仅边框)
        # 上边框
        for i in range(x, x + width):
            self.set_pixel(i, y, 1)
        # 下边框
        for i in range(x, x + width):
            self.set_pixel(i, y + height - 1, 1)
        # 左边框
        for j in range(y, y + height):
            self.set_pixel(x, j, 1)
        # 右边框
        for j in range(y, y + height):
            self.set_pixel(x + width - 1, j, 1)

    # 显示绘制的方块
    self.display()

  def draw_text_hi(self, x, y, string, size=1, space=1):
    def pixel_x(char_number, char_column, point_row):
      char_offset = x + char_number * size * font.cols + space * char_number
      pixel_offset = char_offset + char_column * size + point_row
      #return self.columns - pixel_offset
      return pixel_offset

    def pixel_y(char_row, point_column):
      # char_offset = y + char_row * size
      #另一种布局,修改一下坐标
      #原来的布局
      # char_offset=y+char_row*size
      char_offset = y + (font.rows - 1 - char_row) * size
      #y垂直方向不设置间隔
      # return char_offset + point_column
      return  char_offset + point_column
    def pixel_mask(char, char_column, char_row):
      char_index_offset = ord(char) * font.cols
      return font.bytes[char_index_offset + char_column] >> char_row & 0x1
    pixels = ( 
      (pixel_x(char_number, char_column, point_row),
       pixel_y(char_row, point_column),
       pixel_mask(char, char_column, char_row))
      for char_number, char in enumerate(string)
      for char_column in range(font.cols)
      for char_row in range(font.rows)
      for point_column in range(size)
      for point_row in range(1, size + 1))
    for pixel in pixels:
      self.set_pixel(*pixel)

  #行列互换的字体显示方式
  def draw_ylayout(self, x, y, string, size=1, space=1):
    def pixel_y(char_number,char_column, point_row):
        char_offset = y + char_number * size * font.cols+space * char_number
        pixel_offset =char_offset+char_column * size + point_row
        #y垂直方向不设置间隔
        # return char_offset + point_column
        return  pixel_offset
    def pixel_x( char_row , point_column):
        #行的距离域(128->64)偏移从(5->8)s
          char_offset = x +  char_row * size
          # return self.columns - pixel_offset
          return char_offset + point_column    
    def pixel_mask(char, char_column, char_row):
        char_index_offset = ord(char) * font.cols
        return font.bytes[char_index_offset + char_column] >> char_row & 0x1
    pixels = ((pixel_x(char_row, point_column),
          pixel_y(char_number, char_column, point_row),
          pixel_mask(char, char_column, char_row))
          for char_number, char in enumerate(string)
          for char_column in range(font.cols)
          for char_row in range(font.rows)
          for point_column in range(1, size + 1)
          for point_row in range(size))
          
    for pixel in pixels:
        self.set_pixel(*pixel)

替换这两个文件,到对应的目录,即可实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值