инкременальный энкодер

michman
Offline
Зарегистрирован: 22.05.2013

прошу помощи

есть программа (рабочая) помогите удалить лишнее

нужно оставить только тахометр (от =0= до 2000 об\мин) и угол поворота энкодера (2500 имп\об) 

все это выводить на lcd в реальном времени

буду очень признателен тем кто поможет

#include <avr/pgmspace.h>


// ***** LCD *****
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


// ***** Stepper Motor *****
//#define Step_Per_Revolution           2400
#define StepMotorPort                 PORTL
#define StepMotorInitialization()     DDRL=B11111111               // под мотор выделен весь порт "L", сконфигурирован на выход
#define StepMotorSetPulse()           StepMotorPort &= ~(1<<0)     // Pin49 1
#define StepMotorRemovePulse()        StepMotorPort |= (1<<0)      // Pin49 0
#define StepMotorForward()            StepMotorPort |= (1<<2)      // Pin47 0
#define StepMotorReverse()            StepMotorPort &= ~(1<<2)     // Pin47 1
#define StepMotorEnable()             StepMotorPort |= (1<<4)      // Pin45 0
#define StepMotorDisable()            StepMotorPort &= ~(1<<4)     // Pin45 1
boolean Step_On_flag=false;                                        // флаг прохода энкодера через 0
boolean Motor_En_flag=false;                                       // Enable/Disable Stepper Motor


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


// ***** Encoder *****
#define EncoderPort                   PORTD
#define EncoderInitialization()       DDRD=B00000000               // Под энкодер выделен весь порт "D", сконфигурирован на вход
#define Enc_Line                      3600                         // Кол-во рисок энкодера х2
#define Enc_DDR                       DDRD
register int Enc_Pos asm("r2");                                    // Счетчик положения энкодера
byte Ks_Count;                                                     // Счетчик для "Подача", "Резьба" целая часть
register int Km_Count asm("r6");                                   // Счетчик для "Подача", "Резьба" дробная часть
byte Ks_Divisor;                                                   // Делитель для "Подача", "Резьба" целая часть
int Km_Divisor;                                                    // Делитель для "Подача", "Резьба" дробная часть


// ***** Keyboard *****
enum Pressed_Key
{
  Key_None,
  Key_Right,
  Key_Up,
  Key_Down,
  Key_Left,
  Key_Select
};
byte Pressed_Key=Key_None;
boolean key_flag=false;                                           // флаг нажатой/отжатой кнопки


// ***** Mode *****
enum Mode
{
  Mode_Thread_Left=1,
  Mode_Feed_Left,
  Mode_Divider,
  Mode_Feed_Right,
  Mode_Thread_Right
};
byte Mode = Mode_Divider;


// ***** Feeds *****
// Enc_Line/(Step_Per_Revolution/Feed_Screw*Feed_mm)
#define Total_Feeds                   10               // Кол-во подач
typedef struct
{
  byte  s_Divisor;                                     // Делитель для "Подача" целая часть, дробная часть всегда = 0
  char  Text[7];
}
FEED_INFO;
FEED_INFO Feed_Info[Total_Feeds] =
{
   { 226, "0.02mm" },
   { 113, "0.04mm" },
   { 76,  "0.06mm" },
   { 57,  "0.08mm" },
   { 46,  "0.10mm" },
   { 38,  "0.12mm" },
   { 33,  "0.14mm" },
   { 29,  "0.16mm" },
   { 26,  "0.18mm" },
   { 23,  "0.20mm" },
};
byte Feed_Step = 4;                                      // выборка из массива по умолчанию


// ***** Threads *****
// Enc_Line/(Step_Per_Revolution/Feed_Screw*Thread_mm)
#define Total_Threads                 36                // Кол-во резьб
typedef struct
{
  byte s_Divisor;                                       // Делитель для "Резьба" целая часть
  int  m_Divisor;                                       // Делитель для "Резьба" дробная часть
  char Text[7];
}
THREAD_INFO;
THREAD_INFO Thread_Info[Total_Threads] =
{
   { 11, 2500, "0.20mm" },
   { 9,  0,    "0.25mm" },
   { 7,  5000, "0.30mm" },
   { 6,  4286, "0.35mm" },
   { 5,  6250, "0.40mm" },
   { 4,  5000, "0.50mm" },
   { 3,  7500, "0.60mm" },
   { 3,  2143, "0.70mm" },
   { 3,  0,    "0.75mm" },
   { 2,  8125, "0.80mm" },
   { 2,  2500, "1.00mm" },
   { 1,  8000, "1.25mm" },
   { 1,  5000, "1.50mm" },
   { 1,  2857, "1.75mm" },
   { 1,  1250, "2.00mm" },
   { 7,  866,  "80tpi " },
   { 6,  3780, "72tpi " },
   { 5,  6693, "64tpi " },
   { 5,  3150, "60tpi " },
   { 4,  9606, "56tpi " },
   { 4,  2520, "48tpi " },
   { 3,  8976, "44tpi " },
   { 3,  5433, "40tpi " },
   { 3,  1890, "36tpi " },
   { 2,  8347, "32tpi " },
   { 2,  4803, "28tpi " },
   { 2,  3917, "27tpi " },
   { 2,  3032, "26tpi " },
   { 2,  1260, "24tpi " },
   { 1,  9488, "22tpi " },
   { 1,  7717, "20tpi " },
   { 1,  6831, "19tpi " },
   { 1,  5945, "18tpi " },
   { 1,  4173, "16tpi " },
   { 1,  2402, "14tpi " },
   { 1,  0630, "12tpi " },
};
byte Thread_Step = 10;                      // выборка из массива по умолчанию


// ***** Interrupt *****
#define EnableINT0()          EIMSK |= (1 << INT0)
#define DisableINT0()         EIMSK &= ~(1 << INT0)
#define EnableINT1()          EIMSK |= (1 << INT1)
#define DisableINT1()         EIMSK &= ~(1 << INT1)
//#define Init_INT0_Rising()    EICRA = B00000011
//#define Init_INT0_Falling()   EICRA = B00000010
#define Init_INT0_Any()       EICRA = B00000001


//*********************************************************
void setup()
{
  TIMSK0=0;                                 // !Отключаем таймер! (он что-то свое делает в фоновом режиме)
  
  Enc_Pos=0;
  Ks_Count=0;
  Km_Count=0;
  
  EncoderInitialization();
  PORTD=B00000011;                          // подтяжка PIN_21, 20,
  
  StepMotorInitialization();
  Init_INT0_Any();
  EnableINT0();
  
  lcd.begin(16, 2);
}


//**********************************************************
void loop()
{
  if (Mode == Mode_Divider)
  {
    StepMotorDisable();
  }
  else
  {
  if (Motor_En_flag==true) StepMotorEnable();
  if (Motor_En_flag==false) StepMotorDisable();
  }
  
  menu();
}

//******************************************************************
void menu()
{
  int ADC_value = analogRead(A0);
  if (ADC_value < 65) 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==false)
  {
    switch (Pressed_Key)
    {
    case Key_Right:
      switch (Mode)
      {
      case Mode_Thread_Left:
      case Mode_Feed_Left:
      case Mode_Divider:
      case Mode_Feed_Right:
        {
          Motor_En_flag=false;
          Step_On_flag=false;
          Ks_Count=0;
          Km_Count=0;
          Mode++;
          break;
        }
      }
      key_flag=true;
      break;

    case Key_Left:
      switch (Mode)
      {
      case Mode_Feed_Left:
      case Mode_Divider:
      case Mode_Feed_Right:
      case Mode_Thread_Right:
        {
          Motor_En_flag=false;
          Step_On_flag=false;
          Ks_Count=0;
          Km_Count=0;
          Mode--;
          break;
        }
      }
      key_flag=true;
      break;

    case Key_Up:
      switch (Mode)
      {
      case Mode_Thread_Left:
      case Mode_Thread_Right:
      {
        if (Thread_Step < Total_Threads-1)
        {
          Motor_En_flag=false;
          Step_On_flag=false;
          Ks_Count=0;
          Km_Count=0;
          Thread_Step++;
        }
        break;
      }
      case Mode_Feed_Left:
      case Mode_Feed_Right:
      {
        if (Feed_Step < Total_Feeds-1)
        {
          Ks_Count=0;
          Km_Count=0;
          Feed_Step++;
        }
        break;
      }
      }
      key_flag=true;
      break;

    case Key_Down:
      switch (Mode)
      {
      case Mode_Thread_Left:
      case Mode_Thread_Right:
      {
        if (Thread_Step > 0)
        {
          Motor_En_flag=false;
          Step_On_flag=false;
          Ks_Count=0;
          Km_Count=0;
          Thread_Step--;
        }
        break;
      }
      case Mode_Feed_Left:
      case Mode_Feed_Right:
      {
        if (Feed_Step > 0)
        {
          Ks_Count=0;
          Km_Count=0;
          Feed_Step--;
        }
        break;
      }
      }
      key_flag=true;
      break;  
      
    case Key_Select:
      switch (Mode)
      {
      case Mode_Thread_Left:
      case Mode_Thread_Right:
      case Mode_Feed_Left:
      case Mode_Feed_Right:
      {
        Step_On_flag=false;
        if (Motor_En_flag==false) Motor_En_flag=true;
        else if (Motor_En_flag==true) Motor_En_flag=false;
        break;
      }
      case Mode_Divider:
      {
        Enc_Pos=0;
        break;
      }
      }
      key_flag=true;
      break;
    }
  }
  if (Pressed_Key==Key_None) key_flag=false;

// Вход в режим
  if (Mode==Mode_Thread_Left)
  {
    Thread_Left();
  }
  else if (Mode==Mode_Feed_Left)
  {
    StepMotorReverse();
    Feed_Left();
  }
  else if (Mode==Mode_Divider)
  {
    Divider();
  }
  else if (Mode==Mode_Feed_Right)
  {
    StepMotorForward();
    Feed_Right();
  }
  else if (Mode==Mode_Thread_Right)
  {
    Thread_Right();
  }
}


//***************************************
void Thread_Left()
{  
  Ks_Divisor=Thread_Info[Thread_Step].s_Divisor;
  Km_Divisor=Thread_Info[Thread_Step].m_Divisor;
  char* Print_Pitch = Thread_Info[Thread_Step].Text;
  
  lcd.setCursor(0, 0);
  lcd.print("Mode:  ");
  lcd.setCursor(7, 0);
  if (Motor_En_flag==true)
  {
  lcd.print("ON       ");
  }
  else if (Motor_En_flag==false)
  {
  lcd.print("OFF      ");
  }
  lcd.setCursor(0, 1);
  lcd.print("Thread <= ");
  lcd.setCursor(10, 1);
  lcd.print(Print_Pitch);
}

void Feed_Left()
{  
  Ks_Divisor=Feed_Info[Feed_Step].s_Divisor;
  Km_Divisor=0;
  char* Print_Pitch = Feed_Info[Feed_Step].Text;

  lcd.setCursor(0, 0);
  lcd.print("Mode:  ");
  lcd.setCursor(7, 0);
  if (Motor_En_flag==true)
  {
  lcd.print("ON       ");
  }
  else if (Motor_En_flag==false)
  {
  lcd.print("OFF      ");
  }
  lcd.setCursor(0, 1);
  lcd.print("Feed   <= ");
  lcd.setCursor(10, 1);
  lcd.print(Print_Pitch);
}

void Divider()
{  
//  int Enc_Pos_tmp;
  long Spindle_Angle;
  lcd.setCursor(0, 0);
  lcd.print("Mode:  Divider");
  lcd.setCursor(7, 0);

//    cli();
//    Enc_Pos_tmp=Enc_Pos;
//    sei();
  Spindle_Angle=(Enc_Pos*36000/(Enc_Line));
  lcd.setCursor(0, 1);
  lcd.print("Angle:    ");
  lcd.setCursor(10, 1);
  lcd.print(Spindle_Angle/100);
  lcd.print(",");
  lcd.print(Spindle_Angle%100);
  lcd.print("   ");
}

void Feed_Right()
{  
  Ks_Divisor=Feed_Info[Feed_Step].s_Divisor;
  Km_Divisor=0;
  char* Print_Pitch = Feed_Info[Feed_Step].Text;

  lcd.setCursor(0, 0);
  lcd.print("Mode:  ");
  lcd.setCursor(7, 0);
  if (Motor_En_flag==true)
  {
  lcd.print("ON       ");
  }
  else if (Motor_En_flag==false)
  {
  lcd.print("OFF      ");
  }
  lcd.setCursor(0, 1);
  lcd.print("Feed   => ");
  lcd.setCursor(10, 1);
  lcd.print(Print_Pitch);
}

void Thread_Right()
{
  Ks_Divisor=Thread_Info[Thread_Step].s_Divisor;
  Km_Divisor=Thread_Info[Thread_Step].m_Divisor;
  char* Print_Pitch = Thread_Info[Thread_Step].Text;

  lcd.setCursor(0, 0);
  lcd.print("Mode:  ");
  lcd.setCursor(7, 0);
  if (Motor_En_flag==true)
  {
  lcd.print("ON       ");
  }
  else if (Motor_En_flag==false)
  {
  lcd.print("OFF      ");
  }
  lcd.setCursor(0, 1);
  lcd.print("Thread => ");
  lcd.setCursor(10, 1);
  lcd.print(Print_Pitch);
}

//******************************************************************
ISR(INT0_vect)
{
 if ((PIND & B00000010) == 0) {
      Enc_Pos++;
      if (Enc_Pos == Enc_Line) {
          Enc_Pos=0;
          TahoSetPulse();                                                  // при проходе 0 генерим сигнал Taho
          if (Motor_En_flag==true) {                                       // проверка режима на ON/OFF
              Step_On_flag = true;                                         // при проходе 0 разрешаем счет до к.деления
                                   }
                               }
                 
                     if (Step_On_flag == true) {
                         
                         if (Mode == Mode_Thread_Left) {
                             StepMotorReverse();
                                                       }
                         if (Mode == Mode_Thread_Right) {
                             StepMotorForward();
                                                        }
                                                             
                              if (Ks_Count > Ks_Divisor) {
                                  StepMotorSetPulse();
                                  Km_Count = Km_Count + Km_Divisor;
                                  if (Km_Count > Km_Divisor) {
                                      Km_Count = Km_Count - 10000;
                                      Ks_Count = 0;
                                                             }
                                  else {
                                        Ks_Count = 1;
                                       }
                                                          }
                          Ks_Count++;
                                                }
                               }


 else {
       Enc_Pos--;
       if (Enc_Pos < 0) {
           Enc_Pos = Enc_Line - 1;
           TahoSetPulse();
           if (Motor_En_flag==true) {
               Step_On_flag = true;
                                    }
                        }

                     if (Step_On_flag == true) {
                         
                         if (Mode == Mode_Thread_Left) {
                             StepMotorForward();
                                                       }
                         if (Mode == Mode_Thread_Right) {
                             StepMotorReverse();
                                                        }
                                                             
                              if (Ks_Count == 0) {
                                  StepMotorSetPulse();
                                  Km_Count = Km_Count - Km_Divisor;
                                  if (Km_Count < 1) {
                                      Km_Count = Km_Count + 10000;
                                      Ks_Count = Ks_Divisor + 1;
                                                    }
                                  else {
                                        Ks_Count = Ks_Divisor;
                                       }
                                                 }
                         Ks_Count--;
                                               }
                                       
                                                                      
      }

  TahoRemovePulse();
  StepMotorRemovePulse();
}
//*******************************************************************

 

Rep-Rap-It-FU-Mother
Offline
Зарегистрирован: 29.11.2013

michman пишет:

прошу помощи

есть программа (рабочая) помогите удалить лишнее

нужно оставить только тахометр (от =0= до 2000 об\мин) и угол поворота энкодера (2500 имп\об) 

все это выводить на lcd в реальном времени

буду очень признателен тем кто поможет

шутник ты таваресщ морской прапорщик

2500 имп на оборот, 2000 об/мин= 33 об/сек, 33*2500=83 кГц, 83*4=333 кГц

 

michman
Offline
Зарегистрирован: 22.05.2013

виноват. ответ исчерпывающий, вопрос поставлен неверно.

правильно будет навверно так, 

 

есть программа (рабочая) помогите удалить лишнее

нужно оставить только тахометр (от =0= до 2000 об\мин, есть отдельная одна метка) при работе от двигателя,  и (делилка) угол поворота энкодера в градусах и кнопка сброса =0= (2500 имп\об) вторая кнопка переключения между тахометром и (делилкой)

все это выводить на lcd в реальном времени

буду очень признателен тем кто поможет