======DMX sans fil====== ===== Description du projet ===== Réaliser un réseau de récepteurs sans fil d'un signal DMX. ===== Matériel utilisé ===== * Ordinateur avec CrossPack, DLight, Processing et un éditeur de texte installé * 2 modules XBee * Câbles USB * Câble DMX 5 broches * Platine de conversion USB/Série * Montage réalisé * Boitier Enttec Pro * Programmateur de micro-contrôleur AVR (mySmartUSB ou autre) Le projet a été construit avec un MAC il est aisé de trouver un équivalent des programmes pour Windows ou Linux ===== Montage électronique ===== {{media_03:emetteur.png|Emetteur.png Emetteur.png}} Liste des pièces ^Nom ^Référence ^Quantité^ |Résistance |120 1/4W |2 | |Résistance |220 1/4W |1 | |Résistance |10K 1/4W |1 | |Condensateur céramique |22pF |2 | |Quartz |16 MHz |1 | |Micro contrôleur |Atmega 168 20PU |1 | |Émetteur/Récepteur RS-485|MAX 485 |1 | |Transmetteur sans fil |XBee |1 | |Connecteur |XLR 5 broches mâle|1 | ===== Configuration des modules XBee ===== Pour configurer correctement les modules, j'utilise le script Terminal de Tom Igoe. Une fois le script lancé entrer les séquences suivantes: \\ |Commande |Réponse du système|Commentaire | |+++|OK |Entre dans le mode Commande | |ATRE |OK |Restore les paramètres par défaut | |ATID1234 |OK |Définit l'adresse du réseau | |ATMY1111 |OK |Définit l'adresse du module dans le réseau | |ATBD7 |OK |Définit le taux de transfert des donnée à 115200 Bauds par seconde| |ATAP1 |OK |Permet de faire fonctionner le module en mode API | |ATWR |OK |Écrit la nouvelle configuration dans la mémoire flash du module | |ATCN |OK |Sort du mode configuration | \\ Pour le module récepteur : |Commande |Réponse du système |Commentaire | |+++|OK|Entre dans le mode Commande| |ATRE |OK |Restore les paramètres par défaut | |ATID1234 |OK |Définit l'adresse du réseau | |ATMY0 |OK |Définit l'adresse du module dans le réseau | |ATBD7 |OK |Définit le taux de transfert des donnée à 115200 Bauds par seconde| |ATAP1 |OK |Permet de faire fonctionner le module en mode API | |ATWR |OK |Écrit la nouvelle configuration dans la mémoire flash du module | |ATCN |OK |Sort du mode configuration | \\ ===== Script C ===== //----------------------------------------------------------------------------- // Projet : Transmission XBee 1 emetteur / X récepteurs // Programme : Emetteur // Auteur : Sylvain Blocquaux // Date : 26 septembre 2010 // Version : 4 //----------------------------------------------------------------------------- #include #include #include #include #define nombreXbee 2 #define nombreMaxCanaux 5 #define tailleBuffer 8 // Nombre de canaux différents #define FCPU 16000000 // Fréquence de l'oscillateur en Hz #define BAUD 250000 #define MYUBBR ((FCPU/16)/BAUD-1) extern void transmission(uint8_t *adresse, uint8_t taille); volatile uint8_t message[] = {0x7E, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; volatile uint8_t taille[nombreXbee] = {5, 3}; // La somme des indices doit être égale à tailleBuffer volatile uint8_t tableau[nombreXbee][nombreMaxCanaux]; volatile uint16_t adresseDMX, compteurDMX; volatile uint16_t iter; volatile uint8_t buffer[tailleBuffer]; //----------------------------------------------------------------------------- // Fonction d'envoi des données à travers le XBee //----------------------------------------------------------------------------- void envoie(void) { uint8_t i, addr; uint16_t checksum; for (addr = 0; addr < nombreXbee; addr++) { checksum = 0; message[2] = taille[addr] + 5; message[6] = addr; for (i = 0; i < taille[addr]; i++) { message[i + 8] = tableau[addr][i]; } for (i = 3; i < (taille[addr] + 8); i++) { checksum += message[i]; } checksum %= 256; message[taille[addr] + 8] = 255 - checksum; transmission(&message, (taille[addr] + 9)); } } //----------------------------------------------------------------------------- // Routine d'intérruption de l'USART 0 //----------------------------------------------------------------------------- ISR(USART_RX_vect) { uint8_t status, data; status=UCSR0A; data=UDR0; if(status & 0x10){ // Frame Error compteurDMX = 0; iter = 0; UCSR0A &= ~(1< 0) { buffer[iter - 1] = data; if (iter == tailleBuffer) { iter = 0; envoie(); } else { iter++; } } compteurDMX++; } //----------------------------------------------------------------------------- // Fonction d'initialisation de l'USART //----------------------------------------------------------------------------- void initUART(void) { UCSR0B = (1<>8); // The high byte, UBRR0H UBRR0L = MYUBBR; // The low byte, UBRR0L UCSR0C = (1< ===== Script Assembleur ===== //----------------------------------------------------------------------------- // Projet : Transmission XBee 1 emetteur / X récepteurs // Programme : extension.S // Auteur : Sylvain Blocquaux // Date : 26 septembre 2010 // Version : 4 // Fréquence : 16 MHz // Baud : 115200 // Série : 141 coups d horloge //----------------------------------------------------------------------------- #ifndef __AVR_ATmega168__ #define __AVR_ATmega168__ #endif #include .global transmission transmission: push r16 ; Sauvegarde dans la pile les registre de travail push r17 push r18 push r19 cli movw r30, r24 ; r24 récupère le premier arguments de la fonction comme c'est une adresse sur 2 octet utilisation de movw r30:r31 sont les registres que l'on peut utiliser avec ld clr r18 ; Mise à zéro du compteur de la taille du tableau 1: ld r17, Z+ ; 2 Charge dans r17 le contenu de la mémoire stoocké dans Z (r30:r31) cbi _SFR_IO_ADDR(PORTC), 0 ; Start bit ldi r19, 0 ; 1 11: inc r19 ; 1 cpi r19, 33 ; 1 brlo 11b ; 1 faux, 2 vrai ; boucle 4 x argument => 132 nop nop nop ; 135 ldi r16, 0 ; 1 2: sbrs r17, 0 ; 1 faux / 2 vrai(saut) rjmp 3f ; 2 nop sbi _SFR_IO_ADDR(PORTC), 0 ; 2 rjmp 4f ; 2 3: cbi _SFR_IO_ADDR(PORTC), 0 ; 2 nop nop 4: ldi r19, 0 ; 1 41: inc r19 ; 1 cpi r19, 32 ; 1 brlo 41b ; 1 faux, 2 vrai ; boucle 4 x argument => 128 nop ; 131 lsr r17 ; 1 inc r16 ; 1 sbrs r16, 3 ; 1 faux / 2 vrai (saut) rjmp 2b ; 2 nop nop nop nop sbi _SFR_IO_ADDR(PORTC), 0 ; Stop bit ldi r19, 0 ; 1 42: inc r19 ; 1 cpi r19, 32 ; 1 brlo 42b ; 1 faux, 2 vrai ; boucle 4 x argument => 128 nop nop nop nop inc r18 ; 1 Incrémente le compteur de caractère cp r18, r22 ; 1 Teste si la valeur de la taille du tableau est atteinte brge 5f ; 1 Sort de la boucle si c'est égal ou supérieur rjmp 1b ; 2 5: sei pop r19 pop r18 pop r17 pop r16 ret ===== Makefile ===== # Name: Makefile # Author: Sylvain Blocquaux # Copyright: # License: # This is a prototype Makefile. Modify it according to your needs. # You should at least check the settings for # DEVICE ....... The AVR device you compile for # CLOCK ........ Target AVR clock rate in Hertz # OBJECTS ...... The object files created from your source files. This list is # usually the same as the list of source files with suffix ".o". # PROGRAMMER ... Options to avrdude which define the hardware you use for # uploading to the AVR and the interface where this hardware # is connected. # FUSES ........ Parameters for avrdude to flash the fuses appropriately. DEVICE = atmega168 CLOCK = 16000000 PROGRAMMER = -c avr910 -P /dev/cu.SLAB_USBtoUART OBJECTS = main.o extension.o FUSES = -U lfuse:w:0xE6:m AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE) COMPILE = avr-gcc -Wall -g -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE) # symbolic targets: all: main.hex .c.o: $(COMPILE) -c $< -o $@ .S.o: $(COMPILE) -x assembler-with-cpp -c $< -o $@ # "-x assembler-with-cpp" should not be necessary since this is the default # file type for the .S (with capital S) extension. However, upper case # characters are not always preserved on Windows. To ensure WinAVR # compatibility define the file type manually. .c.s: $(COMPILE) -S $< -o $@ flash: all $(AVRDUDE) -U flash:w:main.hex:i fuse: $(AVRDUDE) $(FUSES) # Xcode uses the Makefile targets "", "clean" and "install" install: flash fuse # if you use a bootloader, change the command below appropriately: load: all bootloadHID main.hex clean: rm -f main.hex main.elf $(OBJECTS) # file targets: main.elf: $(OBJECTS) $(COMPILE) -o main.elf $(OBJECTS) main.hex: main.elf rm -f main.hex avr-objcopy -j .text -j .data -O ihex main.elf main.hex # If you have an EEPROM section, you must also create a hex file for the # EEPROM and add it to the "flash" target. # Targets for code debugging and analysis: disasm: main.elf avr-objdump -d main.elf cpp: $(COMPILE) -E main.c # Permet le debuggage rapide e: clean all flash ===== Script Processing ===== import processing.serial.*; Serial myPort; // Crée un objet de classe Serial int rate, flag, compteur; int checksum = 0; int tailleBuffer = 5; // Taille du tableau reçu il doit égal à la valeur du tableau taille du programme main.c pour le XBee concerné int adresseEmetteur = 0x1111; char val; char[] buffer = new char[tailleBuffer]; // Tableau des valeurs recues char[] valeur = new char[tailleBuffer]; void setup() { size(600, 140); frameRate(60); PFont myFont = createFont(PFont.list()[2], 30); textFont(myFont); textAlign(RIGHT); compteur = 0; flag = 0; checksum = 0; println(Serial.list()); String portName = Serial.list()[0]; rate = 115200; myPort = new Serial(this, portName, rate,'N',8,1.0); // Configuration de la liaison série } void draw() { background(0); // Set background to white text("Récepteur : 1", 250, 50); for (char i = 0; i < tailleBuffer; i++) { text(int(valeur[i]), 80 + i*80, 100); } } void serialEvent(Serial myPort) { val = myPort.readChar(); if (flag == 2) {flag = 0; return;} if ((val == 0x7E) && (flag == 0)) {flag = 1; compteur = 0; checksum = 0; return;} if (((flag == 1) && (compteur == 2)) && (val != 0x81)) { flag = 0;println("erreur 1"); return;} if (((flag == 1) && (compteur == 3)) && (val != adresseEmetteur >> 8)) { flag = 0;println("erreur 2"); return;} if (((flag == 1) && (compteur == 4)) && (val != ((adresseEmetteur << 24) >>24))) { flag = 0;println("erreur 3"); return;} if ((flag == 1) && (compteur == (tailleBuffer + 7))) { if ((val + (checksum % 256)) != 255) { flag = 2; } else { for (char iter = 0; iter < tailleBuffer; iter++) { valeur[iter] = buffer[iter]; } flag = 0; } return; } if ((flag == 1) && (compteur >= 2)) { checksum += val; } if ((flag == 1) && (compteur >= 7)) { buffer[compteur - 7] = val; } compteur++; } ===== Liens externes ===== CrossPack **(en)** : [[http://www.obdev.at/products/crosspack/index.html|Site officiel]] DLight **(fr)** : [[http://www.nicole-banana.com/|Site officiel]] Processing **(en)** : [[http://processing.org/|Site officiel]] Script Processing de Tom Igoe **(fr)** : [[http://www.tigoe.net/pcomp/code/category/Processing/11|Script Terminal]] Tutoriel de mise en route d'un Atmega **(en)** : [[http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=57|Sparkfun]] ===== Archive du projet ===== {{tag> processing sylvain DMX}}