Cours:SaeRobotique : Différence entre versions
(→Diagramme d'état) |
(→utilisation des leds couleur) |
||
| Ligne 347 : | Ligne 347 : | ||
rgb_color colorFalse{5,0,0}; | rgb_color colorFalse{5,0,0}; | ||
for(uint16_t i = 0; i < 4; i++) | for(uint16_t i = 0; i < 4; i++) | ||
| + | { | ||
| + | if (bit_is_set(n,i)) colors[i] = colorTrue; | ||
| + | else colors[i] = colorFalse; | ||
| + | } | ||
| + | ledStrip.write(colors, LED_COUNT); | ||
| + | </source> | ||
| + | |||
| + | Une version plus complète permettant de choisir le nombre de bits, ainsi que la position sur le ruban de leds. | ||
| + | <source lang=cpp> | ||
| + | const uint8_t nBits=3; | ||
| + | const uint8_t firstLed=2; | ||
| + | rgb_color colorTrue{0,5,0}; | ||
| + | rgb_color colorFalse{5,0,0}; | ||
| + | for(uint16_t i = firstLed; i < firstLed+nBits; i++) | ||
{ | { | ||
if (bit_is_set(n,i)) colors[i] = colorTrue; | if (bit_is_set(n,i)) colors[i] = colorTrue; | ||
Version actuelle datée du 1 juin 2026 à 11:46
Sommaire
Ressources communes
structure du programme
Vous pourrez utiliser la structure de programme suivante :
enum state {etapeInit,etapeChercheBalle,etapeDeplacementVersBalle};
state etapeSuivante=etapeInit;
state etapeActive=etapeInit;
int main()
{
while(1)
{
// lecture des capteurs en début de boucle
switch (etapeActive)
{
case etapeInit:
// si ... etapeSuivante=
break;
case etapeChercheBalle:
// si ... etapeSuivante=
break;
case etapeDeplacementVersBalle:
// si ... etapeSuivante=
break;
}
// on modifie l'étape active pour la prochaine boucle
etapeActive=etapeSuivante;
}
}
********************************* ne pas déclarer de variables dans le switch case *********************************
Programmation : comment faire
Exécuter une action une seule fois :
while(1)
{
static bool dejaFait=false;
if (dejaFait==false)
{
executerMonAction();
dejaFait=true;
}
}
Répéter une action régulièrement
void initFonctionsTempsArduino()
{
sei();
// marche pour 328p et 2560 et autres ...
// à adapter suivant le µc
// cf https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring.c
TCCR0A=(1<<WGM01)|(1<<WGM00);
TCCR0B=(1<<CS01)|(1<<CS00);
TIMSK0=(1<<TOIE0);
}
int main()
{
initFonctionsTempsArduino();
while(1)
{
static uint32_t triggerTime=millis();
uint32_t currentTime=millis();
if (currentTime>=triggerTime)
{
faireMonAction();
triggerTime += 500; // prochaine exécution dans 500ms
}
}
}
|
void initFonctionsTempsArduino()
{
sei();
// marche pour 328p et 2560 et autres ...
// à adapter suivant le µc
// cf https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring.c
TCCR0A=(1<<WGM01)|(1<<WGM00);
TCCR0B=(1<<CS01)|(1<<CS00);
TIMSK0=(1<<TOIE0);
}
int main()
{
initFonctionsTempsArduino();
while(1)
{
static uint32_t triggerTime=0;
uint32_t currentTime=millis();
switch (etapeActive)
{
case etapeX:
if ( qqch)
{
etapeSuivante=etapeY;
triggerTime=currentTime;
}
break;
case etapeY:
if ( currentTime >= (triggerTime + duree ) )
{
etapeSuivante=etapeZ;
}
break;
case etapeZ:
...
break;
}
etapeActive=etapeSuivante;
}
}
|
Affichage provisoire pour deboggage
#define debug // mode debug
//ou
#undef debug // mode sans debug
int main()
{
...
while(1)
{
#ifdef debug
Serial.println("juste si debug");
#endif
}
}
|
#define DEBUG //If you comment this line, the DEBUG_PRINT & DEBUG_PRINTLN lines are defined as blank.
#ifdef DEBUG //Macros are usually in all capital letters.
#define DEBUG_PRINT(...) Serial.print(__VA_ARGS__) //DEBUG_PRINT is a macro, debug print
#define DEBUG_PRINTLN(...) Serial.println(__VA_ARGS__) //DEBUG_PRINTLN is a macro, debug print with new line
#else
#define DEBUG_PRINT(...) //now defines a blank line
#define DEBUG_PRINTLN(...) //now defines a blank line
#endif
int main()
{
while(1)
{
DEBUG_PRINTLN("juste si debug");
}
}
|
changement d'état d'un capteur
| au front montant d'un capteur | 1x si le capteur est actif suffisamment longtemps |
|---|---|
bool valeurActuelle=valeurInit;
bool valeurPrecedente=valeurInit;
...
int main()
{
...
while(1)
{
valeurPrecedente=valeurActuelle;
valeurActuelle=lireValeurCapteur();
if ( (valeurPrecedente==false) and (valeurActuelle==true) )
{
// action, par ex:
nombreFrontMontant++;
}
}
}
|
bool valeurActuelle=valeurInit;
int8_t dureeActif=0;
bool isFront=true;
...
int main()
{
...
while(1)
{
valeurActuelle=lireValeurCapteur();
if (valeurActuelle==true)
{
if (dureeActif>=20)
{
// faire l'action, par ex
if (isFront==true)
{
isFront=false;
nombreFrontMontant++;
}
}
else dureeActif++;
}
else
{
dureeActif=0;
isFront=true;
}
}
}
|
filtrer un capteur tor
| filtrer un capteur TOR | sous forme de fonction pour filtrage de plusieurs capteurs |
|---|---|
bool rawValue=readCapteur();
static bool value=false;
const uint8_t filterValue=12;
static uint8_t nbTrue=0;
static uint8_t nbFalse=0;
if ( rawValue )
{
if ( nbTrue>= filterValue)
{
value=true;
nbFalse=0;
}
else nbTrue++;
}
else
{
if ( nbFalse>= filterValue)
{
value=false;
nbTrue=0;
}
else nbFalse++;
}
|
void filtreTor(bool rawValue,bool & value,uint8_t filterValue,uint8_t & nbTrue,uint8_t & nbFalse)
{
if ( rawValue )
{
if ( nbTrue>= filterValue)
{
value=true;
nbFalse=0;
}
else nbTrue++;
}
else
{
if ( nbFalse>= filterValue)
{
value=false;
nbTrue=0;
}
else nbFalse++;
}
}
int main()
{
...
bool rawValue=rawValueTab[i];
static bool value=false;
const uint8_t filterValue=5;
static uint8_t nbTrue=0;
static uint8_t nbFalse=0;
filtreTor(rawValue,value,filterValue,nbTrue,nbFalse);
...
}
|
Optimiser l'exécution d'une fonction
inline void setVitesse(int16_t vmG, int16_t vmD) __attribute__((always_inline));
void setVitesse(int16_t vmG, int16_t vmD)
{
// code de la fonction
...
}
utilisation des leds couleur
Voici comment utiliser une barrette de leds couleur pour afficher la valeur d'un nombre en binaire ( à adapter en fonction du nombre de bits) :
rgb_color colorTrue{0,5,0};
rgb_color colorFalse{5,0,0};
for(uint16_t i = 0; i < 4; i++)
{
if (bit_is_set(n,i)) colors[i] = colorTrue;
else colors[i] = colorFalse;
}
ledStrip.write(colors, LED_COUNT);
Une version plus complète permettant de choisir le nombre de bits, ainsi que la position sur le ruban de leds.
const uint8_t nBits=3;
const uint8_t firstLed=2;
rgb_color colorTrue{0,5,0};
rgb_color colorFalse{5,0,0};
for(uint16_t i = firstLed; i < firstLed+nBits; i++)
{
if (bit_is_set(n,i)) colors[i] = colorTrue;
else colors[i] = colorFalse;
}
ledStrip.write(colors, LED_COUNT);
Diagramme d'état
Pour aller plus loin dans la programmation sous forme de machine à état fini, vous utiliserez comme base le programme suivant :
Media:TestFiniteStateMachine.zip
Composants Kicad
- Résistances :
- symbole R
- boitier suivant la valeur : 1206(CMS)/Axial DIN0309 (traversant)
- Condensateur
- symbole C
- boitier suivant la valeur 1206(CMS)
- VNH7070
- télécharger et décompresser le fichier Media:VNH7070BASTR.zip
- ajouter la librairie en suivante la page : https://www.snapeda.com/about/import/#KiCad6
- attention : pour l'ajout de la librairie de l'empreinte, indique comme "pseudo nom" VNH7070BASTR
- modèle 3d
- ajouter le fichier VNH7070BASTR.step
- faire une rotation sur X de 90°
- Arduino Nano
- symbole Arduino_Nano_v2.x
- modèle 3d
- télécharger et décompresser : Media:Arduino_nano.STEP.zip
- dans les propriétés de la carte (éditeur de pcb), onglet modèle 3d
- ajouter le fichier téléchargé
- rotation X 90
- rotation Z -90
- décalage Z 11mm
- ajouter 2 barrettes M/F
- ${KICAD9_3DMODEL_DIR}/Connector_PinSocket_2.54mm.3dshapes/PinSocket_1x15_P2.54mm_Vertical.step
- décaler le 2ème en X de 15,24mm
- bornier à vis : Screw_Terminal_01x02
- MPU-9250
- mettre 2 barrettes sécables 4 contacts, espacées de 6 pas
- Media:SparkFun MPU-9250 Breakout.step.zip
- convertisseur de niveau
- convertisseur gt1167
- utiliser la librairie : Media:GT117.zip
- documentation : Media:Gt1167.pdf
- convertisseur sparkfun BOB-12009
- utiliser la librairie : Media:BOB-12009.zip
- modèle 3d :
- BOB-12009.step
- rotation 90/0/0
- translation 0/0/9
- ajouter 2 barrettes M/F : ${KICAD9_3DMODEL_DIR}/Connector_PinSocket_2.54mm.3dshapes/PinSocket_1x06_P2.54mm_Vertical.step
- rotation 0/0/0
- translation 5.08/6.35/0 et -5.08/6.35/0
- BOB-12009.step
- convertisseur gt1167
- Autres : Media:SaeS2_2025.zip
- GroveH : Media:groveH.zip
- Connecteur à vis : Media:1729131.zip