T3ch Flicks
Published © CC BY-SA

Smart Buoy - [Making Wave and Temperature Measurements]

How to use a GY86 (wave measurements) and water temperature sensor.

IntermediateFull instructions provided6,569
Smart Buoy - [Making Wave and Temperature Measurements]

Things used in this project

Story

Read more

Code

gy_86_accelerometer_gyroscope.ino

Arduino
No preview (download only).

gy_86_magnetometer.ino

Arduino
No preview (download only).

gy_86_barrometer.ino

Arduino
No preview (download only).

wave_height.ino

Arduino
No preview (download only).

wave_period.ino

Arduino
No preview (download only).

wave_power.ino

Arduino
No preview (download only).

Code snippet #1

Plain text
#include "Wire.h"

#include "I2Cdev.h"
#include "MPU6050.h" 

MPU6050 mpu;

int16_t ax, ay, az;
int16_t gx, gy, gz;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Serial.println("Initializing MP6050...");
  mpu.initialize();
  Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");}

void loop() {
  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  printResults();
  delay(10);
}

void printResults(){
  Serial.print("Acc (x,y,z) m/s/s: "); 
  Serial.print(ax); Serial.print(" "); 
  Serial.print(ay); Serial.print(" "); 
  Serial.print(az);
  Serial.print(" Gyro(x,y,z) °/s: "); 
  Serial.print(gx); Serial.print(" "); 
  Serial.print(gy); Serial.print(" "); 
  Serial.println(gz);
}

Code snippet #2

Plain text
#include "Wire.h"

#include "I2Cdev.h" 
#include "MPU6050.h"
#include "HMC5883L.h" 
 
MPU6050 mpu;
HMC5883L mag;

int16_t mx, my, mz;

// Find the declination where you are from http://www.magnetic-declination.com

//                  -14°     59'            
float declination = (-14.0 - (59.0 / 60.0)) * (PI/180);

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Serial.println("Initializing I2C devices...");
  mpu.setI2CMasterModeEnabled(false);
  mpu.setI2CBypassEnabled(true) ;
  mpu.setSleepEnabled(false);
  mpu.initialize();
  mag.initialize();
  Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  Serial.println(mag.testConnection() ? "HMC5883L connection successful" : "HMC5883L connection failed");

}

void loop() {
  mag.getHeading(&mx, &my, &mz);
  printResults();
  delay(200);
}

void printResults(){
  float heading = atan2(my, mx);
  heading += declination;
  if (heading < 0) heading += 2 * PI;
  if (heading > 2 * PI) heading -= 2 * PI;
  heading *= 180/M_PI;
  
  Serial.print("Heading °:"); 
  Serial.println(heading);
}

Code snippet #3

Plain text
#include "Wire.h"

#include "I2Cdev.h" 
#include "MPU6050.h" 
#include <ms5611.h> 

MPU6050 mpu;
MS5611 baro;

double temp;
long pressure;
double altitude;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Serial.println("Initializing I2C devices...");
  mpu.setI2CMasterModeEnabled(false);
  mpu.setI2CBypassEnabled(true) ;
  mpu.setSleepEnabled(false);
  mpu.initialize();
  Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  while (!baro.begin(MS5611_ULTRA_HIGH_RES)) {
    Serial.println("MS5611 connection unsuccessful, check wiring!");
    delay(500);
  }
}

void loop() {
  temp = baro.readTemperature(true);
  pressure = baro.readPressure(true);
  altitude = baro.getAltitude(pressure);
  printResults();
  delay(200);
}

void printResults(){
  Serial.print("Pressure hPa: "); Serial.print(pressure);
  Serial.print("  Altitude m: "); Serial.print(altitude);
  float tempC = temp / 340.00 + 36.53;
  Serial.print("  Temp °C: "); Serial.println(tempC);
}

Code snippet #4

Plain text
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h" //  ^
#include <ms5611.h> // 

MPU6050 mpu;
MS5611 baro;

long pressure;
double altitude, min_height, max_height, wave_height;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Serial.println("Initializing I2C devices...");
  mpu.setI2CMasterModeEnabled(false);
  mpu.setI2CBypassEnabled(true) ;
  mpu.setSleepEnabled(false);
  mpu.initialize();
  Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  while (!baro.begin(MS5611_ULTRA_HIGH_RES)) {
    Serial.println("MS5611 connection unsuccessful, check wiring!");
    delay(500);
  }
}

void loop() {
  unsigned long start_time = millis();
  pressure = baro.readPressure(true);
  altitude = baro.getAltitude(pressure);
  max_height = altitude;
  min_height = altitude;

  //  for 15 seconds
  while(millis() - start_time < 15000){
    pressure = baro.readPressure(true);
    altitude = baro.getAltitude(pressure);
    if (altitude < min_height) min_height = altitude;
    if (altitude > max_height) max_height = altitude;
  }
  wave_height = (max_height - min_height)/2.0;
  Serial.print("Wave Height m: "); 
  Serial.println(wave_height);
}

Code snippet #5

Plain text
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h" 
#include <ms5611.h> 


MPU6050 mpu;
MS5611 baro;
long pressure;
double altitude, min_height, max_height, mid_point, smudge_factor;
byte escaped, started;
unsigned long period_start, period_end;
float avg_period = -1;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Serial.println("Initializing I2C devices...");
  mpu.setI2CMasterModeEnabled(false);
  mpu.setI2CBypassEnabled(true) ;
  mpu.setSleepEnabled(false);
  mpu.initialize();
  Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  while (!baro.begin(MS5611_ULTRA_HIGH_RES)) {
    Serial.println("MS5611 connection unsuccessful, check wiring!");
    delay(500);
  }
}

void loop() {
  unsigned long start_time = millis();
  pressure = baro.readPressure(true);
  altitude = baro.getAltitude(pressure);
  max_height = altitude;
  min_height = altitude; 

  //  for 15 seconds
  while(millis() - start_time < 15000){
    pressure = baro.readPressure(true);
    altitude = baro.getAltitude(pressure);
    if (altitude < min_height) min_height = altitude;
    if (altitude > max_height) max_height = altitude;
  }
  mid_point = (max_height + min_height)/2.0;
  smudge_factor = (max_height - mid_point)*0.15;
  Serial.print("Mid Point m: "); Serial.print(mid_point);
  
  start_time = millis();
  //  for 15 seconds 
  while(millis() - start_time < 15000){
    pressure = baro.readPressure(true);
    altitude = baro.getAltitude(pressure);
    //    if within a range of 30% of wave height from the mid point
    //    start the timer else stop it
    if (altitude < mid_point + smudge_factor && altitude > mid_point - smudge_factor){
      if ( !started){
        period_start = millis();
        started = true;
      }
      else{
        if ( escaped ){
          // if it has started and escaped and is now returning
          period_end = millis();
          started = false;
          escaped = false;
          // if the variable has already been assigned
          // use its previous value and new value to work out avg
          if(avg_period != -1){
            avg_period = (avg_period + (period_end-period_start)*2)  / 2.0;
          }
          // assign it
          else{
            avg_period =  (period_end-period_start)*2; 
          }
        }
      }
    }
    else{
      escaped = true;
    } 
  }
  Serial.print("  Period s: "); Serial.println(avg_period/1000);
}

Code snippet #6

Plain text
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "HMC5883L.h"
#include "Wire.h"
MPU6050 mpu;
HMC5883L mag;

int16_t mx, my, mz;

#define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno & most boards
float declination = -14.0 - (59.0 / 60.0);

// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
    mpuInterrupt = true;
}

void setup() {
    Serial.begin(115200);
    Wire.begin();
    Wire.setClock(400000); 
    
    mpu.setI2CMasterModeEnabled(false);
    mpu.setI2CBypassEnabled(true) ;
    mpu.setSleepEnabled(false);
    mpu.initialize();
    mag.initialize();
   // initialize device
    Serial.println(F("Initializing I2C devices..."));
    mpu.initialize();
    pinMode(INTERRUPT_PIN, INPUT);
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
devStatus = mpu.dmpInitialize();
  // supply your own gyro offsets here, scaled for min sensitivity
    mpu.setXGyroOffset(112);
    mpu.setYGyroOffset(5);
    mpu.setZGyroOffset(-15);
    mpu.setZAccelOffset(1487); 
    if (devStatus == 0) {
        mpu.setDMPEnabled(true);
        Serial.print(digitalPinToInterrupt(INTERRUPT_PIN));
        attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();
        dmpReady = true;
        packetSize = mpu.dmpGetFIFOPacketSize();
    }

}

void loop() {
    if (!dmpReady) return;
    while (!mpuInterrupt && fifoCount < packetSize) {
        if (mpuInterrupt && fifoCount < packetSize) {
          fifoCount = mpu.getFIFOCount();
        }        
    }       
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();
    fifoCount = mpu.getFIFOCount();
    if ((mpuIntStatus & _BV(MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024) {
        mpu.resetFIFO();
        fifoCount = mpu.getFIFOCount();
    } 
    else if (mpuIntStatus & _BV(MPU6050_INTERRUPT_DMP_INT_BIT)) {
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
        mpu.getFIFOBytes(fifoBuffer, packetSize);
        fifoCount -= packetSize;

      // OUTPUT_READABLE_WORLDACCEL
      mpu.dmpGetQuaternion(&q, fifoBuffer);
      mpu.dmpGetAccel(&aa, fifoBuffer);
      mpu.dmpGetGravity(&gravity, &q);
      mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
      mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
      Serial.print("Acceleration (x,y) m/s/s: ");
      Serial.print(aaWorld.x);
      Serial.print("  ");
      Serial.println(aaWorld.y);

     // Find the angle of acceleration
      //  double angle_of_acc = atan2(aaWorld.y, aaWorld.x);
      //  angle_of_acc *= 180/M_PI;

      // Get compass heading
      // mag.getHeading(&mx, &my, &mz);
      // float heading = atan2(my, mx);
      // if (heading < 0) heading += 2 * PI;
      // if (heading > 2 * PI) heading -= 2 * PI;
      // heading *= 180/M_PI;
      // heading += declination;

      // Offset angle of acceleration by the heading angle
      // wave_direction = angle_off_acc + heading
      
    }
}

Code snippet #7

Plain text
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
#include <ms5611.h> 


MPU6050 mpu;
MS5611 baro;
long pressure;
double altitude, min_height, max_height, wave_height, mid_point, smudge_factor, wave_power;
byte escaped, started;
unsigned long period_start, period_end;
float avg_period = -1;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Serial.println("Initializing I2C devices...");
  mpu.setI2CMasterModeEnabled(false);
  mpu.setI2CBypassEnabled(true) ;
  mpu.setSleepEnabled(false);
  mpu.initialize();
  Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  while (!baro.begin(MS5611_ULTRA_HIGH_RES)) {
    Serial.println("MS5611 connection unsuccessful, check wiring!");
    delay(500);
  }
}

void loop() {
  unsigned long start_time = millis();
  pressure = baro.readPressure(true);
  altitude = baro.getAltitude(pressure);
  max_height = altitude;
  min_height = altitude;

  //  for 15 seconds
  while(millis() - start_time < 15000){
    pressure = baro.readPressure(true);
    altitude = baro.getAltitude(pressure);
    if (altitude < min_height) min_height = altitude;
    if (altitude > max_height) max_height = altitude;
  }
  mid_point = (max_height + min_height)/2.0;
  wave_height = (max_height - mid_point) / 2.0;
  smudge_factor = wave_height * 0.15;
  Serial.print("Wave Height m: "); Serial.print(wave_height);
  
  start_time = millis();
  //  for 15 seconds 
  while(millis() - start_time < 15000){
    pressure = baro.readPressure(true);
    altitude = baro.getAltitude(pressure);
    //    if within a range of 30% of wave height from the mid point
    //    start the timer else stop it
    if (altitude < mid_point + smudge_factor && altitude > mid_point - smudge_factor){
      if ( !started){
        period_start = millis();
        started = true;
      }
      else{
        if ( escaped ){
          // if it has started and escaped and is now returning
          period_end = millis();
          started = false;
          escaped = false;
          // if the variable has already been assigned
          // use its previous value and new value to work out avg
          if(avg_period != -1){
            avg_period = (avg_period + (period_end-period_start)*2)  / 2.0;
          }
          // assign it
          else{
            avg_period =  (period_end-period_start)*2; 
          }

       }
      }
    }
    else{
      escaped = true;
    } 
  }
  Serial.print("  Period s: "); Serial.print(avg_period/1000);
  wave_power = (0.5 * wave_height * wave_height * avg_period / 1000);
  Serial.print("  Wave Power kW/m: "); Serial.println(wave_power); 
}

Code snippet #8

Plain text
#include <onewire.h>
#include <dallastemperature.h>

OneWire oneWire(6);
DallasTemperature sensors(&oneWire);
float water_temperature;

void setup() {
  Serial.begin(115200);
  sensors.begin();
}

void loop() {
  sensors.requestTemperatures();
  water_temperature = sensors.getTempCByIndex(0);  
  Serial.print("Water temperature C "); Serial.println(water_temperature);
  delay(200);
}

Credits

T3ch Flicks

T3ch Flicks

7 projects • 59 followers

Comments