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)

DMX CHART

DMX-Arduino-1Stepper_CHART

Schéma de câblage

shema-1stepper.pdf

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

DMX-Arduino-3Stepper_CHART

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