Arduino и токарный станок
- Войдите на сайт для отправки комментариев
Сб, 23/11/2013 - 14:25
прошу помощи, уважаемые.
есть програмный крод:
#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(); } //*******************************************************************
пожалусто распишите, что куда, откуда идет? очень надо.
хочу использовать часть этого кода у себя.
Мичман, сходи на форум чипмейкеров, там сейчас как раз обсуждают как на ардуино электронную гитару сделать с энкодерами.