Projet IMA3 P8, 2015/2016, TD1 : Différence entre versions

De Wiki de Projets IMA
(Partie informatique)
 
(17 révisions intermédiaires par 4 utilisateurs non affichées)
Ligne 2 : Ligne 2 :
  
 
== Cahier des charges ==
 
== Cahier des charges ==
L'objectif de notre projet est la réalisation d'un Chronomètre qui fonctionnera dans 2 modes, un mode décroissant ( partant d'une valeur donnée ) et un mode croissant ( qui mesura le temps passer).
+
L'objectif de notre projet est la réalisation d'un Chronomètre qui fonctionnera dans 2 modes, un mode décroissant ( partant d'une valeur donnée ) et un mode croissant ( qui mesura le temps passé).
 
La partie électronique du système affichera le temps .
 
La partie électronique du système affichera le temps .
La partie informatique du système permettera de choisir le mode de fonctionnement du système et dans le mode décroissant le temps original.
+
La partie informatique du système permettra de choisir le mode de fonctionnement du système et dans le mode décroissant le temps original.
  
  
Materiels choisi :
+
Matériels choisi :
  
 
Une matrice LED 16*16
 
Une matrice LED 16*16
  
Des boutons poussoire
+
Des boutons poussoirs
  
 
Raspberry Pi/Arduino
 
Raspberry Pi/Arduino
Ligne 24 : Ligne 24 :
  
 
=== Partie électronique ===
 
=== Partie électronique ===
Nous avons commencé à étudier la matrice de LED. Le but étant de pouvoir afficher deux chiffres par matrice 8X8. La première fonction que nous avons voulu mettre en place est la fonction chronomètre.
+
Nous avons commencé à étudier la matrice de LED. Le but étant de pouvoir afficher un chiffres par matrice 8X8. La première fonction que nous avons voulu mettre en place est la fonction chronomètre.
Pour cela nous avons dabord chercher à savoir pour un signal 4bits arrivant sur la matrice,quelle été la table de vérité de chacune des led en questions.
+
Pour cela nous avons d’abord cherché à savoir, pour un signal 4bits arrivant sur la matrice,quel été la table de vérité de chacune des led en questions.
pour chaque chiffre à afficher ils nous faut 13 LED à allumer ou non. Toutefois si nous voulons concevoir un circuit logique répondant a cette table de vérité, le travail risque d'etre long est répétitif.
+
Pour chaque chiffre à afficher ils nous faut 13 LED à allumer ou non.
Nous cherchons donc peut etre a faire en sorte que les LED soient géré plutôt dans la partie informatique.
+
 
 +
[[Fichier:Matrice-de-led-rgb-8x8.jpg]]
 +
 
 +
 
 +
En effet nous voulons qu'un chiffre ai une largeur de 3 led sur une hauteur de 5. Les leds centrales supérieure et inférieure du chiffre ne s'allumant jamais.
 +
le trait rouge sur l'image représente la taille du chiffre sur une matrice led.
 +
Toutefois si nous voulons concevoir un circuit logique répondant à cette table de vérité, le travail risque d'etre long est répétitif.
 +
Nous cherchons donc peut être à faire en sorte que les LED soient gérées plutôt dans la partie informatique.
  
 
=== Partie informatique ===
 
=== Partie informatique ===
Nous avons crée une ébauche du futur site web pour parfaitement définir quel sont les paramètre qu'il renverra .
+
Nous avons crée une ébauche du futur site web pour parfaitement définir quel sont les paramètres qu'il renverra.
Dans un second temps nous sommes intéresser a la matrice LED pour comprendre le fonctionnement , pour cela il fallut nous pencher sur la programmation sur Arduino nous avons rencontré un problème dû au firmware, suite à de nombreuse incompréhension de notre part (du au fait qu'on utiliser du code crée pour un firmware plus reçent ) nous avons décider de changer le firmware, il fallut aussi modifier le programme pour pouvoir afficher des chiffre correctement de se fait le code fonctionne et respecte bien la fonction défini dans le cahier des charge
+
Dans un second temps nous sommes intéresser à la matrice LED pour comprendre le fonctionnement, pour cela il fallut nous pencher sur la programmation sur Arduino. Nous avons rencontré un problème dû au firmware, suite à de nombreuse incompréhension de notre part (du au fait qu'on utilisait du code crée pour un firmware plus réçent) nous avons donc décidé de mettre à jour le firmware en utilisant l'Arduino en tant que ISP (In-System Programmer). Il fallut aussi modifier le programme pour pouvoir afficher des chiffres correctement (la librarie avec le code qu'on a utilisé a été conçu pour afficher des lettres avec une serie de codes Hexa pour chaque lettre spécifiant pour chaque LED si elle doit etre allumer ou non, on a donc modifier les serie de codes Hexa pour afficher les numeéros 0 à 9). De se fait le code fonctionne et respecte bien la fonction défini dans le cahier des charge.
[[Fichier:IMAG3115.jpg]]
+
 
 +
[[Fichier:IMAG3115-ConvertImage.jpg]]
  
 
== Séance 2 ==
 
== Séance 2 ==
  
 
=== Partie électronique ===
 
=== Partie électronique ===
A partir de la table de vérité j'ai cherché les équations de chacune des led grâces a des tableaux de Karnaugh.
+
Nous avons pris la décision de gérer la modification du signal 4bits en 13 signaux contrôlant les leds dans la partie électronique.
Sur ALtium designer nous avons conçus un système logique permettant, grâce a un bus de donné de 4 bits de contrôler les 13 LED permettant l’affichage d'un chiffre sur la matrice.
+
A partir de la table de vérité j'ai cherché les équations de chacune des led grâces à des tableaux de Karnaugh.
 +
Sur ALtium designer nous avons conçus un système logique permettant, grâce à un bus de donné de 4 bits de contrôler les 13 LED permettant l’affichage d'un chiffre sur la matrice.
 
J'ai utilisé des portes et, ou , not.
 
J'ai utilisé des portes et, ou , not.
 
Pour vérifier mes résultats j'utilise un Digital IO.
 
Pour vérifier mes résultats j'utilise un Digital IO.
  
 
[[Fichier:Ppp.png]]
 
[[Fichier:Ppp.png]]
 +
 +
 +
Si le signal recu est par exemple "0011" qui correspond au chiffre "3" les leds qui doivent s'allumer sont donc les suivantes
 +
 +
 +
[[Fichier:Matrice-de-led-rgb.jpg]]
  
 
=== Partie informatique ===
 
=== Partie informatique ===
Ligne 54 : Ligne 69 :
  
 
=== Partie électronique ===
 
=== Partie électronique ===
pendant cette séance notre but était de connecter les 13 sorties précédemment configurées au leds correspondantes sur la matrice.
+
Pendant cette séance notre but était de connecter les 13 sorties précédemment configurées au leds correspondantes sur la matrice.
les LED ne peuvent pas être reliées une par une a ces 13 sorties, il était nécessaire d'utiliser une combinaisons de multiplexeurs permettant l'affichage successif de chaque colonnes. La fréquence d'affichage de chaque colonne étant très rapide, notre oeil percevra l'ensemble des LED affichées au meme moment.
+
Les LED ne peuvent pas être reliées une par une à ces 13 sorties, il était nécessaire d'utiliser une combinaisons de multiplexeurs permettant l'affichage successif de chaque colonnes. La fréquence d'affichage de chaque colonne étant très rapide, notre œil percevra l'ensemble des LED affichées au même moment.
nous verrions donc le chiffre affiché dans son entièreté.
+
Nous verrions donc le chiffre affiché dans son entièreté.
 +
 
 +
 
 +
[[Fichier:Structure de l afficheur a matrice.gif]]
 +
 
 +
Si nous choisissons,par exemple,de mettre la colonne 2 à"1"(allumé) et les autres à 0, le message envoyé sur les lignes s'affichera uniquement sur la colonne 2.
 +
 
 +
 
 +
 
 +
N'ayant pas réussi à réaliser ce montage de multiplexeurs sur Altium, nous ne pouvons vous montrer l’affichage d'un chiffre choisi sur la matrice à LED.
  
 
=== Partie informatique ===
 
=== Partie informatique ===
partant de l'ébauche de site internat réaliser a la premier séance nous avons crée un site internet affichant un chronomètre  
+
partant de l'ébauche de site internat réalisé à la premier séance nous avons créé un site internet affichant un chronomètre.
ce site a 3 fonction  
+
Ce site a 3 fonctions  
- démarrer le chronomètre et envois les chiffre qui serrons convertie par le websocket
+
- démarrer le chronomètre et envoyer les chiffres qui seront convertis par le websocket.
- arrêter le chronomètre se qui provoquer l'affichage continue du même chiffre sur la matrice
+
- arrêter le chronomètre ce qui provoque l'affichage continue du même chiffre sur la matrice.
- réinitialiser le chronomètre se qui bloque l'affichage du chronomètre et réactualisera le temps que si le chronomètre et relance
+
- réinitialiser le chronomètre ce qui bloque l'affichage et réactualisera le temps.
le site envoie les donnée d'un seul morceaux donc il réactualise a la fois les minute et les seconde tout les second
+
Le site envoie les donnée d'un seul morceaux donc il réactualise à la fois les minutes et les secondes, ceci toute les secondes.
  
 
== Démonstration ==
 
== Démonstration ==
  
 
== Conclusion ==
 
== Conclusion ==
 +
'''websocket :'''
 +
  #include <stdio.h>
 +
  #include <stdlib.h>
 +
  #include <string.h>
 +
  #include <libwebsockets.h>
 +
  #include <unistd.h>
 +
  #include <termios.h>
 +
  #include "serial.h"
 +
 
 +
  #define MAX_FRAME_SIZE  1024
 +
  #define WAIT_DELAY      50
 +
  #define        SERIAL_DEVICE          "/dev/ttyUSB0"
 +
 
 +
  int sd;
 +
 
 +
  static int callback_http(
 +
  struct libwebsocket_context *this,
 +
  struct libwebsocket *wsi,enum libwebsocket_callback_reasons reason,
 +
  void *user,void *in,size_t len)
 +
  {
 +
  return 0;
 +
  }
 +
 
 +
  static int callback_my(
 +
  struct libwebsocket_context * this,
 +
  struct libwebsocket *wsi,enum libwebsocket_callback_reasons reason,
 +
  void *user,void *in,size_t len)
 +
  {
 +
  switch(reason){
 +
  case LWS_CALLBACK_ESTABLISHED:
 +
    printf("connection established\n");
 +
    break;
 +
  case LWS_CALLBACK_RECEIVE:
 +
                // Ici sont traites les messages envoyes par le navigateur
 +
               
 +
    printf("received data: %s\n",(char *)in);
 +
    // envois des 2 premiers chiffres
 +
    unsigned char byte=(((((char *)in)[0]-'0')<<4) | (((char *)in)[1]-'0'));
 +
    if(write(sd,&byte,1)!=1){ perror("main.write"); exit(-1); }
 +
    // envois des 2 suivants
 +
    unsigned char byte2=(((((char *)in)[2]-'0')<<4) | (((char *)in)[3]-'0'));
 +
    if(write(sd,&byte2,1)!=1){ perror("main.write"); exit(-1); }
 +
  default:
 +
    break;
 +
  }
 +
  return 0;
 +
  }
 +
 
 +
  static struct libwebsocket_protocols protocols[] = {
 +
  {
 +
    "http-only",  // name
 +
    callback_http, // callback
 +
    0,            // data size
 +
    0              // maximum frame size
 +
  },
 +
  {"myprotocol",callback_my,0,MAX_FRAME_SIZE},
 +
  {NULL,NULL,0,0}
 +
  };
 +
 
 +
  int main(void) {
 +
  int port=9000;
 +
  struct lws_context_creation_info info;
 +
  memset(&info,0,sizeof info);
 +
  info.port=port;
 +
  info.protocols=protocols;
 +
  info.gid=-1;
 +
  info.uid=-1;
 +
  struct libwebsocket_context *context=libwebsocket_create_context(&info);
 +
  if(context==NULL){
 +
  fprintf(stderr, "libwebsocket init failed\n");
 +
  return -1;
 +
  }
 +
  printf("starting server...\n");
 +
  sd=serialOpen(SERIAL_DEVICE,SERIAL_BOTH);
 +
  serialConfig(sd,B9600);
 +
  while(1){
 +
  libwebsocket_service(context,WAIT_DELAY);
 +
  }
 +
  serialClose(sd);
 +
  libwebsocket_context_destroy(context);
 +
  return 0;
 +
  }
 +
 +
'''le Html'''
 +
  <nowiki>
 +
  <!DOCTYPE html>
 +
  <html>
 +
  <head>
 +
    <meta charset="utf-8">
 +
    <script src="jquery.js"></script>
 +
    <script type="text/javascript">
 +
  window.WebSocket=(window.WebSocket||window.MozWebSocket);
 +
 
 +
  var websocket=new WebSocket('ws://127.0.0.1:9000','myprotocol');
 +
 
 +
  websocket.onopen=function(){ $('h1').css('color','green'); };
 +
 
 +
  websocket.onerror=function(){ $('h1').css('color','red'); };
 +
 
 +
  websocket.onmessage=function(message){
 +
  console.log(message.data);
 +
  $('#messages').append($('<p>',{ text: message.data }));
 +
  };
 +
 
 +
  function sendMessage(){
 +
  websocket.send($('#message').val());
 +
  $('#message').val('');
 +
  }
 +
    </script>
 +
  <title>Chronometre</title>
 +
  </head>
 +
  <body>
 +
    <h1>Chronometre Status</h1>
 +
    <span id="chronotime">0:00:00:00</span>
 +
  <form name="chronoForm">
 +
    <input type="button" name="startstop" value="start!" onClick="chronoStart()" />
 +
    <input type="button" name="reset" value="reset!" onClick="chronoReset()" />
 +
  </form>
 +
  </body>
 +
  </html>
 +
  </nowiki>
 +
 +
'''Le javacript'''
 +
  <script language="JavaScript">
 +
  <nowiki><!--</nowiki>
 +
  var startTime = 0
 +
  var start = 0
 +
  var end = 0
 +
  var diff = 0
 +
  var timerID = 0
 +
  var osec = -1
 +
  function chrono(){
 +
    end = new Date()
 +
    diff = end - start
 +
    diff = new Date(diff)
 +
    var msec = diff.getMilliseconds()
 +
    var sec = diff.getSeconds()
 +
    var min = diff.getMinutes()
 +
    var hr = diff.getHours()-1
 +
    if (min < 10){
 +
        min = "0" + min
 +
    }
 +
    if (sec < 10){
 +
        sec = "0" + sec
 +
 
 +
    }
 +
    if(msec < 10){
 +
        msec = "00" +msec
 +
    }
 +
    else if(msec < 100){
 +
        msec = "0" +msec
 +
    }
 +
    document.getElementById("chronotime").innerHTML = hr + ":" + min + ":" + sec + ":" + msec
 +
    timerID = setTimeout("chrono()", 10)
 +
    if(sec!=osec)   
 +
        {
 +
        websocket.send(min+sec)
 +
        osec=sec
 +
        }
 +
 
 +
  }
 +
  function chronoStart(){
 +
    document.chronoForm.startstop.value = "stop!"
 +
    document.chronoForm.startstop.onclick = chronoStop
 +
    document.chronoForm.reset.onclick = chronoReset
 +
    start = new Date()
 +
    chrono()
 +
  }
 +
  function chronoContinue(){
 +
    document.chronoForm.startstop.value = "stop!"
 +
    document.chronoForm.startstop.onclick = chronoStop
 +
    document.chronoForm.reset.onclick = chronoReset
 +
    start = new Date()-diff
 +
    start = new Date(start)
 +
    chrono()
 +
  }
 +
  function chronoReset(){
 +
    document.getElementById("chronotime").innerHTML = "0:00:00:000"
 +
    start = new Date()
 +
  }
 +
  function chronoStopReset(){
 +
    document.getElementById("chronotime").innerHTML = "0:00:00:000"
 +
    document.chronoForm.startstop.onclick = chronoStart
 +
  }
 +
  function chronoStop(){
 +
    document.chronoForm.startstop.value = "start!"
 +
    document.chronoForm.startstop.onclick = chronoContinue
 +
    document.chronoForm.reset.onclick = chronoStopReset
 +
    clearTimeout(timerID)
 +
  }
 +
 
 +
  //-->
 +
  </script>

Version actuelle datée du 31 décembre 2016 à 23:32

Projet IMA3-SC 2015/2016 : Titre

Cahier des charges

L'objectif de notre projet est la réalisation d'un Chronomètre qui fonctionnera dans 2 modes, un mode décroissant ( partant d'une valeur donnée ) et un mode croissant ( qui mesura le temps passé). La partie électronique du système affichera le temps . La partie informatique du système permettra de choisir le mode de fonctionnement du système et dans le mode décroissant le temps original.


Matériels choisi :

Une matrice LED 16*16

Des boutons poussoirs

Raspberry Pi/Arduino

Carte NanoBoard


Optionnel: Si nous avons assez de temps il est possible de rajouter des options de personnalisation sur l'interface web (exemple : changement de couleurs du chronomètre).

Séance 1

Partie électronique

Nous avons commencé à étudier la matrice de LED. Le but étant de pouvoir afficher un chiffres par matrice 8X8. La première fonction que nous avons voulu mettre en place est la fonction chronomètre. Pour cela nous avons d’abord cherché à savoir, pour un signal 4bits arrivant sur la matrice,quel été la table de vérité de chacune des led en questions. Pour chaque chiffre à afficher ils nous faut 13 LED à allumer ou non.

Matrice-de-led-rgb-8x8.jpg


En effet nous voulons qu'un chiffre ai une largeur de 3 led sur une hauteur de 5. Les leds centrales supérieure et inférieure du chiffre ne s'allumant jamais. le trait rouge sur l'image représente la taille du chiffre sur une matrice led. Toutefois si nous voulons concevoir un circuit logique répondant à cette table de vérité, le travail risque d'etre long est répétitif. Nous cherchons donc peut être à faire en sorte que les LED soient gérées plutôt dans la partie informatique.

Partie informatique

Nous avons crée une ébauche du futur site web pour parfaitement définir quel sont les paramètres qu'il renverra. Dans un second temps nous sommes intéresser à la matrice LED pour comprendre le fonctionnement, pour cela il fallut nous pencher sur la programmation sur Arduino. Nous avons rencontré un problème dû au firmware, suite à de nombreuse incompréhension de notre part (du au fait qu'on utilisait du code crée pour un firmware plus réçent) nous avons donc décidé de mettre à jour le firmware en utilisant l'Arduino en tant que ISP (In-System Programmer). Il fallut aussi modifier le programme pour pouvoir afficher des chiffres correctement (la librarie avec le code qu'on a utilisé a été conçu pour afficher des lettres avec une serie de codes Hexa pour chaque lettre spécifiant pour chaque LED si elle doit etre allumer ou non, on a donc modifier les serie de codes Hexa pour afficher les numeéros 0 à 9). De se fait le code fonctionne et respecte bien la fonction défini dans le cahier des charge.

IMAG3115-ConvertImage.jpg

Séance 2

Partie électronique

Nous avons pris la décision de gérer la modification du signal 4bits en 13 signaux contrôlant les leds dans la partie électronique. A partir de la table de vérité j'ai cherché les équations de chacune des led grâces à des tableaux de Karnaugh. Sur ALtium designer nous avons conçus un système logique permettant, grâce à un bus de donné de 4 bits de contrôler les 13 LED permettant l’affichage d'un chiffre sur la matrice. J'ai utilisé des portes et, ou , not. Pour vérifier mes résultats j'utilise un Digital IO.

Ppp.png


Si le signal recu est par exemple "0011" qui correspond au chiffre "3" les leds qui doivent s'allumer sont donc les suivantes


Matrice-de-led-rgb.jpg

Partie informatique

Dans Cette séance de Projet Nous nous somme concentré sur la réalisation de la liaison ordinateur arduino pour pouvoir réaliser les premier teste pour cela il fallut adapter le programme du websocket pour qu'il puisse envoyer des information viable pour l'arduino (et plus tard le FPGA) nous avons rencontré quel que problème lier a la fois au temps de réception des matrice et a l'actualisation de l'affichage de l'as matrice ce qui provoquer des problème d'affichage (nombre incorrect) et des désynchronisation ( la matrice était trop lente ) le premier problème fût régler en ajoutant un pause entre l'envoie des 2 chiffres ,l'autre problème fût de modifier la pause initiale pour arriver a un actualisation d'une seconde de se fait a l'initialisation il y a une légère différence entre se que le site affiche et se que la matrice montre mais cette écart étant constant cela ne pose pas de problème une fois ces 2 problème régler

nous avons crée un premier site qui avais pour seul fonction de pouvoir écrire un nombre et l'envoyer a la matrice

Séance 3

Partie électronique

Pendant cette séance notre but était de connecter les 13 sorties précédemment configurées au leds correspondantes sur la matrice. Les LED ne peuvent pas être reliées une par une à ces 13 sorties, il était nécessaire d'utiliser une combinaisons de multiplexeurs permettant l'affichage successif de chaque colonnes. La fréquence d'affichage de chaque colonne étant très rapide, notre œil percevra l'ensemble des LED affichées au même moment. Nous verrions donc le chiffre affiché dans son entièreté.


Structure de l afficheur a matrice.gif

Si nous choisissons,par exemple,de mettre la colonne 2 à"1"(allumé) et les autres à 0, le message envoyé sur les lignes s'affichera uniquement sur la colonne 2.


N'ayant pas réussi à réaliser ce montage de multiplexeurs sur Altium, nous ne pouvons vous montrer l’affichage d'un chiffre choisi sur la matrice à LED.

Partie informatique

partant de l'ébauche de site internat réalisé à la premier séance nous avons créé un site internet affichant un chronomètre. Ce site a 3 fonctions - démarrer le chronomètre et envoyer les chiffres qui seront convertis par le websocket. - arrêter le chronomètre ce qui provoque l'affichage continue du même chiffre sur la matrice. - réinitialiser le chronomètre ce qui bloque l'affichage et réactualisera le temps. Le site envoie les donnée d'un seul morceaux donc il réactualise à la fois les minutes et les secondes, ceci toute les secondes.

Démonstration

Conclusion

websocket :

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <libwebsockets.h>
 #include <unistd.h>
 #include <termios.h>
 #include "serial.h"
 
 #define MAX_FRAME_SIZE  1024
 #define WAIT_DELAY      50
 #define         SERIAL_DEVICE           "/dev/ttyUSB0"
 
 int sd;
 
 static int callback_http(
 struct libwebsocket_context *this,
 struct libwebsocket *wsi,enum libwebsocket_callback_reasons reason,
 void *user,void *in,size_t len)
 {
 return 0;
 }
 
 static int callback_my(
 struct libwebsocket_context * this,
 struct libwebsocket *wsi,enum libwebsocket_callback_reasons reason,
 void *user,void *in,size_t len)
 {
 switch(reason){
 case LWS_CALLBACK_ESTABLISHED:
   printf("connection established\n");
   break;
 case LWS_CALLBACK_RECEIVE:
               // Ici sont traites les messages envoyes par le navigateur
               
   printf("received data: %s\n",(char *)in);
   // envois des 2 premiers chiffres
   unsigned char byte=(((((char *)in)[0]-'0')<<4) | (((char *)in)[1]-'0'));
   if(write(sd,&byte,1)!=1){ perror("main.write"); exit(-1); }
   // envois des 2 suivants
   unsigned char byte2=(((((char *)in)[2]-'0')<<4) | (((char *)in)[3]-'0'));
   if(write(sd,&byte2,1)!=1){ perror("main.write"); exit(-1); }
 default:
   break;
 }
 return 0;
 }
 
 static struct libwebsocket_protocols protocols[] = {
 {
   "http-only",   // name
   callback_http, // callback
   0,             // data size
   0              // maximum frame size
 },
 {"myprotocol",callback_my,0,MAX_FRAME_SIZE},
 {NULL,NULL,0,0}
 };
 
 int main(void) {
 int port=9000;
 struct lws_context_creation_info info;
 memset(&info,0,sizeof info);
 info.port=port;
 info.protocols=protocols;
 info.gid=-1;
 info.uid=-1;
 struct libwebsocket_context *context=libwebsocket_create_context(&info);
 if(context==NULL){
 fprintf(stderr, "libwebsocket init failed\n");
 return -1;
 }
 printf("starting server...\n");
 sd=serialOpen(SERIAL_DEVICE,SERIAL_BOTH);
 serialConfig(sd,B9600);
 while(1){
 libwebsocket_service(context,WAIT_DELAY);
 }
 serialClose(sd);
 libwebsocket_context_destroy(context);
 return 0;
 }

le Html

 
  <!DOCTYPE html>
  <html>
  <head>
    <meta charset="utf-8">
    <script src="jquery.js"></script>
    <script type="text/javascript">
  window.WebSocket=(window.WebSocket||window.MozWebSocket);
  
  var websocket=new WebSocket('ws://127.0.0.1:9000','myprotocol');
  
  websocket.onopen=function(){ $('h1').css('color','green'); };
  
  websocket.onerror=function(){ $('h1').css('color','red'); };
  
  websocket.onmessage=function(message){
  console.log(message.data);
  $('#messages').append($('<p>',{ text: message.data }));
  };
  
  function sendMessage(){
  websocket.send($('#message').val());
  $('#message').val('');
  }
    </script>
  <title>Chronometre</title>
  </head>
  <body>
    <h1>Chronometre Status</h1>
    <span id="chronotime">0:00:00:00</span>
  <form name="chronoForm">
    <input type="button" name="startstop" value="start!" onClick="chronoStart()" />
    <input type="button" name="reset" value="reset!" onClick="chronoReset()" />
  </form>
  </body>
  </html>
  

Le javacript

 <script language="JavaScript">
 <!--
 var startTime = 0
 var start = 0
 var end = 0
 var diff = 0
 var timerID = 0
 var osec = -1
 function chrono(){
   end = new Date()
   diff = end - start
   diff = new Date(diff)
   var msec = diff.getMilliseconds()
   var sec = diff.getSeconds()
   var min = diff.getMinutes()
   var hr = diff.getHours()-1
   if (min < 10){
       min = "0" + min
   }
   if (sec < 10){
       sec = "0" + sec
 
   }
   if(msec < 10){
       msec = "00" +msec
   }
   else if(msec < 100){
       msec = "0" +msec
   }
   document.getElementById("chronotime").innerHTML = hr + ":" + min + ":" + sec + ":" + msec
   timerID = setTimeout("chrono()", 10)
   if(sec!=osec)    
       {
       websocket.send(min+sec)
       osec=sec
       }
 
 }
 function chronoStart(){
   document.chronoForm.startstop.value = "stop!"
   document.chronoForm.startstop.onclick = chronoStop
   document.chronoForm.reset.onclick = chronoReset
   start = new Date()
   chrono()
 }
 function chronoContinue(){
   document.chronoForm.startstop.value = "stop!"
   document.chronoForm.startstop.onclick = chronoStop
   document.chronoForm.reset.onclick = chronoReset
   start = new Date()-diff
   start = new Date(start)
   chrono()
 }
 function chronoReset(){
   document.getElementById("chronotime").innerHTML = "0:00:00:000"
   start = new Date()
 }
 function chronoStopReset(){
   document.getElementById("chronotime").innerHTML = "0:00:00:000"
   document.chronoForm.startstop.onclick = chronoStart
 }
 function chronoStop(){
   document.chronoForm.startstop.value = "start!"
   document.chronoForm.startstop.onclick = chronoContinue
   document.chronoForm.reset.onclick = chronoStopReset
   clearTimeout(timerID)
 }
 
 //-->
 </script>