Skip to content

Instantly share code, notes, and snippets.

@Dabsunter
Created May 20, 2022 12:04
Show Gist options
  • Save Dabsunter/d3fc2f58e6678476030f656e69ac4ed4 to your computer and use it in GitHub Desktop.
Save Dabsunter/d3fc2f58e6678476030f656e69ac4ed4 to your computer and use it in GitHub Desktop.
//Auteurs: KENGNE TAGNE Ivan, CHAUVEL Benjamin
//Groupe: 3
#include <TimerOne.h>
#include <analogComp.h>
#include <LiquidCrystal.h>
// Pins de l'écran lcd
const byte d7 = 2;
const byte d6 = 3;
const byte d5 = 4;
const byte d4 = 5;
const byte en = 11;
const byte rs = 12;
// Pins divers
const byte pinbutton= 18;
const byte ledverte=36;
const byte ledbleue= 6;
const byte ledrouge= 37;
// temps utilisés pour la (dé)modulation
const byte T0= 20;
const byte T1=35;
const byte Trep=60;
byte deltaT=5;
// lettre lu depuis le port série
char lettre;
// état de lecture (démodulation)
bool lecture = false;
// index du prochain bit à être lu
int idxBit = 0;
// temps mesuré
int temps;
// position sur l'écran lcd
int lcdpos;
// chiffre décodé
int chiffre=0;
// masque
int bytx;
unsigned int t0,t1;
// Déclaration de l'écran lcd
LiquidCrystal lcd(rs,en,d4,d5,d6,d7);
void setup() {
// Configuration des pins
pinMode(ledrouge,OUTPUT);
pinMode(ledverte,OUTPUT);
pinMode(pinbutton,INPUT);
// Démarrage de la communication sur le port série (avec le PC)
Serial.begin(115200);
// Test de l'écran avec un message basique
lcd.print("Pret");
// Configuration de l'écran (16 colonnes, 2 lignes)
lcd.begin(16,2);
// On associe le front montant du bouton poussoir à une interruption sur
// la fonction effacer
attachInterrupt(digitalPinToInterrupt(pinbutton), effacer, RISING);
// On associe la réception d'un signal (front montant) sur le pin A0 à
// une interruption sur la fonction comDetected
analogComparator.setOn(INTERNAL_REFERENCE,A0);
analogComparator.enableInterrupt(comDetected,RISING);
// On initialise Timer1 (interface pour l'horloge matérielle de la carte
// et on dit seulement qu'elle déclenchera une interruption sur la fonction
// inactif
Timer1.initialize();
Timer1.attachInterrupt(inactif);
}
// Appelé (interruption) en cas d'appui sur le bouton poussoir
void effacer(){
// Efface et place le curseur en haut à gauche
lcd.clear();
// Place le curseur en haut à gauche (inutile)
//lcd.setCursor(0,0);
}
// Appelé (interruption) par le timet après trop d'inactivité
void inactif() {
// Allume la led verte
digitalWrite(ledverte,HIGH);
// Remet la position d'écriture à 0 (voir loop() pour voir ce que ça implique)
lcdpos=0;
}
// Envoie l'octet k
void modulation(byte k){
// On allume la led rouge
digitalWrite(ledrouge,HIGH);
// on attend dt
delay(deltaT);
// Pour chaque i dans [0,8[ (= [0,7])
for (int i=0; i<8; i++) {
// on éteint la led rouge
digitalWrite(ledrouge,LOW);
// on créé le masque pour récupérer le i ème bit
bytx = 1 << i;
// Si k a son i ème bit = à 1
if ((k & bytx) != 0) {
// on attend t1
delay(T1);
} else {
// sinon on attend t0
delay(T0);
}
// on réallume la led rouge
digitalWrite(ledrouge,HIGH);
// on attend dt
delay(deltaT);
}
// Finalement on éteint la led rouge et on allume la led bleue
digitalWrite(ledrouge,LOW);
digitalWrite(ledbleue,HIGH);
// On attend t_rep
delay(Trep);
// Puis on éteint la led bleue
digitalWrite(ledbleue,LOW);
}
// Appelé quand on a reçu l'octet chiffre
void demodulation(int chiffre) {
// On écrit le caractère associé dans le serial du PC
Serial.print(String(char(chiffre)));
// On place le curseur à la bonne position sur la 2e ligne
lcd.setCursor(lcdpos, 1);
// On écrit le caractère correspondant à l'octet déchiffré
lcd.print(String(char(chiffre)));
}
// Appelé (interruption) quand on reçoit un signal lumineux
void comDetected(){
// Si on a déjà commencé la lecture
if (lecture) {
// On fixe t1 (on a reçu ce signal à t1)
t1 = millis();
// On mesure le temps écoulé
temps = t1-t0;
// On l'envoie sur le port série (PC)
Serial.println("temps:");
Serial.println(temps);
// Si temps ~ T0
if ((temps > 1.5*deltaT) && (temps < 1.5*T0)) {
// On lit un bit nul (rien à faire)
Serial.println("Ajout: 0");
Serial.println(chiffre);
Serial.println(idxBit);
} else if ((temps > 1.5*deltaT)&&(temps < 1.5*T1)) {
// Sinon si temps ~ T1
// On lit un bit 1
Serial.println("Ajout: 1");
// On ajoute 2^idxBit à chiffre
chiffre = chiffre + puissance(idxBit);
Serial.println(chiffre);
Serial.println(idxBit);
}
// On va recevoir le bit suivant
idxBit++;
// On décale t1 vers t0 (glissement du contexte)
t0 = t1;
// Si on a lu les 8 bits
if (idxBit > 7) {
// on arrête la lecture
lecture = false;
// on traite le chiffre décodé (voir fonction demodulation)
demodulation(chiffre);
// on réinitialise chiffre pour les prochaines lectures
chiffre=0;
// On lance le timer qui détectera une éventuelle inactivité
Timer1.setPeriod(1000*Trep);
Timer1.start();
}
} else {
// Sinon, on commence la lecture
lecture = true;
// On va recevoir le bit d'index 0 (le premier)
idxBit=0;
// On fixe t0 (on a commencé la lecture à t0)
t0 = millis();
}
}
void loop() {
// Si un octet est en attente sur le port série
if(Serial.available()>0){
// On lit cet octet (=caractère en ASCII)
lettre = Serial.read();
// Si c'est le premier caractère à écrire
if (lcdpos == 0) {
// On efface l'écran
lcd.clear();
// On informe le PC que le message a été transmis
Serial.println();
Serial.println("Message envoyé:");
}
// On arrête le timer censé détecter l'inactivité (on vient de lire un caractère)
Timer1.stop();
// on éteint la led verte
digitalWrite(ledverte,LOW);
// On place le curseur à la bonne position sur la 1ère ligne
lcd.setCursor(lcdpos,0);
// On écrit la lettre
lcd.print(lettre);
// On envoie la lettre via LiFi
modulation(lettre);
// Une lettre vient d'être traitée, on avance la position
lcdpos++;
}
}
// = 2^expo
int puissance(int expo) {
int resultat = 1;
for (int t=0; t<expo; t++) {
resultat = 2*resultat;
}
return resultat;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment