Robot savant

Dans ce projet, on fabrique un robot qui peut hocher la tête. On lui pose une question, appuie sur un bouton, et il nous répond (aléatoirement) pour oui ou par non.

AVANCÉ

Il faut commencer par détecter l'appui sur le bouton à l'aide d'un détecteur de front. Ensuite, on tire au sort la réponse : 0 pour oui, 1 pour non. En fonction du résultat, on exécute la séquence correspondante en contrôllant les servomoteurs.

Fiche de présentation du projet

Matériel

Circuit

Sch%C3%A9ma_bb

Code

#include "axe.h"

Axe *axe_rotation = new Axe();
Axe *axe_inclinaison = new Axe();

#define BROCHE_ROTATION 10
#define BROCHE_INCLINAISON 9
#define BROCHE_BOUTON 13

int ancien_etat_bouton = HIGH;

void setup()
{
    axe_rotation->installer(BROCHE_ROTATION);
    axe_inclinaison->installer(BROCHE_INCLINAISON);
    pinMode(BROCHE_BOUTON, INPUT_PULLUP);
}

void servo_sequence_oui()
{
    axe_rotation->atteindre_et_attendre(90, 0);
    axe_inclinaison->atteindre_et_attendre(110, 0);
    axe_inclinaison->atteindre_et_attendre(70, 300);
    axe_inclinaison->atteindre_et_attendre(110, 300);
    axe_inclinaison->atteindre_et_attendre(70, 300);
    axe_inclinaison->atteindre_et_attendre(90, 300);
}

void servo_sequence_non()
{
    axe_inclinaison->atteindre_et_attendre(90, 0);
    axe_rotation->atteindre_et_attendre(110, 0);
    axe_rotation->atteindre_et_attendre(70, 300);
    axe_rotation->atteindre_et_attendre(110, 300);
    axe_rotation->atteindre_et_attendre(70, 300);
    axe_rotation->atteindre_et_attendre(90, 300);
}

void loop()
{   
    int etat_bouton = digitalRead(BROCHE_BOUTON);
    if (ancien_etat_bouton == HIGH && etat_bouton == LOW)
    {
        randomSeed(analogRead(8));
        if (random(2) == 0)
        {
            servo_sequence_oui();
        }
        else
        {
            servo_sequence_non();
        }
    }
    ancien_etat_bouton = etat_bouton;
}

Axe.h

#ifndef axe_h
#define axe_h

#include <Servo.h>

class Axe
{
public:
    Axe();
    void installer(int broche_servo);
    void atteindre(int consigne, unsigned long duree);
    void atteindre_et_attendre(int consigne, unsigned long duree);
    void mettre_a_jour();
    void definir(int consigne);
    void attendre();

private:
    Servo *_servo;
    int _valeur_actuelle;
    int _valeur_consigne;
    int _valeur_consigne_depart;
    unsigned long _instant_consigne_depart;
    unsigned long _duree_consigne;
};

#endif

Axe.cpp

#include "Arduino.h"
#include "axe.h"

Axe::Axe()
{
    _servo = new Servo();
    _valeur_actuelle = 90;
    _valeur_consigne = 0;
    _instant_consigne_depart = 0;
    _valeur_consigne_depart = 0;
    _duree_consigne = 0;
}

void Axe::installer(int broche_servo)
{
    _servo->attach(broche_servo);
    _servo->write(_valeur_actuelle);
}

void Axe::atteindre(int consigne, unsigned long duree)
{
    if (duree > 0)
    {
        _valeur_consigne = consigne;
        _duree_consigne = duree;
        _instant_consigne_depart = millis();
        _valeur_consigne_depart = _valeur_actuelle;
    }
    else
    {
        _valeur_consigne = consigne;
        definir(consigne);
    }
}

void Axe::definir(int consigne)
{
    _valeur_actuelle = consigne;
    _servo->write(_valeur_actuelle);
}

void Axe::mettre_a_jour()
{
    if (_valeur_actuelle != _valeur_consigne)
    {
        float progres = (float)(millis() - _instant_consigne_depart) / (float)_duree_consigne;
        if (progres > 1.0)
        {
            progres = 1.0;
        }
        float consigne = round((1. - progres) * (float)_valeur_consigne_depart + progres * (float)_valeur_consigne);
        definir((int)consigne);
    }
}

void Axe::attendre()
{
    while (_valeur_actuelle != _valeur_consigne)
    {
        mettre_a_jour();
        delay(10);
    }
}

void Axe::atteindre_et_attendre(int consigne, unsigned long duree)
{
    atteindre(consigne, duree);
    attendre();
}

Article précédent Article suivant