
Célérité des ultrasons dans l'air.
La bibliothèque JavaScript web_sciences permet de configurer une interface interactive pour des expérimentations en physique-chimie et SVT. En définissant quelques variables, vous pouvez personnaliser les mesures et les graphiques.
Le code JavaScript, doit être écrit sous la forme d'une chaîne de caractères. En fonction du type d'utilisation choisie, ce code sera inséré automatiquement dans une cellule Jupyter ou dans un fichier HTML.
mode
)"point"
: Arduino envoie une seule mesure sur demande."temporel"
: Arduino envoie un flux continu de mesures."commande"
: Arduino exécute des actions spécifiques basées sur l'interaction utilisateur.mode = "temporel";
commandes
)texte_bouton
: texte affiché sur le bouton.arduino
: commande envoyée à la carte Arduino.commandes = [{texte_bouton: "Charge", arduino: "charge"}, {texte_bouton: "Décharge", arduino: "decharge"}];
series
)grandeur
: nom de la grandeur mesurée.unite
: unité correspondante.series
.series = [{grandeur: "Uc", unite: "V"}, {grandeur: "E", unite: "V"}];
axes
)nom
: label de l'axe.unite
: unité correspondante.axes = [{nom: "Temps", unite: "s"}, {nom: "Uc", unite: "V"}];
series
.d (cm)
).series
.tableur
est un boolean qui formatte la Copie presse papier
au format tableur. Elle est intialisée à false
par defaut.
tableur = true;
stop_possible
est un boolean qui ajoute un bouton permettant de stopper
les mesures dans le cas de mesures temporelles longues. Elle est intialisée à false
par defaut.
stop_possible = true;
precision
est un entier qui permet de préciser le nombre
de chiffres significatifs utilisés par le script. Elle est intialisée à 3
par defaut.
precision = 5;
car_par_ligne
est un entier qui permet de modifier le nombre
de caractères par lignes utilisés chiffres significatifs utilisés dans la Copie presse papier
Elle est intialisée à 70
par defaut.
car_par_ligne = 85;
mode = "commande";
commandes = [{texte_bouton: "Rouge", arduino: "rouge"},
{texte_bouton: "Vert", arduino: "vert"},
{texte_bouton: "Stop", arduino: "stop"}];
mode = "temporel";
commandes = [{texte_bouton: "Démarrer les mesures", arduino: "start"}];
series = [{grandeur: "Température", unite: "°C"}];
axes = [{nom: "Temps", unite: "s"},
{nom: "Température", unite: "°C"}];
titre_graphe = "Loi phénoménologique de Newton";
mode = "point";
commandes = [{texte_bouton:"Mesure", arduino:"mesure"}];
series = [{grandeur: "P", unite: "hPa"}];
titre_graphe = "Loi de Mariotte";
axes = [{grandeur: "V", unite: "mL"}, {grandeur: "P", unite: "hPa"}];
web_sciences.py
et placez-le dans le même dossier que votre notebook Jupyter. Puis, importez-le :
from web_sciences import WebSciences
my_init = """
var mode = "point";
var commandes = [{texte_bouton: "Mesure", arduino: "vas_y"}];
var series = [{grandeur: "T", unite: "°C"}];
"""
affiche
:
interface = WebSciences(my_init)
interface.affiche()
Web Sciences
dans un Fichier HTML distribuable aux élèvesinsere_code.py
web_sciences_complet.html
insere_code.py
et ajoutez votre code JavaScript :
my_init = """
mode = "point";
commandes = [{texte_bouton: "Mesure", arduino: "vas_y"}];
series = [{grandeur: "T", unite: "°C"}];
"""
nom_fichier_html = "interface_arduino.html"
python insere_code.py
Pour une utilisation avec un tableur, ajoutez la ligne suivante dans votre code JavaScript :
var tableur = true;
Cette section explique comment coder les programmes Arduino nécessaires pour les trois modes de fonctionnement
commande
, point
, et temporel
. Chaque mode est présenté avec un exemple de code et des
explications détaillées.
Le mode commande permet à l'Arduino de réagir à des commandes reçues via la liaison série. Il exécute des actions spécifiques et renvoie une réponse à chaque commande. Voici un exemple :
/* déclaration des constantes */
const int ledPin = 13; // Exemple : une LED connectée à la broche 13
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT); // Configure la broche comme sortie
delay(1);
}
void loop() {
if (Serial.available()) {
String chaine = Serial.readString(); // Lecture de la commande
if (chaine == "allume") {
digitalWrite(ledPin, HIGH); // Allume la LED
Serial.println("LED allumée");
} else if (chaine == "eteint") {
digitalWrite(ledPin, LOW); // Éteint la LED
Serial.println("LED éteinte");
} else {
Serial.println("commande non reconnue"); // Réponse par défaut
}
}
}
Dans cet exemple :
allume
et eteint
contrôlent l'état de la LED.Le mode point réalise une mesure unique sur demande et renvoie la valeur mesurée. Par exemple :
const int capteurPin = A0; // Capteur connecté à la broche analogique A0
void setup() {
Serial.begin(9600);
delay(1);
}
void loop() {
if (Serial.available()) {
String chaine = Serial.readString();
if (chaine == "mesure") {
int valeurBrute = analogRead(capteurPin); // Lecture de la valeur
float tension = valeurBrute * (5.0 / 1023.0); // Conversion en volts
Serial.println(tension); // Envoie la mesure
}
else {
Serial.println("commande non reconnue");
}
}
}
Ce code lit la valeur d'un capteur analogique sur la broche A0, la convertit en tension, et envoie la mesure via la liaison série.
Le programme réalise des mesures périodiques à un intervalle fixe. Il transmet en continu les résultats au PC sous la forme d'une série temporelle. Voici un exemple pour deux capteurs connectés sur A0 et A1 :
#define TEMPS 10000 // Durée totale des mesures en ms (10 secondes)
#define N_PTS 100 // Nombre total de points à mesurer
unsigned long t_total = TEMPS;
unsigned long dt = t_total / N_PTS; // Intervalle de temps entre deux mesures en ms
// Définition des constantes pour le capteur
const int capteurPin_0 = A0; // Capteur connecté à la broche analogique A0
const int capteurPin_1 = A1; // Capteur connecté à la broche analogique A1
void setup() {
Serial.begin(9600);
pinMode(capteurPin, INPUT);
delay(1);
}
void mesures() {
unsigned long temps_depart = millis();
unsigned long t_mesure;
while (millis() - temps_depart <= t_total) {
t_mesure = (millis() - temps_depart); // Temps écoulé depuis le début des mesures
int u0 = analogRead(capteurPin_0); // Lecture de la valeur brute du capteur 0
float C_0 = u0 * ... // Conversion capteur_0
int u1 = analogRead(capteurPin_1); // Lecture de la valeur brute du capteur 1
float C_1 = u1 * ... // Conversion capteur_1
// Envoi des séries
Serial.println(String(t_mesure) + "," + String(C_0) + "," + String(C_1));
// Délai personnalisé pour respecter le temps entre deux mesures
while ((millis() - temps_depart) - t_mesure < dt) {}
}
// ne pas oublier d'envoyer le mot "end"
Serial.println("end");
}
void loop() {
if (Serial.available()) {
String chaine = Serial.readString();
if (chaine == "mesures") {
mesures();
} else {
String message = "commande non reconnue";
Serial.println(message);
}
}
}
Macros définies :
#define TEMPS
: Durée totale des mesures (modifiable selon les besoins).#define N_PTS
: Nombre de points à mesurer.Initialisation :
dt = t_total / N_PTS
: Calcule l'intervalle de temps entre deux mesures.Fonction mesures
:
Boucle principale (loop
) :
"mesures"
lancent la série de mesures.Cette structure rend le programme flexible pour différents types de mesures et optimise la précision des mesures temporelles.
temporel rapide
Le programme ci-dessous effectue des mesures rapides de tensions aux bornes d'un circuit RC et aux bornes du condensateur. La constante de temps du circuit RC est faible et la durée d'acquisition est courte (600ms). De façon à être rapide, le programme doit stocker les séries pendant les mesures pour les envoyer en bloc par la liaison série à la fin des mesures.
#define TEMPS 650
#define N_PTS 75
const int pin_led_condo = 3;
const int nb = N_PTS;
unsigned long t_total = TEMPS;
unsigned long temps[nb];
int mesures[nb][2];
void setup() {
for (int i=0; i<nb; i++)
temps[i] = -1;
t_total = t_total * 1000;
pinMode(pin_led_condo, OUTPUT);
digitalWrite(pin_led_condo, LOW);
Serial.begin(9600);
delay(1);
}
void get_mesures(int command) {
int n = 0;
unsigned long dt = t_total / (N_PTS-1);
unsigned long temps_depart = micros();
unsigned long t = temps_depart;
if (command == 1) {
digitalWrite(pin_led_condo, HIGH);
}
else {
digitalWrite(pin_led_condo, LOW);
}
while (t - temps_depart <= t_total) {
temps[n] = (micros() - temps_depart); // t en µs
mesures[n][0] = analogRead(A0);
mesures[n][1] = analogRead(A1);
//un delai personnalisé pour optimiser la rapidité
while ((micros() - temps_depart) - long(n*dt) <= dt) {}
n = n + 1;
t = micros();
}
}
void envoie_mesures() {
int n = 0;
for(int i=0 ; i<nb; i++) {
if (temps[i] != -1) {
// le temps est convertit en ms pour compatibilité avec le programe de charge lente condo.ino
Serial.println(String(float(temps[i])/1000) + "," + String(mesures[i][0]*5.0/1023) + "," + String(mesures[i][1]*5.0/1023));
n = n+1;
}
delay(1);
}
}
void loop() {
if (Serial.available()) {
String chaine = Serial.readString();
if (chaine=="charge") {
get_mesures(1);
envoie_mesures();
Serial.println("end");
}
else if (chaine=="decharge") {
get_mesures(0);
envoie_mesures();
Serial.println("end");
}
else {
Serial.println("commande non reconnue");
}
}
}
Ce programme permet de mesurer rapidement les tensions aux bornes d’un circuit RC (résistance et condensateur) ainsi qu'aux bornes du condensateur, avec une acquisition rapide et une transmission des données en bloc une fois l'acquisition terminée.
#define TEMPS 650
: La durée totale des mesures est fixée à 650 ms.#define N_PTS 75
: Le nombre de points à mesurer est fixé à 75.pin_led_condo
: Applique la tension aux bornes du circuit. Permet de réaliser les différentes
phases de charge et de décharge.A0
: Entrée analogique pour mesurer la tension aux bornes du générateur.A1
: Entrée analogique pour mesurer la tension aux bornes du condensateur.temps[nb]
: Stocke les instants (en microsecondes) où les mesures sont effectuées.mesures[nb][2]
: Stocke les valeurs analogiques des tensions mesurées (colonne 0 pour A0
et colonne 1 pour A1
).setup()
temps
à -1
.t_total
en microsecondes pour une meilleure précision.get_mesures()
command
: Détermine si la mesure correspond à une charge (1
) ou une décharge (0
).dt = t_total / (N_PTS - 1)
(en microsecondes).temps[n]
.mesures[n][0]
et mesures[n][1]
.envoie_mesures()
temps
et mesures
.<temps(ms)>,<tension_A0(V)>,<tension_A1(V)>
.loop()
charge
ou decharge
).get_mesures()
en fonction de la commande reçue puis et envoie_mesures()
."end"
à la fin des mesures.micros()
pour mesurer le temps permet une grande précision temporelle.Ce script est parfaitement adapté pour des situations nécessitant des mesures rapides et peut-être modifié facilement.