Projet IMA3 P8, 2015/2016, TD1 : Différence entre versions
(→Partie informatique) |
m (a déplacé Projet IMA3 P8, 2014/2015, TD1 vers Projet IMA3 P8, 2015/2016, TD1) |
||
(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 | + | 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 | + | 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 | Une matrice LED 16*16 | ||
− | Des boutons | + | 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 | + | 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 | + | 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. | |
− | Nous cherchons donc peut | + | |
+ | [[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 | + | 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 | + | 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 | + | 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 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. | |
− | + | 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é. | |
+ | |||
+ | |||
+ | [[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 | + | 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 | + | - démarrer le chronomètre et envoyer les chiffres qui seront convertis par le websocket. |
− | - arrêter le chronomètre | + | - arrêter le chronomètre ce qui provoque l'affichage continue du même chiffre sur la matrice. |
− | - réinitialiser le chronomètre | + | - 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 == | == 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
Sommaire
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.
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.
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.
Si le signal recu est par exemple "0011" qui correspond au chiffre "3" les leds qui doivent s'allumer sont donc les suivantes
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é.
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>