#include #include /* 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 int memory; unsigned char raising; unsigned char falling; } 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 { char input; 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; float maxSortie; }; /* 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) { if (p < 0 || p > 255) { 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 & 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; } _digital[p].ivalue = value; } void analogWrite(unsigned int p, double value) { if (p < 0 || p > 31) { 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 }