logo

 

La bombe F est un petit montage électronique destiné à foutre la merde dans les magasins d'électroménager.
Elle "explose" à retardement en produisant un signal sonore pré-enregistré, destiné à être amplifié par une chaîne hi-fi précedement réglée à son volume maximum.

Contrairement à sa grande soeur, la bombe H, la bombe F ne produit aucun dégat. Elle fait juste... chier.
Pourquoi "F", me direz-vous ? Pas pour "furrtek", non. Simplement pour "FUCK !", le seul sample intelligent que j'ai trouvé.

Techniquement, la bombe F se compose d'un microcontroleur Atmel ATTiny25, d'une eeprom série SPI, d'un filtre RC, d'une pile bouton et d'un connecteur jack.

Faute de place et pour économiser quelques centimes, le(s) son(s) est(sont) stocké(s) dans l'eeprom plutôt que dans la flash du microcontroleur. Avec une 25128, on dispose de 16ko, soit un peu plus de 2 secondes de son échantillonné à 8kHz.

 

Une fois alimenté, le microcontroleur patiente quelques dizaines de secondes (le temps de se barrer !) avant de commencer à lire le contenu de l'eeprom pour produire le son par PWM et filtrage.

Pour cette occasion, j'ai utilisé deux samples: un petit, et un plus long (un "fuck !" et un "this is bullshit" de Tourettes guy, pour les connaisseurs). Un générateur bidon-aléatoire choisit l'un des deux samples à lire toutes les secondes.

 

Pour être efficace, la bombe F doit être discrète: ça tombe bien, en s'arrangeant, tous les composants peuvent tenir au bout d'un jack 3.5mm.

Deux tiges pour la pile, une petite languette pour l'activer sur place et il ne reste plus qu'à trouver une chaîne avec une entrée ligne !

Code C pour AVRStudio 4, les valeurs à modifier sont précisées en commentaires.

#include "avr/io.h"
#include "util/delay.h"

static unsigned char shft8bit(unsigned char val) {
          USIDR = val;
          USISR = (1<<USIOIF);
          do {
                    USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC);
                    _delay_us(1);
          } while ((USISR & (1<<USIOIF)) == 0);
          return USIDR;
}

int main(void) {
          uint8_t spiread;
          uint16_t rand=0x4E71,b;

          MCUSR = 0x00;        // Pas de watchdog, merci
          WDTCR = (1<<WDCE) | (1<<WDE);
          WDTCR = 0x00;

          DDRB = 0b11111110;   // Tout en outputs sauf DI
          TCCR1 = 0b11000001;  // Utiliser timer1 en PWM
          GTCCR = 0b01100000;  // Utiliser la sortie OCR1
          OCR1C = 0xFF;        // Max
          OCR1B = 0x00;	       // Initialiser la sortie son  0

          _delay_ms(30000);    // Le temps de partir...

          for (;;) {
                    PORTB &= ~_BV(PB3);       // Chip select bas
                    _delay_ms(10);
                    if (rand & 0x400) {
                              spiread=shft8bit(0x03);                 // "READ" pour les 25128
                              spiread=shft8bit(0x00);                 // Commencer  lire  0x0000
                              spiread=shft8bit(0x00);
                              for (b=0;b<0xFB9;b++) {              // Taille du sample 1
                                        spiread=shft8bit(0x00);
                                        OCR1B = spiread;
                                        _delay_us(110);
                                        rand += spiread;
                              }
                    } else {
                              spiread=shft8bit(0x03);                 // "READ" pour les 25128
                              spiread=shft8bit(0x0F);                 // Commencer  lire  0x0FBA
                              spiread=shft8bit(0xBA);
                              for (b=0;b<0x2EA7;b++) {             // Taille du sample 2
                                        spiread=shft8bit(0x00);
                                        OCR1B = spiread;
                                        _delay_us(110);
                                        rand += spiread;
                              }
                    }
                    rand<<=1;
                    if (rand & 0x80) rand |= 1;   // LFSR pourri (mais suffisant)
                    PORTB |= _BV(PB3);             // Chip select haut
                    _delay_ms(1000);
          }
}
footer
symbol symbol symbol symbol symbol