여러분은 가만히 계세요 제가 모두 고장낼게요

IT 지식, PC 모바일 문제 해결 그리고 종종 애니 게임 일상생활 근황을 종종 올리고 있어요!

냐.한국 자세히보기

카테고리 없음

3D프린터개발산업기사 예제 소스코드

Kamilake 2022. 5. 24. 12:37

인터넷에 공개된 코드가 얼마 없어 2년 전에 봤던 시험에 썼던 코드 올려둡니다.

코딩 환경은 시험장과 연습 모두 VSCode + Arduino 플러그인으로 했지만 평범한 Arduino IDE(그 녹색프로그램)를 사용해도 상관없어요

3Dfirmware.zip
0.02MB

즉흥 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;
  }
}