ESP32-C3 配置USB CDC On Boot 方法记录

ESP32-C3

USB CDC OnBoot 配置方法

之前用arduino-cli 配置ESP32-C3,编写代码和编译烧录都没有问题, 只是在使用arduino-cli monitor -p /dev/ttyACM0 没有输出, 查了一圈发现是因为USB CDC Onboot 没有开启, 然后各种搜索完全没有结果,直到我直接去github官方下面开了issue,一小时内就解决了我的问题,这个老哥厉害了。
下面是引用它的引文:

Custom board options such as "**USB CDC On Boot**" are set via the FQBN you pass to `arduino-cli` commands via the `--fqbn` flag.

 The format of the FQBN is like this:

 <vendor ID>:<architecture>:<board ID>[:<menu ID>=<option ID>[,<menu ID>=<option ID>]...]

 You can learn all the available menu IDs and option IDs for a given board by running [the following command](https://arduino.github.io/arduino-cli/latest/commands/arduino-cli_board_details/):

 arduino-cli board details --fqbn <FQBN>

 (where `<FQBN>` is replaced by the fully qualified board name of the board you are using)

 For example if you are using the "**ESP32C3 Dev Module**" board (FQBN: `esp32:esp32:esp32c3`):

$ ./arduino-cli board details -b esp32:esp32:esp32c3
Board name:            ESP32C3 Dev Module
 FQBN:                  esp32:esp32:esp32c3
 Board version:         2.0.4

Package name:          esp32
Package maintainer:    Espressif Systems
Package URL:           https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json    
Package website:       https://github.com/espressif/arduino-esp32
Package online help:   http://esp32.com

Platform name:         esp32
Platform category:     ESP32
Platform architecture: esp32
Platform URL:          https://github.com/espressif/arduino-esp32/releases/download/2.0.4/esp32-2.0.4.zip
Platform file name:    esp32-2.0.4.zip
Platform size (bytes): 259715595
Platform checksum:     SHA-256:832609d6f4cd0edf4e471f02e30b7f0e1c86fdd1b950990ef40431e656237214

Required tool:         esp32:riscv32-esp-elf-gcc                                            gcc8_4_0-esp-2021r2-patch3

Required tool:         esp32:xtensa-esp32-elf-gcc                                           gcc8_4_0-esp-2021r2-patch3

Required tool:         esp32:xtensa-esp32s2-elf-gcc                                         gcc8_4_0-esp-2021r2-patch3

Required tool:         esp32:xtensa-esp32s3-elf-gcc                                         gcc8_4_0-esp-2021r2-patch3

Required tool:       

尝试使用

arduino-cli board details -b esp32:esp32:esp32c3 

然后我突然明白了怎么用了。

<vendor ID>:<architecture>:<board ID>[:<menu ID>=<option ID>[,<menu ID>=<option ID>]...]

这个结构就是我烧录时候需要遵循的。
通过查询找到了USB CDC Onboot的配置是esp32:esp32:esp32c3:USBOnBoot=cdc

menuID: USBOnBoot
optionID: cdc

于是直接烧录:

arduino-cli compile -b esp32:esp32:esp32c3:USBOnBoot=cdc -p /dev/ttyACM0 --upload 

烧录完成直接执行:

arduino-cli monitor -p /dev/ttyACM0

顺利看到输出,就非常奈斯。。
希望对你有帮助哈!

为OLED显示图片生成Bytearray

OLED 0.96

缘起

自从使用Raspberry Pi Pico以后,就觉得MicroPython真的太方便了。各种应用想实现就分分钟搞定。
这里面不得不说OLED屏幕中0.96inch的存在,真是小巧又可爱。
在刷新OLED的屏幕时,常用到ssd1306的库,那都是底层,最重要的还是使用framebuf库的功能。
其中,我最喜欢就是用bytearray去做为输入的buf。
例如我就常常:

from machine import Pin, ADC, I2C
from time import sleep
import framebuf
from ssd1306 import SSD1306_I2C

WIDTH = 128
HEIGHT = 64

buf = bytearray(b'') # 这里定义buf。 后面讲这里的buf怎么实现。

fb = framebuf.FrameBuffer(buf, framebuf.MONO_VLSB)

bus = I2C(1, scl=Pin(15), sda=Pin(14), freq=2000000)
oled = SSD1306_I2C(WIDTH, HEIGHT, bus)

while True:
    oled.fill(0)
    oled.show()
    sleep(0.01)
    oled.blit(fb, 0, 0) 
    oled.show()
    sleep(0.5)

buf的实现方法

  1. 打开windows的绘图板,生成一个128x64的画布
    然后自己随便画个图像并保存。
  2. 然后打开pycharm编写如下代码:

from io import BytesIO
from PIL import Image
import sys

if len(sys.argv) > 1:
    path_to_image = str(sys.argv[1])
    x = int(sys.argv[2])
    y = int(sys.argv[3])
    im = Image.open(path_to_image).convert('1')
    im_resize = im.resize((x,y))
    buf = BytesIO()
    im_resize.save(buf, 'ppm')
    byte_im = buf.getvalue()
    temp = len(str(x) + ' ' + str(y)) + 4
    print(byte_im[temp::])
else:
    print("please specify the location of image i.e img2bytearray.py /path/to/image width heigh")

然后执行这个代码并提供图片的位置,这样就将图片生成了一段bytearray数组,拷贝到buf的位置。

红框部分的内容复制到bytearray的位置。上传到pico,就搞定了。
非常简单。

MPU6050计算三个姿态使用的公式

这两天折腾MPU6050, 仔细看了看文档。

下面内容就是不同的角度的算法。

Pitch angle 俯仰角

  • To find Pitch angle should be the angle between X and Z axis which will be
    atan2(accelZ,accelX)*180/PI

    Roll angle 滚动角

  • For Roll angle should be the angle between Y and Z axis which will be
    atan2(accelZ,accelY)*180/PI

    yaw angle 偏航角

    And to find yaw it should be the angle between X and VectorY+Z which will be

    atan2(sqrt(accelY*accelY+accelZ*accelZ),accelX)*180/PI

    总结

    1. 校准IMU
    2. 读取原始数据
    3. 处理数据信息

树莓派控制Hobbywing 电调控制无刷电机

树莓派4B + ESC (Hobbywing) + SKYwalker 2212 无刷电机

测试步骤

  1. 搭建电路
  2. 校准电调
  3. 驱动电机ESC.py 测试代码:
# This program will let you test your ESC and brushless motor.
# Make sure your battery is not connected if you are going to calibrate it at first.
# Since you are testing your motor, I hope you don't have your propeller attached to it otherwise you are in trouble my friend...?
# This program is made by AGT @instructable.com. DO NOT REPUBLISH THIS PROGRAM... actually the program itself is harmful                                             pssst Its not, its safe.

import os     #importing os library so as to communicate with the system
import time   #importing time library to make Rpi wait because its too impatient 
os.system ("sudo pigpiod") #Launching GPIO library
time.sleep(1) # As i said it is too impatient and so if this delay is removed you will get an error
import pigpio #importing GPIO library

ESC=4  #Connect the ESC in this GPIO pin 

pi = pigpio.pi();
pi.set_servo_pulsewidth(ESC, 0) 

max_value = 2000 #change this if your ESC's max value is different or leave it be
min_value = 700  #change this if your ESC's min value is different or leave it be
print "For first time launch, select calibrate"
print "Type the exact word for the function you want"
print "calibrate OR manual OR control OR arm OR stop"

def manual_drive(): #You will use this function to program your ESC if required
    print "You have selected manual option so give a value between 0 and you max value"    
    while True:
        inp = raw_input()
        if inp == "stop":
            stop()
            break
        elif inp == "control":
            control()
            break
        elif inp == "arm":
            arm()
            break   
        else:
            pi.set_servo_pulsewidth(ESC,inp)

def calibrate():   #This is the auto calibration procedure of a normal ESC
    pi.set_servo_pulsewidth(ESC, 0)
    print("Disconnect the battery and press Enter")
    inp = raw_input()
    if inp == '':
        pi.set_servo_pulsewidth(ESC, max_value)
        print("Connect the battery NOW.. you will here two beeps, then wait for a gradual falling tone then press Enter")
        inp = raw_input()
        if inp == '':            
            pi.set_servo_pulsewidth(ESC, min_value)
            print "Wierd eh! Special tone"
            time.sleep(7)
            print "Wait for it ...."
            time.sleep (5)
            print "Im working on it, DONT WORRY JUST WAIT....."
            pi.set_servo_pulsewidth(ESC, 0)
            time.sleep(2)
            print "Arming ESC now..."
            pi.set_servo_pulsewidth(ESC, min_value)
            time.sleep(1)
            print "See.... uhhhhh"
            control() # You can change this to any other function you want

def control(): 
    print "I'm Starting the motor, I hope its calibrated and armed, if not restart by giving 'x'"
    time.sleep(1)
    speed = 1500    # change your speed if you want to.... it should be between 700 - 2000
    print "Controls - a to decrease speed & d to increase speed OR q to decrease a lot of speed & e to increase a lot of speed"
    while True:
        pi.set_servo_pulsewidth(ESC, speed)
        inp = raw_input()

        if inp == "q":
            speed -= 100    # decrementing the speed like hell
            print "speed = %d" % speed
        elif inp == "e":    
            speed += 100    # incrementing the speed like hell
            print "speed = %d" % speed
        elif inp == "d":
            speed += 10     # incrementing the speed 
            print "speed = %d" % speed
        elif inp == "a":
            speed -= 10     # decrementing the speed
            print "speed = %d" % speed
        elif inp == "stop":
            stop()          #going for the stop function
            break
        elif inp == "manual":
            manual_drive()
            break
        elif inp == "arm":
            arm()
            break   
        else:
            print "WHAT DID I SAID!! Press a,q,d or e"

def arm(): #This is the arming procedure of an ESC 
    print "Connect the battery and press Enter"
    inp = raw_input()    
    if inp == '':
        pi.set_servo_pulsewidth(ESC, 0)
        time.sleep(1)
        pi.set_servo_pulsewidth(ESC, max_value)
        time.sleep(1)
        pi.set_servo_pulsewidth(ESC, min_value)
        time.sleep(1)
        control() 

def stop(): #This will stop every action your Pi is performing for ESC ofcourse.
    pi.set_servo_pulsewidth(ESC, 0)
    pi.stop()

#This is the start of the program actually, to start the function it needs to be initialized before calling... stupid python.    
inp = raw_input()
if inp == "manual":
    manual_drive()
elif inp == "calibrate":
    calibrate()
elif inp == "arm":
    arm()
elif inp == "control":
    control()
elif inp == "stop":
    stop()
else :
    print "Thank You for not following the things I'm saying... now you gotta restart the program STUPID!!"

如何利用 opencv 简单解释二维码的组成

起因

今天 rockets 问我, 是否能够将二维码里面的色块用 0 和 1 表示出来.

分析

我脑海里分析了一下,不知道是不是可以用 opencv 实现,就打开电脑尝试了一下,似乎是可以的.
思路, 首先通过 qrcode 生成一个图片,然后保存一下,通过opencv 导入图片,然后再判断 10x10 大小的块中是否全是白色,如果是白色,就写一个 1
,如果是黑色,就写个 0. 然后遍历整个图片的 shape.

Talk is cheap, show me the code


import qrcode
import cv2
import numpy as np

url = 'https://www.dfrobot.com/product-2480.html'
file_name = 'qrcode.png'

def generate_image(url):
    qr = qrcode.QRCode()
    qr.add_data(url)
    qr.make(fit=False)
    img = qr.make_image(fill_color="black", back_color="white")
    img.save(file_name)

generate_image(url)
img1 = cv2.imread(file_name)
scale_percent = 80
width = int(img1.shape[1] * scale_percent / 100)
height = int(img1.shape[0] * scale_percent / 100)
dim = (width, height)

resized_img = cv2.resize(img1, dim, interpolation=cv2.INTER_AREA)
# gray_img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
for i in range(0, int(resized_img.shape[0]), 10):
    for j in range(0, int(resized_img.shape[1]), 10):
        if np.mean(resized_img[i:i+10, j:j+10]) == 255:
            cv2.putText(resized_img, '0', (i, j), cv2.FONT_HERSHEY_SIMPLEX, .2, (255, 0, 0))
        else:
            cv2.putText(resized_img, '1', (i, j), cv2.FONT_HERSHEY_SIMPLEX, .2, (255, 0, 0))

cv2.imshow('resized_img', resized_img)
cv2.waitKey(0)

执行效果:

重点

np.mean(图片数组) == 255的判断部分,可以判断图片是不是白色.

重构了一下,优化后:

import qrcode
import cv2
import numpy as np

# 定义生成 qrcode 的 url 链接和生成的文件名
url = 'https://www.dfrobot.com/product-2480.html'
file_name = 'qrcode.png'

def generate_image(url):
    """"
    生成二维码并保存
    """
    qr = qrcode.QRCode()
    qr.add_data(url)
    qr.make(fit=False)
    img = qr.make_image(fill_color="black", back_color="white")
    img.save(file_name)

def process_image(filename):
    """
    :param filename: 放入生成的二维码
    :return: 显示图
    """
    img1 = cv2.imread(file_name)
    scale_percent = 80
    width = int(img1.shape[1] * scale_percent / 100)
    height = int(img1.shape[0] * scale_percent / 100)
    dim = (width, height)
    resized_img = cv2.resize(img1, dim, interpolation=cv2.INTER_AREA)
    for i in range(0, int(resized_img.shape[0]), 10):
        for j in range(0, int(resized_img.shape[1]), 10):
            if np.mean(resized_img[i:i+5, j:j+5]) == 255:
                cv2.putText(resized_img, '0', (i+5, j+5), cv2.FONT_HERSHEY_SIMPLEX, .2, (255, 0, 0))
            else:
                cv2.putText(resized_img, '1', (i+5, j+5), cv2.FONT_HERSHEY_SIMPLEX, .2, (255, 0, 0))

    cv2.imshow('resized_img', resized_img)
    cv2.waitKey(0)

if __name__ == "__main__":
    generate_image(url)
    process_image(file_name)

优化后结果:

感觉还是不太对.

继续优化试试看.

import qrcode
import cv2
import numpy as np

# 定义生成 qrcode 的 url 链接和生成的文件名
url = 'https://www.dfrobot.com/product-2480.html'
file_name = 'qrcode.png'

def generate_image(url):
    """"
    生成二维码并保存
    """
    qr = qrcode.QRCode()
    qr.add_data(url)
    qr.make(fit=False)
    img = qr.make_image(fill_color="black", back_color="white")
    img.save(file_name)

def process_image(filename):
    """
    :param filename: 放入生成的二维码
    :return: 显示图
    """
    img1 = cv2.imread(file_name)
    scale_percent = 200
    width = int(img1.shape[1] * scale_percent / 100)
    height = int(img1.shape[0] * scale_percent / 100)
    dim = (width, height)
    resized_img = cv2.resize(img1, dim, interpolation=cv2.INTER_AREA)
    resized_img = cv2.cvtColor(resized_img, cv2.COLOR_BGR2GRAY)
    for i in range(0, int(resized_img.shape[0]), 10):
        for j in range(0, int(resized_img.shape[1]), 10):
            if np.mean(resized_img[i:i+3, j:j+3]) == 255:
                cv2.putText(resized_img, '1', (i + 5, j + 5), cv2.FONT_HERSHEY_SIMPLEX, .2, (0, 0, 255))
            else:
                cv2.putText(resized_img, '0', (i + 5, j + 5), cv2.FONT_HERSHEY_SIMPLEX, .2, (255, 0, 0))

    cv2.imshow('img', resized_img)
    cv2.waitKey(0)

if __name__ == "__main__":
    generate_image(url)
    process_image(file_name)

输出结果:

防止树莓派自动黑屏

前言

树莓派在运行桌面环境的时候,长时间不操作就会自动黑屏,是电源管理的一个节能的功能,有时候挺烦人,可以关闭它。

暂时关闭

在终端中输入:

sudo xset s off
sudo xset -dpms
sudo xset s noblank

永久关闭

  1. 通过sudo raspi-config 命令
    找到Display Options 然后选择Screen Blanking, 问是否启用,选择NO, 然后完成后重启树莓派。
  2. 通过编辑/etc/lightdm/lightdm.conf
    将xserver-command=X 前面的#去掉,然后改成:

    xserver-command=X -s 0 -dpms

    保存后退出重启系统。

    总结

    屡试不爽!

[Raspberry Pi 新系统]树莓派更新失败处理方法

故障现象:

pi@raspberrypi:~ $ sudo apt-get update
Get:1 http://archive.raspberrypi.org/debian buster InRelease [32.6 kB]
Get:2 http://raspbian.raspberrypi.org/raspbian buster InRelease [15.0 kB]
Reading package lists... Done
E: Repository 'http://raspbian.raspberrypi.org/raspbian buster InRelease' changed its 'Suite' value from 'stable' to 'oldstable'
N: This must be accepted explicitly before updates for this repository can be applied. See apt-secure(8) manpage for details.
E: Repository 'http://archive.raspberrypi.org/debian buster InRelease' changed its 'Suite' value from 'testing' to 'oldstable'
N: This must be accepted explicitly before updates for this repository can be applied. See apt-secure(8) manpage for details.

修复方法:

sudo apt-get -y update --allow-releaseinfo-change

结果如下:

Get:1 http://archive.raspberrypi.org/debian buster InRelease [32.6 kB]
Get:2 http://raspbian.raspberrypi.org/raspbian buster InRelease [15.0 kB]
Get:3 http://raspbian.raspberrypi.org/raspbian buster/contrib Sources [78.5 kB]
Get:4 http://archive.raspberrypi.org/debian buster/main armhf Packages [393 kB]
Get:5 http://raspbian.raspberrypi.org/raspbian buster/main Sources [11.4 MB]
Ign:5 http://raspbian.raspberrypi.org/raspbian buster/main Sources
Get:6 http://raspbian.raspberrypi.org/raspbian buster/non-free Sources [139 kB]
Get:7 http://raspbian.raspberrypi.org/raspbian buster/rpi Sources [1,132 B]
Get:8 http://raspbian.raspberrypi.org/raspbian buster/main armhf Packages [13.0 MB]
21% [8 Packages 443 kB/13.0 MB 3%]

顺利解决~

树莓派摄像头-追踪

今天实现了对物体检测并控制舵机运动的应用。
舵机使用了pca9685控制,因此备份一下pac9685舵机控制板的驱动:

PCA9685.py

import time
import math

class PWM:
    _mode_adr      = 0x00
    _base_adr_low  = 0x08
    _base_adr_high = 0x09
    _prescale_adr  = 0xFE

    def __init__(self, bus, address = 0x40):
        '''
        Creates an instance of the PWM chip at given i2c address.
        @param bus: the SMBus instance to access the i2c port(0 or 1).
        @param address: the address of the i2c chip (default: 0x40).
        '''
        self.bus = bus
        self.address = address
        self._writeByte(self._mode_adr, 0x00)

    def setFreq(self, freq):
        '''
        Sets the PWM frequency. The value is stored in the device.
        @param freq: the frequency in Hz (approx.)
        '''
        prescaleValue = 25000000.0  # 25MHz
        prescaleValue /= 4096.0     # 12-bit
        prescaleValue /= float(freq)
        prescaleValue -= 1.0  
        prescale = math.floor(prescaleValue + 0.5)
        oldmode = self._readByte(self._mode_adr)
        if oldmode == None:
            return
        newmode = (oldmode & 0x7F) | 0x10
        self._writeByte(self._mode_adr, newmode)
        self._writeByte(self._prescale_adr, int(math.floor(prescale)))
        self._writeByte(self._mode_adr, oldmode)
        time.sleep(0.005)
        self._writeByte(self._mode_adr, oldmode | 0x80)

    def setDuty(self, channel, duty):
        '''
        Sets a single PWM channel. The value is stored in the device.
        @param channel: one of the channels 0..15
        @param duty: the duty cycle 0..100
        '''
        data = int(duty * 4096 /100)  # 0..4096 (included)
        self._writeByte(self._base_adr_low + 4 * channel, data & 0xFF)
        self._writeByte(self._base_adr_high + 4 * channel, data >> 8)

    def _writeByte(self, reg, value):
        try:
            self.bus.write_byte_data(self.address, reg, value)
        except:
            print("Error while writing to I2C device")

    def _readByte(self, reg):
        try:
            result = self.bus.read_byte_data(self.address, reg)
            return result
        except:
            print("Error while Reading from I2C device")
            return None

调用方法简单:

import time
from smbus2 import SMBus
from pca9685 import PWM

freq = 50
addr = 0x40
channels = [0, 1, 2] 
a = 12.5
b = 2

bus = SMBus(1)
pwm = PWM(bus, addr)
pwm.setFreq(freq)

def setPos(channel, pos):
    duty = a / 180 * pos + b 
    pwm.setDuty(channel, duty)
    time.sleep(0.1)

while True:
    try:
        for pos in range(60, 120, 2):
            setPos(channels[0], pos)
            time.sleep(0.1)

        for pos in range(60, 120, 3):
            setPos(channels[1], pos)
            time.sleep(0.5)

        for pos in range(0, 90, 3):
            setPos(channels[2], pos)
            time.sleep(0.01)

    except KeyboardInterrupt:
        for i in channels:
            setPos(i, 0)
        break

OpenCV 通过颜色检测并控制:

import cv2
import time
import numpy as np
from pca9685 import PWM
from smbus2 import SMBus

freq = 50
addr = 0x40
ch1  = 0
ch2  = 1

bus = SMBus(1)
pwm = PWM(bus, addr)
pwm.setFreq(freq)

def setPos(channel, position):
    pwm.setDuty(channel, position)
    time.sleep(0.01)

def posMap(x, in_min, in_max, out_min, out_max):
    return int((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)

cap = cv2.VideoCapture(0)
cap.set(3, 320)
cap.set(4, 160)
ret, frame = cap.read()

cx = int(frame.shape[1] / 2)
center = int(frame.shape[1] / 2)
pos = 90

while True:
    ret, frame = cap.read()
    frame = cv2.flip(frame, 1)
    hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    ly = np.array([51, 0, 0])
    hy = np.array([180, 255, 255])

    mask = cv2.inRange(hsv_frame, ly, hy)
    contours, hir = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    contours = sorted(contours, key=lambda x: cv2.contourArea(x), reverse=True)
    # cv2.drawContours(frame, contours[1], -1, (0, 0, 255), 2)
    for cnt in contours[1:]:
        (x, y, w, h) = cv2.boundingRect(cnt)
        cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 255,0), 2)
        cx = int((x + x + w)/ 2)
        # cv2.drawContours(frame, cnt, -1, (0, 0, 255), 2)
        cv2.line(frame, (cx, 0), (cx, frame.shape[0]), (0, 0, 255), 1)
        if cx < center:
            pos -= 1.5
        elif cx > center:
            pos += 1.5  
        # pos = posMap(pos, 1, 480, 60, 120)
        setPos(ch1, pos)

        break
    # mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
    # hstack = np.hstack([mask, frame])
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()
setPos(ch1, 0)

总结

就是控制dutyCycle,频率肯定要50hz,一般的多级可能需要a, b函数作为微调。根据自己的舵机微调a和b的值。

可以尝试 a 设置8.5, b设置2

OpenWRT 在树莓派启用WiFi 如此简单!

登陆树莓派CM4, 如果发现wlan0找不到,无法初始化,就这样执行以下命令:

cd /lib/firmware/brcm
cp brcmfmac43455-sdio.raspberrypi,4-model-b.txt brcmfmac43455-sdio.raspberrypi,4-compute-module.txt
reboot

然后尝试改一下wifi-country的信息。

iw reg get 
iw reg set CN
iw reg get 
lsmod |grep brcmfmac

接着尝试用

iw dev
wifi status

看看状态。

uci show wireless

这里需要启用radio0, 并且把AP模式改成STA模式。

uci set wireless.radio0.disabled='0'
uci set wireless.default_radio0.mode='sta'
uci set wireless.default_radio0.network='wan'
uci show wireless

树莓派安装windows11 预览版遇到的问题总结

在最近发现windows11 预览版arm64位系统发布后,可以通过一个cmd的脚本生成需要的镜像,但是也会产生一个非常大容量的目录: MountUUP,应该是通过UUPtoISO生成的临时文件,非常巨大,包含了很多cab的包还有一些wim的东西,在执行删除的时候总是提示你需要trustinstaller的权限,无法删除,会占用大量磁盘,实际上是因为它挂载了一个镜像文件install.wim, 我想要删除它清空磁盘空间,找了一圈,发现可以通过先取消挂载然后再删除就顺利干掉了。
下面是一段网上查到的资料原文。
The following DISM command will look for stale mountpoints on all drives and (attempt to) unmount them:

DISM.exe /cleanup-wim

Or, you can do it manually:

DISM.exe /Unmount-WIM /mountdir=C:\MountUUP /discard

管理员打开cmd窗口,执行上述命令后删除相应目录即可。问题解决。

Ubuntu 上安装 Cacti 现在这么简单了么?

前言

最近讲监控, 又将很久以前的东西重新拾起来, 尝试在我的小 mac 上的虚拟机里面进行各种安装测试.

安装 SNMP

我以前的印象中,安装 snmp 需要用的软件包的名字是: net-snmp,但是在 ubuntu 上我发现,就直接安装snmp 和 snmpd 好像就行了.

   sudo apt-get -y install snmp snmpd 

安装 cacti

我之前的经验是需要安装一套 LAMP 架构.先.
但是发现 ubuntu 上面已经让我可以变得非常懒了, 直接一条命令就都给你安装上来了.

sudo apt-get -y install cacti

顺手更新了一把系统.

疑惑

官方网站上说 cacti 账户和密码默认是 admin,但是好像不行.真是折腾.
后来用了账户 admin,密码用的数据库的密码才正常登陆.

Mac OS 上虚拟机无法联网的临时修复方法记录

事情的起因

由于要上课,因此安装 centos8.3.2011一个短命的系统,但是网卡不好用.

实际的电脑信息

我电脑是:

然后我的 parallel 的虚拟机网卡不好用, 尝试联网各种失败,开机无法联网,CentOS 也不好用.

解决方法:

于是搜了半天, 尝试了半天,终于找到一个看似能用的方法:
->关闭所有VMS和Parallels Desktop-

打开终端并键入:sudo -b /Applications/Parallels\Desktop.app/Contents/MacOS/prl_client_app

总结:

Parallels将打开,也许您需要打开您的VM再次...网络将正常工作...
这是一个临时解决方案,而官方的并行支持不起作用..

浪派-造物志

何谓:浪派?

所谓浪派,其实是我和几个朋友一起搞的一个树莓派小车的项目,其核心内容是想在疫情期间无法面基就只好通过网络交互来实现原先的自由自造的折腾行为.其中涉及到原型设计,芯片选型,PCB设计,打样焊接,程序调试等一系列技术栈,在设计之初为了能够让大家都有参与进来的兴趣,还专门采用了kicad设计软件来进行pcb设计...参与的小伙伴各显神通,但是也遭遇过一些小小的滑铁卢...

回忆杀


未完待续,手机更新大拇指压力太大了....