SoundFi - Transmitting Data Using Sound (Ultrasonic Sound)

I first saw this discussion and it turned out sound was a good choice to transmit data one way>How to transmit data underwater over 40m So, I wanted to make a little project that demonstrates that possibility.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/08f3e331-d0e4-4269-9f3e-920a6f078458/Untitled.png

The Idea

The idea was simple, to transmit data using sound waves. But, not only simple text I wanted to create a device that can demonstrate how we can use sound to take readings in water bodies (oceans) and send it to surface stations.

What I wanted to do was simple. Collect data from BME 280 sensor(measures temperature, humidity and air pressure), send it via sound to a receiver, The receiver takes the data, splits it and sends it to Cloud. I am using Blynk service. It is a very easy to use service to send data and has a simple to use app.

Procedure

The Scrapped Method

I originally thought of using ultrasonic sensors I had laying around. I thought of sending pulses long and short depending on 0 and 1 on the string.

On the receiver end I planned to measure the pulse and determine whether it was a 0 or a 1.

So, I created some test code to send 0 and 1 as pulses of sound and other for receiver that would measure the duration of the pulse.

For the hardware I wired an Arduino Leonardo to transmitting side and an Arduino Uno to receiver ultrasonic sensor. I leaned that the normal ultrasonic sensors don't work at 3.3v so 5v Arduino.s were my only option.

Test code for transmitting   https://gist.github.com/vimarsh244/915b261e7961f9b6f5deed4f124ea8f2

String data = "11011010";
#define oPin D3
void setup() {
  pinMode(oPin, OUTPUT);
}

void loop() {
  for (int x = 1; x < 500; x++) {
    for (int i = 0; i < data.length(); i++) { 
      int n = data[i];
      if (n == 1) {
        digitalWrite(oPin, 1);
        delay(0.5);
        digitalWrite(oPin, 0);
        delay(1);
      }
      if (n == 0) {
        digitalWrite(oPin, 1);
        delay(1);
        digitalWrite(oPin, 0);
        delay(0.5);
      }
    }
    delay(1000);
  }
}

Test code for receiving https://gist.github.com/vimarsh244/ff56771134458e451baf368b33c10485

#define pIn 8

int cumulative_time = 0;

int MAX_DURATION = 500 * 1000;
byte timeD[5000];

String signalR = "";
void setup() {
  pinMode(pIn, INPUT);
  Serial.begin(9600);
}

void loop() {
  long beginning_time = micros() / 1000;
  for ( int i = 0; cumulative_time < MAX_DURATION; i++) {
    int time_delta = micros() / 1000 - beginning_time;
    timeD[i] = (time_delta);
    signalR += digitalRead(pIn);
    cumulative_time = time_delta;
  }

  for(int i=0;i<signalR.length();i++){
        Serial.println(timeD[i],signalR[i]);
        
  }
}

I soon found out that it didn't work. The reason being that ultrasonic sensors work in a very different way. Basically, the echo pin remains high for time from when the pulse was started (when trig pin was hit) to when it received back the pulse. The pulseIn() function in arduino basically thus measures time for which the pin was kept high. Since we cannot remotely trigger a pin without sending, the method cannot work.