Files
c_pompes/AutomForArduino.cpp

428 lines
9.9 KiB
C++
Raw Permalink Normal View History

2025-11-30 09:48:43 +01:00
#include <stdio.h>
#include <time.h>
/* From Arduino.h */
#define HIGH 0x1
#define LOW 0x00
#define IO_INPUT 0x02
#define IO_OUTPUT 0x04
#define DIGITAL 0x08
#define ANALOG 0x10
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define true 1
#define false 0
// Temps
// Timestamp unix en millisecondes
// t_start : timestamp de départ
// t_backup : timestamp de la précédente itération
// t_elapsed : temps écoulé en secondes depuis le départ
// dt (delta t) : temps écoulé en secondes depuis la dernière itération
unsigned long t_start, t_backup;
double t_elapsed, dt;
unsigned long millis()
{
struct timespec now;
clock_gettime(CLOCK_REALTIME, &now);
return ((unsigned long)now.tv_sec) * 1000 + ((unsigned long)now.tv_nsec) / 1000000;
}
#define OP_DIGITAL_READ 0
#define OP_DIGITAL_WRITE 1
#define OP_ANALOG_READ 2
#define OP_ANALOG_WRITE 3
#define OP_PIN_MODE 4
typedef struct PinIO
{
unsigned char mode;
int ivalue;
double dvalue;
int error; // % = 1 /error ex 1 / 20 = 5 %
double efficacite; // 0 - 100%
unsigned long start;
unsigned long time;
double duration;
unsigned int nb; // compteur d'activation
2025-12-07 15:51:07 +01:00
int memory; // valeur précédente
unsigned char raising; // front montant
unsigned char falling; // front descendant
2025-11-30 09:48:43 +01:00
} PinIO;
PinIO _digital[256];
void pinMode(unsigned char p, unsigned char mode)
{
_digital[p].mode = 0x01 | mode;
_digital[p].ivalue = 0;
_digital[p].dvalue = 0.0;
_digital[p].nb = 0;
_digital[p].time = 0.0;
_digital[p].duration = 0.0;
_digital[p].start = 0;
_digital[p].raising = 0;
_digital[p].memory = 0;
}
/* KEYBOARD */
typedef struct
{
2025-12-03 23:27:56 +01:00
int input;
2025-11-30 09:48:43 +01:00
int vKey;
} KeyboardIO;
#define NB_KEYBOARD 10
KeyboardIO _keyboard[NB_KEYBOARD];
void LireClavier(int ch)
{
for (int i = 0; i < NB_KEYBOARD; i++)
{
_digital[_keyboard[i].input].ivalue = (ch == _keyboard[i].vKey);
_digital[_keyboard[i].input].raising = _digital[_keyboard[i].input].ivalue > _digital[_keyboard[i].input].memory;
_digital[_keyboard[i].input].falling = _digital[_keyboard[i].input].ivalue < _digital[_keyboard[i].input].memory;
_digital[_keyboard[i].input].memory = _digital[_keyboard[i].input].ivalue;
}
}
/* ********************************************************
* TEMPORISATION RETARD A LA MONTEE *
* La sortie passe à 1 au bout de la tempo *
******************************************************** */
class TemporisationRetardMontee
{
// methodes
public :
// Contructeur qui prend la duree souhaitee de la temporisation
TemporisationRetardMontee(unsigned long duree)
{
this->duree = duree;
sortie = false;
captureTemps = false;
}
// Activation de la temporisation. Doit etre fait tout le temps de la duree de la tempo
void activation()
{
// Capture du temps de reference
if(!captureTemps)
{
debut = millis();
captureTemps = true;
}
// Calcul du temps ecoule depuis le temps de reference
tempsEcoule = millis() - debut;
// Mise a 1 de la fin de tempo
if (tempsEcoule >= duree)
{
sortie = true;
captureTemps = false;
}
else
{
sortie = false;
}
}
// Precharge de la temporisation
void setDuree(unsigned long majduree)
{
duree = majduree;
sortie = false;
captureTemps = false;
}
// Interrogation du bit de fin de tempo
bool getSortie()
{
return(sortie);
}
// Recuperation du temps ecoule depuis le debut si necessaire
unsigned long getTempsEcoule()
{
return(tempsEcoule);
}
// Attributs
private:
unsigned long duree;
unsigned long debut;
unsigned long tempsEcoule;
bool captureTemps;
bool sortie;
};
/********************************************************
* TEMPORISATION RETARD A LA DESCENTE *
* La sortie passe à 0 au bout de la tempo *
*********************************************************/
class TemporisationRetardDescente
{
public :
// Contructeur qui prend la duree souhaitee de la temporisation
TemporisationRetardDescente(unsigned long duree)
{
this->duree = duree;
sortie = false;
captureTemps = false;
}
// Activation de la temporisation. Doit etre fait tout le temps de la duree de la tempo
void activation()
{
// Capture du temps de reference
if(!captureTemps)
{
debut = millis();
captureTemps = true;
sortie = true;
}
// Calcul du temps ecoule depuis le temps de reference
tempsEcoule = millis() - debut;
// Mise a 0 de la fin de tempo
if (tempsEcoule >= duree)
{
sortie = false;
captureTemps = false;
}
}
// Precharge de la temporisation
void setDuree(unsigned long majduree)
{
duree = majduree;
sortie = false;
captureTemps = false;
}
// Interrogration du bit de fin de tempo
bool getSortie()
{
return(sortie);
}
// Recuperation du temps ecoule depuis le debut si necessaire
unsigned long getTempsEcoule()
{
return(tempsEcoule);
}
private:
unsigned long duree;
unsigned long debut;
unsigned long tempsEcoule;
bool captureTemps;
bool sortie;
};
/********************************************************
**** CLIGNOTEUR *************************************
*********************************************************/
class Clignoteur
{
// methodes
public :
// Construteur qui prend en parametre le temps haut ou bas souhaitee
Clignoteur(int baseDeTemps)
{
this->baseDeTemps = baseDeTemps;
}
// Fonction qui renvoie true si le clignoteur est ├á l'├®tat haut et false s'il est ├á l'├®tat bas
bool statut()
{
return ((millis() / baseDeTemps) % 2 == 1);
}
// Attributs
private:
int baseDeTemps;
};
/********************************************************
**** COMPTEUR *************************************
**** ATTENTION : Il faut gerer le front montant dans le programme
*********************************************************/
class Compteur
{
// methodes
public :
// Constructeur qui prend en parametre la valeur de preselection
Compteur(int valeurPreselection)
{
this->valeurPreselection = valeurPreselection;
valeur = 0;
}
// Incrementation du compteur
void incrementer()
{
valeur++;
}
// Decrementation du compteur
void decrementer()
{
valeur--;
}
// remise a zero du compteur
void remettreAZero()
{
valeur = 0;
}
// recuperation de la valeur courante
int getValeurCourante()
{
return(valeur);
}
// est-ce que la preselection est atteinte (sortie Q compteur Siemens ou Schnieder)
bool getSortie()
{
return(valeur == valeurPreselection);
}
// Attributs
private:
int valeur;
int valeurPreselection;
};
/********************************************************
**** MISE A L'ECHELLE DE VALEUR ************************
*********************************************************/
class MiseAEchelle
{
public :
// Constructeur qui ne prend en parametre la plage d'entree et la plage de sortie
MiseAEchelle(float minEntree,float maxEntree,float minSortie,float maxSortie)
{
this->minEntree = minEntree;
this->maxEntree = maxEntree;
this->minSortie = minSortie;
this->maxSortie = maxSortie;
}
// fonction de conversion qui prend la valeur a convertir et renvoie la valeur convertie
float convertir(float valeurAConvertir)
{
if(valeurAConvertir >= minEntree && valeurAConvertir <= maxEntree)
{
float norm = (1 / (maxEntree - minEntree)) * (valeurAConvertir - minEntree);
float scale = (maxSortie - minSortie) * norm + minSortie;
return(scale);
}
return(-1000);
}
// Attributs
private:
float minEntree;
float minSortie;
float maxEntree;
2025-12-07 15:51:07 +01:00
float maxSortie;
2025-11-30 09:48:43 +01:00
};
/* READ */
int digitalRead(int p)
{
return ((_digital[p].mode & IO_INPUT) && (_digital[p].mode & DIGITAL) && (_digital[p].mode & 0x01)) ? _digital[p].ivalue : 0;
}
double analogRead(int p)
{
return ((_digital[p].mode & IO_INPUT) && (_digital[p].mode & ANALOG) && (_digital[p].mode & 0x01)) ? _digital[p].dvalue : 0.0;
}
/* WRITE */
void digitalWrite(unsigned int p, int value)
{
2025-12-03 23:27:56 +01:00
if (p > 255)
2025-11-30 09:48:43 +01:00
{
printf("Pin %d is out of Range.", p);
return;
}
// En panne !
if (!(_digital[p].mode & 0x01))
{
2025-12-07 15:51:07 +01:00
_digital[p].ivalue = 0;
_digital[p].dvalue = 0.0;
2025-11-30 09:48:43 +01:00
return;
}
if (!(_digital[p].mode & IO_OUTPUT && _digital[p].mode & DIGITAL))
{
printf("Pin %d is not a digital input.", p);
return;
}
unsigned long m = millis();
if (value != _digital[p].ivalue)
{
_digital[p].time = _digital[p].time > 5000 ? 0 : 5000 - _digital[p].time;
}
else
{
_digital[p].time += m - _digital[p].start;
}
if (value && !_digital[p].ivalue)
{
_digital[p].start = m;
_digital[p].nb += 1;
}
else if (value)
{
_digital[p].duration += dt;
}
2025-12-04 20:36:52 +01:00
_digital[p].raising = (_digital[p].memory < _digital[p].ivalue);
_digital[p].falling = (_digital[p].memory > _digital[p].ivalue);
_digital[p].memory = _digital[p].ivalue;
2025-11-30 09:48:43 +01:00
_digital[p].ivalue = value;
}
void analogWrite(unsigned int p, double value)
{
2025-12-03 23:27:56 +01:00
if (p > 31)
2025-11-30 09:48:43 +01:00
{
printf("Pin %d is out of Range.", p);
return;
}
// En panne
if (!(_digital[p].mode & 0x01))
{
return;
}
if (!(_digital[p].mode & IO_OUTPUT) || !(_digital[p].mode & ANALOG))
{
printf("Pin %d is not a analog input.", p);
return;
}
_digital[p].dvalue = value;
}
/* ********************************************************
* Console *
* *
******************************************************** */
void ConsoleInit()
{
setlocale(LC_ALL, ""); // Activer le support des caractères Unicode
setlocale(LC_NUMERIC, "C");
initscr(); // Initialise ncurses
raw(); // Mode brut, sans besoin de validation par Entrée
keypad(stdscr, TRUE); // Active les touches spéciales comme ESC
nodelay(stdscr, TRUE); // Mode non-bloquant pour getch()
noecho(); // Ne pas afficher les touches appuyées
curs_set(0); // Masquer le curseur
}