SE3Binome2023-2

De projets-se.plil.fr
Aller à la navigation Aller à la recherche

Notre Voiture

Objectif

Dans le cadre de notre troisième année, sur cette page nous vous présenterons me déroulement de notre projet consistant à réaliser notre premier système embarqué.

Nous allons réaliser une voiture électrique à l'aide d'une carte PCB, nous vous proposerons de nous suivre dans ce travail de la conception de la carte sur Kicad jusqu'à la programmation de notre notre voiture, pour la conception en effet nous avons utilisé le logiciel Kicad qui nous permettra de créer une carte correspondant à nos attentes et l'envoyer en prodcution.

Par la suite nous utiliserons un Arduino pour bootloader par ISP notre carte et pouvoir passer à la programmation en C.

Microcontrôleur

Pour éviter les problèmes avec les conversions analogique-vers-numérique, le choix se porte sur un microcontrôleur ATmega16u4 ou un ATmega32u4. La programmation peut ainsi se faire très simplement par DFU/USB.

Energie

Les cartes doivent pouvoir être alimentées de façon hybride : par un port USB pour la programmation et les tests, et par une batterie Lithium en mode autonome.

Fonctionnalités

Les cartes doivent comporter des LED commandées par le microcontrôleur, ainsi que d'autres fonctionnalités validées par un intervenant. Les fonctionnalités peuvent inclure :

  • Deux moteurs pour les deux roues motrices
  • Châssis simplifié
  • Avancer
  • Reculer
  • Capteur de détection d'obstacle
  • phares lumineux
  • feux arrières

Conception

Schéma Kicad

La première étape et la réalisation de notre schéma sur kicad, notre schéma comporte tout les composants qui seront présents sur notre carte et leurs liaisons entre eux, nous avons utilisé les schéma déjà présents pour les composant tel que la batterie ou encore le micro contrôleurs.

Pour intégrer la fonctionnalité du capteur de présence, nous avions besoin du schéma d'un capteur spécifique à notre utilisation (OPB733), malheureusement nous n'avons pas pu trouver le symbole de ce capteur sur internet nous avons donc du le créer seul grâce à l'éditeur de symbole Kicad et la datasheet, voici la page de la datasheet qui nous a aidé :

première page de la datahseet

Apres la mise en place de tout les symboles dans notre schématique, la voila finalisé :

Voici notre schéma finalisé

La carte est prête à prendre forme et à être routé.

Routage

Grace à Pcbnew nous pouvons donner la forme que. nous voulons à notre carte et agencer les composants dessus de sorte à avoir la carte la plus ergonomique possible, les fils de cuivre ne doivent pas de croiser et les éléments doivent être placés minutieusement en fonction de leur utilité.

Apres maint correction de la part de notre enseignant, voici la version final de notre routage :

Voici notre routage finalisé

Par la suite nous avons créer les fichiers de production à l'aide des site internet que l'enseignant nous à partager, vous pouvez retrouver tout les fichiers dans notre dépôt GIT.

Soudure

Une fois la carte reçu, les composants ont été mit à dispositions par les enseignants pour procéder à la soudure.

Cependant nous avons rencontré un petit problème, en effet lors du routage de notre carte, nous avons malencontreusement placer l'USB mini trop loin du bord de la carte, ce qui allait poser problème pour brancher le câble servant à alimenter notre système, nous avons donc limé la carte pour laisser passer le chargeur:

Limage.pdf

Ensuite, nous avons soudé les éléments essentiel au test de notre carte pour faire fonctionner les LED et un moteur continu :

Carte soudé pour test

Programmation

Passons maintenant à la programmation.

Bootloading

Premièrement il est nécessaire de bootloader nos carte via le connecteur ISP et un Arduino retenue par M.Redon:

Arduino

cela est nécessaire pour pouvoir coder et le flasher directement sur notre carte sans avoir à passer par un programmateur AVR, après avoir bootloader notre carte, elle pourra passer en mode DFU et prête à recevoir le code.

carte bootloader

Test

LED

Nous écrivons un simple code nous permettant de tester les phares de notre voiture:

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

int main(void) {
    DDRB |= (1 << PB0);

    while (1) {
        PORTB |= (1 << PB0);
        _delay_ms(500);
        PORTB &= ~(1 << PB0);
        _delay_ms(500);
    }

    return 0;
}

et l'exécutons avec le Makefile suivant:

export CC = avr-gcc

export MCU = atmega32u4
export TARGET_ARCH = -mmcu=$(MCU)

export CFLAGS =  -Wall -I. -DF_CPU=16000000 -Os #-g
export LDFLAGS = -g $(TARGET_ARCH) -lm -Wl,--gc-sections #	-Os


TARGET = AVR_prog
TERM = /dev/ttyUSB0
#TERM = /dev/ttyACM0
CPPFLAGS = -mmcu=$(MCU)
PGMER = -c stk500v1 -b 57600 -P $(TERM)
PGMERISP = -c stk500v1 -b 115200 -P $(TERM)
ARVDUDECONF= -C /usr/local/arduino/arduino-0021/hardware/tools/avrdude.conf
export DUDE = /usr/bin/avrdude -F -v -p $(MCU) $(AVRDUDECONF)

C_SRC = $(wildcard *.c)
OBJS = $(C_SRC:.c=.o)


all: $(TARGET).hex

ass:$(C_SRC)
	$(CC) -S $(CPPFLAGS) $(CFLAGS) $< -o $@

clean:
	rm -f *.o *.elf *.hex

%.o:%.c
	$(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@


$(TARGET).elf: $(OBJS)
	$(CC) $(LDFLAGS) -o $@ $(OBJS)

$(TARGET).hex: $(TARGET).elf
	avr-objcopy -j .text -j .data -O ihex $(TARGET).elf $(TARGET).hex

upload: $(TARGET).hex
	stty -F $(TERM) hupcl # reset
	$(DUDE) $(PGMER) -U flash:w:$(TARGET).hex

size: $(TARGET).elf
	avr-size --format=avr --mcu=$(MCU) $(TARGET).elf

# Ajout des cibles spécifiques pour effacer, démarrer et flasher
start:
	$(DUDE) $(PGMER) -U flash:w:$(TARGET).hex

erase:
	$(DUDE) $(PGMER) -e

flash: erase $(TARGET).hex
	$(DUDE) $(PGMER) -U flash:w:$(TARGET).hex

.PHONY: clean start erase flash upload size

Les phares fonctionnent bien comme prévu, nous pouvons passer à la suite et tester le moteur DC

Moteur DC

Nous avons soudé un moteur DC ainsi que le driver pour effecteur notre test.

Voici le code permettant de tester le moteur DC:

Connexions : AIN1 -> PD1 AIN2 -> PD2 PWMA -> PD7

(STBY est déjà connecter au Vcc pas besoin de le contrôler avec le µC)

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

void setup_pwm() {
    DDRD |= (1 << PD7);
    TCCR2A |= (1 << WGM20) | (1 << WGM21);
    TCCR2A |= (1 << COM2A1);
    TCCR2B |= (1 << CS20);
}

void set_motor_speed(uint8_t speed) {
    OCR2A = speed;
}

int main(void) {
    DDRD |= (1 << PD1) | (1 << PD2);

    setup_pwm();

    PORTD |= (1 << PD1);
    PORTD &= ~(1 << PD2);

    set_motor_speed(255);

    while (1) {
    }

    return 0;
}

Nous comptions et exécutons notre programme avec le même Makefile que celui utilisé précédemment.

Programme final

Maintenant que nous nous somme assuré du bon fonctionnement de nos composant et de notre montage? nous pouvons implémenter la totalité des fonctionnalité de notre système embarqué.

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

void setup_pwm() {
    DDRD |= (1 << PD7) | (1 << PD6);
    TCCR2A |= (1 << WGM20) | (1 << WGM21);
    TCCR2A |= (1 << COM2A1);
    TCCR2B |= (1 << CS20);
    TCCR0A |= (1 << WGM00) | (1 << WGM01);
    TCCR0A |= (1 << COM0A1);
    TCCR0B |= (1 << CS00);
}

void set_motor_a_speed(uint8_t speed) {
    OCR2A = speed;
}

void set_motor_b_speed(uint8_t speed) {
    OCR0A = speed;
}

void init_pins() {
    DDRD |= (1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4);
    DDRB |= (1 << PB0);
    DDRF &= ~(1 << PF7);
    PORTF |= (1 << PF7);
}

void stop_motors() {
    set_motor_a_speed(0);
    set_motor_b_speed(0);
}

void move_forward() {
    PORTD |= (1 << PD1);
    PORTD &= ~(1 << PD2);
    set_motor_a_speed(255);
    PORTD |= (1 << PD3);
    PORTD &= ~(1 << PD4);
    set_motor_b_speed(255);
}

void move_backward() {
    PORTD &= ~(1 << PD1);
    PORTD |= (1 << PD2);
    set_motor_a_speed(255);
    PORTD &= ~(1 << PD3);
    PORTD |= (1 << PD4);
    set_motor_b_speed(255);
}

int main(void) {
    init_pins();
    setup_pwm();

    while (1) {
        if (!(PINF & (1 << PF7))) {  // Si obstacle détecté
            // Reculer pendant 1 seconde
            move_backward();
            PORTB |= (1 << PB0);  // Allumer la LED
            _delay_ms(1000);
            // Arrêter les moteurs
            stop_motors();
        } else {
            // Avancer
            move_forward();
            PORTB &= ~(1 << PB0);  // Éteindre la LED
        }

        _delay_ms(100);
    }

    return 0;
}

move_forward() configure les pins pour faire avancer les moteurs. move_backward() configure les pins pour faire reculer les moteurs.

Boucle principale :

Si le capteur détecte un obstacle (la pin PF7 est LOW), la voiture recule pendant 1 seconde (via move_backward()), puis s'arrête (via stop_motors()), et la LED s'allume. Sinon, la voiture avance (via move_forward()), et la LED est éteinte.

Une multitude de comportement a adopté par la voiture peuvent être implémentés, ceci est un exemple de fonctionnement.

Conclusion

En conclusion, notre projet de conception et de réalisation d'une voiture électrique contrôlée par microcontrôleur a été une expérience enrichissante et stimulante, en combinant nos compétences en électronique et en programmation

Malheureusement nous n'avons pas eu le temps de soudé l'entièreté des composants a défaut de posséder la carte, cependant les éléments théoriques qui vous ont été proposés ici sont censé assurer le bon fonctionnement de notre voiture, vous trouverez dans notre dépôt GIT tout les fichiers cités ici.

GIT

projet git : https://archives.plil.fr/yyahiani/Yassine_Bilal_1SE.git