Ce que vous allez faire
Nous allons voir comment faire en sorte que la luminosité perçue d'une LED contrôlée par PWM varie de façon linéaire avec le rapport cyclique.
Un peu de théorie
La sensibilité de l'œil humain n'est pas uniforme, on perçoit moins bien les contrastes en faible éclairage et en fort éclairage, la perception étant meilleure dans la plage intermédiaire. Par contre, l'intensité lumineuse émise par une LED va être strictement proportionnelle au rapport cyclique du signal PWM. Il en résulte que notre œil percevra une luminosité trop importante aux rapports cycliques intermédiaires.
Pour une LED monochrome, ça se traduira par un effet gradient de luminosité tassé dans une plage de rapports cycliques. C'est moche, mais on peut vivre avec. Par contre, avec une LED RGB, ça se traduira par une erreur sur la couleur perçue, ce qui est beaucoup plus gênant.
Pour éviter ces défauts, on doit appliquer au rapport cyclique souhaité la fonction inverse de celle correspondant à la sensibilité de l'œil. Ainsi, on fait varier le rapport cyclique de manière non-linéaire pour que la variation de luminosité correspondante soit perçue de manière linéaire par l'œil.
Cette opération s'appelle la correction de gamma. Pour vous faciliter la vie, un développeur a eu la gentillesse de développer un générateur open-source de tables de correction. Il vous suffit d'indiquer la valeur du gamma (dépend de la source lumineuse, faire des essais), le nombre de pas sur lesquels vous voulez faire varier la luminosité (plus de pas = variation plus fluide), ainsi que la valeur maximale que peut prendre le rapport cyclique (dépend de la manière dont vous avez configuré votre timer).
Exercices
Vous repartirez de ce qui a été fait ici en utilisant une LED de 5mm à la place de celle de la carte de développement, trop petite pour bien voir ce qui se passe. Vous mettrez une résistance en série avec la LED pour limiter le courant qui la traverse. Choisissez une valeur de 1kΩ pour une LED rouge ou jaune, ou de 10kΩ pour une verte, bleue ou blanche. Reliez la LED à la ligne de GPIO de votre choix, comme vous l'avez fait ici.
Observez comment la luminosité de la LED varie. Filmez-la avec votre smartphone pour pouvoir la comparer avec vos essais ultérieurs.
Ensuite, vous utiliserez le générateur dont nous avons déjà parlé pour générer un tableau de valeurs, par exemple en utilisant Gamma = 2.0, Steps = 32 et Max. value = la valeur que vous avez assigné à TIM_Period. Puis vous utiliserez ce tableau à la place de la valeur calculée de dutyCycle dans le code d'origine. Il vous faudra bien sûr ajuster le nombre de pas.
Comparez avec la version précédente, que constatez-vous ? Essayez en régénérant le tableau avec des valeurs différentes de Gamma. Essayez avec un nombre de pas différent. Essayez avec des valeurs différentes pour TIM_Period. Que se passe t-il quand la valeur de dutyCycle est égale à 0 ? Et quand elle est égale à la valeur de TIM_Period ? Que pouvez-vous faire dans ces cas ?
Essayez les 2 façons de connecter votre LED montrées ci-dessous. D'où vient la différence ? Comment pouvez-vous modifier votre code pour éliminer le défaut observé ?
Pour éviter que l'œil perçoive un scintillement, vous devez configurer votre timer pour que la fréquence du signal PWM soit d'environ 100Hz (ou plus).