3D Printer/OctoPrint

Chamber Manager Board 제작 #6 (Door Control Class 제작)

o.OWhyNot? 2019. 1. 5. 01:14

【 3D 프린터 챔버 만들기 】



[ Control Board 제작 #6 : Door Control Class 제작 ]



□ 필요사항


 : 25KHz Fan Control이 Timer1을 사용하기 때문에 Arduino 기본 Servo Library(Timer1 사용)는 사용 불가


  따라서 Timer2를 사용하는 ServoTimer2 Library로 대체 필요



[ Door.h ]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#ifndef DOOR_H
#define DOOR_H
 
#if defined(ARDUINO) && (ARDUINO >= 100)
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif
 
#include <ServoTimer2.h>
 
enum DOOR_STATUS
{
    CLOSED,
    OPENED,
    UNKNOWN
};
 
 
#define SERVO_POS_MAX    2250
#define SERVO_POS_MIN    750
 
class Door
{
    private:
        class Door *next;
        static Door* first;
 
        ServoTimer2 m_ServoDoor;
        int m_nMax = SERVO_POS_MAX;
        int m_nMin = SERVO_POS_MIN;
        unsigned long m_nMilsCheck = 0;
        bool m_bServoOn = false;
        int m_nPort = 0;
        bool m_bOpened = false;
        int m_nPos = 0;
        int m_nHoldTime = 1000;
 
        void Move(int pos);
 
 
    public:
        Door();
        Door(int port, int max, int min);
        void Attach(int port);
        void Detach();
        bool IsAttached();
        static void Refresh();
 
        void SetRange(int max, int min);
 
        void Open();
        void Close();
        void SetAngle(int degree);
        int GetAngle();
 
        int GetMaxPos();
        int GetMinPos();
        
        DOOR_STATUS GetState();
};
 
#endif
 
cs



[ Door.cpp ]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "Door.h"
 
Door *Door::first;
 
Door::Door()
{
 
}
 
Door::Door(int port, int max, int min)
{
  Attach(port);
  SetRange(max, min);
}
 
void Door::Attach(int port)
{
  next = first;
  first = this;
 
  m_nPort = port;
}
 
void Door::Detach()
{
  for ( Door **= &first; *!= 0; p = &((*p)->next) )
  {
    if ( *== this)
    {
      *= this->next;
      this->next = 0;
      if(this->m_ServoDoor.attached()) this->m_ServoDoor.detach();
      return;
    }
  }
}
 
bool Door::IsAttached()
{
  for ( Door *= first; p != 0; p = p->next )
  {
    if ( p == thisreturn true;
  }
  return false;
}
 
void Door::Refresh()
{
  Door *p;
  unsigned long m = millis();
  
  for(p=first; p!=0; p=p->next)
  {
    if(p->m_bServoOn)
    {
      if(m>p->m_nMilsCheck)
      {
        if(p->m_ServoDoor.attached()) p->m_ServoDoor.detach();
        p->m_bServoOn = false;
      }
    }
  }
}
 
void Door::SetRange(int max, int min)
{
  if(max>SERVO_POS_MAX || min<SERVO_POS_MIN) return;
 
  m_nMax = max;
  m_nMin = min;
 
  // HS422's angular velocity is 210us per 60degree(3.5us per degree)
  // Max Position(2,250) - Min Position (750) = Diff(1500) => 180 degree
  // HoldTime : Diff*180degree/MaxDiff(1500)*3.5us = Diff*180/1500*35/10 = Diff*63/150
  m_nHoldTime = ((long)(max - min) * 63)/150 + 200;
}
 
int Door::GetMaxPos()
{
  return m_nMax;
}
 
int Door::GetMinPos()
{
  return m_nMin;
}
 
void Door::Move(int pos)
{
  m_nPos = pos;
  if(!m_ServoDoor.attached())
    m_ServoDoor.attach(m_nPort);
  m_bServoOn = true;
  m_nMilsCheck = millis()+m_nHoldTime;
  m_ServoDoor.write(pos);
}
 
void Door::Open()
{
  Move(m_nMax);
}
 
void Door::Close()
{
  Move(m_nMin);
}
 
void Door::SetAngle(int degree)
{
  if(degree<0) degree = 0;
  if(degree>90) degree = 90;
 
  Move(map(degree, 090, m_nMin, m_nMax));
}
 
int Door::GetAngle()
{
  return map(m_nPos, m_nMin, m_nMax, 090);
}
 
DOOR_STATUS Door::GetState()
{
  if(m_nPos == m_nMax) return OPENED;
  if(m_nPos == m_nMin) return CLOSED;
  return UNKNOWN;
}
cs