m 밀리 (milli) 1mm (미리미터)
μ 마이크로 (micro) 머리카락 굵기 정도
n 나노 (nano) DNA 분자 크기 수준
p 피코 (pico) 원자 크기 수준
LED 속에 커다란게 -임
PNP트랜지스터: 전기를 주면 꺼짐, 뺏으면 켜짐.
NPN트랜지스터: 전기를 주면(High) 켜짐, 뺏으면 꺼짐.
RISC: 코드가 길은만큼 전력소모 감소.
CISC: 코드가 짧은만큼 많은 기능을 함-> 전력소모 증가
ROM: 전원이 꺼져도 저장, 저장할 때
RAM: 전원이 꺼지면 날라감, 변수나 계산할 때
EEPROM(flash rom): ROM의 종류, RAM의 장점도 가져옴. 데이터 변경 가능.
FET(Field Effect Transistor)
platfromio
.elf or .hex 파일이있으면 아두이노에 구울 수 있음.
volatile키워드를 써서 레지스터 주소에 접근할 수 있음.
#include <Arduino.h> // PlatformIO에서는 이 헤더가 필수입니다.
void setup() {
// DDRB 레지스터 주소 (0x24) 직접 접근 -> 5번 비트 출력 설정
*((volatile unsigned char *)0x24) |= 0x20; //2진수로 0010 0000
}
void loop() {
// PORTB 레지스터 (0x25) -> LED ON
*((volatile unsigned char *)0x25) |= 0x20;
delay(1000);
// PORTB 레지스터 (0x25) -> LED OFF
*((volatile unsigned char *)0x25) &= ~0x20;
delay(1000);
}
다른 방식으로 LED 켜보기(C)
#include <Arduino.h>
// 1. LED 상태를 보관할 구조체 정의
typedef struct {
uint8_t pin; // 핀 번호
unsigned long onTime; // 켜져 있을 시간 (ms)
unsigned long offTime; // 꺼져 있을 시간 (ms)
uint8_t state; // 현재 상태 (HIGH/LOW)
unsigned long prevMillis; // 마지막으로 상태가 바뀐 시간
} Flasher;
// 2. 구조체 초기화 함수 (C++의 생성자 역할)
void Flasher_Init(Flasher* f, uint8_t pin, unsigned long on, unsigned long off) {
f->pin = pin;
f->onTime = on;
f->offTime = off;
f->state = LOW;
f->prevMillis = 0;
pinMode(f->pin, OUTPUT);
}
// 3. 상태 업데이트 함수 (구조체 포인터를 받아 상태 변경)
void Flasher_Update(Flasher* f, unsigned long currentMillis) {
// 켜져 있고, 끄는 시간이 되었을 때
if ((f->state == HIGH) && (currentMillis - f->prevMillis >= f->onTime)) {
f->state = LOW;
f->prevMillis = currentMillis;
digitalWrite(f->pin, f->state);
}
// 꺼져 있고, 켜는 시간이 되었을 때
else if ((f->state == LOW) && (currentMillis - f->prevMillis >= f->offTime)) {
f->state = HIGH;
f->prevMillis = currentMillis;
digitalWrite(f->pin, f->state);
}
}
// 구조체 변수(인스턴스) 선언
Flasher led1;
Flasher led2;
Flasher led3;
void setup() {
// 각 LED 초기화 (주소 전달 연산자 '&' 사용)
Flasher_Init(&led1, 13, 1000, 1000); // 13번 핀
Flasher_Init(&led2, 12, 500, 500); // 12번 핀
Flasher_Init(&led3, 11, 100, 100); // 11번 핀
}
void loop() {
// 성능 최적화: loop 한 번당 millis()는 한 번만 호출하여 전달
unsigned long currentMillis = millis();
// 각 LED 상태 업데이트
Flasher_Update(&led1, currentMillis);
Flasher_Update(&led2, currentMillis);
Flasher_Update(&led3, currentMillis);
// 이 위치에 지연 없이 다른 작업 추가 가능
}
C++
#include <Arduino.h>
// LED 상태를 관리하는 클래스 정의
class Flasher {
private:
uint8_t ledPin; // 제어할 핀 번호
unsigned long OnTime; // 켜져 있을 시간 (ms)
unsigned long OffTime; // 꺼져 있을 시간 (ms)
int ledState; // 현재 LED 상태 (HIGH/LOW)
unsigned long previousMillis; // 상태가 마지막으로 바뀐 시간
public:
// 생성자: 핀 번호 및 주기 설정
Flasher(int pin, unsigned long on, unsigned long off) {
ledPin = pin;
OnTime = on;
OffTime = off;
ledState = LOW;
previousMillis = 0;
pinMode(ledPin, OUTPUT);
}
// 상태 업데이트 함수 (loop에서 지속 호출)
void update() {
// 현재 시간 확인
unsigned long currentMillis = millis();
// LED가 켜져 있고, 설정한 켜짐 시간(OnTime)이 지났을 때
if ((ledState == HIGH) && (currentMillis - previousMillis >= OnTime)) {
ledState = LOW; // 상태를 LOW로 변경
previousMillis = currentMillis; // 현재 시간을 과거 시간으로 저장
digitalWrite(ledPin, ledState); // 실제 핀 제어
}
// LED가 꺼져 있고, 설정한 꺼짐 시간(OffTime)이 지났을 때
else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime)) {
ledState = HIGH; // 상태를 HIGH로 변경
previousMillis = currentMillis; // 현재 시간을 과거 시간으로 저장
digitalWrite(ledPin, ledState); // 실제 핀 제어
}
}
};
// 독립적인 주기를 가진 객체 생성
// led1: 13번 핀, 100ms 켜지고 400ms 꺼짐 (빠르게 깜빡임)
Flasher led1(13, 100, 400);
// led2: 12번 핀, 500ms 켜지고 500ms 꺼짐 (느리게 깜빡임)
Flasher led2(12, 500, 500);
// led3: 11번 핀, 50ms 켜지고 950ms 꺼짐 (1초에 한 번 짧게 깜빡임)
Flasher led3(11, 50, 950);
void setup() {
// 핀 초기화는 객체 생성 시 수행되므로 생략 가능
}
void loop() {
// 1. 각 LED의 상태 업데이트
// 내부적으로 millis()를 검사하여 시간이 된 객체만 상태를 반전시킴
led1.update();
led2.update();
led3.update();
// 2. 다른 작업 추가
// delay()가 없으므로 센서 읽기, 통신 등의 작업을 자유롭게 배치 가능
}
TaskScheduler라이브러리 이용
#include <Arduino.h>
#include <TaskScheduler.h>
Scheduler runner;
// 태스크 콜백 함수 선언
void blinkLED1();
void blinkLED2();
// 태스크 객체 생성 (주기ms, 반복횟수, 콜백함수, 스케줄러포인터, 자동시작)
Task task1(1000, TASK_FOREVER, &blinkLED1, &runner, true); // 1초 주기
Task task2(300, TASK_FOREVER, &blinkLED2, &runner, true); // 0.3초 주기
void blinkLED1() {
digitalWrite(13, !digitalRead(13)); // 내장 LED 토글
}
void blinkLED2() {
digitalWrite(12, !digitalRead(12)); // 외부 LED 토글
}
void setup() {
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
runner.startNow(); // 스케줄러 시작
}
void loop() {
runner.execute(); // 스케줄러 실행 루프 (delay 사용 금지)
}