1. Introduction

Pour être honnête ce projet n’aurait pas dû voir le jour lors de mes premières idées concernant le projet d’hiver. Néanmoins mon premier plan est tombé à l’eau lorsque je me suis rendu compte que le premier projet représentait beaucoup de travail pour au final peu de bénéfice. Il me manquait également du matériel relativement onéreux. En tentant de trouver un moyen de contourner ce dernier problème je jouais avec un bout de ficelle traînant sur mon bureau. Il m’est apparu qu’il n’était pas si simple d’en connaître sa longueur sans utiliser de moyen de mesure métrique. Je me suis alors dit que cela pourrait être une bonne piste pour mon projet H.
Dans un premier temps, j’envisageais de déterminer sa longueur grâce à un capteur infrarouge. Cependant cela me paraissait être un peu de la triche puisque le capteur renvoie une donnée dont l’unité est tout de suite le mètre. Je suis alors retombé sur mon cours de physique OS de première année et j’ai réalisé que nous pouvions connaître la longueur si je faisais de ce fil un pendule et que je déterminait sa période. Cela est faisable en utilisant un Thymio. Mais j’ai par la suite décidé d’utiliser une carte micro:bit car elle est programmable en python et l’accéléromètre est plus précis que sur le Thymio. L'objectif de ce qui suit est donc dans un premier temps de déterminer la période de ce pendule, puis d'en calculer sa longueur.

2. Matériel et méthodes

2.1 Matériel

Le matériel nécessaire à la bonne réalisation de ce projet est le suivant:

2.1.1 Hardware

- une carte micro:bit
- une batterie LiPo ou des piles nécessaires à l’alimentation du micro:bit
- une ficelle ou fil à mesurer
- de quoi fixer la batterie sur la carte micro:bit (dans mon cas du Velcro s’est avéré être une bonne option)
- un câble USB vers micro USB pour pouvoir programmer le micro:bit

2.1.2 Software

Nous avons besoin d'un ordinateur où nous téléchargerons un environnement de travail pour coder en micro python tel que Mu Editor ou Visual Studio Code avec l’extension micro:bit.
Il faut également importer le module microbit et depuis le module math importer pi et la racine carrée.

from microbit import *
from math import sqrt, pi

2.2 Méthode

Le micro:bit est attaché à la batterie grâce au velcro et le fil doit être attaché dans le trou le plus proche de l’accéléromètre. Le montage final ressemble à ça. pendule.jpg, fév. 2022
Pour commencer, j’ai décomposé le programme en 3 phases:
1. Phase de sélection, le micro:bit indique les instructions et l’utilisateur peut indiquer le nombre de demi période qu’il veut mesurer.
2. Phase de mesure, le micro:bit mesure la demi-période grâce à l’accéléromètre.
3. Phase ce calcul et d’affichage

Au tout début je commence par définir ces quelques variables et constantes:

acceleration_gravitationnelle = 9.81

give_instruction = True
startmessage = "Combien de demi periode voulez-vous mesurer ?   \\
Appuyez sur A pour soustraire 1   Appuyez sur B pour Ajouter 1   \\
Quand vous-etes pret placer le micro:bit en position et appuyez simultanement sur A et B"

A présent je définis les différentes étapes par lequel passera le micro:bit (cf 2.2.2 Phase de mesure)

initialPosition = 1  # position initial, dans l'attente d'être laché, \\
                             # atm l'acceleration est en dessous 1g
allerSimple = 2  # juste après avoir été laché, jusqu'au moment \\
où il atteint la première extremité, il est à un point mort atm a > 1g
premiereExtremite = 3  # premier point haut, atm a = 1g
balancementChronometre = 4  # balancement chronometré, \\
                                                   # le pendule est en mvt, atm a > 1g
deuxiemeExtremite = 5  # deuxième point mort du pendule, atm a > 1g
calculfinal = 6  # effectuer les calculs et en deduire la longueur du fil
affichage = 7  # afficher le resultat

La variable prog_step nous permettra de naviguer parmis ces étapes.
Ensuite le programme tourne dans une boucle while True afin que l'utilisateur puisse recommencer après avoir fini. Au début de cette boucle seront initialisés ces variables:

prog_step = initialPosition
chrono_status = False
step4_success = False

2.2.1 Phase de sélection

Dans cette première phase, le message de départ donnant les indications à l’utilisateur déroule sur l’affichage du micro:bit. Pour cela le micro:bit dispose déjà d’une fonction nous permettant d’afficher des caractères.

# phase de selection
if give_instruction:

# reinitialiser le nombre de periode à faire
    number_of_half_period = 0
    number_of_half_period_done = 0
    total_time = 0

# montrer le message de départ
    display.scroll(startmessage)
    give_instruction = False

Il est également possible d’ajouter un argument delay à display.scroll() pour ajuster le temps d’affichage. Il faut éviter les accents et caractères spéciaux pour le message de base car le micro:bit ne peut les afficher.
Une fois que le message a bien été communiqué à l’utilisateur, c’est à son tour d’indiquer au programme ce qu’il désire faire. Il peut alors choisir le nombre de demi-période(s) qu’il souhaite chronométrer. Le micro:bit possède alors deux boutons que j’ai exploité. Si nous désirons ajouter une demi période nous appuyons sur le bouton B et le nombre de demi période actuelle apparaît sur l’écran. Au contraire si nous désirons mesurer une période de moins nous appuyons sur le bouton A, le nombre de demi-période actuelle doit également défiler sur l’écran. Il est important d’ajouter une condition précisant que le nombre de demi-période ne peut pas descendre en dessous de 1, sinon le micro:bit n’a rien à mesurer et ne peut donc pas indiquer la longueur du fil.

# on ajoute 1 si on appuie sur a
if button_a.is_pressed() and not button_b.is_pressed():
    number_of_half_period -= 1
    if number_of_half_period < 0 :
        number_of_half_period = 0

    display.scroll(number_of_half_period, delay=90)


# on ajoute 1 si on appuie sur b
if button_b.is_pressed() and not button_a.is_pressed():
    number_of_half_period += 1

    display.scroll(number_of_half_period, delay=90)

Quand l’utilisateur obtient le nombre de période qu’il veut mesurer, il doit alors placer le micro:bit dans sa position initiale et peut alors lancer le programme en appuyant sur les deux boutons simultanément.

if button_a.is_pressed() and button_b.is_pressed():

    number_of_half_period_done = number_of_half_period
    display.show(Image.YES)

    while initialPosition <= prog_step <= affichage :
        
        # dans cette boucle while vient tout ce qui suit

2.2.2 Phase de mesure

J’ai séparé la phase de mesure en 5 étapes clés selon la position du pendule: la position initiale, l'aller simple, la première extrémité, le balancement chronométré et la deuxième extrémité. Pour situer le pendule au cours de ces différentes étapes, j'ai utilisé l'accéléromètre du micro:bit. En connaissant la norme de l'accélération résultante de toutes les forces agissantes sur la carte, nous pouvons en déduire sa position. Le module microbit importé précédemment nous donne accès directement au valeur de l’accéléromètre. Avec le théorème de Pythagore nous pouvons calculer la norme du vecteur accélération résultante. Dans mon code l’accélération résultante se nomme "a".

x, y, z = accelerometer.get_values()
a = sqrt(x ** 2 + y ** 2 + z ** 2)
2.2.2.1 La position initiale

Lors de cette étape, l'utilisateur a placé le micro:bit en position de départ, comme nous pouvons le constater sur la figure suivante, l’accélération ressentie par l'accéléromètre est donc équivalente à 1g. Le programme reste ainsi tant que accélération ne dépasse pas un certain seuil significatif. Cela signifie que le micro:bit attend qu'il soit entrain de tomber avant de passer à l'étape suivante.

2.2.2.2 L'aller simple

Juste après avoir été lâché, jusqu'au moment où il atteint la première extrémité l'accélération est constamment plus grande que 1 g, de par le fait que le pendule est entrain d’osciller. Le pendule se trouve à la première extrémité quand l’accélération sera de nouveau égal à 1g.

if a < 1200 :
    prog_step = premiereExtremite

Dans l'idéal, il faudrait écrire:

if a < 1010 :
    prog_step = premiereExtremite

L'idée étant de mettre la valeur la plus proche de 1000 qui correspond à 1g. Mais par soucis de précision j'ai décidé de mettre la valeur 1200. Car l’accéléromètre du micro:bit n'est pas toujours très précis. Ainsi avec 1200, il détecte à coup sûr le moment où l'accélération retombe. Mais cela entraine une perte de précision de notre mesure et un problème dans une certaine situation, je reviendrais dessus plus tard dans la discussion.

2.2.2.3 La première extrémité

Lorsque le pendule arrive au premier point haut du pendule. Il faut lancer le chronomètre puis le micro:bit redescend.

if not chrono_status:
    time_start = running_time()
    chrono_status = True

else :
    prog_step = balancementChronometre

Le booléen chrono_status a été initialisé à False au début du programme. Le programme passe donc dans le if, lance le chronomètre et change le statut du booléen. Comme il est dans une boucle il revient et passe dans le else, puisque la condition du if n'est plus respectée. Le programme passe donc à la prochaine étape, le balancement chronométré.

2.2.2.4 Le balancement chronométré

Dans cette section, il faut que le programme attende d'être à la deuxième extrémité.

if a > 1200 :
    step4_success = True

elif step4_success :

    if a < 1200 :
        prog_step = deuxiemeExtremite

Le step4_success a été initialisé à False au début et il est nécessaire car sans cela le programme passerait tout de suite à l'étape suivante. En effet l’accélération est toujours très petite juste après le moment où nous arrivons à cette étape. Il faut donc être sûr que le pendule effectue un balancement. Le step4_success sert à cela car il devient vrai seulement après que l'accélération dépasse un certain seuil.
Ensuite nous cherchons le deuxième point haut, comme pour le premier il arrive au moment où l'accélération retombe à 1g. Quand le micro:bit atteint ce point il passe à l'étape suivante.

2.2.2.5 La deuxième extrémité

Quand on arrive au deuxième point haut, il y a plusieurs choses à faire. Tout d'abord arrêter le chronomètre. Déterminer la demi-période et l'ajouter au temps total. Ensuite nous remettons chrono_status à False et nous décrémentons le nombre de demi période à faire.
Si le nombre de demi-période restant à faire et plus grand que 0, en d'autres mots si nous n'avons pas effectué le nombre de période que nous voulions, il faut recommencé une nouvelle mesures. Cela équivaut à imaginer que nous nous retrouvons à la première extrémité, nous renvoyons donc le programme à premiereExtremite. Il ne faut pas oublier de remettre le step4_success à False, sinon le programme va revenir tout droit à cette étape. Si il n'y a plus de demi-période à mesurer, le programme peut passer au calcul.

if chrono_status:
    time_finish = running_time()
    half_period_time = time_finish - time_start
    total_time = total_time + half_period_time
    chrono_status = False
    number_of_half_period -= 1

if number_of_half_period > 0 :
    step4_success = False
    prog_step = premiereExtremite

else:
    prog_step = calculfinal

2.2.3 Phase ce calcul et d’affichage

Commençons par calculer le temps moyen pour une période. Il faut donc prendre le temps total que nous avons et le diviser par le nombre de période qu'il a fait.

Le micro:bit donne le temps en [ ms ] il faut donc diviser par 1000 pour obtenir notre temps en seconde.


Le nombre de période réalisée est égale à la moitié du nombre de demi-période réalisée. Il faut donc diviser par deux le nombre de demi-période réalisée.
La ligne suivante nous donne donc notre temps moyen pour effectuer une période.

Period_time = ((total_time/1000) / (number_of_half_period_done/2))

Nous connaissons donc maintenant suffisamment d'élément pour donner la longueur de notre fil. Par calculs, niveau première année physique OS, nous pouvons montrer que la longueur l vaut:

Où g est l’accélération gravitationnelle [ m/s^2 ] et T la période calculée précédemment [ m ] .

g_sur_4pi2 = acceleration_gravitationnelle / (4 * (pi ** 2))
longueurfil = round(100*(g_sur_4pi2 * (Period_time)**2))

La multiplication par 100 sert à convertir notre réponse de [ m ] à [ cm ] et "round" sert à arrondir notre réponse à l'unité près.


Ensuite il faut transmettre la réponse à l'utilisateur:

display.scroll(str(longueurfil) + " cm")

La réponse s'affichera ainsi en boucle jusqu'à ce que l'utilisateur appuie sur le bouton B pour recommencer. Si c'est le cas nous lui redonnerons les explications afin de recommencer l'experience, il faut donc remettre give_instruction sur vrai et casser notre boucle while afin de recommencer tout au début.

if button_b.is_pressed():
    give_instruction = not give_instruction
    break

3. Résultats

Le système fonctionne et me donne une mesure réaliste du fil, bien qu'elle ne soit pas extrêmement précise. Je dirais que le résultat final est correct et répond à mes attentes. Le micro:bit indique la longueur du fil à quelques centimètres près. Le résultat pourrait être affiner, la mesure obtenu nous permets d'avoir une bonne idée de ce à quoi équivaut la longueur du fil. Si j'avais eu plus de temps, j'aurais pris le temps de réaliser quelques séries de mesure afin de déterminer l'incertitude de mon système. Comme attendu le résultat se rapproche de la bonne valeur quand on teste un plus grand nombre de période.
Il ne s'agit pas d'une mesure de précision pour sûr et le système pourrait être optimisé sur plusieurs aspects différents, mais je reviendrais dessus lors de la discussion.

4. Discussion

4.1 Discussion des résultats

Les résultats obtenus ne sont de toutes évidences précis à plus ou moins quelques centimètres, on s'en rend très bien compte en réalisant l’expérience de nos propres mains. Parfois la valeur indiquée est même complétement fausse. L'on peut expliquer ces imprécisions avec le fait que l'accéléromètre du micro:bit n'est pas très précis. Il convient très bien pour savoir quand on le secoue ou quand on l'incline. Mais pour avoir une mesure précise de l'accélération résultante qu'il subit ce n'est pas l'idéal. Si l'on prend la valeur de l'accélération résultante de l’accéléromètre et qu'on pose le micro:bit sur une table, on se rend compte qu'il n'est pas très précis. Pour pallier à cela j'ai fixé le moment où l'accélération repasse en dessous de 1200 milli-g, cela fonctionne est le micro:bit ne fait (presque) plus d'erreur liée à l’accélération. Néanmoins cela engendre un bug, en effet si nous lâchons le pendule avec un petit angle il n'accélérera pas beaucoup avant d'atteindre l'autre point haut. Pour contourner cela il est donc important de lâcher le micro:bit avec un certain angle.
Le pendule est supposé se comporter comme un pendule simple parfait, mais en réalité il frotte et l'air le ralenti. Néanmoins la perte due à la résistance de l'air n'explique pas toute l’imprécision sur notre résultat, elle y contribue en réalité faiblement.

4.2 Autocritique du projet

Ce projet n’est pas parfait et je trouve donc intéressant de laisser ici mon autocritique. Premièrement bien que le code soit très clair de mon point de vue, ce qui est normal puisque je l’ai imaginé et écris, il s’est avéré qu’il manque de clarté aux yeux des autres potentiels lecteurs. Certaines choses sont en effet explicite pour moi mais ne le sont pas pour les autres personnes lisant mon code. Par exemple, un proche a lu mon code et à quelque fois été interpelé par ma manière de faire les choses ou le choix de mes noms de variables. Il est vrai que je devrais parfois choisir des noms plus judicieux et explicites. Cela permettrait une totale compréhension du code de la part d’une personne tierce au projet.
Il n'est également pas tout à fait clair que le nombre de période que choisi l'utilisateur commence après le premier balancement à vide. En effet si l'utilisateur choisi que le pendule doit effectuer 4 demi-périodes avant d'afficher le résultat, il faut attendre 5 demi-périodes après avoir lâché le pendule avant d'avoir le résultat.

4.3 Optimisation du projet

Il y a plusieurs moyens d'améliorer les résultats obtenus. Soit l'on pourrait prendre un meilleur accéléromètre et ainsi obtenir une mesure plus précise de la période. Soit l'on pourrait analyser les données afin d'obtenir une meilleure idée du moment où le pendule atteint ses points hauts. En effet en traçant un graphique de l'accélération en fonction du temps, il est possible de savoir où sont les points hauts. Au moment où la pente de l'accélération est nulle, nous nous trouvons à l'une des extrémités. Ainsi nous aurions une mesure plus précise de la période.

5. Conclusion

En conclusion, il faut noter que le projet fonctionne relativement bien, mais qu'il pourrait être amélioré sur différents terrains.
Je peux finalement dire que ce projet m'a été très utile dans mon apprentissage de la programmation. En effet je n'avais jamais codé de tel programme et mené de tel projet avant dans ma vie. Cela m'a été très utile afin de comprendre plus comment il fallait réfléchir et quel état d’esprit il fallait adopter lorsque l'on part de juste une idée pour finalement aboutir à la réalisation de cette idée.
J'ai également beaucoup appris sur micro python et python en général et cela m'a été très utile. Néanmoins je constate que je dois faire des progrès sur la clarté de mon code et ses annotations. Cependant je suis satisfait de mon travail et je pense avoir beaucoup appris.

Références

Site officiel microbit
Site officiel MicroPython
Wikipedia pendule simple