Bonjour , je m'appelle Théodore et il y a quelque temps je me suis lancé dans la fabrication d'une horloge. Je suis détenteur d'une imprimante 3D et quand j'ai vu passer sur Thingiverse le projet Hollow Clock de Shiura je me suis dit que ça allait être facile. Je me suis donc lancer tête la première dans ce projet et je me suis très vite trouver ralenti par de multiple obstacle. Le projet initiale comprends trois composant électronique : Le moteur pas a pas 28BYJ-48 et son fidèle module de contrôle ULN2003 et une carte arduino nano classique. Je me suis rendu compte qu'une carte arduino nano n'avait pas du tout la précision suffisante pour un projet d'horloge. J'ai donc fait l'acquisition de l'horloge en temps réel DS3132. Le but d'ajouter ce module était aussi de pouvoir remettre l'horloge a l'heure après une coupure de courant. C'est a ce niveaux la que j'ai rencontré beaucoup de difficulté mais maintenant que je suis sur la fin de ce projet un dernière obstacle s'oppose a ma réussite : Le code . Ça fait maintenant 3 bonnes années que je joue avec l'arduino mais je ne me suis jamais vraiment penché sur cette partie. J'avais donc déjà un code , celui de shiura mais j'ai beaucoup de mal a l'adapter au module DS3132. Malgré l'aide de ChatGPT je ne suis pas parvenu a faire un code bien fonctionnel. J'aurais aimer pouvoir travailler sur ce code moi même mais j'aimerais pouvoir l'envoyer dans les délais et mon emplois du temps est chargé. Je compte donc sur une âme charitable qui saurait faire un code fonctionnel a partir de mes échecs :
#include <Wire.h>
#include <RTClib.h>
// Création de l'objet RTC
RTC_DS3231 rtc;
// Paramètres du moteur pas à pas
#define STEPS_PER_ROTATION 15360 // Nombre de pas pour un tour complet (60 minutes)
int delaytime = 4; // Temps d'attente entre les pas du moteur
int port[4] = {2, 3, 4, 6}; // Broches du moteur pas à pas
// Séquence de contrôle pour le moteur pas à pas
int seq[4][4] = {
{LOW, LOW, HIGH, LOW},
{LOW, LOW, LOW, HIGH},
{HIGH, LOW, LOW, LOW},
{LOW, HIGH, LOW, LOW}
};
// Variables globales pour suivre la position actuelle
long prevPos = 0;
// Fonction pour faire tourner le moteur d'un certain nombre de pas
void rotate(int steps) {
static int phase = 0;
int delta = (steps > 0) ? 1 : 3;
steps = abs(steps);
for (int j = 0; j < steps; j++) {
phase = (phase + delta) % 4;
for (int i = 0; i < 4; i++) {
digitalWrite(port[i], seq[phase][i]);
}
delay(delaytime);
}
// Couper l'alimentation des bobines après le mouvement
for (int i = 0; i < 4; i++) {
digitalWrite(port[i], LOW);
}
}
void setup() {
Serial.begin(9600);
Serial.println("Initialisation de l'horloge Hollow Clock...");
// Initialisation des broches du moteur
for (int i = 0; i < 4; i++) {
pinMode(port[i], OUTPUT);
}
// Initialisation du module RTC
if (!rtc.begin()) {
Serial.println("Erreur : Module RTC introuvable !");
while (1);
}
// Vérification si le RTC a perdu l'alimentation
if (rtc.lostPower()) {
Serial.println("RTC a perdu l'alimentation. Réinitialisation de l'heure...");
rtc.adjust(DateTime(F(__DATlmE__), F(__TIME__))); // Réinitialisation à la date/heure de compilation
}
// Réinitialisation de la position du moteur après coupure de courant
// Faire tourner l'aiguille d'un nombre fixe de pas pour revenir à la position de départ (minute 0)
rotate(-50); // Tourner légèrement pour revenir à la position initiale
// Synchronisation initiale de l'aiguille
DateTime now = rtc.now();
long stepsToCurrentMinute = (STEPS_PER_ROTATION * now.minute()) / 60;
rotate(stepsToCurrentMinute);
prevPos = stepsToCurrentMinute;
Serial.println("Horloge synchronisée.");
Serial.println("Envoyez 'SET' pour remettre à l'heure ou 'SYNC' pour recalibrer l'horloge.");
}
void loop() {
// Lecture de l'heure actuelle
DateTime now = rtc.now();
long currentPos = (STEPS_PER_ROTATION * now.minute()) / 60;
// Mettre à jour la position si nécessaire
if (currentPos != prevPos) {
long steps = currentPos - prevPos;
rotate(steps);
prevPos = currentPos;
}
// Vérification des commandes série
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
command.trim();
if (command == "SET") {
Serial.println("Synchronisation de l'heure avec l'ordinateur...");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Serial.println("Heure synchronisée !");
} else if (command == "SYNC") {
Serial.println("Recalibrage de l'horloge...");
long stepsToCurrentMinute = (STEPS_PER_ROTATION * now.minute()) / 60;
rotate(stepsToCurrentMinute - prevPos);
prevPos = stepsToCurrentMinute;
Serial.println("Recalibrage terminé !");
} else {
Serial.println("Commande non reconnue.");
}
}
delay(1000); // Mise à jour toutes les secondes
}
Merci beaucoup d'avoir pris le temps de lire mon message et un grand merci a celui ou celle qui pourra ne serait-ce que m'aiguiller dans mon projet infernal .
Cette ligne est incorrecte. Vous avez une version correcte de cette ligne ailleurs dans votre code. Décrivez vos observations de l'horloge et décrivez comment vous souhaitez que l'horloge fonctionne. N'utilisez pas chatGPT tant que vous n'avez pas progressé dans le codage.
Ok, mais tu ne dis pas ce qui ne fonctionne pas.
Il faut bien te dire que nous n'avons pas ton matériel sur notre bureau donc il faut donner un peu plus de détails sur ce que tu voudrais que le programme fasse et sur ce qu'il fait en réalité.
Cette ligne utilise la date et l'heure au moment de la compilation. En aucun cas elle ne va lire l'heure sur le PC au moment où tu vas faire la commande set.
Même les mages et les devins ne peuvent se tromper tout le temps
ChatGPT utilise des modèles statistiques et probabilistes pour fournir, coûte que coûte, une réponse plausible au prompt soumis. Mais juste plausible.
Je ne dis pas que c'est inutile ou inefficace mais dès que l'on sort de l'ultra classique ça devient douteux. Or cet « ultra classique » forme la base de ce qu'il faudrait vraiment apprendre pour ensuite progresser et, si besoin, utiliser et surtout corriger chatGPT.
Personnellement j'y ai parfois trouvé une utilité : par flemme pour coder une structure HTML répondant à un besoin particulier, pour lui demander le principe d'un code (mais là, ça permet de ressortir quelques mots clés pour une vraie recherche après) etc.
Mais utiliser du code brut... parfois ça marche c'est vrai mais si on ne sais pas pourquoi, ça n'avance pas à grand chose.
(déso pour la leçon de morale à deux balles, mais j'ai été obligé de faire la même hier à mes élèves )
Bonjour à tous, bonjour Théodore,
cela ne coute pas très cher de placer un lien vers cette horloge : Hollow Clock by Shiura
de meme une petite vidéo Video
Cette horloge fonctionne en boucle ouverte. Le moteur fait tourner les aiguilles et c'est tout.
Pour la remettre à l'heure, il faut le faire à la main.
Si tu veux automatiser le process : 2 solutions :
soit l'alimenter en continu avec une batterie qui va remplacer l'alimentation secteur en cas de défaut. Pour ce faire, le DS3231 est un très bon choix.
L'autre solution c'est de trouver un système pour que le nano connaisse la position des aiguilles. C'est un fameux défi !
Merci je n'avais pas vu , je sais que ChatGPT n'était pas la meilleur option dans cette situation mais cette horloge est un cadeau que j'aimerais envoyé dans pas trop longtemps car je suis déjà en retard. Sinon le problème se situe plus dans la partie de remise a l'heure automatique des aiguilles après une coupure de courant. Le but serait quelle fasse la différence entre l'heure du DS3132 qui continue de compter les minutes grâce a sa propre pile et que l'arduino nano ai pris soin de noter la dernière heure avant qu'on la débranche , on fais ensuite la différence pour vérifier de combien on doit l'avancer. Mais si je débranche / rebranche la carte , elle va commencer a faire un tour alors quelle est déjà à l'heure . Je n'ai pas réussi a voir d'où venez cette instruction du programme pour la supprimer.
Merci beaucoup je suis bien d'accord qu'a ce niveaux la il ne peux servir qu'a optimiser un code , j'ai probablement voulu aller trop vite sur ce projet et au final je n'ai pas acquis beaucoup d'expérience en le réalisant. Maintenant , j'ai beaucoup avancer et je pense sincèrement avoir fait le plus gros du boulot , j'ai dépasser la date d'une semaine et je voudrais finir le projet ce week-end quitte a aller un peu vite je l'avoue .
J'avais penser a placer un capteur a effet hall qui pourrait vérifier la présence de la petite aiguilles sans trop se prendre la tête mais la livraison ne pourra pas arriver avant 4 jour et j'aimerais bien avoir tout fini ce Week-end.
Si vous ne pouvez pas acheter d'appareils conçus pour de tels projets (capteur à effet Hall, micro-interrupteur), vous pouvez improviser un interrupteur en utilisant deux fils nus qui entreront en contact au besoin.
Je pense que vous êtes loin du but… entre l’intégration des capteurs dans le design et leur câblage (faudra modifier le modèle et imprimer et tester que c’est ok) et le code et tests sur le code, il y pour plusieurs jours de boulot…
Si vous perdez le courant vous perdrez la position des aiguilles. Sans capteur de position des deux aiguilles il y a zéro chance de pouvoir les placer au bon endroit…
Si le capteur ne vous donne qu’une position "maison" (un point de référence sur le cercle) alors au boot vous serez obligé de faire un homing pour trouver cette position puis aller placer les aiguilles aux bons endroits.
Si vous n’avez pas les composants ni le temps de les intégrer et recoder en fonction de ces capteurs, vous ne pourrez pas finir non plus pour ce weekend.
PS: je n’ai pas vu le montage des engrenages mais si c’est le rapport des pignons qui fait tourner la petite aiguille d’un douzième de tour quand l’autre a fait ses 60 minutes c’est alors encore plus subtil au niveau mise à l’heure.
PS2: on voit passer de nombreux projets comme cela sur YouTube mais ils ne sont en rien des projets vraiment finis… le gros du boulot a été passé sur le modèle 3D et pas sur le code et la robustesse. Celui de votre modèle est fait pour être mis à l’heure sans doute à la main, comme les vielles montres à aiguilles et comme vous l’avez remarqué la précision de la gestion du temps fait que vous allez dériver et même avec une DS3231 le jeu sur le moteur et les pignons risque d’induire des décalages… vous attendez peut être trop de ce montage…
Bonjour J-M-L,
C’est très bien expliqué dans la vidéo. Il faut désolidariser le moteur de l’affichage pour régler l’heure de départ en faisant tourner les aiguilles à la main.
Le rapport de vitesse entre les 2 aiguilles est fixé par un jeu d’engrenage.
Aucun espoir de faire ce dont il rêve si on n’a pas un feed-back de la position des aiguilles vers le nano.
Je ne vous suis pas , avez vous lu mes messages précedent ? Si on fait la différence entre un module fiable comme le DS3132 et une arduino nano qui n'a qu'une simple valeur a conserver , le risque d'erreur me semble faible. Surtout quelle n'est pas censé être débrancher et ce dispositif ne servira qu'en cas de panne de courant ce qui n'est pas si fréquent.
Si tu concerve une donnée sur une EEPROM, tu es limité par le nombre de mise jour limiter de ce composant.
As tu calculer la duré de vie de ton composant en fonction de la précision que tu veux ?
Terwal, cela a été discuté sur ce forum il y a quelques années. En cas de coupure de courant, un circuit la détecte,crée une interruption et le nano sauve des paramètres dans son EEPROM en étant alimenté par une capa.
C’est jouable.
Oui j’ai vu cela - c’est une approche différente du capteur de position dont vous parliez aussi (qui pourrait être complémentaire) et que je commentais.
Si vous voulez sauver en mémoire non volatile l’heure de la panne de courant c’est possible mais il faut quand même des composants en plus pour que votre arduino ait le temps de faire cette sauvegarde (puisqu’il n’y a pas de courant).
Il faut donc prévoir une petite batterie (ou un « gros » condensateur) et le circuit de détection de coupure de courant.
Vous trouverez un bon tuto sur cela sur le blog de @hbachetti