voici le code complet à jour, la fonction queryirisState est maintenant dans le début du code un peu avant le setup
#include <SPI.h>
#include <Ethernet.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <EthernetUdp.h>
#include <avr/wdt.h>
byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x97, 0xD0 };
EthernetServer server(80);
#define DEBUG 1 // mettre à zero pour supprimer les messages dans le port série et ne pas dépendre du PC et du logiciel Arduino IDE pour démarrer
#define DHCP_EEPROM_ADDR 0 // emplacement pour DHCP on ou off
#define FIRSTSTART_EEPROM_ADDR 1 //emplacement pour déterminer si premier démarrage ou pas
#define IP_ADDR_START 2 //adresse ip de l'arduino
#define MASK_ADDR_START 6 // masque de l'arduino
#define GATEWAY_ADDR_START 10 // passerelle de l'arduino
#define DNS_ADDR_START 14 //DNS de l'arduino
// Adresses EEPROM pour les caméras
#define CAMERA_IP_ADDR_START 18 // Premier emplacement pour stocker les IP des caméras
#define CAMERA_PORT_ADDR_START 54 // Premier emplacement pour stocker les ports des caméras
#define CAMERA_IP_OFFSET 4 // Chaque IP prend 4 octets
#define CAMERA_PORT_OFFSET 2 // Chaque port prend 2 octets (uint16_t)
#define NUM_CAMERAS 9 // Nombre total de caméras
#define EEPROM_INVERSE_PAN_START 72 //premier emplacement pour stocker les inversePAN
#define EEPROM_INVERSE_TILT_START 81 //premier emplacement pour stocker les inverseTILT
#define EEPROM_TYPE_CAM_AVER_START 90 //premier emplacement pour stocker si c'est une cam de marque AVER
LiquidCrystal lcd(14, 15, 5, 4, 3, 2); //ecran lCD 16*2
// Déclaration des boutons
const int zeropad = 6;
const int unpad = 23;
const int deuxpad = 25;
const int troispad = 27;
const int quatrepad = 29;
const int cinqpad = 31;
const int sixpad = 33;
const int septpad = 35;
const int huitpad = 37;
const int neufpad = 39;
const int choixcam = 41;
const int presetcam = 43;
const int clearBtn = 45;
const int pluszoom = 47;
const int moinszoom = 49;
const int plusfocus = A6;
const int moinsfocus = A14;
const int btnspeed = 7;
const int btnplus = 22;
const int btnmoins = 24;
const int togAF = 26; // bouton autofocus on/off
const int btnsetup = 28;
const int btnsortiemenu = 30;
const int supprime_mem = 8;
const int btnenter = A8;
const int btnopt1 = A9;
const int btnopt2 = A10;
const int btnF1 = A11;
const int btnF2 = A12;
const int btnF3 = A13;
const int btnautopan = A4;
const int btnautopatrol = A5;
const int irisclose = A7;
const int irisopen = 34;
// Pins du joystick
const int tiltPin = A0; // Haut/Bas
const int panPin = A1; // Droite/Gauche
// Seuils du joystick
const int neutralMin = 500;
const int neutralMax = 510;
// Variables pour le joystick
int tiltValue, panValue;
byte tiltSpeed, panSpeed;
// Dernières commandes envoyées
byte lastTiltSpeed = 0x03; // Neutre
byte lastPanSpeed = 0x03; // Neutre
// Commandes UDP pour autofocus
byte resetCompteurCommande[] = { 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01 };
byte commandTGAF[] = { 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0x02, 0x81, 0x01, 0x04, 0x38, 0x10, 0xFF };
byte commandFBTGAF[] = { 0x01, 0x10, 0x00, 0x05, 0x00, 0x00, 0x02, 0x01, 0x81, 0x09, 0x04, 0x38, 0xFF };
byte commandSonyTGIrisAuto[] = { 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0x02, 0x81, 0x01, 0x04, 0x39, 0x00, 0xFF };
size_t sizeCommandSonyTGIrisAuto = sizeof(commandSonyTGIrisAuto);
byte commandAVERTGIrisAuto[] = { 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0x02, 0x81, 0x01, 0x04, 0x39, 0x00, 0xFF };
size_t sizeCommandAVERTGIrisAuto = sizeof(commandAVERTGIrisAuto); // Taille du tableau
byte commandSonyTGIrisManuel[] = { 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0x02, 0x81, 0x01, 0x04, 0x39, 0x0B, 0xFF };
size_t sizeCommandSonyTGIrisManuel = sizeof(commandSonyTGIrisManuel); // Taille du tableau
byte commandAVERTGIrisManuel[] = { 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0x02, 0x81, 0x01, 0x04, 0x39, 0x0B, 0xFF };
size_t sizeCommandAVERTGIrisManuel = sizeof(commandAVERTGIrisManuel); // Taille du tableau
byte commandSonyFBTGIrisAuto[] = { 0x01, 0x10, 0x00, 0x05, 0x00, 0x00, 0x02, 0x01, 0x81, 0x09, 0x04, 0x39, 0xFF };
size_t sizeCommandSonyFBTGIrisAuto = sizeof(commandSonyFBTGIrisAuto); // Taille du tableau
byte commandAVERFBTGIrisAuto[] = { 0x01, 0x10, 0x00, 0x05, 0x00, 0x00, 0x02, 0x01, 0x81, 0x09, 0x04, 0x39, 0xFF };
size_t sizeCommandAVERFBTGIrisAuto = sizeof(commandAVERFBTGIrisAuto); // Taille du tableau
// pour lecture de l'UDP entrant
byte packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // Buffer pour les paquets reçus
// État des caméras (0 à 8 pour 9 caméras)
int etatAF[9] = { 0 }; // Initialise l'état AF pour chaque caméra (0 = inconnu)
int etatIrisAuto[9] = { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }; // Initialise l'état AF pour chaque caméra (0 = inconnu)
// Dernier état connu pour éviter un rafraîchissement inutile
int dernierEtatAF[9] = { 0 }; // Initialise avec les mêmes valeurs que etatAF
int dernierEtatIrisAuto[9] = { 0 }; // Initialise avec les mêmes valeurs que etatAF
unsigned long lastUDPPacketTime = 0; // Temps de dernier paquet UDP reçu
unsigned long udpTimeout = 1000; // Timeout pour la réception UDP
int nouvelEtatAF = -1; // Initialisation à une valeur par défaut l'état AF
int nouvelEtatIrisAuto = -1; // Initialisation à une valeur par défaut l'état Iris Auto
unsigned long lastButtonPressTime = 0; // Dernière fois où un bouton a été pressé
const unsigned long udpActiveDuration = 5000; // Activer l'UDP pendant 5 secondes après un bouton
bool udpActive = false; // Indique si l'UDP est actif
const unsigned long udpActiveDuration2 = 5000;
bool udpActive2 = false;
const unsigned long udpActiveDuration3 = 5000;
bool udpActive3 = false;
// Variables pour stocker les octets extraits de l'Iris
byte irisHigh = 0;
byte irisLow = 0;
// États des boutons HIGH pour INPUT_PULLUP
bool lastPlusZoomState = HIGH;
bool lastMoinsZoomState = HIGH;
bool lastPlusFocusState = HIGH;
bool lastMoinsFocusState = HIGH;
// État de la vitesse et type de commande
enum CommandType { ZOOM,
FOCUS };
CommandType currentType = ZOOM;
int zoomSpeed = 2; // Vitesse par défaut pour le zoom
int focusSpeed = 2; // Vitesse par défaut pour le focus
unsigned long startTime;
bool cycleComplete = false;
unsigned long lastButtonPress = 0;
unsigned long debounceDelay = 200; // Débounce de 200ms
bool modeChoixCam = false; //initialise le mode au démarrage
bool modePresetCam = true; //initialise le mode au démarrage
bool attenteChoixCamera = false; //pas en mode choix cam donc pas d'attente de choix cam au démarrage
int choixCamActuel = -1; // Variable pour stocker la caméra choisie
int presetNumber = 0;
//gestion save/recall preset
const unsigned long longPressDuration = 3000; // Durée d'appui long en ms
unsigned long buttonPressStart1 = 0; // Moment où le bouton est pressé
unsigned long buttonPressStart2 = 0;
unsigned long buttonPressStart3 = 0;
unsigned long buttonPressStart4 = 0;
unsigned long buttonPressStart5 = 0;
unsigned long buttonPressStart6 = 0;
unsigned long buttonPressStart7 = 0;
unsigned long buttonPressStart8 = 0;
unsigned long buttonPressStart9 = 0;
// Variables pour la gestion du temps d'affiche de l'* à l'enregistrement de preset
unsigned long presetStarTime = 0; // Moment où l'étoile a été affichée
bool starDisplayed = false; // Flag pour vérifier si l'étoile a été affichée
//UDP port d'écoute de l'arduino
EthernetUDP Udp;
uint16_t udpPort = 52381;
//int selectedCamera = -1;
IPAddress cameraIP;
uint16_t cameraPort;
// Commande VISCA pour remise à zéro
byte viscaResetCommand[] = { 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01 };
// valeur par défaut si pas de DHCP
IPAddress defaultIP(192, 168, 1, 100);
IPAddress defaultMask(255, 255, 0, 0);
IPAddress defaultGateway(192, 168, 1, 1);
IPAddress defaultDNS(8, 8, 8, 8); // DNS par défaut
bool readDHCPFromEEPROM() {
return EEPROM.read(DHCP_EEPROM_ADDR) == 1;
}
bool readInvertTiltFromEEPROM() {
return EEPROM.read(EEPROM_INVERSE_TILT_START) == 1;
}
bool readInvertPanFromEEPROM() {
return EEPROM.read(EEPROM_INVERSE_PAN_START) == 1;
}
bool readTypeCamAverFromEEPROM() {
return EEPROM.read(EEPROM_TYPE_CAM_AVER_START) == 1;
}
void writeDHCPToEEPROM(bool isDHCPEnabled) {
EEPROM.write(DHCP_EEPROM_ADDR, isDHCPEnabled ? 1 : 0);
}
// Fonction pour écrire un booléen pour PAN dans l'EEPROM
void writeInvertPanToEEPROM(bool value, int addr) {
EEPROM.write(addr, value ? 1 : 0);
}
// Fonction pour écrire un booléen pour TILT dans l'EEPROM
void writeInvertTiltToEEPROM(bool value, int addr) {
EEPROM.write(addr, value ? 1 : 0);
}
// Fonction pour écrire un booléen pour TILT dans l'EEPROM
void writeTypeCamAverToEEPROM(bool value, int addr) {
EEPROM.write(addr, value ? 1 : 0);
}
// Fonction pour lire un booléen pour PAN depuis l'EEPROM
bool readInvertPanFromEEPROM(int addr) {
return EEPROM.read(addr) == 1;
}
// Fonction pour lire un booléen pour TILT depuis l'EEPROM
bool readInvertTiltFromEEPROM(int addr) {
return EEPROM.read(addr) == 1;
}
// Fonction pour lire un booléen pour TILT depuis l'EEPROM
bool readTypeCamAverFromEEPROM(int addr) {
return EEPROM.read(addr) == 1;
}
// Variables pour stocker les états
bool inversePan[9];
bool inverseTilt[9];
bool typeCamAver[9];
bool readFirstStartFromEEPROM() {
return EEPROM.read(FIRSTSTART_EEPROM_ADDR) != 1;
}
void writeFirstStartToEEPROM() {
EEPROM.write(FIRSTSTART_EEPROM_ADDR, 1);
}
void printEEPROMValues() {
IPAddress ip = readIPAddressFromEEPROM(IP_ADDR_START);
IPAddress mask = readIPAddressFromEEPROM(MASK_ADDR_START);
IPAddress gateway = readIPAddressFromEEPROM(GATEWAY_ADDR_START);
IPAddress dns = readIPAddressFromEEPROM(DNS_ADDR_START);
#if DEBUG
Serial.println(F("Valeurs stockées dans l'EEPROM :"));
Serial.print(F("IP EEPROM: "));
Serial.println(ip);
Serial.print(F("Masque EEPROM : "));
Serial.println(mask);
Serial.print(F("Passerelle EEPROM : "));
Serial.println(gateway);
Serial.print(F("DNS EEPROM : "));
Serial.println(dns);
#endif
}
uint16_t readPortFromEEPROM(int startAddr) {
uint16_t port = (EEPROM.read(startAddr) << 8) | EEPROM.read(startAddr + 1);
return port;
}
void writePortToEEPROM(uint16_t port, int startAddr) {
EEPROM.write(startAddr, (port >> 8) & 0xFF);
EEPROM.write(startAddr + 1, port & 0xFF);
}
void clearEEPROM() {
for (size_t i = 0; i < EEPROM.length(); i++) {
EEPROM.write(i, 0);
}
}
// pour vidage ram via bouton reset
bool isButtonPressedFor5Seconds() {
unsigned long buttonPressStartTime = 0;
bool buttonState = digitalRead(supprime_mem);
if (buttonState == LOW) {
buttonPressStartTime = millis();
while (digitalRead(supprime_mem) == LOW) {
if (millis() - buttonPressStartTime >= 5000) {
return true;
}
}
}
return false;
}
IPAddress readIPAddressFromEEPROM(int startAddr) {
return IPAddress(EEPROM.read(startAddr), EEPROM.read(startAddr + 1), EEPROM.read(startAddr + 2), EEPROM.read(startAddr + 3));
}
void writeIPAddressToEEPROM(IPAddress ip, int startAddr) {
for (int i = 0; i < 4; i++) {
EEPROM.write(startAddr + i, ip[i]);
}
}
bool isDHCPEnabled = readDHCPFromEEPROM();
// Fonction pour envoyer une commande VISCA over IP
void sendViscaJoystickCommand(byte* command, size_t length) {
// Préfixe obligatoire pour VISCA over IP
byte viscaJoystickPrefix[] = { 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0x02 };
#if DEBUG
Serial.print(F("Envoi de la commande : "));
for (size_t i = 0; i < sizeof(viscaJoystickPrefix); i++) {
Serial.print(F("0x"));
Serial.print(viscaJoystickPrefix[i], HEX);
Serial.print(F(" "));
}
for (size_t i = 0; i < length; i++) {
Serial.print(F("0x"));
Serial.print(command[i], HEX);
Serial.print(F(" "));
}
Serial.println();
#endif
// Envoyer le préfixe suivi de la commande
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(viscaJoystickPrefix, sizeof(viscaJoystickPrefix));
Udp.write(command, length);
Udp.endPacket();
}
// Fonction pour envoyer la commande de reset d'incrémentation
void sendResetCommand() {
byte resetCommand[] = { 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01 };
#if DEBUG
Serial.println(F("Envoi de la commande RESET d'incrémentation."));
#endif
Udp.begin(cameraPort);
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(resetCommand, sizeof(resetCommand));
Udp.endPacket();
}
// Fonction pour envoyer une commande de mouvement
void sendMoveCommand(byte panSpeed, byte tiltSpeed, byte panDirection, byte tiltDirection) {
sendResetCommand(); // Envoyer la commande de reset avant chaque mouvement
byte moveCommand[] = { 0x81, 0x01, 0x06, 0x01, panSpeed, tiltSpeed, panDirection, tiltDirection, 0xFF };
sendViscaJoystickCommand(moveCommand, sizeof(moveCommand));
}
// Fonction pour envoyer une commande d'arrêt
void sendStopCommand() {
sendMoveCommand(0x00, 0x00, 0x03, 0x03); // Stop PAN et TILT
}
// Fonction pour ajuster la vitesse
void adjustSpeed(int change) {
switch (currentType) {
case ZOOM:
zoomSpeed = constrain(zoomSpeed + change, 0, 7);
#if DEBUG
Serial.print(F("Vitesse Zoom: "));
Serial.println(zoomSpeed);
#endif
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("Zoom");
lcd.setCursor(5, 1);
lcd.print(zoomSpeed);
break;
case FOCUS:
focusSpeed = constrain(focusSpeed + change, 0, 7);
#if DEBUG
Serial.print(F("Vitesse Focus: "));
Serial.println(focusSpeed);
#endif
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("Focus ");
lcd.setCursor(6, 1);
lcd.print(focusSpeed);
break;
}
}
//fonction pour afficher la cam en cours avec actualisation AF (reste à ajouter l'IRIS quand fonctionnel)
void afficherEtatCamSelectionnee() {
lcd.setCursor(0, 0);
lcd.print("Cam ");
lcd.print(choixCamActuel);
lcd.print(" ");
lcd.setCursor(6, 0);
lcd.print("Pos ");
lcd.setCursor(14, 0);
lcd.print(dernierEtatAF[choixCamActuel] == 0x02 ? "AF" : "MF");
}
//gestion du bouton reboot sans vidage de l'EEPROM
unsigned long lastButtonPressF3 = 0; // Pour vérifier la durée d'appui du bouton
bool isButtonPressedF3 = false; // Flag pour vérifier l'état du bouton
// Commandes VISCA Iris Close ou Open ou Query
const byte CMD_IRIS_OPEN[] = { 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x02, 0x01, 0x81, 0x01, 0x04, 0x0B, 0x02, 0xFF };
const byte CMD_IRIS_CLOSE[] = { 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x02, 0x01, 0x81, 0x01, 0x04, 0x0B, 0x03, 0xFF };
//const byte CMD_IRIS_QUERY[] = { 0x01, 0x10, 0x00, 0x05, 0x00, 0x00, 0x02, 0x01, 0x81, 0x09, 0x04, 0x4B, 0xFF };
const byte viscaIrisFBpositionCommand[] = { 0x01, 0x10, 0x00, 0x05, 0x00, 0x00, 0x02, 0x01, 0x81, 0x09, 0x04, 0x4B, 0xFF };
//tableau pour équivalent IRIS (peut faire parti du problème)
const char* sonyIrisValues[] = {
"F0", "F14", "F11", "F9.6", "F8", "F6.8", "F5.6", "F4.8", "F4", "F3.4",
"F2.8", "F2.4", "F2", "F1.8", "F1.6"
};
const char* averIrisValues[] = {
"F0", "F14", "F11", "F8", "F6.8", "F5.6", "F4.8", "F4", "F3.4",
"F2.8", "F2.4", "F2", "F1.8", "F1.6"
};
// Déclare un tableau pour stocker l'état de l'iris pour chaque caméra
//byte etatIrisEnCours[9]; // Supposons qu'il y a 9 caméras maximum
const char* etatIrisEnCours[9];
//mise en place du code ici
int irisIndex =-1;
void queryIrisState() {
byte isCameraAver = typeCamAver[choixCamActuel - 1];
int irisIndex =-1;
#if DEBUG
Serial.println(F("Entering queryIrisState function."));
#endif
if (choixCamActuel == -1) {
#if DEBUG
Serial.println(F("No camera selected, exiting queryIrisState."));
#endif
return;
}
Udp.begin(cameraPort);
#if DEBUG
Serial.println(F("Sending VISCA Reset command..."));
#endif
if (cameraIP == IPAddress(0, 0, 0, 0) || cameraPort == 0) {
#if DEBUG
Serial.println(F("Error: Invalid Camera IP or Port!"));
#endif
return;
}
// Sending reset command to camera
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(viscaResetCommand, sizeof(viscaResetCommand));
Udp.endPacket();
#if DEBUG
Serial.println(F("Reset command sent. Sending FB Iris command..."));
#endif
// Sending FB Iris command
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(viscaIrisFBpositionCommand, sizeof(viscaIrisFBpositionCommand));
Udp.endPacket();
#if DEBUG
Serial.println(F("Iris Position FB command sent. Listening for responses..."));
#endif
// Listen for responses for a short period
unsigned long startTime = millis();
bool irisPositionAcknowledged = false;
while (millis() - startTime < 1000) { // Attendre jusqu'à 1 seconde
int packetSize = Udp.parsePacket();
if (packetSize) {
byte incomingPacket[UDP_TX_PACKET_MAX_SIZE];
Udp.read(incomingPacket, packetSize);
// Affiche la taille du paquet
#if DEBUG
Serial.print("Packet size received: ");
Serial.println(packetSize);
#endif
// Afficher le contenu du paquet
#if DEBUG
Serial.print(F("Response from camera (in hex): "));
for (int i = 0; i < packetSize; i++) {
if (incomingPacket[i] < 0x10) Serial.print(F("0"));
Serial.print(incomingPacket[i], HEX);
Serial.print(F(" "));
}
Serial.println();
#endif
// Condition ajustée pour la taille 15 et extraction des octets 13 et 14
if (packetSize == 15 && incomingPacket[8] == 0x90 && incomingPacket[9] == 0x50) {
irisHigh = incomingPacket[12];
irisLow = incomingPacket[13];
irisPositionAcknowledged = true;
break; // Arrêter après la première correspondance
}
}
}
// Afficher les valeurs extraites même si elles ne sont pas confirmées
#if DEBUG
Serial.print(F("Iris High = "));
if (irisHigh < 0x10) Serial.print(F("0"));
Serial.print(irisHigh, HEX);
Serial.print(F(", Iris Low = "));
if (irisLow < 0x10) Serial.print(F("0"));
Serial.println(irisLow, HEX);
#endif
if (irisPositionAcknowledged) {
#if DEBUG
Serial.print(F("Iris Position confirmed. Values extracted: High = "));
if (irisHigh < 0x10) Serial.print(F("0"));
Serial.print(irisHigh, HEX);
Serial.print(F(", Low = "));
if (irisLow < 0x10) Serial.print(F("0"));
Serial.println(irisLow, HEX);
#endif
Serial.print(F("si 0 cam sony si 1 cam Aver :"));
Serial.println(isCameraAver);
if (!isCameraAver) {
if (irisHigh == 0x01 )
{
switch (irisLow) {
case 0x00: irisIndex = 12; break; // F2
case 0x01: irisIndex = 14; break; // F1.6
}
}
if (irisHigh == 0x00) {
if (irisLow == 0x01) {
if (irisIndex == 2) {
irisIndex = 0; // F0
} else if (irisIndex == 0) {
irisIndex = 1; // F0
}
} else {
switch (irisLow) {
case 0x00: irisIndex = 0; break; // F0
case 0x05: irisIndex = 1; break; // F14
case 0x06: irisIndex = 2; break; // F11
case 0x07: irisIndex = 3; break; // F9.6
case 0x08: irisIndex = 4; break; // F8
case 0x09: irisIndex = 5; break; // F6.8
case 0x0A: irisIndex = 6; break; // F5.6
case 0x0B: irisIndex = 7; break; // F4.8
case 0x0C: irisIndex = 8; break; // F4
case 0x0D: irisIndex = 9; break; // F3.4
case 0x0E: irisIndex = 10; break; // F2.8
case 0x0F: irisIndex = 11; break; // F2.4
}
}
}
Serial.println(F("le test que c'est une cam sony"));
// etatIrisEnCours[choixCamActuel - 1] = irisIndex;
etatIrisEnCours[choixCamActuel - 1] = sonyIrisValues[irisIndex];
}
else{
switch (irisLow) {
case 0x00: irisIndex = 0; break; //F0
case 0x01: irisIndex = 1; break; //F14 ou F0
case 0x02: irisIndex = 2; break; //F11
case 0x03: irisIndex = 3; break; //F8
case 0x04: irisIndex = 4; break; //F6.8
case 0x05: irisIndex = 5; break; //F5.6
case 0x06: irisIndex = 6; break; //F4.8
case 0x07: irisIndex = 7; break; //F4
case 0x08: irisIndex = 8; break; //F3.4
case 0x09: irisIndex = 9; break; //F2.8
case 0x0A: irisIndex = 10; break; //2.4
case 0x0B: irisIndex = 11; break; //F2
case 0x0C: irisIndex = 12; break; //F1.8
case 0x0D: irisIndex = 13; break; //F1.6
}
Serial.println(F("le test que c'est une cam Aver"));
etatIrisEnCours[choixCamActuel - 1] = averIrisValues[irisIndex];
// Serial.println(etatIrisEnCours[choixCamActuel - 1]);
}
}
}
void afficheMemIrisValue()
{
// if (irisIndex >= 0) {
lcd.setCursor(11, 1);
lcd.print(" ");
// if (etatIrisEnCours[choixCamActuel - 1] != 0)
// {
lcd.setCursor(11, 1);
lcd.print(" ");
lcd.print(etatIrisEnCours[choixCamActuel - 1]);
// }
// else {
// lcd.setCursor(11, 1);
// lcd.print("Close");
// }
// } else {
// Serial.println(F("Error: Invalid Iris value detected."));
// }
}
// fin de mise en place du code
//fonction pour auto manu Iris
void gererCommandeIrisAuto(int etatIrisActuel) {
if (etatIrisActuel != 0x02 && etatIrisActuel != 0x03) {
#if DEBUG
Serial.print(F("État inattendu reçu dans gererCommandeIrisAuto : "));
Serial.println(etatIrisActuel, HEX);
#endif
return; // Ne rien faire si l'état est invalide
}
// Vérifie si la caméra actuelle est de type Aver ou Sony
bool isCameraAver = typeCamAver[choixCamActuel - 1];
#if DEBUG
Serial.print(F("isCameraAver: "));
Serial.println(isCameraAver); // Débogage pour vérifier la valeur
#endif
byte* commandTGIrisAuto;
size_t commandSizeTGIrisAuto;
byte* commandTGIrisManuel;
size_t commandSizeTGIrisManuel;
byte* commandFBTGIrisAuto;
size_t commandSizeFBTGIrisAuto;
// Sélection des commandes et tailles en fonction du type de caméra
if (isCameraAver) {
commandTGIrisAuto = commandAVERTGIrisAuto;
commandSizeTGIrisAuto = sizeCommandAVERTGIrisAuto;
commandTGIrisManuel = commandAVERTGIrisManuel;
commandSizeTGIrisManuel = sizeCommandAVERTGIrisManuel;
commandFBTGIrisAuto = commandAVERFBTGIrisAuto;
commandSizeFBTGIrisAuto = sizeCommandAVERFBTGIrisAuto;
} else {
commandTGIrisAuto = commandSonyTGIrisAuto;
commandSizeTGIrisAuto = sizeCommandSonyTGIrisAuto;
commandTGIrisManuel = commandSonyTGIrisManuel;
commandSizeTGIrisManuel = sizeCommandSonyTGIrisManuel;
commandFBTGIrisAuto = commandSonyFBTGIrisAuto;
commandSizeFBTGIrisAuto = sizeCommandSonyFBTGIrisAuto;
}
if (etatIrisActuel == 0x02) { // Si l'iris est en mode Auto
#if DEBUG
Serial.println(F("Mode Auto détecté : envoi des commandes correspondantes"));
#endif
sendUDPViscaCommand(resetCompteurCommande, sizeof(resetCompteurCommande));
delay(500);
sendUDPViscaCommand(commandTGIrisManuel, commandSizeTGIrisManuel); // Commande Manuel
delay(500);
sendUDPViscaCommand(resetCompteurCommande, sizeof(resetCompteurCommande));
delay(500);
sendUDPViscaCommand(commandFBTGIrisAuto, commandSizeFBTGIrisAuto);
delay(500);
} else if (etatIrisActuel == 0x03) { // Si l'iris est en mode Manuel
#if DEBUG
Serial.println(F("Mode Manuel détecté : envoi des commandes correspondantes"));
#endif
sendUDPViscaCommand(resetCompteurCommande, sizeof(resetCompteurCommande));
delay(500);
sendUDPViscaCommand(commandTGIrisAuto, commandSizeTGIrisAuto); // Commande Auto
delay(500);
sendUDPViscaCommand(resetCompteurCommande, sizeof(resetCompteurCommande));
delay(500);
sendUDPViscaCommand(commandFBTGIrisAuto, commandSizeFBTGIrisAuto);
delay(500);
}
}
// si on entre dans le menu, sauvegarde du LCD
// État des boutons
bool btnSetupPressed = false;
bool btnSortieMenuPressed = false;
// Variables pour gérer le menu
bool inSetupMenu = false;
int setupMenuState = 0;
void afficherSetupMenu() {
lcd.clear();
switch (setupMenuState) {
case 0: // Afficher l'adresse IP
lcd.print(isDHCPEnabled ? "DHCP: ON IP" : "DHCP: OFF IP");
lcd.setCursor(0, 1);
lcd.print(Ethernet.localIP());
break;
case 1: // Afficher le masque de sous-réseau
lcd.print(isDHCPEnabled ? "DHCP: ON MASQUE" : "DHCP: OFF MASQUE");
lcd.setCursor(0, 1);
lcd.print(Ethernet.subnetMask());
break;
case 2: // Afficher la passerelle
lcd.print(isDHCPEnabled ? "DHCP: ON GW" : "DHCP: OFF GW");
lcd.setCursor(0, 1);
lcd.print(Ethernet.gatewayIP());
break;
}
}
void setup() {
//#if DEBUG
Serial.begin(9600);
//#endif
for (int i = 0; i < 9; i++) {
inversePan[i] = EEPROM.read(EEPROM_INVERSE_PAN_START + i);
inverseTilt[i] = EEPROM.read(EEPROM_INVERSE_TILT_START + i);
typeCamAver[i] = EEPROM.read(EEPROM_TYPE_CAM_AVER_START + i);
}
Udp.begin(udpPort);
pinMode(supprime_mem, INPUT_PULLUP);
pinMode(zeropad, INPUT_PULLUP);
pinMode(unpad, INPUT_PULLUP);
pinMode(deuxpad, INPUT_PULLUP);
pinMode(troispad, INPUT_PULLUP);
pinMode(quatrepad, INPUT_PULLUP);
pinMode(cinqpad, INPUT_PULLUP);
pinMode(sixpad, INPUT_PULLUP);
pinMode(septpad, INPUT_PULLUP);
pinMode(huitpad, INPUT_PULLUP);
pinMode(neufpad, INPUT_PULLUP);
pinMode(choixcam, INPUT_PULLUP);
pinMode(presetcam, INPUT_PULLUP);
pinMode(clearBtn, INPUT_PULLUP);
pinMode(pluszoom, INPUT_PULLUP);
pinMode(moinszoom, INPUT_PULLUP);
pinMode(plusfocus, INPUT_PULLUP);
pinMode(moinsfocus, INPUT_PULLUP);
pinMode(btnspeed, INPUT_PULLUP);
pinMode(btnplus, INPUT_PULLUP);
pinMode(btnmoins, INPUT_PULLUP);
pinMode(togAF, INPUT_PULLUP);
pinMode(btnsetup, INPUT_PULLUP);
pinMode(btnsortiemenu, INPUT_PULLUP);
pinMode(supprime_mem, INPUT_PULLUP);
pinMode(btnenter, INPUT_PULLUP);
pinMode(btnopt1, INPUT_PULLUP);
pinMode(btnopt2, INPUT_PULLUP);
pinMode(btnF1, INPUT_PULLUP);
pinMode(btnF2, INPUT_PULLUP);
pinMode(btnF3, INPUT_PULLUP);
pinMode(btnautopan, INPUT_PULLUP);
pinMode(btnautopatrol, INPUT_PULLUP);
pinMode(irisclose, INPUT_PULLUP);
pinMode(irisopen, INPUT_PULLUP);
printEEPROMValues();
if (readFirstStartFromEEPROM()) {
#if DEBUG
Serial.println(F("Premier démarrage, configuration par défaut..."));
#endif
writeDHCPToEEPROM(true);
writeIPAddressToEEPROM(defaultIP, IP_ADDR_START);
writeIPAddressToEEPROM(defaultMask, MASK_ADDR_START);
writeIPAddressToEEPROM(defaultGateway, GATEWAY_ADDR_START);
writeIPAddressToEEPROM(defaultDNS, DNS_ADDR_START);
writeFirstStartToEEPROM();
}
// Initialisation de l'écran LCD
lcd.begin(16, 2);
lcd.clear();
startTime = millis(); // Initialiser le temps de démarrage pour le cycle de 30 secondes
if (isDHCPEnabled) {
if (Ethernet.begin(mac) == 0) {
#if DEBUG
Serial.println(F("Échec de la configuration DHCP."));
#endif
Ethernet.begin(mac, readIPAddressFromEEPROM(IP_ADDR_START), readIPAddressFromEEPROM(DNS_ADDR_START), readIPAddressFromEEPROM(GATEWAY_ADDR_START), readIPAddressFromEEPROM(MASK_ADDR_START));
}
} else {
Ethernet.begin(mac, readIPAddressFromEEPROM(IP_ADDR_START), readIPAddressFromEEPROM(DNS_ADDR_START), readIPAddressFromEEPROM(GATEWAY_ADDR_START), readIPAddressFromEEPROM(MASK_ADDR_START));
}
#if DEBUG
Serial.print(F("Adresse IP : "));
Serial.println(Ethernet.localIP());
Serial.print(F("Masque de sous-réseau : "));
Serial.println(Ethernet.subnetMask());
Serial.print(F("Passerelle : "));
Serial.println(Ethernet.gatewayIP());
Serial.print(F("DNS : "));
Serial.println(Ethernet.dnsServerIP());
#endif
server.begin();
#if DEBUG
// Affichage des valeurs de l'EEPROM entre les adresses 90 et 98 pour camera Aver ou Sony
Serial.println(F("Lecture de l'EEPROM de l'adresse 90 à 98:"));
for (int i = 90; i <= 98; i++) {
byte val = EEPROM.read(i); // Lire la valeur à l'adresse i
Serial.print(F("Adresse "));
Serial.print(i);
Serial.print(F(": "));
Serial.println(val, HEX); // Afficher la valeur en hexadécimal
}
Serial.println(F("Initialisation terminée. Mode par défaut : presetcam."));
Serial.println(F("init"));
Serial.print(F("mode choix cam :"));
Serial.println(modeChoixCam);
Serial.print(F("mode preset cam :"));
Serial.println(modePresetCam);
Serial.print(F("choix cam actuel :"));
Serial.println(choixCamActuel);
#endif
// Lecture et affichage des données EEPROM
for (int i = 0; i < 9; i++) {
inversePan[i] = EEPROM.read(EEPROM_INVERSE_PAN_START + i) == 1;
inverseTilt[i] = EEPROM.read(EEPROM_INVERSE_TILT_START + i) == 1;
typeCamAver[i] = EEPROM.read(EEPROM_TYPE_CAM_AVER_START + i) == 1;
}
#if DEBUG
// Affichage condensé
for (int i = 0; i < 9; i++) {
Serial.print(F("Caméra "));
Serial.print(i + 1);
Serial.print(F(" - Pan: "));
Serial.print(inversePan[i] ? "Inverse" : "Normal");
Serial.print(F(", Tilt: "));
Serial.println(inverseTilt[i] ? "Inverse" : "Normal");
Serial.print(F("Cam type: "));
Serial.println(typeCamAver[i] ? "Aver" : "Sony");
}
#endif
Udp.stop(); // pour ne pas le laissé ouvert tout le temps
delay(1000);
}
void loop() {
// Vérification si le bouton est pressé pendant 5 secondes pour réinitialiser l'EEPROM
if (isButtonPressedFor5Seconds()) {
#if DEBUG
Serial.println(F("Réinitialisation de l'EEPROM..."));
#endif
clearEEPROM();
#if DEBUG
Serial.println(F("EEPROM réinitialisée. Veuillez redémarrer l'Arduino."));
#endif
delay(2000);
asm volatile(" jmp 0");
}
// affichage en boucle pendant 30 secondes des infos réseau de l'arduino
if (!cycleComplete) {
unsigned long currentTime = millis();
// Gestion de l'affichage réseau pendant 30 secondes
if (currentTime - startTime < 30000) {
static unsigned long lastUpdateTime = 0;
static int currentStep = 0;
// Mise à jour toutes les 3 secondes
if (currentTime - lastUpdateTime >= 3000) {
lastUpdateTime = currentTime;
lcd.clear();
lcd.setCursor(0, 0);
switch (currentStep) {
case 0: // Afficher l'adresse IP
lcd.print(isDHCPEnabled ? "DHCP: ON IP" : "DHCP: OFF IP");
lcd.setCursor(0, 1);
lcd.print(Ethernet.localIP());
break;
case 1: // Afficher le masque de sous-réseau
lcd.print(isDHCPEnabled ? "DHCP: ON MASQUE" : "DHCP: OFF MASQUE");
lcd.setCursor(0, 1);
lcd.print(Ethernet.subnetMask());
break;
case 2: // Afficher la passerelle
lcd.print(isDHCPEnabled ? "DHCP: ON GW" : "DHCP: OFF GW");
lcd.setCursor(0, 1);
lcd.print(Ethernet.gatewayIP());
break;
}
// Passer à l'étape suivante
currentStep = (currentStep + 1) % 3;
}
} else {
// Fin du cycle de 30 secondes
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Bienvenue :-)");
delay(3000); // Pause finale avant d'effacer
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cam");
lcd.setCursor(4, 0);
lcd.print(choixCamActuel);
lcd.setCursor(7, 0);
lcd.print("Pos");
lcd.setCursor(14, 0);
lcd.print(nouvelEtatAF);
lcd.setCursor(0, 1);
lcd.print("Zoom");
lcd.setCursor(5, 1);
lcd.print(zoomSpeed);
cycleComplete = true; // Marquer la fin du cycle
}
}
if (digitalRead(btnsetup) == LOW) {
delay(200);
if (!btnSetupPressed) { // Si le bouton vient d'être pressé
btnSetupPressed = true;
if (!inSetupMenu) {
// Entrer dans le menu de configuration
inSetupMenu = true;
setupMenuState = 0; // Réinitialiser l'état du menu
} else {
// Passer à l'état suivant dans le menu
setupMenuState = (setupMenuState + 1) % 3;
}
afficherSetupMenu(); // Met à jour l'écran en fonction de l'état
}
} else {
btnSetupPressed = false;
}
// Gestion du bouton btnSortieMenu
if (digitalRead(btnsortiemenu) == LOW) {
if (!btnSortieMenuPressed) { // Si le bouton vient d'être pressé
btnSortieMenuPressed = true;
if (inSetupMenu) {
// Sortir du menu de configuration et restaurer l'écran
inSetupMenu = false;
afficherEtatCamSelectionnee();
lcd.setCursor(0, 1);
lcd.print(" "); // Efface la ligne pour éviter des restes
lcd.setCursor(0, 1);
if (currentType == ZOOM) {
lcd.print("Zoom ");
lcd.setCursor(5, 1);
lcd.print(zoomSpeed); // Affiche la vitesse actuelle du Zoom
} else {
lcd.print("Focus ");
lcd.setCursor(6, 1);
lcd.print(focusSpeed); // Affiche la vitesse actuelle du Focus
}
afficheEtatIrisManuAuto();
afficheMemIrisValue();
lcd.setCursor(10, 1);
lcd.print(" ");
}
}
} else {
btnSortieMenuPressed = false;
}
// Lire l'état du bouton pour reboot
bool currentButtonState = digitalRead(btnF3) == LOW; // Bouton appuyé (PULLUP)
// Vérifier si le bouton est pressé
if (currentButtonState && !isButtonPressedF3) {
// Premier appui, on marque le temps
lastButtonPressF3 = millis();
isButtonPressedF3 = true;
}
// Vérifier si le bouton est maintenu enfoncé pendant 3 secondes
if (isButtonPressedF3 && currentButtonState && (millis() - lastButtonPressF3 >= 3000)) {
#if DEBUG
// Appui maintenu pendant 3 secondes, redémarrage
Serial.println(F("Rebooting Arduino..."));
#endif
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Reboot dans 3s");
delay(1000);
lcd.setCursor(0, 0);
lcd.print("Reboot dans 2s");
delay(1000);
lcd.setCursor(0, 0);
lcd.print("Reboot dans 1s");
delay(1000);
// Activer le Watchdog Timer pour un redémarrage immédiat
wdt_enable(WDTO_15MS); // Configure le WDT pour un redémarrage rapide (15ms)
// Ne rien faire après avoir activé le WDT (l'Arduino redémarrera)
while (true) {
// Boucle infinie jusqu'au redémarrage
}
}
// Si le bouton est relâché, on réinitialise le flag
if (!currentButtonState && isButtonPressedF3) {
isButtonPressedF3 = false;
}
// Lecture des valeurs du joystick
tiltValue = analogRead(tiltPin);
panValue = analogRead(panPin);
// Calcul des vitesses
tiltSpeed = map(constrain(abs(tiltValue - (neutralMin + neutralMax) / 2), 0, 513), 0, 513, 0, 24);
panSpeed = map(constrain(abs(panValue - (neutralMin + neutralMax) / 2), 0, 513), 0, 513, 0, 24);
// Détection de direction
byte tiltDirection = (tiltValue < neutralMin) ? 0x01 : (tiltValue > neutralMax) ? 0x02 : 0x03;
byte panDirection = (panValue < neutralMin) ? 0x01 : (panValue > neutralMax) ? 0x02 : 0x03;
// Appliquer les inversions
if (inversePan[choixCamActuel - 1]) {
panDirection = (panDirection == 0x01) ? 0x02 : (panDirection == 0x02) ? 0x01 : 0x03;
}
if (inverseTilt[choixCamActuel - 1]) {
tiltDirection = (tiltDirection == 0x01) ? 0x02 : (tiltDirection == 0x02) ? 0x01 : 0x03;
}
// Vérification des changements et envoi des commandes
if (tiltDirection != 0x03 || panDirection != 0x03) { // Si on bouge le joystick
sendMoveCommand(panSpeed, tiltSpeed, panDirection, tiltDirection);
lastTiltSpeed = tiltSpeed;
lastPanSpeed = panSpeed;
} else if (lastTiltSpeed != 0x03 || lastPanSpeed != 0x03) { // Si on relâche le joystick
sendStopCommand();
lastTiltSpeed = 0x03;
lastPanSpeed = 0x03;
#if DEBUG
Serial.println(F("Commande STOP envoyée"));
#endif
}
// Gestion du bouton speed
if (digitalRead(btnspeed) == LOW) {
delay(200); // Anti-rebond
currentType = (currentType == ZOOM) ? FOCUS : ZOOM;
#if DEBUG
Serial.println(currentType == ZOOM ? "Mode: Réglage de la vitesse du zoom" : "Mode: Réglage de la vitesse du focus");
#endif
// Affiche le mode actif et sa vitesse
lcd.setCursor(0, 1);
lcd.print(" "); // Efface la ligne pour éviter des restes
lcd.setCursor(0, 1);
if (currentType == ZOOM) {
lcd.print("Zoom ");
lcd.setCursor(5, 1);
lcd.print(zoomSpeed); // Affiche la vitesse actuelle du Zoom
} else {
lcd.print("Focus ");
lcd.setCursor(6, 1);
lcd.print(focusSpeed); // Affiche la vitesse actuelle du Focus
}
}
// Gestion des boutons + et - pour ajuster la vitesse
if (digitalRead(btnplus) == LOW) {
adjustSpeed(1); // Augmente la vitesse
delay(200); // Anti-rebond
}
if (digitalRead(btnmoins) == LOW) {
adjustSpeed(-1); // Diminue la vitesse
delay(200); // Anti-rebond
}
// Gestion des boutons zoom et focus individuellement
checkButton(pluszoom, lastPlusZoomState, "Zoom Tele Start", "Zoom Stop", zoomSpeed);
checkButton(moinszoom, lastMoinsZoomState, "Zoom Wide Start", "Zoom Stop", zoomSpeed);
checkButton(plusfocus, lastPlusFocusState, "Focus Near Start", "Focus Stop", focusSpeed);
checkButton(moinsfocus, lastMoinsFocusState, "Focus Far Start", "Focus Stop", focusSpeed);
delay(50); // Petite pause pour éviter les commandes trop fréquentes
unsigned long currentMillis = millis(); // Temps écoulé depuis le démarrage
// Bouton choixcam : passer en mode choix de caméra
if (digitalRead(choixcam) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
modePresetCam = false;
modeChoixCam = true;
attenteChoixCamera = true;
#if DEBUG
Serial.println(F("Mode choix de caméra activé."));
#endif
lastButtonPress = currentMillis;
}
// Bouton presetcam : passer en mode presetcam
if (digitalRead(presetcam) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
modeChoixCam = false;
modePresetCam = true;
#if DEBUG
Serial.println(F("Mode choix de caméra activé."));
#endif
lastButtonPress = currentMillis;
}
// Gérer la sélection de la caméra en mode choixcam
if (modeChoixCam && attenteChoixCamera) {
if (digitalRead(unpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
choixCamActuel = 1;
#if DEBUG
Serial.println(F("Caméra 1 sélectionnée."));
#endif
readCameraConfig(choixCamActuel);
modeChoixCam = false;
modePresetCam = true; // Passer automatiquement en mode presetcam
#if DEBUG
Serial.println(F("Mode presetcam activé."));
#endif
lastButtonPress = currentMillis;
// Met à jour l'affichage pour refléter l'état actuel de la caméra
afficherEtatCamSelectionnee();
afficheEtatIrisManuAuto();
afficheMemIrisValue();
/* lcd.setCursor(10, 1);
lcd.print(" ");*/
} else if (digitalRead(deuxpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
choixCamActuel = 2;
#if DEBUG
Serial.println(F("Caméra 2 sélectionnée."));
#endif
readCameraConfig(choixCamActuel);
modeChoixCam = false;
modePresetCam = true; // Passer automatiquement en mode presetcam
#if DEBUG
Serial.println(F("Mode presetcam activé."));
#endif
lastButtonPress = currentMillis;
// Met à jour l'affichage pour refléter l'état actuel de la caméra
afficherEtatCamSelectionnee();
afficheEtatIrisManuAuto();
afficheMemIrisValue();
} else if (digitalRead(troispad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
choixCamActuel = 3;
#if DEBUG
Serial.println(F("Caméra 3 sélectionnée."));
#endif
readCameraConfig(choixCamActuel);
modeChoixCam = false;
modePresetCam = true; // Passer automatiquement en mode presetcam
#if DEBUG
Serial.println(F("Mode presetcam activé."));
#endif
lastButtonPress = currentMillis;
// Met à jour l'affichage pour refléter l'état actuel de la caméra
afficherEtatCamSelectionnee();
afficheEtatIrisManuAuto();
afficheMemIrisValue();
} else if (digitalRead(quatrepad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
choixCamActuel = 4;
#if DEBUG
Serial.println(F("Caméra 4 sélectionnée."));
#endif
readCameraConfig(choixCamActuel);
modeChoixCam = false;
modePresetCam = true; // Passer automatiquement en mode presetcam
#if DEBUG
Serial.println(F("Mode presetcam activé."));
#endif
lastButtonPress = currentMillis;
// Met à jour l'affichage pour refléter l'état actuel de la caméra
afficherEtatCamSelectionnee();
afficheEtatIrisManuAuto();
afficheMemIrisValue();
} else if (digitalRead(cinqpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
choixCamActuel = 5;
#if DEBUG
Serial.println(F("Caméra 5 sélectionnée."));
#endif
readCameraConfig(choixCamActuel);
modeChoixCam = false;
modePresetCam = true; // Passer automatiquement en mode presetcam
#if DEBUG
Serial.println(F("Mode presetcam activé."));
#endif
lastButtonPress = currentMillis;
// Met à jour l'affichage pour refléter l'état actuel de la caméra
afficherEtatCamSelectionnee();
afficheEtatIrisManuAuto();
afficheMemIrisValue();
} else if (digitalRead(sixpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
choixCamActuel = 6;
#if DEBUG
Serial.println(F("Caméra 6 sélectionnée."));
#endif
readCameraConfig(choixCamActuel);
modeChoixCam = false;
modePresetCam = true; // Passer automatiquement en mode presetcam
#if DEBUG
Serial.println(F("Mode presetcam activé."));
#endif
lastButtonPress = currentMillis;
// Met à jour l'affichage pour refléter l'état actuel de la caméra
afficherEtatCamSelectionnee();
afficheEtatIrisManuAuto();
afficheMemIrisValue();
} else if (digitalRead(septpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
choixCamActuel = 7;
#if DEBUG
Serial.println(F("Caméra 7 sélectionnée."));
#endif
readCameraConfig(choixCamActuel);
modeChoixCam = false;
modePresetCam = true; // Passer automatiquement en mode presetcam
#if DEBUG
Serial.println(F("Mode presetcam activé."));
#endif
lastButtonPress = currentMillis;
// Met à jour l'affichage pour refléter l'état actuel de la caméra
afficherEtatCamSelectionnee();
afficheEtatIrisManuAuto();
afficheMemIrisValue();
} else if (digitalRead(huitpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
choixCamActuel = 8;
#if DEBUG
Serial.println(F("Caméra 8 sélectionnée."));
#endif
readCameraConfig(choixCamActuel);
modeChoixCam = false;
modePresetCam = true; // Passer automatiquement en mode presetcam
#if DEBUG
Serial.println(F("Mode presetcam activé."));
#endif
lastButtonPress = currentMillis;
// Met à jour l'affichage pour refléter l'état actuel de la caméra
afficherEtatCamSelectionnee();
afficheEtatIrisManuAuto();
afficheMemIrisValue();
} else if (digitalRead(neufpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
choixCamActuel = 9;
#if DEBUG
Serial.println(F("Caméra 9 sélectionnée."));
#endif
readCameraConfig(choixCamActuel);
modeChoixCam = false;
modePresetCam = true; // Passer automatiquement en mode presetcam
#if DEBUG
Serial.println(F("Mode presetcam activé."));
#endif
lastButtonPress = currentMillis;
// Met à jour l'affichage pour refléter l'état actuel de la caméra
afficherEtatCamSelectionnee();
afficheEtatIrisManuAuto();
afficheMemIrisValue();
}
// Quand on appuie sur le bouton 0 (escape), on quitte le mode choixcam
else if (digitalRead(zeropad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
modeChoixCam = false;
modePresetCam = true; // Retour au mode presetcam
#if DEBUG
Serial.println(F("Retour au mode presetcam."));
#endif
lastButtonPress = currentMillis;
}
}
// Gérer les presets en mode presetcam
if (modePresetCam) {
// Détection d'un appui sur unpad
if (digitalRead(unpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
// Si c'est le début de l'appui, enregistrer le moment où l'appui commence
if (buttonPressStart1 == 0) {
buttonPressStart1 = currentMillis; // Enregistrer le moment de l'appui
}
// Vérifier si l'appui est long
if ((currentMillis - buttonPressStart1) >= longPressDuration) {
presetNumber = 1;
// Si l'appui est long, effectuer l'action correspondante
#if DEBUG
Serial.println(F("Appui long détecté sur le bouton 1"));
#endif
savePreset(choixCamActuel, presetNumber); // Action spécifique pour l'appui long
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.print(presetNumber);
// lcd.print("*");
// Enregistrer le moment où l'étoile a été affichée
presetStarTime = millis();
starDisplayed = true; // Indiquer que l'étoile a été affichée
buttonPressStart1 = 0; // Réinitialiser pour éviter que l'action se répète
lastButtonPress = currentMillis; // Mettre à jour le moment de l'appui long
} else if (digitalRead(unpad) == HIGH && buttonPressStart1 > 0) {
// Si le bouton est relâché, vérifier la durée de l'appui
if ((currentMillis - buttonPressStart1) < longPressDuration) {
// Si l'appui est court, effectuer l'action pour un appui court
#if DEBUG
Serial.println(F("Appui court détecté sur le bouton 1"));
#endif
presetNumber = 1;
recallPreset(choixCamActuel, presetNumber);
}
buttonPressStart1 = 0; // Réinitialiser la variable de suivi d'appui
lastButtonPress = currentMillis; // Mettre à jour le moment du dernier appui
}
}
// Détection d'un appui sur deuxpad
if (digitalRead(deuxpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
// Si c'est le début de l'appui, enregistrer le moment où l'appui commence
if (buttonPressStart2 == 0) {
buttonPressStart2 = currentMillis; // Enregistrer le moment de l'appui
}
// Vérifier si l'appui est long
if ((currentMillis - buttonPressStart2) >= longPressDuration) {
presetNumber = 2;
// Si l'appui est long, effectuer l'action correspondante
#if DEBUG
Serial.println(F("Appui long détecté sur le bouton 2"));
#endif
savePreset(choixCamActuel, presetNumber); // Action spécifique pour l'appui long
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.print(presetNumber);
// lcd.print("*");
// Enregistrer le moment où l'étoile a été affichée
presetStarTime = millis();
starDisplayed = true; // Indiquer que l'étoile a été affichée
buttonPressStart2 = 0; // Réinitialiser pour éviter que l'action se répète
lastButtonPress = currentMillis; // Mettre à jour le moment de l'appui long
} else if (digitalRead(deuxpad) == HIGH && buttonPressStart2 > 0) {
// Si le bouton est relâché, vérifier la durée de l'appui
if ((currentMillis - buttonPressStart2) < longPressDuration) {
// Si l'appui est court, effectuer l'action pour un appui court
#if DEBUG
Serial.println(F("Appui court détecté sur le bouton 2"));
#endif
presetNumber = 2;
recallPreset(choixCamActuel, presetNumber);
}
buttonPressStart2 = 0; // Réinitialiser la variable de suivi d'appui
lastButtonPress = currentMillis; // Mettre à jour le moment du dernier appui
}
}
// Détection d'un appui sur unpad
if (digitalRead(troispad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
// Si c'est le début de l'appui, enregistrer le moment où l'appui commence
if (buttonPressStart3 == 0) {
buttonPressStart3 = currentMillis; // Enregistrer le moment de l'appui
}
// Vérifier si l'appui est long
if ((currentMillis - buttonPressStart3) >= longPressDuration) {
presetNumber = 3;
// Si l'appui est long, effectuer l'action correspondante
#if DEBUG
Serial.println(F("Appui long détecté sur le bouton 3"));
#endif
savePreset(choixCamActuel, presetNumber); // Action spécifique pour l'appui long
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.print(presetNumber);
// lcd.print("*");
// Enregistrer le moment où l'étoile a été affichée
presetStarTime = millis();
starDisplayed = true; // Indiquer que l'étoile a été affichée
buttonPressStart3 = 0; // Réinitialiser pour éviter que l'action se répète
lastButtonPress = currentMillis; // Mettre à jour le moment de l'appui long
} else if (digitalRead(troispad) == HIGH && buttonPressStart3 > 0) {
// Si le bouton est relâché, vérifier la durée de l'appui
if ((currentMillis - buttonPressStart3) < longPressDuration) {
// Si l'appui est court, effectuer l'action pour un appui court
#if DEBUG
Serial.println(F("Appui court détecté sur le bouton 3"));
#endif
presetNumber = 3;
recallPreset(choixCamActuel, presetNumber);
}
buttonPressStart1 = 0; // Réinitialiser la variable de suivi d'appui
lastButtonPress = currentMillis; // Mettre à jour le moment du dernier appui
}
}
// Détection d'un appui sur unpad
if (digitalRead(quatrepad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
// Si c'est le début de l'appui, enregistrer le moment où l'appui commence
if (buttonPressStart4 == 0) {
buttonPressStart4 = currentMillis; // Enregistrer le moment de l'appui
}
// Vérifier si l'appui est long
if ((currentMillis - buttonPressStart4) >= longPressDuration) {
presetNumber = 4;
// Si l'appui est long, effectuer l'action correspondante
#if DEBUG
Serial.println(F("Appui long détecté sur le bouton 4"));
#endif
savePreset(choixCamActuel, presetNumber); // Action spécifique pour l'appui long
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.print(presetNumber);
// lcd.print("*");
// Enregistrer le moment où l'étoile a été affichée
presetStarTime = millis();
starDisplayed = true; // Indiquer que l'étoile a été affichée
buttonPressStart4 = 0; // Réinitialiser pour éviter que l'action se répète
lastButtonPress = currentMillis; // Mettre à jour le moment de l'appui long
} else if (digitalRead(quatrepad) == HIGH && buttonPressStart4 > 0) {
// Si le bouton est relâché, vérifier la durée de l'appui
if ((currentMillis - buttonPressStart4) < longPressDuration) {
// Si l'appui est court, effectuer l'action pour un appui court
#if DEBUG
Serial.println(F("Appui court détecté sur le bouton 4"));
#endif
presetNumber = 4;
recallPreset(choixCamActuel, presetNumber);
}
buttonPressStart4 = 0; // Réinitialiser la variable de suivi d'appui
lastButtonPress = currentMillis; // Mettre à jour le moment du dernier appui
}
}
// Détection d'un appui sur unpad
if (digitalRead(cinqpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
// Si c'est le début de l'appui, enregistrer le moment où l'appui commence
if (buttonPressStart5 == 0) {
buttonPressStart5 = currentMillis; // Enregistrer le moment de l'appui
}
// Vérifier si l'appui est long
if ((currentMillis - buttonPressStart5) >= longPressDuration) {
presetNumber = 5;
// Si l'appui est long, effectuer l'action correspondante
#if DEBUG
Serial.println(F("Appui long détecté sur le bouton 5"));
#endif
savePreset(choixCamActuel, presetNumber); // Action spécifique pour l'appui long
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.print(presetNumber);
// lcd.print("*");
// Enregistrer le moment où l'étoile a été affichée
presetStarTime = millis();
starDisplayed = true; // Indiquer que l'étoile a été affichée
buttonPressStart5 = 0; // Réinitialiser pour éviter que l'action se répète
lastButtonPress = currentMillis; // Mettre à jour le moment de l'appui long
} else if (digitalRead(cinqpad) == HIGH && buttonPressStart5 > 0) {
// Si le bouton est relâché, vérifier la durée de l'appui
if ((currentMillis - buttonPressStart5) < longPressDuration) {
// Si l'appui est court, effectuer l'action pour un appui court
#if DEBUG
Serial.println(F("Appui court détecté sur le bouton 5"));
#endif
presetNumber = 5;
recallPreset(choixCamActuel, presetNumber);
}
buttonPressStart5 = 0; // Réinitialiser la variable de suivi d'appui
lastButtonPress = currentMillis; // Mettre à jour le moment du dernier appui
}
}
// Détection d'un appui sur unpad
if (digitalRead(sixpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
// Si c'est le début de l'appui, enregistrer le moment où l'appui commence
if (buttonPressStart6 == 0) {
buttonPressStart6 = currentMillis; // Enregistrer le moment de l'appui
}
// Vérifier si l'appui est long
if ((currentMillis - buttonPressStart6) >= longPressDuration) {
presetNumber = 6;
// Si l'appui est long, effectuer l'action correspondante
#if DEBUG
Serial.println(F("Appui long détecté sur le bouton 6"));
#endif
savePreset(choixCamActuel, presetNumber); // Action spécifique pour l'appui long
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.print(presetNumber);
// lcd.print("*");
// Enregistrer le moment où l'étoile a été affichée
presetStarTime = millis();
starDisplayed = true; // Indiquer que l'étoile a été affichée
buttonPressStart6 = 0; // Réinitialiser pour éviter que l'action se répète
lastButtonPress = currentMillis; // Mettre à jour le moment de l'appui long
}
} else if (digitalRead(sixpad) == HIGH && buttonPressStart6 > 0) {
// Si le bouton est relâché, vérifier la durée de l'appui
if ((currentMillis - buttonPressStart6) < longPressDuration) {
// Si l'appui est court, effectuer l'action pour un appui court
#if DEBUG
Serial.println(F("Appui court détecté sur le bouton 6"));
#endif
presetNumber = 6;
recallPreset(choixCamActuel, presetNumber);
}
buttonPressStart6 = 0; // Réinitialiser la variable de suivi d'appui
lastButtonPress = currentMillis; // Mettre à jour le moment du dernier appui
}
// Détection d'un appui sur unpad
if (digitalRead(septpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
// Si c'est le début de l'appui, enregistrer le moment où l'appui commence
if (buttonPressStart7 == 0) {
buttonPressStart7 = currentMillis; // Enregistrer le moment de l'appui
}
// Vérifier si l'appui est long
if ((currentMillis - buttonPressStart1) >= longPressDuration) {
presetNumber = 7;
// Si l'appui est long, effectuer l'action correspondante
#if DEBUG
Serial.println(F("Appui long détecté sur le bouton 7"));
#endif
savePreset(choixCamActuel, presetNumber); // Action spécifique pour l'appui long
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.print(presetNumber);
// lcd.print("*");
// Enregistrer le moment où l'étoile a été affichée
presetStarTime = millis();
starDisplayed = true; // Indiquer que l'étoile a été affichée
buttonPressStart7 = 0; // Réinitialiser pour éviter que l'action se répète
lastButtonPress = currentMillis; // Mettre à jour le moment de l'appui long
}
} else if (digitalRead(septpad) == HIGH && buttonPressStart7 > 0) {
// Si le bouton est relâché, vérifier la durée de l'appui
if ((currentMillis - buttonPressStart7) < longPressDuration) {
// Si l'appui est court, effectuer l'action pour un appui court
#if DEBUG
Serial.println(F("Appui court détecté sur le bouton 7"));
#endif
presetNumber = 7;
recallPreset(choixCamActuel, presetNumber);
}
buttonPressStart7 = 0; // Réinitialiser la variable de suivi d'appui
lastButtonPress = currentMillis; // Mettre à jour le moment du dernier appui
}
// Détection d'un appui sur unpad
if (digitalRead(huitpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
// Si c'est le début de l'appui, enregistrer le moment où l'appui commence
if (buttonPressStart8 == 0) {
buttonPressStart8 = currentMillis; // Enregistrer le moment de l'appui
}
// Vérifier si l'appui est long
if ((currentMillis - buttonPressStart1) >= longPressDuration) {
presetNumber = 8;
// Si l'appui est long, effectuer l'action correspondante
#if DEBUG
Serial.println(F("Appui long détecté sur le bouton 8"));
#endif
savePreset(choixCamActuel, presetNumber); // Action spécifique pour l'appui long
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.print(presetNumber);
// lcd.print("*");
// Enregistrer le moment où l'étoile a été affichée
presetStarTime = millis();
starDisplayed = true; // Indiquer que l'étoile a été affichée
buttonPressStart8 = 0; // Réinitialiser pour éviter que l'action se répète
lastButtonPress = currentMillis; // Mettre à jour le moment de l'appui long
} else if (digitalRead(huitpad) == HIGH && buttonPressStart8 > 0) {
// Si le bouton est relâché, vérifier la durée de l'appui
if ((currentMillis - buttonPressStart8) < longPressDuration) {
// Si l'appui est court, effectuer l'action pour un appui court
#if DEBUG
Serial.println(F("Appui court détecté sur le bouton 8"));
#endif
presetNumber = 8;
recallPreset(choixCamActuel, presetNumber);
}
buttonPressStart8 = 0; // Réinitialiser la variable de suivi d'appui
lastButtonPress = currentMillis; // Mettre à jour le moment du dernier appui
}
// Détection d'un appui sur unpad
if (digitalRead(neufpad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
// Si c'est le début de l'appui, enregistrer le moment où l'appui commence
if (buttonPressStart9 == 0) {
buttonPressStart1 = currentMillis; // Enregistrer le moment de l'appui
}
// Vérifier si l'appui est long
if ((currentMillis - buttonPressStart9) >= longPressDuration) {
presetNumber = 9;
// Si l'appui est long, effectuer l'action correspondante
#if DEBUG
Serial.println(F("Appui long détecté sur le bouton 9"));
#endif
savePreset(choixCamActuel, presetNumber); // Action spécifique pour l'appui long
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.print(presetNumber);
// lcd.print("*");
// Enregistrer le moment où l'étoile a été affichée
presetStarTime = millis();
starDisplayed = true; // Indiquer que l'étoile a été affichée
buttonPressStart9 = 0; // Réinitialiser pour éviter que l'action se répète
lastButtonPress = currentMillis; // Mettre à jour le moment de l'appui long
}
} else if (digitalRead(neufpad) == HIGH && buttonPressStart9 > 0) {
// Si le bouton est relâché, vérifier la durée de l'appui
if ((currentMillis - buttonPressStart9) < longPressDuration) {
// Si l'appui est court, effectuer l'action pour un appui court
#if DEBUG
Serial.println(F("Appui court détecté sur le bouton 9"));
#endif
presetNumber = 9;
recallPreset(choixCamActuel, presetNumber);
}
buttonPressStart9 = 0; // Réinitialiser la variable de suivi d'appui
lastButtonPress = currentMillis; // Mettre à jour le moment du dernier appui
} else if (digitalRead(zeropad) == LOW && (currentMillis - lastButtonPress >= debounceDelay)) {
#if DEBUG
Serial.println(F("Aucun preset sélectionné."));
#endif
lastButtonPress = currentMillis;
}
}
}
//vérifier si 3 secondes se sont écoulées pour suppression de l'étoile d'indiquation de preset enregistré
if (starDisplayed && millis() - presetStarTime >= 3000) {
// Effacer l'étoile après 3 secondes
lcd.setCursor(11, 0);
lcd.print(" "); // Effacer le caractère étoile
starDisplayed = false; // Réinitialiser le flag
}
// Gestion des requêtes client via le serveur Ethernet
EthernetClient client = server.available();
if (client) {
String request = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
request += c;
if (c == '\n' && request.length() > 0) {
// Vérifie les différents types de requêtes
if (request.indexOf("GET /config") >= 0) {
showConfigPage(client);
} else if (request.indexOf("GET /save") >= 0) {
handleSaveRequest(client, request);
} else if (request.indexOf("GET /sauvegardeCameraConfig") >= 0) {
handleSaveCameraConfig(client, request); // Sauvegarde de la config de caméra
} else if (request.indexOf("GET /camera") >= 0) {
showConfigCamera(client);
} else {
showHomePage(client);
}
break;
}
}
}
client.stop();
}
if (digitalRead(togAF) == LOW) {
#if DEBUG
Serial.println(F("Bouton commande appuyé !"));
#endif
sendUDPViscaCommand(resetCompteurCommande, sizeof(resetCompteurCommande));
delay(500);
sendUDPViscaCommand(commandTGAF, sizeof(commandTGAF));
delay(500);
sendUDPViscaCommand(commandFBTGAF, sizeof(commandFBTGAF));
delay(500);
// Activer temporairement la réception UDP
udpActive = true;
lastButtonPressTime = millis(); // Enregistrer le moment du bouton pressé
}
// Gérer la réception UDP seulement si active
if (udpActive) {
if (millis() - lastButtonPressTime < udpActiveDuration) {
// Code de réception UDP
int packetSize = Udp.parsePacket();
if (packetSize > 0) {
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
// Vérifications et affichage des informations sur le paquet
if (packetSize >= 2) {
IPAddress remoteIP = Udp.remoteIP();
if (remoteIP[0] != 0 && remoteIP[3] != 0) {
#if DEBUG
Serial.print(F("Paquet reçu (taille "));
Serial.print(packetSize);
Serial.println(F(" octets) :"));
Serial.print(F("De l'adresse : "));
Serial.print(remoteIP);
Serial.print(F(" : "));
Serial.println(Udp.remotePort());
Serial.print(F("Contenu : "));
#endif
bool contenuVide = true;
for (int i = 0; i < packetSize; i++) {
if (packetBuffer[i] > 0) contenuVide = false;
#if DEBUG
if (packetBuffer[i] < 0x10) Serial.print(F("0"));
Serial.print(packetBuffer[i], HEX);
Serial.print(F(" "));
#endif
}
#if DEBUG
Serial.println();
#endif
if (!contenuVide && packetBuffer[0] == 0x01 && packetBuffer[1] == 0x11) {
nouvelEtatAF = packetBuffer[packetSize - 2];
if (dernierEtatAF[choixCamActuel] != nouvelEtatAF) {
dernierEtatAF[choixCamActuel] = nouvelEtatAF;
etatAF[choixCamActuel] = nouvelEtatAF;
#if DEBUG
Serial.print(F("État AF de la caméra "));
Serial.print(choixCamActuel);
Serial.println(nouvelEtatAF == 0x02 ? "AF ON" : "MF OFF");
afficherEtatAF(nouvelEtatAF);
#endif
lcd.setCursor(14, 0);
lcd.print(nouvelEtatAF == 0x02 ? "AF" : "MF");
}
}
}
}
}
} else {
udpActive = false; // Désactiver la réception UDP après le délai
}
}
if (digitalRead(btnF1) == LOW) { // Bouton appuyé
#if DEBUG
Serial.println(F("Bouton IRIS Auto commande appuyé !"));
Serial.print(F("État actuel de l'iris pour la caméra "));
Serial.print(choixCamActuel);
Serial.print(F(": "));
#endif
// Utilisation de l'index corrigé
int index = choixCamActuel - 1;
#if DEBUG
Serial.println(etatIrisAuto[index], HEX);
for (int i = 0; i < 9; i++) {
Serial.print(F("Indice "));
Serial.print(i);
Serial.print(F(": "));
Serial.println(dernierEtatIrisAuto[i], HEX); // Affiche la valeur en hexadécimal
}
#endif
// Vérification de l'état de l'iris
if (etatIrisAuto[index] == 0x02 || etatIrisAuto[index] == 0x03) {
gererCommandeIrisAuto(etatIrisAuto[index]);
} else {
#if DEBUG
Serial.println(F("Erreur : état actuel de l'iris invalide, aucune commande envoyée."));
#endif
}
// Activer temporairement la réception UDP
udpActive2 = true;
lastButtonPressTime = millis(); // Enregistrer le moment du bouton pressé
// Attendre un moment pour éviter les rebonds du bouton
delay(200);
}
if (udpActive2) {
if (millis() - lastButtonPressTime < udpActiveDuration2) {
// Réception UDP
int packetSize = Udp.parsePacket();
if (packetSize > 0) {
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
#if DEBUG
// Affichage du paquet reçu pour debug
Serial.print(F("Réponse reçue en hexadécimal : "));
for (int i = 0; i < packetSize; i++) {
if (packetBuffer[i] < 0x10) Serial.print(F("0"));
Serial.print(packetBuffer[i], HEX);
Serial.print(F(" "));
}
Serial.println();
#endif
// Vérifications de base sur le paquet
if (packetSize >= 4 && packetBuffer[packetSize - 1] == 0xFF) {
uint8_t avantDernierOctet = packetBuffer[packetSize - 2];
#if DEBUG
Serial.print(F("Avant-dernier octet : "));
Serial.println(avantDernierOctet, HEX);
#endif
// Vérification du type de caméra
bool etatValide = false;
// Vérifications selon le type de caméra
if (avantDernierOctet == 0x00 || avantDernierOctet == 0x0B) {
etatValide = true;
nouvelEtatIrisAuto = (avantDernierOctet == 0x00) ? 0x02 : 0x03;
}
// Mise à jour de l'état
if (etatValide) {
#if DEBUG
Serial.print(F("Nouvel état Iris Auto : "));
Serial.println(nouvelEtatIrisAuto, HEX);
#endif
// Mise à jour en utilisant l'index corrigé
int index = choixCamActuel - 1;
if (dernierEtatIrisAuto[index] != nouvelEtatIrisAuto) {
dernierEtatIrisAuto[index] = nouvelEtatIrisAuto;
etatIrisAuto[index] = nouvelEtatIrisAuto; // Mise à jour ici
#if DEBUG
Serial.print(F("État Iris Auto mis à jour pour caméra "));
Serial.println(choixCamActuel);
#endif
} else {
#if DEBUG
Serial.println(F("Aucun changement dans l'état Iris Auto."));
#endif
}
} else {
#if DEBUG
Serial.println(F("Valeur non pertinente pour le type de caméra."));
#endif
}
} else {
#if DEBUG
Serial.println(F("Paquet invalide ou structure non reconnue."));
#endif
}
afficheEtatIrisManuAuto();
}
} else {
udpActive2 = false; // Désactivation après le délai
}
}
if (digitalRead(irisclose) == LOW) // Bouton irisclose pressé
{
// Vérifie si la caméra actuelle est de type Aver ou Sony
sendViscaCommandIris(CMD_IRIS_CLOSE, sizeof(CMD_IRIS_CLOSE));
udpActive3 = true;
queryIrisState();
lastButtonPressTime = millis(); // Enregistrer le moment du bouton pressé
delay(200);
#if DEBUG
Serial.print(F("Etat Iris en cours :"));
Serial.println(etatIrisEnCours[choixCamActuel - 1]);
#endif
afficheMemIrisValue();
}
if (digitalRead(irisopen) == LOW) // Bouton irisopen pressé
{
sendViscaCommandIris(CMD_IRIS_OPEN, sizeof(CMD_IRIS_OPEN));
udpActive3 = true;
queryIrisState();
lastButtonPressTime = millis(); // Enregistrer le moment du bouton pressé
delay(200);
#if DEBUG
Serial.print(F("Etat Iris en cours :"));
Serial.println(etatIrisEnCours[choixCamActuel - 1]);
#endif
afficheMemIrisValue();
}
}
//affiche la page web acueil avec les 2 boutons
void showHomePage(EthernetClient client) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html; charset=UTF-8");
client.println();
client.println("<html><body>");
client.println("<br>");
client.println("<h1 style='text-align:center;'>Télécommande PTZ VISCA OVER IP by HawaienProduction</h1>");
client.println("<br>");
client.println("<hr>");
client.println("<br>");
client.println("<form style='text-align:center;' action='/config' method='get'>");
client.println("<button type='submit'>Configuration IP télécommande</button>");
client.println("</form>");
client.println("<br>");
client.println("<form style='text-align:center;' action='/camera' method='get'>");
client.println("<button type='submit'>Configuration IP Caméras</button>");
client.println("</form>");
client.println("</body></html>");
}
//affiche la page de gestion des ip des caméras à piloter
void showConfigCamera(EthernetClient client) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html; charset=UTF-8");
client.println();
client.println("<html><body>");
client.println("<h1 style='text-align:center;'>Configuration IP Caméras</h1><br><hr><br>");
client.println("<form action='/sauvegardeCameraConfig' method='get'>");
for (int i = 0; i < 9; i++) {
IPAddress camIP = readIPAddressFromEEPROM(CAMERA_IP_ADDR_START + (i * CAMERA_IP_OFFSET));
uint16_t camPort = readPortFromEEPROM(CAMERA_PORT_ADDR_START + (i * CAMERA_PORT_OFFSET));
client.print("<h3>Caméra ");
client.print(i + 1);
client.println("</h3>");
client.print("IP Caméra ");
client.print(i + 1);
client.print(": <input type='text' name='ip");
client.print(i);
client.print("' value='");
client.print(ipToString(camIP));
client.println("'><br>");
client.print("Port Caméra ");
client.print(i + 1);
client.print(": <input type='text' name='port");
client.print(i);
client.print("' value='");
client.print(camPort);
client.println("'><br><br>");
client.print("<div><label>Caméra ");
client.print(i + 1);
client.println("</label><br>");
// Case à cocher PAN
client.print("<input type='checkbox' name='pan");
client.print(i + 1);
client.print("' value='on' ");
if (inversePan[i]) client.print("checked");
client.println("> Inverser PAN<br>");
// Case à cocher TILT
client.print("<input type='checkbox' name='tilt");
client.print(i + 1);
client.print("' value='on' ");
if (inverseTilt[i]) client.print("checked");
client.println("> Inverser TILT<br>");
// Case à cocher Caméra Aver
client.print("<input type='checkbox' name='typeCamAver");
client.print(i + 1);
client.print("' value='on' ");
if (typeCamAver[i]) client.print("checked");
client.println("> Caméra Aver<br></div><br>");
}
client.println("<input type='submit' value='Enregistrer'>");
client.println("</form>");
client.println("<br><form action='/' method='get'><button type='submit'>Page Accueil</button></form>");
client.println("</body></html>");
}
//affiche la pag de config reseau de l'arduino
void showConfigPage(EthernetClient client) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html; charset=UTF-8");
client.println();
client.println("<html><body>");
client.println("<br>");
client.println("<h1 style='text-align:center;'>Configuration Réseau</h1>");
client.println("<br>");
client.println("<hr>");
client.println("<br>");
// Afficher les informations réseau actuelles
client.println("<p>Adresse IP actuelle : ");
client.print(Ethernet.localIP());
//client.println("</p>");
client.println("<p>Masque de sous-réseau actuel : ");
client.print(Ethernet.subnetMask());
//client.println("</p>");
client.println("<p>Passerelle actuelle : ");
client.print(Ethernet.gatewayIP());
// client.println("</p>");
// client.println("<p></p>");
client.println("<p>DNS actuel : ");
client.print(Ethernet.dnsServerIP());
client.println("</p>");
client.println("<p></p>");
client.println("<br>");
client.println("<hr>");
client.println("<br>");
client.println("<form action='/save' method='get'>");
client.print("DHCP : <input type='checkbox' name='dhcp' ");
if (readDHCPFromEEPROM()) client.print("checked");
client.println("><br>");
client.println("<br>");
client.print("Adresse IP : <input type='text' name='ip' value='");
client.print(ipToString(readIPAddressFromEEPROM(IP_ADDR_START)));
client.println("'><br>");
client.print("Masque de sous-réseau : <input type='text' name='mask' value='");
client.print(ipToString(readIPAddressFromEEPROM(MASK_ADDR_START)));
client.println("'><br>");
client.print("Passerelle : <input type='text' name='gateway' value='");
client.print(ipToString(readIPAddressFromEEPROM(GATEWAY_ADDR_START)));
client.println("'><br>");
client.print("DNS : <input type='text' name='dns' value='");
client.print(ipToString(readIPAddressFromEEPROM(DNS_ADDR_START)));
client.println("'><br>");
client.println("<br>");
client.println("<input type='submit' value='Enregistrer'>");
client.println("</form>");
client.println("<br>");
client.println("<hr>");
client.println("<br>");
client.println("<form style='text-align:center;' action='/' method='get'>");
client.println("<button type='submit'>Page Accueil</button>");
client.println("</form>");
client.println("</body></html>");
}
//gere la sauvegarde dans EEPROM du reseau de l'arduino
void handleSaveRequest(EthernetClient client, String request) {
IPAddress ip, mask, gateway, dns;
bool dhcp = request.indexOf("dhcp=on") != -1;
if (extractIPAddress(request, "ip=", ip)) writeIPAddressToEEPROM(ip, IP_ADDR_START);
if (extractIPAddress(request, "mask=", mask)) writeIPAddressToEEPROM(mask, MASK_ADDR_START);
if (extractIPAddress(request, "gateway=", gateway)) writeIPAddressToEEPROM(gateway, GATEWAY_ADDR_START);
if (extractIPAddress(request, "dns=", dns)) writeIPAddressToEEPROM(dns, DNS_ADDR_START);
writeDHCPToEEPROM(dhcp);
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html; charset=UTF-8");
client.println();
client.println("<html><body><h1>Configuration enregistrée</h1>");
client.println("<br>");
client.print("<p>Veuillez redémarrer l'appareil et ouvrir une nouvelle page à l'adresse IP affichée sur l'écran LCD de l'appareil au redémarrage.</p>");
client.println("</body></html>");
}
//gere la sauvegarde dans EEPROM des IP et port des caméras
void handleSaveCameraConfig(EthernetClient client, String request) {
for (int i = 0; i < 9; i++) {
IPAddress camIP;
uint16_t camPort;
// Traitement des paramètres dans la requête
String panParam = "pan" + String(i + 1) + "=";
String tiltParam = "tilt" + String(i + 1) + "=";
String typeCaamAverParam = "typeCamAver" + String(i + 1) + "=";
if (extractIPAddress(request, "ip" + String(i) + "=", camIP)) {
writeIPAddressToEEPROM(camIP, CAMERA_IP_ADDR_START + (i * CAMERA_IP_OFFSET));
}
int portIndex = request.indexOf("port" + String(i) + "=");
if (portIndex != -1) {
camPort = request.substring(portIndex + 5 + String(i).length()).toInt();
writePortToEEPROM(camPort, CAMERA_PORT_ADDR_START + (i * CAMERA_PORT_OFFSET));
}
if (request.indexOf("pan" + String(i + 1) + "=on") != -1) {
inversePan[i] = true;
} else {
inversePan[i] = false;
}
if (request.indexOf("tilt" + String(i + 1) + "=on") != -1) {
inverseTilt[i] = true;
} else {
inverseTilt[i] = false;
}
if (request.indexOf("typeCamAver" + String(i + 1) + "=on") != -1) {
typeCamAver[i] = true;
} else {
typeCamAver[i] = false;
}
// Sauvegarde des options dans l'EEPROM
writeInvertPanToEEPROM(inversePan[i], EEPROM_INVERSE_PAN_START + i);
writeInvertTiltToEEPROM(inverseTilt[i], EEPROM_INVERSE_TILT_START + i);
writeTypeCamAverToEEPROM(typeCamAver[i], EEPROM_TYPE_CAM_AVER_START + i);
}
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html; charset=UTF-8");
client.println();
client.println("<html><body><h1>Configuration des caméras enregistrée</h1><br>");
client.println("<p>Les informations de configuration des caméras ont été enregistrées avec succès.</p>");
client.println("<form action='/' method='get'><button type='submit'>Page Accueil</button></form>");
client.println("</body></html>");
}
String ipToString(IPAddress ip) {
return String(ip[0]) + "." + String(ip[1]) + "." + String(ip[2]) + "." + String(ip[3]);
}
//lit l'ip et le port des cameras dans EEPROM pour affichage
void readCameraConfig(int choixCamActuel) {
int ipStartAddr = CAMERA_IP_ADDR_START + ((choixCamActuel * CAMERA_IP_OFFSET) - 4);
cameraIP = readIPAddressFromEEPROM(ipStartAddr);
#if DEBUG
Serial.print(F("Camera "));
Serial.print(choixCamActuel);
Serial.print(F(" IP: "));
Serial.println(cameraIP);
#endif
int portAddr = CAMERA_PORT_ADDR_START + ((choixCamActuel * CAMERA_PORT_OFFSET) - 2);
cameraPort = readPortFromEEPROM(portAddr);
#if DEBUG
Serial.print(F("Camera "));
Serial.print(choixCamActuel);
Serial.print(F(" Port: "));
Serial.println(cameraPort);
#endif
}
//fonction pour le rappel des preset
void recallPreset(int choixCamActuel, int presetNumber) {
#if DEBUG
Serial.println(F("Entering recallPreset function."));
#endif
if (choixCamActuel == -1) {
#if DEBUG
Serial.println(F("No camera selected, exiting recallPreset."));
#endif
return;
}
Udp.begin(cameraPort);
byte presetHex = presetNumber - 1;
#if DEBUG
Serial.print(F("Preset hex value: "));
Serial.println(presetHex, HEX);
#endif
byte viscaPresetCommand[] = { 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0x02, 0x81, 0x01, 0x04, 0x3F, 0x02, presetHex, 0xFF };
#if DEBUG
Serial.println(F("Sending VISCA Reset command..."));
#endif
if (cameraIP == IPAddress(0, 0, 0, 0) || cameraPort == 0) {
#if DEBUG
Serial.println(F("Error: Invalid Camera IP or Port!"));
#endif
return;
}
// Sending reset command to camera
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(viscaResetCommand, sizeof(viscaResetCommand));
Udp.endPacket();
#if DEBUG
Serial.println(F("Reset command sent. Sending recall preset command..."));
#endif
// Sending recall preset command
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(viscaPresetCommand, sizeof(viscaPresetCommand));
Udp.endPacket();
#if DEBUG
Serial.println(F("Recall preset command sent. Listening for responses..."));
#endif
// Listen for responses for a short period
unsigned long startTime = millis();
bool presetAcknowledged = false;
while (millis() - startTime < 1000) { // Attendre jusqu'à 1 seconde
int packetSize = Udp.parsePacket();
if (packetSize) {
byte incomingPacket[UDP_TX_PACKET_MAX_SIZE];
Udp.read(incomingPacket, packetSize);
// Afficher la réponse reçue en hexadécimal pour le débogage
#if DEBUG
Serial.print(F("Response from camera (in hex): "));
for (int i = 0; i < packetSize; i++) {
if (incomingPacket[i] < 0x10) {
Serial.print(F("0"));
}
Serial.print(incomingPacket[i], HEX);
Serial.print(F(" "));
}
Serial.println();
#endif
// Vérifier si c'est la réponse attendue
if (packetSize >= 10 && incomingPacket[8] == 0x90 && incomingPacket[9] == 0x51) {
presetAcknowledged = true;
break; // On arrête de chercher dès qu'on trouve la bonne réponse
}
}
}
if (presetAcknowledged) {
#if DEBUG
Serial.println(F("Preset change confirmed by camera."));
#endif
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.print(presetNumber);
}
}
//fonction pour la sauvegarde des presets
void savePreset(int choixCamActuel, int presetNumber) {
#if DEBUG
Serial.println(F("Entering savePreset function."));
#endif
if (choixCamActuel == -1) {
#if DEBUG
Serial.println(F("No camera selected, exiting savePreset."));
#endif
return;
}
Udp.begin(cameraPort);
byte presetHex = presetNumber - 1; // Conversion du numéro de preset en hexadécimal (de 0x00 à 0x08)
#if DEBUG
Serial.print(F("Preset hex value: "));
Serial.println(presetHex, HEX);
#endif
byte viscaSavePresetCommand[] = { 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x02, 0x01, 0x81, 0x01, 0x04, 0x3F, 0x01, presetHex, 0xFF };
#if DEBUG
Serial.println(F("Sending VISCA Reset command..."));
#endif
if (cameraIP == IPAddress(0, 0, 0, 0) || cameraPort == 0) {
#if DEBUG
Serial.println(F("Error: Invalid Camera IP or Port!"));
#endif
return;
}
// Sending reset command to camera
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(viscaResetCommand, sizeof(viscaResetCommand));
Udp.endPacket();
#if DEBUG
Serial.println(F("Reset command sent. Sending recall preset command..."));
#endif
// Sending recall preset command
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(viscaSavePresetCommand, sizeof(viscaSavePresetCommand));
Udp.endPacket();
#if DEBUG
Serial.println(F("save preset command sent. Listening for responses..."));
#endif
// Listen for responses for a short period
unsigned long startTime = millis();
bool presetAcknowledged = false;
while (millis() - startTime < 1000) { // Attendre jusqu'à 1 seconde
int packetSize = Udp.parsePacket();
if (packetSize) {
byte incomingPacket[UDP_TX_PACKET_MAX_SIZE];
Udp.read(incomingPacket, packetSize);
// Afficher la réponse reçue en hexadécimal pour le débogage
#if DEBUG
Serial.print(F("Response from camera (in hex): "));
for (int i = 0; i < packetSize; i++) {
if (incomingPacket[i] < 0x10) {
Serial.print(F("0"));
}
Serial.print(incomingPacket[i], HEX);
Serial.print(F(" "));
}
Serial.println();
#endif
// Vérifier si c'est la réponse attendue
if (packetSize >= 10 && incomingPacket[8] == 0x90 && incomingPacket[9] == 0x51) {
presetAcknowledged = true;
break; // On arrête de chercher dès qu'on trouve la bonne réponse
}
}
}
if (presetAcknowledged) {
presetStarTime = millis();
starDisplayed = true;
#if DEBUG
Serial.println(F("Save Preset change confirmed by camera."));
#endif
lcd.setCursor(11, 0);
lcd.print("*");
} else {
#if DEBUG
Serial.println(F("Preset change not confirmed or no valid response received."));
#endif
}
}
// Fonction pour envoyer des commandes VISCA avec préfixe pour VISCA sur IP
void sendViscaPZCommand(const char* action, int speed) {
#if DEBUG
Serial.print(F("Commande VISCA : "));
Serial.print(action);
Serial.print(F(" à vitesse "));
Serial.println(speed);
#endif
// Préfixe VISCA sur IP
byte viscaPZPrefix[] = { 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0x02 };
// Commande de base VISCA
byte viscaPZCommand[] = { 0x81, 0x01, 0x04, 0x00, 0x00, 0xFF };
if (strcmp(action, "Zoom Tele Start") == 0) {
viscaPZCommand[3] = 0x07;
viscaPZCommand[4] = 0x21 + speed; // Vitesse ajustée pour zoom télé
} else if (strcmp(action, "Zoom Wide Start") == 0) {
viscaPZCommand[3] = 0x07;
viscaPZCommand[4] = 0x31 + speed; // Vitesse ajustée pour zoom wide
} else if (strcmp(action, "Focus Near Start") == 0) {
viscaPZCommand[3] = 0x08;
viscaPZCommand[4] = 0x21 + speed; // Vitesse ajustée pour Focus Near
} else if (strcmp(action, "Focus Far Start") == 0) {
viscaPZCommand[3] = 0x08;
viscaPZCommand[4] = 0x31 + speed; // Vitesse ajustée pour Focus Far
} else if (strcmp(action, "Zoom Stop") == 0) {
viscaPZCommand[3] = 0x07;
viscaPZCommand[4] = 0x00; // Pas de vitesse pour l'arrêt
} else if (strcmp(action, "Focus Stop") == 0) {
viscaPZCommand[3] = 0x08;
viscaPZCommand[4] = 0x00; // Pas de vitesse pour l'arrêt
}
#if DEBUG
Serial.println(F("envoi de la commande Reset"));
#endif
byte resetPZCommand[] = { 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01 };
// udp.begin(cameraPort); // Port local
Udp.begin(cameraPort);
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(resetPZCommand, sizeof(resetPZCommand));
Udp.endPacket();
#if DEBUG
Serial.println(F("envoi de la commande apres reset"));
#endif
// Envoie du paquet via UDP
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(viscaPZPrefix, sizeof(viscaPZPrefix));
Udp.write(viscaPZCommand, sizeof(viscaPZCommand));
Udp.endPacket();
}
// Fonction pour vérifier un bouton et exécuter les actions correspondantes
void checkButton(int pin, bool& lastState, const char* pressCommand, const char* releaseCommand, int speed) {
bool currentState = digitalRead(pin);
if (currentState != lastState) {
lastState = currentState;
if (currentState == LOW) {
sendViscaPZCommand(pressCommand, speed);
} else {
sendViscaPZCommand(releaseCommand, 0);
}
}
}
// Fonction pour envoyer une commande UDP
void sendUDPViscaCommand(byte* command, size_t commandSize) {
#if DEBUG
Serial.println(F("Début envoi UDP..."));
Serial.print(F("Commande envoyée en hexadécimal : "));
for (size_t i = 0; i < commandSize; i++) {
if (command[i] < 0x10) Serial.print(F("0")); // Ajoute un zéro pour les valeurs inférieures à 0x10
Serial.print(command[i], HEX);
Serial.print(F(" "));
}
Serial.println(); // Nouvelle ligne après l'affichage de la commande
#endif
Udp.begin(cameraPort);
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(command, commandSize); // Utiliser la taille explicite
Udp.endPacket();
#if DEBUG
Serial.println(F("Fin envoi UDP."));
#endif
}
// Fonction pour envoyer des commandes VISCA avec reset compteur
void sendViscaCommandIris(const byte* command, size_t length) {
Udp.begin(cameraPort);
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(resetCompteurCommande, sizeof(resetCompteurCommande));
Udp.endPacket();
delay(200);
Udp.beginPacket(cameraIP, cameraPort);
Udp.write(command, length);
Udp.endPacket();
#if DEBUG
Serial.print(F("Sent VISCA command: "));
for (size_t i = 0; i < length; i++) {
if (command[i] < 0x10) Serial.print(F("0"));
Serial.print(command[i], HEX);
Serial.print(F(" "));
}
Serial.println();
#endif
}
#if DEBUG
//fonction pour afficher l'état AF dans le monitor
void afficherEtatAF(int etat) {
if (etat == 0x02) {
Serial.println(F("Affichage : AF ON"));
} else if (etat == 0x03) {
Serial.println(F("Affichage : MF OFF"));
}
}
#endif
#if DEBUG
//fonction pour afficher l'état Iris auto manu dans le monitor (a supprimer au nettoyage du code)
void afficherEtatIrisAuto(int etatIA) {
if (etatIA == 0x02) {
Serial.println(F("Affichage : IA"));
} else if (etatIA == 0x03) {
Serial.println(F("Affichage : IM"));
}
}
#endif
//fonction pour afficher l'état Iris auto manu sur LCD
void afficheEtatIrisManuAuto() {
int index = choixCamActuel - 1;
lcd.setCursor(8, 1);
lcd.print(" ");
lcd.setCursor(8, 1);
lcd.print(etatIrisAuto[index] == 0x02 ? "IA " : "IM");
}
bool extractIPAddress(String request, String key, IPAddress& ip) {
int start = request.indexOf(key);
if (start == -1) return false;
start += key.length();
int end = request.indexOf("&", start);
if (end == -1) end = request.length();
String ipString = request.substring(start, end);
int parts[4];
if (sscanf(ipString.c_str(), "%d.%d.%d.%d", &parts[0], &parts[1], &parts[2], &parts[3]) == 4) {
ip = IPAddress(parts[0], parts[1], parts[2], parts[3]);
return true;
}
return false;
}