336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
인터넷에 공개된 코드가 얼마 없어 2년 전에 봤던 시험에 썼던 코드 올려둡니다.
코딩 환경은 시험장과 연습 모두 VSCode + Arduino 플러그인으로 했지만 평범한 Arduino IDE(그 녹색프로그램)를 사용해도 상관없어요
즉흥 2시간 타임어텍으로 만든 데다 돌아가는 것만이 목표이기에 지저분합니다. 궁금한 내용이 있다면 댓글에 남겨주시면 답장해 드릴게요 :)
#include "LiquidCrystal.h"
#include <arduino.h>
#define PIN_CLK 2
#define PIN_DT 3
#define PIN_SW 4
uint16_t currentPage; // 지금 보고 있는 페이지
uint8_t clk = 2, dt = 3, sw = 4;
uint8_t lastCLK = 2, lastDT = 3, lastSW = 4;
bool switchPushed = 0; // 스위치 켜짐 상태 확인
bool pageDown = 0; // 인코더를 아래로 내리면
bool pageUp = 0; // 인코더를 위로 올리면
char ss[20];
//모터
#define PIN_DIRECTION 5 //스텝드라이버 방향제어 핀번호
#define PIN_STEP 6 //스텝드라이버 스텝제어 핀번호
//히터
int heatingTarget, heatingCurrent;
bool heaterEnabled = false;
int heaterCount; //500ms마다 히터 온도가 1도씩 올라가야 함
float angle;
// LED
#define PINLED_R 33
#define PINLED_G 35
#define PINLED_B 37
//근접센서
#define PIN_PSENSOR 7
#define PIN_BEEP A5
//화면
#if 0
uint8_t rs = 12;
uint8_t enable = 13;
uint8_t d0 = 8;
uint8_t d1 = 9;
uint8_t d2 = 10;
uint8_t d3 = 11;
#else
#define rs 12
#define enable 13
#define d0 8
#define d1 9
#define d2 10
#define d3 11
#endif
LiquidCrystal lcd(rs, enable, d0, d1, d2, d3);
void readEncoder()
{
clk = digitalRead(PIN_CLK);
dt = digitalRead(PIN_DT);
sw = digitalRead(PIN_SW);
pageDown = 0; // 아래로 내리면
pageUp = 0; // 위로 올리면
if (clk && !lastCLK)
{
if (dt)
pageDown = true;
else
pageUp = true;
}
if (sw && !lastSW)
{
switchPushed = 1;
}
else
switchPushed = 0;
lastCLK = clk;
lastDT = dt;
lastSW = sw;
}
void bedHeating()
{
if (heaterEnabled)
{
heaterCount++;
heatingCurrent = (int)(heaterCount / 40);
if (heatingCurrent == heatingTarget)
{
analogWrite(PIN_STEP, 128);
digitalWrite(PINLED_R, HIGH);
digitalWrite(PINLED_G, LOW);
digitalWrite(PINLED_B, LOW);
delay(500);
digitalWrite(PINLED_R, LOW);
digitalWrite(PINLED_G, HIGH);
digitalWrite(PINLED_B, LOW);
delay(500);
digitalWrite(PINLED_R, LOW);
digitalWrite(PINLED_G, LOW);
digitalWrite(PINLED_B, HIGH);
delay(500);
heaterCount = 0;
heaterEnabled = false;
}
}
}
void emergencyWatchdog()
{
if (digitalRead(PIN_PSENSOR) == LOW &&
(currentPage == 410 || currentPage == 420)) // 감지되면
{
lcd.setCursor(0, 0);
analogWrite(PIN_STEP, 0);
lcd.print(">STATE:DANGER");
for (uint8_t i = 0; i < 5; i++)
{
digitalWrite(PIN_BEEP, HIGH);
delay(500);
digitalWrite(PIN_BEEP, LOW);
delay(500);
}
analogWrite(PIN_STEP, 128);
}
}
void setup()
{
Serial.begin(115200);
pinMode(PIN_CLK, INPUT);
pinMode(PIN_DT, INPUT);
pinMode(PIN_SW, INPUT);
//모터
pinMode(PIN_DIRECTION, OUTPUT);
pinMode(PIN_STEP, OUTPUT);
// led
pinMode(PINLED_R, OUTPUT);
pinMode(PINLED_G, OUTPUT);
pinMode(PINLED_B, OUTPUT);
//근접센서
pinMode(PIN_PSENSOR, INPUT_PULLUP);
pinMode(PIN_BEEP, OUTPUT);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.setCursor(0, 0);
lcd.print("3D PRINTER A320M");
lcd.setCursor(0, 1);
lcd.print("READY TO DRIVE");
delay(1000);
}
void loop()
{
readEncoder();
bedHeating();
emergencyWatchdog();
Serial.println(currentPage);
switch (currentPage)
{
case 0:
lcd.setCursor(0, 0);
lcd.print("X: Y: A320");
lcd.setCursor(0, 1);
lcd.print("3D Printer Ready");
if (switchPushed)
{
lcd.clear();
currentPage = 100;
}
break;
case 100:
lcd.setCursor(0, 0);
lcd.print(">EXIT");
lcd.setCursor(0, 1);
lcd.print(" MOTOR TEST");
if (switchPushed) //스위치가 눌리면
{
lcd.clear();
currentPage = 0;
}
if (pageUp) //위로한칸
{
lcd.clear();
currentPage = 400;
}
if (pageDown) //아래로한칸
{
lcd.clear();
currentPage = 200;
}
break;
case 200:
lcd.setCursor(0, 0);
lcd.print(" EXIT");
lcd.setCursor(0, 1);
lcd.print(">MOTOR TEST");
if (switchPushed) //스위치가 눌리면
{
lcd.clear();
currentPage = 210;
}
if (pageUp) //위로한칸
{
lcd.clear();
currentPage = 100;
}
if (pageDown) //아래로한칸
{
lcd.clear();
currentPage = 300;
}
break;
case 210:
lcd.setCursor(0, 0);
sprintf(ss, ">ANGLE:%+04d.%1d", (int)angle,
abs((int)((int)(angle * 10) % 10)));
lcd.print(ss);
lcd.setCursor(0, 1);
lcd.print(" RETURN");
if (switchPushed) //스위치가 눌리면
{
lcd.clear();
currentPage = 211;
}
if (pageUp) //위로한칸
{
lcd.clear();
currentPage = 220;
}
if (pageDown) //아래로한칸
{
lcd.clear();
currentPage = 220;
}
break;
case 211:
lcd.setCursor(0, 0);
sprintf(ss, "*ANGLE:%+04d.%1d", (int)angle,
abs((int)((int)(angle * 10) % 10)));
lcd.print(ss);
lcd.setCursor(0, 1);
lcd.print(" RETURN");
if (switchPushed) //스위치가 눌리면 여기서 모터도돌림
{
if (angle < 0) //모터 반대로 도는 코드
{
angle = -angle;
digitalWrite(PIN_DIRECTION, HIGH);
}
else
digitalWrite(PIN_DIRECTION, LOW);
for (int i = 0; i < (angle / 1.8); i++) //모터구동 코드
{
digitalWrite(PIN_STEP, HIGH);
delayMicroseconds(1000);
digitalWrite(PIN_STEP, LOW);
delayMicroseconds(1000);
}
lcd.clear();
currentPage = 210;
}
if (pageUp) //위로한칸
{
lcd.clear();
angle -= 1.8;
}
if (pageDown) //아래로한칸
{
lcd.clear();
angle += 1.8;
}
break;
case 220: //리턴
lcd.setCursor(0, 0);
sprintf(ss, " ANGLE:%+04d.%1d", (int)angle,
abs((int)((int)(angle * 10) % 10)));
lcd.print(ss);
lcd.setCursor(0, 1);
lcd.print(">RETURN");
if (switchPushed) //스위치가 눌리면
{
lcd.clear();
currentPage = 200;
}
if (pageUp) //위로한칸
{
lcd.clear();
currentPage = 210;
}
if (pageDown) //아래로한칸
{
lcd.clear();
currentPage = 210;
}
break;
case 300:
lcd.setCursor(0, 0);
lcd.print(" MOTOR TEST");
lcd.setCursor(0, 1);
lcd.print(">HEATING BED");
if (switchPushed) //스위치가 눌리면
{
lcd.clear();
currentPage = 310;
}
if (pageUp) //위로한칸
{
lcd.clear();
currentPage = 200;
}
if (pageDown) //아래로한칸
{
lcd.clear();
currentPage = 400;
}
break;
case 310:
lcd.setCursor(0, 0);
sprintf(ss, ">HEATING:%d/%d", heatingCurrent, heatingTarget);
lcd.print(ss);
lcd.setCursor(0, 1);
lcd.print(" RETURN");
if (switchPushed) //스위치가 눌리면
{
lcd.clear();
currentPage = 311;
}
if (pageUp) //위로한칸
{
lcd.clear();
currentPage = 320;
}
if (pageDown) //아래로한칸
{
lcd.clear();
currentPage = 320;
}
break;
case 311:
lcd.setCursor(0, 0);
sprintf(ss, "*HEATING:%d/%d", heatingCurrent, heatingTarget);
lcd.print(ss);
lcd.setCursor(0, 1);
lcd.print(" RETURN");
if (switchPushed) //스위치가 눌리면
{
lcd.clear();
currentPage = 310;
heaterEnabled = true;
}
if (pageUp) //위로한칸
{
lcd.clear();
heatingTarget--;
}
if (pageDown) //아래로한칸
{
lcd.clear();
heatingTarget++;
}
break;
case 320:
lcd.setCursor(0, 0);
sprintf(ss, " HEATING:%d/%d", heatingCurrent, heatingTarget);
lcd.print(ss);
lcd.setCursor(0, 1);
lcd.print(">RETURN");
if (switchPushed) //스위치가 눌리면
{
lcd.clear();
currentPage = 300;
heaterEnabled = false;
heaterCount = 0;
heatingCurrent = 0;
heatingTarget = 0;
analogWrite(PIN_STEP, 0);
}
if (pageUp) //위로한칸
{
lcd.clear();
currentPage = 310;
}
if (pageDown) //아래로한칸
{
lcd.clear();
currentPage = 310;
}
break;
case 400:
lcd.setCursor(0, 0);
lcd.print(" HEATING BED");
lcd.setCursor(0, 1);
lcd.print(">EMERGENCY SET");
if (switchPushed) //스위치가 눌리면
{
lcd.clear();
currentPage = 410;
analogWrite(PIN_STEP, 128);
}
if (pageUp) //위로한칸
{
lcd.clear();
currentPage = 300;
}
if (pageDown) //아래로한칸
{
lcd.clear();
currentPage = 500;
}
break;
case 410:
lcd.setCursor(0, 0);
lcd.print(">STATE:STABLE");
lcd.setCursor(0, 1);
lcd.print(" RETURN");
if (switchPushed) //스위치가 눌리면
{
lcd.clear();
}
if (pageUp) //위로한칸
{
lcd.clear();
currentPage = 420;
}
if (pageDown) //아래로한칸
{
lcd.clear();
currentPage = 420;
}
break;
case 420:
lcd.setCursor(0, 0);
lcd.print(" STATE:STABLE");
lcd.setCursor(0, 1);
lcd.print(">RETURN");
if (switchPushed) //스위치가 눌리면
{
lcd.clear();
currentPage = 400;
analogWrite(PIN_STEP, 0);
}
if (pageUp) //위로한칸
{
lcd.clear();
currentPage = 410;
}
if (pageDown) //아래로한칸
{
lcd.clear();
currentPage = 410;
}
break;
case 500:
lcd.setCursor(0, 0);
lcd.print(" EMERGENCY SET");
lcd.setCursor(0, 1);
lcd.print(">EXIT");
if (switchPushed) //스위치가 눌리면
{
lcd.clear();
// currentPage = 0;
}
if (pageUp) //위로한칸
{
lcd.clear();
currentPage = 400;
}
if (pageDown) //아래로한칸
{
lcd.clear();
currentPage = 200;
}
break;
}
}