update Code

This commit is contained in:
Clément SAILLANT
2023-09-11 19:13:12 +02:00
committed by GitHub
parent 8fedb379db
commit 9aa0727e7d
11 changed files with 877 additions and 0 deletions
+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
+30
View File
@@ -0,0 +1,30 @@
; 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:PCB-v01a]
platform = espressif32
board = featheresp32
; change microcontroller to ESP32M4
board_build.mcu = esp32
; change MCU frequency
board_build.f_cpu = 240000000L
framework = arduino
;upload_protocol = esp-prog
monitor_speed = 115200
monitor_filters = esp32_exception_decoder
; debug_tool = esp-prog
; 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 = 16; // define the IO pin the DMX TX pin is connected to
const int rx_pin = 17; // 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 1 // define the divider potentiometer value
+143
View File
@@ -0,0 +1,143 @@
#define nb_dmx_channel 2 // nombre de canaux DMX utilisés
#define pos_array 0 // position de la position dans le tableau DMX_data
#define speed_array 1 // 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 200 // 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() // fonction pour lire le codeur d'adresse DMX
{
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;
}
total = ((total + 1) * 2) - 1; // correction battarde de l'adresse DMX
return total;
}
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
{
for (int i = 0; i < nb_dmx_channel + 1; i++)
{
dmx_count[i] = 0;
}
}
void receiveDMX() // fonction pour recevoir les données DMX
{
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
}
}
}
+67
View File
@@ -0,0 +1,67 @@
// ********************** 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 = 100; // 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; // nombre de pas pour bien positionner le moteur à la position de départ
volatile int limit_steps; // nombre de pas pour bien positionner le moteur à la position de fin
void homeReachedCallback(); // callback function that will be called when the home position is reached
void limitReachedCallback(); // callback function that will be called when the limit position is reached
void IRAM_ATTR limitSwitchHandler(); // interrupt handler for the limit switch
void IRAM_ATTR homeSwitchHandler(); // interrupt handler for the home switch
void limit_sw_check(); // fonction pour la sécurité si une limite est détectée par le bouton poussoir
void home_sw_check(); // fonction pour la sécurité si une limite est détectée par le bouton poussoir
void homeReachedCallback() // callback function that will be called when the home position is reached
{
Serial.println("Home reached");
}
void limitReachedCallback() // callback function that will be called when the limit position is reached
{
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;
}
}
+169
View File
@@ -0,0 +1,169 @@
/*
controle de moteur pas à pas selon commande DMX
code par Clément SAILLANT pour Hémisphère - 2023
[email protected]
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
*/
#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 <esp_dmx.h>
#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");
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'
/*
// 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);
*/
// lecture des potentiomètres pour définir les offset de pas a ajouter aux positions home et limit
limit_steps = map((analogRead(limit_set_pot)), 4095, 0, min_offset, max_offset);
home_steps = map((analogRead(home_set_pot)), 4095, 0, min_offset, max_offset);
// 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(1); // core 1 sinon bug avec le dmx et déplacement aléatoire du moteur
init_range(); // set home and limit position of the motor
DMX_start_channel = readSwitch(); // lecture de la position du codeurs BCD pour définir le canal DMX de départ
// DMX_start_channel = 2; // pour test avec adresse fixe
pos_channel = DMX_start_channel;
speed_channel = DMX_start_channel + 1;
Serial.println("----------------------------------------");
Serial.printf("number of tasks is %i\n", uxTaskGetNumberOfTasks());
Serial.printf("home position is %i\n", min_steps);
Serial.printf("limit position is %i\n", max_steps);
Serial.printf("Limit setting is %i\n", limit_steps);
Serial.printf("Home setting is %i\n", home_steps);
Serial.printf("DMX start channel is %i\n", DMX_start_channel);
Serial.printf("DMX position channel is %i\n", pos_channel);
Serial.printf("DMX speed channel is %i\n", speed_channel);
Serial.println("----------------------------------------");
}
void loop()
{
receiveDMX(); // reception des données DMX
// mise à jour de la vitesse du moteur si la valeur DMX a changée
if (dataChanged[speed_array] == true)
{
dataChanged[speed_array] = false;
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_array] == true && emergencyStop == false && digitalRead(MOTOR_ENABLE_PIN) == LOW)
if (dataChanged[pos_array] == true)
{
// stepper.setTargetPositionToStop();
dataChanged[pos_array] = false;
pos_in_step = map(DMX_data[pos_array], 255, 0, min_steps, max_steps);
// pos_map(); // fonction pour convertir la valeur DMX en position
stepper.setTargetPositionInSteps(pos_in_step);
DMX_data_old[pos_array] = DMX_data[pos_array];
last_dmx_change_pos = millis();
Serial.printf("dmx pos to step => %ld\n", pos_in_step);
}
// gestion de la position du moteur si la valeur DMX n'a pas changée mais que le moteur n'est pas à la position demandée
if (millis() - last_dmx_change_pos > 1000)
{
int codeur_pos = map(encoder.getCount(), min_count, max_count, min_steps, max_steps);
if (pos_in_step <= min_steps && ConfirmedHomeSwitchState != switch_active && stepper.getDirectionOfMotion() == 0)
{
Serial.println("!!!!!!!!!!!!! home not reached");
Serial.printf("codeur pos => %i\n", codeur_pos);
// stepper.setTargetPositionInSteps(min_steps - codeur_pos); // home_steps
int step_add = nb_microstep * 2;
stepper.setTargetPositionRelativeInSteps(-step_add);
delay(100);
}
else if (pos_in_step >= max_steps && ConfirmedLimitSwitchState != switch_active && stepper.getDirectionOfMotion() == 0)
{
Serial.println("!!!!!!!!!!!!! limit not reached");
Serial.printf("codeur pos => %i\n", codeur_pos);
// stepper.setTargetPositionInSteps(max_steps + (max_steps - codeur_pos)); // limit_steps
int step_add = nb_microstep * 2;
stepper.setTargetPositionRelativeInSteps(step_add);
delay(100);
}
else if (abs(codeur_pos - pos_in_step) > 100 && stepper.getDirectionOfMotion() == 0)
{
Serial.println("!!!!!!!!!!!!! Not in position");
Serial.printf("codeur pos => %i\n", codeur_pos);
Serial.printf("pos in step => %i\n", pos_in_step);
stepper.setTargetPositionInSteps(pos_in_step);
}
}
// 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
}
+165
View File
@@ -0,0 +1,165 @@
#define nb_microstep 8 // nombre de microstep configuré sur le driver moteur
#define STEP_PER_REV_MOTOR 200 // nombre de pas par tour du moteur
#define CPR_ENCODER 4000 // nombre de pas par tour du codeur optique
/*
Nb SW1 SW2 SW3 SW4
1 200 on on on on
4 800 off on on on
8 1600 on off on on
16 3200 off off on on
32 6400 on on off on
64 12800 off on off on
128 25600 on off off on
256 51200 off off off on
5 1000 on on on off
10 2000 off on on off
20 4000 on off on off
25 5000 off off on off
40 8000 on on off off
50 10000 off on off off
100 20000 on off off off
200 40000 off off off off
*/
#define SECOND_PER_REV 2 // nombre de seconde pour faire un tour
const int STEP_PER_REV = nb_microstep * STEP_PER_REV_MOTOR; // nombre de pas par tour du moteur
const int MIN_SPEED = 1; // vitesse minimum du moteur
const int MAX_SPEED = ((STEP_PER_REV / 2) / SECOND_PER_REV) * nb_microstep; // vitesse maximum du moteur (1/2 révolution par SECOND_PER_REV seconde)
//const int MAX_SPEED = ((STEP_PER_REV / 2) / SECOND_PER_REV) * nb_microstep; // vitesse maximum du moteur (1/2 révolution par SECOND_PER_REV seconde)
const int SPEED_IN_STEPS_PER_SECOND = STEP_PER_REV; // vitesse initiale de déplacement du moteur = 1/2 de la vitesse maximum
const int ACCELERATION_IN_STEPS_PER_SECOND = nb_microstep * 2; // accélération initiale du moteur
const int DECELERATION_IN_STEPS_PER_SECOND = nb_microstep; // décélération initiale du moteur
int ACC_DEC_REMOVE_STEP = ACCELERATION_IN_STEPS_PER_SECOND + DECELERATION_IN_STEPS_PER_SECOND; // nombre de pas à enlever à la position pour l'accélération et la décélération ?
int min_steps = 0; // position de départ du moteur
int max_steps = STEP_PER_REV / 2; // position de fin du moteur (1600 en 16 microstep) (400 en 1 microstep)
int pos_in_step = max_steps / 2; // position du moteur en pas pour le mappage de la position
int min_count = 0; // valeur minimum du compteur du codeur optique
int max_count = CPR_ENCODER / 4; // valeur maximum du compteur du codeur optique avec uniquement les fronts montants du codeur
const int min_offset = 0; // min offset pour le potentiomètre de réglage de la position min/max
const int max_offset = nb_microstep * 5; // max offset pour le potentiomètre de réglage de la position min/max
volatile unsigned long last_dmx_change_pos;
volatile int speed_in_accel = MAX_SPEED / 10; // variable pour la vitesse d'acceleration
volatile int speed_in_decel = DECELERATION_IN_STEPS_PER_SECOND; // variable pour la vitesse de deceleration
// fonction
void targetPositionReachedCallback(long position); // callback function as the target position is reached
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 map count is %ld\n", map(encoder.getCount(), min_count, max_count, min_steps, max_steps));
Serial.printf("Encoder count is %ld\n", encoder.getCount());
}
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, MAX_SPEED);
stepper.setSpeedInStepsPerSecond(speed_in_step);
Serial.printf("dmx speed receive => %ld\n", DMX_data[speed_array]);
Serial.printf("speed in step => %ld\n", speed_in_step);
}
void pos_map() // fonction de mapping de la position du moteur
{
//int pos_in_step = map(DMX_data[pos_array], 255, 0, min_steps, max_steps);
//int pos_in_step = map(DMX_data[pos_array], 0, 255, min_steps - home_steps, max_steps + limit_steps); // fait dans la fonction limit_check
//stepper.setTargetPositionInSteps(pos_in_step);
Serial.printf("dmx pos to step => %ld\n", pos_in_step);
}
void set_min() // fonction pour position minimum de la plage de déplacement du moteur
{
home_steps = map((analogRead(home_set_pot)), 4095, 0, min_offset, max_offset);
stepper.setCurrentPositionAsHomeAndStop(); // set the current position as the home position and stop the stepper
// min_steps = stepper.getCurrentPositionInSteps() - home_steps; // position min du moteur en pas
min_steps = stepper.getCurrentPositionInSteps();
encoder.setCount(0); // remise à zéro de l'encodeur
min_count = encoder.getCount(); // valeur minimum du compteur du codeur en position min
}
void set_max() // fonction pour position maximum de la plage de déplacement du moteur
{
limit_steps = map((analogRead(limit_set_pot)), 4095, 0, min_offset, max_offset);
// max_steps = stepper.getCurrentPositionInSteps() + limit_steps; // position max du moteur en pas
max_steps = stepper.getCurrentPositionInSteps();
max_count = encoder.getCount(); // valeur maximum du compteur du codeur en position max
}
void init_range() // fonction d'initialisation de la plage de déplacement du moteur
{
int direction = -1;
bool limit_OK = false;
int position_init = max_steps / 2;
Serial.println("starting homing");
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_init);
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
}
}
set_min();
Serial.println("home OK");
stepper.clearLimitSwitchActive(); // clear the limit switch flag to allow movement in both directions again
limit_OK = false;
Serial.println("waiting for limit switch");
stepper.setTargetPositionInSteps(position_init); // set the target position to the middle of the range
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() < (max_steps - (max_steps / 4)))
{
position_init = stepper.getCurrentPositionInSteps() + (max_steps / 8);
}
else
{
position_init = stepper.getCurrentPositionInSteps() + nb_microstep;
}
stepper.setTargetPositionInSteps(position_init);
}
}
Serial.println("limit init OK");
stepper.setTargetPositionToStop();
position_init = max_steps / 2;
stepper.clearLimitSwitchActive(); // clear the limit switch flag to allow movement in both directions again
set_max();
stepper.setTargetPositionInSteps(position_init); // set the target position to the middle of the range
delay(500);
buttonStateChangeDetected = false; // remise à zéro du flag de changement d'état des switchs
}
+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
+167
View File
@@ -0,0 +1,167 @@
#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
/*
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();
}
}
*/
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)
{
if (newPosition > old_count || newPosition < old_count)
{
lastStepTime = millis();
emergencyStop = false;
}
if (newPosition >= old_count + loss_step || newPosition <= old_count - loss_step)
{
old_count = newPosition;
}
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)
{
Serial.printf("emergency stop timer : %i\n", millis() - emercency_stop_timer);
if (millis() - emercency_stop_timer > emergency_release_time && emergencyStop == true)
{
digitalWrite(MOTOR_ENABLE_PIN, LOW); // enable motor
Serial.println("======================> emergency stop released");
lastStepTime = millis();
emergencyStop = false;
last_dmx_change_pos = millis();
// stepper.setTargetPositionInSteps(pos_in_step);
}
else if (digitalRead(MOTOR_ENABLE_PIN) == LOW && emergencyStop == true)
{
Serial.println("======================> emergency stop engaged");
digitalWrite(MOTOR_ENABLE_PIN, HIGH); // disable and free motor
}
}
else if (digitalRead(MOTOR_ENABLE_PIN) == HIGH && emergencyStop == false)
{
digitalWrite(MOTOR_ENABLE_PIN, LOW); // enable motor
Serial.println("======================> emergency HARD stop released");
lastStepTime = millis();
// last_dmx_change_pos = millis();
// stepper.setTargetPositionInSteps(pos_in_step);
}
}
void limit_check() // fonction pour la sécurité si une limite est détectée par le bouton poussoir
{
const int limit_step_lost = nb_microstep; // nombre de pas à perdre avant de déclencher l'arrêt d'urgence en cas de détection de limite
limit_sw_check(); // check limit switch
home_sw_check(); // check home switch
// si aucun bouton n'est appuyé
if (ConfirmedHomeSwitchState != switch_active && ConfirmedLimitSwitchState != switch_active && buttonStateChangeDetected == true)
{
buttonStateChangeDetected = false;
stepper.clearLimitSwitchActive(); // clear the limit switch flag to allow movement in both directions again
return;
}
// si les deux boutons sont appuyés il y a un problème
if (ConfirmedHomeSwitchState == switch_active && ConfirmedLimitSwitchState == switch_active)
{
Serial.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ERROOOOORRRRRREEE !!!!!!!!");
stepper.emergencyStop(true);
emergencyStop = true;
}
// si le bouton de début de course est appuyé
if (ConfirmedHomeSwitchState == switch_active)
{
home_steps = map((analogRead(home_set_pot)), 4095, 0, min_offset, max_offset); // mise à jour de la valeur de l'offset de la position de départ
// 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
stepper.setCurrentPositionAsHomeAndStop();
}
// si le bouton vient d'être appuyé on va à la position de départ selon la config d'offset par le potentiomètre
else if (buttonStateChangeDetected == true)
{
Serial.printf("===========> Home <===========\n");
buttonStateChangeDetected = false;
home_steps = map((analogRead(home_set_pot)), 4095, 0, min_offset, max_offset);
// set_min(); // on enregistre la position actuelle comme position de départ
min_count = encoder.getCount(); // valeur minimum du compteur du codeur en position min
stepper.setCurrentPositionAsHomeAndStop(); // set the current position as the home position and stop the stepper
stepper.setCurrentPositionInSteps(min_steps); // mise à jour de la position pour compenser un décalage éventuel
stepper.setTargetPositionInSteps(min_steps - home_steps); // on va à la position de départ selon la config d'offset par le potentiomètre
Serial.printf("go to Home set : %i\n", min_steps - home_steps);
Serial.printf("min_steps : %i\n", min_steps);
Serial.printf("add config step : %i\n", home_steps);
Serial.printf("pos_in_step : %i\n", pos_in_step);
}
}
// si le bouton de fin de course est appuyé
if (ConfirmedLimitSwitchState == switch_active)
{
limit_steps = map((analogRead(limit_set_pot)), 4095, 0, min_offset, max_offset); // mise à jour de la valeur de l'offset de la position de fin
// 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
}
// si le bouton vient d'être appuyé on va à la position de fin selon la config d'offset par le potentiomètre
else if (buttonStateChangeDetected == true)
{
Serial.printf("===========> Limit <===========\n");
buttonStateChangeDetected = false;
limit_steps = map((analogRead(limit_set_pot)), 4095, 0, min_offset, max_offset);
// set_max(); // on enregistre la position actuelle comme position de fin
max_count = encoder.getCount(); // valeur maximum du compteur du codeur en position max
stepper.setCurrentPositionInSteps(max_steps); // mise à jour de la position pour compenser un décalage éventuel
stepper.setTargetPositionInSteps(max_steps); // mise à jour de la position pour compenser un décalage éventuel
stepper.setTargetPositionInSteps(max_steps + limit_steps); // on va à la position de fin selon la config d'offset par le potentiomètre
Serial.printf("go to Limit set : %i\n", max_steps + limit_steps);
Serial.printf("max_steps : %i\n", max_steps);
Serial.printf("add config step : %i\n", limit_steps);
}
}
}
+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