라즈베리파이 피코 보드의 펌웨어실습을 위한 베이직 트레이닝보드를 소개 합니다.
현재 네이버 스마트스토어에서 판매가 진행되고 있습니다.
라즈베리파이 피코보드를 DIP 타입으로 사용성을 높인 도킹보드는 아래에서 판매 중입니다.
피코 베이직 트레이닝보드의 기능은 아래와 같습니다.
① DC 파워 홀더 : 5V 파워 잭을 결합하여 전원을 공급합니다.
② 보드 결합 핀 : 보드와 연결 할 수 있는 핀 헤더
③ OLED : 텍스트나 정보를 디스플레이 할 수 있는 OLED
④ 부저 : 주파수 신호로 소리를 나타낼 수 있습니다.
⑤ DHT11 센서 : 온도 습도를 측정하는 센서입니다.
⑥ LED : GPIO 신호 출력으로 ON OFF가 가능합니다.
⑦ SD CARD : SD CARD에 파일을 저장 할 수 있습니다.
⑧ BLE 모듈 : UART 통신으로 스마트폰과 무선 통신을 할 수 있습니다.
슬라이드 스위치를 이용하여 UART외부 컨넥터 및 블루투스를 이용한 제어가 가능합니다.
⑨ 외부 전원 인가 단자 : PWM을 외부 전원으로 사용하여 12V 모터와 12V LED를 컨트롤 할 수 있습니다.
점퍼소켓을 이용하여 외부전원 및 내부 5V전원을 사용 할 수 있습니다.
⑩ PWM 출력단자 : PWM 신호를 출력하는 단자입니다.
DC모터 속도제어 및 LED 밝제어를 할 수 있습니다.
⑪ CDS : 빛을 감지하는 센서 입니다.
⑫ 외부 모듈 연결핀: 외부 모듈을 사용하거나 I2C 확장 핀입니다.
⑬ 버튼 : 버튼 스위치이며 디지털 신호를 입력 할 수 있습니다 .
⑭ WS2812 : 풀컬러 LED 이며 통신으로 컨트롤 가능합니다.
⑮ 서보모터핀 : 서보모터를 사용할 수 있는 핀입니다.
⑯ 가변저항 : 가변되는 저항체로 분배법칙을 이용하여 전압을 조절합니다.(ADC 제어 실습 가능)
⑰ 릴레이 : 스위치와 같은 계념으로 5V신호를 이용하여 250V 10A까지 사용가능 합니다.
피코 베이직 트레이닝 보드는 피코 도킹보드를 이용하여 사용이 가능합니다.
- 피코보드의 핀맵 입니다.
* 헤더소켓이 앵글 커넥터 내장으로 실크와 실제 연결하는 부분이 반대로 되어있습니다.
이점을 유의하여 연결하여야 합니다.
피코 핀 맵 | 베이지트레이닝 보드 핀 맵 | 베이지트레이닝 보드 핀 맵 | 피고 핀 맵 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
GP0 / PWM1 GP1 / PWM2 GND GP2 / LED0 GP3 / LED1 GP4 GP5 GND GP6 / BUZZER GP7 / DHT11 GP8 / SDMISO GP9 / SDCS GND GP10 / SDCLK GP11 / SDMOSI GP12 / RELAY GP13 / WS2812 GND GP14 / SDA0 GP15 / SDL0 |
VBUS VSYS GND 3.3V_EN 3.3V_OUT ADC_REF GP28 GND GP27 / CdS GP26 / VR RUN / RESET GP22 / SW GND GP21 GP20 GP19 / SERVO1 GP18 / SERVO2 GND GP17 / RXD0 GP16 / TXD0 |
40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 |
- 라즈베리파이 피코 베이지 트레이닝보드 전체 기능제어 맛보기
아래의 코드를 이용하여 동영상의 구동 제어 실습을 할 수 있습니다.
main.py
from machine import UART, Pin, I2C, ADC, PWM,SPI
from time import sleep
import neopixel
import ssd1306
import dht
import sdcard
import uos
import random
led1 = Pin(2,Pin.OUT)
led2 = Pin(3,Pin.OUT)
relay = Pin(12,Pin.OUT)#릴레이 설정
CdS_adc = ADC(Pin(27))
vr_adc = ADC(Pin(26))
buzzer = PWM(Pin(6))
i2c = I2C(1,scl=Pin(15), sda=Pin(14))#I2C설정
oled = ssd1306.SSD1306_I2C(128,64,i2c,0x3c)#OLED설정
dhtIn = Pin(7,Pin.IN) # 온/습도 센서 설정
dhtOut = dht.DHT11(dhtIn)# 온/습도 센서 설정
uart0 = UART(0, baudrate=115200, bits=8, parity=None, stop=1, tx=Pin(16), rx=Pin(17))# UART 설정
uart0.write("pico sensorBoard Test\n")
swCount=0
def handle_interrupt(sw):
global swCount
swCount = swCount+1
if swCount==8:
swCount=0
sw = Pin(22,Pin.IN,Pin.PULL_UP)
sw.irq(trigger=Pin.IRQ_FALLING, handler=handle_interrupt)
CS = Pin(9, Pin.OUT)
spi = machine.SPI(1,baudrate=1000000,polarity=0,phase=0,bits=8,firstbit=SPI.MSB,sck=Pin(10),mosi=Pin(11),miso=Pin(8))
sd = sdcard.SDCard(spi,CS)
vfs = uos.VfsFat(sd)
uos.mount(vfs, '/sd')
print(uos.listdir('/sd'))
servo1_pwm = Pin(19, Pin.OUT)
servo2_pwm = Pin(18, Pin.OUT)
servo1 = PWM(servo1_pwm)
servo2 = PWM(servo2_pwm)
servo1.freq(50)
servo2.freq(50)
servo1.duty_u16(0)
servo2.duty_u16(0)
in_min =0
in_max =65535
out_min =1000
out_max =9000
out1 = Pin(20,Pin.OUT)
pwm_out1 = PWM(out1)
pwm_out1.freq(500)
pwm_out1.duty_u16(0)
out2 = Pin(21,Pin.OUT)
pwm_out2 = PWM(out2)
pwm_out2.freq(500)
pwm_out2.duty_u16(0)
oled.fill(1)
oled.show()
led1.value(0)
led2.value(0)
sleep(1)
oled.fill(0)
oled.show()
led1.value(1)
led2.value(1)
sleep(1)
##########################################################################################
#NEOPIXEL FUN
n =4# 네오픽셀 개체 수
p =13# 핀 번호
np = neopixel.NeoPixel(Pin(p),n)# 네오픽셀 설정
def set_color(r,g,b):
for i in range(n):
np[i] = (r,g,b)
np.write()
# bounce
def bounce(r, g, b, wait):
for i in range(2* n):
for j in range(n):
np[j] = (r, g, b)
if (i // n) % 2==0:
np[i % n] = (0, 0, 0)
else:
np[n -1- (i % n)] = (0, 0, 0)
np.write()
sleep(wait)
# cycle
def cycle(r, g, b, wait):
for i in range(n):
for j in range(n):
np[j] = (0, 0, 0)
np[i % n] = (r, g, b)
np.write()
sleep(wait)
def wheel(pos):
if pos <0or pos >255:
return (0, 0, 0)
if pos <85:
return (255- pos *3, pos *3, 0)
if pos <170:
pos -=85
return (0, 255- pos *3, pos *3)
pos -=170
return (pos *3, 0, 255- pos *3)
# rainbow
def rainbow_cycle(wait):
for j in range(255):
if swCount ==2:
for i in range(n):
if swCount ==2:
rc_index = (i *256// n) + j
np[i] = wheel(rc_index &255)
else: break
np.write()
sleep(wait)
else: break
# turn off all pixels
def clear():
for i in range(n):
np[i] = (0, 0, 0)
np.write()
##########################################################################################
tones = {
"B0": 31,"C1": 33,"CS1": 35,"D1": 37,"DS1": 39,"E1": 41,"F1": 44,"FS1": 46,
"G1": 49,"GS1": 52,"A1": 55,"AS1": 58,"B1": 62,"C2": 65,
"CS2": 69,"D2": 73,"DS2": 78,"E2": 82,"F2": 87,"FS2": 93,"G2": 98,
"GS2": 104,"A2": 110,"AS2": 117,"B2": 123,"C3": 131,"CS3": 139,
"D3": 147,"DS3": 156,"E3": 165,"F3": 175,"FS3": 185,
"G3": 196,"GS3": 208,"A3": 220,"AS3": 233,"B3": 247,"C4": 262,"CS4": 277,"D4": 294,"DS4": 311,
"E4": 330,"F4": 349,"FS4": 370,"G4": 392,"GS4": 415,"A4": 440,"AS4": 466,"B4": 494,"C5": 523,"CS5": 554,"D5": 587,"DS5": 622,"E5": 659,"F5": 698,
"FS5": 740,"G5": 784,"GS5": 831,"A5": 880,"AS5": 932,"B5": 988,"C6": 1047,"CS6": 1109,"D6": 1175,"DS6": 1245,"E6": 1319,"F6": 1397,"FS6": 1480,"G6": 1568,"GS6": 1661,
"A6": 1760,"AS6": 1865,"B6": 1976,"C7": 2093,"CS7": 2217,"D7": 2349,"DS7": 2489,"E7": 2637,"F7": 2794,"FS7": 2960,"G7": 3136,"GS7": 3322,"A7": 3520,
"AS7": 3729,"B7": 3951,"C8": 4186,"CS8": 4435,"D8": 4699,"DS8": 4978
}
song = ["E5","G5","A5","P","E5","G5","B5","A5","P","E5","G5","A5","P","G5","E5"]
mario = ["E7", "E7", 0, "E7", 0, "C7", "E7", 0, "G7", 0, 0, 0, "G6", 0, 0, 0, "C7", 0, 0, "G6",
0, 0, "E6", 0, 0, "A6", 0, "B6", 0, "AS6", "A6", 0, "G6", "E7", 0, "G7", "A7", 0, "F7", "G7",
0, "E7", 0,"C7", "D7", "B6", 0, 0, "C7", 0, 0, "G6", 0, 0, "E6", 0, 0, "A6", 0, "B6", 0,
"AS6", "A6", 0, "G6", "E7", 0, "G7", "A7", 0, "F7", "G7", 0, "E7", 0,"C7", "D7", "B6", 0, 0]
def playtone(frequency):
buzzer.duty_u16(30000)
buzzer.freq(frequency)
def bequiet():
buzzer.duty_u16(0)
def playsong(mysong):
for i in range(len(mysong)):
if swCount ==1:
if (mysong[i] =="P"or mysong[i] ==0 ):
bequiet()
else:
playtone(tones[mysong[i]])
else: break
sleep(0.2)
bequiet()
temp=0
humi=0
def tempHumiSensor():
global temp, humi
dhtOut.measure()
temp = dhtOut.temperature()
humi = dhtOut.humidity()
sleep(0.5)
VRData=0
def adcInput(ch):
global VRData
if ch ==0: #VR
VRData = vr_adc.read_u16()
VRDataV = (3.3/65535) * VRData
VRDataV = round(VRDataV,2)
return VRDataV
elif ch ==1: #CdS
CdSData = CdS_adc.read_u16()
CdSDataV = (3.3/65535) * CdSData
CdSDataV = round(CdSDataV,2)
return CdSDataV
#file = open("/sd/sample1.txt","w")
#file.write("SDCARD DATA TEST\n")
#file.close()
def sdcardwrite():
led2.value(0)
file=open("/sd/sample1.txt","a")
file.write("{:>5d} Temperature : {:.0f}C Humidity : {:.0f}% VRVolt : {:.2f}V CdSVolt : {:.2f}V RELAY : {}\r\n".format(num, temp, humi, adcInput(0),adcInput(1),relayState))
file.close()
led2.value(1)
##########################################################################################
num=1
relayState=0
whileTrue:
print(uart0.readline())
tempHumiSensor()
print('Temperature = {:<05.2f}C Humidity = {:.2f}%'.format(temp,humi))
print('CdS Volt = {:<05.2f}V VR Volt = {:.2f}V'.format(adcInput(0),adcInput(1)))
print('SW COUNTER = {0}\n'.format(swCount))
vrInput = adcInput(0)
cdsInput = adcInput(1)
if cdsInput <=1:
relay.off() #relay on
relayState=1
else:
relay.on() #relay off
relayState=0
uart0.write("temp : ")
uart0.write(str(temp))
uart0.write('C')
uart0.write(" Humi : ")
uart0.write(str(humi))
uart0.write('%')
uart0.write(" CdSV : ")
uart0.write(str(cdsInput))
uart0.write('V')
uart0.write(" VR_V : ")
uart0.write(str(vrInput))
uart0.write('V')
uart0.write(" SW COUNTER : ")
uart0.write(str(swCount))
uart0.write('\n')
oled.fill(0)
oled.text("Temp(C) : ",0,0)
oled.text(str(temp),80,0)
oled.text("Humi(%) : ",0,12)
oled.text(str(humi),80,12)
oled.text("CdS(V) : ",0,24)
oled.text(str(cdsInput),80,24)
oled.text("VR(V) : ",0,36)
oled.text(str(vrInput),80,36)
if swCount==1:
oled.text("SW : ",0,48)
oled.text(str(swCount),40,48)
oled.text("(BUZZER)",50,48)
elif swCount==2:
oled.text("SW : ",0,48)
oled.text(str(swCount),40,48)
oled.text("(WS2812)",50,48)
elif swCount==3:
oled.text("SW : ",0,48)
oled.text(str(swCount),40,48)
oled.text("(SERVO1)",50,48)
elif swCount==4:
oled.text("SW : ",0,48)
oled.text(str(swCount),40,48)
oled.text("(SERVO2)",50,48)
elif swCount==5:
oled.text("SW : ",0,48)
oled.text(str(swCount),40,48)
oled.text("(PWM1)",50,48)
elif swCount==6:
oled.text("SW : ",0,48)
oled.text(str(swCount),40,48)
oled.text("(PWM2)",50,48)
elif swCount==7:
oled.text("SW : ",0,48)
oled.text(str(swCount),40,48)
oled.text("(SDCARD)",50,48)
else:
oled.text("SW : ",0,48)
oled.text(str(swCount),40,48)
oled.show()
if swCount==1:
led1.value(0)
playsong(mario)
led1.value(1)
elif swCount==2:
led1.value(0)
rainbow_cycle(0.01)
clear()
led1.value(1)
elif swCount==3:
servo1Data = (VRData - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
servo1.duty_u16(int(servo1Data))
elif swCount==4:
servo2Data = (VRData - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
servo2.duty_u16(int(servo2Data))
elif swCount==5:
pwm_out1.duty_u16(VRData)
elif swCount==6:
pwm_out2.duty_u16(VRData)
elif swCount==7:
sdcardwrite()
num = num +1
if num ==101:
led2.value(0)
file=open("/sd/sample1.txt","a")
file.write("\r\n")
file.close()
led2.value(1)
num=1
else:
servo1.duty_u16(0)
servo2.duty_u16(0)
pwm_out1.duty_u16(0)
pwm_out2.duty_u16(0)
sleep(0.5)
ssd1306.py
from micropython import const
import framebuf
# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xA4)
SET_NORM_INV = const(0xA6)
SET_DISP = const(0xAE)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xA0)
SET_MUX_RATIO = const(0xA8)
SET_IREF_SELECT = const(0xAD)
SET_COM_OUT_DIR = const(0xC0)
SET_DISP_OFFSET = const(0xD3)
SET_COM_PIN_CFG = const(0xDA)
SET_DISP_CLK_DIV = const(0xD5)
SET_PRECHARGE = const(0xD9)
SET_VCOM_DESEL = const(0xDB)
SET_CHARGE_PUMP = const(0x8D)
class SSD1306(framebuf.FrameBuffer):
def __init__(self, width, height, external_vcc):
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):
for cmd in (
SET_DISP, # display off
# address setting
SET_MEM_ADDR,
0x00, # horizontal
# resolution and layout
SET_DISP_START_LINE, # start at line 0
SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
SET_MUX_RATIO,
self.height - 1,
SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
SET_DISP_OFFSET,
0x00,
SET_COM_PIN_CFG,
0x02 if self.width > 2 * self.height else 0x12,
# timing and driving scheme
SET_DISP_CLK_DIV,
0x80,
SET_PRECHARGE,
0x22 if self.external_vcc else 0xF1,
SET_VCOM_DESEL,
0x30, # 0.83*Vcc
# display
SET_CONTRAST,
0xFF, # maximum
SET_ENTIRE_ON, # output follows RAM contents
SET_NORM_INV, # not inverted
SET_IREF_SELECT,
0x30, # enable internal IREF during display on
# charge pump
SET_CHARGE_PUMP,
0x10 if self.external_vcc else 0x14,
SET_DISP | 0x01, # display on
): # on
self.write_cmd(cmd)
self.fill(0)
self.show()
def poweroff(self):
self.write_cmd(SET_DISP)
def poweron(self):
self.write_cmd(SET_DISP | 0x01)
def contrast(self, contrast):
self.write_cmd(SET_CONTRAST)
self.write_cmd(contrast)
def invert(self, invert):
self.write_cmd(SET_NORM_INV | (invert & 1))
def rotate(self, rotate):
self.write_cmd(SET_COM_OUT_DIR | ((rotate & 1) << 3))
self.write_cmd(SET_SEG_REMAP | (rotate & 1))
def show(self):
x0 = 0
x1 = self.width - 1
if self.width != 128:
# narrow displays use centred columns
col_offset = (128 - self.width) // 2
x0 += col_offset
x1 += col_offset
self.write_cmd(SET_COL_ADDR)
self.write_cmd(x0)
self.write_cmd(x1)
self.write_cmd(SET_PAGE_ADDR)
self.write_cmd(0)
self.write_cmd(self.pages - 1)
self.write_data(self.buffer)
class SSD1306_I2C(SSD1306):
def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False):
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
self.write_list = [b"\x40", None] # Co=0, D/C#=1
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.temp[0] = 0x80 # Co=1, D/C#=0
self.temp[1] = cmd
self.i2c.writeto(self.addr, self.temp)
def write_data(self, buf):
self.write_list[1] = buf
self.i2c.writevto(self.addr, self.write_list)
class SSD1306_SPI(SSD1306):
def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
self.rate = 10 * 1024 * 1024
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(1)
self.res(0)
time.sleep_ms(10)
self.res(1)
super().__init__(width, height, external_vcc)
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)
def write_data(self, buf):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(buf)
self.cs(1)
dht.py
import sys
if sys.platform.startswith("esp"):
from esp import dht_readinto
elif sys.platform == "mimxrt":
from mimxrt import dht_readinto
elif sys.platform == "rp2":
from rp2 import dht_readinto
elif sys.platform == "pyboard":
from pyb import dht_readinto
else:
from machine import dht_readinto
class DHTBase:
def __init__(self, pin):
self.pin = pin
self.buf = bytearray(5)
def measure(self):
buf = self.buf
dht_readinto(self.pin, buf)
if (buf[0] + buf[1] + buf[2] + buf[3]) & 0xFF != buf[4]:
raise Exception("checksum error")
class DHT11(DHTBase):
def humidity(self):
return self.buf[0]
def temperature(self):
return self.buf[2]
class DHT22(DHTBase):
def humidity(self):
return (self.buf[0] << 8 | self.buf[1]) * 0.1
def temperature(self):
t = ((self.buf[2] & 0x7F) << 8 | self.buf[3]) * 0.1
if self.buf[2] & 0x80:
t = -t
return t
sdcard.py
from micropython import const
import time
_CMD_TIMEOUT = const(100)
_R1_IDLE_STATE = const(1 << 0)
# R1_ERASE_RESET = const(1 << 1)
_R1_ILLEGAL_COMMAND = const(1 << 2)
# R1_COM_CRC_ERROR = const(1 << 3)
# R1_ERASE_SEQUENCE_ERROR = const(1 << 4)
# R1_ADDRESS_ERROR = const(1 << 5)
# R1_PARAMETER_ERROR = const(1 << 6)
_TOKEN_CMD25 = const(0xFC)
_TOKEN_STOP_TRAN = const(0xFD)
_TOKEN_DATA = const(0xFE)
class SDCard:
def __init__(self, spi, cs, baudrate=1320000):
self.spi = spi
self.cs = cs
self.cmdbuf = bytearray(6)
self.dummybuf = bytearray(512)
self.tokenbuf = bytearray(1)
for i in range(512):
self.dummybuf[i] = 0xFF
self.dummybuf_memoryview = memoryview(self.dummybuf)
# initialise the card
self.init_card(baudrate)
def init_spi(self, baudrate):
try:
master = self.spi.MASTER
except AttributeError:
# on ESP8266
self.spi.init(baudrate=baudrate, phase=0, polarity=0)
else:
# on pyboard
self.spi.init(master, baudrate=baudrate, phase=0, polarity=0)
def init_card(self, baudrate):
# init CS pin
self.cs.init(self.cs.OUT, value=1)
# init SPI bus; use low data rate for initialisation
self.init_spi(100000)
# clock card at least 100 cycles with cs high
for i in range(16):
self.spi.write(b"\xff")
# CMD0: init card; should return _R1_IDLE_STATE (allow 5 attempts)
for _ in range(5):
if self.cmd(0, 0, 0x95) == _R1_IDLE_STATE:
break
else:
raise OSError("no SD card")
# CMD8: determine card version
r = self.cmd(8, 0x01AA, 0x87, 4)
if r == _R1_IDLE_STATE:
self.init_card_v2()
elif r == (_R1_IDLE_STATE | _R1_ILLEGAL_COMMAND):
self.init_card_v1()
else:
raise OSError("couldn't determine SD card version")
# get the number of sectors
# CMD9: response R2 (R1 byte + 16-byte block read)
if self.cmd(9, 0, 0, 0, False) != 0:
raise OSError("no response from SD card")
csd = bytearray(16)
self.readinto(csd)
if csd[0] & 0xC0 == 0x40: # CSD version 2.0
self.sectors = ((csd[8] << 8 | csd[9]) + 1) * 1024
elif csd[0] & 0xC0 == 0x00: # CSD version 1.0 (old, <=2GB)
c_size = csd[6] & 0b11 | csd[7] << 2 | (csd[8] & 0b11000000) << 4
c_size_mult = ((csd[9] & 0b11) << 1) | csd[10] >> 7
self.sectors = (c_size + 1) * (2 ** (c_size_mult + 2))
else:
raise OSError("SD card CSD format not supported")
# print('sectors', self.sectors)
# CMD16: set block length to 512 bytes
if self.cmd(16, 512, 0) != 0:
raise OSError("can't set 512 block size")
# set to high data rate now that it's initialised
self.init_spi(baudrate)
def init_card_v1(self):
for i in range(_CMD_TIMEOUT):
self.cmd(55, 0, 0)
if self.cmd(41, 0, 0) == 0:
self.cdv = 512
# print("[SDCard] v1 card")
return
raise OSError("timeout waiting for v1 card")
def init_card_v2(self):
for i in range(_CMD_TIMEOUT):
time.sleep_ms(50)
self.cmd(58, 0, 0, 4)
self.cmd(55, 0, 0)
if self.cmd(41, 0x40000000, 0) == 0:
self.cmd(58, 0, 0, 4)
self.cdv = 1
# print("[SDCard] v2 card")
return
raise OSError("timeout waiting for v2 card")
def cmd(self, cmd, arg, crc, final=0, release=True, skip1=False):
self.cs(0)
# create and send the command
buf = self.cmdbuf
buf[0] = 0x40 | cmd
buf[1] = arg >> 24
buf[2] = arg >> 16
buf[3] = arg >> 8
buf[4] = arg
buf[5] = crc
self.spi.write(buf)
if skip1:
self.spi.readinto(self.tokenbuf, 0xFF)
# wait for the response (response[7] == 0)
for i in range(_CMD_TIMEOUT):
self.spi.readinto(self.tokenbuf, 0xFF)
response = self.tokenbuf[0]
if not (response & 0x80):
# this could be a big-endian integer that we are getting here
for j in range(final):
self.spi.write(b"\xff")
if release:
self.cs(1)
self.spi.write(b"\xff")
return response
# timeout
self.cs(1)
self.spi.write(b"\xff")
return -1
def readinto(self, buf):
self.cs(0)
# read until start byte (0xff)
for i in range(_CMD_TIMEOUT):
self.spi.readinto(self.tokenbuf, 0xFF)
if self.tokenbuf[0] == _TOKEN_DATA:
break
time.sleep_ms(1)
else:
self.cs(1)
raise OSError("timeout waiting for response")
# read data
mv = self.dummybuf_memoryview
if len(buf) != len(mv):
mv = mv[: len(buf)]
self.spi.write_readinto(mv, buf)
# read checksum
self.spi.write(b"\xff")
self.spi.write(b"\xff")
self.cs(1)
self.spi.write(b"\xff")
def write(self, token, buf):
self.cs(0)
# send: start of block, data, checksum
self.spi.read(1, token)
self.spi.write(buf)
self.spi.write(b"\xff")
self.spi.write(b"\xff")
# check the response
if (self.spi.read(1, 0xFF)[0] & 0x1F) != 0x05:
self.cs(1)
self.spi.write(b"\xff")
return
# wait for write to finish
while self.spi.read(1, 0xFF)[0] == 0:
pass
self.cs(1)
self.spi.write(b"\xff")
def write_token(self, token):
self.cs(0)
self.spi.read(1, token)
self.spi.write(b"\xff")
# wait for write to finish
while self.spi.read(1, 0xFF)[0] == 0x00:
pass
self.cs(1)
self.spi.write(b"\xff")
def readblocks(self, block_num, buf):
nblocks = len(buf) // 512
assert nblocks and not len(buf) % 512, "Buffer length is invalid"
if nblocks == 1:
# CMD17: set read address for single block
if self.cmd(17, block_num * self.cdv, 0, release=False) != 0:
# release the card
self.cs(1)
raise OSError(5) # EIO
# receive the data and release card
self.readinto(buf)
else:
# CMD18: set read address for multiple blocks
if self.cmd(18, block_num * self.cdv, 0, release=False) != 0:
# release the card
self.cs(1)
raise OSError(5) # EIO
offset = 0
mv = memoryview(buf)
while nblocks:
# receive the data and release card
self.readinto(mv[offset : offset + 512])
offset += 512
nblocks -= 1
if self.cmd(12, 0, 0xFF, skip1=True):
raise OSError(5) # EIO
def writeblocks(self, block_num, buf):
nblocks, err = divmod(len(buf), 512)
assert nblocks and not err, "Buffer length is invalid"
if nblocks == 1:
# CMD24: set write address for single block
if self.cmd(24, block_num * self.cdv, 0) != 0:
raise OSError(5) # EIO
# send the data
self.write(_TOKEN_DATA, buf)
else:
# CMD25: set write address for first block
if self.cmd(25, block_num * self.cdv, 0) != 0:
raise OSError(5) # EIO
# send the data
offset = 0
mv = memoryview(buf)
while nblocks:
self.write(_TOKEN_CMD25, mv[offset : offset + 512])
offset += 512
nblocks -= 1
self.write_token(_TOKEN_STOP_TRAN)
def ioctl(self, op, arg):
if op == 4: # get number of blocks
return self.sectors
* main.py, ssd1306.py, dht.py, sdcard.py 모듈을 Pico 보드에 넣으면 됩니다.
* Thonny 프로그램에서의 F5 또는 재생 버튼을 누르면 보드의 각 기능을 체크할 수 있습니다.
'제품소개' 카테고리의 다른 글
아두이노 초음파센서 제어(HC-SR04) (0) | 2023.06.19 |
---|---|
인두기 팁 클리너 스펀지 (0) | 2023.06.19 |
USB to RS485 / Arduino Download / ESP32 Download (0) | 2023.06.19 |
I2C or RS485 to 릴레이 4채널 제어모듈 / DIN 레일 커넥터 내장 (0) | 2023.05.26 |
멀티컬러 LED(전원 인가시 멀티컬러 변경) (0) | 2023.03.03 |
댓글