Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
yasuhiro yamashita
Created July 22, 2022 © Apache-2.0

Landslide Warning System

Japan is a mountainous country and many landslide disasters occur during the rainy season. This device detects and reports signs of landslid

BeginnerFull instructions provided4 hours36
Landslide Warning System

Things used in this project

Hardware components

Spresense boards (main & extension)
Sony Spresense boards (main & extension)
Only the main board is used.
×1
Garden light with solar panel and battery
Very inexpensive garden lights sold at a Japanese store called Daiso for about $2.5.
×1
3-axis acceleration, 3-axis gyro, barometric pressure, temperature sensor Add-on board
Equipped with BMI 160.
×1
HW-106
step up Power supply module
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

Landslide Warning System

Arduino
Reads acceleration information from the BMI160 and issues an alarm when an angle change greater than a threshold value occurs.
#include <Wire.h>
#include <math.h>
#include <BMI160Gen.h>
#include <LowPower.h>
#include <RTC.h>
#include <Arduino.h>
#include <File.h>
#include <Flash.h>

#define BAUDRATE  115200
#define SENSE_RATE   200
#define GYRO_RANGE   250
#define ACCL_RANGE     2

#define COUNT_FOR_CALIB 1024

#define deg_to_rad(a) (a/180*M_PI)
#define rad_to_deg(a) (a/M_PI*180)

#define PRINT_ACCL

uint16_t adjust_usec;
static float calib_accel_x = 0, calib_accel_y = 0, calib_accel_z = 0;
volatile int alarmInt = 0;
const int LEDPIN = 1;                //LED pin number for alert
const double threthold = 10.0;        //***Threshold for alerting (unit:degree)*******

void printClockMode()
{
  clockmode_e mode = LowPower.getClockMode();

  Serial.println("--------------------------------------------------");
  Serial.print("clock mode: ");
  switch (mode) {
  case CLOCK_MODE_156MHz: Serial.println("156MHz"); break;
  case CLOCK_MODE_32MHz:  Serial.println("32MHz"); break;
  case CLOCK_MODE_8MHz:   Serial.println("8MHz"); break;
  }
}

float convertRawAccel(int aRaw) 
{
  // ex) if the range is +/-2g ; +/-32768/2 = +/-16384 LSB/g
  float lsb_g = float(0x7FFF) / ACCL_RANGE;
  return aRaw / lsb_g;
}


void setup() {
//  Serial.begin(BAUDRATE);
  RTC.begin();
  LowPower.begin();
  LowPower.clockMode(CLOCK_MODE_8MHz);
//  printClockMode();
  bootcause_e bc = LowPower.bootCause();
//  Serial.print("bc = ");
//  Serial.println(bc);
  pinMode(LEDPIN, OUTPUT);
  digitalWrite(LEDPIN, LOW);

  digitalWrite(LED0,LOW);
  digitalWrite(LED1,LOW);
  digitalWrite(LED2,LOW);
  digitalWrite(LED3,LOW);
  
  BMI160.begin(BMI160GenClass::I2C_MODE);
  BMI160.setAccelerometerRate(SENSE_RATE);
  BMI160.setAccelerometerRange(ACCL_RANGE);

  // Serial.println("Calibrating...");
  unsigned long sampling_rate = 1000 / SENSE_RATE;

  // Calcurate offset
  for (int i = 0; i < COUNT_FOR_CALIB; ++i) {
    int xAcc, yAcc, zAcc;
    BMI160.readAccelerometer(xAcc, yAcc, zAcc);
    calib_accel_x += convertRawAccel(xAcc);
    calib_accel_y += convertRawAccel(yAcc);
    calib_accel_z += convertRawAccel(zAcc);
  }
  
  // mean value
  calib_accel_x /= COUNT_FOR_CALIB;
  calib_accel_y /= COUNT_FOR_CALIB;
  calib_accel_z /= COUNT_FOR_CALIB;
  double xInit = calib_accel_x, yInit = calib_accel_y, zInit = calib_accel_z;
  
  // Processing at initial startup
  if (bc == 0){
    if (Flash.exists("initData.txt")) Flash.remove("initData.txt");
    File initData = Flash.open("initData.txt",FILE_WRITE);
    initData.print(String(calib_accel_x, 3));
    initData.print(",");
    initData.print(String(calib_accel_y, 3));
    initData.print(",");
    initData.print(String(calib_accel_z, 3));
    initData.print(",");
    initData.close();
  }

  //Processing after deep sleep
  int counter = 0;
  if (bc == 5){
    String str;
    File initData = Flash.open("initData.txt");  
    while(initData.available()){
      if (counter == 0) {
        xInit = initData.readStringUntil(',').toDouble();
      }else if (counter == 1){
        yInit = initData.readStringUntil(',').toDouble();
      }else if (counter == 2){
        zInit = initData.readStringUntil(',').toDouble();
      }else{
        str += char(initData.read());
      }
      counter++;
    }
    initData.close();
/*
    Serial.println("start");
    Serial.println("init_x:" + String(xInit, 3));
    Serial.println("init_y:" + String(yInit, 3));
    Serial.println("init_z:" + String(zInit, 3));
    Serial.println("finish");
*/
  }

 /*
  Serial.println("calib_a_x:" + String(calib_accel_x, 3));
  Serial.println("calib_a_y:" + String(calib_accel_y, 3));
  Serial.println("calib_a_z:" + String(calib_accel_z, 3));
*/

  // SENSE_RATE is Hz and 2 millsec is the process time for this sketch
  adjust_usec = (1000/SENSE_RATE - 2) * 1000; 

  // Calculate the angle between the initial angle and the current angle
  double numerator = (xInit * calib_accel_x) + (yInit * calib_accel_y) + (zInit * calib_accel_z);
  double denominator1 = sqrt(pow(abs(xInit),2) + pow(abs(yInit),2) + pow(abs(zInit),2));
  double denominator2 = sqrt(pow(abs(calib_accel_x),2) + pow(abs(calib_accel_y),2) + pow(abs(calib_accel_z),2));
  double degree = acos(numerator/(denominator1*denominator2))*(180/3.141592654);
//  Serial.println(degree);

  //alart output setting
  if (degree >= threthold){
    while(true){
      digitalWrite(LEDPIN,HIGH);
      digitalWrite(LED3,HIGH);
      delay(1000);
      digitalWrite(LEDPIN,LOW);
      digitalWrite(LED3,LOW);
      delay(1000);
    }
  }

/*
  if (degree >= 8){
      digitalWrite(LED0,HIGH);
      digitalWrite(LED1,HIGH);
      digitalWrite(LED2,HIGH);
      digitalWrite(LED3,HIGH);      
      delay(1000);
  } else if (degree >= 6){
      digitalWrite(LED0,HIGH);
      digitalWrite(LED1,HIGH);
      digitalWrite(LED2,HIGH);
      digitalWrite(LED3,LOW);
      delay(1000);
  } else if (degree >= 4){
      digitalWrite(LED0,HIGH);
      digitalWrite(LED1,HIGH);
      digitalWrite(LED2,LOW);
      digitalWrite(LED3,LOW);
      delay(1000);
  } else if (degree >= 2){
      digitalWrite(LED0,HIGH);
      digitalWrite(LED1,LOW);
      digitalWrite(LED2,LOW);
      digitalWrite(LED3,LOW);
      delay(1000);
  } else {
      digitalWrite(LED0,LOW);
      digitalWrite(LED1,LOW);
      digitalWrite(LED2,LOW);
      digitalWrite(LED3,LOW);
  }
*/

  LowPower.deepSleep(3600);
}

void loop() {
}

Credits

yasuhiro yamashita

yasuhiro yamashita

2 projects • 0 followers

Comments