Attiny85 초소형 아두이노 개발보드

 

ATTiny85 기반 초소형 MCU인 Digispark입니다. digistump.com 사이트에서 정보를 찾아 사용했었는데 사이트 접속이 되질 않습니다.

 

정보를 찾아본 후 세팅(윈도우 11 23H2, Arduino IDE 2.3.2)을 해 보며 방법을 기록해봅니다.

 

2024년 4월 첫 번째 주 기준입니다.

 

자동으로 드라이버가 잡히는 경우도 있고 오류가 날 경우 https://technical.swissmicros.com/doc/libusb_install/libusb_install.html 이 사이트를 참조해 드라이버를 다운받아 설치해줍니다.

 

Arduino IDE의 File->Preference 를 열고 Settings 탭의 Additional boards manager URLs:http://drazzy.com/package_drazzy.com_index.json 를 입력하고 OK 버튼을 누릅니다.

 

Tools->Board->Boards Manager(Ctrl-Shift-B) 를 선택 후 Type를 Contributed로 바꾸고 ATTinyCore 를 설치(INSTALL) 합니다.

 

Tools->Board->ATTinyCore에서 ATtiny85(Micronucles / Digispark)를 선택합니다.

 

이 MCU는 자동으로 USB Port를 잡아주질 않으므로(libusb-win32 devices / Digispark Bootloader로 잡힙니다) Tools->Port->COM1을 선택합니다.

 

내장 LED를 1초 간격으로 깜빡이는 코드를 넣어 테스트 해 봅니다.

void setup() {
  // put your setup code here, to run once:
  // pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  // digitalWrite(0, HIGH);
  digitalWrite(1, HIGH);
  delay(1000);
  // digitalWrite(0, LOW);
  digitalWrite(1, LOW);
  delay(1000);
}

 

업로드(MCU연결을 끊고 업로드 후 60초내에 연결하라믄 메시지가 나오면 MCU를 연결합니다) 해 보면 잘 작동하는것을 알 수 있습니다.

많은 유저가 있는 debian이나 ubuntu의 경우엔 apt를 이용해 편하게 설치할 수 있지만 Archlinux는 검색해보니 좀 다릅니다. 제 경우엔 익숙해서 archlinux를 이용하고 있습니다.

Thonny를 설치하는 방법중 하나로 snapd 패키지 관리자를 이용합니다.

snapd 및 Thonny 설치

git이 설치되어 있다는 가정하에 시작합니다.

$ git clone https://aur.archlinux.org/snapd.git
$ cd snapd
$ makepkg -si
$ sudo systemctl enable --now spand.socket
$ sudo ln -s /var/lib/snapd/snap /snap

 

snap설정이 될때까지 약간의 시간이 필요할 수 있습니다.

$ sudo snap install thonny

 

snap 설정 및 업그레이드 후 thonny 가 설치됩니다. 제 노트북에서는 대략 5분정도 걸렸습니다.

esptool 설치

$ sudo pacman -S esptool
$ esptool.py

 

설치 후 Thonny를 실행하고 기본 세팅(폰트설정 등)을 마친 후 MCU를 연결해 하단에서 MCU를 선택해주면 됩니다.

$ sudo thonny

기본 설정 후 우측하단을 클릭해보면 연결된 MCU가 나타납니다.
예를들면 제 경우엔 MicroPython (ESP8266) - USB Serial @ /dev/ttyUSB0

https://ko.aliexpress.com/item/1005006365878568.html

  • WiFi 개발보드, 4MB
  • 11 디지털 입력/출력 핀, 모든 핀에 인터럽트/pwm/I2C/one-wire 지원(D0 제외)
  • 1 아날로그 입력 (3.3V 최대입력)
  • Type-C or micro USB 연결

알리 익스프레스를 뒤적거리다 천원마트를 통해 2,500원(2024년 3월말 기준)에 구매한 MCU입니다. 블루투스까지는 필요가 없는 작은 프로젝트에 이용해보면 어떨까 해서 구매했습니다.

납땜이 되어 오질 않기 때문에 납땜을 해야 합니다. 핀헤더는 다양하게 포함되어 있어 응용하기 좋습니다.

연결

PC에 연결 후 CH340으로 잡힙니다. 저는 이미 드라이버가 설치되어 있어 바로 잡혔고 드라이버가 없다면 설치해주셔야 합니다. (24년 4월 9일 : 테스트해보니 Windows 11 에서는 자동으로 잡힙니다)

CH340 Driver

 

CH341SER.ZIP - 南京沁恒微电子股份有限公司

USB转串口Windows驱动和DLL库,支持CH340和CH341,内含非标准波特率的设置等使用说明,支持USB转UART的3线和9线SERIAL串口。支持32/64位Windows 11/10/8.1/8/7/VISTA/XP,SERVER 2022/2019/2016/2012/2008/2003,2000/ME/98,

www.wch.cn

 

CH340 Driver

 

최근 MicroPython을 이용해보려고 노력중이라 MicroPython을 기준으로 기록합니다.
Thonny를 실행 후 IDE하단에서 MCU를 선택하면 MicroPython용 펌웨어가 없다고 표시됩니다.

 

bootloader error

펌웨어 업로드

펌웨어 업로드를 위해 esptool이 필요하고 미리 설치되어 있지 않다면 설치 합니다.

pip install esptool

 

esptool.py를 이용해 연결된 디바이스의 flash메모리를 지웁니다.
Thonny를 사용중이면 메뉴중 Tools - Open system shell 메뉴를 선택해 쉘을 연 후

esptool --port /dev/ttyUSB0 erase_flash
# windows
esptool --port COM4 erase_flash

 

펌웨어를 다운로드 하고 MCU에 업로드 합니다.

https://docs.micropython.org/en/latest/esp8266/tutorial/intro.html#deploying-the-firmware

 

1. Getting started with MicroPython on the ESP8266 — MicroPython latest documentation

Be aware of and try to exclude hardware problems. There are 2 common problems: bad power source quality and worn-out/defective FlashROM. Speaking of power source, not just raw amperage is important, but also low ripple and noise/EMI in general. If you expe

docs.micropython.org

esptool --port COM4 --baud 115200 write_flash --flash_size=detect 0 ESP8266_GENERIC-20240222-v1.22.2.bin

 

업로드가 잘 되었는지 확인 후 Thonny를 실행하면 하단 Shell에 Python 인터프리터가 보여집니다. 간단히 아래 코드를 실행해 정상작동 하는지 확인합니다.

print("Hello, world")

 

esp-12f hello world

테스트

WiFi를 통해 웹페이지에 Hello, world! 를 표시하는 코드를 작성해 테스트해봅니다. ssid에 사용하시는 공유기의 SSID를 넣고 password를 넣어 저장한 후 Thonny를 통해 업로드 합니다.

html = """<!DOCTYPE html>
<html>
    <head> <title>ESP8266 Test</title> </head>
    <body> <h1>Hello, world!</h1>
    </body>
</html>
"""

response = 'HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n'
ssid = 'xxxxxxxx'
password = 'xxxxxxxx'

import network

wifistation = network.WLAN(network.STA_IF)
wifistation.active(True)
wifistation.connect(ssid, password)

print('Connected to : ', wifistation.ifconfig()[0])

import socket

address = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

s = socket.socket()
s.bind(address)
s.listen(1)

conn, address = s.accept()
conn.send(response)
conn.send(html)
conn.close()

 

업로드 후 MCU를 리셋(Thonny에서 소프트리셋을 해줍니다)하면 Shell에 공유기로부터 부여받은 주소가 나옵니다. 웹브라우저(크롬, 엣지등)를 열어 주소에 Shell에 나온 주소를 입력하고 엔터를 누르면 Hello, world! 가 출력되고 MCU의 동작이 멈추게 됩니다.

 

물론 이 부분은 루프처리를 해서 WiFi 네트워크에 접속을 하고 사용자 반응을 대기를 하는 방식으로 처리를 해야 하지만 여기에서는 동작확인만 해 본 상태입니다.

 

저렴한 장비이지만 잘 작동합니다.

 

이제 이 장비를 이용해 다른 작업을 해 봐야겠습니다.

MCU의 정보들을 보여주기 위한 방법들이 여러가지 있습니다. 그중 저렴한 OLED 제품들이 오픈마켓이나 알리등을 통해 저렴하게 구매할 수 있었습니다. 꽤 밝고 선명해서 사용하기 편리합니다.

 

일단 테스트를 위해 여러가지를 구매해서 사용해보는 중이고 이 글에서는 128x32 (0.91인치) 제품을 이용해봅니다. MCU는 DOIT ESP32 Devkit V1을 사용했습니다. ESP32 WROOM 계열 제품이면 비슷하게 작동될것으로 보입니다.

0.91인치 128x32 OLED Display
DOIT ESP32 Devkit V1

OLED에 신호를 보내는 방법은 여러가지가 있을 수 있으나 여기서는 I2C(Hardware)방식을 이용합니다.

 

 

 

핀배열을 위 그림과 같고 I2C 통신을 이용하려면 D21(I2C_SDA)을 OLED의 SDA와 연결하고 D22(I2C_SCL)을 OLED의 SCL(간혹 제품에 SCK로 표시된 경우도 있음)과 연결합니다. OLED의 전원은 3.3V~5V까지 지원되므로 VCC와 GND(Ground)에 적절한 전원을 연결해 줍니다.

 

OLED제품을 이용하려면 모듈이 필요한데 SSD1306을 다운로드 받아 main.py와 동일한 위치에 넣어놓고 함께 업로드 되어야 합니다.

 

ESP32를 PC와 연결 후 다음 코드(main.py)를 업로드 하고(물론 MicroPython을 사용하기 위한 펌웨어 업로드 등의 전 작업이 미리 되어 있어야 합니다) EN키를 누르며 Boot키를 눌러 MCU를 재기동 하면 OLED 상단에 Hello, World! 가 출력됩니다.

 

from machine import Pin, I2C
import ssd1306

i2c = I2C(sda=Pin(21), scl=Pin(22))
display = ssd1306.SSD1306_I2C(128, 32, i2c)

display.text('Hello, World!', 0, 0, 1)
display.show()

 

SSD1306 모듈에 다양한 기능이 있으니 레퍼런스를 참고하면 다양하게 제어할 수 있습니다. 아두이노를 사용할때는 u8g2라는 라이브러리로 사용했었습니다.

기본 폰트의 크기는 8x8로 화면 가득 채우면 16x4개의 문자를 사용할 수 있습니다.

 

 

이미지 출력

이 OLED는 단일색상이므로 이미지는 BW로 만들어야 합니다. 보통 이미지 파일을 만들어 함께 업로드 해 읽어 처리하거나 이미지를 List로 만들어 main.py내에 포함시켜 처리하게 됩니다.

간단하게 List를 이용해 봅니다. 아래 이미지는 구글 검색을 통해 나온것으로 핀터레스트에 있는 이미지 입니다.

 

 

이 이미지를 List로 만들어 보면 다음처럼 표현할 수 있습니다.

from machine import Pin, I2C
import ssd1306

i2c = I2C(sda=Pin(21), scl=Pin(22))
display = ssd1306.SSD1306_I2C(128, 32, i2c)

MARIO = [
    [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0],
    [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
    [0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
    [0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
    [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0],
    [0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0],
    [0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0],
    [0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0],
    [0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],
    [0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1],
    [0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
    [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
    [0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
    [0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0],
    [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0],
    [1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0],
    [1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0],
    [1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0],
    [0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0],
    [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
    [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
    [0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1],
    [0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1],
    [0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0],
    [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0],
    [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0],
]

display.fill(0) # 화면지우기
for y, row in enumerate(MARIO):
    for x, c in enumerate(row):
        display.pixel(x, y, c)

display.show()

 

0인 부분은 건너뛰고 1인 부분에 픽셀을 찍어 OLED 화면 좌측 상단에 마리오 그림이 보여집니다. 물론 bit단위로 처리를 해야 효율적이겠지만 간단히 구조를 이해해보기 편한 방법으로 해봤습니다.

Autohotkey를 자주 이용하면서 컴퓨터 자원을 최대한 활용해보기 위해 CPU사용량을 알아보고 싶었습니다. 여기저기 검색을 하던 중 reddit에서 이런 방법을 추천하는걸 찾았습니다.

MsgBox, % GetCpuLoad()


GetCpuLoad(period := 500) {
 total := GetSystemTimes(idle)
 Sleep, % period
 total2 := GetSystemTimes(idle2)
 Return 100*(1 - (idle2 - idle)/(total2 - total))
}

GetSystemTimes(ByRef IdleTime) {
 DllCall("GetSystemTimes", "Int64P", IdleTime, "Int64P", KernelTime, "Int64P", UserTime)

 Return KernelTime + UserTime
}

일단 작동에 문제는 없으나 작업관리자에 나온값과 실시간으로는 차이가 좀 있어 보입니다만 이 정도면 충분히 사용할만 하다고 생각되어 좀 더 깔끔한 코드를 찾아보았습니다.

Loop{
 ToolTip % CPULoad() "`n" 
 Sleep 1000
}

; CPULoad ===========================================================================
CPULoad(){
 static PIT, PKT, PUT

 if (Pit = "")
 {
     return 0, DllCall("GetSystemTimes", "Int64P", PIT, "Int64P", PKT, "Int64P", PUT)
 }

 DllCall("GetSystemTimes", "Int64P", CIT, "Int64P", CKT, "Int64P", CUT)
 IdleTime := PIT - CIT, KernelTime := PKT - CKT, UserTime := PUT - CUT
 SystemTime := KernelTime + UserTime

 return ((SystemTime - IdleTime) * 100) // SystemTime, PIT := CIT, PKT := CKT, PUT := CUT
}

응용을 잘 해봐야겠네요.

트위터를 보다가 소개된 5분안에 간단히 go 언어에 대해 알아보기

 

쭉 훑어보기 좋음

 

gist.github.com/prologic/5f6afe9c1b98016ca278f4d507e65510

 

Learn Go in ~5mins

Learn Go in ~5mins. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

i7-3770 / 1880 | E5-1650 / 1740 | Ryzen 3600 / 5310 | i5-9500 / 2670 | i3-4130 / 890 | i5-4690 / 1400 | Ryzen 3300X / 4420 (Normal) | Ryzen 2600 / 3390 | i5-8400 / 2430

 

 

 

 

 

일반적으로 USB 메모리를 UEFI 부팅을 통해 PE와 같은 이미지로 가능하게 하는것은 Rufus를 이용하는것이 유리함

 

외장 HDD(SSD)는 Rufus에서는 인식이 되질 않아 직접 부팅 영역을 구성

 

외장 HDD 파티션 구성

 

관리자권한으로 PowerShell이나 cmd 실행

 

C:\.....>diskpart

 

DISKPART>list disk 혹은 디스크관리를 통해 외장 HDD의 디스크 번호를 확인(확인된 번호가 5번이라면)

 

DISKPART>select disk 5 (sel disk 5로 줄여도 됨)

 

DISKPART>clean (디스크의 구성된 파티션등을 모두 삭제)

 

DISKPART>convert GPT (디스크를 GPT로 변경)

 

DISKPART>create partition EFI size=100 (100MB EFI 파티션을 생성)

 

DISKPART>format quick fs=fat32 label=EFI (fat32로 빠른 포맷을 하고 EFI라는 라벨명을 붙임)

 

DISKPART>assign letter=O (EFI 파티션을 O 드라이브로 할당, 구성중인 PC의 드라이브명과 겹치지 않게)

 

DISKPART>create partition primary (윈도우를 설치할 주 파티션을 생성)

 

DISKPART>format quick fs=NTFS label=WTG (주 파티션을 NTFS 형식으로 빠른 포맷 후 라벨명 지정)

 

DISKPART>assign letter=P (주 파티션을 P 드라이브로 할당)

 

DISKPART>attribute volumn set NODEFAULTDRIVELETTER

 

DISKPART>list part (이 명령을 통해 구성된 내용의 확인이 가능)

 

DISKPART>exit

 

윈도우 구성

 

imagex.exe 프로그램을 구하고 윈도우 원본의 SOURCES 폴더내의 install.wim 파일을 동일 폴더에 넣어 놓고

 

C:\....>imagex /apply install.wim 1 p:\ (wim 이미지를 만들어둔 주 파티션에 풀어냄)

 

이후 EFI 파티션에 부팅에 필요한 파일과 정보를 넣어줌

 

C:\...>bcdboot p:\Windows /s g: /f UEFI

 

이후 PC 부팅시 이 USB를 선택하면 WTG로 부팅되고 최초 실행시 윈도우 초기 설치시와 같은 기본 세팅 진행.

+ Recent posts