Arduino pro mini для управления шаговым двигателем

Как собрать и запрограммировать робота на Arduino(Freeduino, Roboduino, Seeduino ...). Используем Wiring и Processing.

Re: Arduino pro mini для управления шаговым двигателем

Сообщение Revenger » 22 сен 2015, 00:01

Залил новый скетч. Результат порадовал! Практически мгновенная реакция на изменение импульса в оптопаре!
Правда пока (на столе) наоборот, чем чаще я создаю импульсы, тем меньше обороты ШД. Но в меню еще ничего не крутил т.к. лучше на экструдер понести и на шестерню поставить и пробовать.

Кстати... "поломка" оптопары оказалась банальной грязью... а точнее смазка с шестерни просто испачкала рабочую часть и сигнал не проходил нормальный ))) Надо всё же разнести/распилить оптопару, т.к. ювелирной точности я добиться не смогу, шестерню на 1,5мм "колбасит" из стороны в сторону и ровнять её дело не благодарное.
Аватара пользователя
Revenger
 
Сообщения: 1728
Зарегистрирован: 01 ноя 2014, 00:50
Откуда: Ставрополье
ФИО: Александр

Re: Arduino pro mini для управления шаговым двигателем

Сообщение RootAdmin » 22 сен 2015, 12:26

Это хорошо. Да, оптопару если помещается впритык - лучше разделить. Я вообще делал "П"-образную скобу из пластика, в ножки вставлял светодиод и фотодиод на клей, сверля по месту. Причем скобу вообще из куска выпиливал болгаркой. :)
Будут тестовые результаты - допилим программу, надо больше цифр после запятой выводить и вообще - знать рабочие скорости. И настройку переделать - скорее всего удобней будет кнопками влево-вправо выбирать разряд, который хотим изменить - а вверх-вниз - менять этот разряд. В смысле двигать курсор и менять цифру в позиции курсора.
Китаец мне чего-то не отправил микрометр, закажу у другого. Хочется непрерывный контроль ключевого параметра - диаметра.
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: Arduino pro mini для управления шаговым двигателем

Сообщение Revenger » 22 сен 2015, 12:34

Сейчас попробую с опто пока так, потом красивостями разнесения займусь.
По меню не могу пока ничего сказать, главное пока добиться нужной реакции всего в целом ))
Как определить рабочие скорости? Экструдер и его обороты я уже считал ранее, диаметры и кол-ва зубов тоже. Экструдер скорее будет почти на пределе работать, разве что небольшой запас думаю должен оставаться.
Я микрометр не покупал, у меня есть штанген, который я готов пустить "в расход", он как раз с клеммой. Может передать его для опытов? Или пока то что есть по программе погоняем/доведём?
Аватара пользователя
Revenger
 
Сообщения: 1728
Зарегистрирован: 01 ноя 2014, 00:50
Откуда: Ставрополье
ФИО: Александр

Re: Arduino pro mini для управления шаговым двигателем

Сообщение RootAdmin » 22 сен 2015, 13:01

Сначала попробуем с тем что есть взлететь.
А мирометром я и называю электронную часть штангеля. Пока лучше отложим. Возможно придется математику внутри переделать, привести все значения к единому виду (например - обороты в секунду) не только при выводе но и внутри.
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: Arduino pro mini для управления шаговым двигателем

Сообщение Revenger » 22 сен 2015, 14:19

Да, пока думаю и та стартанём, затем уже вкусности ))

Я тут с работой еще не добрался до экструдера, по этому напомню про вопросик по поводу поведения ШД.. это пока просто на столе у меня так получилось или просто показалось, что при уменьшении частоты импульсов оптодатчика обороты ШД наоборот, увеличиваются ? Просто уточняю, чтобы потом снова все не тащить на перепрошивку к компьютеру.
Аватара пользователя
Revenger
 
Сообщения: 1728
Зарегистрирован: 01 ноя 2014, 00:50
Откуда: Ставрополье
ФИО: Александр

Re: Arduino pro mini для управления шаговым двигателем

Сообщение RootAdmin » 22 сен 2015, 14:50

Сейчас проверю...

Добавлено спустя 2 минуты 50 секунд:
Такс, кажется напутал. Сейчас.

Добавлено спустя 20 минут 8 секунд:
Код: Выделить всё
/*
Управление шаговиком (драйвер степ-дир) переменным резистором
теперь с кнопками! :)
А на этот раз - с экраном и резистивными кнопками.
Добавил измерение скорости вращения экструдера. Чуть подправил генерацию импульса на шаговик.
Управление преработано. Кнопка Select переключает режим "выбор" и "редактирование" Частота экструдера - в оборотах в минуту.
Добавлен коэффициент
v 0.6a */

/*
Вывод    Назначение
0        UART
1        UART
2        Внешнее прерывание от оптопары (не менять!)
3       
4       
5        Dir_pin
6        Step_pin     
7        LCD RS
8        LCD RW
9        LCD E
10       LCD DB4
11       LCD DB5
12       LCD DB6
13       LCD DB7
A0       Резистор
A1        Кнопки
A2
A3
A4       
A5       
A6
A7
*/




#include <EEPROM.h> //подключаем библиотеку EEPROM

#include <LiquidCrystal.h> // Подключаем стандартную библиотеку LiquidCrystal
// Инициализируем объект-экран, передаём использованные
// для подключения контакты на Arduino в порядке:
#define lcd_RS_pin 7
#define lcd_RW_pin 8
#define lcd_E_pin 9
#define lcd_DB4_pin 10
#define lcd_DB5_pin 11
#define lcd_DB6_pin 12
#define lcd_DB7_pin 13
//                    RS,         RW,        E,         DB4,           DB5,       DB6,          DB7
LiquidCrystal lcd(lcd_RS_pin, lcd_RW_pin, lcd_E_pin, lcd_DB4_pin, lcd_DB5_pin, lcd_DB6_pin, lcd_DB7_pin);


#define Step_pin 6 //вывод Arduino для ноги STEP контроллера (выход)
#define Dir_pin 5 //вывод Arduino для ноги DIR контроллера (выход)
#define Resistor_pin A0 //вывод Arduino резистора 0-5вольт (аналоговый вход)

//Оптодатчик:
#define OptoSensor_pin 2 //вывод Arduino для оптодатчика (вход)
#define ToothSumm 4 //сколько усреднять событий
#define ToothAll 140 // Событий на оборот
float ExtruderConst=(float)1/((float)(ToothAll/ToothSumm)*((float)1/250000)); // Коэффициент тиков :) Для оборотов в СЕКУНДУ делим его на измеренные
float DivK =500; //Коэффициент для соотношения скорости шаговика к скорости экструдера

volatile unsigned long OptoSensorTicks=0;//Переменная для хранения тиков таймера на 1 вызов (время между зубьями)
volatile byte OptoToothCounter =0; //Указатель на текущтй зуб в массиве
volatile unsigned int OptoToothTimeArray [ToothSumm]; //массив с таймингами зубьев




//********** Кнопки:
#define btnRIGHT  1 //Определяем кнопки, это просто внутренние номера, НЕ ноги-выводы
#define btnUP     2
#define btnDOWN   3
#define btnLEFT   4
#define btnSELECT 5
#define btnNONE   0
//**********
#define btnDEFtime   30 //Значение для антидребезга - клавиша удерживаемая столько времени в миллисекундах считается нажатой.
#define btnPAUSEtime   400 //Значение в миллисекундах паузы между повторами
int lcd_key     = btnNONE;  //Для хранения полученного значеник кнопки
byte keyTemp = btnNONE; //Переменная для хранения временного состояния кнопок
byte keyCONTpress; //Переменная взводится после первого срабатывания клавиши и определяет автоповтор
unsigned long BtnTime; //Хранит время начала нажатия кнопок
byte btnCONTpress; //Переменная взводится после первого срабатывания клавиши и определяет автоповтор
byte btnTemp=btnNONE; //Для хранения номера ранее нажатой кнопки
#if defined(Razr)  //Мне для отладки
    #define ButtonPin A7 //Сюда подключены кнопки
#else
  #define ButtonPin A1 //Сюда подключены кнопки
#endif
//************

/*
//структура под меню
typedef struct
{
     char* nam;
    byte posX;
    byte posY;
} menu;
//typedef struct menu menuEl;

menu menus[3] ={{"Mm1",0,0},
{"Mm2",1,1},
{"Mm3",3,3}};
*/



byte ControlPos = 0; //Переменная определяет элемент в строке управления. 1 - коэффициент. 0 - частота протяжки
byte ControlMode = 0; //Переменная определяет режим управления. 0 - выбор, 1 - редактирование
int ScreenPass =100; //Для пропуска циклов, чтоб экран не мерцал.


volatile unsigned char FullTimer0; //Переменная для остатка значения таймера
volatile unsigned int FullTimer256;//Переменная для количества холостых 256циклов таймера
volatile unsigned int FullTimer256Count; //внутренный счетчик таймера


//значение минимальной частоты
#define LowFreq 10
//значение МАКСИмальной частоты
#define HighFreq 2000
//Переменная для шага чаcтоты на едниницу изменения АЦП
// float FreqStep;
float OutFreq = LowFreq; //Переменная для хранения установленной частоты


/*
//Переменная для текущего значения резистора
int sensorValue = 0;
//Переменная для Старого значения резистора
int OLDsensorValue = 0;
*/

void setup() {               
  pinMode(Step_pin,OUTPUT);  // Конфигурим вывод Step_pin как выход
  pinMode(Dir_pin,OUTPUT);  // Конфигурим вывод Dir_pin как выход
//  pinMode(Resistor_pin,INPUT);  // Конфигурим вывод Dir_pin как вход

  pinMode(OptoSensor_pin,INPUT);  // Конфигурим вывод OptoSensor_pin как вход
  attachInterrupt(0, OptoSensor, CHANGE); // привязываем 0-е прерывание к функции OptoSensor(). На изменение состояния. Да, из-за разницы между шириной самого зуба и межзубного расстояния - будут различия, усредним.
 
  lcd.begin(16,2); //Инициализируем экран
 
 
  //Установим на выходах 0
  digitalWrite(Step_pin, LOW);
  digitalWrite(Dir_pin, LOW);
 
//  // Посчитаем "шаг" изменения частоты на единицу изменения резистора
//  FreqStep=(float)(HighFreq-LowFreq)/1024;
 
  //Запускает последовательный порт
  Serial.begin(9600);
 
  //Сообщение о запуске программы
  Serial.println("Program started"); 
// Serial.print("FreqStep="); 
// Serial.println(FreqStep); 
 
  //Запускает таймер и получает загружаемое значение таймера.
  //Параметр - желаемая частота в герцах.
 
   FullTimer0=SetupTimer2(OutFreq);
   
  //Установки Таймер2: Делитель частоты /64, режим 0
  //Частота = 16MHz/32 = 500000 герц или
  //Делитель /32 дает нам лучший рабочий диапазон в районе 1 кгц
  //так что сейчас мы просто жестко запрограммируем это.
  TCCR2A = 0;
  TCCR2B = 0<<CS22 | 1<<CS21 | 1<<CS20; //это на 32
  //TCCR2B = 1<<CS22 | 0<<CS21 | 0<<CS20; //это на 64
  //TCCR2B = 1<<CS22 | 0<<CS21 | 1<<CS20; //это на 128
  //Подключение прерывания по переполнению Timer2
  TIMSK2 = 1<<TOIE2;

  //Установки Таймер1: Делитель частоты /64, режим 0
  //Частота = 16MHz/64 = 250000 герц или
  //Делитель /64 дает нам хороший рабочий диапазон
  //так что сейчас мы просто жестко запрограммируем это.
  TCCR1A = 0;
  TCCR1B = 1<<CS22 | 0<<CS21 | 0<<CS20; //это на 64
  //Подключение прерывания по переполнению Timer0 (для обнуления скорости)
  TIMSK1 = 1<<TOIE1;
   
 
  //Выводит загружаемое значение таймера
  Serial.print("Timer2 Load:");
  Serial.println(FullTimer0,HEX);
 
  lcd.setCursor(0, 0); //устанавливаем курсор
  lcd.print("Stepper control"); //выводим на него  строку
  lcd.setCursor(0, 0); //устанавливаем курсор
  lcd.print("#St  Div  Ext"); //выводим на него  строку
  lcd.setCursor(0, 0); //устанавливаем курсор
//  lcd.cursor(); //Включим курсор
//  lcd.blink(); //Пусть мигает
 
  delay(10);
}

void loop() {
OptoSensorTicks=0;
//Один тик таймера - это 4 микросекунды (.000004) Зубъев у нас 70, причем реагируем на вход зуба а оптосенсор и на выход. Значит - 140 событий на оборот экструдера.
//Складывая время
for (int i=0; i<ToothSumm; i++)   {OptoSensorTicks+=OptoToothTimeArray[i];}
ScreenPass++; //Инкремент счетчика
if (ScreenPass>1000)
{
  ScreenPass=0; //Обнуляем счетчик
 
        lcd_key=read_LCD_buttons(); //прочитаем нажатую кнопку
      //0   4   8   12  |
      // St  Div  Ext
      //000  00000 00000
       
        if (lcd_key) //Нажата какая-то кнопка
        {
           if (btnSELECT==lcd_key) //Если нажата кнопка Select
             {
               ControlMode=!ControlMode;
               if (ControlMode)
               {
                 if (ControlPos==0)
                     {
                       lcd.setCursor(0, 0);
                        lcd.print("*");
                        lcd.setCursor(4, 0);
                        lcd.print(" ");
                     }
                 if (ControlPos==1)
                     {
                        lcd.setCursor(0, 0);
                        lcd.print(" ");
                        lcd.setCursor(4, 0);
                        lcd.print("*");
                     }
                 }
                 else
                 {
                   lcd.setCursor(0, 0);
                   lcd.print(" ");
                   lcd.setCursor(4, 0);
                   lcd.print(" ");
                   if (ControlPos==1){lcd.setCursor(4, 0); lcd.print("#"); }
                   if (ControlPos==0){lcd.setCursor(0, 0); lcd.print("#"); }
                 }
              } //Меняем режим на другой :)
           if (ControlMode) //Если режим - "редактирование"
             {
               if (btnUP==lcd_key) //Если нажата кнопка "Больше"
                 {
                       if (ControlPos==0) //Меняем частоту протяжки шагами
                         {
                           OutFreq+=10;
                           SetupTimer2(OutFreq); //устанавливаем таймер
                          }
                       if (ControlPos==1) //Меняем коэффициент шагами
                         {DivK+=1;}
                  }
               if (btnDOWN==lcd_key) //Если нажата кнопка "Меньше"
                 {
                       if (ControlPos==0) //Меняем частоту протяжки шагами
                         {
                           OutFreq-=10;
                           SetupTimer2(OutFreq); //устанавливаем таймер
                          }
                       if (ControlPos==1) //Меняем коэффициент шагами
                         {DivK-=1;}
                  }
               if (btnRIGHT==lcd_key) //Если нажата кнопка "ВПРАВО"
                 {
                       if (ControlPos==0) //Меняем частоту протяжки единицами
                         {
                           OutFreq+=1;
                           SetupTimer2(OutFreq); //устанавливаем таймер
                          }
                       if (ControlPos==1) //Меняем коэффициент единицами
                         {DivK+=.01;}
                  }
               if (btnLEFT==lcd_key) //Если нажата кнопка "ВЛЕВО"
                 {
                       if (ControlPos==0) //Меняем частоту протяжки единицами
                         {
                           OutFreq-=1;
                           SetupTimer2(OutFreq); //устанавливаем таймер
                         }
                       if (ControlPos==1) //Меняем коэффициент единицами
                         {DivK-=.01;}
                  }
             }
            else //режим "выбор"
             {
                if (btnRIGHT==lcd_key) //нажата кнопка ВПРАВО
                  {
                    lcd.setCursor(0, 0);
                    lcd.print(" ");
                    lcd.setCursor(4, 0);
                    lcd.print("#");
                    ControlPos = 1;
                  }
                if (btnLEFT==lcd_key) //нажата кнопка ВЛЕВО   
                {
                    lcd.setCursor(4, 0);
                    lcd.print(" ");
                    lcd.setCursor(0, 0);
                    lcd.print("#");
                    ControlPos = 0;
                }
             }
        }
             
             
      //Теперь в зависимости от режима нужно...
      //Либо считать частоту шаговика от коэффициента при ControlMode==1 и ControlPos==1
      //Либо вычислять коэффициент при ControlMode==1 и ControlPos==0
      //Либо вычислять частоту шаговика от коэффициента при ControlMode==0
      //Короче, только при ControlMode==1 и ControlPos==0 вычислять коэффициент. В остальных случаях - частоту.
       if ((ControlMode==1) && (ControlPos==0)) //Если режим - редактирование, изменение шаговика
        {
         DivK= ((float)OutFreq*(float)OptoSensorTicks)/1000;  //Вычислим коэффициент
         }
      else
        {
          OutFreq=((float)DivK*1000)/(float)OptoSensorTicks;
          if (OutFreq>HighFreq){OutFreq=HighFreq;}
          if (OutFreq<LowFreq){OutFreq=LowFreq;}
          SetupTimer2(OutFreq); //устанавливаем таймер
        }
 
      //Выведем коэффициент
         lcd.setCursor(8, 1);
         lcd.print(DivK, DEC);
     
      //выведем скорость
          lcd.setCursor(10, 0);
          lcd.print("     ");
          lcd.setCursor(10, 0);
          lcd.print(ExtruderConst/OptoSensorTicks, DEC);
         
      //    lcd.setCursor(9, 1);
      //    lcd.print("     ");
      //    lcd.setCursor(9, 1);
      //    lcd.print(OptoSensorTicks);
     
          lcd.setCursor(0, 1);
          lcd.print(OutFreq/200); //выведем частоту в оборотах в СЕКУНДУ. Коэффициент 1 секунд*200 имп.оборот = 200
     
       
          /*
            Serial.print("sensor=");
            Serial.println(sensorValue,DEC);
            Serial.print("FullTimerCount");
            Serial.println(FullTimerCount);
            Serial.print("FullTimer");
            Serial.println(FullTimer,DEC);
           
            Serial.print("timer=");
            Serial.println(FullTimer0,DEC);
           
            Serial.print("ButtPressed=");
            Serial.println(ButtPressed,DEC);
            Serial.print("OutFreq=");
            Serial.println(OutFreq,DEC);
            Serial.println("***");
            Serial.println("");
         
          Serial.println("***");   
            Serial.print("OutFreq=");
            Serial.println(OutFreq,DEC);
          Serial.println(OptoSensorTicks);
          delay (200);
         
             
              Serial.println("***");   
              Serial.print(FullTimer256);
              Serial.print("===");
              Serial.println(FullTimer0);
              */
}

}

//Timer1 указатель вектора прерывания по переполнению
ISR(TIMER1_OVF_vect)
{
    OptoToothTimeArray[OptoToothCounter]=0; //присваиваем элементу массива 0
    OptoToothCounter++; //инкрементим счетчик
    if (ToothSumm==OptoToothCounter) {OptoToothCounter=0;} //если счетчик равен количеству элементов массива (а индекс массива начинается с 0 - то обнуляем.
}

//Timer2 указатель вектора прерывания по переполнению
ISR(TIMER2_OVF_vect)
{
  noInterrupts(); //Запретили прерывания
  if (FullTimer256Count==0) // Срабатывание
        {
         //Переключение IO-вывода в HIGH
          digitalWrite(Step_pin,HIGH); //Переключение IO-вывода в HIGH (Старт импульса)
         FullTimer256Count=FullTimer256;
//         //Переключение IO-вывода в другое состояние.
//         digitalWrite(Step_pin,!digitalRead(Step_pin));
            //Перезагрузка таймера и коррекция по задержке
            if (!FullTimer256)
//                {TCNT2=0;} //Если холостые циклы есть  - максимальное значение
//            else
//                {TCNT2+=FullTimer0;}
                  {TCNT2=FullTimer0;}
          digitalWrite(Step_pin,LOW); //Переключение IO-вывода в LOW (Стоп импульса)
        }
  if (FullTimer256Count==1) //предпоследний цикл
     {
       TCNT2=FullTimer0;
       FullTimer256Count=0;
     }
  if (FullTimer256Count>1) //Обычный цикл
     {FullTimer256Count--;}
  interrupts(); //Разрешили прерывания
}


#define TIMER_CLOCK_FREQ 1000000.0
//15625 for /1024
//2MHz for /8 prescale from 16MHz
//Возвращает начальное значение таймера, которое должно быть загружено в TCNT2
//внутри вашей процедуры ISR.
unsigned char SetupTimer2(float timeoutFrequency){
  //Подсчет начального значения таймера
  //Слегка усложним, добавив холостые просчеты
  long ticks = TIMER_CLOCK_FREQ/timeoutFrequency; // тиков счетчика для получения заданной частоты
//          #if defined(Razr)
//             lcd.setCursor(9, 0);
//             lcd.print(ticks);
//          #endif
  FullTimer256=ticks/256; //Вычисляем количество ПОЛНЫХ 256 циклов таймера
  ticks-=FullTimer256*256;
  ticks-=8;
  FullTimer0=(byte)(255.0-ticks);  //Вычисляем количество доплнительных тиков таймера
  //загружает таймер для первого цикла
  //Сейчас не надо, убираю.
//  if (FullTimer256)
//    {TCNT2=0;} //Если холостые циклы есть  - максимальное значение
//  else
//      {TCNT2=FullTimer0;}
}



// *****************************
//Чтение кнопок с антидребезгом
// read the buttons
int read_LCD_buttons()
{
int adc_key_in = analogRead(ButtonPin);      // Получаем напряжение с АЦП
byte btnTempTemp = btnNONE; //Переменная для хранения свежесчитанного внутри функции
//digitalWrite (LED_pin,0); //debug
//lcd.setCursor(5, 0); //debug
//lcd.print(adc_key_in); //debug
//delay (400); //debug
//Тут используем millis() для отслеживания нажатия кнопки
// Запоминиаем в переменной BtnTime ВРЕМЯ НАЧАЛА нажатия
// Запоминаем в переменной btnTemp нажатия
// Дефиним время антидребезга #define

if (adc_key_in > 950) //Ничего не нажато
  {
   //BtnTime=0; //Скидываем время нажатия
   btnCONTpress=0;
   return btnNONE; // We make ths the 1st option for speed reasons since it will be the most likely result
  }
else //что-то нажато
   {
      if (adc_key_in < 790) { btnTempTemp=btnSELECT; } //Определяем в переменную ТЕКУЩУЮ нажатую кнопку.
      if (adc_key_in < 555) { btnTempTemp=btnLEFT; }
      if (adc_key_in < 380) { btnTempTemp=btnDOWN; }
      if (adc_key_in < 195) { btnTempTemp=btnUP; }
      if (adc_key_in < 50)  { btnTempTemp=btnRIGHT; }

     //А тут проверим, совпадает ли с btnTemp (была ли нажата ранее)
/*     lcd.setCursor(0, 0); //debug
     lcd.print(btnTempTemp); //debug
     lcd.setCursor(2, 0); //debug
     lcd.print(btnTemp); //debug
     lcd.setCursor(1, 1); //debug
     lcd.print(millis()); //debug
     lcd.setCursor(12, 1); //debug
     digitalWrite (LED_pin,1); //debug
     delay (100);
     lcd.print("    "); //debug
     lcd.setCursor(12, 1); //debug
     lcd.print(adc_key_in); //debug
*/
     if (btnTempTemp==btnTemp) //Кнопка уже БЫЛА нажата
     {
        if (btnCONTpress) //Повторные установки клавиши
          {
            if ((millis()-BtnTime) > btnPAUSEtime)
            {
              BtnTime=millis(); // Ставим стартово время для автоповтора
              return btnTemp;
            }
          } 
        else //Первая установка клавиши
           {
              if ((millis()-BtnTime) > btnDEFtime)
              {
                btnCONTpress=1;
                BtnTime=millis(); // Ставим стартово время для автоповтора
                return btnTemp;
              }
           }
     }
     else //Раньше было другое состояние
     {
//       digitalWrite (LED_pin,1); //debug
//       delay (100);
       btnCONTpress=0;
       BtnTime=millis(); //Устанавливаем ТЕКУЩЕЕ время в переменную BtnTime
       btnTemp=btnTempTemp; //устанавливаем кнопку во временную переменную.
     }
   }
return btnNONE;   // Если ничего не сработало, то ничего не возвращаем
}
//***********************************

void OptoSensor() // функция обработки прерывания. Меняет глобальные прееменные
{//Сработал - значит считаем тики. F njxytt - echtlyztv pf
  OptoToothTimeArray[OptoToothCounter]=TCNT1; //присваиваем элементу массива текущее значение таймера
  TCNT1 = 0; //сбрасываем таймер
  OptoToothCounter++; //инкрементим счетчик
  if (ToothSumm==OptoToothCounter) {OptoToothCounter=0;} //если счетчик равен количеству элементов массива (а индекс массива начинается с 0 - то обнуляем.
}
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: Arduino pro mini для управления шаговым двигателем

Сообщение Revenger » 22 сен 2015, 14:56

Спасибо! Всё, залил. Судя по показаниям дисплея (ШД не подключал) теперь всё правильно. Только множитель ранее был в один разряд, вчера был 50, а сейчас стал 500. Это нормально?
После трёх часов сегодня протестирую на экструдере. Может пластик даже даванУ чуть ))
Аватара пользователя
Revenger
 
Сообщения: 1728
Зарегистрирован: 01 ноя 2014, 00:50
Откуда: Ставрополье
ФИО: Александр

Re: Arduino pro mini для управления шаговым двигателем

Сообщение RootAdmin » 22 сен 2015, 15:40

Это нормально. Подберем коэффициент по удобству.
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: Arduino pro mini для управления шаговым двигателем

Сообщение Revenger » 22 сен 2015, 21:27

Попробовал регулировать DIV, но устал ждать результата )) не понял что и как, но параметр 7000 сложно менять по одному разряду (у меня почему-то там более 7тыс число стало). Реакция на замедление двигателя экструдера действует и мало того... подняв обороты ШД (в моем случае почти до 7) и нажав селект, оно сохранилось и четко реагировало на изменения! Супер!
Одно, мне кажется неуместное "но"... если экструдер выключить совсем, то инф падает на ноль, и ШД начинает вращаться на максимуме (частота становится 10). Лучше было бы, если бы он замедлялся до минимума или останавливался наверное.
Пока вот такие наблюдения.

Добавлено спустя 3 часа 6 минут 6 секунд:
Ну вот. Провёл тест в реальных боевых условиях. :roll:
Пока пытался выйти на нормальный диаметр прогнал несколько метров пластика. Та еще работёнка я вам скажу ))
Результат не очень. Не знаю причины, но толи пластик сам по себе не стабильная субстванция, толи экструдер не "как надо", но то идёт нормально вроде, то, вдруг, нить становится толще прямо на глазах, приходилось "крутить" скорость ШД вручную в больших пределах, пытаясь регулировать. Ну тут еще оптопара пока на соплях, тоже может что не так. Затем я убрал ролики, типа поддерживающие нить, она стала идти "провисом", под своим весом чуть вытягиваясь и результат стал получше (её не стало колбасить за счет того, что остывая она кое-где искривлялась и протяжка её мотыляла немного). Смог несколько метров пусть не стабильного диаметра выдавить, но хотя бы то, что можно воткнуть в принтер и уже попечатать. Есть мысль сделать протяжку как в филаструдере (если не ошибаюсь), где нить из экструдера свисает вниз и снова вверх в протяжку идёт, может тогда, путём подбора диаметра сопла получится стабилизировать диаметр. Или думать как и куда прилепить микрометр, чтобы контроль был мгновенный на малейшее изменение диаметра. Опять же.. куда его? За протяжку? Пока снова стала не понятна общая картина работы в комплексе :crazy:

п.с. Еще что подумалось... наверняка, для каждого отдельного экструдера необходимо искать "свой коэффициент", т.к. увеличивая обороты экструдера, протяжка реагирует в моём случае сильно ускоряясь, тем самым делая нить тоньше, причём сильно.

Пару фото в процессе
Вложения
IMG_1653[1].JPG
Здесь я просто "запомнил" более близкие к номиналу "свои" параметры ))
IMG_1652[1].JPG
Аватара пользователя
Revenger
 
Сообщения: 1728
Зарегистрирован: 01 ноя 2014, 00:50
Откуда: Ставрополье
ФИО: Александр

Re: Arduino pro mini для управления шаговым двигателем

Сообщение alfamosk » 22 сен 2015, 22:14

Я тут спросить хотел) а потом будет выкладываться код для ардуинки как что подключать?

Мне драйвер пришел из китая)
Аватара пользователя
alfamosk
 
Сообщения: 368
Зарегистрирован: 14 мар 2015, 00:36
Откуда: Казань-Италия

Re: Arduino pro mini для управления шаговым двигателем

Сообщение Revenger » 22 сен 2015, 22:50

Дык всё в теме )) По крайней мере пока автор ничего другого не решил.
А драйвер.. это хорошо, это просто замечательно. )) Присоединяйся к опытам ;)
Аватара пользователя
Revenger
 
Сообщения: 1728
Зарегистрирован: 01 ноя 2014, 00:50
Откуда: Ставрополье
ФИО: Александр

Re: Arduino pro mini для управления шаговым двигателем

Сообщение RootAdmin » 23 сен 2015, 00:03

Ага, увидел живые параметры. Допишу более плавное реагирование, буду усреднять дельту разности. А скорость экструдера сильно скачет? Это которая справа сверху. В каких пределах меняется?

Добавлено спустя 10 минут 46 секунд:
Ага, ускорение ШД при остановке экструдера - пофиксим.
Вижу в дальнейшем математику процесса не как функции y=kx где y - скорость протяжки, k - коэффициент, x - скорость экструдера, а чуть сложнее.
Попробуем, возможно все ж придется микрометр ставить.
Ещё: если использовать активное охлаждение (вентилятор) нити между экструдером и протяжкой, получится расстояние уменьшить? Дело в том что система сейчас слишком инерционная.
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: Arduino pro mini для управления шаговым двигателем

Сообщение alfamosk » 23 сен 2015, 00:08

Просто например мне не очень понятно какие компоненты использовались и что куда подключать) а в теме куча куча всего что я не могу разобрать((. И коды всегда допиливались и какой заливать не понятно) но судя по последнему комменту еще будете дорабатывать :)
Аватара пользователя
alfamosk
 
Сообщения: 368
Зарегистрирован: 14 мар 2015, 00:36
Откуда: Казань-Италия

Re: Arduino pro mini для управления шаговым двигателем

Сообщение RootAdmin » 23 сен 2015, 00:22

alfamosk писал(а):Я тут спросить хотел) а потом будет выкладываться код для ардуинки как что подключать?

Дык автор темы - Revenger. Не думаю что будет против.
А скетч изначально свободный. Надо GPL вставить. :)
Будут вопросы по подключению - поможем.

Добавлено спустя 6 минут 27 секунд:
Дорабатывать - будем, надо импортных экструдерщиков догнать и перегнать.
Так что надо покупать микрометр. :)
Вообще - надо набросать схему установки.
И сейчас больше склоняюсь к необходимости регулировки (поддержания) скорости экструдера.
Если .3 оборота в секунду, то время между срабатываниями оптопары .048 сек.
Подумаем...
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: Arduino pro mini для управления шаговым двигателем

Сообщение Revenger » 23 сен 2015, 00:41

RootAdmin писал(а):Ага, увидел живые параметры. Допишу более плавное реагирование, буду усреднять дельту разности. А скорость экструдера сильно скачет? Это которая справа сверху. В каких пределах меняется?

......................
Попробуем, возможно все ж придется микрометр ставить.
Ещё: если использовать активное охлаждение (вентилятор) нити между экструдером и протяжкой, получится расстояние уменьшить? Дело в том что система сейчас слишком инерционная.


По первому пункту: Я не додумался посмотреть пределы мкорости, но на 0,3 примерно это где-то 80% скорости, а 0,36 вроде максимум уже. Остальные цифры правее 3 меняются так, что не видно особо. Скорость экструдера скачет на доли секунды вроде, когда "зёрнышко" попадается и пока экструдер его не разрежет со щелчком. Возможно еще может чуть замедляться при просадке напряжения, но этого я не вижу.

По микрометру "я за" :good: Лишняя контролирующая зона ой как не помешает мне кажется.. однако...
на счет инерционности.. я и не додумался придвинуть протяжку ближе и просто охладить нить сразу на выходе... возможно это упростит процесс. Кулеры валются, но я их отключил пока, видел просто у других подобный провис или по роликам едет.. Да у того же Лимана.. ванна водяная на пути, но кулеры я попробую поставить и расстояние как минимум вдвое уменьшится.
Ну и сопло я снял, хочу завтра в него внедрить сменный жиклёр. Рассверлю чуть меньше нужного диаметра как у других и попробую. Сейчас 2мм у меня там, думал протяжкой вытягивать, но надо попробовать разные варианты. Одно дело слова других, а другое своё )) У всех разный конструктив.

Добавлено спустя 4 минуты 6 секунд:
alfamosk писал(а):Просто например мне не очень понятно какие компоненты использовались и что куда подключать) а в теме куча куча всего что я не могу разобрать((. И коды всегда допиливались и какой заливать не понятно) но судя по последнему комменту еще будете дорабатывать :)

Начни сначала, если драйвер появился в наличии. Как раз с драйвера то тут у нас всё и началось. Далее всё быстро - как что и куда подсоединить (если у тебя такой), затем сразу ардуино пошла и тоже всё есть. А далее уже пошло много постов мечт и обсуждений, можешь пропустить до последнего скетча и уже начать тестировать с крайним (разве что куда какую ногу чуть ранее ищи, или в самОм скетче всё Андрей расписАл.
Я бы тоже хотел найти темку, где в одном посте было бы всё.. от схемы до советов в работе, но нет такой. Вот... создаём как можем :oops: Ну как создаём.. Мастер программирования создаёт, а я только кнопки жму :P
Аватара пользователя
Revenger
 
Сообщения: 1728
Зарегистрирован: 01 ноя 2014, 00:50
Откуда: Ставрополье
ФИО: Александр

Пред.След.

Вернуться в Arduino и другие Xduino

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

cron