200117StepMotorControl

Dependencies:   X_NUCLEO_IHM02A1 TextLCD

Revision:
29:d5c13978c8e9
Parent:
28:ed18e436f437
diff -r ed18e436f437 -r d5c13978c8e9 main.cpp
--- a/main.cpp	Thu Jan 16 06:27:47 2020 +0000
+++ b/main.cpp	Fri Jan 17 07:58:29 2020 +0000
@@ -43,10 +43,7 @@
 DigitalIn upin(D14,PullDown);    //값올림 버튼
 DigitalIn downin(D2,PullDown);  //값내림 버튼
 
-//DigitalIn set(D9);   //설정버튼
-//DigitalIn mov(D8);   //자릿수선택 버튼
-//DigitalIn up(D1);    //값올림 버튼
-//DigitalIn down(D0);  //값내림 버튼
+
 //LCD 출력의 현재시각 측정(단위:초)
 time_t NOWLCD;
 //LCD 출력을 조절하기 위한 이전시각(NOWLCD)저장
@@ -61,12 +58,15 @@
 int   SET_SV2 = 0;            //설정모드에서 표시될 농도 지시값(1의 자릿수값)
 int   SET_SV3 = 0;            //설정모드에서 표시될 농도 지시값(소수점1의 자릿수값)
 
+//lcd설정값과 밸브의 현재위치를 저장하기 위한 플래쉬메모리의 위치(LCD설정값(0x0000,0x0001), 밸브의 현재위치(0x0002,0x0003)(오일밸브현재 위치,희석수밸브현재위치
+uint16_t VirtAddVarTab[4] = {0x0000, 0x0001, 0x0002, 0x0003};
+//lcd설정값(자연수,소수점,절삭유현재위치,희석수현재위치)
+uint16_t VarDataTab[] = {0, 0, 0, 0};
 
-uint16_t VirtAddVarTab[2] = {0x0000, 0x0001};
-uint16_t VarDataTab[] = {0, 0};
-
-float PV  = 0;                //현재측정 절삭유 농도값
-float PPV = 0;                //이전측정 절각유 농도값
+float PV  = 0;                //1초동안 샘플링한 절삭유 농도값
+float PPV = 0;                //이전측정 절삭유 농도값
+float CPV = 0;                //현재 절삭유 농도값
+float SPV = 0;                //1초동안 계속 평균을 계산하여 저장하는 절삭유 농도값
 
 int OIL_VALVE_OPEN_P = 0;     //오일밸브 열림%
 int WATER_VALVE_OPEN_P = 0;   //희석수밸브 열림%
@@ -165,6 +165,15 @@
 int oilhomeposition = 0;
 int waterhomeposition = 0;
 
+
+//샘플링 카운트 수
+int samplecnt = 0;
+
+
+//절삭유밸브와 희석수밸브의 현재 포지션
+short oilcurrposition = 0;
+short watercurrposition = 0;
+
 //오일탱크밸브와 수탱크밸브가 오픈된 시간을 저장
 Timer OIL_VALVE_TIMER;
 Timer WATER_VALVE_TIMER;
@@ -177,6 +186,9 @@
 //현재시각
 time_t NOW;
 
+//농도값 샘플링을 위한 시각비교값 저장
+time_t SAMPLE;
+
 //오일탱크밸브와 수탱크밸브가 열려있는지 저장
 bool OIL_VALVE_ON = false;
 bool WATER_VALVE_ON = false;
@@ -193,9 +205,9 @@
 void LCD_CTRL_THREAD(void const *args)
 {
     
-    //설정값을 FLASH메모리에서 읽고쓰기하기 위하여 락을 해제한다.
-    HAL_FLASH_Unlock();
-    EE_Init();
+    ////설정값을 FLASH메모리에서 읽고쓰기하기 위하여 락을 해제한다.
+    //HAL_FLASH_Unlock();
+    //EE_Init();
     
     
     //SV값은 총4byte float값인데 EEPROM Library는 기본적으로 2byte씩메모리를 엑세스하게 되어있음
@@ -253,7 +265,7 @@
         NOWLCD = time(NULL);
         /*------------------------------- LCD표시 ---------------------------------------------------*/
         //1.5초마다 화면을 갱신한다.
-        if(NOWLCD - DISPLAY_TIME >= 1.5 and !set_mode)
+        if(NOWLCD - DISPLAY_TIME >= 1 and !set_mode)
         {
         
             //현재 측정한 절삭유 농도값이 이전측정값과 다르다면 LCD화면을 갱신한다.
@@ -514,14 +526,16 @@
 
 int main()
 {
-    
+    //설정값을 FLASH메모리에서 읽고쓰기하기 위하여 락을 해제한다.
+    HAL_FLASH_Unlock();
+    EE_Init();
     
     //LCD제어를 위한 쓰레드를 호출
     Thread thread(LCD_CTRL_THREAD);
 
     
     
-    //while(1);
+
     
     
     //스텝모터 드라이브와 F401RE보드와 통신하기 위하여 SPI통신핀을 초기화 해준다.
@@ -541,53 +555,97 @@
     printf("Motor Control Application Example for 2 Motors\r\n\n");
 
 
+    //절삭유와 희석수의 현재위치값을 가져온다.
+    for (int i=2; i<4; i++)
+    {
+        EE_ReadVariable(VirtAddVarTab[i], &VarDataTab[i]);
+    }
+
+    //절삭유 현재위치값을 플래쉬 메모리에서 가져온다.
+    oilcurrposition = VarDataTab[2];
+    //희석수 현재위치값을 플래쉬 메모리에서 가져온다.
+    watercurrposition = VarDataTab[3];
+    
+    //만약 현재의 위치가 홈포지션(0)이 아니라면 홈포지션으로 모터를 회전시킨다.
+    printf("currunt oil valve position %d",oilcurrposition); 
+
     //제일처음 전원이 들어왔을경우 현재값을 초기값으로 지정한다.
     printf("--> Set Home position.\r\n");
     motors[0]->set_home();
-    oilhomeposition = motors[0]->get_position();
+    //oilhomeposition = motors[0]->get_position();
+    oilhomeposition = 0;
     
     
     motors[1]->set_home();
-    waterhomeposition = motors[0]->get_position();
+    //waterhomeposition = motors[0]->get_position();
+    waterhomeposition = 0;
     //wait_ms(DELAY_1);
     
     
     
+    
+    
+    
+    
 
     //루프를 돌면서 농도값,밸브열림%,설정,모터제어 관련 작업을 진행한다.
     while(1)
     {
-        
+        //현재시간을 체크한다.
+        NOW = time(NULL);
         
         //현재 농도값을 읽는다.
         //아날로그 값은 0~1값으로 들어온다. (참고로 STM32F401보드는 ADC의 분해능이 12bit이다.)
-        //250옴 저항을 사용했을경우 아래와 같은 범위에서 값이 들어온다. 
-        //4ma = 1V, 20ma = 5v이다. 
+        //165옴 저항을 사용했을경우 아래와 같은 범위에서 값이 들어온다. 
+        //4ma = 0.66V, 20ma = 3.3v이다. 
         
         
-        //Nucleo-64보드의 아날로그read()함수는 값을 아두이노처럼 0~5v사이의 값을 분해능값으로 (즉 0~4095)로 
+        //Nucleo-64보드의 아날로그read()함수는 값을 아두이노처럼 0~3.3v사이의 값을 분해능값으로 (즉 0~4095)로 
         //리턴하는것이 아니라 Voltage값으로 리턴한다.(내부적으로 아날로그값을 Voltage로 바꾸어준다.)
-        //0~1 사이의 값을 리턴하는데 그값을 보드의 기준전압인 5.0을 곱해주면 현재 아날로그 입력으로 들어오는 전압값을 알수 있다.
-        //따라서 4ma의 전압값은 1.0v이고 20ma의 값은 5.0v이므로 (입력값-최저값)*100/(최대값-최저값) 계산으로 농도가 몇%인지 계산이 가능하다. 
+        //0~1 사이의 값을 리턴하는데 그값을 보드의 기준전압인 3.3을 곱해주면 현재 아날로그 입력으로 들어오는 전압값을 알수 있다.
+        //따라서 4ma의 전압값은 0.66v이고 20ma의 값은 3.3v이므로 (입력값-최저값)*100/(최대값-최저값) 계산으로 농도가 몇%인지 계산이 가능하다. 
         
         float cc = CurCon.read()* 3.3;
+        //float cc = CurCon.read()* 3.3;
         printf("CC = %f \r\n",cc);
         
         
-        //5V시그널을 사용할것이므로 250옴의 저항을 연결하면 4ma = 1.0V, 20ma = 5.0v가된다.
+        //3.3v신호를 사용할것이므로 165옴의 저항을 연결하면 4ma = 0.66V, 20ma = 3.3v가된다.
         //따라서 현재들어오는 전압값을 100분율로 계산하면 몇%의 절삭유농도인지 알수가 있다.
+        //4ma = -2.0% ~ 20ma = 33.5%
         //PV = ((cc - 1)*100.0)/(5.0 - 1);
-        //3.3V로 계산
-        PV = ((cc - 0.66)*100.0)/(3.3 - 0.66);
-        printf("PV = %f \r\n",PV);
+        //0V ~ 3.3V를 백분율로 계산한다.
+        CPV = ((cc - 0.66)*35.5)/(3.3 - 0.66) - 2.0;
+        //printf("PV = %f \r\n",PV);
+        
+        
+        //샘플링 시간을 비교한다.
+        //샘플링 시간 1초를 지나면 평균값으로 PV값을 입력한다.
+        if(NOW - SAMPLE >=2)
+        {
+            PV = SPV;
+            samplecnt = 0;
+            SPV = 0;
+            SAMPLE = NOW;
+        }
+        //샘플링 시간이 지나가지 않았다면 계속 평균값을 구한다.
+        else
+        {
+            
+            if(samplecnt == 0) SPV = CPV;
+            else
+            {
+                SPV = (SPV + CPV) / 2;
+            }
+            samplecnt++;
+        }
         
         
         
         
              
         
-        //현재시간을 체크한다.
-        NOW = time(NULL);
+        
         
         
         //만약 절삭유 농도가  10%(기준농도) 미만이라면 절삭유탱크 밸브를 연다.
@@ -602,6 +660,10 @@
                 //수탱크 밸브가 HOME 위치로 갈때까지 대기
                 motors[1]->wait_while_active();
                 
+                //플래시메모리에 현재의 희석수 밸브 포지션을 저장한다.
+                VarDataTab[3] = 0;
+                EE_WriteVariable(VirtAddVarTab[3],VarDataTab[3] );
+                
                 WATER_VALVE_ON = false;
                 
                 //현재밸브가 열린%를 계산한다.
@@ -619,6 +681,14 @@
                 //모터의 회전이 완료될때까지 기다린다.
                 motors[0]->wait_while_active();
                 
+                //절삭유모터의 2바퀴회전후의 포지션을 가져온다. 
+                short oilcurrposition = motors[0]->get_position();
+                printf("--> Oil Tank Valve Position %d \r\n", oilcurrposition);
+                
+                //플래시메모리에 현재의 절삭유 밸브 포지션을 저장한다.
+                VarDataTab[2] = oilcurrposition;
+                EE_WriteVariable(VirtAddVarTab[2],VarDataTab[2] );
+                
                 OIL_VALVE_ON = true;
                 
                 //오일밸브 타이머 시작
@@ -654,7 +724,7 @@
             
             
         }
-        //만약 절삭유 농도가 10%(기준농도) < 현재농도 < 12% 라면 수탱크 밸브를 연다.
+        //만약 절삭유 농도가 10%(기준농도) < 현재농도 < 10.5% 라면 수탱크 밸브를 연다.
         else if(SV + 0.5 <= PV )
         {
             //절삭유 탱크 밸브가 열려있다면