Bonjour à tous
j'ai un moteur 28 BYJ 48 sur un ESP8866
et quand je commande le moteur il patine et il fait demi-tour en plein déplacement
c'est ce projet que j'ai réalisé
https://www.webastro.net/forums/topic/195389-r%C3%A9alisation-roue-a-filtre-en-impression-3d-motoris%C3%A9e-et-pilot%C3%A9e-par-microcontroleur-esp8266esp32/
j'ai testé avec un autre moteur et c'est la même chose
avec une meilleure alimentation toujours rien qui change
des idées ???
Merci
cdt
Bonsoir,
Peut tu donner plus d'explications stp.
Tu dis que le moteur "patine" :
- est-ce le moteur à vide ou intégré dans sa mécanique ?
- comment est alimenté ce moteur ?
Si c'est sur le 5 V de la carte ce n'est pas terrible à plusieurs points de vue : courant disponible qui peut être faiblard et pollution de l'alim de la carte, d'où possible dysfonctionnement du microcontrôleur, j'ai "possible" ce n'est pas une affirmation.
Le moindre chargeur de téléphone fait maintenant 5 V 2 A il serait préférable d'en utiliser un pour le moteur
Il existe sur le net des centaines d'exemples pour ce moteur hyper courant.
En as-tu réalisé ? Avec juste un moteur à l'air libre sans charge pour se mettre dans les conditions matérielles des tutos "YouTube".
Information : ce moteur est du type unipolaire à 4 bobinages. L'ULN 2003 est constitué de transistors bipolaires utilisés en montage darlington, son inconvénient est la tension de déchet Vcesat de 1 V, j'espère que le moteur n'est pas alimenté à partir du 3,3 V.
Bonsoir astronomy
Sur le schéma, le câblage est bon. Ces fonctionnements erratiques sont typiques de mauvaises masses (GND). Elles doivent toutes câblées ensemble avec de bons contacts.
Mets ton programme en ligne.
Cordialement
jpbbricole
C'est ce que j'ai fait, j'ai décrit le problème à l'air libre
quand le moteur est chargé il ne bouge pas du tout
je l'ai alimenté avec une prise USB supplémentaire et il n'y a rien qui change
cdt
//
// =============================================================================
// SMO FILTER WHEEL
// =============================================================================
//
// Mandatory hardware
// ESP8266 or ESP32
// Stepper Motor 28BYJ-48 + UNL2003
//
//
// =============================================================================
// SMO DEFINES (optional compil)
// =============================================================================
//
// Choose ESP8266 or ESP32
//#define SMO_USE_ESP32
#define SMO_USE_ESP8266
// Verif
#if defined(SMO_USE_ESP32) and defined(SMO_USE_ESP8266)
#error "Choose ESP8266 or ESP32"
#endif
// OPTIONAL: SMO_DEBUG : Debug or not...
#define SMO_DEBUG
// OPTIONAL: SMO_USE_WIFI : Wifi or not...
#define SMO_USE_WIFI
#define SMO_USE_WIFI_CLIENT
#define SMO_USE_WIFI_ADHOC
// Verif
#if defined(SMO_USE_WIFI) and !defined(SMO_USE_WIFI_CLIENT) and !defined(SMO_USE_WIFI_ADHOC)
#error "Define one Wifi mode at least (CLIENT/AP/CLIENT+AP)"
#endif
#if defined(SMO_USE_WIFI) and defined(SMO_USE_WIFI_CLIENT)
// Mandatory, one wifi ssid and password
#define SSID_1 "XXX"
#define PASSWORD_1 "XXX"
// If you need to add another ssid/password, uncoment the following lines
#define SSID_2 "reseau2"
#define PASSWORD_2 "password2"
#define SSID_3 "reseau3"
#define PASSWORD_3 "password3"
#endif
#if defined (SMO_USE_WIFI) and defined (SMO_USE_WIFI_ADHOC)
#define SSID_AP "mls-rf"
#define PASSWORD_AP "Tus0r@p@"
#endif
// OPTIONAL: SMO_USE_WIFI_OTA : ESP8266 OTA or not... (need SMO_USE_WIFI)
#ifdef SMO_USE_WIFI
#define SMO_USE_WIFI_OTA
#define SMO_OTA_PASSWORD "123"
#endif
// MANDATORY: SMO_PROTOCOL_xxx : Choose one protocol to handle serial commands...
// note: OPTEC do not work at this time...
// note: choose QUANTUM and disable DEBUG serial outputif you want to use the wheel with EKOS/INDI
//#define SMO_PROTOCOL_PERSO
#define SMO_PROTOCOL_QUANTUM
//#define SMO_PROTOCOL_OPTEC
// OPTIONAL: for immediate or background move (choose background to avoid timeout in Ekos/Indi)
#define SMO_BACKGROUND_MOVE
//
// =============================================================================
// INCLUDES
// =============================================================================
//
#include <AccelStepper.h>
#include <EEPROM.h>
#ifdef SMO_USE_WIFI
#ifdef SMO_USE_WIFI_ADHOC
#ifdef SMO_USE_ESP8266
#include <ESP8266WiFi.h>
#endif
#ifdef SMO_USE_ESP32
#include <WiFi.h>
#endif
#endif
#ifdef SMO_USE_ESP8266
#include <ESP8266WiFiMulti.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>
#endif
#ifdef SMO_USE_ESP32
#include <WiFiMulti.h>
#include <ESPmDNS.h>
#include <WebServer.h>
#endif
#ifdef SMO_USE_WIFI_OTA
#include <ArduinoOTA.h>
#endif
#endif
//
// =============================================================================
// DEFINES (values)
// =============================================================================
//
#define SMO_PRODUCT "SMO-RF"
#define SMO_VERSION "1.1.1"
#define SMO_HOSTNAME "smo-rf"
// Caracteristiques Moteur
#define motorPin1 5 // IN1 pin on the ULN2003A driver to pin D1 on NodeMCU board
#define motorPin2 4 // IN2 pin on the ULN2003A driver to pin D2 on NodeMCU board
#define motorPin3 0 // IN3 pin on the ULN2003A driver to pin D3 on NodeMCU board
#define motorPin4 2 // IN4 pin on the ULN2003A driver to pin D4 on NodeMCU board
//sur ESP32 ne as utiliser GPIO 6-11 et 34-39
// Steppers
#define defStepperMaxSpeed 1000
#define minStepperMaxSpeed 100
#define maxStepperMaxSpeed 2000
#define defStepperSpeed 800
#define minStepperSpeed 100
#define maxStepperSpeed 2000
#define defStepperAccel 200
#define minStepperAccel 100
#define maxStepperAccel 1000
#define defStepsPerRevolution 64.0
#define minStepsPerRevolution 1.0
#define maxStepsPerRevolution 100.0
// Wheel
#define defStepperMaxPos 20000
#define minStepperMaxPos 10000
#define maxStepperMaxPos 40000
#define defStepperMaxAngle 180
#define minStepperMaxAngle 10
#define maxStepperMaxAngle 360
#define defNbDentsAxeMoteur 20
#define minNbDentsAxeMoteur 10
#define maxNbDentsAxeMoteur 100
#define defNbDentsAxeRoue 100
#define minNbDentsAxeRoue 50
#define maxNbDentsAxeRoue 500
// FilterWheel
#define maxFilterNameSize 8
#define eepromSize 1024
#ifdef SMO_PROTOCOL_PERSO
#define SERIAL_BAUD 9600
#define SERIAL_TIMEOUT 250
// Caracteristiques roue a filtre
#define defFilterSlots 5
#define maxFilterSlots 8
const unsigned long SMO1 = 339126000;
const unsigned long SMO2 = 339126001;
const int eepromStepperAddress = 0; //Adresse de départ pour enregistrement
const int eepromWheelAddress = 50; //Adresse de départ pour enregistrement
#endif
#ifdef SMO_PROTOCOL_QUANTUM
#define SERIAL_BAUD 9600
#define SERIAL_TIMEOUT 250
// Caracteristiques roue a filtre
#define defFilterSlots 5
#define maxFilterSlots 7
const unsigned long SMO1 = 339126000;
const unsigned long SMO2 = 339126002;
const int eepromStepperAddress = 0; //Adresse de départ pour enregistrement
const int eepromWheelAddress = 200; //Adresse de départ pour enregistrement
#endif
#ifdef SMO_PROTOCOL_OPTEC
#define SERIAL_BAUD 19200
#define SERIAL_TIMEOUT 250
// Caracteristiques roue a filtre
#define defFilterSlots 5
#define maxFilterSlots 9
#define defFilterWheels 1
#define maxFilterWheels 5
const unsigned long SMO1 = 339126000;
const unsigned long SMO2 = 339126003;
const int eepromStepperAddress = 0; //Adresse de départ pour enregistrement
const int eepromWheelAddress = 300; //Adresse de départ pour enregistrement
#endif
//
// =============================================================================
// TYPES
// =============================================================================
//
// ma structure config stepper (10 octets)
struct stepperConfigStruct {
int stepperMaxSpeed = defStepperMaxSpeed;
int stepperSpeed = defStepperSpeed;
int stepperAccel = defStepperAccel;
float stepsPerRevolution = defStepsPerRevolution; // steps per revolution
// float stepsPerRevolution = 71.8; // steps per revolution
};
// ma structure config wheel (34 octets)
struct wheelConfigStruct {
unsigned long smo;
stepperConfigStruct stepperConfig;
long maxPosition = defStepperMaxPos;
long currentPosition = 0;
float maxAngle = defStepperMaxAngle;
float currentAngle = 0;
int nbDentsAxeMoteur = defNbDentsAxeMoteur;
int nbDentsAxeRoue = defNbDentsAxeRoue;
float ratioAxe = (float)nbDentsAxeRoue / nbDentsAxeMoteur;
float degreePerRevolution = 360.0 / (stepperConfig.stepsPerRevolution * ratioAxe) ; // degree per revolution
};
// ma structure config (102 octets) SMO_PROTOCOL_PERSO
// ma structure config (90 octets) SMO_PROTOCOL_QUANTUM
// ma structure config (556 octets) SMO_PROTOCOL_OPTEC
struct filterWheelConfigStruct {
unsigned long smo;
#if defined(SMO_PROTOCOL_PERSO) or defined(SMO_PROTOCOL_QUANTUM)
int nbFilterSlots = defFilterSlots;
int slotsPositions[maxFilterSlots];
int slotsOffsets[maxFilterSlots];
char slotsNames[maxFilterSlots][maxFilterNameSize];
#endif
#if defined(SMO_PROTOCOL_OPTEC)
int nbFilterWhells = defFilterWheels;
int nbFilterSlots[maxFilterWheels];
int slotsPositions[maxFilterWheels][maxFilterSlots];
int slotsOffsets[maxFilterWheels][maxFilterSlots];
char slotsNames[maxFilterWheels][maxFilterSlots][maxFilterNameSize];
#endif
// Keeps track of the position in slotsPosition[] we are about to run
int currentSlot = 0;
int targetSlot = 0;
#ifdef SMO_PROTOCOL_OPTEC
int currentFilterWheel = 0;
#endif
};
//
// ============================================================
// GLOBAL VAR
// ============================================================
//
char incomingChar;
String incomingMessage;
String lastInputMessage;
String lastOutputMessage;
bool connected = false;
#ifdef SMO_USE_WIFI
bool connected_wifi = false;
bool wifi_request = false;
#ifdef SMO_USE_ESP8266
ESP8266WiFiMulti wifiMulti;
ESP8266WebServer server(80);
#endif
#ifdef SMO_USE_ESP32
WiFiMulti wifiMulti;
WebServer server(80);
#endif
#endif
/*
* AccelStepper::FULL2WIRE (2) means: 2 wire stepper (2 pins needed).
* AccelStepper::FULL3WIRE (3) means: 3 wire stepper, like a harddisk motor (3 pins needed).
* AccelStepper::FULL4WIRE (4) means: 4 wire stepper (4 pins needed).
* AccelStepper::HALF3WIRE (6) means: 3 wire half stepper, like a harddisk motor (3 pins needed)
* AccelStepper::HALF4WIRE (8) means: 4 wire half stepper (4 pins needed)
*
* AccelStepper uses AccelStepper::FULL4WIRE (4 pins needed) by default.
*/
//AccelStepper stepper(AccelStepper::HALF4WIRE, motorPin1, motorPin3, motorPin2, motorPin4);
AccelStepper stepper(AccelStepper::HALF4WIRE, motorPin1, motorPin3, motorPin2, motorPin4);
wheelConfigStruct wheelConfig;
filterWheelConfigStruct filterWheelConfig;
#if defined(SMO_PROTOCOL_PERSO) or defined(SMO_PROTOCOL_QUANTUM)
String slotsNames[maxFilterSlots];
#endif
#ifdef SMO_PROTOCOL_OPTEC
char filterWheelsNames[maxFilterWheels] = { 'A', 'B', 'C', 'D', 'E'};
String slotsNames[maxFilterWheels][maxFilterSlots];
#endif
// HELP PROTOCOL MESSAGE
#ifdef SMO_PROTOCOL_PERSO
String helpmessage = FPSTR("<pre>SMO_PROTOCOL pour Roue a Filtre Perso<br>WE --> IE Wheel Filter Entering Serial Mode<br>WX --> IX Wheel Filter eXiting Serial Mode<br>WI --> II Wheel Init, set slot 1 and step 0<br>WR --> IR Wheel Reset, move to 1 and set step 0<br>WD --> ID Wheel Dump, Debug Dump<br>WFSG --> IFS<x> Wheel Filter Slots Get, get slots amount 1-9 (int)<br>WFSS<x> --> IFS<x> Wheel Filter Slots Set, set slots amount 1-9 (int)<br>WFPG --> IFP<x> Wheel Filter Pos Get, get slot position 1-9 (int)<br>WFPS<x> --> IFP<x> Wheel Filter Pos Set, slot number to go 1-9 (int)<br>WFPS+ --> IFP<x> Wheel Filter Pos Set Next slot 1-9 (int)<br>WFPS- --> IFP<x> Wheel Filter Pos Set Previous slot 1-9 (int)<br>WFNG<x> --> IFN<x><y> Wheel Filter Name Get, x=1-9, y=name (max 8 char)<br>WFNS<x><y> --> IFN<x><y> Wheel Filter Name Set, x=1-9, y=newname (max 8 char)<br>WFOG<x> --> IFO<x><y> Wheel Filter Offset Get, x=1-9, y=value 1-1000 (int)<br>WFOS<x><y> --> IFO<x><y> Wheel Filter Offset Set, x=1-9, y=newvalue 1-1000 (int)<br>WMSG --> IMS<x> Wheel Motor Step Get, get motor step position<br>WMSS+ --> IMS<x> Wheel Motor Step Set +10 step (calibration move)<br>WMSS- --> IMS<x> Wheel Motor Step Set -10 step (calibration move)<br>WMSS> --> IMS<x> Wheel Motor Step Set +100 step (calibration move)<br>WMSS< --> IMS<x> Wheel Motor Step Set -100 step (calibration move)<br>WPG<x> --> IP<x><y> Wheel Param Get, param=x value=y<br>WPS<x><y> --> IP<x><y> Wheel Param Set, param=x value=y, Modif params<br> param=MS MaxSpeed 100-2000 (int) default=1000<br> param=CS CurrentSpeed 100-2000 (int) default=500<br> param=CA CurrentAccel 100-1000 (int) default=200<br> param=SR StepPerRevolutiion 1.00-100.00 (float) default=64<br> param=GM GearMotor tooth 10-100 (int) default=20<br> param=GR GearWheel tooth 50-500 (int) default=100<br></pre>");
/* const char helpmessage[] PROGMEM = R"rawliteral(
<pre>
SMO_PROTOCOL pour Roue a Filtre Perso
WE --> IE Wheel Filter Entering Serial Mode
WX --> IX Wheel Filter eXiting Serial Mode
WI --> II Wheel Init, set slot 1 and step 0
WR --> IR Wheel Reset, move to 1 and set step 0
WD --> ID Wheel Dump, Debug Dump
WFSG --> IFSx Wheel Filter Slots Get, get slots amount 1-9 (int)
WFSSx --> IFSx Wheel Filter Slots Set, set slots amount 1-9 (int)
WFPG --> IFPx Wheel Filter Pos Get, get slot position 1-9 (int)
WFPSx --> IFPx Wheel Filter Pos Set, slot number to go 1-9 (int)
WFPS+ --> IFPx Wheel Filter Pos Set Next slot 1-9 (int)
WFPS- --> IFPx Wheel Filter Pos Set Previous slot 1-9 (int)
WFNGx --> IFNxy Wheel Filter Name Get, x=1-9, y=name (max 8 char)
WFNSxy --> IFNxy Wheel Filter Name Set, x=1-9, y=newname (max 8 char)
WFOGx --> IFOxy Wheel Filter Offset Get, x=1-9, y=value 1-1000 (int)
WFOSxy --> IFOxy Wheel Filter Offset Set, x=1-9, y=newvalue 1-1000 (int)
WMSG --> IMSxxxx Wheel Motor Step Get, get motor step position
WMSS+ --> IMSxxxx Wheel Motor Step Set +10 step (calibration move)
WMSS- --> IMSxxxx Wheel Motor Step Set -10 step (calibration move)
WMSS> --> IMSxxxx Wheel Motor Step Set +100 step (calibration move)
WMSS< --> IMSxxxx Wheel Motor Step Set -100 step (calibration move)
WPGx --> IPxy Wheel Param Get, param=x value=y
WPSxy --> IPxy Wheel Param Set, param=x value=y, Modif params
param=MS MaxSpeed 100-2000 (int) default=1000
param=CS CurrentSpeed 100-2000 (int) default=500
param=CA CurrentAccel 100-1000 (int) default=200
param=SR StepPerRevolutiion 1.00-100.00 (float) default=64
param=GM GearMotor tooth 10-100 (int) default=20
param=GR GearWheel tooth 50-500 (int) default=100
</pre>
)rawliteral";
*/
#endif
#ifdef SMO_PROTOCOL_QUANTUM
String helpmessage = FPSTR("<pre>Quantum SMO_PROTOCOL<br>EN --> N<n> Get number of filter positions<br>DS --> none Disconnect<br>G<n> --> P<n> Go to filter position n<br>F<n> --> F<n><name> Get filter name<br>f<n><name> --> none Set filter name<br>O<n> --> O<n><offset> Get filter offset<br>o<n><offset> --> none Set filter offset<br> SN --> SN<desc> Get description<br>VR --> VR<version> Get version<br></pre>");
/* const char helpmessage[] PROGMEM = R"rawliteral(
<pre>
Quantum SMO_PROTOCOL
Get number of filter positions EN N<number>
Disconnect DS
Go to filter position G<number>
position is returned when the move finishes P<number>
get filter name F<number> F<number><name>
set filter name f<number><name>
Get filter offset O<number> O<number><offset>
set filter offset o<number><offset>
Get description SN SN<details>
get version VR VR<details>
</pre>
)rawliteral";
*/
#endif
#ifdef SMO_PROTOCOL_OPTEC
String helpmessage = FPSTR("<pre>SMO_PROTOCOLE pour Roue a Filtre Optec<br>WSMODE --> !<br>WVAAAA --> V= 2.04<br>WHOME --> A, B, C, D, E ou F, G, H<br>WIDENT --> A, B, C, D, E ou F, G, H<br>WFILTR --> x (1 a 5 ou 1 a 8)<br>WGOTO<x> --> *<br>WREAD --> n1..40 ou n64 (chaine de 40 ou 64 caracteres)<br>WLOAD<y>*<n1..n40> ou n64 --> !<br>WEXITS --> END<br></pre>");
/* const char helpmessage[] PROGMEM = R"rawliteral(
<pre>
SMO_PROTOCOLE pour Roue a Filtre Optec
WSMODE --> !
WVAAAA --> V= 2.04
WHOME --> A, B, C, D, E ou F, G, H
WIDENT --> A, B, C, D, E ou F, G, H
WFILTR --> x (1 à 5 ou 1 à 8)
WGOTOx --> *
WREAD --> n1..40 ou n64 (chaine de 40 ou 64 caracteres)
WLOADy*n1..n40 ou n64 --> !
WEXITS --> END
</pre>
)rawliteral";
*/
#endif
//
// =============================================================================
// FUNCTIONS (common)
// =============================================================================
//
// =============================================================================
#ifdef SMO_DEBUG
void DebugVarStepper(AccelStepper as) {
Serial.println(F("DF:DebugVarStepper"));
Serial.println(F("D:########################"));
Serial.println(F("D:## DEBUG VAR STEPPER ##"));
Serial.println(F("D:########################"));
Serial.print(F("D:maxSpeed:"));
Serial.println(as.maxSpeed());
Serial.print(F("D:speed:"));
Serial.println(as.speed());
Serial.print(F("D:currentPosition:"));
Serial.println(as.currentPosition());
Serial.print(F("D:targetPosition:"));
Serial.println(as.targetPosition());
Serial.print(F("D:distanceToGo:"));
Serial.println(as.distanceToGo());
Serial.println(F("D:########################"));
}
#endif
// =============================================================================
#ifdef SMO_DEBUG
void DebugVarWheelConfig(wheelConfigStruct sc) {
Serial.println(F("DF:DebugVar"));
Serial.println(F("D:######################"));
Serial.println(F("D:## DEBUG VAR WHEEL ##"));
Serial.println(F("D:######################"));
Serial.print(F("D:stepperMaxSpeed:"));
Serial.println(sc.stepperConfig.stepperMaxSpeed);
Serial.print(F("D:stepperSpeed:"));
Serial.println(sc.stepperConfig.stepperSpeed);
Serial.print(F("D:stepperAccel:"));
Serial.println(sc.stepperConfig.stepperAccel);
Serial.print(F("D:stepsPerRevolution:"));
Serial.println(sc.stepperConfig.stepsPerRevolution, 2);
Serial.print(F("D:maxPosition:"));
Serial.println(sc.maxPosition);
Serial.print(F("D:currentPosition:"));
Serial.println(sc.currentPosition);
Serial.print(F("D:maxAngle:"));
Serial.println(sc.maxAngle, 2);
Serial.print(F("D:currentAngle:"));
Serial.println(sc.currentAngle, 2);
Serial.print(F("D:nbDentsAxeMoteur:"));
Serial.println(sc.nbDentsAxeMoteur);
Serial.print(F("D:nbDentsAxeRoue:"));
Serial.println(sc.nbDentsAxeRoue);
Serial.print(F("D:ratioAxe:"));
Serial.println(sc.ratioAxe, 2);
Serial.print(F("D:degreePerRevolution:"));
Serial.println(sc.degreePerRevolution, 2);
Serial.println(F("D:######################"));
}
#endif
// =============================================================================
#ifdef SMO_DEBUG
void DebugVarFilterWheelConfig(filterWheelConfigStruct fwc) {
int i, j;
Serial.println(F("DF:DebugVar"));
Serial.println(F("D:############################"));
Serial.println(F("D:## DEBUG VAR FILTERWHEEL ##"));
Serial.println(F("D:############################"));
#ifdef SMO_PROTOCOL_OPTEC
Serial.print(F("D:nbFilterSlots:"));
Serial.println(fwc.nbFilterSlots[fwc.currentFilterWheel]);
Serial.print(F("D:slotsPositions:"));
for (i = 0; i < fwc.nbFilterSlots[fwc.currentFilterWheel]; i++) {
Serial.print(fwc.slotsPositions[fwc.currentFilterWheel][i]);
Serial.print("|");
}
Serial.println("");
Serial.print(F("D:slotsOffsets:"));
for (i = 0; i < fwc.nbFilterSlots[fwc.currentFilterWheel]; i++) {
Serial.print(fwc.slotsOffsets[fwc.currentFilterWheel][i]);
Serial.print("|");
}
Serial.println("");
Serial.print(F("D:slotsNames:"));
for (i = 0; i < fwc.nbFilterSlots[fwc.currentFilterWheel]; i++) {
for (j = 0; j < maxFilterNameSize; j++) {
Serial.print(fwc.slotsNames[fwc.currentFilterWheel][i][j]);
}
Serial.print("|");
}
Serial.println("");
Serial.print(F("D:slotsNames2:"));
for (i = 0; i < fwc.nbFilterSlots[fwc.currentFilterWheel]; i++) {
Serial.print(slotsNames[fwc.currentFilterWheel][i]);
Serial.print("|");
}
Serial.println("");
#else
Serial.print(F("D:nbFilterSlots:"));
Serial.println(fwc.nbFilterSlots);
Serial.print(F("D:slotsPositions:"));
for (i = 0; i < fwc.nbFilterSlots; i++) {
Serial.print(fwc.slotsPositions[i]);
Serial.print("|");
}
Serial.println("");
Serial.print(F("D:slotsOffsets:"));
for (i = 0; i < fwc.nbFilterSlots; i++) {
Serial.print(fwc.slotsOffsets[i]);
Serial.print("|");
}
Serial.println("");
Serial.print(F("D:slotsNames:"));
for (i = 0; i < fwc.nbFilterSlots; i++) {
for (j = 0; j < maxFilterNameSize; j++) {
Serial.print(fwc.slotsNames[i][j]);
}
Serial.print("|");
}
Serial.println("");
Serial.print(F("D:slotsNames2:"));
for (i = 0; i < fwc.nbFilterSlots; i++) {
Serial.print(slotsNames[i]);
Serial.print("|");
}
Serial.println("");
#endif
#ifdef SMO_PROTOCOL_OPTEC
Serial.print(F("D:currentFilterWheel:"));
Serial.println(fwc.currentFilterWheel);
#endif
Serial.print(F("D:currentSlot:"));
Serial.println(fwc.currentSlot);
Serial.print(F("D:targetSlot:"));
Serial.println(fwc.targetSlot);
Serial.println(F("D:######################"));
}
#endif
// =============================================================================
#ifdef SMO_DEBUG
void DebugVar() {
Serial.println(F("DF:DebugVar"));
Serial.println(F("D:################"));
Serial.println(F("D:## DEBUG VAR ##"));
Serial.println(F("D:################"));
DebugVarWheelConfig(wheelConfig);
DebugVarStepper(stepper);
DebugVarFilterWheelConfig(filterWheelConfig);
Serial.println(F("D:################"));
}
#endif
// =============================================================================
#if defined(SMO_DEBUG) and defined(SMO_USE_WIFI)
void DebugWifi() {
Serial.println(F("DF:DebugWifi"));
Serial.println(F("D:#################"));
Serial.println(F("D:## DEBUG WIFI ##"));
Serial.println(F("D:#################"));
#ifdef SMO_USE_WIFI_ADHOC
Serial.println(F("D:WiFi created"));
Serial.print(F("D:MAC : "));
Serial.println(WiFi.softAPmacAddress());
Serial.print(F("D:IP address: "));
Serial.println(WiFi.softAPIP());
#endif
#ifdef SMO_USE_WIFI_CLIENT
Serial.println(F("D:WiFi connected"));
Serial.print(F("D:MAC : "));
Serial.println(WiFi.macAddress());
Serial.print(F("D:IP address: "));
Serial.println(WiFi.localIP());
Serial.print(F("D:SSID: "));
Serial.println(WiFi.SSID());
WiFi.printDiag(Serial);
#endif
Serial.println(F("D:################"));
}
#endif
// =============================================================================
#if defined(SMO_USE_WIFI) and defined(SMO_USE_WIFI_OTA)
void InitOTA(void) {
#ifdef SMO_DEBUG
Serial.println(F("DF:InitOTA"));
#endif
// Hostname defaults to esp8266-[ChipID]
ArduinoOTA.setHostname(SMO_HOSTNAME);
// No authentication by default
ArduinoOTA.setPassword((const char *)SMO_OTA_PASSWORD);
ArduinoOTA.onStart([]() {
Serial.println(F("\nOTA Start"));
});
ArduinoOTA.onEnd([]() {
Serial.println(F("\nOTA End"));
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("OTA Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println(F("OTA Auth Failed"));
else if (error == OTA_BEGIN_ERROR) Serial.println(F("OTA Begin Failed"));
else if (error == OTA_CONNECT_ERROR) Serial.println(F("OTA Connect Failed"));
else if (error == OTA_RECEIVE_ERROR) Serial.println(F("OTA Receive Failed"));
else if (error == OTA_END_ERROR) Serial.println(F("OTA End Failed"));
});
ArduinoOTA.begin();
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleRoot() {
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleRoot"));
#endif
HandleSelectFilter();
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleSelectFilter() {
String html_page;
int i;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleSelectFilter"));
#endif
html_page = "<!DOCTYPE html><html lang=\"en-us\">";
html_page += "<head><meta charset=\"UTF-8\">";
html_page += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"</head><body>";
html_page += "<h2>Filter Wheel " + String(SMO_PRODUCT) + " " + String(SMO_VERSION) + "<h2><h3>Select Filters</h3>";
html_page += "<form action=\"/select_filter\" method=\"POST\">";
html_page += "<table><thead><tr><th>Filtre</th><th>Name</th><th>Select</th></thead></tr><tbody>";
#ifdef SMO_PROTOCOL_OPTEC
for (i = 0; i < filterWheelConfig.nbFilterSlots[filterWheelConfig.currentFilterWheel]; i++) {
html_page += "<tr><td>" + String(i+1) + "</td>:<td>" + slotsNames[filterWheelConfig.currentFilterWheel][i];
#else
for (i = 0; i < filterWheelConfig.nbFilterSlots; i++) {
html_page += "<tr><td>" + String(i+1) + "</td>:<td>" + slotsNames[i];
#endif
html_page += "</td><td><input type=\"radio\" name=\"filters\" value=\"filter" + String(i+1) + "\"";
if (i == filterWheelConfig.currentSlot) {
html_page += "checked";
}
html_page += "></td></tr>";
}
html_page += "</tbody></table><br><input type=\"submit\" value=\"Submit\"><br><br>";
html_page += "<a href=\"/config_filters\">Config Filters</a><br>";
html_page += "<a href=\"/config_wheel\">Config Wheel</a><br>";
html_page += "<a href=\"/send_message\">Send Messages</a><br>";
html_page += "<a href=\"/manual_move\">Manual Move</a><br>";
html_page += "<a href=\"/debug\">Debug</a>";
html_page += "</form>";
html_page += "</body></html>";
server.setContentLength(html_page.length()); // Permet l'affichage plus rapide après chaque clic sur les boutons
server.send(200, "text/html", html_page);
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleRespSelectFilter() {
String element;
int i;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleRespSelectFilter"));
#endif
#ifdef SMO_DEBUG
for (i=0; i <= server.args(); i++) {
Serial.println(server.arg(i));
}
#endif
#ifdef SMO_PROTOCOL_OPTEC
for (i = 1; i <= filterWheelConfig.nbFilterSlots[filterWheelConfig.currentFilterWheel]; i++) {
element = String("filter") + String(i);
if ( server.hasArg("filters") && server.arg("filters") == element ) {
filterWheelConfig.targetSlot = i - 1;
}
}
if (filterWheelConfig.targetSlot != filterWheelConfig.currentSlot) {
#ifdef SMO_BACKGROUND_MOVE
stepper.moveTo(degsToSteps(filterWheelConfig.slotsPositions[filterWheelConfig.currentFilterWheel][filterWheelConfig.targetSlot]));
#else
stepper.runToNewPosition(degsToSteps(filterWheelConfig.slotsPositions[filterWheelConfig.currentFilterWheel][filterWheelConfig.targetSlot]));
#endif
filterWheelConfig.currentSlot = filterWheelConfig.targetSlot;
}
#else
for (i = 1; i <= filterWheelConfig.nbFilterSlots; i++) {
element = String("filter") + String(i);
if ( server.hasArg("filters") && server.arg("filters") == element ) {
filterWheelConfig.targetSlot = i - 1;
}
}
if (filterWheelConfig.targetSlot != filterWheelConfig.currentSlot) {
#ifdef SMO_BACKGROUND_MOVE
stepper.moveTo(degsToSteps(filterWheelConfig.slotsPositions[filterWheelConfig.targetSlot]));
#else
stepper.runToNewPosition(degsToSteps(filterWheelConfig.slotsPositions[filterWheelConfig.targetSlot]));
#endif
filterWheelConfig.currentSlot = filterWheelConfig.targetSlot;
}
#endif
HandleSelectFilter();
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleConfigFilters() {
String html_page;
int i;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleConfigFilters"));
#endif
html_page = "<!DOCTYPE html><html lang=\"en-us\">";
html_page += "<head><meta charset=\"UTF-8\">";
html_page += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"</head><body>";
html_page += "<h2>Filter Wheel " + String(SMO_PRODUCT) + " " + String(SMO_VERSION) + "<h2><h3>Config Filters</h3>";
html_page += "<form action=\"/config_filters\" method=\"POST\">";
html_page += "<table><thead><tr><th>Filtre</th><th>Name</th><th>Offset</th></thead></tr><tbody>";
#ifdef SMO_PROTOCOL_OPTEC
for (i = 0; i < filterWheelConfig.nbFilterSlots[filterWheelConfig.currentFilterWheel]; i++) {
html_page += "<tr><td>" + String(i+1) + "</td>:<td><input type=\"text\" name=\"namefilter";
html_page += String(i + 1) + "\" value=\"" + slotsNames[filterWheelConfig.currentFilterWheel][i] + "\" size=10 maxlength=8>";
html_page += "</td><td><input type=\"text\" name=\"offsetfilter" + String(i + 1);
html_page += "\" value=\"" + String(filterWheelConfig.slotsOffsets[filterWheelConfig.currentFilterWheel][i]) + "\"></td></tr>";
}
#else
for (i = 0; i < filterWheelConfig.nbFilterSlots; i++) {
html_page += "<tr><td>" + String(i+1) + "</td>:<td><input type=\"text\" name=\"namefilter";
html_page += String(i + 1) + "\" value=\"" + slotsNames[i] + "\" size=10 maxlength=8>";
html_page += "</td><td><input type=\"text\" name=\"offsetfilter" + String(i + 1);
html_page += "\" value=\"" + String(filterWheelConfig.slotsOffsets[i]) + "\"></td></tr>";
}
#endif
html_page += "</tbody></table><br><input type=\"submit\" value=\"Submit\"><br><br>";
html_page += "</form>";
html_page += "<a href=\"/\">Back</a>";
html_page += "</body></html>";
server.setContentLength(html_page.length()); // Permet l'affichage plus rapide après chaque clic sur les boutons
server.send(200, "text/html", html_page);
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleRespConfigFilters() {
String element, s_number;
int i_number;
bool configmodif = false;
int i;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleRespConfigFilters"));
#endif
#ifdef SMO_DEBUG
for (i=0; i <= server.args(); i++) {
Serial.println(server.arg(i));
}
#endif
#if defined(SMO_PROTOCOL_OPTEC)
for ( int i = 0 ; i < filterWheelConfig.nbFilterSlots[filterWheelConfig.currentFilterWheel]; i++) {
element = String("namefilter") + String(i + 1);
if ( server.hasArg(element) ) {
slotsNames[filterWheelConfig.currentFilterWheel][i] = server.arg(element);
configmodif = true;
}
}
#else
for ( int i = 0 ; i < filterWheelConfig.nbFilterSlots; i++) {
element = String("namefilter") + String(i + 1);
if ( server.hasArg(element) ) {
slotsNames[i] = server.arg(element);
configmodif = true;
}
}
#endif
#if defined(SMO_PROTOCOL_OPTEC)
for ( int i = 0 ; i < filterWheelConfig.nbFilterSlots[filterWheelConfig.currentFilterWheel]; i++) {
element = String("offsetfilter") + String(i + 1);
if ( server.hasArg(element) && server.arg(element) != NULL ) {
s_number = server.arg(element);
i_number = s_number.toInt();
filterWheelConfig.slotsOffsets[filterWheelConfig.currentFilterWheel][i] = i_number;
configmodif = true;
}
}
#else
for ( int i = 0 ; i < filterWheelConfig.nbFilterSlots; i++) {
element = String("offsetfilter") + String(i + 1);
if ( server.hasArg(element) && server.arg(element) != NULL ) {
s_number = server.arg(element);
i_number = s_number.toInt();
filterWheelConfig.slotsOffsets[i] = i_number;
configmodif = true;
}
}
#endif
if (configmodif) {
CopyToSlotsNamesConfig();
SauvegardeFilterWheelEEPROM();
}
HandleConfigFilters();
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleConfigWheel() {
String html_page;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleConfigWheel"));
#endif
html_page = "<!DOCTYPE html><html lang=\"en-us\">";
html_page += "<head><meta charset=\"UTF-8\">";
html_page += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"</head><body>";
html_page += "<h2>Filter Wheel " + String(SMO_PRODUCT) + " " + String(SMO_VERSION) + "<h2><h3>Config Wheel</h3>";
html_page += "<form action=\"/config_wheel\" method=\"POST\">";
html_page += "<table><thead><tr><th>Name</th><th>Value</th><th>Min-Max</th></thead></tr><tbody>";
html_page += "<tr><td>Nb Filtres</td>:<td><input type=\"text\" name=\"nbfiltres\" value=\"";
#ifdef SMO_PROTOCOL_OPTEC
html_page += String(filterWheelConfig.nbFilterSlots[filterWheelConfig.currentFilterWheel]) + "\"></td><td>1-9</td></tr>";
#else
html_page += String(filterWheelConfig.nbFilterSlots) + "\"></td><td>1-9</td></tr>";
#endif
html_page += "<tr><td>MaxSpeed</td>:<td><input type=\"text\" name=\"maxspeed\" value=\"";
html_page += String(wheelConfig.stepperConfig.stepperMaxSpeed) + "\"></td><td>" + String(minStepperMaxSpeed) + "-" + String(maxStepperMaxSpeed) + "</td></tr>";
html_page += "<tr><td>Speed</td>:<td><input type=\"text\" name=\"speed\" value=\"";
html_page += String(wheelConfig.stepperConfig.stepperSpeed) + "\"></td><td>" + String(minStepperSpeed) + "-" + String(maxStepperSpeed) + "</td></tr>";
html_page += "<tr><td>Accel</td>:<td><input type=\"text\" name=\"accel\" value=\"";
html_page += String(wheelConfig.stepperConfig.stepperAccel) + "\"></td><td>" + String(minStepperAccel) + "-" + String(maxStepperAccel) + "</td></tr>";
html_page += "<tr><td>StepsPerRevolution</td>:<td><input type=\"text\" name=\"steprevolution\" value=\"";
html_page += String(wheelConfig.stepperConfig.stepsPerRevolution) + "\"></td><td>" + String(minStepsPerRevolution) + "-" + String(maxStepsPerRevolution) + "</td></tr>";
html_page += "<tr><td>GearMotor</td>:<td><input type=\"text\" name=\"gearmotor\" value=\"";
html_page += String(wheelConfig.nbDentsAxeMoteur) + "\"></td><td>" + String(minNbDentsAxeMoteur) + "-" + String(maxNbDentsAxeMoteur) + "</td></tr>";
html_page += "<tr><td>GearWheel</td>:<td><input type=\"text\" name=\"gearwheel\" value=\"";
html_page += String(wheelConfig.nbDentsAxeRoue) + "\"></td><td>" + String(minNbDentsAxeRoue) + "-" + String(maxNbDentsAxeRoue) + "</td></tr>";
html_page += "</tbody></table><br><input type=\"submit\" value=\"Submit\"><br><br>";
html_page += "</form>";
html_page += "<a href=\"/\">Back</a>";
html_page += "</body></html>";
server.setContentLength(html_page.length()); // Permet l'affichage plus rapide après chaque clic sur les boutons
server.send(200, "text/html", html_page);
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleRespConfigWheel() {
String s_number;
float f_number;
int i_number;
bool configmodif = false;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleRespConfigFocuserEP"));
#endif
#ifdef SMO_DEBUG
for (int i=0; i <= server.args(); i++) {
Serial.println(server.arg(i));
}
#endif
if ( server.hasArg("nbfiltres") && server.arg("nbfiltres") != NULL ) {
s_number = server.arg("nbfiltres");
i_number = s_number.toInt();
if (i_number >= 1 && i_number <= maxFilterSlots) {
#ifdef SMO_PROTOCOL_OPTEC
filterWheelConfig.nbFilterSlots[filterWheelConfig.currentFilterWheel] = i_number;
#else
filterWheelConfig.nbFilterSlots = i_number;
#endif
configmodif = true;
}
}
if ( server.hasArg("maxspeed") && server.arg("maxspeed") != NULL ) {
s_number = server.arg("maxspeed");
i_number = s_number.toInt();
if (i_number >= minStepperMaxSpeed && i_number <= maxStepperMaxSpeed) {
wheelConfig.stepperConfig.stepperMaxSpeed = i_number;
configmodif = true;
}
}
if ( server.hasArg("speed") && server.arg("speed") != NULL ) {
s_number = server.arg("speed");
i_number = s_number.toInt();
if (i_number >= minStepperSpeed && i_number <= maxStepperSpeed) {
wheelConfig.stepperConfig.stepperSpeed = i_number;
configmodif = true;
}
}
if ( server.hasArg("accel") && server.arg("accel") != NULL ) {
s_number = server.arg("accel");
i_number = s_number.toInt();
if (i_number >= minStepperAccel && i_number <= maxStepperAccel) {
wheelConfig.stepperConfig.stepperAccel = i_number;
configmodif = true;
}
}
if ( server.hasArg("steprevolution") && server.arg("steprevolution") != NULL ) {
String s_number = server.arg("steprevolution");
f_number = s_number.toFloat();
if (f_number >= minStepsPerRevolution && f_number <= maxStepsPerRevolution) {
wheelConfig.stepperConfig.stepsPerRevolution = f_number;
configmodif = true;
}
}
if ( server.hasArg("gearmotor") && server.arg("gearmotor") != NULL ) {
s_number = server.arg("gearmotor");
i_number = s_number.toInt();
if (i_number >= minNbDentsAxeMoteur && i_number <= maxNbDentsAxeMoteur ) {
wheelConfig.nbDentsAxeMoteur = i_number;
configmodif = true;
}
}
if ( server.hasArg("gearwheel") && server.arg("gearwheel") != NULL ) {
s_number = server.arg("gearwheel");
i_number = s_number.toInt();
if (i_number >= minNbDentsAxeRoue && i_number <= maxNbDentsAxeRoue) {
wheelConfig.nbDentsAxeRoue = i_number;
configmodif = true;
}
}
if (configmodif) {
ComputeParams();
SauvegardeWheelEEPROM();
}
HandleConfigWheel();
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleSendMessage() {
String html_page;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleSendMessage"));
#endif
// When URI / is requested, send a web page with a button to get the message
html_page = "<!DOCTYPE html><html lang=\"en-us\">";
html_page += "<head><meta charset=\"UTF-8\">";
html_page += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"</head><body>";
html_page += "<h2>Filter Wheel " + String(SMO_PRODUCT) + " " + String(SMO_VERSION) + "<h2><h3>Send Message</h3>";
html_page += "<form name=\"send_message\" action=\"/send_message\" method=\"POST\"><input type=\"text\"";
html_page += "name=\"message\" placeholder=\"Message\"></br><input type=\"submit\" value=\"Submit\">";
html_page += "</form>";
if ( lastInputMessage != NULL ) {
html_page += "<br>Last message : " + lastInputMessage + "<br>";
html_page += "Last result : " + lastOutputMessage + "<br>";
html_page += "<form name=\"refresh\" action=\"/send_message\" method=\"GET\">";
html_page += "<input type=\"submit\" value=\"Refresh\"><br><br>";
html_page += "</form>";
}
html_page += "<br><a href=\"/\">Back</a>";
html_page += helpmessage;
html_page += "</body></html>";
server.setContentLength(html_page.length()); // Permet l'affichage plus rapide après chaque clic sur les boutons
server.send(200, "text/html", html_page);
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleRespSendMessage() {
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleRespSendMessage"));
#endif
if( ! server.hasArg("message") || server.arg("message") == NULL) {
// If the POST request doesn't have data
server.send(400, "text/plain", "400: Invalid Request");
// The request is invalid, so send HTTP status 400
return;
}
incomingMessage = server.arg("message");
lastInputMessage = server.arg("message");
lastOutputMessage = "please refresh, asynchronous message handling...";
wifi_request = true;
HandleSendMessage();
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleManualMove() {
String html_page;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleManualMove"));
#endif
// When URI / is requested, send a web page with a button to get the message
html_page = "<!DOCTYPE html><html lang=\"en-us\">";
html_page += "<head><meta charset=\"UTF-8\">";
html_page += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"</head><body>";
html_page += "<h2>Filter Wheel " + String(SMO_PRODUCT) + " " + String(SMO_VERSION) + "<h2><h3>Manual Move</h3>";
html_page += "Note: filter wheel reset to slot 1 position after a \"valid\" manual move<br>";
html_page += "Note: enter a \"valid\" angle between 360.0 and -360.0 degree<br>";
html_page += "<form action=\"/manual_move\" method=\"POST\"><input type=\"text\"";
html_page += "name=\"angle\" placeholder=\"Angle (deg)\"></br><input type=\"submit\" value=\"Submit\"><br><br>";
html_page += "</form>";
html_page += "<a href=\"/\">Back</a>";
html_page += "</body></html>";
server.setContentLength(html_page.length()); // Permet l'affichage plus rapide après chaque clic sur les boutons
server.send(200, "text/html", html_page);
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleRespManualMove() {
String s_number;
float f_number;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleRespManualMove"));
#endif
#ifdef SMO_DEBUG
for (int i=0; i <= server.args(); i++) {
Serial.println(server.arg(i));
}
#endif
if ( server.hasArg("angle") && server.arg("angle") != NULL ) {
s_number = server.arg("angle");
f_number = s_number.toFloat();
if (f_number >= -360.0 && f_number <= 360.0) {
if (!stepper.isRunning() && stepper.distanceToGo() == 0) {
#ifdef SMO_BACKGROUND_MOVE
/*stepper.moveTo(stepper.currentPosition() + degsToSteps(f_number));
int startTime=millis();
int currentTime;
while (stepper.distanceToGo() != 0) {
stepper.run();
currentTime=millis();
if ((currentTime-startTime)>1000) {
startTime=currentTime;
}
}*/
stepper.moveTo(stepper.currentPosition() + degsToSteps(f_number));
#else
stepper.runToNewPosition(stepper.currentPosition() + degsToSteps(f_number));
#endif
InitStepper();
filterWheelConfig.currentSlot = 0;
filterWheelConfig.targetSlot = 0;
}
}
}
HandleManualMove();
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
String HandleDebugStepper(AccelStepper as) {
String html_page;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleDebugStepper"));
#endif
html_page = "D:maxSpeed:" + String(as.maxSpeed()) + "<br>";
html_page += "D:speed:" + String(as.speed()) + "<br>";
html_page += "D:currentPosition:" + String(as.currentPosition()) + "<br>";
html_page += "D:targetPosition:" + String(as.targetPosition()) + "<br>";
html_page += "D:distanceToGo:" + String(as.distanceToGo()) + "<br><br>";
return html_page;
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
String HandleDebugWheel(wheelConfigStruct wc) {
String html_page;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleDebugWheel"));
#endif
html_page = "D:stepperMaxSpeed:" + String(wc.stepperConfig.stepperMaxSpeed) + "<br>";
html_page += "D:stepperSpeed:" + String(wc.stepperConfig.stepperSpeed) + "<br>";
html_page += "D:stepperAccel:" + String(wc.stepperConfig.stepperAccel) + "<br>";
html_page += "D:stepsPerRevolution:"+ String(wc.stepperConfig.stepsPerRevolution, 2) + "<br>";
html_page += "D:maxPosition:" + String(wc.maxPosition) + "<br>";
html_page += "D:currentPosition:" + String(wc.currentPosition) + "<br>";
html_page += "D:nbDentsAxeMoteur:"+ String(wc.nbDentsAxeMoteur) + "<br>";
html_page += "D:nbDentsAxeRoue:" + String(wc.nbDentsAxeRoue) + "<br>";
html_page += "D:ratioAxe:" + String(wc.ratioAxe, 2) + "<br>";
html_page += "D:degreePerRevolution:" + String(wc.degreePerRevolution, 2) + "<br><br>";
return html_page;
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
String HandleDebugFilterWheel(filterWheelConfigStruct fwc) {
int i, j;
String html_page;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleDebugFilterWheel"));
#endif
html_page = "";
#ifdef SMO_PROTOCOL_OPTEC
html_page += "D:nbFilterSlots:" + String(fwc.nbFilterSlots[fwc.currentFilterWheel]) + "<br>";
html_page += "D:slotsPositions:";
for (i = 0; i < fwc.nbFilterSlots[fwc.currentFilterWheel]; i++) {
html_page += String(fwc.slotsPositions[fwc.currentFilterWheel][i]) + "|";
}
html_page += "<br>";
html_page += "D:slotsOffsets:";
for (i = 0; i < fwc.nbFilterSlots[fwc.currentFilterWheel]; i++) {
html_page += String(fwc.slotsOffsets[fwc.currentFilterWheel][i]) + "|";
}
html_page += "<br>";
html_page += "D:slotsNames:";
for (i = 0; i < fwc.nbFilterSlots[fwc.currentFilterWheel]; i++) {
for (j = 0; j < maxFilterNameSize; j++) {
html_page += String(fwc.slotsNames[fwc.currentFilterWheel][i][j]) + "|";
}
}
html_page += "<br>";
html_page += "D:slotsNames2:";
for (i = 0; i < fwc.nbFilterSlots[fwc.currentFilterWheel]; i++) {
html_page += String(slotsNames[fwc.currentFilterWheel][i])+ "|";
}
html_page += "<br>";
#else
html_page += "D:nbFilterSlots:" + String(fwc.nbFilterSlots) + "<br>";
html_page += "D:slotsPositions:";
for (i = 0; i < fwc.nbFilterSlots; i++) {
html_page += String(fwc.slotsPositions[i]) + "|";
}
html_page += "<br>";
html_page += "D:slotsOffsets:";
for (i = 0; i < fwc.nbFilterSlots; i++) {
html_page += String(fwc.slotsOffsets[i]) + "|";
}
html_page += "<br>";
html_page += "D:slotsNames:";
for (i = 0; i < fwc.nbFilterSlots; i++) {
for (j = 0; j < maxFilterNameSize; j++) {
html_page += String(fwc.slotsNames[i][j]);
}
html_page += "|";
}
html_page += "<br>";
html_page += "D:slotsNames2:";
for (i = 0; i < fwc.nbFilterSlots; i++) {
html_page += String(slotsNames[i]) + "|";
}
html_page += "<br>";
#endif
#ifdef SMO_PROTOCOL_OPTEC
html_page += "D:currentFilterWheel:" + String(fwc.currentFilterWheel) + "<br>";
#endif
html_page += "D:currentSlot:" + String(fwc.currentSlot) + "<br>";
html_page += "D:targetSlot:" + String(fwc.targetSlot) + "<br>";
return html_page;
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
String HandleDebugWifi() {
int i, j;
String html_page;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleDebugWifi"));
#endif
html_page = "";
#ifdef SMO_USE_WIFI_ADHOC
html_page += "D:WiFi created<br>";
html_page += "D:MAC : " + String(WiFi.softAPmacAddress()) + "<br>";
html_page += "D:IP address: " + WiFi.softAPIP().toString() + "<br>";
#endif
#ifdef SMO_USE_WIFI_CLIENT
html_page += "D:WiFi connected<br>";
html_page += "D:MAC : " + String(WiFi.macAddress()) + "<br>";
html_page += "D:IP address: " + WiFi.localIP().toString() + "<br>";
html_page += "D:SSID: " + WiFi.SSID() + "<br><br>";
//html_page += String(WiFi.printDiag());
#endif
return html_page;
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleDebug() {
String html_page;
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleDebug"));
#endif
// When URI / is requested, send a web page with a button to get the message
html_page = "<!DOCTYPE html><html lang=\"en-us\">";
html_page += "<head><meta charset=\"UTF-8\">";
html_page += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"</head><body>";
html_page += "<h2>Filter Wheel " + String(SMO_PRODUCT) + " " + String(SMO_VERSION) + "<h2><h3>Debug</h3>";
html_page += "D:#############################<br>D:## DEBUG WIFI ##<br>D:#############################<br>";
html_page += "D:Debug Wifi<br>";
html_page += HandleDebugWifi();
html_page += "D:#############################<br>D:## DEBUG VAR WHEEL ##<br>D:#############################<br>";
html_page += "D:Debug wheelConfig<br>";
html_page += HandleDebugWheel(wheelConfig);
html_page += "D:#######################<br>D:## DEBUG VAR STEPPER ##<br>D:#######################<br>";
html_page += "D:Debug stepper<br>";
html_page += HandleDebugStepper(stepper);
html_page += "D:###########################<br>D:## DEBUG VAR FILTERWHEEL ##<br>D:###########################<br>";
html_page += "D:Debug filterWheelConfig<br>";
html_page += HandleDebugFilterWheel(filterWheelConfig);
html_page += "D:####################<br>";
html_page += "<br><form action=\"/debug\" method=\"POST\">";
html_page += "<input type=\"submit\" value=\"Refresh\"><br><br>";
html_page += "</form>";
html_page += "<a href=\"/\">Back</a>";
html_page += "</body></html>";
server.setContentLength(html_page.length()); // Permet l'affichage plus rapide après chaque clic sur les boutons
server.send(200, "text/html", html_page);
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleRespDebug() {
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleRespDebug"));
#endif
HandleDebug();
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleUnknownMessage() {
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleUnknownMessage"));
#endif
lastOutputMessage = "message -> " + lastInputMessage + " <- is unknown !";
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleCorrectMessage(String protocolResponse) {
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleCorrectMessage"));
#endif
lastOutputMessage = protocolResponse;
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void HandleNotFound(){
#ifdef SMO_DEBUG
Serial.println(F("DF:HandleNotFound"));
#endif
// Send HTTP status 404 (Not Found) when there's no handler for the URI in the request
server.send(404, "text/plain", "404: Not found");
}
#endif
// =============================================================================
#ifdef SMO_USE_WIFI
void InitWifi(void) {
int count = 3;
#ifdef SMO_DEBUG
Serial.println(F("DF:InitWifi"));
#endif
WiFi.persistent(false);
#if defined(SMO_USE_WIFI_CLIENT) and defined(SMO_USE_WIFI_ADHOC)
WiFi.mode(WIFI_AP_STA);
#elif defined(SMO_USE_WIFI_ADHOC)
WiFi.mode(WIFI_AP);
#elif defined(SMO_USE_WIFI_CLIENT)
WiFi.mode(WIFI_STA);
#endif
#ifdef SMO_USE_WIFI_ADHOC
#ifdef SMO_DEBUG
Serial.println(F("D:Creating Wifi..."));
#endif
WiFi.softAP(SSID_AP,PASSWORD_AP);
#ifdef SMO_DEBUG
Serial.println(F("D:WiFi created"));
Serial.print(F("D:MAC : "));
Serial.println(WiFi.softAPmacAddress());
Serial.print(F("D:IP address: "));
Serial.println(WiFi.softAPIP());
#endif
connected_wifi = true;
#endif
#ifdef SMO_USE_WIFI_CLIENT
// We start by connecting to a WiFi network
wifiMulti.addAP(SSID_1, PASSWORD_1);
#ifdef SSID_2
wifiMulti.addAP(SSID_2, PASSWORD_2);
#endif
#ifdef SSID_3
wifiMulti.addAP(SSID_3, PASSWORD_3);
#endif
#ifdef SMO_DEBUG
Serial.println(F("D:Connecting Wifi..."));
#endif
while ( wifiMulti.run() != WL_CONNECTED && count >= 0) {
delay ( 500 );
count--;
#ifdef SMO_DEBUG
Serial.print ( "." );
#endif
}
if (wifiMulti.run() == WL_CONNECTED) {
#ifdef SMO_DEBUG
Serial.println(F("D:WiFi connected"));
Serial.print(F("D:MAC : "));
Serial.println(WiFi.macAddress());
Serial.print(F("D:IP address: "));
Serial.println(WiFi.localIP());
WiFi.printDiag(Serial);
#endif
connected_wifi = true;
}
#endif
if (MDNS.begin(SMO_HOSTNAME)) { // Start the mDNS responder for esp8266.local
#ifdef SMO_DEBUG
Serial.println(F("D:mDNS responder started"));
#endif
} else {
#ifdef SMO_DEBUG
Serial.println(F("D:Error setting up MDNS responder!"));
#endif
}
// Start Web Server
// Call the 'handleRoot' function when a client requests URI "/"
server.on("/", HTTP_GET, HandleRoot);
server.on("/select_filter", HTTP_GET, HandleSelectFilter);
server.on("/select_filter", HTTP_POST, HandleRespSelectFilter);
server.on("/config_filters", HTTP_GET, HandleConfigFilters);
server.on("/config_filters", HTTP_POST, HandleRespConfigFilters);
server.on("/config_wheel", HTTP_GET, HandleConfigWheel);
server.on("/config_wheel", HTTP_POST, HandleRespConfigWheel);
server.on("/send_message", HTTP_GET, HandleSendMessage);
server.on("/send_message", HTTP_POST, HandleRespSendMessage);
server.on("/manual_move", HTTP_GET, HandleManualMove);
server.on("/manual_move", HTTP_POST, HandleRespManualMove);
server.on("/debug", HTTP_GET, HandleDebug);
server.on("/debug", HTTP_POST, HandleRespDebug);
// When a client requests an unknown URI, call function "HandleNotFound"
server.onNotFound(HandleNotFound);
server.begin();
#ifdef SMO_DEBUG
Serial.println(F("D:HTTP server started"));
#endif
#ifdef SMO_DEBUG
Serial.setDebugOutput(true);
#endif
}
#endif
// =============================================================================
void SendProtocolResponse(String protocolResponse) {
#ifdef SMO_DEBUG
Serial.println(F("DF:SendProtocolResponse"));
#endif
Serial.println(protocolResponse);
#ifdef SMO_USE_WIFI
if (wifi_request) {
HandleCorrectMessage(protocolResponse);
}
#endif
}
// =============================================================================
void FinMessage() {
#ifdef SMO_DEBUG
Serial.println(F("DF:FinMessage"));
#endif
incomingMessage = "";
#ifdef SMO_USE_WIFI
wifi_request = false;
#endif
}
// =============================================================================
//
// Converts degrees to steps
//
// 28BYJ-48 motor has 5.625 degrees per step
// 360 degrees / 5.625 = 64 steps per revolution
//
// Example with degsToSteps(45):
// (64 / 5.625) * 45 = 512 steps
//
float degsToSteps(float deg) {
return (wheelConfig.stepperConfig.stepsPerRevolution / wheelConfig.degreePerRevolution) * deg;
}
// =============================================================================
//
// Converts steps to degrees
//
// 28BYJ-48 motor has 5.625 degrees per step
// 360 degrees / 5.625 = 64 steps per revolution
//
// Example with stepsToDegs(512):
// (5.625 / 64) * 512 = 45 deg
//
#ifdef SMO_USE_ROTATOR
float stepsToDegs(float step) {
return (wheelConfig.degreePerRevolution / wheelConfig.stepperConfig.stepsPerRevolution) * step;
}
#endif
// =============================================================================
void ComputeParams() {
#ifdef SMO_DEBUG
Serial.println(F("DF:ComputeParams"));
#endif
wheelConfig.ratioAxe = (float)wheelConfig.nbDentsAxeRoue / wheelConfig.nbDentsAxeMoteur;
wheelConfig.degreePerRevolution = 360.0 / (wheelConfig.stepperConfig.stepsPerRevolution * wheelConfig.ratioAxe) ;
#ifdef SMO_PROTOCOL_OPTEC
for (int i = 0; i < filterWheelConfig.nbFilterSlots[filterWheelConfig.currentFilterWheel]; i++) {
filterWheelConfig.slotsPositions[filterWheelConfig.currentFilterWheel][i] = ceil(i * (360.0 / filterWheelConfig.nbFilterSlots[filterWheelConfig.currentFilterWheel]));
}
#else
for (int i = 0; i < filterWheelConfig.nbFilterSlots; i++) {
filterWheelConfig.slotsPositions[i] = ceil(i * (360.0 / filterWheelConfig.nbFilterSlots));
}
#endif
}
// =============================================================================
void InitWheelConfig() {
#ifdef SMO_DEBUG
Serial.println(F("DF:InitWheelConfig"));
#endif
wheelConfig.stepperConfig.stepperMaxSpeed = defStepperMaxSpeed;
wheelConfig.stepperConfig.stepperSpeed = defStepperSpeed;
wheelConfig.stepperConfig.stepperAccel = defStepperAccel;
wheelConfig.stepperConfig.stepsPerRevolution = defStepsPerRevolution;
wheelConfig.maxPosition = defStepperMaxPos;
wheelConfig.currentPosition = 0;
wheelConfig.maxAngle = defStepperMaxAngle;
wheelConfig.currentAngle = 0;
wheelConfig.nbDentsAxeMoteur = defNbDentsAxeMoteur;
wheelConfig.nbDentsAxeRoue = defNbDentsAxeRoue;
}
// =============================================================================
void InitSlotsNamesConfig() {
#ifdef SMO_DEBUG
Serial.println(F("DF:InitSlotsNamesConfig"));
#endif
#if defined(SMO_PROTOCOL_OPTEC)
filterWheelConfig.nbFilterWhells = maxFilterWheels;
for (int j = 0; j < maxFilterWheels; j++) {
filterWheelConfig.nbFilterSlots[j] = maxFilterSlots;
for (int i = 0 ; i < maxFilterSlots; i++) {
for ( int k = 0 ; k < maxFilterNameSize; k++) {
filterWheelConfig.slotsNames[j][i][k] = ' ';
}
}
}
#else
filterWheelConfig.nbFilterSlots = maxFilterSlots;
for ( int i = 0 ; i < maxFilterSlots; i++) {
for ( int k = 0 ; k < maxFilterNameSize; k++) {
filterWheelConfig.slotsNames[i][k] = ' ';
}
}
#endif
}
// =============================================================================
void InitSlotsPositionsConfig() {
#ifdef SMO_DEBUG
Serial.println(F("DF:InitSlotsPositionsConfig"));
#endif
#ifdef SMO_PROTOCOL_OPTEC
for (int j = 0; j < maxFilterWheels; j++) {
for (int i = 0; i < maxFilterSlots; i++) {
filterWheelConfig.slotsPositions[j][i] = ceil(i * (360.0 / maxFilterSlots));
}
}
#else
for (int i = 0; i < maxFilterSlots; i++) {
filterWheelConfig.slotsPositions[i] = ceil(i * (360.0 / maxFilterSlots));
}
#endif
}
// =============================================================================
void InitSlotsOffsetsConfig() {
#ifdef SMO_DEBUG
Serial.println(F("DF:InitSlotsOffsetsConfig"));
#endif
#ifdef SMO_PROTOCOL_OPTEC
for (int j = 0; j < maxFilterWheels; j++) {
for (int i = 0; i < maxFilterSlots; i++) {
filterWheelConfig.slotsOffsets[j][i] = 0;
}
}
#else
for (int i = 0; i < maxFilterSlots; i++) {
filterWheelConfig.slotsOffsets[i] = 0;
}
#endif
}
// =============================================================================
void CopyFromSlotsNamesConfig() {
#ifdef SMO_DEBUG
Serial.println(F("DF:CopyFromSlotsNamesConfig"));
#endif
#ifdef SMO_DEBUG
DebugVar();
#endif
#if defined(SMO_PROTOCOL_OPTEC)
for (int j = 0; j < maxFilterWheels; j++) {
for (int i = 0 ; i < maxFilterSlots; i++) {
slotsNames[j][i] = " ";
for ( int k = 0 ; k < maxFilterNameSize; k++) {
slotsNames[j][i].setCharAt(k, filterWheelConfig.slotsNames[j][i][k]);
}
slotsNames[j][i].trim();
}
}
#else
for ( int i = 0 ; i < maxFilterSlots; i++) {
slotsNames[i] = " ";
for ( int k = 0 ; k < maxFilterNameSize; k++) {
slotsNames[i].setCharAt(k, filterWheelConfig.slotsNames[i][k]);
}
slotsNames[i].trim();
}
#endif
#ifdef SMO_DEBUG
DebugVar();
#endif
}
// =============================================================================
void CopyToSlotsNamesConfig() {
#ifdef SMO_DEBUG
Serial.println(F("DF:CopyToSlotsNamesConfig"));
#endif
#ifdef SMO_DEBUG
DebugVar();
#endif
#if defined(SMO_PROTOCOL_OPTEC)
for (int j = 0; j < maxFilterWheels; j++) {
for (int i = 0 ; i < maxFilterSlots; i++) {
slotsNames[j][i].toCharArray(filterWheelConfig.slotsNames[j][i], slotsNames[j][i].length() + 1);
for (int k = slotsNames[j][i].length(); k < maxFilterNameSize; k++) {
filterWheelConfig.slotsNames[j][i][k] = ' ';
}
}
}
#else
for ( int i = 0 ; i < maxFilterSlots; i++) {
slotsNames[i].toCharArray(filterWheelConfig.slotsNames[i], slotsNames[i].length() + 1);
for (int k = slotsNames[i].length(); k < maxFilterNameSize; k++) {
filterWheelConfig.slotsNames[i][k] = ' ';
}
}
#endif
#ifdef SMO_DEBUG
DebugVar();
#endif
}
// =============================================================================
void InitStepper() {
#ifdef SMO_DEBUG
Serial.println(F("DF:InitStepper"));
#endif
stepper.setMaxSpeed(wheelConfig.stepperConfig.stepperMaxSpeed); // set the max motor speed
stepper.setAcceleration(wheelConfig.stepperConfig.stepperAccel); // set the acceleration
stepper.setSpeed(wheelConfig.stepperConfig.stepperSpeed); // set the current speed
stepper.setCurrentPosition(0); // set the current step
}
// =============================================================================
void UpdateStepper() {
#ifdef SMO_DEBUG
Serial.println(F("DF:UpdateStepper"));
#endif
stepper.setMaxSpeed(wheelConfig.stepperConfig.stepperMaxSpeed); // set the max motor speed
stepper.setAcceleration(wheelConfig.stepperConfig.stepperAccel); // set the acceleration
stepper.setSpeed(wheelConfig.stepperConfig.stepperSpeed); // set the current speed
}
// =============================================================================
// Sauvegarde en mémoire EEPROM le contenu actuel de la structure wheelConfig
void SauvegardeWheelEEPROM() {
#ifdef SMO_DEBUG
Serial.println(F("DF:SauvegardeWheelEEPROM"));
#endif
// Met à jour le nombre magic avant l'écriture
wheelConfig.smo = SMO1;
EEPROM.begin(eepromSize);
EEPROM.put(eepromStepperAddress, wheelConfig);
EEPROM.commit();
EEPROM.end();
}
// =============================================================================
// Sauvegarde en mémoire EEPROM le contenu actuel de la structure filterWheelConfig
void SauvegardeFilterWheelEEPROM() {
#ifdef SMO_DEBUG
Serial.println(F("DF:SauvegardeFilterWheelEEPROM"));
#endif
// Met à jour le nombre magic avant l'écriture
filterWheelConfig.smo = SMO2;
EEPROM.begin(eepromSize);
EEPROM.put(eepromWheelAddress, filterWheelConfig);
EEPROM.commit();
EEPROM.end();
}
// =============================================================================
// Init les structures Config et ecrit le contenu de la mémoire EEPROM
void InitWheelEEPROM() {
#ifdef SMO_DEBUG
Serial.println(F("DF:InitWheelEEPROM"));
#endif
// Valeurs par défaut pour les variables de config
InitWheelConfig();
// Sauvegarde les nouvelles données
SauvegardeWheelEEPROM();
}
// =============================================================================
// Init les structures Config et ecrit le contenu de la mémoire EEPROM
void InitFilterWheelEEPROM() {
#ifdef SMO_DEBUG
Serial.println(F("DF:InitConfigEEPROM"));
#endif
// Valeurs par défaut pour les variables de config
InitSlotsPositionsConfig();
InitSlotsOffsetsConfig();
InitSlotsNamesConfig();
// Sauvegarde les nouvelles données
SauvegardeFilterWheelEEPROM();
}
// =============================================================================
// Charge le contenu de la mémoire EEPROM dans la structure wheelConfig
void ChargeWheelEEPROM() {
#ifdef SMO_DEBUG
Serial.println(F("DF:chargeWheelEEPROM"));
#endif
// charge eepromSize octet memoire eeprom en RAM
EEPROM.begin(eepromSize);
#ifdef SMO_DEBUG
Serial.println(String(F("D:Taille eeprom ")) + String(EEPROM.length()));
#endif
// Lit la mémoire EEPROM
EEPROM.get(eepromStepperAddress,wheelConfig);
EEPROM.end();
#ifdef SMO_DEBUG
Serial.println(String(F("D:Valeur lu de magic : ")) + String(wheelConfig.smo));
#endif
// Détection d'une mémoire non initialisée
bool erreur = wheelConfig.smo != SMO1;
if (erreur) {
#ifdef SMO_DEBUG
Serial.println(F("D:Erreur fichier config non initialisé"));
#endif
InitWheelEEPROM();
}
#ifdef SMO_DEBUG
else Serial.println(F("D:Config ok"));
#endif
}
// =============================================================================
// Charge le contenu de la mémoire EEPROM dans la structure filterWheelConfig
void ChargeFilterWheelEEPROM() {
#ifdef SMO_DEBUG
Serial.println(F("DF:chargeFilterWheelEEPROM"));
#endif
// charge eepromSize octet memoire eeprom en RAM
EEPROM.begin(eepromSize);
#ifdef SMO_DEBUG
Serial.println(String(F("D:Taille eeprom ")) + String(EEPROM.length()));
#endif
// Lit la mémoire EEPROM
EEPROM.get(eepromWheelAddress, filterWheelConfig);
EEPROM.end();
#ifdef SMO_DEBUG
Serial.println(String(F("D:Valeur lu de magic : ")) + String(filterWheelConfig.smo));
#endif
// Détection d'une mémoire non initialisée
bool erreur = filterWheelConfig.smo != SMO2;
if (erreur) {
#ifdef SMO_DEBUG
Serial.println(F("D:Erreur fichier config non initialisé"));
#endif
InitFilterWheelEEPROM();
}
CopyFromSlotsNamesConfig();
#ifdef SMO_DEBUG
Serial.println(F("D:Config ok"));
#endif
}
//
// =============================================================================
// FUNCTIONS (specific SMO_PROTOCOL_PERSO)
// =============================================================================
//
// =============================================================================
//
// SMO_PROTOCOL pour Roue a Filtre Perso
//
// WE --> IE Wheel Filter Entering Serial Mode
// WX --> IX Wheel Filter eXiting Serial Mode
// WI --> II Wheel Init, set slot 1 and step 0
// WR --> IR Wheel Reset, move to 1 and set step 0
// WD --> ID Wheel Dump, Debug Dump
// WFSG --> IFSx Wheel Filter Slots Get, get slots amount 1-9 (int)
// WFSSx --> IFSx Wheel Filter Slots Set, set slots amount 1-9 (int)
// WFPG --> IFPx Wheel Filter Pos Get, get slot position 1-9 (int)
// WFPSx --> IFPx Wheel Filter Pos Set, slot number to go 1-9 (int)
// WFPS+ --> IFPx Wheel Filter Pos Set Next slot 1-9 (int)
// WFPS- --> IFPx Wheel Filter Pos Set Previous slot 1-9 (int)
// WFNGx --> IFNxy Wheel Filter Name Get, x=1-9, y=name (max 8 char)
// WFNSxy --> IFNxy Wheel Filter Name Set, x=1-9, y=newname (max 8 char)
// WFOGx --> IFOxy Wheel Filter Offset Get, x=1-9, y=value 1-1000 (int)
// WFOSxy --> IFOxy Wheel Filter Offset Set, x=1-9, y=newvalue 1-1000 (int)
// WMSG --> IMSxxxx Wheel Motor Step Get, get motor step position
// WMSS+ --> IMSxxxx Wheel Motor Step Set +10 step (calibration move)
// WMSS- --> IMSxxxx Wheel Motor Step Set -10 step (calibration move)
// WMSS> --> IMSxxxx Wheel Motor Step Set +100 step (calibration move)
// WMSS< --> IMSxxxx Wheel Motor Step Set -100 step (calibration move)
// WPGx --> IPxy Wheel Param Get, param=x value=y
// WPSxy --> IPxy Wheel Param Set, param=x value=y, Modif params
// param=MS MaxSpeed 100-2000 (int) default=1000
// param=CS CurrentSpeed 100-2000 (int) default=500
// param=CA CurrentAccel 100-1000 (int) default=200
// param=SR StepPerRevolutiion 1.00-100.00 (float) default=64
// param=GM GearMotor tooth 10-100 (int) default=20
// param=GR GearWheel tooth 50-500 (int) default=100
//
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_ConnexionWheel(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_ConnexionWheel"));
#endif
if (msg.startsWith("WE")) {
connected = true;
SendProtocolResponse("IE");
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_DeconnexionWheel(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_DeconnexionWheel"));
#endif
if (msg.startsWith("WX")) {
connected = false;
SendProtocolResponse("IX");
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_GetNbFilters (String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_GetNbFilters"));
#endif
if (msg.startsWith("WFSG")) {
SendProtocolResponse("IFS" + String(filterWheelConfig.nbFilterSlots));
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_SetNbFilters (String msg) {
String s_number;
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_SetNbFilters"));
#endif
if (msg.startsWith("WFSS")) {
s_number = msg.substring(4, 5);
number = s_number.toInt();
if (number >= 1 && number <= maxFilterSlots) {
filterWheelConfig.nbFilterSlots = number;
ComputeParams();
SauvegardeFilterWheelEEPROM();
SendProtocolResponse("IFS" + String(filterWheelConfig.nbFilterSlots));
}
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_GetFilterPosition(String msg) {
String s_number;
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_GetFilterPosition"));
#endif
if (msg.startsWith("WFPG")) {
SendProtocolResponse("IFP" + String(filterWheelConfig.currentSlot + 1));
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_GoToFilterPosition(String msg) {
int number = 0;
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_GoToFilterPosition"));
#endif
if (msg.startsWith("WFPS")) {
if (msg.charAt(4) == '+') {
number = (filterWheelConfig.currentSlot + 1 + filterWheelConfig.nbFilterSlots) % (filterWheelConfig.nbFilterSlots);
}
else if (msg.charAt(4) == '-') {
number = (filterWheelConfig.currentSlot - 1 + filterWheelConfig.nbFilterSlots) % (filterWheelConfig.nbFilterSlots);
}
else {
msg.remove(0, 4);
// on recoit une valeur entre 1 et 9, on veut un indice tableau entre 0 et 8
number = msg.toInt() - 1;
}
if (number >= 0 && number <= (filterWheelConfig.nbFilterSlots - 1) && number != filterWheelConfig.currentSlot && !stepper.isRunning() && stepper.distanceToGo() == 0) {
filterWheelConfig.targetSlot = number;
#ifdef SMO_BACKGROUND_MOVE
stepper.moveTo(degsToSteps(filterWheelConfig.slotsPositions[filterWheelConfig.targetSlot]));
int startTime=millis();
int currentTime;
while (stepper.distanceToGo() != 0) {
stepper.run();
currentTime=millis();
if ((currentTime-startTime)>1000) {
startTime=currentTime;
SendProtocolResponse(".");
}
}
#else
stepper.runToNewPosition(degsToSteps(filterWheelConfig.slotsPositions[filterWheelConfig.targetSlot]));
#endif
filterWheelConfig.currentSlot = filterWheelConfig.targetSlot;
SendProtocolResponse("IFP" + String(filterWheelConfig.currentSlot + 1));
}
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_GetFilterName(String msg) {
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_GetFilterName"));
#endif
if (msg.startsWith("WFNG")) {
msg.remove(0, 4);
number = msg.toInt() - 1;
if (number >= 0 && number <= (filterWheelConfig.nbFilterSlots - 1)) {
SendProtocolResponse("IFN" + String(number + 1) + String(slotsNames[number]));
}
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_SetFilterName(String msg) {
String s_number;
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_SetFilterName"));
#endif
if (msg.startsWith("WFNS")) {
s_number = msg.substring(4, 5);
number = s_number.toInt() - 1;
if (number >= 0 && number <= (filterWheelConfig.nbFilterSlots - 1)) {
msg.remove(0, 5);
slotsNames[number] = msg;
CopyToSlotsNamesConfig();
SauvegardeFilterWheelEEPROM();
SendProtocolResponse("IFN" + String(number + 1) + String(slotsNames[number]));
}
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_GetFilterOffset(String msg) {
String s_number;
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_GetFilterOffset"));
#endif
if (msg.startsWith("WFOG")) {
s_number = msg.substring(4, 5);
number = s_number.toInt() - 1;
if (number >= 0 && number <= (filterWheelConfig.nbFilterSlots - 1)) {
SendProtocolResponse("IFO" + String(number + 1) + String(filterWheelConfig.slotsOffsets[number]));
}
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_SetFilterOffset(String msg) {
String s_number;
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_SetFilterOffset"));
#endif
if (msg.startsWith("WFOS")) {
s_number = msg.substring(4, 5);
number = s_number.toInt() - 1;
if (number >= 0 && number <= (filterWheelConfig.nbFilterSlots - 1)) {
msg.remove(0, 5);
filterWheelConfig.slotsOffsets[number] = msg.toInt();
SauvegardeFilterWheelEEPROM();
SendProtocolResponse("IFO" + String(number + 1) + String(filterWheelConfig.slotsOffsets[number]));
}
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_GetMotorStep(String msg) {
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_GetMotorStep"));
#endif
if (msg.startsWith("WMSG")) {
SendProtocolResponse("IMS" + String(stepper.currentPosition()));
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_SetMotorStep(String msg) {
String s_number;
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_SetMotorStep"));
#endif
if (msg.startsWith("WMSS")) {
if (msg.charAt(4) == '+') {
if (!stepper.isRunning() && stepper.distanceToGo() == 0) {
#ifdef SMO_BACKGROUND_MOVE
stepper.move(10);
#else
stepper.runToNewPosition(stepper.currentPosition() + 10);
#endif
}
}
else if (msg.charAt(4) == '-') {
if (!stepper.isRunning() && stepper.distanceToGo() == 0) {
#ifdef SMO_BACKGROUND_MOVE
stepper.move(-10);
#else
stepper.runToNewPosition(stepper.currentPosition() - 10);
#endif
}
}
else if (msg.charAt(4) == '>') {
if (!stepper.isRunning() && stepper.distanceToGo() == 0) {
#ifdef SMO_BACKGROUND_MOVE
stepper.move(100);
#else
stepper.runToNewPosition(stepper.currentPosition() + 100);
#endif
}
}
else if (msg.charAt(4) == '<') {
if (!stepper.isRunning() && stepper.distanceToGo() == 0) {
#ifdef SMO_BACKGROUND_MOVE
stepper.move(-100);
#else
stepper.runToNewPosition(stepper.currentPosition() - 100);
#endif
}
}
SendProtocolResponse("IMS" + String(stepper.currentPosition()));
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_InitWheel(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_InitWheel"));
#endif
if (msg.startsWith("WI")) {
InitStepper();
filterWheelConfig.currentSlot = 0;
SendProtocolResponse("II");
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_ResetWheel(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_ResetWheel"));
#endif
if (msg.startsWith("WR")) {
if (!stepper.isRunning() && stepper.distanceToGo() == 0) {
#ifdef SMO_BACKGROUND_MOVE
stepper.moveTo(0);
int startTime=millis();
int currentTime;
while (stepper.distanceToGo() != 0) {
stepper.run();
currentTime=millis();
if ((currentTime-startTime)>1000) {
startTime=currentTime;
SendProtocolResponse(".");
}
}
#else
stepper.runToNewPosition(0);
#endif
}
InitStepper();
filterWheelConfig.currentSlot = 0;
SendProtocolResponse("IR");
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_DumpWheel(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_DumpWheel"));
#endif
if (msg.startsWith("WD")) {
#ifdef SMO_DEBUG
DebugWifi();
DebugVar();
#endif
SendProtocolResponse("ID");
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_GetParamWheel(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_GetParamWheel"));
#endif
if (msg.startsWith("WPG") && msg.length() >= 5) {
if (msg.substring(3, 5) == "MS") {
SendProtocolResponse("IPMS" + String(wheelConfig.stepperConfig.stepperMaxSpeed));
}
else if (msg.substring(3, 5) == "CS") {
SendProtocolResponse("IPCS" + String(wheelConfig.stepperConfig.stepperSpeed));
}
else if (msg.substring(3, 5) == "CA") {
SendProtocolResponse("IPCA" + String(wheelConfig.stepperConfig.stepperAccel));
}
else if (msg.substring(3, 5) == "SR") {
SendProtocolResponse("IPSR" + String(wheelConfig.stepperConfig.stepsPerRevolution));
}
else if (msg.substring(3, 5) == "GM") {
SendProtocolResponse("IPGM" + String(wheelConfig.nbDentsAxeMoteur));
}
else if (msg.substring(3, 5) == "GR") {
SendProtocolResponse("IPGR" + String(wheelConfig.nbDentsAxeRoue));
}
else if (msg.substring(3, 5) == "SN") {
SendProtocolResponse("IPSN" + String(filterWheelConfig.nbFilterSlots));
}
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void Perso_SetParamWheel(String msg) {
String s_number;
float f_number;
int i_number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Perso_SetParamWheel"));
#endif
if (msg.startsWith("WPS") && msg.length() >= 6) {
s_number = msg.substring(5,msg.length());
f_number = s_number.toFloat();
if (msg.substring(3, 5) == "MS" && f_number >= minStepperMaxSpeed && f_number <= maxStepperMaxSpeed) {
wheelConfig.stepperConfig.stepperMaxSpeed = (int)f_number;
SendProtocolResponse("IPMS" + String(wheelConfig.stepperConfig.stepperMaxSpeed));
}
else if (msg.substring(3, 5) == "CS" && f_number >= minStepperSpeed && f_number <= maxStepperSpeed) {
wheelConfig.stepperConfig.stepperSpeed = (int)f_number;
SendProtocolResponse("IPCS" + String(wheelConfig.stepperConfig.stepperSpeed));
}
else if (msg.substring(3, 5) == "CA" && f_number >= minStepperAccel && f_number <= maxStepperAccel) {
wheelConfig.stepperConfig.stepperAccel = (int)f_number;
SendProtocolResponse("IPCA" + String(wheelConfig.stepperConfig.stepperAccel));
}
else if (msg.substring(3, 5) == "SR" && f_number >= minStepsPerRevolution && f_number <= maxStepsPerRevolution) {
wheelConfig.stepperConfig.stepsPerRevolution = f_number;
SendProtocolResponse("IPSR" + String(wheelConfig.stepperConfig.stepsPerRevolution));
}
else if (msg.substring(3, 5) == "GM"&& f_number >= minNbDentsAxeMoteur && f_number <= maxNbDentsAxeMoteur ) {
wheelConfig.nbDentsAxeMoteur = (int)f_number;
SendProtocolResponse("IPGM" + String(wheelConfig.nbDentsAxeMoteur));
}
else if (msg.substring(3, 5) == "GR" && f_number >= minNbDentsAxeRoue && f_number <= maxNbDentsAxeRoue) {
wheelConfig.nbDentsAxeRoue = (int)f_number;
SendProtocolResponse("IPGR" + String(wheelConfig.nbDentsAxeRoue));
}
ComputeParams();
UpdateStepper();
SauvegardeWheelEEPROM();
#ifdef SMO_DEBUG
DebugVar();
#endif
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void setup() {
Serial.begin(SERIAL_BAUD); // initialise the serial monitor
Serial.flush();
delay(1000);
ChargeWheelEEPROM();
ChargeFilterWheelEEPROM();
filterWheelConfig.currentSlot = 0;
ComputeParams();
Perso_InitWheel("WI");
#ifdef SMO_USE_WIFI
InitWifi();
#endif
#if defined(SMO_USE_WIFI) and defined(SMO_USE_WIFI_OTA)
InitOTA();
#endif
while (!Serial) {
// wait for serial port to connect. Needed for native USB
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_PERSO
void loop() {
#if defined(SMO_USE_WIFI) and defined(SMO_USE_WIFI_OTA)
ArduinoOTA.handle();
#endif
#ifdef SMO_USE_WIFI
server.handleClient();
if (wifi_request) {
#ifdef SMO_DEBUG
Serial.print(F("D:incomingMessage(wifi): "));
Serial.println(incomingMessage);
#endif
}
#endif
if (Serial.available() > 0) {
Serial.setTimeout(SERIAL_TIMEOUT);
incomingMessage = Serial.readStringUntil('\n');
#ifdef SMO_DEBUG
Serial.print(F("D:incomingMessage: "));
Serial.println(incomingMessage);
#endif
}
else {
if (incomingMessage.startsWith("WE")) {
Perso_ConnexionWheel(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WX")) {
Perso_DeconnexionWheel(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WI")) {
Perso_InitWheel(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WR")) {
Perso_ResetWheel(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WD")) {
Perso_DumpWheel(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WFSG")) {
Perso_GetNbFilters(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WFSS")) {
Perso_SetNbFilters(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WFPG")) {
Perso_GetFilterPosition(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WFPS")) {
Perso_GoToFilterPosition(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WFNG")) {
Perso_GetFilterName(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WFNS")) {
Perso_SetFilterName(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WFOG")) {
Perso_GetFilterOffset(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WFOS")) {
Perso_SetFilterOffset(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WMSG")) {
Perso_GetMotorStep(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WMSS")) {
Perso_SetMotorStep(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WPG")) {
Perso_GetParamWheel(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WPS")) {
Perso_SetParamWheel(incomingMessage);
FinMessage();
}
#ifdef SMO_USE_WIFI
else if (wifi_request) {
HandleUnknownMessage();
FinMessage();
}
#endif
else if (incomingMessage.length() != 0) {
FinMessage();
}
}
stepper.run();
}
#endif
//
// =============================================================================
// FUNCTIONS (specific SMO_PROTOCOL_QUANTUM)
// =============================================================================
//
// =============================================================================
//
// Quantum SMO_PROTOCOL
//
// Get number of filter positions EN N<number>
// Disconnect DS
// Go to filter position G<number>
// position is returned when the move finishes P<number>
// get filter name F<number> F<number><name>
// set filter name f<number><name>
// Get filter offset O<number> O<number><offset>
// set filter offset o<number><offset>
// Get description SN SN<details>
// get version VR VR<details>
//
// =============================================================================
#ifdef SMO_PROTOCOL_QUANTUM
void Quantum_GetNbFilters (String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Quantum_GetNbFilters"));
#endif
if (msg.startsWith("EN")) {
SendProtocolResponse("N" + String(filterWheelConfig.nbFilterSlots));
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_QUANTUM
void Quantum_Disconnect (String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Quantum_Disconnect"));
#endif
if (msg.startsWith("DS")) {
connected = false;
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_QUANTUM
void Quantum_GoToFilterPosition(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Quantum_GoToFilterPosition"));
#endif
if (msg.startsWith("G")) {
msg.remove(0, 1);
filterWheelConfig.targetSlot = msg.toInt();
if (!stepper.isRunning() && stepper.distanceToGo() == 0) {
//SendProtocolResponse("P" + String(filterWheelConfig.targetSlot));
#ifdef SMO_BACKGROUND_MOVE
stepper.moveTo(degsToSteps(filterWheelConfig.slotsPositions[filterWheelConfig.targetSlot]));
int startTime=millis();
int currentTime;
while (stepper.distanceToGo() != 0) {
stepper.run();
currentTime=millis();
if ((currentTime-startTime)>1000) {
startTime=currentTime;
SendProtocolResponse("M" + String(filterWheelConfig.targetSlot));
}
}
#else
stepper.runToNewPosition(degsToSteps(filterWheelConfig.slotsPositions[filterWheelConfig.targetSlot]));
#endif
SendProtocolResponse("P" + String(filterWheelConfig.targetSlot));
filterWheelConfig.currentSlot = filterWheelConfig.targetSlot;
}
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_QUANTUM
void Quantum_GetFilterName(String msg) {
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Quantum_GetFilterName"));
#endif
if (msg.startsWith("F")) {
msg.remove(0, 1);
number = msg.toInt();
SendProtocolResponse("F" + String(number) + String(slotsNames[number]));
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_QUANTUM
void Quantum_SetFilterName(String msg) {
String s_number;
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Quantum_SetFilterName"));
#endif
if (msg.startsWith("f")) {
s_number = msg.substring(1, 2);
number = s_number.toInt();
msg.remove(0, 2);
slotsNames[number] = msg;
CopyToSlotsNamesConfig();
SauvegardeFilterWheelEEPROM();
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_QUANTUM
void Quantum_GetFilterOffset(String msg) {
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Quantum_GetFilterOffset"));
#endif
if (msg.startsWith("O")) {
msg.remove(0, 1);
number = msg.toInt();
SendProtocolResponse("O" + String(number) + String(filterWheelConfig.slotsOffsets[number]));
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_QUANTUM
void Quantum_SetFilterOffset(String msg) {
String s_number;
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Quantum_SetFilterOffset"));
#endif
if (msg.startsWith("o")) {
s_number = msg.substring(1, 2);
number = s_number.toInt();
msg.remove(0, 2);
filterWheelConfig.slotsOffsets[number] = msg.toInt();
SauvegardeFilterWheelEEPROM();
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_QUANTUM
void Quantum_GetDescription(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Quantum_GetDescription"));
#endif
if (msg.startsWith("SN")) {
SendProtocolResponse(msg + String(SMO_PRODUCT));
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_QUANTUM
void Quantum_GetVersion(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Quantum_GetVersion"));
#endif
if (msg.startsWith("VR")) {
SendProtocolResponse(msg + String(SMO_VERSION));
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_QUANTUM
void setup() {
Serial.begin(SERIAL_BAUD); // initialise the serial monitor
Serial.flush();
delay(1000);
ChargeWheelEEPROM();
ChargeFilterWheelEEPROM();
filterWheelConfig.currentSlot = 0;
ComputeParams();
InitStepper();
incomingMessage = "";
#ifdef SMO_USE_WIFI
InitWifi();
#endif
#if defined(SMO_USE_WIFI) and defined(SMO_USE_WIFI_OTA)
InitOTA();
#endif
while (!Serial) {
// wait for serial port to connect. Needed for native USB
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_QUANTUM
void loop() {
#if defined(SMO_USE_WIFI) and defined(SMO_USE_WIFI_OTA)
ArduinoOTA.handle();
#endif
#ifdef SMO_USE_WIFI
server.handleClient();
if (wifi_request) {
#ifdef SMO_DEBUG
Serial.print(F("D:incomingMessage(wifi): "));
Serial.println(incomingMessage);
#endif
}
#endif
if (Serial.available() > 0) {
Serial.setTimeout(SERIAL_TIMEOUT);
incomingMessage = Serial.readStringUntil('\n');
#ifdef SMO_DEBUG
Serial.print(F("D:incomingMessage: "));
Serial.println(incomingMessage);
#endif
}
else {
if (incomingMessage.startsWith("EN")) {
Quantum_GetNbFilters(incomingMessage);
FinMessage();
}
else if (incomingMessage.startsWith("DS")) {
Quantum_Disconnect(incomingMessage);
FinMessage();
}
else if (incomingMessage.startsWith("G")) {
Quantum_GoToFilterPosition(incomingMessage);
FinMessage();
}
else if (incomingMessage.startsWith("F")) {
Quantum_GetFilterName(incomingMessage);
FinMessage();
}
else if (incomingMessage.startsWith("f")) {
Quantum_SetFilterName(incomingMessage);
FinMessage();
}
else if (incomingMessage.startsWith("O")) {
Quantum_GetFilterOffset(incomingMessage);
FinMessage();
}
else if (incomingMessage.startsWith("o")) {
Quantum_SetFilterOffset(incomingMessage);
FinMessage();
}
else if (incomingMessage.startsWith("SN")) {
Quantum_GetDescription(incomingMessage);
FinMessage();
}
else if (incomingMessage.startsWith("VR")) {
Quantum_GetVersion(incomingMessage);
FinMessage();
}
#ifdef SMO_USE_WIFI
else if (wifi_request) {
HandleUnknownMessage();
FinMessage();
}
#endif
else if (incomingMessage.length() != 0) {
FinMessage();
}
}
stepper.run();
}
#endif
//
// =============================================================================
// FUNCTIONS (specific SMO_PROTOCOL_OPTEC)
// =============================================================================
//
// =============================================================================
// SMO_PROTOCOLE pour Roue a Filtre Optec
//
// WSMODE --> !
// WVAAAA --> V= 2.04
// WHOME --> A, B, C, D, E ou F, G, H
// WIDENT --> A, B, C, D, E ou F, G, H
// WFILTR --> x (1 à 5 ou 1 à 8)
// WGOTOx --> *
// WREAD --> n1..40 ou n64 (chaine de 40 ou 64 caracteres)
// WLOADy*n1..n40 ou n64 --> !
// WEXITS --> END
//
// =============================================================================
#ifdef SMO_PROTOCOL_OPTEC
void Optec_StartSerialMode(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Optec_StartSerialMode"));
#endif
if (msg.startsWith("WSMODE")) {
connected = true;
SendProtocolResponse("!");
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_OPTEC
void Optec_GetFirmware(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Optec_StartSerialMode"));
#endif
if (msg.startsWith("WVAAAA")) {
SendProtocolResponse("V= 2.04");
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_OPTEC
void Optec_WheelHome(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Optec_StartSerialMode"));
#endif
if (msg.startsWith("WHOME")) {
filterWheelConfig.currentSlot = 0;
//todo: identify filterwheel, and load filternames for current wheel from eeprom
SendProtocolResponse(String(filterWheelsNames[filterWheelConfig.currentFilterWheel]));
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_OPTEC
void Optec_WheelIdent(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Optec_StartSerialMode"));
#endif
if (msg.startsWith("WIDENT")) {
SendProtocolResponse(String(filterWheelsNames[filterWheelConfig.currentFilterWheel]));
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_OPTEC
void Optec_GetFilterPos(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Optec_GetFilterPos"));
#endif
if (msg.startsWith("WFILTR")) {
SendProtocolResponse(String(filterWheelConfig.currentSlot + 1));
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_OPTEC
void Optec_GoToFilterPosition(String msg) {
int number;
#ifdef SMO_DEBUG
Serial.println(F("DF:Optec_GoToFilterPosition"));
#endif
if (msg.startsWith("WGOTO")) {
msg.remove(0, 5);
filterWheelConfig.targetSlot = msg.toInt() - 1;
if (!stepper.isRunning() && stepper.distanceToGo() == 0) {
#ifdef SMO_BACKGROUND_MOVE
stepper.moveTo(degsToSteps(filterWheelConfig.slotsPositions[filterWheelConfig.currentFilterWheel][filterWheelConfig.targetSlot]));
int startTime=millis();
int currentTime;
while (stepper.distanceToGo() != 0) {
stepper.run();
currentTime=millis();
if ((currentTime-startTime)>1000) {
startTime=currentTime;
SendProtocolResponse(".");
}
}
#else
stepper.runToNewPosition(degsToSteps(filterWheelConfig.slotsPositions[filterWheelConfig.currentFilterWheel][filterWheelConfig.targetSlot]));
#endif
filterWheelConfig.currentSlot = filterWheelConfig.targetSlot;
}
SendProtocolResponse("*");
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_OPTEC
void Optec_GetFilterNames(String msg) {
String resp = "";
#ifdef SMO_DEBUG
Serial.println(F("DF:Optec_GetFilterNames"));
#endif
if (msg.startsWith("WREAD")) {
for (int i = 0; i < filterWheelConfig.nbFilterSlots[filterWheelConfig.currentFilterWheel]; i++) {
resp.concat(slotsNames[filterWheelConfig.currentFilterWheel][i]);
for (int j = slotsNames[filterWheelConfig.currentFilterWheel][i].length(); j < maxFilterNameSize; j++) {
resp.concat(" ");
}
}
SendProtocolResponse(resp);
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_OPTEC
void Optec_SetFilterNames(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Optec_SetFilterNames"));
#endif
int indice = 0;
if (msg.startsWith("WLOAD")) {
indice = msg.charAt(5) - 'A';
for (int i = 0; i < filterWheelConfig.nbFilterSlots[indice]; i++) {
slotsNames[indice][i] = msg.substring(7 + i * maxFilterNameSize, 7 + i * maxFilterNameSize + maxFilterNameSize);
}
SendProtocolResponse("!");
CopyToSlotsNamesConfig();
SauvegardeFilterWheelEEPROM();
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_OPTEC
void Optec_ExitSerialMode(String msg) {
#ifdef SMO_DEBUG
Serial.println(F("DF:Optec_ExitSerialMode"));
#endif
if (msg.startsWith("WEXITS")) {
connected = false;
SendProtocolResponse("END");
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_OPTEC
void setup() {
Serial.begin(SERIAL_BAUD, SERIAL_8N1); // initialise the serial monitor
Serial.flush();
delay(1000);
ChargeWheelEEPROM();
ChargeFilterWheelEEPROM();
filterWheelConfig.currentFilterWheel = 0;
filterWheelConfig.currentSlot = 0;
ComputeParams();
InitStepper();
incomingMessage = "";
#ifdef SMO_USE_WIFI
InitWifi();
#endif
#if defined(SMO_USE_WIFI) and defined(SMO_USE_WIFI_OTA)
InitOTA();
#endif
while (!Serial) {
// wait for serial port to connect. Needed for native USB
}
}
#endif
// =============================================================================
#ifdef SMO_PROTOCOL_OPTEC
void loop() {
#if defined(SMO_USE_WIFI) and defined(SMO_USE_WIFI_OTA)
ArduinoOTA.handle();
#endif
#ifdef SMO_USE_WIFI
server.handleClient();
if (wifi_request) {
#ifdef SMO_DEBUG
Serial.print(F("D:incomingMessage(wifi): "));
Serial.println(incomingMessage);
#endif
}
#endif
if (Serial.available() > 0) {
Serial.setTimeout(SERIAL_TIMEOUT);
incomingMessage = Serial.readStringUntil('\n');
#ifdef SMO_DEBUG
Serial.print(F("D:incomingMessage: "));
Serial.println(incomingMessage);
#endif
}
else {
if (incomingMessage.startsWith("WSMODE")) {
Optec_StartSerialMode(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WVAAAA")) {
Optec_GetFirmware(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WHOME")) {
Optec_WheelHome(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WIDENT")) {
Optec_WheelIdent(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WFILTR")) {
Optec_GetFilterPos(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WGOTO")) {
Optec_GoToFilterPosition(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WREAD")) {
Optec_GetFilterNames(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WLOAD")) {
Optec_SetFilterNames(incomingMessage);
FinMessage();
}
else if (connected && incomingMessage.startsWith("WEXITS")) {
Optec_ExitSerialMode(incomingMessage);
FinMessage();
}
#ifdef SMO_USE_WIFI
else if (wifi_request) {
HandleUnknownMessage();
FinMessage();
}
#endif
else if (incomingMessage.length() != 0) {
FinMessage();
}
}
stepper.run();
}
#endif
// =============================================================================
// END
// =============================================================================
voilà
merci
cdt
Bonjour astronomy
Sur le schéma il y a
Pin moteur D0, D1, D2, D3
Dans le programme, il y a
// Caracteristiques Moteur
#define motorPin1 5 // IN1 pin on the ULN2003A driver to pin D1 on NodeMCU board
#define motorPin2 4 // IN2 pin on the ULN2003A driver to pin D2 on NodeMCU board
#define motorPin3 0 // IN3 pin on the ULN2003A driver to pin D3 on NodeMCU board
#define motorPin4 2 // IN4 pin on the ULN2003A driver to pin D4 on NodeMCU board
Cordialement
jpbbricole
Mon opinion : avec un programme aussi long les sources de non fonctionnement sont trop nombreuses pour que quelqu'un comme moi s'y retrouve.
Je serai à ta place je ferais en priorité un programme extrêmement simple qui ne fait que faire tourner le moteur puisqu'il y a un problème sur le moteur, et je n'irai pas chercher une bibliothèque comme accelsteper mais quelque chose de très simple. Certes acccelstepper est puissante mais qui dit puissance dit aussi risque d'incompréhension vu les documentations assez succintes . Autant se placer à raz des paquerettes.
Tant que cet essai n'est pas transformé je n'irais pas plus loin.
Une fois réussi, tu pourra essayer de prendre en main accelstepper si tu le désires.
Puis ajoutes les fonctions une par une jusqu'à obtenir le programme que tu souhaites.
C'est ma méthode de travail, elle vaut ce qu'elle vaut, mais en général elle permet d'atteindre un résultat. Surtout que je ne pense pas que ce soit un choix personnel d'écrire les commentaires en anglais, c'est donc un programme récupéré quelque part.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.