<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://wiki.tge.cegeplabs.qc.ca/index.php?action=history&amp;feed=atom&amp;title=Zumo32U4_Combat</id>
	<title>Zumo32U4 Combat - Historique des versions</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.tge.cegeplabs.qc.ca/index.php?action=history&amp;feed=atom&amp;title=Zumo32U4_Combat"/>
	<link rel="alternate" type="text/html" href="https://wiki.tge.cegeplabs.qc.ca/index.php?title=Zumo32U4_Combat&amp;action=history"/>
	<updated>2026-04-17T15:50:04Z</updated>
	<subtitle>Historique des versions pour cette page sur le wiki</subtitle>
	<generator>MediaWiki 1.43.3</generator>
	<entry>
		<id>https://wiki.tge.cegeplabs.qc.ca/index.php?title=Zumo32U4_Combat&amp;diff=69&amp;oldid=prev</id>
		<title>Philippe le 1 décembre 2025 à 14:50</title>
		<link rel="alternate" type="text/html" href="https://wiki.tge.cegeplabs.qc.ca/index.php?title=Zumo32U4_Combat&amp;diff=69&amp;oldid=prev"/>
		<updated>2025-12-01T14:50:37Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;fr&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Version précédente&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Version du 1 décembre 2025 à 14:50&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Ligne 1 :&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Ligne 1 :&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;/* Exemple Zumo32U4 sumo adapté :&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;/* Exemple Zumo32U4 sumo adapté :&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;    - Surface de combat : sol gris&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;    - Surface de combat : sol gris&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key my_wiki:diff:1.41:old-68:rev-69:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>Philippe</name></author>
	</entry>
	<entry>
		<id>https://wiki.tge.cegeplabs.qc.ca/index.php?title=Zumo32U4_Combat&amp;diff=68&amp;oldid=prev</id>
		<title>Philippe : Page créée avec « &lt;pre&gt;  /* Exemple Zumo32U4 sumo adapté :    - Surface de combat : sol gris    - Bordure / mur : tape noir au sol      Le robot :    - Utilise les capteurs de ligne pour détecter la bordure noire (mur) et reculer.    - Utilise les capteurs de proximité pour chercher l’adversaire et foncer dessus.      Pour que le code fonctionne, les jumpers de la front sensor array    doivent connecter :      - pin 4 -&gt; RGT      - pin 20 -&gt; LFT      Testé avec un Zumo 32U4... »</title>
		<link rel="alternate" type="text/html" href="https://wiki.tge.cegeplabs.qc.ca/index.php?title=Zumo32U4_Combat&amp;diff=68&amp;oldid=prev"/>
		<updated>2025-12-01T14:50:08Z</updated>

		<summary type="html">&lt;p&gt;Page créée avec « &amp;lt;pre&amp;gt;  /* Exemple Zumo32U4 sumo adapté :    - Surface de combat : sol gris    - Bordure / mur : tape noir au sol      Le robot :    - Utilise les capteurs de ligne pour détecter la bordure noire (mur) et reculer.    - Utilise les capteurs de proximité pour chercher l’adversaire et foncer dessus.      Pour que le code fonctionne, les jumpers de la front sensor array    doivent connecter :      - pin 4 -&amp;gt; RGT      - pin 20 -&amp;gt; LFT      Testé avec un Zumo 32U4... »&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nouvelle page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Exemple Zumo32U4 sumo adapté :&lt;br /&gt;
   - Surface de combat : sol gris&lt;br /&gt;
   - Bordure / mur : tape noir au sol&lt;br /&gt;
 &lt;br /&gt;
   Le robot :&lt;br /&gt;
   - Utilise les capteurs de ligne pour détecter la bordure noire (mur) et reculer.&lt;br /&gt;
   - Utilise les capteurs de proximité pour chercher l’adversaire et foncer dessus.&lt;br /&gt;
 &lt;br /&gt;
   Pour que le code fonctionne, les jumpers de la front sensor array&lt;br /&gt;
   doivent connecter :&lt;br /&gt;
     - pin 4 -&amp;gt; RGT&lt;br /&gt;
     - pin 20 -&amp;gt; LFT&lt;br /&gt;
 &lt;br /&gt;
   Testé avec un Zumo 32U4 et moteurs 75:1 HP.&lt;br /&gt;
*/&lt;br /&gt;
 &lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
#include &amp;lt;Zumo32U4.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
// Si tu as l’ancien écran noir/vert, utilise Zumo32U4LCD.&lt;br /&gt;
// Ici : OLED.&lt;br /&gt;
Zumo32U4OLED display;&lt;br /&gt;
 &lt;br /&gt;
Zumo32U4ButtonA buttonA;&lt;br /&gt;
Zumo32U4Buzzer buzzer;&lt;br /&gt;
Zumo32U4Motors motors;&lt;br /&gt;
Zumo32U4LineSensors lineSensors;&lt;br /&gt;
Zumo32U4ProximitySensors proxSensors;&lt;br /&gt;
 &lt;br /&gt;
unsigned int lineSensorValues[3];&lt;br /&gt;
 &lt;br /&gt;
// *** IMPORTANT ***&lt;br /&gt;
// On a : sol gris au centre, bordure en tape noir.&lt;br /&gt;
// Quand la lecture sur un capteur de ligne VA AU-DESSUS de ce seuil,&lt;br /&gt;
// on considère qu’il détecte le MUR (tape noir) à la bordure.&lt;br /&gt;
// --&amp;gt; Ajuste lineSensorThreshold après avoir mesuré:&lt;br /&gt;
//     - valeur au centre (gris)&lt;br /&gt;
//     - valeur sur le tape noir&lt;br /&gt;
//     Mets un seuil entre les 2 et vérifie que la condition (&amp;gt;) marche.&lt;br /&gt;
const uint16_t lineSensorThreshold = 1000;&lt;br /&gt;
 &lt;br /&gt;
// Vitesse en marche arrière&lt;br /&gt;
const uint16_t reverseSpeed = 200;&lt;br /&gt;
 &lt;br /&gt;
// Vitesse pour tourner sur place&lt;br /&gt;
const uint16_t turnSpeed = 200;&lt;br /&gt;
 &lt;br /&gt;
// Vitesse en marche avant (mode normal)&lt;br /&gt;
const uint16_t forwardSpeed = 200;&lt;br /&gt;
 &lt;br /&gt;
// Vitesses pour “dévier” vers la gauche ou la droite en cherchant l’ennemi&lt;br /&gt;
const uint16_t veerSpeedLow  = 0;&lt;br /&gt;
const uint16_t veerSpeedHigh = 250;&lt;br /&gt;
 &lt;br /&gt;
// Vitesse de “ramming” (quand on pense pousser l’adversaire)&lt;br /&gt;
const uint16_t rammingSpeed = 400;&lt;br /&gt;
 &lt;br /&gt;
// Temps à passer en marche arrière après avoir détecté la bordure (ms)&lt;br /&gt;
const uint16_t reverseTime = 200;&lt;br /&gt;
 &lt;br /&gt;
// Temps min/max pour scanner en tournant (ms)&lt;br /&gt;
const uint16_t scanTimeMin = 200;&lt;br /&gt;
const uint16_t scanTimeMax = 2100;&lt;br /&gt;
 &lt;br /&gt;
// Temps d’attente après appui bouton A avant de bouger (ms) (règle sumo)&lt;br /&gt;
const uint16_t waitTime = 5000;&lt;br /&gt;
 &lt;br /&gt;
// Temps à avancer tout droit avant de décider qu’on est en “stalemate” (ms)&lt;br /&gt;
const uint16_t stalemateTime = 4000;&lt;br /&gt;
 &lt;br /&gt;
// États principaux de la machine à états&lt;br /&gt;
enum State&lt;br /&gt;
{&lt;br /&gt;
  StatePausing,&lt;br /&gt;
  StateWaiting,&lt;br /&gt;
  StateScanning,&lt;br /&gt;
  StateDriving,&lt;br /&gt;
  StateBacking,&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
State state = StatePausing;&lt;br /&gt;
 &lt;br /&gt;
enum Direction&lt;br /&gt;
{&lt;br /&gt;
  DirectionLeft,&lt;br /&gt;
  DirectionRight,&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
// Direction de scan la prochaine fois qu’on cherchera un adversaire&lt;br /&gt;
Direction scanDir = DirectionLeft;&lt;br /&gt;
 &lt;br /&gt;
// Temps (ms) d’entrée dans l’état courant&lt;br /&gt;
uint16_t stateStartTime;&lt;br /&gt;
 &lt;br /&gt;
// Temps (ms) de dernier refresh de l’affichage&lt;br /&gt;
uint16_t displayTime;&lt;br /&gt;
 &lt;br /&gt;
// Vrai quand on vient de changer d’état&lt;br /&gt;
bool justChangedState;&lt;br /&gt;
 &lt;br /&gt;
// Vrai quand l’écran vient d’être effacé&lt;br /&gt;
bool displayCleared;&lt;br /&gt;
 &lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  // Décommente si un moteur tourne à l’envers :&lt;br /&gt;
  // motors.flipLeftMotor(true);&lt;br /&gt;
  // motors.flipRightMotor(true);&lt;br /&gt;
 &lt;br /&gt;
  // On utilise les 3 capteurs de ligne (gauche, milieu, droite)&lt;br /&gt;
  lineSensors.initThreeSensors();&lt;br /&gt;
 &lt;br /&gt;
  // On utilise aussi les 3 capteurs de proximité (gauche, front, droite)&lt;br /&gt;
  proxSensors.initThreeSensors();&lt;br /&gt;
 &lt;br /&gt;
  changeState(StatePausing);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  bool buttonPress = buttonA.getSingleDebouncedPress();&lt;br /&gt;
 &lt;br /&gt;
  if (state == StatePausing)&lt;br /&gt;
  {&lt;br /&gt;
    // État de pause : on affiche la tension batterie&lt;br /&gt;
    // et on attend que l’utilisateur appuie sur A.&lt;br /&gt;
 &lt;br /&gt;
    motors.setSpeeds(0, 0);&lt;br /&gt;
 &lt;br /&gt;
    if (justChangedState)&lt;br /&gt;
    {&lt;br /&gt;
      justChangedState = false;&lt;br /&gt;
      display.print(F(&amp;quot;Press A&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    if (displayIsStale(100))&lt;br /&gt;
    {&lt;br /&gt;
      displayUpdated();&lt;br /&gt;
      display.gotoXY(0, 1);&lt;br /&gt;
      display.print(readBatteryMillivolts());&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    if (buttonPress)&lt;br /&gt;
    {&lt;br /&gt;
      // Passage à l’état d’attente avant départ&lt;br /&gt;
      changeState(StateWaiting);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else if (buttonPress)&lt;br /&gt;
  {&lt;br /&gt;
    // Appui sur A pendant que le robot tourne -&amp;gt; on met en pause.&lt;br /&gt;
    changeState(StatePausing);&lt;br /&gt;
  }&lt;br /&gt;
  else if (state == StateWaiting)&lt;br /&gt;
  {&lt;br /&gt;
    // On attend waitTime ms avant de commencer à bouger.&lt;br /&gt;
 &lt;br /&gt;
    motors.setSpeeds(0, 0);&lt;br /&gt;
 &lt;br /&gt;
    uint16_t time = timeInThisState();&lt;br /&gt;
 &lt;br /&gt;
    if (time &amp;lt; waitTime)&lt;br /&gt;
    {&lt;br /&gt;
      // Affiche le temps restant (en secondes, avec 1 décimale)&lt;br /&gt;
      uint16_t timeLeft = waitTime - time;&lt;br /&gt;
      display.gotoXY(0, 0);&lt;br /&gt;
      display.print(timeLeft / 1000 % 10);&lt;br /&gt;
      display.print(&amp;#039;.&amp;#039;);&lt;br /&gt;
      display.print(timeLeft / 100 % 10);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      // Assez attendu, on commence le scan de l’adversaire&lt;br /&gt;
      changeState(StateScanning);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else if (state == StateBacking)&lt;br /&gt;
  {&lt;br /&gt;
    // Marche arrière après avoir détecté la bordure.&lt;br /&gt;
 &lt;br /&gt;
    if (justChangedState)&lt;br /&gt;
    {&lt;br /&gt;
      justChangedState = false;&lt;br /&gt;
      display.print(F(&amp;quot;back&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    motors.setSpeeds(-reverseSpeed, -reverseSpeed);&lt;br /&gt;
 &lt;br /&gt;
    // Après reverseTime ms, on repasse en scan&lt;br /&gt;
    if (timeInThisState() &amp;gt;= reverseTime)&lt;br /&gt;
    {&lt;br /&gt;
      changeState(StateScanning);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else if (state == StateScanning)&lt;br /&gt;
  {&lt;br /&gt;
    // Robot tourne sur place et cherche l’adversaire.&lt;br /&gt;
 &lt;br /&gt;
    if (justChangedState)&lt;br /&gt;
    {&lt;br /&gt;
      justChangedState = false;&lt;br /&gt;
      display.print(F(&amp;quot;scan&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    if (scanDir == DirectionRight)&lt;br /&gt;
    {&lt;br /&gt;
      motors.setSpeeds(turnSpeed, -turnSpeed);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      motors.setSpeeds(-turnSpeed, turnSpeed);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    uint16_t time = timeInThisState();&lt;br /&gt;
 &lt;br /&gt;
    if (time &amp;gt; scanTimeMax)&lt;br /&gt;
    {&lt;br /&gt;
      // Rien vu depuis longtemps -&amp;gt; on avance&lt;br /&gt;
      changeState(StateDriving);&lt;br /&gt;
    }&lt;br /&gt;
    else if (time &amp;gt; scanTimeMin)&lt;br /&gt;
    {&lt;br /&gt;
      // On regarde les capteurs de proximité frontaux&lt;br /&gt;
      proxSensors.read();&lt;br /&gt;
      if (proxSensors.countsFrontWithLeftLeds()  &amp;gt;= 2&lt;br /&gt;
       || proxSensors.countsFrontWithRightLeds() &amp;gt;= 2)&lt;br /&gt;
      {&lt;br /&gt;
        // Adversaire détecté devant -&amp;gt; on avance&lt;br /&gt;
        changeState(StateDriving);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else if (state == StateDriving)&lt;br /&gt;
  {&lt;br /&gt;
    // On avance, on surveille :&lt;br /&gt;
    // - la bordure (mur noir),&lt;br /&gt;
    // - la présence de l’adversaire devant / sur les côtés.&lt;br /&gt;
 &lt;br /&gt;
    if (justChangedState)&lt;br /&gt;
    {&lt;br /&gt;
      justChangedState = false;&lt;br /&gt;
      display.print(F(&amp;quot;drive&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    // *** DÉTECTION BORDURE ***&lt;br /&gt;
    // On lit les 3 capteurs de ligne.&lt;br /&gt;
    lineSensors.read(lineSensorValues);&lt;br /&gt;
 &lt;br /&gt;
    // Avec sol gris + tape noir :&lt;br /&gt;
    // -&amp;gt; on considère qu’on voit le MUR si la valeur est AU-DESSUS du seuil.&lt;br /&gt;
    if (lineSensorValues[0] &amp;gt; lineSensorThreshold)&lt;br /&gt;
    {&lt;br /&gt;
      // Bordure détectée côté gauche -&amp;gt; on reculera puis on tournera vers la droite&lt;br /&gt;
      scanDir = DirectionRight;&lt;br /&gt;
      changeState(StateBacking);&lt;br /&gt;
    }&lt;br /&gt;
    if (lineSensorValues[2] &amp;gt; lineSensorThreshold)&lt;br /&gt;
    {&lt;br /&gt;
      // Bordure détectée côté droit -&amp;gt; on reculera puis on tournera vers la gauche&lt;br /&gt;
      scanDir = DirectionLeft;&lt;br /&gt;
      changeState(StateBacking);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    // *** DÉTECTION ADVERSAIRE PAR PROXIMITÉ ***&lt;br /&gt;
    proxSensors.read();&lt;br /&gt;
    uint8_t sum  = proxSensors.countsFrontWithRightLeds()&lt;br /&gt;
                 + proxSensors.countsFrontWithLeftLeds();&lt;br /&gt;
    int8_t diff  = proxSensors.countsFrontWithRightLeds()&lt;br /&gt;
                 - proxSensors.countsFrontWithLeftLeds();&lt;br /&gt;
 &lt;br /&gt;
    if (sum &amp;gt;= 4 || timeInThisState() &amp;gt; stalemateTime)&lt;br /&gt;
    {&lt;br /&gt;
      // Forte détection frontale OU on avance depuis longtemps -&amp;gt; on fonce (ramming)&lt;br /&gt;
      motors.setSpeeds(rammingSpeed, rammingSpeed);&lt;br /&gt;
 &lt;br /&gt;
      // LED rouge allumée quand on “ram”&lt;br /&gt;
      ledRed(1);&lt;br /&gt;
    }&lt;br /&gt;
    else if (sum == 0)&lt;br /&gt;
    {&lt;br /&gt;
      // Rien devant, on continue tout droit en mode normal&lt;br /&gt;
      motors.setSpeeds(forwardSpeed, forwardSpeed);&lt;br /&gt;
 &lt;br /&gt;
      // Mais on surveille les côtés pour repasser en scan si on voit qqch&lt;br /&gt;
      if (proxSensors.countsLeftWithLeftLeds() &amp;gt;= 2)&lt;br /&gt;
      {&lt;br /&gt;
        // Objet sur la gauche&lt;br /&gt;
        scanDir = DirectionLeft;&lt;br /&gt;
        changeState(StateScanning);&lt;br /&gt;
      }&lt;br /&gt;
 &lt;br /&gt;
      if (proxSensors.countsRightWithRightLeds() &amp;gt;= 2)&lt;br /&gt;
      {&lt;br /&gt;
        // Objet sur la droite&lt;br /&gt;
        scanDir = DirectionRight;&lt;br /&gt;
        changeState(StateScanning);&lt;br /&gt;
      }&lt;br /&gt;
 &lt;br /&gt;
      ledRed(0);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      // On voit quelque chose devant mais pas super fort :&lt;br /&gt;
      // on “pivote” légèrement pour viser l’adversaire.&lt;br /&gt;
 &lt;br /&gt;
      if (diff &amp;gt;= 1)&lt;br /&gt;
      {&lt;br /&gt;
        // Lecture droite plus forte -&amp;gt; on vire à droite&lt;br /&gt;
        motors.setSpeeds(veerSpeedHigh, veerSpeedLow);&lt;br /&gt;
      }&lt;br /&gt;
      else if (diff &amp;lt;= -1)&lt;br /&gt;
      {&lt;br /&gt;
        // Lecture gauche plus forte -&amp;gt; on vire à gauche&lt;br /&gt;
        motors.setSpeeds(veerSpeedLow, veerSpeedHigh);&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
      {&lt;br /&gt;
        // Égal -&amp;gt; tout droit&lt;br /&gt;
        motors.setSpeeds(forwardSpeed, forwardSpeed);&lt;br /&gt;
      }&lt;br /&gt;
      ledRed(0);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// Temps passé dans l’état courant (ms).&lt;br /&gt;
// Overflow après ~65s, mais ce n’est pas grave ici.&lt;br /&gt;
uint16_t timeInThisState()&lt;br /&gt;
{&lt;br /&gt;
  return (uint16_t)(millis() - stateStartTime);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// Change d’état, reset les LEDs et efface l’écran.&lt;br /&gt;
void changeState(uint8_t newState)&lt;br /&gt;
{&lt;br /&gt;
  state = (State)newState;&lt;br /&gt;
  justChangedState = true;&lt;br /&gt;
  stateStartTime = millis();&lt;br /&gt;
  ledRed(0);&lt;br /&gt;
  ledYellow(0);&lt;br /&gt;
  ledGreen(0);&lt;br /&gt;
  display.clear();&lt;br /&gt;
  displayCleared = true;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// True si l’affichage est “vieux” de plus que staleTime (ms)&lt;br /&gt;
// ou vient d’être clear.&lt;br /&gt;
bool displayIsStale(uint16_t staleTime)&lt;br /&gt;
{&lt;br /&gt;
  return displayCleared || (millis() - displayTime) &amp;gt; staleTime;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// À appeler à chaque fois qu’on met à jour l’écran.&lt;br /&gt;
void displayUpdated()&lt;br /&gt;
{&lt;br /&gt;
  displayTime = millis();&lt;br /&gt;
  displayCleared = false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Philippe</name></author>
	</entry>
</feed>