first commit

This commit is contained in:
Clément SAILLANT
2023-04-17 17:12:03 +02:00
commit 40caa8f5da
16 changed files with 858 additions and 0 deletions
Vendored
BIN
View File
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
+10
View File
@@ -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"
]
}
+3
View File
@@ -0,0 +1,3 @@
{
"idf.flashType": "JTAG"
}
+39
View File
@@ -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
View File
@@ -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
+38
View File
@@ -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
+32
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
+15
View File
@@ -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
View File
@@ -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
}
+8
View File
@@ -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
View File
@@ -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
View File
@@ -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