« SE3Groupe2024-5 » : différence entre les versions
(Page créée avec « == Description == === Objectif === === Cahier des charges === === Spécification techniques === == Carte électronique == === Schématique === === Routage === === Réalisation === == Programmation == == Tests == == Rendus == === Archive GIT === === Autres rendus === ») |
|||
(52 versions intermédiaires par 3 utilisateurs non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
== Description == | == Description == | ||
=== Objectif === | === Objectif === | ||
Concevoir et réaliser un mini sonar à partir d'un émetteur-récepteur ultrason, avec un traitement des données effectué par un micro-contrôleur. Les données seront ensuite communiquées par ondes radio à un ordinateur. Le système devra être capable de fonctionner aussi bien sur batterie que connecté en USB à un ordinateur, et devra au minimum comporter des LED d'indication. | |||
=== Cahier des charges === | === Cahier des charges === | ||
* Contrôle et traitement des informations de l'émetteur-récepteur ultrason | |||
* Pilotage par moteur de l'angle de l'émetteur-récepteur ultrason | |||
* Retour de l'information par des LED sur la carte | |||
* Gestion de l'alimentation par USB | |||
* Communication sans fil avec un ordinateur | |||
* Gestion de l'alimentation sur batterie | |||
* Interface pour visualiser les informations sur ordinateur | |||
=== Spécification techniques === | === Spécification techniques === | ||
* angle de détection large (-90°,90°) | |||
* deux émetteurs/récepteurs à ultrason HC-SR04 | |||
* Recharge par USB | |||
* transmission des données par onde radio via un module RF (NRFL2401) | |||
* Batteries Li-ion | |||
* une LED tricolore, pour notamment informer des différents niveaux de batterie | |||
* un afficheur 7 segments pour le débogage | |||
* interface machine via une application python | |||
* microcontroleur atmega | |||
== Carte électronique == | == Carte électronique == | ||
=== Schématique === | === Schématique === | ||
[[Fichier:Schematique-sonar.pdf|alt=schématique de la carte|gauche|vignette|schématique de la carte de pilotage du sonar]] | |||
<p style="clear: both;" /> | |||
=== Routage === | === Routage === | ||
[[Fichier:Routage-sonar.pdf|alt=image du routage de la carte|gauche|vignette|capture d'écran du routage du sonar]] | |||
<p style="clear: both;" /> | |||
=== Vue 3D === | |||
[[Fichier:Vue-3D-sonar.pdf|alt=Vue 3D de la carte|gauche|vignette|Vue 3D de face du routage]] | |||
[[Fichier:Vue3DdosPCB.pdf|alt=capture d'écran de la vue 3D de dos de la carte|gauche|vignette|vue 3D de dos]] | |||
<p style="clear: both;" /> | |||
=== CAO de la carte du sonar === | |||
[[Fichier:Sonar.zip|vignette]] | |||
<p style="clear: both;" /> | |||
=== Matériel supplémentaire à commander === | |||
CD4543 en DIP-16 | |||
=== Réalisation === | === Réalisation === | ||
<p style="clear: both;" />Afin d'assurer le bon déroulement de la soudure de la carte, nous avons divisé les composants à souder dans des jalons, pour nous assurer étape par étape du bon fonctionnement de la carte. | |||
<p style="clear: both;" /> | |||
<p style="clear: both;" />Le premier jalon comporte naturellement le microcontrôleur et les composants nécessaires à son bon fonctionnement, ainsi que la connectique USB pour pouvoir charger des programmes sur la carte. | |||
<p style="clear: both;" />La liste des jalons est disponible ci-contre: | |||
[[Fichier:Jalons.txt|alt=fichier texte comprenant les jalons pour la soudure|vignette]] | |||
<p style="clear: both;" /> | |||
<p style="clear: both;" /> | |||
== Programmation == | == Programmation == | ||
Lorsque les premiers composants ont été soudés, nous avons testé le bon fonctionnement du microcontrôleur avec un simple programme pour tester les entrées/sorties:<syntaxhighlight lang="c" line="1" start="1"> | |||
//avr-gcc -mmcu=atmega32u4 -Wall -Werror -I. -DF_CPU=8000000 -Os -o allumeled.elf allumeled.c | |||
//avr-objcopy -j .text -j .data -O ihex allumeled.elf allumeled.hex | |||
//dfu-programmer atmega32u4 erase | |||
//dfu-programmer atmega32u4 flash allumeled.hex | |||
//dfu-programmer atmega32u4 reset | |||
#include <avr/io.h> | |||
#include <util/delay.h> | |||
int main(void){ | |||
DDRD |= 0x10; // Sortie pour la LED | |||
DDRD &= ~0x20; // Entrée pour le bouton | |||
while(1){ | |||
if(PIND & 0x20) | |||
{ | |||
PORTD|=0x10; //allume | |||
} | |||
else | |||
{ | |||
PORTD&=~0x10; //eteint | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
Afin de tester le fonctionnement du sonar, nous avons utilisé le code qui suit:<syntaxhighlight lang="c" line="1" start="1"> | |||
//avr-gcc -mmcu=atmega32u4 -Wall -Werror -I. -DF_CPU=8000000 -Os -o UC_pulse.elf UC_pulse.c | |||
//avr-objcopy -j .text -j .data -O ihex UC_pulse.elf UC_pulse.hex | |||
//dfu-programmer atmega32u4 erase | |||
//dfu-programmer atmega32u4 flash UC_pulse.hex | |||
//dfu-programmer atmega32u4 reset | |||
#include <avr/io.h> | |||
#include <util/delay.h> | |||
#include <avr/interrupt.h> | |||
//#include "Uart.h" | |||
//#include "Uart.c" | |||
#define TRIG_PIN 0 | |||
#define ECHO_PIN 4 | |||
void prescale_8MHz() | |||
{ | |||
cli(); | |||
CLKPR=(1<<CLKPCE); | |||
CLKPR=0x00; | |||
sei(); | |||
} | |||
void HCSR04_init() { | |||
// Set TRIG as output, ECHO as input | |||
MCUCR |= (1 << JTD); | |||
MCUCR |= (1 << JTD); | |||
DDRF |= (1 << TRIG_PIN); // TRIG: output | |||
DDRF &= ~(1 << ECHO_PIN); // ECHO: input | |||
PORTF&= ~(1 << TRIG_PIN); // Ensure TRIG is low | |||
// Timer1 in normal mode, prescaler = 8 | |||
TCCR1A = 0x00; | |||
TCCR1B = (1 << CS11); // clk/8 -> 1 tick = 1 µs at 8 MHz | |||
TCCR1B &= ~(1 << WGM12); | |||
TCCR1B &= ~(1 << WGM13); | |||
} | |||
uint16_t HCSR04_read_distance_cm() { | |||
uint16_t count; | |||
// Send 10us trigger pulse | |||
PORTF |= (1 << TRIG_PIN); | |||
_delay_us(10); | |||
PORTF &= ~(1 << TRIG_PIN); | |||
// Wait for echo to go HIGH | |||
while (!(PINF & (1 << ECHO_PIN))) _delay_us(1); | |||
// Start Timer1 | |||
TCNT1 = 0; | |||
TCCR1B |= (1 << CS11); | |||
// Wait for echo to go LOW | |||
while (PINF & (1 << ECHO_PIN)) _delay_us(1); | |||
// Read timer value in microseconds | |||
TCCR1B &= ~(1 << CS11); | |||
count = TCNT1; | |||
// Distance in cm = time_us / 58 | |||
return count / 58; | |||
} | |||
int main(void) { | |||
prescale_8MHz(); | |||
HCSR04_init(); | |||
uint16_t distance; | |||
DDRD|=0x10; | |||
PORTD&=~0x10; | |||
while (1) { | |||
distance = HCSR04_read_distance_cm(); | |||
if(distance <= 10) | |||
{ | |||
PORTD|=0x10; | |||
_delay_ms(100); | |||
PORTD&=~0x10; | |||
} | |||
else | |||
{ | |||
PORTD|=0x10; | |||
_delay_ms(2000); | |||
PORTD&=~0x10; | |||
} | |||
_delay_ms(100); | |||
} | |||
} | |||
</syntaxhighlight> | |||
== Programmateur AVR == | |||
=== Tests allumage des LEDs === | |||
Lorsque nous avons fini de souder les composants sur la carte, nous avons voulu tester que la carte fonctionnait correctement, c'est pourquoi nous avons écrit un petit programme permettant l'allumage des leds jaunes(une qui s'allume à l'appui sur le bouton bleu traversant, une qui clignote à 10 Hz).<syntaxhighlight lang="c" line="1" start="1"> | |||
//avr-gcc -mmcu=atmega8u2 -Wall -Werror -I. -DF_CPU=16000000 -Os -o blink.elf blink.c | |||
//avr-objcopy -j .text -j .data -O ihex blink.elf blink.hex | |||
// avrdude -v -patmega8u2 -carduino -b115200 -P/dev/ttyACM0 -U flash:w:blink.hex | |||
#include <avr/io.h> | |||
#include <util/delay.h> | |||
int main(void){ | |||
CLKSEL0 = 0b00010101; // sélection de l'horloge externe | |||
CLKSEL1 = 0b00001111; // minimum de 8Mhz | |||
CLKPR = 0b10000000; // modification du diviseur d'horloge (CLKPCE=1) | |||
CLKPR = 0; // 0 pour pas de diviseur (diviseur de 1) | |||
DDRD |= 0x00; // Sortie pour la LED | |||
DDRC=0x24; // Entrée pour le bouton | |||
while(1){ | |||
if(PIND & 0x40) PORTC =0x20; // LED éteinte | |||
else PORTC |= 0x00; // LED allumée | |||
} | |||
PORTC^=0x04; | |||
_delay_ms(100); | |||
} | |||
</syntaxhighlight>Une fois le code compilé et uploadé, on obtient le résultat suivant:[[Fichier:Image pcb.jpg|gauche|vignette|Allumage de 2 LEDs sur la carte.]] | |||
<div style="clear: both;"> | |||
Pour que le microcontroleur se comporte comme un programmateur AVR USB, il faut d'abord qu'il puisse être reconnu comme un appareil USB, c'est pourquoi nous avons utilisé la bibliothèque LUFA et avons programmé notre carte avec le code qui suit pour qu'il puisse communiquer en USB:<syntaxhighlight lang="makefile" line="1" start="1"> | |||
MCU = atmega8u2 | |||
ARCH = AVR8 | |||
BOARD = NONE | |||
F_CPU = 16000000 | |||
F_USB = $(F_CPU) | |||
OPTIMIZATION = s | |||
TARGET = VirtualSerial | |||
SRC = $(TARGET).c Descriptors.c $(LUFA_SRC_USB) | |||
LUFA_PATH = ../../LUFA | |||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ | |||
LD_FLAGS = | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="c" line="1" start="1"> | |||
char* ReportString = NULL; | |||
static bool ActionSent = false; | |||
static bool button = false; | |||
/* Device must be connected and configured for the task to run */ | |||
if (USB_DeviceState != DEVICE_STATE_Configured) | |||
return; | |||
/* Determine if a joystick action has occurred */ | |||
if (!(PIND & 0x40)){ | |||
if(!button){ | |||
ReportString = "BOUTON PRESSE\r\n"; | |||
ActionSent=false; | |||
} | |||
button=true; | |||
} | |||
else button=false; | |||
</syntaxhighlight>En faisant un lsusb, on observe que la carte est reconnue comme un appareil USB, configuré d'après les fichiers de configuration de la LUFA.[[Fichier:Screenshot 2025-03-26 13-23-23.jpg|centré|vignette|800x800px|carte apparaissant comme appareil USB]]Le résultat est présenté dans la vidéo ci-dessous:[[Fichier:Video pcb(1).mp4|gauche|vignette|Communication USB entre ISP et PC visualisée via minicom]]</div> | |||
<div style="clear: both;"> | |||
== Tests == | == Tests == | ||
Ligne 22 : | Ligne 254 : | ||
=== Archive GIT === | === Archive GIT === | ||
https://gitea.plil.fr/abiernac/SE3_2024_B5.git | |||
=== Autres rendus === | === Autres rendus === | ||
[[Fichier:SE3_2024_G5_prog_schema.pdf|thumb|left]] | |||
[[Fichier:SE3_2024_G5_prog_PCB.png|thumb|right]] | |||
Projet KiCad programmateur AVR : [[Fichier:SE3-2024-G5-prog-kicad.zip]] | |||
<p style="clear: both;" /> |
Version actuelle datée du 15 juin 2025 à 15:28
Description
Objectif
Concevoir et réaliser un mini sonar à partir d'un émetteur-récepteur ultrason, avec un traitement des données effectué par un micro-contrôleur. Les données seront ensuite communiquées par ondes radio à un ordinateur. Le système devra être capable de fonctionner aussi bien sur batterie que connecté en USB à un ordinateur, et devra au minimum comporter des LED d'indication.
Cahier des charges
- Contrôle et traitement des informations de l'émetteur-récepteur ultrason
- Pilotage par moteur de l'angle de l'émetteur-récepteur ultrason
- Retour de l'information par des LED sur la carte
- Gestion de l'alimentation par USB
- Communication sans fil avec un ordinateur
- Gestion de l'alimentation sur batterie
- Interface pour visualiser les informations sur ordinateur
Spécification techniques
- angle de détection large (-90°,90°)
- deux émetteurs/récepteurs à ultrason HC-SR04
- Recharge par USB
- transmission des données par onde radio via un module RF (NRFL2401)
- Batteries Li-ion
- une LED tricolore, pour notamment informer des différents niveaux de batterie
- un afficheur 7 segments pour le débogage
- interface machine via une application python
- microcontroleur atmega
Carte électronique
Schématique
Routage
Vue 3D
CAO de la carte du sonar
Matériel supplémentaire à commander
CD4543 en DIP-16
Réalisation
Afin d'assurer le bon déroulement de la soudure de la carte, nous avons divisé les composants à souder dans des jalons, pour nous assurer étape par étape du bon fonctionnement de la carte.
Le premier jalon comporte naturellement le microcontrôleur et les composants nécessaires à son bon fonctionnement, ainsi que la connectique USB pour pouvoir charger des programmes sur la carte.
La liste des jalons est disponible ci-contre: Fichier:Jalons.txt
Programmation
Lorsque les premiers composants ont été soudés, nous avons testé le bon fonctionnement du microcontrôleur avec un simple programme pour tester les entrées/sorties:
//avr-gcc -mmcu=atmega32u4 -Wall -Werror -I. -DF_CPU=8000000 -Os -o allumeled.elf allumeled.c
//avr-objcopy -j .text -j .data -O ihex allumeled.elf allumeled.hex
//dfu-programmer atmega32u4 erase
//dfu-programmer atmega32u4 flash allumeled.hex
//dfu-programmer atmega32u4 reset
#include <avr/io.h>
#include <util/delay.h>
int main(void){
DDRD |= 0x10; // Sortie pour la LED
DDRD &= ~0x20; // Entrée pour le bouton
while(1){
if(PIND & 0x20)
{
PORTD|=0x10; //allume
}
else
{
PORTD&=~0x10; //eteint
}
}
}
Afin de tester le fonctionnement du sonar, nous avons utilisé le code qui suit:
//avr-gcc -mmcu=atmega32u4 -Wall -Werror -I. -DF_CPU=8000000 -Os -o UC_pulse.elf UC_pulse.c
//avr-objcopy -j .text -j .data -O ihex UC_pulse.elf UC_pulse.hex
//dfu-programmer atmega32u4 erase
//dfu-programmer atmega32u4 flash UC_pulse.hex
//dfu-programmer atmega32u4 reset
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//#include "Uart.h"
//#include "Uart.c"
#define TRIG_PIN 0
#define ECHO_PIN 4
void prescale_8MHz()
{
cli();
CLKPR=(1<<CLKPCE);
CLKPR=0x00;
sei();
}
void HCSR04_init() {
// Set TRIG as output, ECHO as input
MCUCR |= (1 << JTD);
MCUCR |= (1 << JTD);
DDRF |= (1 << TRIG_PIN); // TRIG: output
DDRF &= ~(1 << ECHO_PIN); // ECHO: input
PORTF&= ~(1 << TRIG_PIN); // Ensure TRIG is low
// Timer1 in normal mode, prescaler = 8
TCCR1A = 0x00;
TCCR1B = (1 << CS11); // clk/8 -> 1 tick = 1 µs at 8 MHz
TCCR1B &= ~(1 << WGM12);
TCCR1B &= ~(1 << WGM13);
}
uint16_t HCSR04_read_distance_cm() {
uint16_t count;
// Send 10us trigger pulse
PORTF |= (1 << TRIG_PIN);
_delay_us(10);
PORTF &= ~(1 << TRIG_PIN);
// Wait for echo to go HIGH
while (!(PINF & (1 << ECHO_PIN))) _delay_us(1);
// Start Timer1
TCNT1 = 0;
TCCR1B |= (1 << CS11);
// Wait for echo to go LOW
while (PINF & (1 << ECHO_PIN)) _delay_us(1);
// Read timer value in microseconds
TCCR1B &= ~(1 << CS11);
count = TCNT1;
// Distance in cm = time_us / 58
return count / 58;
}
int main(void) {
prescale_8MHz();
HCSR04_init();
uint16_t distance;
DDRD|=0x10;
PORTD&=~0x10;
while (1) {
distance = HCSR04_read_distance_cm();
if(distance <= 10)
{
PORTD|=0x10;
_delay_ms(100);
PORTD&=~0x10;
}
else
{
PORTD|=0x10;
_delay_ms(2000);
PORTD&=~0x10;
}
_delay_ms(100);
}
}
Programmateur AVR
Tests allumage des LEDs
Lorsque nous avons fini de souder les composants sur la carte, nous avons voulu tester que la carte fonctionnait correctement, c'est pourquoi nous avons écrit un petit programme permettant l'allumage des leds jaunes(une qui s'allume à l'appui sur le bouton bleu traversant, une qui clignote à 10 Hz).
//avr-gcc -mmcu=atmega8u2 -Wall -Werror -I. -DF_CPU=16000000 -Os -o blink.elf blink.c
//avr-objcopy -j .text -j .data -O ihex blink.elf blink.hex
// avrdude -v -patmega8u2 -carduino -b115200 -P/dev/ttyACM0 -U flash:w:blink.hex
#include <avr/io.h>
#include <util/delay.h>
int main(void){
CLKSEL0 = 0b00010101; // sélection de l'horloge externe
CLKSEL1 = 0b00001111; // minimum de 8Mhz
CLKPR = 0b10000000; // modification du diviseur d'horloge (CLKPCE=1)
CLKPR = 0; // 0 pour pas de diviseur (diviseur de 1)
DDRD |= 0x00; // Sortie pour la LED
DDRC=0x24; // Entrée pour le bouton
while(1){
if(PIND & 0x40) PORTC =0x20; // LED éteinte
else PORTC |= 0x00; // LED allumée
}
PORTC^=0x04;
_delay_ms(100);
}
Une fois le code compilé et uploadé, on obtient le résultat suivant:
MCU = atmega8u2
ARCH = AVR8
BOARD = NONE
F_CPU = 16000000
F_USB = $(F_CPU)
OPTIMIZATION = s
TARGET = VirtualSerial
SRC = $(TARGET).c Descriptors.c $(LUFA_SRC_USB)
LUFA_PATH = ../../LUFA
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/
LD_FLAGS =
char* ReportString = NULL;
static bool ActionSent = false;
static bool button = false;
/* Device must be connected and configured for the task to run */
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
/* Determine if a joystick action has occurred */
if (!(PIND & 0x40)){
if(!button){
ReportString = "BOUTON PRESSE\r\n";
ActionSent=false;
}
button=true;
}
else button=false;
Tests
Rendus
Archive GIT
https://gitea.plil.fr/abiernac/SE3_2024_B5.git
Autres rendus
Projet KiCad programmateur AVR : Fichier:SE3-2024-G5-prog-kicad.zip