Stepper Arduino-DMX
Contrôle d'un moteur pas à pas bipolaire via DMX 512
Matériel
ARDUINO Nano (microcontroleur)
A4988 (driver Stepper)
MAX485 RS485 (in DMX XLR-3)
LED témoin signal DMX
interrupteur de butée (en option)
Schéma de câblage
TUTO ARDUINO MAX485 DMX SEND&RECEIVE https://www.g-rom.fr/2018/01/aquila-reloaded-chapitre-3/
Doc de la lib arduino DMXSerial http://www.mathertel.de/Arduino/DMXSerial.aspx
Code ARDUINO
v006-1stepper-noInterupt-DMX6CH
#include <DMXSerial.h>
#include <AccelStepper.h>
// A4988 GPIO config
#define dirPin_1 4 // D4
#define stepPin_1 5 // D5
#define MS1 14 // A0
#define MS2 15 // A1
#define MS3 16 // A2
#define motorInterfaceType 1
// control GPIO config
#define LED_SIGNAL 10 // D10 // LED allume si presence de signal dmx
#define INTER 3 // D3 OPTION interrupteur de fin/debut de course
// dmx ADRESS&CHART CONFIG
#define ADRESS_DMX 1 // et un jour on pourra la changer
//
#define COARSE 0 // ADRESS_DMX + CHANNEL - 1
#define FINE 1 // ADRESS_DMX + CHANNEL - 1
#define SPEED 2 // ADRESS_DMX + CHANNEL - 1
#define ACCELERATION 3 // ADRESS_DMX + CHANNEL - 1
#define RESOLUTION 4 // ADRESS_DMX + CHANNEL - 1
#define CONTROL 5 // ADRESS_DMX + CHANNEL - 1
// Create a new instance of the AccelStepper class:
AccelStepper stepper = {AccelStepper(motorInterfaceType, stepPin_1, dirPin_1)};
// variables
// control
int INTENSITY_SIGNAL = 15; // intensité d'alllumage de la LED_SIGNAL 0-255
// stepper
int Acceleration = 50; //faible valeur acceleration douce // POTENTIELLEMENT INUTILE
int MaxSpeed = 500; // POTENTIELLEMENT INUTILE
//dmx
long DATA[2][6] = { // DMX Chart
{0, 0, 0, 0, 0, 0}, // [0]actual frame
{0, 0, 0, 0, 0, 0} // [1]previous frame
};
byte MS_state;
bool MS[5][3] = {
{0, 0, 0}, // [0] FULL STEP
{1, 0, 0}, // [1] 1/2
{0, 1, 0}, // [2] 1/4
{1, 1, 0}, // [3] 1/8
{1, 1, 1} // [4] 1/16
};
byte CONTROL_state;
long CONTROL_rotation = 1;
void setup() {
//
pinMode(LED_SIGNAL, OUTPUT);
pinMode(MS1, OUTPUT);
pinMode(MS2, OUTPUT);
pinMode(MS3, OUTPUT);
pinMode(INTER, INPUT_PULLUP);
// dmx MODE SETUP
// DMXSerial.init(DMXController); // for DMX SEND
DMXSerial.init(DMXReceiver); // for DMX RECEIVE
// stepper setup VALEURS PAR DEFAULT
stepper.setMaxSpeed(MaxSpeed);
stepper.setAcceleration(Acceleration);
set_zero(); // ZERO
// RESET DE DEMARRAGE
reset();
// AND PLAY
} // end setup
void loop() {
// allum voyant LED_SIGNAL si DMX in present
if(DMXSerial.noDataSince() > 3000) { analogWrite(LED_SIGNAL, 0); }
else { analogWrite(LED_SIGNAL, INTENSITY_SIGNAL); }
// READ DMX
read_DMX();
// Run to target position with set speed and acceleration/deceleration:
stepper.run();
} // end loop
void reset(){ // tourne jusqu'a la fin de course ATTENTION AU SENS DE ROTATION
//A ECRIRE SI BESOIN
} // end reset
void set_zero(){ // tourne jusqu'a la fin de course ATTENTION AU SENS DE ROTATION
stepper.setCurrentPosition(0);
} // end set_zero
void read_DMX(){
// Lecture de la trame dmx
for (int i = 0; i < 6; i++) { DATA[0][i] = DMXSerial.read(ADRESS_DMX + i); }
// test conditionnels
if ( (DATA[0][COARSE] != DATA[1][COARSE]) || (DATA[0][FINE] != DATA[1][FINE]) ) { // POSITION COARSE or FINE
DATA[1][COARSE] = DATA[0][COARSE]; //
DATA[1][FINE] = DATA[0][FINE]; //
stepper.moveTo( ( (DATA[0][COARSE] * 256) + DATA[0][FINE]) * CONTROL_rotation);
}
if ( (DATA[0][SPEED] != DATA[1][SPEED]) ) {
DATA[1][SPEED] = DATA[0][SPEED]; //
stepper.setMaxSpeed(DATA[0][SPEED] * 5);
}
if ( (DATA[0][ACCELERATION] != DATA[1][ACCELERATION]) ) {
DATA[1][ACCELERATION] = DATA[0][ACCELERATION]; //
stepper.setAcceleration(DATA[0][ACCELERATION] * 5);
}
if ( (DATA[0][RESOLUTION] != DATA[1][RESOLUTION]) ) {
DATA[1][RESOLUTION] = DATA[0][RESOLUTION]; //
MS_state = DATA[0][RESOLUTION] / 52;
digitalWrite(MS1, MS[MS_state][0]); // LOW-HIGH
digitalWrite(MS2, MS[MS_state][1]);
digitalWrite(MS3, MS[MS_state][2]);
}
if ( (DATA[0][CONTROL] != DATA[1][CONTROL]) ) {
DATA[1][CONTROL] = DATA[0][CONTROL]; //
CONTROL_state = DATA[0][CONTROL] / 64;
if ( CONTROL_state == 0){CONTROL_rotation = 1;} // rotation anti horaire
if ( CONTROL_state == 1){CONTROL_rotation = -1;} // rotation horaire
if ( CONTROL_state == 2){set_zero();} // SET ZERO
if ( CONTROL_state == 3){reset();} // RESET
}
} // end read_DMX
Contrôle de trois moteur pas à pas bipolaire via DMX 512
Matériel
ARDUINO Nano (microcontroleur)
3*A4988 (driver Stepper)
MAX485 RS485 (in DMX XLR-3)
CNC Shield
Code ARDUINO
v008-3steppers-cncshield (16ch)
#include <DMXSerial.h>
#include <AccelStepper.h>
// A4988 GPIO config
#define dirPin_1 4 // D4 //Z
#define stepPin_1 7 // D7
#define dirPin_2 3 //Y
#define stepPin_2 6
#define dirPin_3 2 //X
#define stepPin_3 5
#define MS1 14 // A0
#define MS2 15 // A1
#define MS3 16 // A2
#define dmxselectorpin 12 // used by DMXSerial.h
#define motorInterfaceType 1
// control GPIO config
//#define LED_SIGNAL 10 // D10 // LED allume si presence de signal dmx // on peu aussi utiliser LED_BUILTIN
#define INTER 3 // D3 OPTION interrupteur de fin/debut de course
// dmx ADRESS&CHART CONFIG
#define ADRESS_DMX 2 // et un jour on pourra la changer
//
const int RESOLUTION = 0; // ADRESS_DMX + CHANNEL - 1
const int COARSE[] = {1, 6, 11}; // ADRESS_DMX + CHANNEL - 1
const int FINE[] = {2, 7, 12}; // ADRESS_DMX + CHANNEL - 1
const int SPEED[] = {3, 8, 13}; // ADRESS_DMX + CHANNEL - 1
const int ACCELERATION[] = {4, 9, 14}; // ADRESS_DMX + CHANNEL - 1
const int CONTROL[] = {5, 10, 15}; // ADRESS_DMX + CHANNEL - 1
// Create a new instance of the AccelStepper class:
AccelStepper stepper[3] = {AccelStepper(motorInterfaceType, stepPin_1, dirPin_1), AccelStepper(motorInterfaceType, stepPin_2, dirPin_2), AccelStepper(motorInterfaceType, stepPin_3, dirPin_3)};
// variables
// control
int INTENSITY_SIGNAL = 15; // intensité d'alllumage de la LED_SIGNAL 0-255
// stepper
int Acceleration = 100 ; //faible valeur acceleration douce // valeur par default
int MaxSpeed = 500; // valeur par default
//dmx
long DATA[2][16] = { // DMX Chart
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, // [0]actual frame
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // [1]previous frame
};
byte MS_state;
const bool MS[5][3] = {
{0, 0, 0}, // [0] FULL STEP
{1, 0, 0}, // [1] 1/2
{0, 1, 0}, // [2] 1/4
{1, 1, 0}, // [3] 1/8
{1, 1, 1} // [4] 1/16
};
byte CONTROL_state;
long CONTROL_rotation[3] = {1, 1, 1};
void setup() {
//
//pinMode(LED_SIGNAL, OUTPUT);
pinMode(MS1, OUTPUT);
pinMode(MS2, OUTPUT);
pinMode(MS3, OUTPUT);
pinMode(INTER, INPUT_PULLUP);
// dmx MODE SETUP
// DMXSerial.init(DMXController); // for DMX SEND
DMXSerial.init(DMXReceiver, dmxselectorpin); // for DMX RECEIVE
// stepper setup VALEURS PAR DEFAULT
for (int i = 0; i <= 2; i++) {stepper[i].setMaxSpeed(MaxSpeed); }
for (int i = 0; i <= 2; i++) {stepper[i].setAcceleration(Acceleration); }
set_zero(); // ZERO
// RESET DE DEMARRAGE
reset();
// AND PLAY
} // end setup
void loop() {
// allum voyant LED_SIGNAL si DMX in present
if(DMXSerial.noDataSince() > 3000) {
// analogWrite(LED_SIGNAL, 0);
digitalWrite(LED_BUILTIN, LOW);
}
else {
// analogWrite(LED_SIGNAL, INTENSITY_SIGNAL);
digitalWrite(LED_BUILTIN, HIGH);
}
// READ DMX
read_DMX();
// Run to target position with set speed and acceleration/deceleration:
for (int i = 0; i <= 2; i++) {stepper[i].run(); }
} // end loop
void reset(){ // tourne jusqu'a la fin de course ATTENTION AU SENS DE ROTATION
//A ECRIRE SI BESOIN
} // end reset
void set_zero(){ // set curerent position a 0
for (int i = 0; i <= 2; i++) {stepper[i].setCurrentPosition(0);}
} // end set_zero
void read_DMX(){
// Lecture de la trame dmx
for (int i = 0; i < 16; i++) { DATA[0][i] = DMXSerial.read(ADRESS_DMX + i); }
// test conditionnels
for (int i = 0; i < 3 ; i++){
if ( (DATA[0][COARSE[i]] != DATA[1][COARSE[i]]) || (DATA[0][FINE[i]] != DATA[1][FINE[i]]) ) { // POSITION COARSE or FINE
DATA[1][COARSE[i]] = DATA[0][COARSE[i]]; //
DATA[1][FINE[i]] = DATA[0][FINE[i]]; //
stepper[i].moveTo( ( (DATA[0][COARSE[i]] * 256) + DATA[0][FINE[i]]) * CONTROL_rotation[i]);
}
if ( (DATA[0][SPEED[i]] != DATA[1][SPEED[i]]) ) {
DATA[1][SPEED[i]] = DATA[0][SPEED[i]]; //
stepper[i].setMaxSpeed(DATA[0][SPEED[i]] * 5);
}
if ( (DATA[0][ACCELERATION[i]] != DATA[1][ACCELERATION[i]]) ) {
DATA[1][ACCELERATION[i]] = DATA[0][ACCELERATION[i]]; //
stepper[i].setAcceleration(DATA[0][ACCELERATION[i]] * 5);
}
if ( (DATA[0][CONTROL[i]] != DATA[1][CONTROL[i]]) ) {
DATA[1][CONTROL[i]] = DATA[0][CONTROL[i]]; //
CONTROL_state = DATA[0][CONTROL[i]] / 64;
if ( CONTROL_state == 0){CONTROL_rotation[i] = 1;} // rotation anti horaire
if ( CONTROL_state == 1){CONTROL_rotation[i] = -1;} // rotation horaire
if ( CONTROL_state == 2){set_zero();} // SET ZERO
if ( CONTROL_state == 3){reset();} // RESET
}
}
if ( (DATA[0][RESOLUTION] != DATA[1][RESOLUTION]) ) {
DATA[1][RESOLUTION] = DATA[0][RESOLUTION]; //
MS_state = DATA[0][RESOLUTION] / 52;
digitalWrite(MS1, MS[MS_state][0]); // LOW-HIGH
digitalWrite(MS2, MS[MS_state][1]);
digitalWrite(MS3, MS[MS_state][2]);
}
} // end read_DMX
Liens divers