Water Frequencies

by evr_freq in Circuits > Microcontrollers

512 Views, 2 Favorites, 0 Comments

Water Frequencies

Teaser: Water_Frequencies

The installation explores the relationship between humans and bodies of water. The diverse range of water infrastructures is represented through sound recordings, collected in thematic radio frequencies. The emphasis on sound allows an in-depth exploration of water bodies beyond what's visible to the naked eye. Each station creates narratives that mostly prescind any geographical context, focusing on water bodies themselves or recalling their social and cultural dimension.
Each radio station is dedicated to a specific theme and is divided into two modulations, FM, the main, and AM. Frequency Modulations reproduce the collected sounds, while Amplitude Modulations are characterized by monologues or dialogues that provide an interpretation inherent to the channel theme.

Supplies

Design Process

Darsena-MI.jpg
IMG_9504.jpg
lake - MI.jpg
0.png
concept2.png
sounds classification.png

This project is born from an exploration around the theme of water, in particular the bodies of water considered as entities influencing environments and gathering together living creatures in the establishment of collective systems. The research started with an initial fieldwork around water bodies mostly based in Milan, then expanded to other bodies of water without geographical restrictions.

The explorative practice was intended to investigate different aspects related to water infrastructures such as cultural issues to understand shifting meanings in the urban context and throughout time; environmental issues, looking at the impact on water flows and surrounding environment of those infrastructures; patterns and similarities that might be seen in different urban contexts close to water; and social aspects, related both to the use of the water, to human behaviours observed nearby water infrastructures and to their connections with people’s emotions and memories. The fieldwork has been carried out both on-site and online due to the pandemic restrictions. The tools used to record and share the findings has been pictures, video recordings, audio recordings and notes with personal observations.

The initial direction emerged from the gathered data has been to develop a sound mapping of the different water infrastructures, as a comparison between bodies of water in different geographical areas. Afterwards, the sound recording analysis shifted our focus in the consideration of social behaviours related to the fieldworks’ sites, and finally the analysis has been widened to any sound recording that can be connected to water.

To support this auditive exploration of water’s sounds, a cardboard radio has been built. The tangible interaction, mediated by a common object such as a radio, enhances the experience to a familiar and daily level, and invites to discover the peculiarities of each space and their surrounding environments.

The sounds classification comprises seven thematic radio stations; each one of them explores cultural and social dimensions of water bodies in their relationship with humans, prescind any geographical context. The thematic radio stations are potentially unlimited and work as narrative filters by which water infrastructures are interpreted. Each station is divided into two modulations, FM - the main - composed by a sequence of sound recordings, and AM, curated to enrich the listening experience with dialogues or monologues inherent to the theme. The FM numbers are based on the typical frequencies to which water molecules react according to pseudo-sciences, while AM numbers are respect human voice frequencies.

The seven stations are, respectively, 436. Big Kahuna, 440. Comrade, 444. Drop out Radio, 448. Dripping Rituals, 452. Drain Line, 456. Unblemished and 460. Bottled FM. Big Kahuna radio is composed of primordial water sounds, such as floods in the forest, natural rivers, and underwater registrations. In Comrade radio, sounds reproducing recordings about social interactions around water infrastructures become an element of union between humans and animals, so ducks interacting near a lake are compared with children playing in a pool. Drop out Radio interprets water as the symbol of infinity and freedom, reproducing boat horns and extreme sports. Dripping rituals links together performative practices around water infrastructures, from daily coffee making in a Moka to religious baptisms. Further, Drain Line provides a mechanist reading of water, reproducing sounds released by human bodies, and machinery' mechanics. In Unblemished radio, water is the central element of hygienic practices. The collection adopts a transversal cut linking natural and artificial contexts, domestic and industrial activities, man and machine. Finally, Bottled FM reproduces sounds from commodified water bodies, such as water dispensers and fountains inside a mall.

Wire Up the Radio

IMG_20210120_145510.jpg

To make the device look believable, we added all the minimal interface elements to keep the same affordance of a real radio: a frequency-tuning wheel, a signal switch and volume buttons. The output information (device name, frequency and station name) are conveyed through a digital LCD screen.

Here below you can find the full schematics for this project.

​Radio Tuner, AM/FM Switch and Volume Buttons

Water_Frequencies_bb_1.png

The potentiometer will be used to navigate "horizontally" through the different radio stations by changing the frequency value, while the AM/FM linear switch will control the "vertical" navigation between the FM signal (sounds) and AM signal (voices). The volume is controlled by two pushbuttons, but can optionally be replaced by another potentiometer. When wiring the potentiometer, a 0.1uF capacitor between the GND and the Output can help to attenuate the analog noise and improve the accuracy of the potentiometer.

10kΩ Potentiometer

  • VCC > 3.3V
  • GND > GND
  • Vout > GPIO34

Linear switch

  • VCC > 3.3V
  • GND > GND
  • Vout > GPIO34

Vol+ Pushbutton

  • Button leg > GND
  • Buton leg > GPIO17

Vol- Pushbutton

  • Button leg > GND
  • Button leg > GPIO16

​Digital Radio Display

Water_Frequencies_bb_2.png

The display will contain information about the frequency and the name of the radio station. It will also display the volume level when pressing the volume buttons. To facilitate the wiring, we chose a LCD display with a i2C backpack module, so that only 4 wires (VCC, GND, SDA, SCL) will be needed to make it work. TIP: If you decide to use it, remember to set your desired screen brightness by turning the tiny potentiometer on the module with the help of a screwdriver. Sometimes the factory-set screen brightness is too high and you won't be able to see the characters on the display.

  • VCC > 5V
  • GND > GND
  • SDA > GPIO21 (SDA)
  • SCL > GPIO22 (SCL)

Water_Frequencies_bb_3.png

Audio files storage

The microSD card reader will store the audio files to be played by the radio. The one we will be using works on 5V but there should be no problem in using a 3.3V one.

  • VCC > 5V
  • GND > GND
  • MISO > GPIO19 (MISO)
  • MOSI > GPIO23 (MOSI)
  • SCK > GPIO18 (SCK)
  • CS > GPIO5 (SS)

​Radio Speaker and DAC

Water_Frequencies_bb_4.png

For this project, we will use a DAC (Digital-to-Analog Converter) to drive the speaker. Specifically we chose a MAX98357A capable of driving 3.2W with 4Ω speakers and 1.8W with 8Ω. It will allow for a simpler management of the sound playback and has a decent audio quality.

  • VO+ > Negative pin (speaker)
  • VO- > Positive pin (speaker)
  • VIN > 3.3VGND > GND
  • DIN > GPIO25
  • LRCLK > GPIO26
  • BCLK > GPIO27

Write the Code

IMG_20210120_135011.jpg

The following is the code used to make the radio work. Feel free to use it as you like as long as you give the credits to us. The .cpp file to flash in your ESP32 is available below.

Libraries used:

#include "Audio.h"#include "SD.h"#include "FS.h"#include <LiquidCrystal_I2C.h>#include "HystFilter.h"LiquidCrystal_I2C lcd(0x27,16,2); //Specify the address and the size of the display. In this case the serial is 0x27 and it's a 16x2 characters display. HystFilter potA( 4096, 34, 15 ); //12 bit ADC = 4096, 34 discrete output values required, margin = 15 units (of 4096)// Specify the pins used for the SD card reader and the i2S DAC#define SD_CS          5#define SPI_MOSI      23#define SPI_MISO      19#define SPI_SCK       18#define I2S_DOUT      25#define I2S_BCLK      27#define I2S_LRC       26Audio audio; //declare audio object (from the ESP32-AudioI2S library)//AM/FM (pin selection, HIGH/LOW state and unit string)const int amfmPin = 14;int switchState = 0;bool FMSignal;String signalUnits; //the unit of measure of the frequency, can be any string of text and can change when switching between AM and FM//Volume (pin selection, initial gain value, increment value and other variables)const int volUpPin = 17;const int volDownPin = 16;int volumeUp = 0;int volumeDown = 0;int gainVal = 15;int volumeIncrement = 1; //Potentiometer (pin selection abd variables to store the AnalogRead value)const int potPin = 34;long potValue = 0;String radioFreq;bool booted=false; //used to trigger the first input reads in the codeint saveState;const int dbLength = 13;const char *savedAudio;const char *radioNoise = "noise.mp3"; //the noise sound is stored in the root of the sd card//a three-dimensional array of char to store the paths of the audio files for each station. Those have been collected in subfolders of the root directory.//7 radio stations, 2 signals and 12 maximum audio files + the name of the radio in the first index position of the arrayconst char *radioDB[7][2][dbLength] = {  {    {"Big Kahuna","/101/01_PRIMORDIAL_RAIN.mp3","/101/02_PRIMORDIAL_UNDERWATER_WAILING.mp3","/101/03_PRIMORDIAL_ICE_MELTING.mp3","/101/04_PRIMORDIAL_UNDERWATER_IMPACT.mp3","/101/05_PRIMORDIAL_UNDERWATER.mp3","/101/06_PRIMORDIAL_ICE_BREAK.mp3","/101/07_PRIMORDIAL_SNOW_CRUNCH.mp3","/101/08_PRIMORDIAL_BIRTH.mp3","/101/09_PRIMORDIAL_WAVES.mp3","/101/10_PRIMORDIAL_WHALE.mp3","/101/11_PRIMORDIAL_WATER_EVAPORATING.mp3", 0},    {"101/101_The_Consciousness_of_Water.mp3"}  },  {    {"Comrade","/102/001_COMRADE_KIDSINBATH.mp3","/102/002_COMRADE_DUCKSINTHELAKE.mp3","/102/003_COMRADE_KIDSONTHEBEACH.mp3","/102/004_COMRADE_ANIMALSINTHELAKE.mp3","/102/005_COMRADE_SINGINGONTHEBEACH.mp3","/102/006_COMRADE_BIRDS.mp3","/102/007_COMRADE_PENGUINS.mp3","/102/008_COMRADE_SWIMMINGPOOL.mp3",0,0,0,0},    {"/102/102_How_humans_and_animals_can_live_together.mp3"}  },  {    {"Drop out radio","/103/001_ATLANTIS_BOATHORN.mp3","/103/002_ATLANTIS_SUBMARINE.mp3","/103/003_DIVING.mp3","/103/004_ATLANTIDE_SURF.mp3","/103/005_ATLANTIDE_SAILING.mp3","/103/006_ATLANTIS_PADDLING_A_KAYAK.mp3","/103/007_ATLANTIDE_SKI_MOUNTAINEERING.mp3","/103/008_COMRADE_BOAT.mp3",0,0,0,0},    {"/103/103_Barbarian Days_William_Finnegan.mp3"}  },  {    {"Dripping Rituals","/104/001_RITUALS_FILLING_BATH.mp3","/104/002_RITUALS_CHINESE TEA_CEREMONY.mp3","/104/003_RITUALS_COPTIC_BAPTISM.mp3","/104/004_RITUALS_COOKING.mp3","/104/005_RITUALS_WOMEN_BATH_IN_GANGES_RIVER.mp3","/104/006_RITUALS_COFFEE_MAKING.mp3","/104/007_RITUALS_MALI_FISHING_RITUAL.mp3","/104/008_RITUALS_SAUNA.mp3,","/104/009_RITUALS_THERMAL WATERS.mp3",0,0,0},    {"/104/104_Mexican_priest_uses_watergun_to_spray_holy_water.mp3"}  },  {    {"Drain Line","/105/001_MB_DRINKING.mp3","/105/002_MB_TANK.mp3","/105/003_MB_BEERCAN.mp3","/105/004_MB_COFFEEMAKER.mp3","/105/005_MB_SIPPING.mp3","/105/006_MB_VIBRATING_STEEL_CABLE.mp3","/105/007_MB_SWALLOW.mp3","/105/008_MB_SALIVA.mp3","/105/009_MB_ENGINE_UNDERWATER.mp3","/105/010_MB_BABYHEART.mp3","/105/011_MB_HEATING_VALVE.mp3","/105/012_MB_PEEING_WC.mp3"},    {"/105/105_How_Cooling_System_Works.mp3"}  },  {    {"Unblemished","/106/001_HYGENE_SHOWER.mp3","/106/002_HYGENE_DISHWASHER.mp3","/106/003_HYGENE_IRONING.mp3","/106/004_HYGENE_HAND-WASHING_CLOTHES.mp3","/106/005_HYGENE_CAR_WASH.mp3","/106/006_HYGENE_WASHING_FACE_AND_TEETH.mp3","/106/007_HYGENE_FISH_CLEANING_STATION.mp3","/106/008_HYGENE_HIGH_PRESSURE_WATER_PIPE_CLEANING.mp3","/106/009_HYGENE_LAUNDROMAT_AMBIENCE.mp3","/106/010_HYGENE_GARGLING.mp3","/106/011_HYGENE_WASHING_DISHES.mp3",0},    {"/106/106_Your Cleanliness_1953.mp3"}  },  {    {"Bottled FM","/107/001_BOTTLED_WATER_DISPENSER.mp3","/107/002_BOTTLED_FILL BOTTLE.mp3","/107/003_BOTTLED_PILL_DISSOLVING_WATER.mp3","/107/004_BOTTLED_IRRIGATION.mp3","/107/005_BOTTLED_TOURIST_GUIDE.mp3","/107/006_BOTTLED_MALL_FOUNTAIN.mp3","/107/007_BOTTLED_VERSAILLES_FOUNTAINS.mp3","/107/008_BOTTLED_CRUISE.mp3",0,0,0,0},    {"/107/107_Is_Water_a_Human_Right.mp3"}  }};int saveStatesDB[7] = {1,1,1,1,1,1,1}; //savestates of the 7 radio stations. the value of a specific station increases after the end of every audio.void clearLCDLine(int line) //function to clear a single line of the LCD display. Created by bperrybap: <a href="https://forum.arduino.cc/index.php?topic=212460.msg4375326#msg4375326"> https://forum.arduino.cc/index.php?topic=212460.m...</a>{        lcd.setCursor(0,line);        for(int n = 0; n < 16; n++)        {                lcd.print(" ");        }}void Station(int radioIndex){ //called when tuning to a new radio station or when a new audio plays in the same one.    //RADIO NAME    String radioName = radioDB[radioIndex][0][0];    saveState = saveStatesDB[radioIndex]; //read from db    Serial.println(radioName);    clearLCDLine(1);    lcd.setCursor(0, 1);    lcd.print(radioName);    //RADIO AUDIO    if(FMSignal){ //select FM audio if FMSignal is true      savedAudio = radioDB[radioIndex][0][saveState];    }    else{ //select AM audio if FMSignal is false      savedAudio = radioDB[radioIndex][1][0];    }    audio.connecttoFS(SD, savedAudio); //play the selected audio    Serial.println(savedAudio);}void SaveAudio(int radioIndex){ //read, increase and write the savestate into the db  saveState = saveStatesDB[radioIndex]; //read from db  saveState++;  if(saveState==dbLength || saveState==0) {saveState=1;};  saveStatesDB[radioIndex] = saveState; //write to db}void audio_eof_mp3(const char *info){  //triggered at the end of the audio file (from the ESP32-AudioI2S library)    Serial.print("eof_mp3     ");Serial.println(info);    if(potValue==4){SaveAudio(0); Station(0);} //radioIndex    else if(potValue==8){SaveAudio(1); Station(1);} //radioIndex    else if(potValue==12){SaveAudio(2); Station(2);} //radioIndex    else if(potValue==16){SaveAudio(3); Station(3);} //radioIndex    else if(potValue==20){SaveAudio(4); Station(4);} //radioIndex    else if(potValue==24){SaveAudio(5); Station(5);} //radioIndex    else if(potValue==28){SaveAudio(6); Station(6);} //radioIndex    else if(potValue==31){clearLCDLine(1); audio.connecttoFS(SD, radioNoise);}    Serial.println("SaveStatesDB:");    for(int a=0; a < 6; a++){        Serial.print(saveStatesDB[a]);        Serial.print(" ");    }    Serial.println();}void setup(){    //Init SD card reader    pinMode(SD_CS, OUTPUT);    digitalWrite(SD_CS, HIGH);    SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);    SD.begin(SD_CS);    //init serial monitor (optional)    Serial.begin(115200);    //Init the LCD display    lcd.init();    lcd.clear();    lcd.backlight();    //Init the I2S DAC    audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);    audio.setVolume(gainVal); // 0...21    delay(300);    //Init AM/FM switch and volume pins    pinMode(amfmPin, INPUT_PULLUP);    pinMode(volUpPin, INPUT_PULLUP);    pinMode(volDownPin, INPUT_PULLUP);    //start initial device name animation    lcd.setCursor(0, 0);    lcd.print("WATER");    Serial.println("WATER");    delay(500);    lcd.setCursor(0, 1);    lcd.print("FREQUENCIES");    Serial.println("FREQUENCIES");    delay(1000);    //read initial AM/FM trigger state      if(switchState==HIGH){FMSignal = true;} //FM RADIO      else{FMSignal = false;} //AM RADIO    booted=true;    lcd.clear(); //clear the screen}//END OF SETUP FUNCTIONlong previousMillis = 0;long interval = 500;static int potValueOld = 0;static int oldSwitchState = 0;int alpha = 2;int beta = 3;void loop(){  switchState = digitalRead(amfmPin); //read switch state  volumeUp = digitalRead(volUpPin); //read vol+ state  volumeDown = digitalRead(volDownPin); //read vol- state  //potValue = potA.getOutputLevel(analogRead(potPin)); //read potentiometer value with hysterisis filter  potValue = (potA.getOutputLevel(analogRead(potPin)) * alpha + potValue * beta) / (alpha + beta); //read potentiometer value with hysterisis filter and a further noise attenuation operation  unsigned long currentMillis = millis();  if(((potValueOld != potValue || switchState != oldSwitchState) && currentMillis - previousMillis > interval) || booted){ //trigger only when the ESP32 is booted and when the potentiometer or the switch are moved (after a short interval)     previousMillis = currentMillis;        if (switchState != oldSwitchState){ //triggers at any state change of the switch      clearLCDLine(0);      if(switchState==HIGH){        FMSignal = true; //FM RADIO      }      else{        FMSignal = false; //AM RADIO      }    }      if(FMSignal){        signalUnits = "Hz"; //signal unit string for FM        radioFreq = String(432 + potValue) +" "+signalUnits;        clearLCDLine(0);        lcd.setCursor(0, 0);        lcd.print(radioFreq);      }      else{        signalUnits = "Hz"; //signal unit string for AM        radioFreq = String(125 + potValue*2) +" "+signalUnits;        clearLCDLine(0);        lcd.setCursor(0, 0);        lcd.print(radioFreq);      }    if(potValueOld != potValue || booted){ //triggers and any value change of the potentiometer or if the device as been booted      //RADIO FREQUENCY      Serial.println(radioFreq);      clearLCDLine(0);      lcd.setCursor(0, 0);      lcd.print(radioFreq);      if(booted){      booted=false;      }    }      if(potValue==4){Station(0);} //radioIndex      else if(potValue==8){Station(1);} //radioIndex      else if(potValue==12){Station(2);} //radioIndex      else if(potValue==16){Station(3);} //radioIndex      else if(potValue==20){Station(4);} //radioIndex      else if(potValue==24){Station(5);} //radioIndex      else if(potValue==28){Station(6);} //radioIndex      else if(potValue==31){audio.connecttoFS(SD, radioNoise); clearLCDLine(1);}      else{audio.stopSong(); clearLCDLine(1);};      potValueOld = potValue;      oldSwitchState = switchState;  }  if(volumeUp==LOW && gainVal < 22 && currentMillis - previousMillis > 300){ //triggers volume up. If the user keep pressed it will trigger every 300ms     previousMillis = currentMillis;    gainVal += volumeIncrement;    audio.setVolume(gainVal);    Serial.println("Vol: "+String(gainVal));    clearLCDLine(0);    lcd.setCursor(0, 0);    lcd.print("Vol: "+String(gainVal));  }  if(volumeDown==LOW && gainVal > -1 && currentMillis - previousMillis > 300){ //triggers volume down. If the user keep pressed it will trigger every 300ms     previousMillis = currentMillis;    gainVal -= volumeIncrement;    audio.setVolume(gainVal);    Serial.println("Vol: "+String(gainVal));    clearLCDLine(0);    lcd.setCursor(0, 0);    lcd.print("Vol: "+String(gainVal));  }  audio.loop();}// optional from the ESP32-AudioI2S library (not used)void audio_info(const char *info){    Serial.print("info        "); Serial.println(info);}void audio_id3data(const char *info){  //id3 metadata    Serial.print("id3data     ");Serial.println(info);}void audio_bitrate(const char *info){    Serial.print("bitrate     ");Serial.println(info);}

Downloads

Building the Box

Tavola disegno 1@2x-100.jpg
2.jpg
3.JPG
4 copia.jpg
5 copia.jpg
6 copia.jpg

To build the radio box containing the electronic components, honeycomb cardboard was used as the main material. The general dimensions of the box are: 25x15x9 cm.

The parts 1 and 2 were the first to be cut (25x15 cm). The two parts 3 and 4 have been cut 25x9 cm, and the internal thickness of 2 cm has been removed from both sides to be able to fit them on the parts 1 and 2.

The two side parts (5,6) consist only of the outer cardboard sheets of the honeycomb cardboard. The 2 cm thickness was then removed. A 3x9.5 cm hole was cut in these two parts.

Inside this hole, the texture of the speakers was applied, which is made from the inside of the honeycomb cardboard, then the two external walls of it were removed.

Once the general cuts for the external walls were completed, the knob was made with rigid polyurethane. Starting from a 5x5x2 cm block, the knob with a diameter of 3.5 cm and a height of 1.5 cm was obtained. The tools used in this case were cutter and sandpapers.

The knob was subsequently completed with the black paint (spray painting) and the insertion of a black circular card inside it.

The next step was to cut out the black cards useful for the interface. In particular there are:

  • The cardboard around the volume buttons at the top (dimension 8x3 cm), with the holes for the buttons respectively 2 cm apart from the outer sides of the card and with the + and - symbols applied.
  • The 7x1 cm card on the front face of the radio with the AF and FM writing applied.

The first is 3 cm distant from the edges of the radio, the second is applied 0.5 cm above the screen in the main face of the radio.

At this point, the holes have been made for the components visible outside the box (switches, screens, knobs, buttons). There are two visible switches, one for AM / FM on the front face, one for ON / OFF on the back of the radio.

Both were applied to the radio through copper tacks.

On the back of the radio we can find the ON / OFF switch at the bottom left (3 cm distant from the edges) and a hole with a diameter of 0.5 cm and 3.5 cm away from the switch.

On the front face, the screen is placed at a distance of 4 cm from the side and 5.5 cm from the bottom. The knob is instead positioned at a distance of 7 cm from the right side and 8 cm from the upper side.

Once all the holes have been applied, we have inserted the electronic components / external components, then we have fixed the parts 1, 4 and 2. We have inserted the electronic components correctly connected to each other inside, and, as a last step, we have closed the box by applying the grids for the speakers and the two external sides.

The Interface

Schermata 2021-01-24 alle 21.12.42.png
Schermata 2021-01-24 alle 21.12.51.png
Schermata 2021-01-24 alle 21.12.59.png
Schermata 2021-01-24 alle 21.13.07.png
Schermata 2021-01-24 alle 21.13.14.png
Schermata 2021-01-24 alle 21.13.22.png
Schermata 2021-01-24 alle 21.31.06.png
Schermata 2021-01-24 alle 21.31.28.png
code.png

The aim of the interface is to support more the user in exploring the sounds of water.The interface is presented as a digital flyer, with a simple structure (a home page and the pages of the different radio stations) that tries to deepen the user experience both visually through evocative images, and textually through the descriptions and the tracks of the FM stations.

The website is responsive, displayable on any type of device. However, the main format is the mobile one, since the user connects to the website through the qr code of the radio.

Library used for the code: Bootstrap