ЧПУ станок для намотки трансформаторов на Arduino и Digispark.

Доброго времени суток!

Эта статья является инструкцией, по управлению ЧПУ станком для намотки трансформаторов на Arduino, а также инструкцией по самостоятельной сборке этого же станка.


Эта статья состоит из таких тем:

Перечень расходных материалов, которые использовались при сборке станка.

Обзор функций клавиатуры для ЧПУ станка на Arduino.

Сборка, проверка, и подключение клавиатуры к ЧПУ станку на Arduino.

Сборка электронных частей ЧПУ станка, для намотки трансформаторов.



Перечень расходных материалов, которые использовались при сборке станка.


Так как в моем случае не планируется использовать станок для намотки крупных трансформаторов, то было решено сэкономить на материалах для корпуса и механики. Применив для изготовления корпуса Б/У ДСП и саморезы по дереву.


Для изготовления механики использовались:

Шпилька с резьбой на 8мм, длинна 1 метр, повышенного класса прочности.

Обычные и удлинённые гайки с резьбой на 8мм.

Шайбы с внутренним диаметром 8мм.

Головка под гайку на 13, с квадратом ½ дюйма.

Пружина длинной 40мм и внутренним диаметром 8-9мм.

Болт с резьбой 8мм и длинной 80мм.

Подшипники марки 608, размером 8*22мм.

Биполярный шаговый двигатель NEMA17.

Ремень зубчатый GT2 длинной 200мм.

Шкив для зубчатого ремня GT2 6мм Z16 D5.

Шкив для зубчатого ремня GT2 6мм Z60 D8.

Магнит от маленького магнитного замка.

Строительный уголок 60*80мм.


Для изготовления электронной части использовались:

Плата Arduino Uno.

Плата Digispark Attini85.

Модули датчиков холла 2 шт.

CNC Shield V3.

Драйвер биполярного шагового двигателя DRV8825 или A4988.

Кнопки 8 шт.

Потенциометр 3-10 кОм.

Сопротивления (одинаковые) 200-600 Ом 8 шт.

Сопротивление 15-22 кОм 1 шт.

Сопротивления 400-900 Ом 3 шт. (для спец драйвера).

Разъемы.

Провода.

LCD I2C дисплей 1602.

Односторонняя плата 7*9см, или примерно такого размера (для клавиатуры).

Односторонняя плата примерно 4*5см (для сборки спец драйвера).

Так как для плат и для драйвера шагового двигателя рекомендуется использовать разные источники питания, то понадобятся 2 блока питания, 5 вольт 1 ампер, и 12 вольт 3 ампера. Если Вы планируете в дальнейшем добавлять механизм для укладки провода, то тогда понадобится 12 вольтовый блок питания не на 3 ампера, а на 8-10 ампер. Или можно как я, применить блок питания от старого компьютера. Для его запуска надо будет замкнуть зеленый провод на минус!



На фото, которое ниже показан внешний вид станка, без механизма направляющего провод, а также без механизма предназначенного для крепления мотка с проводом, и для натяжения провода.

ЧПУ станок для намотки трансформаторов на Arduino, без механизма направляющего провод.

Обзор функций клавиатуры для ЧПУ станка на Arduino.


На фото которое ниже, показано меню для управления ЧПУ станком, где подписано, для чего используется каждый элемент меню.

Также показана панель с кнопками, где отмечено, для чего используется каждая кнопка панели.

LCD дисплей 1602 и клавиатура, для ЧПУ станка по намотке трансформаторов на Arduino.

Подробное видео по первой части проекта, с обзором возможностей станка, а также о том как собрать корпус и механику из доступных материалов.


ЧПУ станок для намотки трансформаторов на Arduino и Digispark Attyny85, 1 часть.



Внимание!


В проекте используется две платы, связь между которыми реализована по шине I2C. Плата Arduino UNO используется в качестве главного устройства, и в шине I2C она выступает в роли Мастера (Master).

Плата Digispark используется в качестве контроллера, для биполярного шагового двигателя. Она обеспечивает плавный пуск, и остановку шагового двигателя Nema17. И к шине I2C она подключается как Слейв (Slave).

Для платы Digispark используется код, и схема для сборки спец драйвера, из недавнего проекта, который найдете по этой ссылке

Код предназначенный для платы Digispark, следует загружать без внесения изменений!



Сборка, проверка, и подключение клавиатуры к ЧПУ станку на Arduino.


Для обозначения кнопок пришлось нарисовать рисунок, который показан на фото ниже.

Можете его тоже использовать, для этой же цели.

Для этого надо кликнуть правой кнопкой мышки в области рисунка, в выпадающем меню выбрать пункт “Сохранить картинку как…”, указать место куда вы хотите сохранить рисунок, и нажать “Сохранить”.

После чего вы сможете распечатать его на своем принтере, или в ближайшем фотоцентре, задав перед печатью такой же размер рисунка, как размер платы на которую он будет приклеен.

Обозначение кнопок клавиатуры, для ЧПУ станка по намотке трансформаторов на Arduino.

Прежде чем собирать клавиатуру для ЧПУ станка, надо загрузить этот код на плату Arduino.

С помощью этого кода вы сможете проверить корректность сборки клавиатуры.

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


//Начало скетча


void setup() { 
  Serial.begin(9600);
}

void loop() {
  int a_0 = analogRead(A0);
  int a_3 = analogRead(A3);
  Serial.print("Pin13="); Serial.print(digitalRead(13));
  Serial.print("  A0="); Serial.print(a_0);
  Serial.print("  A3="); Serial.println(a_3);
  delay(1000);        
}

//Конец скетча




Если вы не планируете в будущем добавлять механизм для укладки провода, то можно собрать клавиатуру по этой схеме, и подключить ее на прямую к Arduino, без использования CNC шилда.

В таком случае в качестве главной платы, можно использовать не только плату Arduino Uno, а и любую другую плату из линейки Arduino!

Перед подключением клавиатуры к Arduino, следует тщательно проверить корректность спаянной схемы, и прозвонить контакты на отсутствие короткого замыкания!

Подключение клавиатуры к Arduino.

И если вы в будущем планируете добавлять механизм для укладки провода, то надо подключать клавиатуру к Arduino Uno, через CNC Shield V3, как показано на фото, которое ниже!

При этом сама клавиатура собирается по той же схеме, что на фото выше!

Перед подключением клавиатуры к Arduino, следует тщательно проверить корректность спаянной схемы, и прозвонить контакты на отсутствие короткого замыкания!

Подключение клавиатуры к Arduino с помощью CNC Shield V3.

Проверять клавиатуру следует, как показано на видео во 2 части этого проекта, его найдете ниже в этой же статье!

Убедившись, что схема клавиатуры работает корректно, можно приступать к дальнейшей сборке станка.



Сборка электронных частей ЧПУ станка, для намотки трансформаторов.


Прежде чем собирать электронную часть станка, следует загрузить в плату Arduino код, который ниже.

Внимание! Этот код будет работать при условии, если I2C адрес вашего LCD дисплея тоже 3f, если же адрес дисплея другой, то его следует указать в коде, после чего его можно загружать в плату Arduino. О том, как это делается, я рассказывал в видео 2 части проекта, которое найдете ниже.

Основой код для платы Arduino.


//Начало скетча


#include "Wire.h"           // Библиотека для с шиной I2C
#include "EEPROM.h"         // Библиотека для работы с энергонезависимой памятью (EEPROM)

//Библиотека для дисплея 1602
//#include "Adafruit_LiquidCrystal.h"  // Для использования скетча в UnoArdusim
#include <LiquidCrystal_I2C.h>         // Для загрузки скетча в Arduino

//I2C адрес дисплея 1602
//Adafruit_LiquidCrystal lcd(0x20);   // Для использования скетча в UnoArdusim
LiquidCrystal_I2C lcd(0x3f, 16, 2);   // Для загрузки скетча в Arduino

#define holl_1 5                      //Контакт для подключения 1 датчика холла
#define holl_2 2                      //Контакт для подключения 2 датчика холла
#define buttons A3                    //Контакт для подключения резистивной клавиатуры
#define potentiometr A0               //Контакт для подключения потенциометра
#define button_START 13               //Контакт для подключения кнопки START

#define button_ST 3                   //Контакт для подключения перемычки

const int address_I2C_Stepper_1 = 8;  //I2C адрес ведущего шагового двигателя 

int sp_2 = 40;
int sp_1 = 20;

//Функция для первоначальной записи настроек в EEPROM, а также для считывания настроек из EEPROM
void EEPROM_parameters();
boolean flag_EEPROM = 0;
int count_batton_ = 0, count_batton_UP = 0;
int address_ = 0;

void send_to_I2C(int int_x, int ADDR_to_Slave); //Фукция для отправки команд по шине I2C
byte masiv[2];

void Scan_Buttos();       //Функция для считавания состояний кнопок
void Scan_potentiometr(); //Функция для считавания состояния потенциометра
void Send_to_Display();   //Функция для вывода на дисплей
void Go_to_menu_();       //Функция для запуска меню с настройами, по удержанию кнопки START более 5 секунд

int raznitsa = 10, pause_ = 500, pause_2 = 300, pause_3 = 300, analog_Buttons = 1023, analog_Speed = 0, analog_Speed_BUF = 0;
int flag_Rotation = 0, command_Rotate = 102, pp = 0, Max_Speed = 100;
boolean button_Start_, button_St_ = 1, flag_Rotation_1 = 1, flag_Rotation_2 = 1, flag_Forward = 1, flag_STOP_Forward = 0, Direction_of_rotation = 1;
boolean flag_button = 1, flag_button2 = 1, flag_button_START = 0, flag_Display = 0, program = 0, fl = 0;
unsigned long saveMillis = 0, saveMillis0 = 0, saveMillis1 = 0, saveMillis2 = 0, saveMillis3 = 0;
int count_Reverse0 = 0, count_Reverse1 = 0;
unsigned long millis_Reverse0 = 0, millis_Reverse1 = 0;

//const char str0[] PROGMEM = "||";  //Перенос строк во флеш память (заготорка на будущее)
//const char str1[] PROGMEM = "<|";
//const char * const stringi[] PROGMEM = {str0, str1};

//                    0     1     2    3     4     5      6        7              8                  9           10     11          12      13         14        15     16
String stringi[] = {"||", "<|", "|>", "<<", ">>", "KV", "VV", "Speed:", "Sawe parameters!", "Start program!", ">", "Batton:", "Param", "      ", "Completed!", "RS", "SAVE"};
int indikator_Revers = 0, indikator_Start = 4;
long K_V = 0, K_V_count = 1;

void scan_holls();  //Фукция для мониторинга состояния датчиков холла
volatile int count = 0; 
volatile int state_;
volatile int last_State;
volatile int V_V = 0;

//Переменные для хранения значений аналоговых кнопок
//Их адреса   2              4                6                8                   10               12                14
int button_STOP = 0, button_UP = 0, button_DOWN = 0, button_KV_0 = 0, button_Forward = 0, button_Back = 0, button_Reverse = 0;

String name_[] = {"MAX SPEED", "", "STOP", "", "UP", "", "DOWN", "", "KV_0", "", "Forward", "", "Back", "", "Revers", "", ""};

//---------------------------------------- void setup() -------------------------------------------  
void setup() {
  Wire.begin(1);          // i2c адрес платы Arduino будет #1

  //lcd.begin(16, 2);     // Для использования скетча в UnoArdusim, и для загрузки в Arduino
  lcd.init();             // Для загрузки скетча в Arduino

  lcd.setBacklight(HIGH);
  EEPROM_parameters();
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print(stringi[14]);
  delay(1500);
  flag_Display = 1;
  pinMode (holl_1,INPUT);                 //Назначить контакт holl_1 входом
  pinMode (holl_2,INPUT);                 //Назначить контакт holl_2 входом
  pinMode (button_START,INPUT_PULLUP);    //Назначить контакт button_START входом
  pinMode (button_ST,INPUT_PULLUP);       //Назначить контакт button_ST входом

  send_to_I2C(113, address_I2C_Stepper_1);//Задать ускорение 113 
  last_State = digitalRead(holl_1);       // Считать начальное состояние выхода holl_1
  //Первоочередной запуск функции scan_holls, если изменено состояние контакта holl_2
  attachInterrupt(0, scan_holls, CHANGE);  
}
//------------------------------------- start void loop() ------------------------------------------- 
void loop() {
  Scan_Buttos();

  //Условие разрешающее повторное считывание кнопки, через пол секунды после того как она была нажата
  if (millis() - saveMillis > pause_) { flag_button = 1;}

  //Условие для вывода на дисплей количества намотаных витков
  if (millis() - saveMillis3 > pause_3) {
    saveMillis3 = millis();
    lcd.setCursor(10, 0);lcd.print(stringi[13]);
    lcd.setCursor(10, 0);lcd.print(V_V);
  }

  //Условие для корок UP и DOWN. При удержании кнопок выполняет увеличение шага изменения значения.
  if (millis() - saveMillis2 > pause_2) { 
    if((button_St_ == LOW && analog_Buttons > button_UP - raznitsa) && (analog_Buttons < button_UP + raznitsa) || button_St_ == LOW && (analog_Buttons > button_DOWN - raznitsa) && (analog_Buttons < button_DOWN + raznitsa)){
      count_batton_UP++;
      if(count_batton_UP > 37){ K_V_count = 10000;
      }else if(count_batton_UP > 28){ K_V_count = 1000;
      }else if(count_batton_UP > 19){ K_V_count = 100;
      }else if(count_batton_UP > 10){ K_V_count = 10;
      }else{  K_V_count = 1;}
    }else{  count_batton_UP = 0;}
    flag_button2 = 1;
  }

  Go_to_menu_();
  Send_to_Display();
  Scan_potentiometr();

  //Если кнопка START нажата то присвоить 1 переменной flag_button_START
  if(flag_button == 1 && K_V != V_V){
    if(digitalRead(button_START) == LOW){  
      flag_button_START = 1; program = 1;
      flag_button = 0; saveMillis = millis();
    }
  }

  //Если переменная flag_button_START равна 1, и кнопка START отпущена 
  if(flag_button_START == 1 && digitalRead(button_START) == HIGH){
    flag_button_START = 0;
    //Отправить команду для запуска вращения вала шагового двигателя
    send_to_I2C(command_Rotate, address_I2C_Stepper_1); send_to_I2C(analog_Speed_BUF, address_I2C_Stepper_1);
    //Обновить индикатор на дисплее 1602
    if(Direction_of_rotation == 1){
      lcd.setCursor(14, 1); lcd.print(stringi[4]);
    }
    if(Direction_of_rotation == 0){
      lcd.setCursor(14, 1); lcd.print(stringi[3]);
    }
  }

  //Опрос кнопки STOP
  if(flag_button == 1 && button_St_ == LOW && ((analog_Buttons > button_STOP - raznitsa) && (analog_Buttons < button_STOP + raznitsa))){ 
    send_to_I2C(0, address_I2C_Stepper_1);
    lcd.setCursor(14, 1); lcd.print(stringi[indikator_Revers]);
    flag_button = 0; program = 0; saveMillis = millis();
  }

  //Опрос кнопки UP (и ST)
  if(flag_button2 == 1 && button_St_ == LOW && ((analog_Buttons > button_UP - raznitsa) && (analog_Buttons < button_UP + raznitsa))){ 
    K_V = K_V + K_V_count; if(K_V > 90000){ K_V = 90000;}
    lcd.setCursor(2, 0); lcd.print(stringi[13]);
    lcd.setCursor(2, 0); lcd.print(K_V);
    flag_button2 = 0; saveMillis2 = millis(); 
  }

  //Опрос кнопки DOWN (и ST)
  if(flag_button2 == 1 && button_St_ == LOW && ((analog_Buttons > button_DOWN - raznitsa) && (analog_Buttons < button_DOWN + raznitsa))){ 
    K_V = K_V - K_V_count;
    lcd.setCursor(2, 0); lcd.print(stringi[13]);
    lcd.setCursor(2, 0); lcd.print(K_V);
    flag_button2 = 0; saveMillis2 = millis();
  }

  //----------------------------------------------------------- STOP -------------------------------------------------------------
  if(program == 0){ //Если состояние программы STOP, то можно обнулить значения, и выполнять ручное управление валом

    //Опрос кнопки KV_0 (и ST), если кнопка нажата, то обнулить значения заданых и намотаных витков
    if(flag_button == 1 && button_St_ == LOW && ((analog_Buttons > button_KV_0 - raznitsa) && (analog_Buttons < button_KV_0 + raznitsa))){ 
      K_V = 0; V_V = 0;
      lcd.setCursor(2, 0);  lcd.print(stringi[13]);
      lcd.setCursor(2, 0);  lcd.print(K_V);
      lcd.setCursor(10, 0); lcd.print(stringi[13]);
      lcd.setCursor(10, 0); lcd.print(V_V);
      flag_button = 0; saveMillis = millis();
    }

    //Если нажата кнопка Forward, то выполнять вращение вперед, пока она нажата
    if(button_St_ == LOW && ((analog_Buttons > button_Forward - raznitsa) && (analog_Buttons < button_Forward + raznitsa))){ 
      flag_STOP_Forward = 0; fl = 1;
      if(flag_Forward == 1){  flag_Forward = 0;
        lcd.setCursor(14, 1); lcd.print(stringi[2]);
        send_to_I2C(102, address_I2C_Stepper_1); send_to_I2C(analog_Speed_BUF, address_I2C_Stepper_1);}
      //Если нажата кнопка Back, то выполнять вращение в обратном направлении, пока она нажата    
    }else if(button_St_ == LOW && ((analog_Buttons > button_Back - raznitsa) && (analog_Buttons < button_Back + raznitsa))){  
      flag_STOP_Forward = 0; fl = 1;
      if(flag_Forward == 1){  flag_Forward = 0;
        lcd.setCursor(14, 1); lcd.print(stringi[1]);
        send_to_I2C(103, address_I2C_Stepper_1); send_to_I2C(analog_Speed_BUF, address_I2C_Stepper_1);}
    }else{  flag_STOP_Forward = 1; fl = 0;}

    //Иначе остановить вращение
    if(flag_Forward == 0 && flag_STOP_Forward == 1){  flag_Forward = 1; flag_STOP_Forward = 0;
      send_to_I2C(0, address_I2C_Stepper_1); flag_Display = 1;
    }

    //Опрос кнопки Reverse (и ST)
    if(Direction_of_rotation ==  0 && flag_button2 == 1 && button_St_ == LOW && ((analog_Buttons > button_Reverse - raznitsa) && (analog_Buttons < button_Reverse + raznitsa))){ 
      if (millis() - millis_Reverse0 > 10) { count_Reverse0++; millis_Reverse0 = millis();}
    } else{count_Reverse0 = 0;}    
      if(count_Reverse0 > 3){
        Direction_of_rotation = 1; command_Rotate = 102; indikator_Revers = 0; indikator_Start = 4;
        lcd.setCursor(14, 1); lcd.print(stringi[indikator_Revers]);
        flag_button2 = 0; pp = 0; saveMillis2 = millis();
        count_Reverse0 = 0;
    }  

    if(Direction_of_rotation ==  1 && flag_button2 == 1 && button_St_ == LOW && ((analog_Buttons > button_Reverse - raznitsa) && (analog_Buttons < button_Reverse + raznitsa))){
      if (millis() - millis_Reverse1 > 10) { count_Reverse1++; millis_Reverse1 = millis();}
    } else{count_Reverse1 = 0;} 
      if(count_Reverse1 > 3){
        Direction_of_rotation = 0; command_Rotate = 103; indikator_Revers = 15; indikator_Start = 3;
        lcd.setCursor(14, 1); lcd.print(stringi[indikator_Revers]);
        flag_button2 = 0; pp = 1; saveMillis2 = millis();
        count_Reverse1 = 0;
      }
    //----------------------------------------------------------- START -------------------------------------------------------------                 
  }else{  //Если состояние программы START, то проверять остаток витков до завершения
    flag_Rotation = K_V - V_V;
    //Если до завершения осталось 2 витка то перейти скорость sp_2
    if(flag_Rotation == 2 - pp && flag_Rotation_2 == 1){  send_to_I2C(sp_2, address_I2C_Stepper_1); flag_Rotation_2 = 0;}
    //Если до завершения остался 1 виток то перейти на скорость sp_1
    if(flag_Rotation == 1 - pp && flag_Rotation_1 == 1){  send_to_I2C(sp_1, address_I2C_Stepper_1); flag_Rotation_1 = 0;}
    //Если до завершения остался 0 виток то остановить вращение вала
    if(flag_Rotation == 0 - pp){
      send_to_I2C(0, address_I2C_Stepper_1);
      lcd.setCursor(14, 1); lcd.print(stringi[indikator_Revers]);
      program = 0; flag_button_START = 0; flag_Rotation_1 = 1; flag_Rotation_2 = 1;}
  }

}//------------------------------------- end void loop() ----------------------------------------

//Функция для вывода на дисплей. Запускается только после выхода из меню для настройки кнопок
void Send_to_Display(){
  if(flag_Display == 1){
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(stringi[5]); lcd.print(K_V);
    lcd.setCursor(8, 0);
    lcd.print(stringi[6]); lcd.print(V_V);
    lcd.setCursor(0, 1);
    lcd.print(stringi[7]);
    lcd.setCursor(6, 1);
    lcd.print("   ");
    lcd.setCursor(6, 1);
    lcd.print(analog_Speed_BUF);
    lcd.setCursor(14, 1);
    lcd.print(stringi[indikator_Revers]);
    flag_Display = 0;   
  }
}

//Функция для запуска меню с настройами, по удержанию кнопки START более 5 секунд
void Go_to_menu_(){
  if (millis() - saveMillis0 > 500) { 
    saveMillis0 = millis();
    if(digitalRead(button_START) == LOW){
      count_batton_++;}else{  count_batton_ = 0;}
    if(count_batton_ > 10){ flag_EEPROM = 1; count_batton_ = 0;
      send_to_I2C(0, address_I2C_Stepper_1);
      EEPROM_parameters();
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(stringi[8]);
      delay(3000);
      flag_Display = 1;
      Send_to_Display();
    }
  }
}

//Функция для первоначальной записи настроек в EEPROM, а также для считывания настроек из EEPROM
void EEPROM_parameters(){
  //Анимация при запуске меню для настроек
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print(stringi[9]);
  lcd.setCursor(0, 1);
  for(int x_ = 0; x_ < 17; x_++){
    delay(300); lcd.print(stringi[10]);
  } 

  int EEPROM_parameter = 0; //Переменная для хранения параметра полученого из EEPROM

  while(address_ < 15 && flag_EEPROM == 0){ //Цикл для проверки наличия нулевых записей в EEPROM
    EEPROM.get(address_, EEPROM_parameter);
    if(EEPROM_parameter == 0 || EEPROM_parameter == -1){  flag_EEPROM = 1;} //Если имеется нулевая запись, то перейти к следующему циклу
    address_+=2;
  }   address_ = 0;

  while(address_ < 15 && flag_EEPROM == 1){ //Цикл для сохранения параметров кнопок
    int time_ = 300;
    EEPROM.get(address_, EEPROM_parameter);
    analog_Buttons = analogRead(buttons);
    if(digitalRead(button_START) == 0){ //Если нажата кнопка button_START, то сохранить параметр кнопки
      if(address_ == 0){  EEPROM.put(address_, analog_Speed);}
      if(address_ > 1){ EEPROM.put(address_, analog_Buttons);}
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(stringi[16]);
      lcd.setCursor(7, 0);
      lcd.print(name_[address_]); 
      address_+=2;
      //time_ = 3000;
      delay(3000);
    }
    if(address_ == 0){  //Блок выводит на дисплей параметры во время их настройки (отенциометр)
      analog_Speed = analogRead(potentiometr)/10;
      if(analog_Speed > 100){ analog_Speed = 100;}
      if(analog_Speed < 1){ analog_Speed = 1;}
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(stringi[11]);
      lcd.setCursor(0, 1);
      lcd.print(stringi[12]);
      lcd.setCursor(7, 0);
      lcd.print(name_[address_]); //Отобразить текущее название кнопки
      lcd.setCursor(7, 1);
      lcd.print(EEPROM_parameter);//Отобразить значение скорости записаное в EEPROM
      lcd.setCursor(12, 1);
      lcd.print(analog_Speed);  //Отобразить текущее значение кнопки
      delay(300);
    }
    if(address_ > 1){ //Блок выводит на дисплей параметры во время их настройки (кнопки)
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(stringi[11]);
      lcd.setCursor(0, 1);
      lcd.print(stringi[12]);
      lcd.setCursor(7, 0);
      lcd.print(name_[address_]); //Отобразить текущее название кнопки
      lcd.setCursor(7, 1);
      lcd.print(EEPROM_parameter);//Отобразить значение кнопки записаное в EEPROM
      lcd.setCursor(12, 1);
      lcd.print(analog_Buttons);  //Отобразить текущее значение кнопки
      delay(300);
    }
  }address_ = 0; flag_EEPROM = 0;
  //Получение значений настроек из энергонезависимой памяти (EEPROM)
  EEPROM.get(0, Max_Speed); //Максимальная скорость вращения
  EEPROM.get(2, button_STOP);
  EEPROM.get(4, button_UP);
  EEPROM.get(6, button_DOWN);
  EEPROM.get(8, button_KV_0);
  EEPROM.get(10, button_Forward);
  EEPROM.get(12, button_Back);
  EEPROM.get(14, button_Reverse);
  //Чтобы при выходе из меню не запускался двигатель
  analog_Speed_BUF = analog_Speed;
  flag_button_START = 0; program = 0;
}

void Scan_Buttos(){ //Функция для считавания состояний кнопок
  analog_Buttons = analogRead(buttons);
  button_St_ = digitalRead(button_ST);
}

void Scan_potentiometr(){ //Функция для считавания состояния потенциометра
  if (millis() - saveMillis1 > 500) {
    saveMillis1 = millis();
    analog_Speed = analogRead(potentiometr)/10;
    if(analog_Speed > Max_Speed){ analog_Speed = Max_Speed;}
    if(analog_Speed < 1){ analog_Speed = 1;}    

    if(analog_Speed_BUF != analog_Speed){
      analog_Speed_BUF = analog_Speed;
      lcd.setCursor(6, 1);
      lcd.print("   ");
      lcd.setCursor(6, 1);
      lcd.print(analog_Speed_BUF);
      if(program == 1 || fl == 1){  send_to_I2C(analog_Speed_BUF, address_I2C_Stepper_1);}
    }
  }
}

void send_to_I2C(int int_x, int ADDR_to_Slave){ //Фукция для отправки команд по шине I2C
  Wire.beginTransmission(ADDR_to_Slave);        // Начать передачу данных
  masiv[0] = (int_x >> 8);
  masiv[1] = (int_x & 0xff);
  Wire.write(masiv[0]);                 // Отправка байта
  Wire.write(masiv[1]);                 // Отправка байта
  Wire.endTransmission();               // Прекратить передачу
}

void scan_holls(){  //Фукция для мониторинга состояния датчиков холла
  state_ = digitalRead(holl_1);     // Считать текущее состояние holl_1
  // Если предыдущее и текущее состояние holl_1 различаются, это означает, что произошел импульс.
  if (state_ != last_State){     
    // Если состояние входа holl_2 отличается от holl_1, это означает, что вращение по часовой стрелке.
    if (digitalRead(holl_2) != state_) {
      count++;
      //Если при вращении вперед выполнилось 2 импульса, то прибавить 1 виток
      if(count > 1){count = 0; V_V++;}
    }else{  count--;
      //Если при вращении назад выполнилось 2 импульса, то отнять 1 виток
      if(count < -1){ count = 0; V_V--;}
    }
  } last_State = state_;        // Обновляет предыдущее состояние входа holl_1 текущим состоянием
}


//Конец скетча




После загрузки кода можно собирать все как показано на одной из двух схем, которые представлены ниже.


Схема для использования любой платы Arduino, если вы не планируете в будущем добавлять механизм для укладки провода.

Схема ЧПУ станка для намотки трансформаторов на Arduino и Digispark Attiny85, без использования CNC Shield V3.

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

Схема ЧПУ станка для намотки трансформаторов на Arduino Uno и Digispark Attiny85, с использованием CNC Shield V3.

Добавление перемычки на обратной стороне CNC шилда.

Добавление перемычки на обратной стороне CNC шилда.

После сборки проверьте все, и если все верно, то можно включать питание.

При первом запуске станка, на дисплее появится анимация Start program, и запустится меню для настройки. О том, как выполнять настройку при первом запуске станка, смотрите видео которое ниже.

Подробное видео по второй части проекта, о том как собрать клавиатуру, как ее проверить, как подключить к станку, а также первый запуск и настройка станка для намотки трансформатора на Arduino и Digispark Attiny85.


ЧПУ станок для намотки трансформаторов на Arduino и Digispark Attyny85, 2 часть.