Skip to content

Instantly share code, notes, and snippets.

@maelvls
Last active July 8, 2022 10:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maelvls/b2b2e67395e6c45ad814 to your computer and use it in GitHub Desktop.
Save maelvls/b2b2e67395e6c45ad814 to your computer and use it in GitHub Desktop.
Micro-programme de l'Arduino pour le contrôle des relais de la monture équatoriale par l'ordinateur de contrôle.
/*
* arduino.ino
*
* Description :
* Ce fichier permet de programmer l'Arduino One tel qu'il réponde aux
* commandes envoyées par l'ordinateur connecté par son port USB.
* Arduino enverra alors les commandes aux relais de la monture équatoriale
* à travers les DIGITAL PINS (les pins de 2 à 12).
*
* NOTE : les pins 0 et 1 sont déjà utilisés par défaut pour la com. série
*
* On peut compiler et uploader ce programme sur l'arduino
* grâce à l'IDE Arduino téléchargeable ici :
* http://arduino.cc/en/main/software > Arduino IDE
*
* Pour envoyer des commandes depuis l'ordinateur connecté à l'arduino,
* vous pouvez utiliser le "Moniteur série" de l'IDE Arduino et envoyer la
* chaine "4,1000" qui enverra une impulsion de 1000ms au pin numéro 4.
*
* Pour des raisons de facilité de compréhension, les commandes sont transmises
* à travers des chaines de caractères au lieu de nombre "bruts".
*
* TEST DE CONNEXION : pour savoir si l'arduino est toujours connecté,
* on peut lui envoyer le caractere ascii "ENQ" (code 5),
* il renverra "ACK" (code 6).
*
* ATTENTION: il est possible d'allumer tous les pins en même temps : il faut
* contrôler cela dans le programme utilisateur pour éviter qu'un moteur soit
* allumé dans deux directions par exemple !
*
* Author Maël Valais
*
* Date 16/04/2014 11:21
* Version 1.2 (22 août 2014)
*
* Notes de version :
*
* v0.8 - Première version mono-LED
*
* v0.9 - Ajout du test de connexion avec le caractère 'ENQ' répondu par 'ACK'
*
* v1.0 - Utilisation de serialEvent pour allumer plusieurs LED simultanément
* Correction des pins contrôlés dans verifierEtatsPins() (le PIN_MAX
* n'était jamais contrôlé)
*
* v1.1 - Utilisation d'un seul caractère (le 5 et le 6 respectivement) pour vérifier
* la connexion
*
* v1.2 - Modif des bornes de durée d'impulsion :
* DUREE_MIN devient 0 (permet d'éteindre un pin)
* DUREE_MAX reste à 60000, mais j'ai corrigé un bug d'entier
* (int [-32500,32500]) passé en long (pour la variable "duree")
* Ajout de la fonction eteindrePin(pin) pour clarifier le code
*
*/
// La librairie qui contient les fonctions d'arduino (setup(), pinMode()...)
#include "Arduino.h"
#define _DEBUG_
int pin; // Le pin (DIGITAL) choisi
long duree; // La duree choisie en ms
#define SIZE_BUFF 200 // Le buffer pour lire la chaine de caractères recue
char buffer[SIZE_BUFF];
size_t size_read = 0; // Taille effective du buffer
char *token; // Token pour parser la chaine (découpe en 2 entiers)
#define PIN_MIN 0 // Quels pins sont utilisables
#define PIN_MAX 13
unsigned long tempsDebut[14]; // Pour les 14 pins
unsigned long dureeTotale[14];
#define DUREE_MIN 0 // Le min est 1 ms
#define DUREE_MAX 60000 // Le max est 60 secondes
// Codes ASCII (char) pour le contrôle
#define ENQ 5 // Es-tu toujours là ? (ordinateur)
#define ACK 6 // Oui, je suis là (arduino)
void allumerPin(int pin, int duree) {
tempsDebut[pin] = millis();
dureeTotale[pin] = duree;
digitalWrite(pin, HIGH);
}
void eteindrePin(int pin) {
tempsDebut[pin] = 0;
dureeTotale[pin] = 0;
digitalWrite(pin, LOW);
}
void verifierEtatsPins() {
for(int pin = PIN_MIN; pin <= PIN_MAX; pin++) {
if(dureeTotale[pin]>=0 && tempsDebut[pin]>0
&& millis() - tempsDebut[pin] >= dureeTotale[pin]) {
eteindrePin(pin); // Ce pin doit etre eteint
}
}
}
void lireNumeroPinEtDuree(char* chaine) {
long duree = -1;
int pin = -1;
char* token;
// Parsing de la chaine (ex: '1,2345')
token = strtok(chaine, ", ;"); // (ex: le premier token sera '1')
pin = atoi(token); // On traduit la chaine '1' en int
token = strtok(NULL, " ,;"); // (ex: le second token sera '2345')
duree = atol(token); // On traduit la chaine '2345' en int
if(pin < PIN_MIN || pin > PIN_MAX) { // Vérification du choix du pin
Serial.print("Pin incorrect: " + String(pin));
}
else if(duree < DUREE_MIN || duree > DUREE_MAX) { // Vérif du choix de la durée
Serial.println("Duree incorrecte: " + String(duree));
}
else {
Serial.println("Cmd ok "+String(pin)+","+String(duree));
allumerPin(pin,duree); // Envoi de l'impulsion
}
}
/**
Configuration au démarrage d'Arduino
Arduino se configure à chaque redémarrage,
par exemple lorsqu'on appuie sur le bouton RESET
*/
void setup() {
// On configure les pins 0 à 13 pour utilisables en sortie
for (int pin_i=PIN_MIN; pin_i <= PIN_MAX ; pin_i++) {
pinMode(pin_i, OUTPUT);
}
Serial.begin(9600);
for(int pin = PIN_MIN; pin < PIN_MAX; pin++) {
dureeTotale[pin] = 0;
tempsDebut[pin] = 0;
}
size_read = 0;
}
/**
* La boucle de fonctionnement d'Arduino
*/
void loop() {
verifierEtatsPins();
}
void serialEvent() { // Quelque chose a été reçu
char car; // Le caractere en cours
while(Serial.available() > 0) { // Tant que buffer non vide (64bytesMax)
car = Serial.read();
if(car == ENQ) { // Arduino, es tu connecté ?
Serial.print((char)ACK); // Oui, je suis toujours là.
}
else {
buffer[size_read++] = car;
if(car == '\0' || car == '\r' || car == '\n') { // 13 = Retour charriot
buffer[size_read-1] = '\0'; // Chaine type C
lireNumeroPinEtDuree(buffer);
size_read = 0;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment