millis() и ISR

sivanko
Offline
Зарегистрирован: 25.02.2016

Добрый день. Возникла проблема. Переделываю под себя програму для управления токарником на ардуино.

Проблема в том что millis() выдает все время 0. Изза этого не получается настроить тахометр. Возможно ли это изза использования ISR прерываний? Хотя в предидущей версии прошивки тахометр работает. Мозг сломан. Читал что millis() не работает в самом прерывании. В теле програмы должно работать... Ткните носом куда копать?

rkit
Offline
Зарегистрирован: 23.11.2016

Все твои предположения неверны. Копать нужно в код.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

sivanko пишет:
Ткните носом куда копать?

В сторону размещения кода. И строго по правилам форума, иначе его никто не станет читать.

sivanko
Offline
Зарегистрирован: 25.02.2016
#include <avr/pgmspace.h>

/////////////////////////////////////////////////////////
// ***** Параметры *****
#define Motor_X_Step_Per_Rev    200      // Кол-во шагов/об, ось X
#define Motor_Y_Step_Per_Rev    200      // Кол-во шагов/об, ось Y
#define MicroStep_X             4        // Микрошаг, ось X
#define MicroStep_Y             4        // Микрошаг, ось Y
#define Enc_Line_per_Rev        1750     // Кол-во линий энкодера
#define Total_Feeds             7        // Кол-во подач
#define Total_Threads           47       // Кол-во резьб
#define Accel                   15       // К.деления с которого будем ускоряться на рабочих режимах, Accel+Ks должен быть < 255
// ***** Ускоренные перемещения *****
#define max_Rapid_Motion        8                   // Меньше - бОльшая конечная скорость             // 16000000/128/((5+1)*2)/800*60 = 781rpm
#define min_Rapid_Motion        max_Rapid_Motion + 50  // Больше - мЕньшая начальная скорость, max 255   // 16000000/128/((25+1)*2)/800*60 = 180rpm
                                                       // длительность разгона                           // 25*Repeat(16)/Microstep(4) = 100 полных шагов цикл ускорения
/////////////////////////////////////////////////////////

unsigned long currentMillis=0;                                  //+++ Переменная для запоминания тукущего времени для вычисления оборотов шпинделя
unsigned long currentMillis_prev=0;                             //+++ Переменная для запоминания предыдущего времени прохождения шпинделя через 0 для вычисления оборотов шпинделя
volatile int tahometr=0;                                     //+++ Тут запоминаем время затраченное на один оборот шпинделя 
int RPM=0;

// ***** LCD *****
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
char LCD_Row_1[17];
char LCD_Row_2[17];

// ***** Символы электронных упоров ***** // Возможно кому-то пригодится
byte a_left[8] =
{0b00000, 0b10010, 0b10110, 0b11110, 0b10110, 0b10010, 0b00000, 0b00000};
byte a_right[8] =
{0b00000, 0b01001, 0b01101, 0b01111, 0b01101, 0b01001, 0b00000, 0b00000};
//byte a_front[8] =
//{0b11111, 0b00100, 0b01110, 0b11111, 0b00000, 0b00000, 0b00000, 0b00000};
//byte a_rear[8] =
//{0b00000, 0b00000, 0b00000, 0b11111, 0b01110, 0b00100, 0b11111, 0b00000};
byte gr[8] =
{0b11100, 0b10100, 0b11100, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000};

// ***** Stepper Motor *****
#define MotorPort                    PORTL
#define MotorInitialization()        DDRL=B11111111

#define Motor_X_SetPulse()           MotorPort &= ~(1<<0)
#define Motor_X_RemovePulse()        MotorPort |= (1<<0)
#define Motor_X_InvertPulse()        MotorPort ^= (1<<0)

#define Motor_Y_SetPulse()           MotorPort &= ~(1<<1)
#define Motor_Y_RemovePulse()        MotorPort |= (1<<1)
#define Motor_Y_InvertPulse()        MotorPort ^= (1<<1)

#define Motor_X_CW()                 MotorPort &= ~(1<<2)
#define Motor_X_CCW()                MotorPort |= (1<<2)
boolean Motor_X_CW_flag = true;

#define Motor_Y_CW()                 MotorPort |= (1<<3)
#define Motor_Y_CCW()                MotorPort &= ~(1<<3)
boolean Motor_Y_CW_flag = true;

#define Motor_X_Enable()             MotorPort |= (1<<4)
#define Motor_X_Disable()            MotorPort &= ~(1<<4)

#define Motor_Y_Enable()             MotorPort |= (1<<5)
#define Motor_Y_Disable()            MotorPort &= ~(1<<5)

boolean Step_On_flag = false;
boolean X_Feed_flag = false;
boolean Y_Feed_flag = false;


// ***** Taho *****
#define TahoPort                      PORTL
#define TahoSetPulse()                TahoPort |= (1<<6)
#define TahoRemovePulse()             TahoPort &= ~(1<<6)


// ***** Encoder *****
#define Enc_Tick                      Enc_Line_per_Rev*2
#define EncoderPort                   PORTD
#define EncoderInitialization()       DDRD=B00000000;\
                                      PORTD = B00001111
                                      
#define Enc_Read                      (PIND & B00000010)
volatile int Enc_Pos = 0;
volatile byte Ks_Count = 0;
volatile int Km_Count = 0;
byte Ks_Divisor = 0;
int Km_Divisor = 0;
int Enc_Pos_tmp = 0;
long Spindle_Angle = 0;
#define Spindle_Direction_CW         0
#define Spindle_Direction_CCW        1
boolean Spindle_Direction = Spindle_Direction_CW;


//***** Ускорение *****
byte tmp_Accel = Accel;
byte tmp_Ks_Divisor = Accel;
#define Repeat                       MicroStep_X * 4       // Кол-во повторов для постоянной скорости в пределах полного шага,
byte tmp_Repeat = 0;


//***** Ускоренное перемещение *****
#define Timer2_Init()                     TCCR2A = (1<<WGM21);\
                                          TCCR2B = (1<<CS20);\
                                          TCCR2B = (1<<CS20)|(1<<CS22)
                                          
#define EnableINT_T2()                    TIMSK2 |= (1 << OCIE2A)
#define DisableINT_T2()                   TIMSK2 &= ~(1 << OCIE2A)
byte tmp_Rapid_Motion = min_Rapid_Motion;
boolean Rapid_Step_On_flag = false;
boolean Rapid_On_flag = false;
boolean ev = true;

int Brake_Compens = 0;


//***** Sensor & Limit *****
#define LimitPort                        PORTC
#define LimitInit()                      DDRC=B10101010;\
                                         PORTC = B11111111

#define Limit_Left_LED_On()              LimitPort &= ~(1<<7)
#define Limit_Left_LED_Off()             LimitPort |= (1<<7)
#define Limit_Right_LED_On()             LimitPort &= ~(1<<5)
#define Limit_Right_LED_Off()            LimitPort |= (1<<5)
#define Limit_Front_LED_On()             LimitPort &= ~(1<<3)
#define Limit_Front_LED_Off()            LimitPort |= (1<<3)
#define Limit_Rear_LED_On()              LimitPort &= ~(1<<1)
#define Limit_Rear_LED_Off()             LimitPort |= (1<<1)

#define Limit_Left_Button                (PINC & B01000000)
#define Limit_Right_Button               (PINC & B00010000)
#define Limit_Front_Button               (PINC & B00000100)
#define Limit_Rear_Button                (PINC & B00000001)
boolean Limit_Button_flag = false;

#define Limit_Pos_Max                    1073741824
#define Limit_Pos_Min                   -1073741824

long tmp_Limit_Position = 0;
long Limit_Pos_Left = Limit_Pos_Max;
long Limit_Pos_Right = Limit_Pos_Min;
boolean Limit_Pos_Left_Flag = false;
boolean Limit_Pos_Right_Flag = false;
long Motor_X_Pos = 0;

long Limit_Pos_Front = Limit_Pos_Max;
long Limit_Pos_Rear = Limit_Pos_Min;
boolean Limit_Pos_Front_Flag = false;
boolean Limit_Pos_Rear_Flag = false;
long Motor_Y_Pos = 0;


//***** Key & Joy *****
enum Pressed_Key
{
  Key_None,
  Key_Right,
  Key_Up,
  Key_Down,
  Key_Left,
  Key_Select
};
byte Pressed_Key = Key_None;
boolean key_flag = false;

#define JoyPort                     PORTK
#define Joy                         PINK
#define Joy_Left                    (PINK & B00000001)
#define Joy_Right                   (PINK & B00000010)
#define Joy_Front                   (PINK & B00000100)
#define Joy_Rear                    (PINK & B00001000)
#define Joy_Button                  (PINK & B00010000)
#define Joy_Init()                  DDRK=B10000000;\
                                    PORTK = B00011111
boolean Joy_On_flag = false;


// ***** Mode *****
enum Mode
{
  Mode_Thread = 1,
  Mode_Feed
};
byte Mode = Mode_Feed;
//byte Mode = Mode_Thread;

// ***** Feeds *****
typedef struct
{
  byte  X_Divisor;
  byte  Y_Divisor;
  char  Text[7];
  char  Ogr[8];
}
FEED_INFO;
FEED_INFO Feed_Info[Total_Feeds] =
{
   { 291, 66, "0.03mm", "1800rpm" },   // Считаем по формуле:
   { 145, 83,  "0.06mm", "1800rpm" },   // Enc_Line/(Step_Per_Revolution/Feed_Screw*Feed_mm)
   { 97,  22,  "0.09mm", "1800rpm" },   // Просчитан под 800 шаг/оборот (1/4 дробление, 1.5мм шаг винта)
   { 72,  92,  "0.12mm", "1800rpm" },
   { 58,  33,  "0.15mm", "1800rpm" },
   { 48,  61,  "0.18mm", "1800rpm" },
   { 41,  67,  "0.21mm", "1800rpm" },
};
byte Feed_Step = 2;


// ***** Threads *****
typedef struct
{
  byte X_Divisor;
  int  m_Divisor;
  char Text[7];
  char  Ogr[8];
}
THREAD_INFO;
THREAD_INFO Thread_Info[Total_Threads] =
{                                     // Считаем по формуле:
   { 35, 0,    "0.25mm", "2200rpm" }, // Enc_Line/(Step_Per_Revolution/Feed_Screw*Thread_mm)
   { 29, 1667, "0.30mm", "1900rpm" }, // Просчитан под 800 шаг/оборот (1/4 дробление, 1.5мм шаг винта)
   { 25, 0,    "0.35mm", "1600rpm" },
   { 21, 8750, "0.40mm", "1400rpm" },
   { 17, 5000, "0.50mm", "1100rpm" },
   { 14, 5833, "0.60mm", " 950rpm" },
   { 12, 5000, "0.70mm", " 810rpm" },
   { 11, 6667, "0.75mm", " 760rpm" },
   { 10, 9375, "0.80mm", " 710rpm" },
   { 8,  7500, "1.00mm", " 570rpm" },
   { 7,  0,    "1.25mm", " 460rpm" },
   { 5,  8333, "1.50mm", " 380rpm" },
   { 5,  0,    "1.75mm", " 320rpm" },
   { 4,  3750, "2.00mm", " 280rpm" },
   { 3,  0,    "2.50mm", " 220rpm" },
   { 2,  9167, "3.00mm", " 180rpm" },
   { 2,  1875, "4.00mm", " 140rpm" },
   { 1,  7500, "5.00mm", " 110rpm" },
   { 1,  4583, "6.00mm", "  90rpm" },
   
   { 27, 5591, "80tpi ", "  xxrpm" },
   { 24, 8031, "72tpi ", "  xxrpm" },
   { 22,  472, "64tpi ", "  xxrpm" },
   { 20, 6693, "60tpi ", "  xxrpm" },
   { 19, 2913, "56tpi ", "  xxrpm" },
   { 16, 5354, "48tpi ", "  xxrpm" },
   { 15, 1575, "44tpi ", "  xxrpm" },
   { 13, 7795, "40tpi ", "  xxrpm" },
   { 12, 4016, "36tpi ", "  xxrpm" },
   { 11,  236, "32tpi ", "  xxrpm" },
   { 9,  6457, "28tpi ", "  xxrpm" },
   { 9,  3012, "27tpi ", "  xxrpm" },
   { 8,  9567, "26tpi ", "  xxrpm" },
   { 8,  2677, "24tpi ", "  xxrpm" },
   { 7,  5787, "22tpi ", "  xxrpm" },
   { 6,  8898, "20tpi ", "  xxrpm" },
   { 6,  5453, "19tpi ", "  xxrpm" },
   { 6,  2008, "18tpi ", "  xxrpm" },
   { 5,  5118, "16tpi ", "  xxrpm" },
   { 4,  8228, "14tpi ", "  xxrpm" },
   { 4,  1339, "12tpi ", "  xxrpm" },
   { 3,  4449, "10tpi ", "  xxrpm" },
   { 3,  1004,  "9tpi ", "  xxrpm" },
   { 2,  7559,  "8tpi ", "  xxrpm" },
   { 2,  4114,  "7tpi ", "  xxrpm" },
   { 2,   669,  "6tpi ", "  xxrpm" },
   { 1,  7224,  "5tpi ", "  xxrpm" },
   { 1,   3780,  "4tpi ", "  xxrpm" },
};
byte Thread_Step = 9;


// ***** Interrupts *****
#define EnableINT0()          EIMSK |= (1 << INT0)
#define DisableINT0()         EIMSK &= ~(1 << INT0)
#define Init_INT0_Any()       EICRA = B00000001


//*********************************************************
void setup()
{
  TIMSK0 = 0;
  
  Timer2_Init();
  DisableINT_T2();
  OCR2A = tmp_Rapid_Motion;
  
  EncoderInitialization();
  MotorInitialization();
  Init_INT0_Any();
  EnableINT0();
  Joy_Init();                                     
  LimitInit();
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.createChar(1, a_left);   // создаем символ "левый упор"
  lcd.createChar(2, a_right);  // создаем символ "..."
  lcd.createChar(5, gr);  
//  lcd.createChar(3, a_front);  // создаем символ "..."
//  lcd.createChar(4, a_rear);   // создаем символ "..."
}


//**********************************************************
void loop()
{
  Serial.println (millis());
  Enc_Pos_tmp = Enc_Pos;                    // ниже будем читать повторно и сравнивать
 
  
  // Тахометр
currentMillis = millis();
if ( currentMillis >= currentMillis_prev+1000){

                                         //calculates rpm
RPM= tahometr*60;
currentMillis_prev=millis();             //saves the current time


tahometr=0;
 // snprintf(LCD_Row_2, 17, "Ob/min: %4d  ",RPM ); // Вторая строка для печати тахометр
}  

  menu();
  Joystick();
  Limit_Button();
    
  Print();

}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********** Функция обработки событий в главном меню ********** /////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void menu()
{
  int ADC_value = analogRead(A0);
  if (ADC_value < 60) Pressed_Key = Key_Right;
  else if (ADC_value < 220) Pressed_Key = Key_Up;
  else if (ADC_value < 390) Pressed_Key = Key_Down;
  else if (ADC_value < 600) Pressed_Key = Key_Left;
  else if (ADC_value < 870) Pressed_Key = Key_Select;
  else Pressed_Key = Key_None;
  
  if (!key_flag)
  {
      switch (Pressed_Key)
      {
        case Key_Left:
          MenuKeyLeftPressed();
          break;
        case Key_Right:
          MenuKeyRightPressed();
          break;
        case Key_Up:
          MenuKeyUpPressed();
          break;
        case Key_Down:
          MenuKeyDownPressed();
          break;       
        case Key_Select:
          MenuKeySelectPressed();    
          break;
      }
  }
  if (Pressed_Key == Key_None) key_flag = false;

  SelectWorkMode();
}

// ********** Обработчик нажатия кнопки Select **********
void MenuKeySelectPressed()
{

  switch (Mode) 
  {
      case Mode_Thread:
         if (!Joy_On_flag)
         {
            Ks_Count = 0;
            Km_Count = 0;
            tmp_Repeat = 0;
            
            Step_On_flag = false;
            Rapid_Step_On_flag = false;
            Mode++;
         }
         break;
         
      case Mode_Feed:
         if (!Joy_On_flag)
         {
            Ks_Count = 0;
            Km_Count = 0;
            tmp_Repeat = 0;
            Mode--;
            
            tmp_Accel = Accel + Thread_Info[Thread_Step].X_Divisor;
            tmp_Ks_Divisor = Accel + Thread_Info[Thread_Step].X_Divisor;
            
            Step_On_flag = false;
            Rapid_Step_On_flag = false;
         }
        break; 
   }
   key_flag = true;
}

// ********** Обработчик нажатия кнопки Up **********
void MenuKeyUpPressed()
{
  switch (Mode)
  {
      case Mode_Thread:
        if (Thread_Step < Total_Threads-1)
        {
           if (!Joy_On_flag)
           {
              Ks_Count = 0;
              Km_Count = 0;
              tmp_Repeat = 0;
              
              Thread_Step++;
              tmp_Accel = Accel + Thread_Info[Thread_Step].X_Divisor;
              tmp_Ks_Divisor = Accel + Thread_Info[Thread_Step].X_Divisor;
            
              Step_On_flag = false;
              Rapid_Step_On_flag = false;
           }
        }
        break;
        
      case Mode_Feed:
        if (Feed_Step < Total_Feeds-1)
        {
          Ks_Count = 0;
          Km_Count = 0;
          tmp_Repeat = 0;
  
          Feed_Step++;
        }
        break;
  }
  key_flag = true;
}

// ********** Обработчик нажатия кнопки Down **********
void MenuKeyDownPressed()
{
   switch (Mode)
   { 
      case Mode_Thread:
        if (Thread_Step > 0)
        {
           if (!Joy_On_flag)
           {
              Ks_Count = 0;
              Km_Count = 0;
              tmp_Repeat = 0;
              
              Thread_Step--;
              tmp_Accel = Accel + Thread_Info[Thread_Step].X_Divisor;
              tmp_Ks_Divisor = Accel + Thread_Info[Thread_Step].X_Divisor;
              
              Step_On_flag = false;
              Rapid_Step_On_flag = false;
           }
        }
        break;
        
      case Mode_Feed:
        if (Feed_Step > 0)
        {
          Ks_Count = 0;
          Km_Count = 0;
          tmp_Repeat = 0;
          
          Feed_Step--;
        }
        break;
   }
   key_flag = true;
}

// ********** Обработчик нажатия кнопки Left **********
void MenuKeyLeftPressed()
{ 
   if (!Limit_Button_flag)
   {
     Limit_Button_flag = true;
     if (!Joy_On_flag)
     { 
       if (Limit_Pos_Left_Flag == false)
       {
         if ( Motor_X_Pos > (Limit_Pos_Right + ((min_Rapid_Motion - max_Rapid_Motion) * Repeat)*2) )
         {
           Limit_Pos_Left_Flag = true;
           Limit_Pos_Left = ((Motor_X_Pos + MicroStep_X/2) & ~(MicroStep_X-1))-1;
           lcd.setCursor(13, 0); lcd.print("\1");
         }
       }
       else
       {
         Limit_Pos_Left_Flag = false;
         Limit_Pos_Left = Limit_Pos_Max;
         lcd.setCursor(13, 0); lcd.print(" ");
       }
     }
   }
   key_flag = true;
}

// ********** Обработчик нажатия кнопки Right **********
void MenuKeyRightPressed()
{
   if (!Limit_Button_flag)
   {
     Limit_Button_flag = true;
     if (!Joy_On_flag)
     { 
       if (Limit_Pos_Right_Flag == false)
       {
         if (Motor_X_Pos < (Limit_Pos_Left - ((min_Rapid_Motion - max_Rapid_Motion) * Repeat)*2) )
         {
           Limit_Pos_Right_Flag = true;
           Limit_Pos_Right = ((Motor_X_Pos + MicroStep_X/2) & ~(MicroStep_X-1))+1;
           lcd.setCursor(15, 0); lcd.print("\2");
         }
       }
       else
       {
         Limit_Pos_Right_Flag = false;
         Limit_Pos_Right = Limit_Pos_Min;
         lcd.setCursor(15, 0); lcd.print(" ");
       }
     }
   }
   key_flag = true;
}

// ********** Выбор режима работы **********
void SelectWorkMode()
{
   switch (Mode)
   {
    case Mode_Thread:
        Thread();
        break;
    case Mode_Feed:
        Feed();
        break;
   }
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********** Обработка кнопок лимита ********** ////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Limit_Button()
{
  // ********** Обработчик нажатия кнопки Limit_Left **********
  if (!Limit_Left_Button)
  {
    // 
  } 
   
  // ********** Обработчик нажатия кнопки Limit_Right **********
  else if (!Limit_Right_Button)
  {
    //
  }

   // ********** Обработчик нажатия кнопки Limit_Front **********
   else if (!Limit_Front_Button)
   {
     //
   } 

   // ********** Обработчик нажатия кнопки Limit_Rear **********   
   else if (!Limit_Rear_Button)
   {
     //
   }   
   
   else
   {
      Limit_Button_flag = false;
   }
   
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********** Обработка положения джойстика ********** ///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Joystick()
{
  if (!Joy_Left) {Joy_LeftPressed();}
  else if (!Joy_Right) {Joy_RightPressed();}
  else if (!Joy_Front)  {Joy_UpPressed();}
  else if (!Joy_Rear) {Joy_DownPressed();}
  else {Joy_NoPressed();}
  if (!Joy_Button ) {Rapid_Feed();}
  else {No_Rapid_Feed();}
}  
  

// ********** Обработчик Джойстик Влево **********
void Joy_LeftPressed()
{
   Y_Feed_flag = false;
   X_Feed_flag = true;
   Joy_On_flag = true;
   Motor_X_Enable();
      
   if (Mode == Mode_Thread)
   {
      if (Spindle_Direction == Spindle_Direction_CW)
      {
         Motor_X_CW();
         Motor_X_CW_flag = true; 
      }
      else
      {
         Motor_X_CCW();
         Motor_X_CW_flag = false;
      }
   }

   else
   {
      Motor_X_CW();
      Motor_X_CW_flag = true;
   }
}  


// ********** Обработчик Джойстик Вправо **********  
void Joy_RightPressed()
{
   Y_Feed_flag = false;
   X_Feed_flag = true;
   Joy_On_flag = true;
   Motor_X_Enable();

   if (Mode == Mode_Thread)
   {
      if (Spindle_Direction == Spindle_Direction_CW)
      {
         Motor_X_CCW();
         Motor_X_CW_flag = false; 
      }
      else
      {
         Motor_X_CW();
         Motor_X_CW_flag = true; 
      }
   }
   else
   {
      Motor_X_CCW();
      Motor_X_CW_flag = false;
   }
}


// ********** Обработчик Джойстик Вверх **********  
void Joy_UpPressed()
{
//
}


// ********** Обработчик Джойстик Вниз **********  
void Joy_DownPressed()
{
//
}


// ********** Обработчик Джойстик в нейтрали **********  
void Joy_NoPressed()
{
   Joy_On_flag = false;
   Rapid_On_flag = false;
   if ( (Step_On_flag == false) && (Rapid_Step_On_flag == false) )
   {
      Motor_X_Disable();
   }
}


// ********** Обработчик быстрое перемещение **********
void Rapid_Feed()
{
  if ( (Joy_On_flag == true) && (Mode != Mode_Thread) )
  {
     if (Motor_X_CW_flag == true)
     {
        if ( Motor_X_Pos < (Limit_Pos_Left - ((min_Rapid_Motion - max_Rapid_Motion) * Repeat)*2) )
        {
           Brake_Compens = ( ((min_Rapid_Motion - max_Rapid_Motion) * Repeat)/2 );
           Rapid_On_flag = true;
           DisableINT0();
           EnableINT_T2();
        }
     }
     
     else
     {
        if ( Motor_X_Pos > (Limit_Pos_Right + ((min_Rapid_Motion - max_Rapid_Motion) * Repeat)*2) )
        {
           Brake_Compens = ( ((min_Rapid_Motion - max_Rapid_Motion) * Repeat)/2 );
           Rapid_On_flag = true;
           DisableINT0();
           EnableINT_T2();
        }
     }
  }
}


// ********** Обработчик быстрое перемещение "Кнопка отжата"**********
void No_Rapid_Feed()
{
   Rapid_On_flag = false;
   if ( (Rapid_Step_On_flag == false) && (Mode != Mode_Thread) )
   {
      DisableINT_T2();
      EnableINT0();
      Brake_Compens = 0;
   }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********** Режим "Резьба" ********** //////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Thread()
{
  Ks_Divisor=Thread_Info[Thread_Step].X_Divisor;
  Km_Divisor=Thread_Info[Thread_Step].m_Divisor;
  
  Brake_Compens = Accel * Repeat;
  if (Motor_X_CW_flag == true)
     {
        tmp_Limit_Position = Limit_Pos_Left - Brake_Compens;
     }
     else
     {
        tmp_Limit_Position = Limit_Pos_Right + Brake_Compens;
     }
     
  snprintf(LCD_Row_1, 17, "Thrd: %s", Thread_Info[Thread_Step].Text);
  
  if (Enc_Pos == Enc_Pos_tmp)
  {
    Spindle_Angle = (Enc_Pos*360000/(Enc_Tick));
    snprintf(LCD_Row_2, 17, "Angle:  %3d\5 ", Spindle_Angle/1000);
    
    
  }
  else
  {
   
   snprintf(LCD_Row_2, 17, "Ob/min: %3d  ",RPM  ); // Вторая строка для печати тахометр
   
  }
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********** Режим "Подача" ********** //////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Feed()
{
   if (Y_Feed_flag == true)
   {
      Ks_Divisor=Feed_Info[Feed_Step].Y_Divisor;
      Km_Divisor=0;
   }
   else
   {
      Ks_Divisor=Feed_Info[Feed_Step].X_Divisor;
      Km_Divisor=0;
   }
      
   tmp_Accel = Ks_Divisor;
   tmp_Ks_Divisor = Ks_Divisor;
   
   if (Motor_X_CW_flag == true)
  {
     tmp_Limit_Position = Limit_Pos_Left - Brake_Compens;
  }
  else
  {
     tmp_Limit_Position = Limit_Pos_Right + Brake_Compens;
  }
  
  snprintf(LCD_Row_1, 17, "Feed: %s", Feed_Info[Feed_Step].Text);
      
  if (Enc_Pos == Enc_Pos_tmp)
  {
    Spindle_Angle = (Enc_Pos*360000/(Enc_Tick));
    snprintf(LCD_Row_2, 17,  "Angle:  %3d\5 ", Spindle_Angle/1000);
    
  }
  else
  {
   snprintf(LCD_Row_2, 17,"Ob/min: %4d  ",RPM  ); // Вторая строка для печати тахометр
  
  }
}


//******************************************************************
void Print()
{
lcd.setCursor(0, 0);
lcd.print(LCD_Row_1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(LCD_Row_2);

}

//******************************************************************
ISR(INT0_vect)
{
   TahoRemovePulse();
   Motor_X_RemovePulse();

   if (!Enc_Read)
   {
      Spindle_Direction = Spindle_Direction_CW;
      Enc_Pos++;
      if (Enc_Pos == Enc_Tick)
      {                                           
         Enc_Pos = 0;
         TahoSetPulse();
         tahometr++;
         
         if (Joy_On_flag == true)
         {
            Step_On_flag = true;
         }
      }
   } 
   else
   {
      Spindle_Direction = Spindle_Direction_CCW;
      Enc_Pos--;
      if (Enc_Pos < 0)
      {
         Enc_Pos = Enc_Tick - 1;
         TahoSetPulse();
         tahometr++;
         if (Joy_On_flag == true)
         {
            Step_On_flag = true;
         }
      }
   }
      
                 
   if ( ((Motor_X_CW_flag == true) && (Motor_X_Pos > tmp_Limit_Position)) || ((Motor_X_CW_flag == false) && (Motor_X_Pos < tmp_Limit_Position)) || (!Joy_On_flag) )
   {
      if (tmp_Ks_Divisor < tmp_Accel)
      {
         Ks_Count++;
         if (Ks_Count > tmp_Ks_Divisor)
         {
            Motor_X_SetPulse();
            if (Motor_X_CW_flag == true)
            {
               Motor_X_Pos ++;
            }
            else Motor_X_Pos --;
            Ks_Count = 0;
            tmp_Repeat ++;
            if (tmp_Repeat == Repeat)
            {
               tmp_Repeat = 0;
               tmp_Ks_Divisor ++;
            }
         }
      }  
      else
      {
         Step_On_flag = false;
      }
   }

   else if ( (Step_On_flag == true) && (Joy_On_flag == true) )
   {
      Ks_Count++;
      if (Ks_Count > tmp_Ks_Divisor)
      {
         Motor_X_SetPulse();
         if (Motor_X_CW_flag == true)
            {
               Motor_X_Pos ++;
            }
            else Motor_X_Pos --;
         if (tmp_Ks_Divisor > Ks_Divisor)
         {
            Ks_Count = 0;
            tmp_Repeat ++;
            if (tmp_Repeat == Repeat)
            {
               tmp_Repeat = 0;
               tmp_Ks_Divisor --;
            }
         }
         else
         {  
            Km_Count = Km_Count + Km_Divisor;
            if (Km_Count > Km_Divisor)
            {
               Km_Count = Km_Count - 10000;
               Ks_Count = 0;
            }
            else
            {
               Ks_Count = 1;
            }
         }
      }
   }
}


//***********************************************************************
ISR (TIMER2_COMPA_vect)
{
  Rapid_Step_On_flag = true;
  if ( ((Motor_X_CW_flag == true) && (Motor_X_Pos > tmp_Limit_Position)) || ((Motor_X_CW_flag == false) && (Motor_X_Pos < tmp_Limit_Position)) || (Rapid_On_flag == false) )
  {
     if (tmp_Rapid_Motion < min_Rapid_Motion)
     {
        Motor_X_InvertPulse();
        ev = !ev;
        if (!ev)
        {
           if (Motor_X_CW_flag == true)
           {
              Motor_X_Pos ++;
           }
            else Motor_X_Pos --;
        }
        tmp_Repeat ++;
        if (tmp_Repeat == Repeat)
        {
           tmp_Repeat = 0;
           tmp_Rapid_Motion++;
        }
     }
     else
     {
        Rapid_Step_On_flag = false;
     }
  }
  
  else
  {
     Motor_X_InvertPulse();
     ev = !ev;
        if (!ev)
        {
           if (Motor_X_CW_flag == true)
           {
              Motor_X_Pos ++;
           }
            else Motor_X_Pos --;
        }
     if (tmp_Rapid_Motion > max_Rapid_Motion)
     {

        tmp_Repeat ++;
        if (tmp_Repeat == Repeat)
        {
           tmp_Repeat = 0;
           tmp_Rapid_Motion--;
        }
     }
  }
  
  OCR2A = tmp_Rapid_Motion;
}

//*******************************************************************

 

sivanko
Offline
Зарегистрирован: 25.02.2016

Сам тахометр - строчки с 314 по 325. Переменная tahometr увеличивается на единицу при прохождении енкодера через 0.

Serial.print сразу после void loop() выдает постоянно  0

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Строка №285 убивает millis нахрен.

Хотите, чтобы работал millis - не трогайте грязными руками нулевой таймер.

sivanko
Offline
Зарегистрирован: 25.02.2016

Добрый день. Убрал строчку - все заработало. Большое спасибо!!! Код не мой. Брал готовый, переделывал под себя.