first commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"idf.flashType": "JTAG"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
@@ -0,0 +1,38 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:esp32doit-devkit-v1]
|
||||
platform = espressif32
|
||||
board = esp32doit-devkit-v1
|
||||
framework = arduino
|
||||
upload_protocol = esp-prog
|
||||
monitor_speed = 115200
|
||||
build_flags = -DCORE_DEBUG_LEVEL=5
|
||||
lib_deps =
|
||||
https://github.com/someweisguy/esp_dmx
|
||||
https://github.com/madhephaestus/ESP32Encoder
|
||||
pkerspe/ESP-FlexyStepper @ ^1.4.3
|
||||
|
||||
|
||||
[env:esp32dev]
|
||||
platform = espressif32
|
||||
board = esp32doit-devkit-v1
|
||||
framework = arduino
|
||||
upload_protocol = esp-prog
|
||||
debug_tool = esp-prog
|
||||
monitor_speed = 115200
|
||||
monitor_filters = esp32_exception_decoder
|
||||
debug_init_break = tbreak setup
|
||||
build_type=debug
|
||||
lib_deps =
|
||||
https://github.com/someweisguy/esp_dmx
|
||||
https://github.com/madhephaestus/ESP32Encoder
|
||||
pkerspe/ESP-FlexyStepper @ ^1.4.3
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/// ********************** PIN ASSIGNEMENTS **********************
|
||||
// DMX
|
||||
const int tx_pin = 17; // define the IO pin the DMX TX pin is connected to
|
||||
const int rx_pin = 16; // define the IO pin the DMX RX pin is connected to
|
||||
const int rts_pin = 4; // define the IO pin the DMX RTS pin is connected to
|
||||
|
||||
// capteur BCD pour adressage DMX
|
||||
#define q1 21 // define the IO pin for the thumbwheel '1' is connected to
|
||||
#define q2 19 // define the IO pin for the thumbwheel '2' is connected to
|
||||
#define q4 18 // define the IO pin for the thumbwheel '4' is connected to
|
||||
#define q8 5 // define the IO pin for the thumbwheel '8' is connected to
|
||||
|
||||
// driver moteur
|
||||
const int MOTOR_ENABLE_PIN = 27; // define the IO pin the motor enable pin is connected to
|
||||
const int MOTOR_STEP_PIN = 26; // define the IO pin the motor step pin is connected to
|
||||
const int MOTOR_DIRECTION_PIN = 25; // define the IO pin the motor direction pin is connected to
|
||||
#ifndef dev_mode
|
||||
const int EMERGENCY_STOP_PIN = 13; // define the IO pin the emergency stop switch is connected to
|
||||
#endif
|
||||
const int HOME_SWITCH_PIN = 35; // define the IO pin where the home switches are connected to (switches in series in normally closed setup against ground)
|
||||
const int LIMIT_SWITCH_PIN = 34; // define the IO pin where the limit switches are connected to (switches in series in normally closed setup against ground)
|
||||
|
||||
// encoder moteur pas à pas
|
||||
#define EB_plus 22 // define the IO pin for the encoder B is connected to
|
||||
#define EA_plus 23 // define the IO pin for the encoder A is connected to
|
||||
|
||||
// potentiomètre pour le réglage des fins de course
|
||||
#define home_set_pot 36 // define the IO pin for the home set potentiometer is connected to
|
||||
#define limit_set_pot 39 // define the IO pin for the limit set potentiometer is connected to
|
||||
#define divider_pot 100 // define the divider potentiometer value
|
||||
|
||||
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
#define nb_dmx_channel 2 // nombre de canaux DMX utilisés
|
||||
#define pos_array 1 // position de la position dans le tableau DMX_data
|
||||
#define speed_array 2 // position de la vitesse dans le tableau DMX_data
|
||||
int DMX_start_channel; // numéro de la première adresse DMX
|
||||
int pos_channel; // numéro de l'adresse DMX de la position
|
||||
int speed_channel; // numéro de l'adresse DMX de la vitesse
|
||||
const dmx_port_t dmx_num = DMX_NUM_2; // numéro du port DMX
|
||||
byte data[DMX_PACKET_SIZE]; // tableau de données DMX
|
||||
bool dmxIsConnected = false; // état de la connexion DMX
|
||||
unsigned long lastUpdate = millis(); // temps de la dernière mise à jour des données DMX
|
||||
uint8_t DMX_data[nb_dmx_channel + 1]; // tableau de données DMX
|
||||
uint8_t DMX_data_old[nb_dmx_channel + 1]; // tableau de données DMX précédentes
|
||||
bool dataChanged[nb_dmx_channel + 1]; // tableau de drapeau pour donnée DMX ayant changées
|
||||
unsigned long last_connected_Time = 0; // temps de la dernière connexion DMX
|
||||
unsigned long last_disconnected_Time = 0; // temps de la dernière déconnexion DMX
|
||||
#define DMX_Connected_Time 1000 // temps en ms entre chaque vérification de la connexion DMX
|
||||
#define DMX_Read_Time 500 // temps en ms entre chaque mise à jour des données DMX
|
||||
#define dmx_debounce_try 0 // nombre de boucle pour le debounce DMX afin d'éviter les valeurs de 0 ou 255 erronées
|
||||
int dmx_count[nb_dmx_channel + 1]; // compteur de boucle pour le debounce DMX afin d'éviter les valeurs de 0 ou 255 erronées
|
||||
|
||||
// fonction
|
||||
int readSwitch(); // fonction pour lire le codeur d'adresse DMX
|
||||
void reset_dmx_counter(); // fonction pour réinitialiser le compteur de boucle pour le debounce DMX afin d'éviter les valeurs de 0 ou 255 erronées
|
||||
void receiveDMX(); // fonction pour recevoir les données DMX
|
||||
|
||||
int readSwitch()
|
||||
{
|
||||
int total = 0;
|
||||
if (digitalRead(q1) == HIGH)
|
||||
{
|
||||
total += 1;
|
||||
}
|
||||
if (digitalRead(q2) == HIGH)
|
||||
{
|
||||
total += 2;
|
||||
}
|
||||
if (digitalRead(q4) == HIGH)
|
||||
{
|
||||
total += 4;
|
||||
}
|
||||
if (digitalRead(q8) == HIGH)
|
||||
{
|
||||
total += 8;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void reset_dmx_counter()
|
||||
{
|
||||
for (int i = 0; i < nb_dmx_channel + 1; i++)
|
||||
{
|
||||
dmx_count[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void receiveDMX()
|
||||
{
|
||||
// set channel
|
||||
// #ifndef dev_mode
|
||||
// DMX_start_channel = readSwitch();
|
||||
// #else
|
||||
DMX_start_channel = 1;
|
||||
pos_channel = DMX_start_channel;
|
||||
speed_channel = DMX_start_channel + 1;
|
||||
// #endif
|
||||
|
||||
dmx_packet_t packet;
|
||||
if (dmx_receive(dmx_num, &packet, DMX_TIMEOUT_TICK))
|
||||
{
|
||||
|
||||
if (!packet.err)
|
||||
{
|
||||
if (!dmxIsConnected)
|
||||
{
|
||||
Serial.println("DMX is connected!");
|
||||
last_connected_Time = millis();
|
||||
dmxIsConnected = true;
|
||||
}
|
||||
dmx_read(dmx_num, data, packet.size);
|
||||
// mise à jour des données DMX si elles ont changé et si le temps écoulé depuis la dernière mise à jour est supérieur à DMX_Read_Time
|
||||
if (millis() - lastUpdate > DMX_Read_Time)
|
||||
{
|
||||
lastUpdate = millis(); // réinitialisation du temps de la dernière mise à jour des données DMX
|
||||
last_connected_Time = millis(); // réinitialisation du temps de la dernière connexion DMX
|
||||
// mise à jour de la position
|
||||
if (DMX_data[pos_array] != data[pos_channel])
|
||||
{
|
||||
if (DMX_data[pos_array] == 0 || DMX_data[pos_array] == 255)
|
||||
{
|
||||
dmx_count[pos_array]++;
|
||||
if (dmx_count[pos_array] > dmx_debounce_try)
|
||||
{
|
||||
DMX_data[pos_array] = data[pos_channel];
|
||||
reset_dmx_counter();
|
||||
(dataChanged[pos_array]) = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DMX_data[pos_array] = data[pos_channel];
|
||||
reset_dmx_counter();
|
||||
(dataChanged[pos_array]) = true;
|
||||
}
|
||||
}
|
||||
|
||||
// mise à jour de la vitesse
|
||||
if (DMX_data[speed_array] != data[speed_channel])
|
||||
{
|
||||
if (DMX_data[speed_array] == 0 || DMX_data[speed_array] == 255)
|
||||
{
|
||||
dmx_count[speed_array]++;
|
||||
if (dmx_count[speed_array] > dmx_debounce_try)
|
||||
{
|
||||
DMX_data[speed_array] = data[speed_channel];
|
||||
reset_dmx_counter();
|
||||
(dataChanged[speed_array]) = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DMX_data[speed_array] = data[speed_channel];
|
||||
reset_dmx_counter();
|
||||
(dataChanged[speed_array]) = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reset_dmx_counter();
|
||||
Serial.println("A DMX error occurred.");
|
||||
}
|
||||
}
|
||||
else if (dmxIsConnected)
|
||||
{
|
||||
reset_dmx_counter();
|
||||
// Serial.println("DMX was disconnected."); // affichage de la déconnexion DMX
|
||||
if (millis() - last_connected_Time > DMX_Connected_Time)
|
||||
{
|
||||
dmxIsConnected = false;
|
||||
last_disconnected_Time = millis(); // réinitialisation du temps de la dernière déconnexion DMX
|
||||
Serial.println("DMX was halted."); // affichage de la déconnexion DMX
|
||||
// emergencyStop = true; // arrêt du moteur en cas de déconnexion DMX
|
||||
// emercency_stop_timer = millis(); // réinitialisation du timer d'arrêt d'urgence
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
|
||||
// ********************** variables for software debouncing of the limit switches **********************
|
||||
#define switch_active 1 // active low switch configuration (NO connection with internal pull up) or HIGH for active high switch configuration (NC connection with internal pull up)
|
||||
|
||||
volatile unsigned long lastDebounceTime = 0; // the last time the limit switch input pin was toggled
|
||||
volatile unsigned long debounceDelay = 250; // the minimum delay in milliseconds to check for bouncing of the switch. Increase this slighlty if you switches tend to bounce a lot
|
||||
bool buttonStateChangeDetected = false; // flag to indicate that the button state has changed
|
||||
volatile byte limitSwitchState = !switch_active; // the current reading from the limit switch input pin
|
||||
byte ConfirmedLimitSwitchState = !switch_active; // the last confirmed reading from the limit switch input pin
|
||||
volatile byte homeSwitchState = !switch_active; // the current reading from the home switch input pin
|
||||
byte ConfirmedHomeSwitchState = !switch_active; // the last confirmed reading from the home switch input pin
|
||||
|
||||
volatile int home_steps = 15; // nombre de pas pour bien positionner le moteur à la position de départ
|
||||
volatile int limit_steps = 105; // nombre de pas pour bien positionner le moteur à la position de fin
|
||||
|
||||
void homeReachedCallback()
|
||||
{
|
||||
Serial.println("Home reached");
|
||||
}
|
||||
|
||||
void limitReachedCallback()
|
||||
{
|
||||
Serial.println("Limit reached");
|
||||
}
|
||||
|
||||
void IRAM_ATTR limitSwitchHandler() // interrupt handler for the limit switch
|
||||
{
|
||||
lastDebounceTime = millis();
|
||||
limitSwitchState = digitalRead(LIMIT_SWITCH_PIN);
|
||||
}
|
||||
|
||||
void IRAM_ATTR homeSwitchHandler() // interrupt handler for the home switch
|
||||
{
|
||||
lastDebounceTime = millis();
|
||||
homeSwitchState = digitalRead(HOME_SWITCH_PIN);
|
||||
}
|
||||
|
||||
void limit_sw_check() // fonction pour la sécurité si une limite est détectée par le bouton poussoir
|
||||
{
|
||||
|
||||
if (limitSwitchState != ConfirmedLimitSwitchState && (millis() - lastDebounceTime) > debounceDelay)
|
||||
{
|
||||
ConfirmedLimitSwitchState = limitSwitchState;
|
||||
Serial.printf("Limit switch change detected. New state is %i\n", limitSwitchState);
|
||||
Serial.printf("Limit setting is %i\n", limit_steps);
|
||||
buttonStateChangeDetected = true;
|
||||
}
|
||||
}
|
||||
|
||||
void home_sw_check() // fonction pour la sécurité si une limite est détectée par le bouton poussoir
|
||||
{
|
||||
if (homeSwitchState != ConfirmedHomeSwitchState && (millis() - lastDebounceTime) > debounceDelay)
|
||||
{
|
||||
ConfirmedHomeSwitchState = homeSwitchState;
|
||||
Serial.printf("Home switch change detected. New state is %i\n", homeSwitchState);
|
||||
Serial.printf("Home setting is %i\n", home_steps);
|
||||
buttonStateChangeDetected = true;
|
||||
}
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
|
||||
/*
|
||||
|
||||
TESTER AVEC LIB : https://github.com/Valar-Systems/FastAccelStepper-ESP32 ???
|
||||
|
||||
controle de moteur pas à pas selon commande DMX
|
||||
|
||||
code par Clément SAILLANT pour Hémisphère - 2023
|
||||
c.saillant@gmail.com
|
||||
0625334420
|
||||
|
||||
Un canal DMX est utilisé pour la commande de la position du moteur
|
||||
Un autre canal DMX est utilisé pour la commande de la vitesse du moteur
|
||||
Une fonction affine est utilisée pour convertir la valeur DMX en position ou vitesse
|
||||
La position et la vitesse sont stockées dans des variables globales
|
||||
Une fonction est utilisée pour la sécurité si un obstacle est détecté par la perte de pas du moteur
|
||||
|
||||
moteur : 34HS59-6004D-E1000
|
||||
Angle de pas: 1.8 deg
|
||||
Résolution de l'encodeur: 1000PPR(4000CPR)
|
||||
https://www.omc-stepperonline.com/download/34HS59-6004D-E1000_Torque_Curve.pdf
|
||||
https://www.omc-stepperonline.com/download/34HS59-6004D-E1000.pdf
|
||||
|
||||
Controleur CL86T V4.0
|
||||
https://www.omc-stepperonline.com/index.php?route=product/product/get_file&file=389/CL86T%20(V4.0).pdf
|
||||
|
||||
SW1 0
|
||||
SW2 0
|
||||
SW3 1
|
||||
SW4 1
|
||||
|
||||
SW5 On CCW
|
||||
SW6 Off Close loop
|
||||
SW7 Off Pul/Dir
|
||||
SW8 Off Brk
|
||||
*/
|
||||
|
||||
// #define dev_mode // mode developpeur
|
||||
|
||||
#include "PIN_mapping.h" // fichier contenant les variables globales et le mapping des pins
|
||||
bool emergencyStop = false; // variable pour stocker l'état de l'arrêt d'urgence
|
||||
|
||||
#include <Arduino.h>
|
||||
// #include <Arduino_FreeRTOS.h>
|
||||
// #include "esp_attr.h"
|
||||
|
||||
#include <esp_dmx.h>
|
||||
// #include "esp_task_wdt.h" // librairie pour le watchdog
|
||||
#include <ESP_FlexyStepper.h> // librairie pour le controle des moteurs pas à pas
|
||||
#include <ESP32Encoder.h> // librairie pour le controle des encodeurs
|
||||
|
||||
ESP_FlexyStepper stepper; // création de l'ojet motor
|
||||
ESP32Encoder encoder; // création de l'objet encoder
|
||||
|
||||
#include "limit.h" // fichier contenant les fonctions de limites
|
||||
#include "dmx_data.h" // fichier contenant les fonctions dmx
|
||||
#include "moving.h" // fichier contenant les fonctions de mouvement
|
||||
#include "security.h" // fichier contenant les fonctions de sécurité type emergency stop
|
||||
|
||||
void setup()
|
||||
{
|
||||
delay(1000);
|
||||
Serial.begin(115200);
|
||||
Serial.println("started");
|
||||
|
||||
// configuration DMX
|
||||
dmx_set_pin(dmx_num, tx_pin, rx_pin, rts_pin);
|
||||
dmx_driver_install(dmx_num, DMX_DEFAULT_INTR_FLAGS);
|
||||
|
||||
// configuration encoder pour suivre la position du moteur et la perte de pas
|
||||
encoder.attachHalfQuad(EB_plus, EA_plus);
|
||||
encoder.setCount(0);
|
||||
|
||||
// configuration ENABLE motor
|
||||
pinMode(MOTOR_ENABLE_PIN, OUTPUT);
|
||||
// configuration BCD Coder
|
||||
pinMode(q1, INPUT); // thumbwheel '1'
|
||||
pinMode(q2, INPUT); // thumbwheel '2'
|
||||
pinMode(q4, INPUT); // thumbwheel '4'
|
||||
pinMode(q8, INPUT); // thumbwheel '8'
|
||||
|
||||
/*
|
||||
#ifndef dev_mode
|
||||
// attach an interrupt to the IO pin of the ermegency stop switch and specify the handler function
|
||||
pinMode(EMERGENCY_STOP_PIN, INPUT_PULLUP);
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(EMERGENCY_STOP_PIN), emergencySwitchHandler, RISING);
|
||||
#endif
|
||||
*/
|
||||
pinMode(MOTOR_ENABLE_PIN, OUTPUT);
|
||||
pinMode(LIMIT_SWITCH_PIN, INPUT);
|
||||
pinMode(HOME_SWITCH_PIN, INPUT);
|
||||
|
||||
|
||||
// ???????????????? Error : attachInterrupt with ADC enabled :'( ????????????????
|
||||
|
||||
// attach an interrupt to the IO pin of the home switch and specify the handler function
|
||||
attachInterrupt(digitalPinToInterrupt(HOME_SWITCH_PIN), homeSwitchHandler, CHANGE);
|
||||
stepper.registerHomeReachedCallback(homeReachedCallback);
|
||||
|
||||
// attach an interrupt to the IO pin of the limit switch and specify the handler function
|
||||
attachInterrupt(digitalPinToInterrupt(LIMIT_SWITCH_PIN), limitSwitchHandler, CHANGE);
|
||||
stepper.registerLimitReachedCallback(limitReachedCallback);
|
||||
|
||||
// connect and configure the stepper motor to its IO pins
|
||||
stepper.connectToPins(MOTOR_STEP_PIN, MOTOR_DIRECTION_PIN);
|
||||
// set the speed and acceleration rates for the stepper motor
|
||||
stepper.setSpeedInStepsPerSecond(SPEED_IN_STEPS_PER_SECOND);
|
||||
stepper.setAccelerationInStepsPerSecondPerSecond(ACCELERATION_IN_STEPS_PER_SECOND);
|
||||
stepper.setDecelerationInStepsPerSecondPerSecond(DECELERATION_IN_STEPS_PER_SECOND);
|
||||
stepper.setStepsPerRevolution(STEP_PER_REV);
|
||||
stepper.registerTargetPositionReachedCallback(targetPositionReachedCallback);
|
||||
|
||||
// start the stepper instance as a service in the "background" as a separate task
|
||||
stepper.startAsService(); // at core 1
|
||||
|
||||
init_range(); // set home and limit position of the motor
|
||||
|
||||
Serial.print("number of tasks is ");
|
||||
Serial.println(uxTaskGetNumberOfTasks());
|
||||
Serial.print("home position is ");
|
||||
Serial.println(min_steps);
|
||||
Serial.print("limit position is ");
|
||||
Serial.println(max_steps);
|
||||
Serial.println("----------------------------------------");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
receiveDMX(); // reception des données DMX
|
||||
|
||||
// mise à jour de la vitesse du moteur si la valeur DMX a changé
|
||||
if (dataChanged[speed_array])
|
||||
{
|
||||
dataChanged[speed_array] = false;
|
||||
Serial.printf("dmx speed receive => %ld\n", DMX_data[speed_array]);
|
||||
speed_map(); // fonction pour convertir la valeur DMX en vitesse/acceleration/deceleration
|
||||
}
|
||||
|
||||
// mise à jour de la position du moteur si la valeur DMX a changée
|
||||
if (dataChanged[pos_channel] == true && emergencyStop == false)
|
||||
{
|
||||
// stepper.setTargetPositionToStop();
|
||||
dataChanged[pos_channel] = false;
|
||||
int pos_in_step = map(DMX_data[pos_array], 0, 255, min_steps, max_steps);
|
||||
|
||||
// adaptation de la vitesse d'acceleration en fonction de la distance à parcourir
|
||||
if (abs(DMX_data_old[pos_array] - DMX_data[pos_array]) < 25)
|
||||
{
|
||||
speed_in_accel = 50;
|
||||
}
|
||||
else
|
||||
{
|
||||
speed_in_accel = 500;
|
||||
}
|
||||
stepper.setAccelerationInStepsPerSecondPerSecond(speed_in_accel);
|
||||
stepper.setTargetPositionInSteps(pos_in_step);
|
||||
Serial.printf("dmx pos to step => %ld\n", pos_in_step);
|
||||
DMX_data_old[pos_array] = DMX_data[pos_array];
|
||||
}
|
||||
|
||||
// motor_follower(emergency_stop_loss_step); // fonction pour suivre la position du moteur et la perte de pas
|
||||
emergency_check(); // fonction pour la sécurité si un obstacle est détecté par la perte de pas du moteur
|
||||
limit_check(); // fonction pour la sécurité si un obstacle est détecté par le bouton poussoir
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <Arduino.h>
|
||||
const int MOTOR_ENABLE_PIN = 27;
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(MOTOR_ENABLE_PIN, OUTPUT);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
digitalWrite(MOTOR_ENABLE_PIN, HIGH); // disable and free motor
|
||||
delay(500);
|
||||
digitalWrite(MOTOR_ENABLE_PIN, LOW); // enable motor
|
||||
delay(500);
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
#define STEP_PER_REV 3200 // nombre de pas par tour du moteur
|
||||
|
||||
const int MIN_SPEED[3] = {0, 0, 0}; // vitesse, acceleration et deceleration minimum du moteur
|
||||
const int MAX_SPEED[3] = {1000, 5000, 5000}; // vitesse, acceleration et deceleration maximum du moteur
|
||||
const int SPEED_IN_STEPS_PER_SECOND = 500; // vitesse de déplacement du moteur
|
||||
const int ACCELERATION_IN_STEPS_PER_SECOND = 500; // accélération du moteur
|
||||
const int DECELERATION_IN_STEPS_PER_SECOND = 100; // décélération du moteur
|
||||
int min_steps = 0; // position de départ du moteur
|
||||
int max_steps = 1600; // position de fin du moteur
|
||||
|
||||
volatile int speed_in_accel = 100;
|
||||
volatile int speed_in_decel = 100;
|
||||
|
||||
// fonction
|
||||
void targetPositionReachedCallback(long position); // callback function as the target position is reached
|
||||
// void limitSwitchHandler(); // interrupt handler for the limit switch
|
||||
// void homeSwitchHandler(); // interrupt handler for the home switch
|
||||
void speed_map(); // fonction de mapping de la vitesse du moteur avec accélération et décélération
|
||||
void pos_map(); // fonction de mapping de la position du moteur
|
||||
void set_min(); // fonction pour position minimum de la plage de déplacement du moteur
|
||||
void set_max(); // fonction pour position maximum de la plage de déplacement du moteurF
|
||||
void init_range(); // fonction d'initialisation de la plage de déplacement du moteur
|
||||
|
||||
void targetPositionReachedCallback(long position) // callback function as the target position is reached
|
||||
{
|
||||
Serial.printf("Stepper reached target position %ld\n", position);
|
||||
Serial.printf("Encoder count is %ld\n", encoder.getCount());
|
||||
}
|
||||
|
||||
// fonction de mapping de la vitesse du moteur avec accélération et décélération
|
||||
void speed_map() // fonction de mapping de la vitesse du moteur avec accélération et décélération
|
||||
{
|
||||
int speed_in_step = map(DMX_data[speed_array], 0, 255, MIN_SPEED[0], MAX_SPEED[0]);
|
||||
// int speed_in_accel = map(DMX_data[speed_array], 0, 255, MIN_SPEED[1], MAX_SPEED[1]);
|
||||
// int speed_in_decel = map(DMX_data[speed_array], 0, 255, MIN_SPEED[2], MAX_SPEED[2]);
|
||||
stepper.setSpeedInStepsPerSecond(speed_in_step);
|
||||
// set the speed and acceleration rates for the stepper motor
|
||||
stepper.setAccelerationInStepsPerSecondPerSecond(speed_in_accel);
|
||||
stepper.setDecelerationInStepsPerSecondPerSecond(speed_in_decel);
|
||||
}
|
||||
|
||||
void pos_map() // fonction de mapping de la position du moteur
|
||||
{
|
||||
int pos_in_step = map(DMX_data[pos_array], 0, 255, min_steps, max_steps);
|
||||
stepper.setTargetPositionInSteps(pos_in_step);
|
||||
}
|
||||
|
||||
void set_min() // fonction pour position minimum de la plage de déplacement du moteur
|
||||
{
|
||||
min_steps = stepper.getCurrentPositionInSteps() - home_steps;
|
||||
encoder.setCount(0); // remise à zéro de l'encodeur
|
||||
}
|
||||
|
||||
void set_max() // fonction pour position maximum de la plage de déplacement du moteur
|
||||
{
|
||||
max_steps = stepper.getCurrentPositionInSteps() + limit_steps;
|
||||
}
|
||||
|
||||
void init_range() // fonction d'initialisation de la plage de déplacement du moteur
|
||||
{
|
||||
#ifndef dev_mode
|
||||
int direction = -1;
|
||||
bool limit_OK = false;
|
||||
int position_limit = 500;
|
||||
Serial.println("starting homing");
|
||||
// delay(2000);
|
||||
digitalWrite(MOTOR_ENABLE_PIN, LOW); // enable motor
|
||||
stepper.setDirectionToHome(direction);
|
||||
if (digitalRead(HOME_SWITCH_PIN) == switch_active) // si position est déjà à home
|
||||
{
|
||||
Serial.println("already in home position");
|
||||
stepper.setCurrentPositionAsHomeAndStop(); // set the current position as the home position and stop the stepper
|
||||
stepper.setTargetPositionInSteps(position_limit);
|
||||
delay(2000);
|
||||
}
|
||||
stepper.goToLimitAndSetAsHome(); // go to the limit switch and set the current position as the home position
|
||||
|
||||
while (!limit_OK)
|
||||
{
|
||||
home_sw_check();
|
||||
if (ConfirmedHomeSwitchState == switch_active)
|
||||
{
|
||||
stepper.setLimitSwitchActive(stepper.LIMIT_SWITCH_BEGIN); // this will cause to stop any motion that is currently going on and block further movement in the same direction as long as the switch is active
|
||||
stepper.setTargetPositionToStop();
|
||||
limit_OK = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
stepper.clearLimitSwitchActive(); // clear the limit switch flag to allow movement in both directions again
|
||||
}
|
||||
}
|
||||
|
||||
stepper.setCurrentPositionAsHomeAndStop(); // set the current position as the home position and stop the stepper
|
||||
set_min();
|
||||
encoder.setCount(0); // remise à zéro de l'encodeur
|
||||
Serial.println("home OK");
|
||||
stepper.clearLimitSwitchActive(); // clear the limit switch flag to allow movement in both directions again
|
||||
limit_OK = false;
|
||||
position_limit = 0;
|
||||
Serial.println("waiting for limit switch");
|
||||
stepper.setTargetPositionInSteps(160);
|
||||
while (!limit_OK)
|
||||
{
|
||||
limit_sw_check();
|
||||
if (ConfirmedLimitSwitchState == switch_active)
|
||||
{
|
||||
stepper.setLimitSwitchActive(stepper.LIMIT_SWITCH_END); // this will cause to stop any motion that is currently going on and block further movement in the same direction as long as the switch is active
|
||||
stepper.setTargetPositionToStop();
|
||||
limit_OK = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
stepper.clearLimitSwitchActive(); // clear the limit switch flag to allow movement in both directions again
|
||||
if (stepper.getCurrentPositionInSteps() < 1350)
|
||||
{
|
||||
position_limit = stepper.getCurrentPositionInSteps() + 200;
|
||||
}
|
||||
else
|
||||
{
|
||||
position_limit = stepper.getCurrentPositionInSteps() + 5;
|
||||
}
|
||||
stepper.setTargetPositionInSteps(position_limit);
|
||||
}
|
||||
}
|
||||
Serial.println("limit init OK");
|
||||
stepper.setTargetPositionToStop();
|
||||
set_max();
|
||||
stepper.clearLimitSwitchActive(); // clear the limit switch flag to allow movement in both directions again
|
||||
stepper.setTargetPositionInSteps(max_steps / 2);
|
||||
delay(2000);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
https://github.com/arttupii/CLSMB Closed loop step motor controller
|
||||
|
||||
https://www.switchdoc.com/2018/04/esp32-tutorial-debouncing-a-button-press-using-interrupts/
|
||||
avec vtask pour plus d'efficacité
|
||||
|
||||
voir pour mieur gérer le homming avec les fonctions explicité dans la lib felxystepper
|
||||
|
||||
rajouter plus de délai à la lecture dmx pour mieux éviter les problème de chanement de valeurs trop rapide
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
|
||||
#define emergency_stop_bounce_time 1000 // time in ms to wait before disabling the motor in emergency when step as been lost
|
||||
#define emergency_release_time 2000 // time in ms to wait before releasing the emergency stop
|
||||
#define emergency_stop_loss_step 5 // number of step to wait before disabling the motor in emergency when step as been lost
|
||||
unsigned long emercency_stop_timer; // temps en ms depuis lequel le moteur est en arrêt d'urgence
|
||||
unsigned long lastStepTime; // variable pour stocker le temps de la dernière mise à jour des données encoder
|
||||
long old_count; // variable des précedentes données de l'encoder
|
||||
long newPosition; // variable des données de l'encoder
|
||||
|
||||
// fonction :
|
||||
void motor_follower(int loss_step); // fonction pour suivre la position du moteur et la perte de pas
|
||||
void emergency_check(); // fonction pour la sécurité si un obstacle est détecté par la perte de pas du moteur
|
||||
void limit_check(); // fonction pour la sécurité si une limite est détectée par le bouton poussoir
|
||||
|
||||
#ifndef dev_mode
|
||||
/*
|
||||
void IRAM_ATTR emergencySwitchHandler() // interrupt handler for the emergency stop switch
|
||||
{
|
||||
|
||||
// we do not realy need to debounce here, since we only want to trigger a stop, no matter what.
|
||||
// So even triggering mutliple times does not realy matter at the end
|
||||
if (digitalRead(EMERGENCY_STOP_PIN) == LOW) // Switch is configured in active low configuration
|
||||
{
|
||||
// the boolean true in the following command tells the stepper to hold the emergency stop until reaseEmergencyStop() is called explicitly.
|
||||
// If ommitted or "false" is given, the function call would only stop the current motion and then instanlty would allow for new motion commands to be accepted
|
||||
stepper.emergencyStop(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// release a previously enganed emergency stop when the emergency stop button is released
|
||||
stepper.releaseEmergencyStop();
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
void motor_follower(int loss_step) // fonction pour suivre la position du moteur et la perte de pas
|
||||
{
|
||||
// Quand le moteur est en mouvement, on vérifie si la position a changé de plus de 5 pas
|
||||
// mise à jour de la position de l'encodeur
|
||||
newPosition = encoder.getCount();
|
||||
if (stepper.getDirectionOfMotion() != 0)
|
||||
{
|
||||
// Serial.printf("new position is %ld\n", newPosition);
|
||||
if (newPosition > old_count || newPosition < old_count)
|
||||
{
|
||||
lastStepTime = millis();
|
||||
emergencyStop = false;
|
||||
}
|
||||
if (newPosition >= old_count + loss_step || newPosition <= old_count - loss_step)
|
||||
{
|
||||
// Serial.printf("new position => %ld\n", newPosition);
|
||||
// Serial.printf("old position => %ld\n", old_count);
|
||||
old_count = newPosition;
|
||||
}
|
||||
// dans le else : newPosition == old_count &&
|
||||
else if (millis() - lastStepTime > emergency_stop_bounce_time / (DMX_data[speed_array] + 1) && emergencyStop == false)
|
||||
{
|
||||
Serial.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!! emergency stop");
|
||||
stepper.setTargetPositionToStop();
|
||||
emercency_stop_timer = millis();
|
||||
emergencyStop = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void emergency_check() // fonction pour la sécurité si un obstacle est détecté par la perte de pas du moteur
|
||||
{
|
||||
if (emergencyStop)
|
||||
{
|
||||
if (millis() - emercency_stop_timer > emergency_release_time && emergencyStop == true)
|
||||
{
|
||||
digitalWrite(MOTOR_ENABLE_PIN, LOW); // enable motor
|
||||
Serial.println("======================> emergency stop released");
|
||||
emergencyStop = false;
|
||||
}
|
||||
else if (digitalRead(MOTOR_ENABLE_PIN) == LOW && emergencyStop == true)
|
||||
{
|
||||
Serial.println("======================> emergency stop engaged");
|
||||
digitalWrite(MOTOR_ENABLE_PIN, HIGH); // disable and free motor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void limit_check() // fonction pour la sécurité si une limite est détectée par le bouton poussoir
|
||||
{
|
||||
const int limit_step_lost = 5;
|
||||
limit_sw_check();
|
||||
home_sw_check();
|
||||
// active high switch configuration (NC connection with internal pull up)
|
||||
if (limitSwitchState == switch_active && buttonStateChangeDetected == true)
|
||||
{
|
||||
buttonStateChangeDetected = false;
|
||||
// limit_step = analogRead(limit_set_pot) / divider_pot;
|
||||
ConfirmedLimitSwitchState = limitSwitchState;
|
||||
Serial.printf("Limit switch change detected. New state is %i\n", limitSwitchState);
|
||||
Serial.printf("Limit setting is %i\n", limit_steps);
|
||||
// set_max();
|
||||
motor_follower(limit_step_lost);
|
||||
if (emergencyStop)
|
||||
{
|
||||
stepper.setLimitSwitchActive(stepper.LIMIT_SWITCH_END); // this will cause to stop any motion that is currently going on and block further movement in the same direction as long as the switch is agtive
|
||||
}
|
||||
else
|
||||
{
|
||||
stepper.setTargetPositionInSteps(max_steps + limit_steps);
|
||||
Serial.printf("go to Limit set : %i\n", max_steps + limit_steps);
|
||||
}
|
||||
}
|
||||
else if (buttonStateChangeDetected == true)
|
||||
{
|
||||
buttonStateChangeDetected = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
stepper.clearLimitSwitchActive(); // clear the limit switch flag to allow movement in both directions again
|
||||
}
|
||||
|
||||
if (homeSwitchState == switch_active && buttonStateChangeDetected == true)
|
||||
{
|
||||
buttonStateChangeDetected = false;
|
||||
// home_step = analogRead(home_set_pot) / divider_pot;
|
||||
ConfirmedHomeSwitchState = homeSwitchState;
|
||||
Serial.printf("Home switch change detected. New state is %i\n", homeSwitchState);
|
||||
Serial.printf("Home setting is %i\n", home_steps);
|
||||
stepper.setCurrentPositionAsHomeAndStop(); // set the current position as the home position and stop the stepper
|
||||
// set_min();
|
||||
motor_follower(limit_step_lost);
|
||||
if (emergencyStop)
|
||||
{
|
||||
stepper.setLimitSwitchActive(stepper.LIMIT_SWITCH_BEGIN); // this will cause to stop any motion that is currently going on and block further movement in the same direction as long as the switch is agtive
|
||||
}
|
||||
else
|
||||
{
|
||||
stepper.setTargetPositionInSteps(min_steps - home_steps);
|
||||
Serial.printf("go to Home set : %i\n", min_steps - home_steps);
|
||||
}
|
||||
}
|
||||
else if (buttonStateChangeDetected == true)
|
||||
{
|
||||
buttonStateChangeDetected = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
stepper.clearLimitSwitchActive(); // clear the limit switch flag to allow movement in both directions again
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||
Reference in New Issue
Block a user