Sound Bulbs

/* ===============================================================
      Project: Multi Record/Playback Controller - An Ode to Alvin Lucier
       Author: Paul Cooper
 Collaborator: Clara Cheong
      Created: January 2021
     Modified: Feburary 2021
  Description: Controls 6 audio recorders to simulate an automated
  version of Alvin Lucier's "I am sitting in a room" recording.
  We wanted to create a live version that allows for audience interruptions.

  The record/plyback sequence will begin as soon as power is applied.
  OPTIONAL: Audiences are invited to strike the tuning fork at anytime to 'reset'
  the interruption.

      Updated:  2-Mar-2021
                Pause on restart awaiting trigger via ultrasonic sensors, then
                auto shutdown and reboot sequence included to allow for some quiet time.
                Sound Bulbs, once triggered will record and playback collected sounds 
                for ~8minutes, then reboot and wait ~8minutes before being able to be retriggered
  ================================================================== */
/*
  HARDWARE:
  1x Arduino UNO
  6x Arduino Compatible Record and Playback Module (Jaycar XC4605)
  3x HC-SR04 ultrasonic sensors
  1x Expanded terinal sheild to provide 6x power terminal socket pairs
  1x 5V - 12V power supply.  Audio board requires only 5V


  WIRING:
  Audio Bd -- Arduino
  VCC -- 5V
  GND -- GND
  Rec -- Digital Pin 2, 4, 6, 8, 10, 12
  PlayL -- Digital Pin 3, 5, 7, 9, 11, 13

  HC-SR04 Module -- Arduino
  Vcc -- 5V
  GND -- GND
  Trig -- A0, A2, A4
  Echo -- A1, A3, A5

  Audio board internal mics are used in this project.
  Sound quality is lo-fi, but suitable for this project.

  To RECORD - set pin high for the duration of desired recording period (max'ed at 10seconds)
  To PLAY - hold the PLAY-L pin high.  Once low, play stops
*/

#include <Ultrasonic.h>
#include <avr/wdt.h>


//Variables
int RanREC;
int const PBut = 500;
int const RBut = 10000;
int REC[7] = {0, 2, 4, 6, 8, 10, 12}; // record pins
int PLAY[7] = {0, 3, 5, 7, 9, 11, 13}; // play pins
unsigned long Time0;
unsigned long Time1;
long const t = 120000;  // 500000 is ~8 minutes and 15 seconds; test mode suggested setting is 120000 (2 minutes)

Ultrasonic uS1(A0, A1);  // Ultrasonic sensor HC-04 TRIG, ECHO
Ultrasonic uS2(A2, A3);
Ultrasonic uS3(A4, A5);

void setup() {
  Serial.begin(9600);
  Serial.println("***** Sound Bulbs, 2021 *****");
  Serial.println("by Paul Cooper & Clache Raong");
  Serial.println();
  Serial.println("setting up GPIOs");
  randomSeed(analogRead(A0));
  
  // GPIO Setup
  for (int i = 1 ; i <= 6; i += 1) {
    pinMode(REC[i], OUTPUT);
    }
  for (int i = 1 ; i <= 6; i += 1) {
    pinMode(PLAY[i], OUTPUT);
    }
  
  // Turn off output lines
  for (int i = 1 ; i <= 6; i += 1) {
    digitalWrite(REC[i], LOW);
    }
  for (int i = 1 ; i <= 6; i += 1) {
    digitalWrite(PLAY[i], LOW);
    }

  // Record reset
  Serial.println("reset recordings");
  for (int i = 1 ; i <= 6; i += 1) {
    digitalWrite(REC[i], HIGH);
    }
  delay(RBut);
  for (int i = 1 ; i <= 6; i += 1) {
    digitalWrite(REC[i], LOW);
    }
  Serial.println("END SETUP");
  Serial.println("now in pause mode");  
  delay(t/4);    // silence is golden, about 8 minutes worth anyway 
  
  // End Setup
  }

void loop(){
  Serial.println("awaiting movement");
  Time0 = millis();
  Serial.print("Time0 = ");
  Serial.println(Time0);
  Serial.print("uS1 = "); 
  Serial.println(uS1.distanceRead());
  Serial.print("uS2 = "); 
  Serial.println(uS2.distanceRead());
  Serial.print("uS3 = "); 
  Serial.println(uS3.distanceRead());
  if ((uS1.distanceRead() <150  && uS1.distanceRead() >10) ||
      (uS2.distanceRead() <150  && uS2.distanceRead() >10) ||
      (uS3.distanceRead() <150  && uS3.distanceRead() >10)) { // sensor trigger 10cm to 150cm
        Serial.println("motion detected"); 
        Time1 = millis();
        while (Time1 < (Time0 + t)) { 
          RanREC = random(1, 7);
          Serial.println();
          Serial.println("SoundBulbs do its thing");
          Serial.print("Time1 = ");
          Serial.println(Time1);
          Serial.print("Time0 + t = ");
          Serial.println(Time0 + t);
          Serial.println();
          SoundBulb(RanREC);
          Time1 = millis();
        }
        Serial.println("Going to Sleep");
        GoToSleep();
     }
   delay(1000); 
  }

void SoundBulb(int x) {
  /*  
   *  The record module (R) is chosen at random and all other
   *  modules are set to play.
   *  There are 2 groups of 3 sound modules (A & B)
   *  This is done to ensure there is no gap in the the sound
   *  (eventually)
  */
  nowPLAYA(x);
  delay(2500);
  nowREC(x);
  stopPLAYB(x);
  delay(2500);
  nowPLAYB(x);
  delay(5000);
  stopPLAYA(x);
  delay(2500);
  nowPLAYA(x);
  stopREC(x);
  } 

void nowPLAYA(int R) {
  for (int i = 1 ; i <= 3; i += 1) {
    if (i != R) {
      digitalWrite(PLAY[i], HIGH);
      }
    }
  }

void stopPLAYA(int R) {
  for (int i = 1 ; i <= 3; i += 1) {
    if (i != R) {
      digitalWrite(PLAY[i], LOW);
      }
    }
  }

void nowPLAYB(int R) {
  for (int i = 4 ; i <= 6; i += 1) {
    if (i != R) {
      digitalWrite(PLAY[i], HIGH);
      }
    }
  }

void stopPLAYB(int R) {
  for (int i = 4 ; i <= 6; i += 1) {
    if (i != R) {
      digitalWrite(PLAY[i], LOW);
      }
    }
  }

void nowREC(int R) {
  digitalWrite(PLAY[R], LOW);
  delay(PBut);
  digitalWrite(REC[R], HIGH);
  }

void stopREC(int R) {
  digitalWrite(REC[R], LOW);
  }

void GoToSleep(){
  for (int i = 1 ; i <= 6; i += 1) {
    digitalWrite(PLAY[i], HIGH);
    Serial.print("now playing: ");
    Serial.println(i);
    }
    delay(10000);
    for (int i = 1 ; i <= 6; i += 1) {
      digitalWrite(PLAY[i], LOW);
      Serial.print("now shutting down: ");
      Serial.println(i);
      delay(10000);
    }
    reboot();
  }

void reboot() {
  wdt_disable();
  wdt_enable(WDTO_15MS);
  while (1) {}
  }  

Copyright Paul Cooper, unless otherwise stated | hosted and administered by Coopers26.Com.