« SE3Groupe2024-5 » : différence entre les versions

De projets-se.plil.fr
Aller à la navigation Aller à la recherche
Aucun résumé des modifications
 
(6 versions intermédiaires par 2 utilisateurs non affichées)
Ligne 48 : Ligne 48 :
<p style="clear: both;" />
<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;" />
=== Matériel ===


CD4543 en DIP-16
<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);


<p style="clear: both;" />
    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 ==
== Programmateur AVR ==

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

schématique de la carte
schématique de la carte de pilotage du sonar

Routage

image du routage de la carte
capture d'écran du routage du sonar

Vue 3D

Vue 3D de la carte
Vue 3D de face du routage
capture d'écran de la vue 3D de dos de la carte
vue 3D de dos

CAO de la carte du sonar

Fichier:Sonar.zip

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:

Allumage de 2 LEDs sur la carte.
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:
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;
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.
carte apparaissant comme appareil USB
Le résultat est présenté dans la vidéo ci-dessous:
Communication USB entre ISP et PC visualisée via minicom

Tests

Rendus

Archive GIT

https://gitea.plil.fr/abiernac/SE3_2024_B5.git

Autres rendus

SE3 2024 G5 prog schema.pdf
SE3 2024 G5 prog PCB.png

Projet KiCad programmateur AVR : Fichier:SE3-2024-G5-prog-kicad.zip