200117StepMotorControl

Dependencies:   X_NUCLEO_IHM02A1 TextLCD

Committer:
danjecsr
Date:
Fri Jan 17 07:58:29 2020 +0000
Revision:
29:d5c13978c8e9
Parent:
28:ed18e436f437
ProjectStep200117

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Davidroid 0:5148e9486cf2 1 /**
Davidroid 0:5148e9486cf2 2 ******************************************************************************
danjecsr 28:ed18e436f437 3 이프로그램은 16x2크기의 LCD표시 및 제어, 스텝모터 제어 2가지 기능을 한다.
danjecsr 28:ed18e436f437 4 사용자에서 실시간으로 LCD와 스텝모터의 동시제어를 위하여 2개의 쓰레드로 분리시켰다.
danjecsr 28:ed18e436f437 5 모터가 회전할때는 적어도 1~2초의 시간이 소모되는데, 싱글 쓰레드로 한다면 모터가 작동할때
danjecsr 28:ed18e436f437 6 LCD제어는 멈추게 된다. 따라서 작은시간을 서로 쪼개어 사용하여 서로간의 제어에
danjecsr 28:ed18e436f437 7 영향을 받지 않도록 하기 위하여 2개의 쓰레드로 분리 시켰음.
Davidroid 0:5148e9486cf2 8 ******************************************************************************
Davidroid 0:5148e9486cf2 9 */
Davidroid 0:5148e9486cf2 10
Davidroid 0:5148e9486cf2 11
Davidroid 0:5148e9486cf2 12 /* Includes ------------------------------------------------------------------*/
Davidroid 0:5148e9486cf2 13
danjecsr 28:ed18e436f437 14 // mbed의 기능을 사용하기 위한 헤더파일
Davidroid 0:5148e9486cf2 15 #include "mbed.h"
Davidroid 27:b25816ce6043 16 #include "rtos.h"
Davidroid 0:5148e9486cf2 17
danjecsr 28:ed18e436f437 18
danjecsr 28:ed18e436f437 19 //텍스트LCD를 사용하기 위한 라이브러리의 헤더파일
danjecsr 28:ed18e436f437 20 #include "TextLCD.h"
danjecsr 28:ed18e436f437 21
danjecsr 28:ed18e436f437 22 //내부 FLASH ROM을 사용하기 위한 라이브러리 헤더파일
danjecsr 28:ed18e436f437 23 #include "eeprom.h"
danjecsr 28:ed18e436f437 24 #include <ctype.h>
danjecsr 28:ed18e436f437 25
danjecsr 28:ed18e436f437 26 //스텝모터 드라이버와 SPI통신을 위한 헤더파일
Davidroid 0:5148e9486cf2 27 #include "DevSPI.h"
Davidroid 0:5148e9486cf2 28
danjecsr 28:ed18e436f437 29 //스텝모터 확장보드 사용을 위한 라이브러리 헤더파일
Davidroid 26:caec5f51abe8 30 #include "XNucleoIHM02A1.h"
Davidroid 0:5148e9486cf2 31
Davidroid 0:5148e9486cf2 32
danjecsr 28:ed18e436f437 33
Davidroid 0:5148e9486cf2 34
danjecsr 28:ed18e436f437 35 /*----------------------------------------------LCD제어관련 변수정의 -------------------------------------------------------*/
danjecsr 28:ed18e436f437 36 //16x2 크기의 LCD를 제어하기 위한 객체생성
danjecsr 28:ed18e436f437 37 TextLCD lcd(D10, D9, D8, D7, D6, D5,TextLCD::LCD16x2); // H/L Register(RS) 선택핀, Enable(E) 선택핀, D4,D5,D6,D7(LCD출력핀)
danjecsr 28:ed18e436f437 38 //DigitalOut rw(D7); // H/L Read,Write신호핀
danjecsr 28:ed18e436f437 39
danjecsr 28:ed18e436f437 40 //Digital 입력핀 설정(기본으로 신호가 없을시 풀다운신호(0V)를 출력하도록 설정한다.)
danjecsr 28:ed18e436f437 41 DigitalIn setin(A3,PullDown); //설정버튼
danjecsr 28:ed18e436f437 42 DigitalIn movin(D15,PullDown); //자릿수선택 버튼
danjecsr 28:ed18e436f437 43 DigitalIn upin(D14,PullDown); //값올림 버튼
danjecsr 28:ed18e436f437 44 DigitalIn downin(D2,PullDown); //값내림 버튼
Davidroid 1:9f1974b0960d 45
danjecsr 29:d5c13978c8e9 46
danjecsr 28:ed18e436f437 47 //LCD 출력의 현재시각 측정(단위:초)
danjecsr 28:ed18e436f437 48 time_t NOWLCD;
danjecsr 28:ed18e436f437 49 //LCD 출력을 조절하기 위한 이전시각(NOWLCD)저장
danjecsr 28:ed18e436f437 50 time_t DISPLAY_TIME;
Davidroid 0:5148e9486cf2 51
danjecsr 28:ed18e436f437 52 float SV = 10.5; //절삭유 농도 지시값(기준값)
danjecsr 28:ed18e436f437 53 int SV1 = 1; //화면에 표시될 절삭유 농도 지시값(10의 자릿수값 정수값1문자)
danjecsr 28:ed18e436f437 54 int SV2 = 0; //화면에 표시될 절삭유 농도 지시값(1의 자릿수값 정수값1문자)
danjecsr 28:ed18e436f437 55 int SV3 = 5; //화면에 표시될 절삭유 농도 지시값(소수점1의 자릿수값 정수값1문자)
danjecsr 28:ed18e436f437 56
danjecsr 28:ed18e436f437 57 int SET_SV1 = 0; //설정모드에서 표시될 농도 지시값(10의 자릿수값)
danjecsr 28:ed18e436f437 58 int SET_SV2 = 0; //설정모드에서 표시될 농도 지시값(1의 자릿수값)
danjecsr 28:ed18e436f437 59 int SET_SV3 = 0; //설정모드에서 표시될 농도 지시값(소수점1의 자릿수값)
Davidroid 0:5148e9486cf2 60
danjecsr 29:d5c13978c8e9 61 //lcd설정값과 밸브의 현재위치를 저장하기 위한 플래쉬메모리의 위치(LCD설정값(0x0000,0x0001), 밸브의 현재위치(0x0002,0x0003)(오일밸브현재 위치,희석수밸브현재위치
danjecsr 29:d5c13978c8e9 62 uint16_t VirtAddVarTab[4] = {0x0000, 0x0001, 0x0002, 0x0003};
danjecsr 29:d5c13978c8e9 63 //lcd설정값(자연수,소수점,절삭유현재위치,희석수현재위치)
danjecsr 29:d5c13978c8e9 64 uint16_t VarDataTab[] = {0, 0, 0, 0};
Davidroid 0:5148e9486cf2 65
danjecsr 29:d5c13978c8e9 66 float PV = 0; //1초동안 샘플링한 절삭유 농도값
danjecsr 29:d5c13978c8e9 67 float PPV = 0; //이전측정 절삭유 농도값
danjecsr 29:d5c13978c8e9 68 float CPV = 0; //현재 절삭유 농도값
danjecsr 29:d5c13978c8e9 69 float SPV = 0; //1초동안 계속 평균을 계산하여 저장하는 절삭유 농도값
danjecsr 28:ed18e436f437 70
danjecsr 28:ed18e436f437 71 int OIL_VALVE_OPEN_P = 0; //오일밸브 열림%
danjecsr 28:ed18e436f437 72 int WATER_VALVE_OPEN_P = 0; //희석수밸브 열림%
danjecsr 28:ed18e436f437 73 int OIL_VALVE_OPEN_PP = 0; //오일밸브 열림%(이전값)
danjecsr 28:ed18e436f437 74 int WATER_VALVE_OPEN_PP = 0; //희석수밸브 열림%(이전값)
danjecsr 28:ed18e436f437 75
danjecsr 28:ed18e436f437 76 bool set_button = false; //설정버튼 눌림 플래그
danjecsr 28:ed18e436f437 77 bool mov_button = false; //자릿수선택 버튼 눌림 플래그
danjecsr 28:ed18e436f437 78 bool up_button = false; //값올림버튼 눌림 플래그
danjecsr 28:ed18e436f437 79 bool down_button = false; //값내림버튼 눌림 플래그
Davidroid 0:5148e9486cf2 80
danjecsr 28:ed18e436f437 81 bool set_mode = false; //설정버튼 ON/OFF모드
danjecsr 28:ed18e436f437 82 int cursor_loc = 0; //SV값을 설정하기 위하여 현재cursor의 위치를 저장(2번째행 11번열, 12번열 두개값중에 하나를 저장하고 있음)
danjecsr 28:ed18e436f437 83
danjecsr 28:ed18e436f437 84
danjecsr 28:ed18e436f437 85
danjecsr 28:ed18e436f437 86
danjecsr 28:ed18e436f437 87 /*----------------------------------------------STEP모터 제어관련 변수정의 -------------------------------------------------------*/
danjecsr 28:ed18e436f437 88
danjecsr 28:ed18e436f437 89
danjecsr 28:ed18e436f437 90 //스텝수 정의
danjecsr 28:ed18e436f437 91 #define STEPS_1 (200 * 128) //1바퀴에 200스텝(1스텝당 1.8도)을 가지고 있는 스텝모터를 1/128정밀도의 마이크로 스텝을 제어.(1바퀴 회전정의)
danjecsr 28:ed18e436f437 92 #define STEPS_2 (STEPS_1 * 2) //2바퀴 회전정의
danjecsr 28:ed18e436f437 93
danjecsr 28:ed18e436f437 94
danjecsr 28:ed18e436f437 95
danjecsr 28:ed18e436f437 96 //스텝모터 확장모듈 드라이버 객체생성
Davidroid 26:caec5f51abe8 97 XNucleoIHM02A1 *x_nucleo_ihm02a1;
Davidroid 0:5148e9486cf2 98
danjecsr 28:ed18e436f437 99 //스텝모터 파라미터값 정의
davide.aliprandi@st.com 24:d1f487cb02ba 100 L6470_init_t init[L6470DAISYCHAINSIZE] = {
danjecsr 28:ed18e436f437 101 // 첫번째 Motor.(절삭유밸브 모터)
Davidroid 9:f35fbeedb8f4 102 {
danjecsr 28:ed18e436f437 103 12.0, /* Motor supply voltage in V. */
danjecsr 28:ed18e436f437 104 200, /* Min number of steps per revolution for the motor. */
Davidroid 18:591a007effc2 105 1.7, /* Max motor phase voltage in A. */
Davidroid 18:591a007effc2 106 3.06, /* Max motor phase voltage in V. */
Davidroid 18:591a007effc2 107 300.0, /* Motor initial speed [step/s]. */
Davidroid 18:591a007effc2 108 500.0, /* Motor acceleration [step/s^2] (comment for infinite acceleration mode). */
Davidroid 18:591a007effc2 109 500.0, /* Motor deceleration [step/s^2] (comment for infinite deceleration mode). */
Davidroid 18:591a007effc2 110 992.0, /* Motor maximum speed [step/s]. */
Davidroid 18:591a007effc2 111 0.0, /* Motor minimum speed [step/s]. */
Davidroid 18:591a007effc2 112 602.7, /* Motor full-step speed threshold [step/s]. */
Davidroid 18:591a007effc2 113 3.06, /* Holding kval [V]. */
Davidroid 18:591a007effc2 114 3.06, /* Constant speed kval [V]. */
Davidroid 18:591a007effc2 115 3.06, /* Acceleration starting kval [V]. */
Davidroid 18:591a007effc2 116 3.06, /* Deceleration starting kval [V]. */
Davidroid 18:591a007effc2 117 61.52, /* Intersect speed for bemf compensation curve slope changing [step/s]. */
Davidroid 18:591a007effc2 118 392.1569e-6, /* Start slope [s/step]. */
Davidroid 18:591a007effc2 119 643.1372e-6, /* Acceleration final slope [s/step]. */
Davidroid 18:591a007effc2 120 643.1372e-6, /* Deceleration final slope [s/step]. */
Davidroid 18:591a007effc2 121 0, /* Thermal compensation factor (range [0, 15]). */
Davidroid 18:591a007effc2 122 3.06 * 1000 * 1.10, /* Ocd threshold [ma] (range [375 ma, 6000 ma]). */
Davidroid 18:591a007effc2 123 3.06 * 1000 * 1.00, /* Stall threshold [ma] (range [31.25 ma, 4000 ma]). */
Davidroid 18:591a007effc2 124 StepperMotor::STEP_MODE_1_128, /* Step mode selection. */
Davidroid 18:591a007effc2 125 0xFF, /* Alarm conditions enable. */
Davidroid 18:591a007effc2 126 0x2E88 /* Ic configuration. */
Davidroid 9:f35fbeedb8f4 127 },
Davidroid 9:f35fbeedb8f4 128
danjecsr 28:ed18e436f437 129 //두번째 Motor(희석수밸브 모터)
Davidroid 9:f35fbeedb8f4 130 {
danjecsr 28:ed18e436f437 131 12.0, /* Motor supply voltage in V. */
danjecsr 28:ed18e436f437 132 200, /* Min number of steps per revolution for the motor. */
Davidroid 18:591a007effc2 133 1.7, /* Max motor phase voltage in A. */
Davidroid 18:591a007effc2 134 3.06, /* Max motor phase voltage in V. */
Davidroid 18:591a007effc2 135 300.0, /* Motor initial speed [step/s]. */
Davidroid 18:591a007effc2 136 500.0, /* Motor acceleration [step/s^2] (comment for infinite acceleration mode). */
Davidroid 18:591a007effc2 137 500.0, /* Motor deceleration [step/s^2] (comment for infinite deceleration mode). */
Davidroid 18:591a007effc2 138 992.0, /* Motor maximum speed [step/s]. */
Davidroid 18:591a007effc2 139 0.0, /* Motor minimum speed [step/s]. */
Davidroid 18:591a007effc2 140 602.7, /* Motor full-step speed threshold [step/s]. */
Davidroid 18:591a007effc2 141 3.06, /* Holding kval [V]. */
Davidroid 18:591a007effc2 142 3.06, /* Constant speed kval [V]. */
Davidroid 18:591a007effc2 143 3.06, /* Acceleration starting kval [V]. */
Davidroid 18:591a007effc2 144 3.06, /* Deceleration starting kval [V]. */
Davidroid 18:591a007effc2 145 61.52, /* Intersect speed for bemf compensation curve slope changing [step/s]. */
Davidroid 18:591a007effc2 146 392.1569e-6, /* Start slope [s/step]. */
Davidroid 18:591a007effc2 147 643.1372e-6, /* Acceleration final slope [s/step]. */
Davidroid 18:591a007effc2 148 643.1372e-6, /* Deceleration final slope [s/step]. */
Davidroid 18:591a007effc2 149 0, /* Thermal compensation factor (range [0, 15]). */
Davidroid 18:591a007effc2 150 3.06 * 1000 * 1.10, /* Ocd threshold [ma] (range [375 ma, 6000 ma]). */
Davidroid 18:591a007effc2 151 3.06 * 1000 * 1.00, /* Stall threshold [ma] (range [31.25 ma, 4000 ma]). */
Davidroid 18:591a007effc2 152 StepperMotor::STEP_MODE_1_128, /* Step mode selection. */
Davidroid 18:591a007effc2 153 0xFF, /* Alarm conditions enable. */
Davidroid 18:591a007effc2 154 0x2E88 /* Ic configuration. */
Davidroid 9:f35fbeedb8f4 155 }
Davidroid 9:f35fbeedb8f4 156 };
Davidroid 9:f35fbeedb8f4 157
Davidroid 0:5148e9486cf2 158
danjecsr 28:ed18e436f437 159
danjecsr 28:ed18e436f437 160 //현재 농도를 받아오는 Analog input 핀번호를 선택한다.(PA_0)즉 핀번호 Analog 0번핀을 선택한다.
danjecsr 28:ed18e436f437 161 AnalogIn CurCon(A0);
danjecsr 28:ed18e436f437 162
danjecsr 28:ed18e436f437 163
danjecsr 28:ed18e436f437 164 //절삭유밸브와 희석수밸브의 초기위치
danjecsr 28:ed18e436f437 165 int oilhomeposition = 0;
danjecsr 28:ed18e436f437 166 int waterhomeposition = 0;
danjecsr 28:ed18e436f437 167
danjecsr 29:d5c13978c8e9 168
danjecsr 29:d5c13978c8e9 169 //샘플링 카운트 수
danjecsr 29:d5c13978c8e9 170 int samplecnt = 0;
danjecsr 29:d5c13978c8e9 171
danjecsr 29:d5c13978c8e9 172
danjecsr 29:d5c13978c8e9 173 //절삭유밸브와 희석수밸브의 현재 포지션
danjecsr 29:d5c13978c8e9 174 short oilcurrposition = 0;
danjecsr 29:d5c13978c8e9 175 short watercurrposition = 0;
danjecsr 29:d5c13978c8e9 176
danjecsr 28:ed18e436f437 177 //오일탱크밸브와 수탱크밸브가 오픈된 시간을 저장
danjecsr 28:ed18e436f437 178 Timer OIL_VALVE_TIMER;
danjecsr 28:ed18e436f437 179 Timer WATER_VALVE_TIMER;
danjecsr 28:ed18e436f437 180
danjecsr 28:ed18e436f437 181
danjecsr 28:ed18e436f437 182 //밸브가 열린후 카운트 시간
danjecsr 28:ed18e436f437 183 time_t OIL_VALVE_OPEN_TIME;
danjecsr 28:ed18e436f437 184 time_t WATER_VALVE_OPEN_TIME;
danjecsr 28:ed18e436f437 185
danjecsr 28:ed18e436f437 186 //현재시각
danjecsr 28:ed18e436f437 187 time_t NOW;
danjecsr 28:ed18e436f437 188
danjecsr 29:d5c13978c8e9 189 //농도값 샘플링을 위한 시각비교값 저장
danjecsr 29:d5c13978c8e9 190 time_t SAMPLE;
danjecsr 29:d5c13978c8e9 191
danjecsr 28:ed18e436f437 192 //오일탱크밸브와 수탱크밸브가 열려있는지 저장
danjecsr 28:ed18e436f437 193 bool OIL_VALVE_ON = false;
danjecsr 28:ed18e436f437 194 bool WATER_VALVE_ON = false;
danjecsr 28:ed18e436f437 195
danjecsr 28:ed18e436f437 196
danjecsr 28:ed18e436f437 197 //딜레이시간 정의 (milli seconds)
danjecsr 28:ed18e436f437 198 #define DELAY_1 1000
danjecsr 28:ed18e436f437 199 #define DELAY_2 2000
danjecsr 28:ed18e436f437 200 #define DELAY_3 5000
danjecsr 28:ed18e436f437 201
danjecsr 28:ed18e436f437 202
danjecsr 28:ed18e436f437 203
danjecsr 28:ed18e436f437 204 //LCD제어를 위한 쓰레드 생성
danjecsr 28:ed18e436f437 205 void LCD_CTRL_THREAD(void const *args)
danjecsr 28:ed18e436f437 206 {
danjecsr 28:ed18e436f437 207
danjecsr 29:d5c13978c8e9 208 ////설정값을 FLASH메모리에서 읽고쓰기하기 위하여 락을 해제한다.
danjecsr 29:d5c13978c8e9 209 //HAL_FLASH_Unlock();
danjecsr 29:d5c13978c8e9 210 //EE_Init();
danjecsr 28:ed18e436f437 211
danjecsr 28:ed18e436f437 212
danjecsr 28:ed18e436f437 213 //SV값은 총4byte float값인데 EEPROM Library는 기본적으로 2byte씩메모리를 엑세스하게 되어있음
danjecsr 28:ed18e436f437 214 //따라서 2byte메모리를 읽어서 4byte값으로 만들것임.
danjecsr 28:ed18e436f437 215 for (int i=0; i<2; i++)
danjecsr 28:ed18e436f437 216 {
danjecsr 28:ed18e436f437 217 EE_ReadVariable(VirtAddVarTab[i], &VarDataTab[i]);
danjecsr 28:ed18e436f437 218 }
danjecsr 28:ed18e436f437 219
danjecsr 28:ed18e436f437 220 //읽은값을 정수자릿수 2byte + 소숫점1자릿수 2byte값을 합쳐서 4byte float값으로 변경(설정값 저장)
danjecsr 28:ed18e436f437 221 SV = VarDataTab[0] + VarDataTab[1]*0.1;
danjecsr 28:ed18e436f437 222
danjecsr 28:ed18e436f437 223
danjecsr 28:ed18e436f437 224 //SV값을 LCD에 출력하기위하여 SV1,SV2,SV3로 분리한다.
danjecsr 28:ed18e436f437 225 SV1 = (int)(SV/10);
danjecsr 28:ed18e436f437 226 SV2 = (int)(SV-(SV1*10));
danjecsr 28:ed18e436f437 227 SV3 = (int)(((SV-((SV1*10)+SV2))*10)+0.5);
danjecsr 28:ed18e436f437 228
danjecsr 28:ed18e436f437 229
danjecsr 28:ed18e436f437 230
danjecsr 28:ed18e436f437 231
danjecsr 28:ed18e436f437 232 //rw =0;
danjecsr 28:ed18e436f437 233 lcd.cls(); //화면을 초기화 한다.
danjecsr 28:ed18e436f437 234
danjecsr 28:ed18e436f437 235
danjecsr 28:ed18e436f437 236
danjecsr 28:ed18e436f437 237 //절삭유 공급밸브 열림% LCD출력
danjecsr 28:ed18e436f437 238 lcd.locate(0,0);
danjecsr 28:ed18e436f437 239 lcd.printf("P1:");
danjecsr 28:ed18e436f437 240 lcd.printf("%03d%%",OIL_VALVE_OPEN_P);
danjecsr 28:ed18e436f437 241
danjecsr 28:ed18e436f437 242 //절삭유 현재 농도값 LCD출력
danjecsr 28:ed18e436f437 243 lcd.locate(8,0);
danjecsr 28:ed18e436f437 244 lcd.printf("PV:");
danjecsr 28:ed18e436f437 245 lcd.printf("%02.1f%%",PV);
danjecsr 28:ed18e436f437 246
danjecsr 28:ed18e436f437 247 //희석수 공급밸브 열림% LCD출력
danjecsr 28:ed18e436f437 248 lcd.locate(0,1);
danjecsr 28:ed18e436f437 249 lcd.printf("P2:");
danjecsr 28:ed18e436f437 250 lcd.printf("%03d%%",WATER_VALVE_OPEN_P);
danjecsr 28:ed18e436f437 251
danjecsr 28:ed18e436f437 252 //절삭유 지시(목표) 농도값 LCD출력
danjecsr 28:ed18e436f437 253 lcd.locate(8,1);
danjecsr 28:ed18e436f437 254 lcd.printf("SV:");
danjecsr 28:ed18e436f437 255 lcd.printf("%d%d.%d%%",SV1,SV2,SV3);
danjecsr 28:ed18e436f437 256
danjecsr 28:ed18e436f437 257
danjecsr 28:ed18e436f437 258 //커서표시와 깜밖임을 없앤다.
danjecsr 28:ed18e436f437 259 lcd.setCursor(lcd.CurOff_BlkOff);
danjecsr 28:ed18e436f437 260
danjecsr 28:ed18e436f437 261
danjecsr 28:ed18e436f437 262
danjecsr 28:ed18e436f437 263 while (1)
danjecsr 28:ed18e436f437 264 {
danjecsr 28:ed18e436f437 265 NOWLCD = time(NULL);
danjecsr 28:ed18e436f437 266 /*------------------------------- LCD표시 ---------------------------------------------------*/
danjecsr 28:ed18e436f437 267 //1.5초마다 화면을 갱신한다.
danjecsr 29:d5c13978c8e9 268 if(NOWLCD - DISPLAY_TIME >= 1 and !set_mode)
danjecsr 28:ed18e436f437 269 {
danjecsr 28:ed18e436f437 270
danjecsr 28:ed18e436f437 271 //현재 측정한 절삭유 농도값이 이전측정값과 다르다면 LCD화면을 갱신한다.
danjecsr 28:ed18e436f437 272 if(PV != PPV)
danjecsr 28:ed18e436f437 273 {
danjecsr 28:ed18e436f437 274 lcd.locate(11,0);
danjecsr 28:ed18e436f437 275 lcd.printf("%02.1f%%",PV);
danjecsr 28:ed18e436f437 276
danjecsr 28:ed18e436f437 277 //현재값을 이전값변수에 입력한다.(다음타이밍에 비교하기 위하여)
danjecsr 28:ed18e436f437 278 PPV = PV;
danjecsr 28:ed18e436f437 279 }
danjecsr 28:ed18e436f437 280
danjecsr 28:ed18e436f437 281 //현재 오일밸브의 오픈%가 이전값과 달다면 LCD화면을 갱신한다.
danjecsr 28:ed18e436f437 282 if(OIL_VALVE_OPEN_P != OIL_VALVE_OPEN_PP)
danjecsr 28:ed18e436f437 283 {
danjecsr 28:ed18e436f437 284 lcd.locate(3,0);
danjecsr 28:ed18e436f437 285 lcd.printf("%03d%%",OIL_VALVE_OPEN_P);
danjecsr 28:ed18e436f437 286
danjecsr 28:ed18e436f437 287 //현재값을 이전 측정값을 저장하는 변수에 복사
danjecsr 28:ed18e436f437 288 OIL_VALVE_OPEN_PP = OIL_VALVE_OPEN_P;
danjecsr 28:ed18e436f437 289 }
danjecsr 28:ed18e436f437 290
danjecsr 28:ed18e436f437 291
danjecsr 28:ed18e436f437 292 //현재 희석수밸브의 오픈%가 이전값과 달다면 LCD화면을 갱신한다.
danjecsr 28:ed18e436f437 293 if(WATER_VALVE_OPEN_P != WATER_VALVE_OPEN_PP)
danjecsr 28:ed18e436f437 294 {
danjecsr 28:ed18e436f437 295 lcd.locate(3,1);
danjecsr 28:ed18e436f437 296 lcd.printf("%03d%%",WATER_VALVE_OPEN_P);
danjecsr 28:ed18e436f437 297
danjecsr 28:ed18e436f437 298 //현재값을 이전 측정값을 저장하는 변수에 복사
danjecsr 28:ed18e436f437 299 WATER_VALVE_OPEN_PP = WATER_VALVE_OPEN_P;
danjecsr 28:ed18e436f437 300 }
danjecsr 28:ed18e436f437 301
danjecsr 28:ed18e436f437 302 //다음 시간비교를 위해서 현재시각을 저장한다.
danjecsr 28:ed18e436f437 303 DISPLAY_TIME = NOWLCD;
danjecsr 28:ed18e436f437 304 }
danjecsr 28:ed18e436f437 305
danjecsr 28:ed18e436f437 306
danjecsr 28:ed18e436f437 307
danjecsr 28:ed18e436f437 308
danjecsr 28:ed18e436f437 309 /*------------------------------- LCD설정 ---------------------------------------------------*/
danjecsr 28:ed18e436f437 310
danjecsr 28:ed18e436f437 311 //----------농도 설정
danjecsr 28:ed18e436f437 312 //SV(농도지시값)값 설정버튼(SET)을 눌렀을경우 플래그를 세팅한다.(정확한 세팅상태를 지정하기 위함)
danjecsr 28:ed18e436f437 313 if(setin and set_button == false)
danjecsr 28:ed18e436f437 314 {
danjecsr 28:ed18e436f437 315 set_button = true; //설정버튼 플래그 활성화
danjecsr 28:ed18e436f437 316 }
danjecsr 28:ed18e436f437 317
danjecsr 28:ed18e436f437 318 //SET버튼이 눌려지다가 떨어지면 세팅모드로 들어간다.
danjecsr 28:ed18e436f437 319 if(!setin and set_button == true and set_mode == false)
danjecsr 28:ed18e436f437 320 {
danjecsr 28:ed18e436f437 321 printf("LCD SETTING MODE IN\r\n");
danjecsr 28:ed18e436f437 322 lcd.locate(14,1); //설정값 첫번째 위치로 이동
danjecsr 28:ed18e436f437 323 cursor_loc = 14; //현재 커서위치 저장
danjecsr 28:ed18e436f437 324 lcd.setCursor(lcd.CurOff_BlkOn); //설정위치에서 커서 깜박임
danjecsr 28:ed18e436f437 325
danjecsr 28:ed18e436f437 326 set_mode = true; //설정모드 활성화
danjecsr 28:ed18e436f437 327 set_button = false; //설정버튼 플래그 초기화
danjecsr 28:ed18e436f437 328 }
danjecsr 28:ed18e436f437 329
danjecsr 28:ed18e436f437 330 //만약 SV설정 버튼이 true인 상태에서 한번더 누르면 현재값을 저장하고 모드를 빠져나온다(커서의 깜박임을 멈춘다.)
danjecsr 28:ed18e436f437 331 if(!setin and set_button == true and set_mode == true )
danjecsr 28:ed18e436f437 332 {
danjecsr 28:ed18e436f437 333 printf("LCD SETTING MODE OUT\r\n");
danjecsr 28:ed18e436f437 334 SV = (SV1*10) + (SV2*1) + (SV3*0.1); //설정값을 float형(4byte 부동소수점형)으로 저장한다.
danjecsr 28:ed18e436f437 335
danjecsr 28:ed18e436f437 336 //플래쉬메모리에 설정값을 저장한다.
danjecsr 28:ed18e436f437 337
danjecsr 28:ed18e436f437 338 //정수자릿수와 소수점 자릿수로 나눈다.
danjecsr 28:ed18e436f437 339 VarDataTab[0] = (uint16_t)SV; //정수자릿수
danjecsr 28:ed18e436f437 340 VarDataTab[1] = (uint16_t)(((SV-VarDataTab[0])*10)+0.5); //소수점1자릿수(45.5라는 숫자가 45.4999999같은 값이 될수 있으므로 소수점 첫번째에서 반올림한다.)
danjecsr 28:ed18e436f437 341
danjecsr 28:ed18e436f437 342 //내부 플래쉬 메모리에 값을 저장한다.
danjecsr 28:ed18e436f437 343 EE_WriteVariable(VirtAddVarTab[0],VarDataTab[0] );
danjecsr 28:ed18e436f437 344 EE_WriteVariable(VirtAddVarTab[1],VarDataTab[1] );
danjecsr 28:ed18e436f437 345
danjecsr 28:ed18e436f437 346 lcd.setCursor(lcd.CurOff_BlkOff); //설정위치의 커버 깜박임 꺼짐
danjecsr 28:ed18e436f437 347
danjecsr 28:ed18e436f437 348 set_mode = false; //설정모드 종료
danjecsr 28:ed18e436f437 349 set_button = false; //설정버튼 플래그 초기화
danjecsr 28:ed18e436f437 350 }
danjecsr 28:ed18e436f437 351
danjecsr 28:ed18e436f437 352
danjecsr 28:ed18e436f437 353
danjecsr 28:ed18e436f437 354
danjecsr 28:ed18e436f437 355
danjecsr 28:ed18e436f437 356
danjecsr 28:ed18e436f437 357
danjecsr 28:ed18e436f437 358
danjecsr 28:ed18e436f437 359 //-------------자릿수 설정
danjecsr 28:ed18e436f437 360 //자릿수 지정버튼(◁)을 눌렀을경우 플래그를 세팅한다.(정확한 세팅상태를 지정하기 위함)
danjecsr 28:ed18e436f437 361 if(movin and mov_button == false and set_mode == true)
danjecsr 28:ed18e436f437 362 {
danjecsr 28:ed18e436f437 363 mov_button = true; //자릿수 이동버튼 플래그 활성화
danjecsr 28:ed18e436f437 364 }
danjecsr 28:ed18e436f437 365
danjecsr 28:ed18e436f437 366 //만약 현재 설정모드이고 자릿수 버튼이 눌려졌다면 커서를 앞뒤로 이동한다.
danjecsr 28:ed18e436f437 367 if(!movin and mov_button == true and set_mode == true)
danjecsr 28:ed18e436f437 368 {
danjecsr 28:ed18e436f437 369 printf("LCD MOVE\r\n");
danjecsr 28:ed18e436f437 370 //만약 현재 cursor의 위치가 11이라면 14로 옮기고, 12라면 11로, 14라면 12로 옮긴다.
danjecsr 28:ed18e436f437 371 if(cursor_loc == 11)
danjecsr 28:ed18e436f437 372 {
danjecsr 28:ed18e436f437 373 //커서의 위치를 옮긴후 현재의 위치를 저장한다.
danjecsr 28:ed18e436f437 374 lcd.locate(14,1);
danjecsr 28:ed18e436f437 375 cursor_loc = 14;
danjecsr 28:ed18e436f437 376 }
danjecsr 28:ed18e436f437 377 //만약 현재 cursor의 위치가 12라면 11로 옮긴다.
danjecsr 28:ed18e436f437 378 else if(cursor_loc == 12)
danjecsr 28:ed18e436f437 379 {
danjecsr 28:ed18e436f437 380 //커서의 위치를 옮긴후 현재의 위치를 저장한다.
danjecsr 28:ed18e436f437 381 lcd.locate(11,1);
danjecsr 28:ed18e436f437 382 cursor_loc = 11;
danjecsr 28:ed18e436f437 383 }
danjecsr 28:ed18e436f437 384 //만약 현재 cursor의 위치가 14라면 12로 옮긴다.
danjecsr 28:ed18e436f437 385 else if(cursor_loc == 14)
danjecsr 28:ed18e436f437 386 {
danjecsr 28:ed18e436f437 387 //커서의 위치를 옮긴후 현재의 위치를 저장한다.
danjecsr 28:ed18e436f437 388 lcd.locate(12,1);
danjecsr 28:ed18e436f437 389 cursor_loc = 12;
danjecsr 28:ed18e436f437 390 }
danjecsr 28:ed18e436f437 391
danjecsr 28:ed18e436f437 392
danjecsr 28:ed18e436f437 393 mov_button = false; //자릿수 이동버튼 플래그 초기화
danjecsr 28:ed18e436f437 394 }
danjecsr 28:ed18e436f437 395
danjecsr 28:ed18e436f437 396
danjecsr 28:ed18e436f437 397
danjecsr 28:ed18e436f437 398
danjecsr 28:ed18e436f437 399
danjecsr 28:ed18e436f437 400 //------------지시값 설정
danjecsr 28:ed18e436f437 401 //설정모드에서 값올림(△)버튼을 눌렀을 경우 올림버튼 플래그를 활성화 한다.
danjecsr 28:ed18e436f437 402 if(upin and up_button == false and set_mode == true)
danjecsr 28:ed18e436f437 403 {
danjecsr 28:ed18e436f437 404 up_button = true; //값올림 버튼 플래그 활성화
danjecsr 28:ed18e436f437 405 }
danjecsr 28:ed18e436f437 406
danjecsr 28:ed18e436f437 407 //설정모드에서 값올림 버튼을 눌렀다면 현재 커서가 깜박이는 위치의 자릿수 값을 1씩 올린다.
danjecsr 28:ed18e436f437 408 if(!upin and up_button == true and set_mode == true)
danjecsr 28:ed18e436f437 409 {
danjecsr 28:ed18e436f437 410 printf("LCD UP\r\n");
danjecsr 28:ed18e436f437 411 //10의 자릿수에 커서가 위치해 있다면 10의자릿수 값에 1을 더한다.
danjecsr 28:ed18e436f437 412 if(cursor_loc == 11)
danjecsr 28:ed18e436f437 413 {
danjecsr 28:ed18e436f437 414 SV1++;
danjecsr 28:ed18e436f437 415 //만약 더한값이 10이상이라면 다시 0으로 바꾼다.
danjecsr 28:ed18e436f437 416 if(SV1 >= 10) SV1 = 0;
danjecsr 28:ed18e436f437 417 //LCD화면의 값을 바꾼다.
danjecsr 28:ed18e436f437 418 lcd.printf("%d",SV1);
danjecsr 28:ed18e436f437 419 //화면에 프린트하면 location이 자동으로 증가하므로 다시 원래위치로 돌린다.
danjecsr 28:ed18e436f437 420 lcd.locate(11,1);
danjecsr 28:ed18e436f437 421 cursor_loc == 11;
danjecsr 28:ed18e436f437 422
danjecsr 28:ed18e436f437 423 }
danjecsr 28:ed18e436f437 424 //1의 자릿수에 커서가 위치해 있다면 1의자릿수 값에 1을 더한다.
danjecsr 28:ed18e436f437 425 else if(cursor_loc == 12)
danjecsr 28:ed18e436f437 426 {
danjecsr 28:ed18e436f437 427 SV2++;
danjecsr 28:ed18e436f437 428 //만약 더한값이 10이상이라면 다시 0으로 바꾼다.
danjecsr 28:ed18e436f437 429 if(SV2 >= 10) SV2 = 0;
danjecsr 28:ed18e436f437 430 //LCD화면의 값을 바꾼다.
danjecsr 28:ed18e436f437 431 lcd.printf("%d",SV2);
danjecsr 28:ed18e436f437 432 //화면에 프린트하면 location이 자동으로 증가하므로 다시 원래위치로 돌린다.
danjecsr 28:ed18e436f437 433 lcd.locate(12,1);
danjecsr 28:ed18e436f437 434 cursor_loc == 12;
danjecsr 28:ed18e436f437 435 }
danjecsr 28:ed18e436f437 436 //소수점1의 자릿수에 커서가 위치해 있다면 소수점1의자릿수 값에 1을 더한다.
danjecsr 28:ed18e436f437 437 else if(cursor_loc == 14)
danjecsr 28:ed18e436f437 438 {
danjecsr 28:ed18e436f437 439 SV3++;
danjecsr 28:ed18e436f437 440 //만약 더한값이 10이상이라면 다시 0으로 바꾼다.
danjecsr 28:ed18e436f437 441 if(SV3 >= 10) SV3 = 0;
danjecsr 28:ed18e436f437 442 //LCD화면의 값을 바꾼다.
danjecsr 28:ed18e436f437 443 lcd.printf("%d",SV3);
danjecsr 28:ed18e436f437 444 //화면에 프린트하면 location이 자동으로 증가하므로 다시 원래위치로 돌린다.
danjecsr 28:ed18e436f437 445 lcd.locate(14,1);
danjecsr 28:ed18e436f437 446 cursor_loc == 14;
danjecsr 28:ed18e436f437 447 }
danjecsr 28:ed18e436f437 448
danjecsr 28:ed18e436f437 449 up_button = false; //값올림 버튼 플래그 초기화
danjecsr 28:ed18e436f437 450 }
danjecsr 28:ed18e436f437 451
danjecsr 28:ed18e436f437 452
danjecsr 28:ed18e436f437 453
danjecsr 28:ed18e436f437 454
danjecsr 28:ed18e436f437 455 //설정모드에서 값내림(▽)버튼을 눌렀을 경우 내림버튼 플래그를 활성화 한다.
danjecsr 28:ed18e436f437 456 if(downin and down_button == false and set_mode == true)
danjecsr 28:ed18e436f437 457 {
danjecsr 28:ed18e436f437 458 down_button = true; //값내림 버튼 플래그 활성화
danjecsr 28:ed18e436f437 459 }
danjecsr 28:ed18e436f437 460
danjecsr 28:ed18e436f437 461 //설정모드에서 값내림 버튼을 눌렀다면 현재 커서가 깜박이는 위치의 자릿수 값을 1씩 내린다.
danjecsr 28:ed18e436f437 462 if(!downin and down_button == true and set_mode == true)
danjecsr 28:ed18e436f437 463 {
danjecsr 28:ed18e436f437 464 printf("LCD DOWN\r\n");
danjecsr 28:ed18e436f437 465 //10의 자릿수에 커서가 위치해 있다면 10의자릿수 값에 1을 뺀다.
danjecsr 28:ed18e436f437 466 if(cursor_loc == 11)
danjecsr 28:ed18e436f437 467 {
danjecsr 28:ed18e436f437 468 SV1--;
danjecsr 28:ed18e436f437 469 //만약 뺀값이 -1이하라면 값을 9로 바꾼다.
danjecsr 28:ed18e436f437 470 if(SV1 <= -1) SV1 = 9;
danjecsr 28:ed18e436f437 471 //LCD화면의 값을 바꾼다.
danjecsr 28:ed18e436f437 472 lcd.printf("%d",SV1);
danjecsr 28:ed18e436f437 473 //화면에 프린트하면 location이 자동으로 증가하므로 다시 원래위치로 돌린다.
danjecsr 28:ed18e436f437 474 lcd.locate(11,1);
danjecsr 28:ed18e436f437 475 cursor_loc == 11;
danjecsr 28:ed18e436f437 476
danjecsr 28:ed18e436f437 477 }
danjecsr 28:ed18e436f437 478 //1의 자릿수에 커서가 위치해 있다면 1의자릿수 값에 1을 뺀다
danjecsr 28:ed18e436f437 479 else if(cursor_loc == 12)
danjecsr 28:ed18e436f437 480 {
danjecsr 28:ed18e436f437 481 SV2--;
danjecsr 28:ed18e436f437 482 //만약 뺀값이 -1이하라면 값을 9로 바꾼다.
danjecsr 28:ed18e436f437 483 if(SV2 <= -1) SV2 = 9;
danjecsr 28:ed18e436f437 484 //LCD화면의 값을 바꾼다.
danjecsr 28:ed18e436f437 485 lcd.printf("%d",SV2);
danjecsr 28:ed18e436f437 486 //화면에 프린트하면 location이 자동으로 증가하므로 다시 원래위치로 돌린다.
danjecsr 28:ed18e436f437 487 lcd.locate(12,1);
danjecsr 28:ed18e436f437 488 cursor_loc == 12;
danjecsr 28:ed18e436f437 489 }
danjecsr 28:ed18e436f437 490 //소수점1의 자릿수에 커서가 위치해 있다면 소수점1의자릿수 값에 1을 뺀다
danjecsr 28:ed18e436f437 491 else if(cursor_loc == 14)
danjecsr 28:ed18e436f437 492 {
danjecsr 28:ed18e436f437 493 SV3--;
danjecsr 28:ed18e436f437 494 //만약 뺀값이 10이하라면 값을 9로 바꾼다.
danjecsr 28:ed18e436f437 495 if(SV3 <= -1) SV3 = 9;
danjecsr 28:ed18e436f437 496 //LCD화면의 값을 바꾼다.
danjecsr 28:ed18e436f437 497 lcd.printf("%d",SV3);
danjecsr 28:ed18e436f437 498 //화면에 프린트하면 location이 자동으로 증가하므로 다시 원래위치로 돌린다.
danjecsr 28:ed18e436f437 499 lcd.locate(14,1);
danjecsr 28:ed18e436f437 500 cursor_loc == 14;
danjecsr 28:ed18e436f437 501 }
danjecsr 28:ed18e436f437 502
danjecsr 28:ed18e436f437 503 down_button = false; //값내림 버튼 플래그 초기화
danjecsr 28:ed18e436f437 504 }
danjecsr 28:ed18e436f437 505
danjecsr 28:ed18e436f437 506
danjecsr 28:ed18e436f437 507
danjecsr 28:ed18e436f437 508
danjecsr 28:ed18e436f437 509 //쓰레드 대기
danjecsr 28:ed18e436f437 510 Thread::wait(10);
danjecsr 28:ed18e436f437 511 }
danjecsr 28:ed18e436f437 512 }
danjecsr 28:ed18e436f437 513
danjecsr 28:ed18e436f437 514
danjecsr 28:ed18e436f437 515
danjecsr 28:ed18e436f437 516
danjecsr 28:ed18e436f437 517
danjecsr 28:ed18e436f437 518
danjecsr 28:ed18e436f437 519
danjecsr 28:ed18e436f437 520
danjecsr 28:ed18e436f437 521
danjecsr 28:ed18e436f437 522
danjecsr 28:ed18e436f437 523
danjecsr 28:ed18e436f437 524
Davidroid 0:5148e9486cf2 525 /* Main ----------------------------------------------------------------------*/
Davidroid 0:5148e9486cf2 526
Davidroid 0:5148e9486cf2 527 int main()
Davidroid 0:5148e9486cf2 528 {
danjecsr 29:d5c13978c8e9 529 //설정값을 FLASH메모리에서 읽고쓰기하기 위하여 락을 해제한다.
danjecsr 29:d5c13978c8e9 530 HAL_FLASH_Unlock();
danjecsr 29:d5c13978c8e9 531 EE_Init();
danjecsr 28:ed18e436f437 532
danjecsr 28:ed18e436f437 533 //LCD제어를 위한 쓰레드를 호출
danjecsr 28:ed18e436f437 534 Thread thread(LCD_CTRL_THREAD);
Davidroid 1:9f1974b0960d 535
danjecsr 28:ed18e436f437 536
danjecsr 28:ed18e436f437 537
danjecsr 29:d5c13978c8e9 538
danjecsr 28:ed18e436f437 539
danjecsr 28:ed18e436f437 540
danjecsr 28:ed18e436f437 541 //스텝모터 드라이브와 F401RE보드와 통신하기 위하여 SPI통신핀을 초기화 해준다.
Davidroid 23:073b26366d03 542 #ifdef TARGET_STM32F429
Davidroid 23:073b26366d03 543 DevSPI dev_spi(D11, D12, D13);
Davidroid 23:073b26366d03 544 #else
Davidroid 3:fd280b953f77 545 DevSPI dev_spi(D11, D12, D3);
Davidroid 23:073b26366d03 546 #endif
Davidroid 0:5148e9486cf2 547
danjecsr 28:ed18e436f437 548 //확장보드 초기화
Davidroid 26:caec5f51abe8 549 x_nucleo_ihm02a1 = new XNucleoIHM02A1(&init[0], &init[1], A4, A5, D4, A2, &dev_spi);
Davidroid 0:5148e9486cf2 550
danjecsr 28:ed18e436f437 551 //모터 컨트롤 모터리스트 객체
davide.aliprandi@st.com 24:d1f487cb02ba 552 L6470 **motors = x_nucleo_ihm02a1->get_components();
Davidroid 0:5148e9486cf2 553
danjecsr 28:ed18e436f437 554 //콘솔화면 프린트
Davidroid 0:5148e9486cf2 555 printf("Motor Control Application Example for 2 Motors\r\n\n");
Davidroid 0:5148e9486cf2 556
Davidroid 1:9f1974b0960d 557
danjecsr 29:d5c13978c8e9 558 //절삭유와 희석수의 현재위치값을 가져온다.
danjecsr 29:d5c13978c8e9 559 for (int i=2; i<4; i++)
danjecsr 29:d5c13978c8e9 560 {
danjecsr 29:d5c13978c8e9 561 EE_ReadVariable(VirtAddVarTab[i], &VarDataTab[i]);
danjecsr 29:d5c13978c8e9 562 }
danjecsr 29:d5c13978c8e9 563
danjecsr 29:d5c13978c8e9 564 //절삭유 현재위치값을 플래쉬 메모리에서 가져온다.
danjecsr 29:d5c13978c8e9 565 oilcurrposition = VarDataTab[2];
danjecsr 29:d5c13978c8e9 566 //희석수 현재위치값을 플래쉬 메모리에서 가져온다.
danjecsr 29:d5c13978c8e9 567 watercurrposition = VarDataTab[3];
danjecsr 29:d5c13978c8e9 568
danjecsr 29:d5c13978c8e9 569 //만약 현재의 위치가 홈포지션(0)이 아니라면 홈포지션으로 모터를 회전시킨다.
danjecsr 29:d5c13978c8e9 570 printf("currunt oil valve position %d",oilcurrposition);
danjecsr 29:d5c13978c8e9 571
danjecsr 28:ed18e436f437 572 //제일처음 전원이 들어왔을경우 현재값을 초기값으로 지정한다.
danjecsr 28:ed18e436f437 573 printf("--> Set Home position.\r\n");
davide.aliprandi@st.com 24:d1f487cb02ba 574 motors[0]->set_home();
danjecsr 29:d5c13978c8e9 575 //oilhomeposition = motors[0]->get_position();
danjecsr 29:d5c13978c8e9 576 oilhomeposition = 0;
danjecsr 28:ed18e436f437 577
Davidroid 1:9f1974b0960d 578
danjecsr 28:ed18e436f437 579 motors[1]->set_home();
danjecsr 29:d5c13978c8e9 580 //waterhomeposition = motors[0]->get_position();
danjecsr 29:d5c13978c8e9 581 waterhomeposition = 0;
danjecsr 28:ed18e436f437 582 //wait_ms(DELAY_1);
danjecsr 28:ed18e436f437 583
danjecsr 28:ed18e436f437 584
danjecsr 28:ed18e436f437 585
danjecsr 29:d5c13978c8e9 586
danjecsr 29:d5c13978c8e9 587
danjecsr 29:d5c13978c8e9 588
danjecsr 29:d5c13978c8e9 589
Davidroid 1:9f1974b0960d 590
danjecsr 28:ed18e436f437 591 //루프를 돌면서 농도값,밸브열림%,설정,모터제어 관련 작업을 진행한다.
danjecsr 28:ed18e436f437 592 while(1)
danjecsr 28:ed18e436f437 593 {
danjecsr 29:d5c13978c8e9 594 //현재시간을 체크한다.
danjecsr 29:d5c13978c8e9 595 NOW = time(NULL);
danjecsr 28:ed18e436f437 596
danjecsr 28:ed18e436f437 597 //현재 농도값을 읽는다.
danjecsr 28:ed18e436f437 598 //아날로그 값은 0~1값으로 들어온다. (참고로 STM32F401보드는 ADC의 분해능이 12bit이다.)
danjecsr 29:d5c13978c8e9 599 //165옴 저항을 사용했을경우 아래와 같은 범위에서 값이 들어온다.
danjecsr 29:d5c13978c8e9 600 //4ma = 0.66V, 20ma = 3.3v이다.
danjecsr 28:ed18e436f437 601
danjecsr 28:ed18e436f437 602
danjecsr 29:d5c13978c8e9 603 //Nucleo-64보드의 아날로그read()함수는 값을 아두이노처럼 0~3.3v사이의 값을 분해능값으로 (즉 0~4095)로
danjecsr 28:ed18e436f437 604 //리턴하는것이 아니라 Voltage값으로 리턴한다.(내부적으로 아날로그값을 Voltage로 바꾸어준다.)
danjecsr 29:d5c13978c8e9 605 //0~1 사이의 값을 리턴하는데 그값을 보드의 기준전압인 3.3을 곱해주면 현재 아날로그 입력으로 들어오는 전압값을 알수 있다.
danjecsr 29:d5c13978c8e9 606 //따라서 4ma의 전압값은 0.66v이고 20ma의 값은 3.3v이므로 (입력값-최저값)*100/(최대값-최저값) 계산으로 농도가 몇%인지 계산이 가능하다.
danjecsr 28:ed18e436f437 607
danjecsr 28:ed18e436f437 608 float cc = CurCon.read()* 3.3;
danjecsr 29:d5c13978c8e9 609 //float cc = CurCon.read()* 3.3;
danjecsr 28:ed18e436f437 610 printf("CC = %f \r\n",cc);
danjecsr 28:ed18e436f437 611
danjecsr 28:ed18e436f437 612
danjecsr 29:d5c13978c8e9 613 //3.3v신호를 사용할것이므로 165옴의 저항을 연결하면 4ma = 0.66V, 20ma = 3.3v가된다.
danjecsr 28:ed18e436f437 614 //따라서 현재들어오는 전압값을 100분율로 계산하면 몇%의 절삭유농도인지 알수가 있다.
danjecsr 29:d5c13978c8e9 615 //4ma = -2.0% ~ 20ma = 33.5%
danjecsr 28:ed18e436f437 616 //PV = ((cc - 1)*100.0)/(5.0 - 1);
danjecsr 29:d5c13978c8e9 617 //0V ~ 3.3V를 백분율로 계산한다.
danjecsr 29:d5c13978c8e9 618 CPV = ((cc - 0.66)*35.5)/(3.3 - 0.66) - 2.0;
danjecsr 29:d5c13978c8e9 619 //printf("PV = %f \r\n",PV);
danjecsr 29:d5c13978c8e9 620
danjecsr 29:d5c13978c8e9 621
danjecsr 29:d5c13978c8e9 622 //샘플링 시간을 비교한다.
danjecsr 29:d5c13978c8e9 623 //샘플링 시간 1초를 지나면 평균값으로 PV값을 입력한다.
danjecsr 29:d5c13978c8e9 624 if(NOW - SAMPLE >=2)
danjecsr 29:d5c13978c8e9 625 {
danjecsr 29:d5c13978c8e9 626 PV = SPV;
danjecsr 29:d5c13978c8e9 627 samplecnt = 0;
danjecsr 29:d5c13978c8e9 628 SPV = 0;
danjecsr 29:d5c13978c8e9 629 SAMPLE = NOW;
danjecsr 29:d5c13978c8e9 630 }
danjecsr 29:d5c13978c8e9 631 //샘플링 시간이 지나가지 않았다면 계속 평균값을 구한다.
danjecsr 29:d5c13978c8e9 632 else
danjecsr 29:d5c13978c8e9 633 {
danjecsr 29:d5c13978c8e9 634
danjecsr 29:d5c13978c8e9 635 if(samplecnt == 0) SPV = CPV;
danjecsr 29:d5c13978c8e9 636 else
danjecsr 29:d5c13978c8e9 637 {
danjecsr 29:d5c13978c8e9 638 SPV = (SPV + CPV) / 2;
danjecsr 29:d5c13978c8e9 639 }
danjecsr 29:d5c13978c8e9 640 samplecnt++;
danjecsr 29:d5c13978c8e9 641 }
danjecsr 28:ed18e436f437 642
danjecsr 28:ed18e436f437 643
danjecsr 28:ed18e436f437 644
danjecsr 28:ed18e436f437 645
danjecsr 28:ed18e436f437 646
danjecsr 28:ed18e436f437 647
danjecsr 29:d5c13978c8e9 648
danjecsr 28:ed18e436f437 649
danjecsr 28:ed18e436f437 650
danjecsr 28:ed18e436f437 651 //만약 절삭유 농도가 10%(기준농도) 미만이라면 절삭유탱크 밸브를 연다.
danjecsr 28:ed18e436f437 652 if(PV < SV - 0.5)
danjecsr 28:ed18e436f437 653 {
danjecsr 28:ed18e436f437 654 //수탱크 밸브가 열려있다면
danjecsr 28:ed18e436f437 655 if(waterhomeposition != motors[1]->get_position())
danjecsr 28:ed18e436f437 656 {
danjecsr 28:ed18e436f437 657 //수탱크 밸브를 원상복귀 시킨다.
danjecsr 28:ed18e436f437 658 printf("--> Going Home Position Water Tank Value.\r\n");
danjecsr 28:ed18e436f437 659 motors[1]->go_home();
danjecsr 28:ed18e436f437 660 //수탱크 밸브가 HOME 위치로 갈때까지 대기
danjecsr 28:ed18e436f437 661 motors[1]->wait_while_active();
danjecsr 28:ed18e436f437 662
danjecsr 29:d5c13978c8e9 663 //플래시메모리에 현재의 희석수 밸브 포지션을 저장한다.
danjecsr 29:d5c13978c8e9 664 VarDataTab[3] = 0;
danjecsr 29:d5c13978c8e9 665 EE_WriteVariable(VirtAddVarTab[3],VarDataTab[3] );
danjecsr 29:d5c13978c8e9 666
danjecsr 28:ed18e436f437 667 WATER_VALVE_ON = false;
danjecsr 28:ed18e436f437 668
danjecsr 28:ed18e436f437 669 //현재밸브가 열린%를 계산한다.
danjecsr 28:ed18e436f437 670 WATER_VALVE_OPEN_P = 0.0;
danjecsr 28:ed18e436f437 671 }
danjecsr 28:ed18e436f437 672
danjecsr 28:ed18e436f437 673
danjecsr 28:ed18e436f437 674 //만약 절삭유밸브가 열려있지 않다면 밸브를 연다.
danjecsr 28:ed18e436f437 675 if(oilhomeposition == motors[0]->get_position())
danjecsr 28:ed18e436f437 676 {
danjecsr 28:ed18e436f437 677 //밸브를 앞방향으로 90도(모터2바퀴) 돌린다.
danjecsr 28:ed18e436f437 678 printf("--> Moving forward Oil Tank Valve %d steps.\r\n", STEPS_2);
danjecsr 28:ed18e436f437 679 //모터회전 명령을 내린다.
danjecsr 28:ed18e436f437 680 motors[0]->move(StepperMotor::FWD, STEPS_2);
danjecsr 28:ed18e436f437 681 //모터의 회전이 완료될때까지 기다린다.
danjecsr 28:ed18e436f437 682 motors[0]->wait_while_active();
danjecsr 28:ed18e436f437 683
danjecsr 29:d5c13978c8e9 684 //절삭유모터의 2바퀴회전후의 포지션을 가져온다.
danjecsr 29:d5c13978c8e9 685 short oilcurrposition = motors[0]->get_position();
danjecsr 29:d5c13978c8e9 686 printf("--> Oil Tank Valve Position %d \r\n", oilcurrposition);
danjecsr 29:d5c13978c8e9 687
danjecsr 29:d5c13978c8e9 688 //플래시메모리에 현재의 절삭유 밸브 포지션을 저장한다.
danjecsr 29:d5c13978c8e9 689 VarDataTab[2] = oilcurrposition;
danjecsr 29:d5c13978c8e9 690 EE_WriteVariable(VirtAddVarTab[2],VarDataTab[2] );
danjecsr 29:d5c13978c8e9 691
danjecsr 28:ed18e436f437 692 OIL_VALVE_ON = true;
danjecsr 28:ed18e436f437 693
danjecsr 28:ed18e436f437 694 //오일밸브 타이머 시작
danjecsr 28:ed18e436f437 695 //OIL_VALVE_TIMER.start();
danjecsr 28:ed18e436f437 696 OIL_VALVE_OPEN_TIME = time(NULL);
danjecsr 28:ed18e436f437 697
danjecsr 28:ed18e436f437 698 //현재밸브가 열린%를 계산한다.
danjecsr 28:ed18e436f437 699 OIL_VALVE_OPEN_P = (STEPS_2*100)/STEPS_2;
danjecsr 28:ed18e436f437 700
danjecsr 28:ed18e436f437 701 }
danjecsr 28:ed18e436f437 702
danjecsr 28:ed18e436f437 703 //만약 오일밸브 타이머가 시작되어 있다면 시간을 체크한다.
danjecsr 28:ed18e436f437 704 if(OIL_VALVE_ON == true)
danjecsr 28:ed18e436f437 705 {
danjecsr 28:ed18e436f437 706
danjecsr 28:ed18e436f437 707 //만약 절삭유의 현재값이 목표값(설정값) - 0.5 이상이고 절삭유밸브가 OPEN되고 2초이상 지났다면 절삭유가 파이프를 통해서 흘러가는 잔류량을 고려하여 밸브를 닫는다.
danjecsr 28:ed18e436f437 708 if(PV >= SV - 0.5)
danjecsr 28:ed18e436f437 709 {
danjecsr 28:ed18e436f437 710 if((NOW - OIL_VALVE_OPEN_TIME) > 2)
danjecsr 28:ed18e436f437 711 {
danjecsr 28:ed18e436f437 712 printf("--> Going Home Position Oil Tank Value.\r\n");
danjecsr 28:ed18e436f437 713 motors[0]->go_home();
danjecsr 28:ed18e436f437 714 //절삭유탱크 밸브가 HOME 위치로 갈때까지 대기
danjecsr 28:ed18e436f437 715 motors[0]->wait_while_active();
danjecsr 28:ed18e436f437 716
danjecsr 28:ed18e436f437 717 OIL_VALVE_ON = false;
danjecsr 28:ed18e436f437 718 }
danjecsr 28:ed18e436f437 719 }
danjecsr 28:ed18e436f437 720 //printf("--> Aready Oil Tank Valve Opened\r\n");
danjecsr 28:ed18e436f437 721 }
danjecsr 28:ed18e436f437 722
danjecsr 28:ed18e436f437 723
danjecsr 28:ed18e436f437 724
danjecsr 28:ed18e436f437 725
danjecsr 28:ed18e436f437 726 }
danjecsr 29:d5c13978c8e9 727 //만약 절삭유 농도가 10%(기준농도) < 현재농도 < 10.5% 라면 수탱크 밸브를 연다.
danjecsr 28:ed18e436f437 728 else if(SV + 0.5 <= PV )
danjecsr 28:ed18e436f437 729 {
danjecsr 28:ed18e436f437 730 //절삭유 탱크 밸브가 열려있다면
danjecsr 28:ed18e436f437 731 if(waterhomeposition != motors[0]->get_position())
danjecsr 28:ed18e436f437 732 {
danjecsr 28:ed18e436f437 733 //절삭유 탱크 밸브를 원상복귀 시킨다.
danjecsr 28:ed18e436f437 734 printf("--> Going Home Position Oil Tank Valve\r\n");
danjecsr 28:ed18e436f437 735 motors[0]->go_home();
danjecsr 28:ed18e436f437 736 //절삭유탱크 밸브가 HOME 위치로 갈때까지 대기
danjecsr 28:ed18e436f437 737 motors[0]->wait_while_active();
danjecsr 28:ed18e436f437 738
danjecsr 28:ed18e436f437 739 OIL_VALVE_ON = false;
danjecsr 28:ed18e436f437 740
danjecsr 28:ed18e436f437 741 //현재밸브가 열린%를 계산한다.
danjecsr 28:ed18e436f437 742 OIL_VALVE_OPEN_P = 0.0;
danjecsr 28:ed18e436f437 743 }
danjecsr 28:ed18e436f437 744
danjecsr 28:ed18e436f437 745
danjecsr 28:ed18e436f437 746 //만약 절삭유밸브가 열려있지 않다면 밸브를 연다.
danjecsr 28:ed18e436f437 747 if(waterhomeposition == motors[1]->get_position())
danjecsr 28:ed18e436f437 748 {
danjecsr 28:ed18e436f437 749 //밸브를 앞방향으로 45도(1바퀴) 돌린다.
danjecsr 28:ed18e436f437 750 printf("--> Moving forward Water Tank Valve %d steps.\r\n", STEPS_2);
danjecsr 28:ed18e436f437 751 //모터회전 명령을 내린다.
danjecsr 28:ed18e436f437 752 motors[1]->move(StepperMotor::FWD, STEPS_2);
danjecsr 28:ed18e436f437 753 //모터의 회전이 완료될때까지 기다린다.
danjecsr 28:ed18e436f437 754 motors[1]->wait_while_active();
danjecsr 28:ed18e436f437 755
danjecsr 28:ed18e436f437 756 WATER_VALVE_ON = true;
danjecsr 28:ed18e436f437 757
danjecsr 28:ed18e436f437 758 //희석수탱크밸브 타이머 시작
danjecsr 28:ed18e436f437 759 //WATER_VALVE_TIMER.start()
danjecsr 28:ed18e436f437 760 WATER_VALVE_OPEN_TIME = time(NULL);
danjecsr 28:ed18e436f437 761
danjecsr 28:ed18e436f437 762 //현재밸브가 열린%를 계산한다.
danjecsr 28:ed18e436f437 763 WATER_VALVE_OPEN_P = (STEPS_2*100)/STEPS_2;
danjecsr 28:ed18e436f437 764
danjecsr 28:ed18e436f437 765 }
danjecsr 28:ed18e436f437 766
danjecsr 28:ed18e436f437 767 //만약 수탱크 타이머가 시작되어 있다면 시간을 체크한다.
danjecsr 28:ed18e436f437 768 if(WATER_VALVE_ON == true)
danjecsr 28:ed18e436f437 769 {
danjecsr 28:ed18e436f437 770 //만약 절삭유의 현재값이 기준값(목표값)+ 0.5 이하이고 절삭유밸브가 OPEN되고 2초이상 지났다면 절삭유가 파이프를 통해서 흘러가는 잔류량을 고려하여 밸브를 닫는다.
danjecsr 28:ed18e436f437 771 if(PV <= SV + 0.5)
danjecsr 28:ed18e436f437 772 {
danjecsr 28:ed18e436f437 773 if((NOW - WATER_VALVE_OPEN_TIME) > 2)
danjecsr 28:ed18e436f437 774 {
danjecsr 28:ed18e436f437 775 printf("--> Going Home Position Oil Tank Value.\r\n");
danjecsr 28:ed18e436f437 776 motors[1]->go_home();
danjecsr 28:ed18e436f437 777 //희석수탱크 밸브가 HOME 위치로 갈때까지 대기
danjecsr 28:ed18e436f437 778 motors[1]->wait_while_active();
danjecsr 28:ed18e436f437 779
danjecsr 28:ed18e436f437 780 OIL_VALVE_ON = false;
danjecsr 28:ed18e436f437 781 }
danjecsr 28:ed18e436f437 782 }
danjecsr 28:ed18e436f437 783 }
danjecsr 28:ed18e436f437 784
danjecsr 28:ed18e436f437 785 }
danjecsr 28:ed18e436f437 786 //정상이라면 절삭유탱크밸브 및 수탱크밸브를 HOME위치로 이동시킨다.
danjecsr 28:ed18e436f437 787 else
danjecsr 28:ed18e436f437 788 {
danjecsr 28:ed18e436f437 789 //절삭유 탱크 밸브를 원상복귀 시킨다.
danjecsr 28:ed18e436f437 790 //절삭유 탱크 밸브가 열려있다면
danjecsr 28:ed18e436f437 791 if(waterhomeposition != motors[0]->get_position())
danjecsr 28:ed18e436f437 792 {
danjecsr 28:ed18e436f437 793 printf("--> Going Home Position Oil Tank Value.\r\n");
danjecsr 28:ed18e436f437 794 motors[0]->go_home();
danjecsr 28:ed18e436f437 795 //절삭유탱크 밸브가 HOME 위치로 갈때까지 대기
danjecsr 28:ed18e436f437 796 motors[0]->wait_while_active();
danjecsr 28:ed18e436f437 797
danjecsr 28:ed18e436f437 798 OIL_VALVE_ON = false;
danjecsr 28:ed18e436f437 799
danjecsr 28:ed18e436f437 800 //현재밸브가 열린%를 계산한다.
danjecsr 28:ed18e436f437 801 OIL_VALVE_OPEN_P = 0.0;
danjecsr 28:ed18e436f437 802 }
danjecsr 28:ed18e436f437 803
danjecsr 28:ed18e436f437 804
danjecsr 28:ed18e436f437 805 //희석수탱크 밸브가 열려있다면
danjecsr 28:ed18e436f437 806 if(waterhomeposition != motors[1]->get_position())
danjecsr 28:ed18e436f437 807 {
danjecsr 28:ed18e436f437 808 //수탱크 밸브를 원상복귀 시킨다.
danjecsr 28:ed18e436f437 809 printf("--> Going Home Position Water Tank Value.\r\n");
danjecsr 28:ed18e436f437 810 motors[1]->go_home();
danjecsr 28:ed18e436f437 811 //희석수탱크 밸브가 HOME 위치로 갈때까지 대기
danjecsr 28:ed18e436f437 812 motors[1]->wait_while_active();
danjecsr 28:ed18e436f437 813
danjecsr 28:ed18e436f437 814 WATER_VALVE_ON = false;
danjecsr 28:ed18e436f437 815
danjecsr 28:ed18e436f437 816 //현재밸브가 열린%를 계산한다.
danjecsr 28:ed18e436f437 817 WATER_VALVE_OPEN_P = 0.0;
danjecsr 28:ed18e436f437 818 }
danjecsr 28:ed18e436f437 819 }
danjecsr 28:ed18e436f437 820
danjecsr 28:ed18e436f437 821
danjecsr 28:ed18e436f437 822
danjecsr 28:ed18e436f437 823
danjecsr 28:ed18e436f437 824
danjecsr 28:ed18e436f437 825
danjecsr 28:ed18e436f437 826
danjecsr 28:ed18e436f437 827
danjecsr 28:ed18e436f437 828
danjecsr 28:ed18e436f437 829 //내부적인 프로세스 처리를 우해서 반드시 일정시간 멈추어야한다.
danjecsr 28:ed18e436f437 830 Thread::wait(10);
danjecsr 28:ed18e436f437 831
danjecsr 28:ed18e436f437 832 //wait_ms(100);
danjecsr 28:ed18e436f437 833
danjecsr 28:ed18e436f437 834
danjecsr 28:ed18e436f437 835
Davidroid 22:e81ccf73bc5d 836 }
Davidroid 18:591a007effc2 837
Davidroid 1:9f1974b0960d 838
Davidroid 1:9f1974b0960d 839
Davidroid 22:e81ccf73bc5d 840 }