Здравствуйте!
Этот мини проект является частью большого проекта, по созданию
ЧПУ станка для намотки трансформаторов
, но он также сгодится за основу, и для других ваших или моих проектов, где требуется плавный пуск и остановка биполярных шаговых двигателей.
Уникальность этого проекта в том, что благодаря связи платы Arduino с платой Digispark по шине I2C, всего по двум проводам, одной платой Arduino можно выполнять управление до 125 шаговых двигателей.
На фото которое ниже показано подключение двух шаговых двигателей к плате Arduino Nano. В принципе это могут быть и другие платы, например: Arduino Uno, Arduino Mega, Arduino Pro Mini, Arduino Pro Micro, да практически любая плата из линейки Arduino.
В этом проекте плата Arduino является мастером, то есть главным устройством в шине I2C, поэтому пример кода который ниже следует загрузить в нее! Данный код позволяет управлять двумя униполярными шаговыми двигателями по I2C адресам 7 и 8.
//Начало скетча
#include <Wire.h>
void send_to_I2C(int int_x, int ADDR_to_Slave);
byte masiv[2];
void setup() {
delay(6000);
Wire.begin(1); // i2c адрес платы Arduino будет #1
}
void loop() {
send_to_I2C(119, 8); //Mitsumi установка значения ускорения
send_to_I2C(100, 8); //Mitsumi разгон до 100%
send_to_I2C(100, 7); //Nema17 разгон до 100%
delay(15000);
send_to_I2C(0, 8); //Mitsumi полная остановка
send_to_I2C(30, 7); //Nema17 снижение скорости до 30%
delay(15000);
send_to_I2C(110, 8); //Mitsumi установка значения ускорения
send_to_I2C(103, 8); //Mitsumi изменение направления вращения
send_to_I2C(100, 8); //Mitsumi разгон до 100%
delay(15000);
send_to_I2C(101, 8); //Mitsumi мгновенная остановка
send_to_I2C(102, 8); //Mitsumi изменение направления вращения
delay(5000);
}//void loop()
void send_to_I2C(int int_x, int ADDR_to_Slave){
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(); // Прекратить передачу
}
//Конец скетча
//Начало скетча
#include <Wire.h>
void send_to_I2C(int int_x, int ADDR_to_Slave);
byte masiv[2];
void setup() {
delay(6000);
Wire.begin(1); // i2c адрес платы Arduino будет #1
}
void loop() {
send_to_I2C(100, 0); //разгон до 100% всех шаговых двигателей
delay(5000);
send_to_I2C(0, 0); //полная остановка всех шаговых двигателей
delay(5000);
}//void loop()
void send_to_I2C(int int_x, int ADDR_to_Slave){
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(); // Прекратить передачу
}
//Конец скетча
Так как для платы Arduino был задан I2C адрес 1, и для отправки команд используются адреса 7 и 8, то для плат Digispark следует указать также адреса 7 и 8.
Информацию о том как прошить плату Digispark по этой ссылке”Как прошить Digispark”
//Начало скетча
#include <USIWire.h>
const int SLAVE_ADDR = 0x8; // i2c адрес этого устройства
const int STEP = 1; //Контакт STEP подключается к контакту 1
const int DIR = 3; //Контакт DIR подключается к контакту 3
int z = 35; //Ускорение по умолчанию 35 миллисекунд
//Ускорение, задается командами от 110 до 120
//Команды 110 111 112 113 114 115 116 117 118 119 120
int z_[] = {1, 5, 10, 15, 25, 35, 45, 60, 75, 95, 120};
//100 скоростей 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 24 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
int speed_[] = {0,30000,15000,10000,7500,6000,5000,4286,3751,3335,3002,2729,2501,2308,2143,2000,1875,1764,1666,1578,1499,1427,1362,1305,1250,1200,1153,1104,1064,1027,991,956,922,889,857,826,796,766,737,708,680,652,625,598,572,547,523,500,478,457,437,418,400,383,366,350,335,321,308,296,285,275,266,258,251,245,240,235,230,225,220,215,210,205,200,195,190,185,180,175,170,165,160,155,150,145,140,135,130,125,120,115,110,105,100,95,90,85,70,75,60};
int i = 0, i2 = 0, x = 0, index, x_speed;
boolean flag = 1, State = LOW;
long timing = 0, timing1 = 0;
void read_I2C(int how_many);
void setup()
{
Wire.begin(SLAVE_ADDR);
Wire.onReceive(read_I2C);
pinMode(STEP, OUTPUT);
pinMode(DIR, OUTPUT); digitalWrite(DIR, LOW);
}
void loop()
{
if(x >= 0 && x <= 100){x_speed = x;}
if(x == 101){i2 = 0;} //Резкая остановка шагового двигателя
if(x == 102){digitalWrite(DIR, LOW);} //Задать направление вращения влево
if(x == 103){digitalWrite(DIR, HIGH);} //Задать направление вращения вправо
if(x >= 110 && x <=120){index = x - 110; z = z_[index];}//Задать ускорение
//Следующие 5 сток выполняют ускорение, или замедление вращения шагового двигателя
if (millis() - timing1 > z && i2 != x_speed && (x >= 0 && x <= 100)){
timing1 = millis();
if(i2 < x_speed){i2++; if(i2 > 100){i2 = 100;}} //Если i2 меньше x, то увеличить скорость
if(i2 > x_speed){i2--; if(i2 < 0){i2 = 0;}} //Если i2 больше x, то уменьшить скорость
}
//Здесь формируются импульсы для STEP сигнала
if (micros() - timing > speed_[i2] && (x >= 0 && x <= 100)){
timing = micros();
if(i2 != 0){
if (State == LOW) { //Изменить состояние переменной State
State = HIGH;
} else { State = LOW;
}
/*Задать соответствующее состояние на выходе для контакта STEP
согласно переменной State*/
digitalWrite(STEP, State);
}
}
}
void read_I2C(int how_many) {
int i=0;
while (Wire.available()){
byte c = Wire.read(); // Получить байт как символ, и поместить в переменную c
if (i==0) x = ((c & 0xff) << 8);
else x = x | c; i++;// Объединить полученные байты
}
}
//Конец скетча
После загрузки скетчей в платы можно собирать все по этой схеме.
Проверьте правильность подключения, и прозвоните контакты на отсутствие короткого замыкания, которое могло образоваться во время пайки платы. Если все верно, то можно подавать питание для проверки работоспособности прибора.
1-100 | Команды для вращения |
0 | Команда для плавной остановки |
101 | Команда для резкой остановки |
102 | Команда задать вращение вправо |
103 | Команда задать вращение влево |
110-120 | Команды для выбора ускорения |