stroboduino/stroboduino.ino

229 lines
8.4 KiB
Arduino
Raw Permalink Normal View History

2017-04-23 11:44:52 +02:00
//------------------------------------------------------------------------------
// *** STROBODUINO ***
//------------------------------------------------------------------------------
char Ver[] = "cg230417";
2017-04-12 19:28:37 +02:00
2017-04-23 16:29:12 +02:00
#include <TimerOne.h> // Timer1 --> timer entre étincelle et Flash
#include <Encoder.h> // Bibiliothèque pour gestion encoder avec anti-rebond
#include <EEPROM.h> // Lect/Ecrit dans l'EEPROM interne à l'ATMEL pour svg des param.
#include <LiquidCrystal.h> // LCD
#include <RunningAverage.h> // Calcul de moy. glissante pour lisser le compte-tour
2017-04-12 19:28:37 +02:00
2017-05-08 13:05:15 +02:00
bool debug = 0; // true si debug
2017-04-23 11:44:52 +02:00
//------------------------------------------------------------------------------
2017-04-23 16:29:12 +02:00
// PARAMETRES (stockés dans l'EEPROM)
2017-04-23 11:44:52 +02:00
//------------------------------------------------------------------------------
2017-04-12 19:28:37 +02:00
2017-04-23 16:29:12 +02:00
byte D_Flash = 10; // Durée du flash en µs, autour de 10µs
byte Ncyl = 2; // Nombre de cylindres
byte Refresh = 100; // Refresh du LCD en millisec.
2017-04-14 23:43:53 +02:00
2017-04-23 11:44:52 +02:00
//------------------------------------------------------------------------------
2017-04-14 23:43:53 +02:00
// CONSTANTES
2017-04-23 11:44:52 +02:00
//------------------------------------------------------------------------------
2017-04-13 20:45:22 +02:00
2017-04-23 16:29:12 +02:00
#define Etin 2 // Entrée bobine
#define Inter 5 // Inter du codeur
#define Flash 11 // Flash
#define Codeur_A 3 // D3 pour entrée codeur A sous interruption
#define Codeur_B 4 // D4 pour entrée codeur B
const byte lissrpm = 3; // Nb de valeurs pour moy. glissante compte-tours
const int deg_Initial = 10; // Affiché au demarrage
2017-04-12 19:28:37 +02:00
2017-04-23 11:44:52 +02:00
//-------------------------------------------------------------------------------
2017-04-12 19:28:37 +02:00
// VARIABLES
2017-04-23 11:44:52 +02:00
//-------------------------------------------------------------------------------
2017-05-08 13:05:15 +02:00
volatile long T = 0; // Periode en cours(signée pour le calcul de D_deg)
unsigned long prec_H = 0; // Heure du front precedent en µs
volatile int deg_dem = deg_Initial; // Compteur des degrés demandés
volatile long D_deg = 0; // Délai pour deg_dem degrès en µs
unsigned long N = 0; // N en tours/mn
unsigned long Nc = 0; // Pour le calcul de N
unsigned long pm = 0; // Previous millis pour Refresh LCD
byte modconfig = 0; // Flag pour savoir si on est en mode config
int degT = 720 / Ncyl; // Degrés entre 2 étincelles
2017-04-23 11:44:52 +02:00
LiquidCrystal lcd( 9, 17, 15, 16, 14, 10);
//lcd(RS, E, D4, D5, D6, D7)
2017-04-14 10:57:12 +02:00
Encoder Enco(Codeur_A, Codeur_B);
2017-04-23 16:29:12 +02:00
RunningAverage RArpm(lissrpm);
2017-04-23 11:44:52 +02:00
//--------------------------------------------------------------------------------
2017-04-15 16:14:58 +02:00
// ISR
2017-04-23 11:44:52 +02:00
//--------------------------------------------------------------------------------
2017-04-12 19:28:37 +02:00
2017-04-14 10:57:12 +02:00
void isrEtincelle() {
2017-04-23 11:44:52 +02:00
T = micros() - prec_H; // Calcul de T
prec_H = micros();
2017-04-14 10:57:12 +02:00
Timer1.initialize(D_deg); // Flash après delai D_deg µs
}
void isrFlash(){
Timer1.stop();
2017-04-23 11:44:52 +02:00
//Flash et flash sur LED13
digitalWrite (Flash, 1); delayMicroseconds(D_Flash); digitalWrite (Flash, 0);
2017-05-08 13:05:15 +02:00
digitalWrite (LED_BUILTIN, 1); delayMicroseconds(10 * D_Flash); digitalWrite (LED_BUILTIN, 0);
2017-04-23 11:44:52 +02:00
//Délai en µs pour les degrés demandés, periode suivante
D_deg = float(T * deg_dem) / float(degT);
2017-04-23 16:29:12 +02:00
// Si retard demandé, on ajoute un tour
2017-04-23 11:44:52 +02:00
if (deg_dem < 0){D_deg += float(T * 360) / float(degT);}
2017-04-23 16:29:12 +02:00
// On ajoute la valeur de T au calcul de moy. glissante
RArpm.addValue(T);
2017-04-23 11:44:52 +02:00
// DEBUG
2017-04-23 16:29:12 +02:00
//if (debug) {Serial.print("T : "); Serial.print(T); Serial.print(" D_deg : "); Serial.println(D_deg);}
//if (debug) {Serial.print("degT : "); Serial.print(degT); Serial.print(" deg_dem : "); Serial.println(deg_dem);}
2017-04-14 10:57:12 +02:00
}
2017-04-23 11:44:52 +02:00
//--------------------------------------------------------------------------------
2017-04-15 16:14:58 +02:00
// FONCTIONS
2017-04-23 11:44:52 +02:00
//--------------------------------------------------------------------------------
2017-04-15 16:14:58 +02:00
2017-04-23 16:29:12 +02:00
void Affic_N_et_deg_dem(){ // Affiche compte-tour et dégrés demandés
N = Nc / RArpm.getAverage(); // Calculer N en t/mn
2017-04-23 11:44:52 +02:00
lcd.setCursor(0, 0); lcd.print(" ");
lcd.setCursor(0, 0); lcd.print(N); // Régime tr/min
2017-04-15 16:14:58 +02:00
lcd.setCursor(0, 1); lcd.print(" ");
2017-04-23 11:44:52 +02:00
lcd.setCursor(0, 1); lcd.print(deg_dem); lcd.write(223); // Avance °
}
2017-04-12 19:28:37 +02:00
2017-04-23 11:44:52 +02:00
void Affich_fond_ecran(){ // Affiche le fond d'écran au début ou après la config.
2017-04-15 16:14:58 +02:00
lcd.clear();
2017-04-23 16:29:12 +02:00
lcd.setCursor(5, 0); lcd.print("tpm");
lcd.setCursor(5, 1); lcd.print(Ncyl); lcd.print("c");
2017-04-15 16:14:58 +02:00
}
2017-04-23 16:29:12 +02:00
void Regl(byte &var, String titre){ // Macro de réglage pour param type byte
lcd.clear(); lcd.print(titre);
Enco.write(var*4); // Init l'encodeur avec la valeur actuelle
2017-04-23 11:44:52 +02:00
while (digitalRead(Inter) == 1){ // tant qu'on appuie pas on régle
2017-04-14 23:43:53 +02:00
var = Enco.read()/4;
lcd.setCursor(3, 1);
2017-04-23 16:29:12 +02:00
lcd.print(var); // Affiche la valeur
2017-04-14 23:43:53 +02:00
lcd.print(" ");
}
while (digitalRead(Inter) == 0); // Si on a appuyé, on attend le relachement
}
2017-04-23 16:29:12 +02:00
void Regl(bool &var, String titre){ // Macro de réglage pour param type bool
2017-04-15 16:14:58 +02:00
lcd.clear();
lcd.print(titre);
lcd.setCursor(3, 1);
lcd.print(var);
lcd.print(" ");
long flag = 0;
Enco.write(0);
2017-04-23 11:44:52 +02:00
while (digitalRead(Inter) == 1){ // tant qu'on appuie pas on régle
2017-04-15 16:14:58 +02:00
if (flag != Enco.read()/4) {
var = !var;
flag = Enco.read()/4;
lcd.setCursor(3, 1);
lcd.print(var);
lcd.print(" ");
}
}
while (digitalRead(Inter) == 0); // Si on a appuyé, on attend le relachement
}
void ConfiG() {
2017-05-08 13:05:15 +02:00
modconfig=0;
2017-04-14 19:04:05 +02:00
lcd.clear();
lcd.print("CONFIG");
2017-04-14 22:37:04 +02:00
lcd.setCursor(7, 1);
2017-04-15 16:14:58 +02:00
lcd.write(126);
while (digitalRead(Inter) == 0); //toujours appuyé ? on attend
2017-04-23 16:29:12 +02:00
// Réglages avec le codeur
Regl(Ncyl, "Nb cyl.");
2017-04-14 23:43:53 +02:00
Regl(D_Flash, "D Flash");
Regl(Refresh, "Refresh");
2017-04-23 16:29:12 +02:00
// Sauvegarde des paramètres dans l'EEPROM
2017-04-14 23:43:53 +02:00
EEPROM.write(0, Ncyl);
EEPROM.write(1, D_Flash);
EEPROM.write(2, Refresh);
2017-04-23 16:29:12 +02:00
2017-04-14 19:04:05 +02:00
IniT();
}
2017-04-23 11:44:52 +02:00
//------------------------------------------------------------------------------
// SETUP
//------------------------------------------------------------------------------
2017-04-23 16:29:12 +02:00
void IniT() {
// On charge les paramètres stockés en mémoire
Ncyl = EEPROM.read(0);
2017-04-15 16:14:58 +02:00
D_Flash = EEPROM.read(1);
Refresh = EEPROM.read(2);
2017-04-23 16:29:12 +02:00
// Interruption détection d'étincelle
2017-04-14 10:57:12 +02:00
attachInterrupt(digitalPinToInterrupt(Etin), isrEtincelle, RISING);
2017-04-23 16:29:12 +02:00
// Timer entre Etincelle et Flash
Timer1.attachInterrupt(isrFlash);
2017-04-14 10:57:12 +02:00
Timer1.stop();
2017-04-23 11:44:52 +02:00
modconfig=0;
2017-04-14 23:43:53 +02:00
2017-04-23 16:29:12 +02:00
// Affichage titre
2017-04-13 20:45:22 +02:00
lcd.clear();
2017-04-15 16:14:58 +02:00
lcd.print("Strobo"); lcd.setCursor(3, 1); lcd.print("duino");
delay(1200);
2017-04-23 16:29:12 +02:00
// Bouton appuyé
if (digitalRead(Inter) == 0) {modconfig++;}
2017-04-15 16:14:58 +02:00
2017-04-23 16:29:12 +02:00
// Test Flash
2017-04-14 08:58:42 +02:00
digitalWrite (Flash, 1); delayMicroseconds(D_Flash); digitalWrite (Flash, 0);
2017-04-15 16:14:58 +02:00
2017-05-08 13:05:15 +02:00
lcd.clear(); lcd.print("Version"); // Affichage version
lcd.setCursor(0, 1); lcd.print(Ver); // N° de version
2017-04-13 20:45:22 +02:00
delay(1000);
2017-04-23 16:29:12 +02:00
if (digitalRead(Inter) == 0) {modconfig++;} // si bouton toujours appuyé
2017-05-08 13:05:15 +02:00
if (modconfig >= 2) {ConfiG();} // on entre dans le mode config
2017-04-15 16:14:58 +02:00
2017-04-14 18:30:33 +02:00
Enco.write(deg_Initial*4);
2017-04-23 16:29:12 +02:00
degT = 720 / Ncyl;
Nc = 120000000 / Ncyl;
T = 150000;
RArpm.addValue(T);
2017-04-23 11:44:52 +02:00
D_deg = float(T * deg_dem) / float(degT); // Pour le premier cycle
2017-04-23 16:29:12 +02:00
Affich_fond_ecran();
2017-04-11 23:00:12 +02:00
Affic_N_et_deg_dem();
}
2017-04-12 19:28:37 +02:00
2017-04-11 23:00:12 +02:00
void setup() {
2017-04-23 11:44:52 +02:00
if (debug) {Serial.begin(9600);} // Pour debug
pinMode(Etin, INPUT); // Entrée bobine
pinMode(Flash, OUTPUT); // Sortie FLASH
2017-04-13 20:45:22 +02:00
pinMode(Codeur_A, INPUT_PULLUP);
2017-04-12 19:28:37 +02:00
pinMode(Codeur_B, INPUT_PULLUP);
2017-04-23 11:44:52 +02:00
pinMode(Inter, INPUT_PULLUP); // Le codeur met son inter à la masse quand poussé
2017-04-23 16:29:12 +02:00
lcd.begin(8, 2); // LCD 8 colonnes, 2 lignes
2017-04-23 11:44:52 +02:00
IniT();
}
//------------------------------------------------------------------------------
// LOOP
//------------------------------------------------------------------------------
2017-04-12 19:28:37 +02:00
2017-04-23 16:29:12 +02:00
void loop(){
if ((millis() - pm) > Refresh) { // Mise à jour affichage LCD
2017-04-23 11:44:52 +02:00
Affic_N_et_deg_dem(); // Affichage tr/min et deg_demandés
2017-04-14 18:30:33 +02:00
pm = millis();
2017-04-23 11:44:52 +02:00
deg_dem = Enco.read()/4; // On lit les degrés demandés via l'encodeur
2017-04-14 10:57:12 +02:00
}
2017-04-23 16:29:12 +02:00
2017-04-23 11:44:52 +02:00
if (digitalRead(Inter) == 0) { // Si l'inter du codeur est poussé, geler l'affichage
delay(1000); while (digitalRead(Inter) == 0); // Encore poussé, attendre
delay(100); // Continuer
2017-04-11 23:00:12 +02:00
}
2017-04-15 16:14:58 +02:00
}