инкременальный энкодер
- Войдите на сайт для отправки комментариев
Чт, 28/11/2013 - 13:52
прошу помощи
есть программа (рабочая) помогите удалить лишнее
нужно оставить только тахометр (от =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();
}
//*******************************************************************
прошу помощи
есть программа (рабочая) помогите удалить лишнее
нужно оставить только тахометр (от =0= до 2000 об\мин) и угол поворота энкодера (2500 имп\об)
все это выводить на lcd в реальном времени
буду очень признателен тем кто поможет
шутник ты таваресщ морской прапорщик
2500 имп на оборот, 2000 об/мин= 33 об/сек, 33*2500=83 кГц, 83*4=333 кГц
виноват. ответ исчерпывающий, вопрос поставлен неверно.
правильно будет навверно так,
есть программа (рабочая) помогите удалить лишнее
нужно оставить только тахометр (от =0= до 2000 об\мин, есть отдельная одна метка) при работе от двигателя, и (делилка) угол поворота энкодера в градусах и кнопка сброса =0= (2500 имп\об) вторая кнопка переключения между тахометром и (делилкой)
все это выводить на lcd в реальном времени
буду очень признателен тем кто поможет