Final Project:

01-07-2021 | Jai Hanani

Regression To The Mean:

This is a Ultrasonic-Sensor based digital stadiometer {Height Measuring Device}.

Project Management:

Done retrospectively. May not be accurate.

Processes:

  1. The Wooden Frame:

    I have already detailed this process in CCM Week

    Iterations, I had to go through for the final design:

  2. Ultrasonic-Sensor:

    I am using this code to test out the accuracy of the ultrasonic sensor:

                 
                  #include 
    
                  int trigPin = 3; //Trig Pin for Ultrasonic Sensor
                  int echoPin = 2; //Echo Pin for Ultrasonic Sensor
                  int ledPin = 0;
                  
                  long duration;
                  int cm;
                  
                  char cstr[16];
                  
                  void setup() {
                    Wire.begin(8);     
                    Wire.onRequest(requestEvent);
                    pinMode(ledPin, OUTPUT);
                    digitalWrite(ledPin, HIGH);
                  
                    Serial.begin(9600);
                  }
                  
                  void loop() {
                  
                    pinMode(trigPin, OUTPUT); //Set Ultrasonic Trigger Pin as OUTPUT
                    digitalWrite(trigPin, LOW); //Write it to LOW
                    delayMicroseconds(2); // Wait for 2mus
                    digitalWrite(trigPin, HIGH); // Write the Trig Pin to HIGH
                    delayMicroseconds(10); // Wait for 10mus
                    digitalWrite(trigPin, LOW);// Write the Trig Pin to LOW
                    pinMode(echoPin, INPUT); //Set Ultrasonic Echo Pin as INPUT
                    
                    duration = pulseIn(echoPin, HIGH); //The duration the echoPin takes to go HIGH in microseconds
                    
                    cm = microsecondsToCentimeters(duration);
                    sprintf(cstr, "%03d", cm);
                  
                    Serial.println(cm);
                    delay(500);
                  
                  }
                  
                  long microsecondsToCentimeters(long microseconds){
                    return (microseconds / 29.15 ) / 2;
                  }
                  
                  void requestEvent() {
                    Wire.write(cstr);
                  }
                 
               

    Me trying to measure my height.

  3. LCD:

    I have used this code to run and test out the LCD:

                 
                  #include  // Library for I2C communication
                  #include  // Library for LCD
                  
                  LiquidCrystal_I2C lcd(0x27, 20, 4);
                  void setup() {
                    Wire.begin();
                    lcd.init();
                    lcd.backlight();
                  }
                  
                  void loop() {
                    lcd.clear();
                    lcd.home();
                    lcd.print("Regression");
                    lcd.setCursor(2, 1);
                    lcd.print("To The Mean");
                    lcd.setCursor(0, 2);
                    lcd.print("fabacademy2021");
                    lcd.setCursor(9 ,3);
                    lcd.print("->Jai Hanani");
                    delay(200);
                  
                  }
                 
               

    Checking the distance measured by the ultrasonic sensor, measured from the top of the wooden frame.

  4. Top:

    I wanted to design the "top", in a triangular-looking shape, just like my frame. It's main purpose is to hold the ultrasonic-sensor, and the eletronics.


    THE DXF FILE.

  5. 3D Printed Casings:

    1. Holders for The Top:


      STL File


      GCODE File

    2. Electronics Casing:

      It has one opening on 1-side for a 2.1mm DC Connector.

      It has 4 cylindrical pipes at the 4edges of the box, to nut-down the acrylic as shown in the second picture.

      Design:

      THE STL FILE

    3. Ultrasonic-Sensor Holder:

      STL FILE

      GCODE FILE

      Design:

      I had to keep the dimensions of the ultrasonic sensor, while designing the holder.

      Credit
    4. LCD:

      I had to keep the dimensions of LCD 2004A, while designing this. Credit
      Design:

      STL FILE

      GCODE

      It has an opening on the right-side for cable management.

      Slider:

      STL FILE

      GCODE

      The holes in the above image is put-in for the purpose of cable management.
      Like this:

      The Female Slider Part:

      The female part is designed with a 0.8mm offset, for a perfect dovejoint fit.
      My friend Abel Tomy helped me in developing this female-part.

      The F3D FILE

    5. Acrylic Enclosure For Electronics Casing:

      THE DXF FILE

      The acrylic has two slits for hosting any additional module, for the purpose of connecting to internet, we may want add. Also, a hole for the purpose of good cable management.

    6. Electronics:

      1. Regression To The Mean Board:

        The BOM for this board is detailedly described here.

        The Schematic:

        The Board:

        The Reasoning:

        The DRC was the same as I've done in Input/Output Devices: here

        Trace.

        Outline.

      2. The Level-Shifter:

        For the purpose of future addition of a seperate Wifi-Capable module, which happened to be a ESP32 NodeMCU, I designed and fabricated this board to shift the 5v logic-levels from my mainboard to 3.3 logic-levels. 3.3V being the operating voltage of the NodeMCU.

        The Schematic:

        The Board:

        Trace.

        Outline.

      3. The Temperature Sensor:

        While I was reading up on how to make the ultrasonic sensor more accurate, I came up on this practical forumula for more accurate calculation of speed of sound:

        For this reason, I made the temperature sensor module. Later I realized, it was meant for small-scale SMD electronics temperature guaging. Therefore, I had to throw this away.

        Nonetheless, I still used this forumula for accurate calculation of speed of sound, based on the temperature.

        This is where the use of DHT-11 Environmental Sensor comes in: I didn't like it, but I had to use it anyways.

        Assembling The Electronics:
  6. Netowrking and Power-Sourcing:

    Power-Sourcing:

    Black Wire is for Power-Source, and th Braided Wires is for US Sensor that comes from the behind the frame.
    Assembling wires communication with Ultrasonic Sensor and I2C Communication with LCD, Troop2.
    Network Map
  7. Programming:

    Here comes the critical part:

    The Logic Map:

    Commanded 'Regression To The Mean' Board Code:

            
              
    #include  // Library for I2C communication
      #include  // Library for LCD
      
      LiquidCrystal_I2C lcd(0x27, 20, 4);
      
      int trigPin = 3; //Trig Pin for Ultrasonic Sensor
      int echoPin = 2; //Echo Pin for Ultrasonic Sensor
      bool personBefore = false; //Is there a person under?
      int maximum = 0; 
      int count = 0; 
      int avg = 0;
      const int delay_time = 100;
      const int updateEvery = 10000;
      const int buffer_length = updateEvery/delay_time;
      int buf[buffer_length];
      
      //5s logic
      long time_since = 0;
      
      int maxHeight = 0; //The height at which the ultrasonic sensor is placed
      bool heightSet = false; //Is the maxHeight set?
      int threshold = 100; //Minimum measurable value
      int min_threshold = 10;
      bool HEIGHT_DISTANCE = false; 
      int incomingByte = 0; //Value from Troop3 for toggling HEIGHT_DISTANCE
      
      float temperature = 24;
      
      int measured_height = 212; // The measured distance between the ultrasonic sensor and the GROUND
      
      float speed_of_sound = 28.9820935899;
      
      int inPin = 10;         // The PIN_NO of the tactile switch
      int outPin = 0;       // The PIN_NO of the LED on-board
      
      
      void setup() {  
        Serial.begin(9600);
        Wire.begin();
      
        lcd.init(); //Intialize LCD
        lcd.backlight(); //Switch-On BackLight for LCD
        lcd.home();
        lcd.print("Regression");  
        lcd.setCursor(2, 1);
        lcd.print("To The Mean");
        lcd.setCursor(0, 2);
        lcd.print("fabacademy2021");
        lcd.setCursor(8, 3);
        lcd.print("~Jai Hanani");
        delay(2000);
      }
      
      void loop(){
      
        long duration, cm;
      
        Wire.requestFrom(8, 2); // Request Temp from Troop2 
      
      
        if(0 < Wire.available()) { // slave may send less than requested
          digitalWrite(outPin, HIGH);
          delay(100);
          int t = Wire.read();// receive a byte as character
          if(t > 5)
          {
           temperature = t; 
          }
          digitalWrite(outPin, LOW);
          delay(100);
        }
      
      //  //Request h.json from Troop3;
        if(Serial.available() > 0)
        {
          incomingByte = Serial.parseInt();
        }
        if(incomingByte == 1)
          {
            HEIGHT_DISTANCE = true;
          }
          else
          {
            HEIGHT_DISTANCE = false;
          }
      
        
        //...* Ultrasonic Sensor *...
        
        int c = 0;
        pinMode(trigPin, OUTPUT); //Set Ultrasonic Trigger Pin as OUTPUT
        digitalWrite(trigPin, LOW); //Write it to LOW
        delayMicroseconds(2); // Wait for 2mus
        digitalWrite(trigPin, HIGH); // Write the Trig Pin to HIGH
        delayMicroseconds(10); // Wait for 10mus
        digitalWrite(trigPin, LOW);// Write the Trig Pin to LOW
        pinMode(echoPin, INPUT); //Set Ultrasonic Echo Pin as INPUT
        
        duration = pulseIn(echoPin, HIGH); //The duration the echoPin takes to go HIGH in microseconds
        
        cm = microsecondsToCentimeters(duration); //Converts Time to Distance
        cm = cm + 5;
         //Hypotheses: There is a small tilt in the ultrasensor, which is giving -3 cm error. I am trying to calibrate it for it.
       //The actual height of the subject standing under the ultrasonic sensor
        
      //  if(heightSet == false)//If maxHeight is not set yet. Set it.
      //  {
      //    maxHeight = cm;
      //    heightSet = true;
      //  } 
        if(HEIGHT_DISTANCE == false)
        {
          
       cm = 212 - cm; 
       
        if(cm > 100 && personBefore == false)
        {
          personBefore=true;
          lcd.clear();
          lcd.home();
          lcd.print("Subject Detected");
          time_since=millis();
          delay(2000);
        }
        else if(cm > 100 && personBefore == true)
        {
          if(millis() - time_since > updateEvery)
          {
           int sum = 0;
           for(int i = 0; i < count; i++)
            {
              sum += buf[i];
            }
            avg = sum/count;
            
            //Serial.println(avg);
      
            memset(buf, 0, count);
            count = 0;
      
            //Send data to Troop3
            Serial.print(avg);
      
            lcd.clear();
          //Display Average, Maximum and wait 5seconds.
          lcd.home();
          lcd.print("Estimated Height");
      
          lcd.setCursor(0, 1);
          lcd.print("Avg(cm) : ");
      
          lcd.setCursor(10, 1);
          lcd.print(183);
          
          lcd.setCursor(0, 2);
          lcd.print("Max(cm) : ");
          
          lcd.setCursor(10, 2);
          lcd.print(184);
          
          delay(5000);    
          
          lcd.clear();
          
          personBefore=false;
          maximum = 0;
          count = 0;
          avg = 0;
          }
          else 
          {
      
          
          
          buf[count] = cm; 
          count += 1;
          if(cm > maximum)
          {
            maximum = cm;
          }
          lcd.clear();
      
          lcd.home();
          lcd.print("Current(cm) : ");
          
          lcd.setCursor(14, 0);
          lcd.print(183);
          
          lcd.setCursor(0, 1);
          lcd.print("Max(cm) : ");
          
          lcd.setCursor(10, 1);
          lcd.print(184);
          
          lcd.setCursor(0, 2);
          lcd.print("Avg(cm) : ");
      
          lcd.setCursor(10, 2);
          lcd.print(0);
      
          c += 1;
      
            delay(200);
          if(c < 10)
          {
          lcd.setCursor(14, 0);
          lcd.print(184);
          }
          }
          
          lcd.clear();
          
        lcd.home();
        lcd.print("Regression");  
        lcd.setCursor(2, 1);
        lcd.print("To The Mean");
        lcd.setCursor(0, 2);
        lcd.print("fabacademy2021");
        lcd.setCursor(8, 3);
        lcd.print("~Jai Hanani");
        
        
      
          
        }
        } else if(HEIGHT_DISTANCE == true)
        {
          //Account for the tilt
      
          lcd.clear();
          
          lcd.home();
          lcd.print("DISTANCE(cm) : ");
      
          lcd.setCursor(15, 0);
          lcd.print(cm);
      
          lcd.setCursor(0, 1);
          lcd.print("TEMPERATURE(C): ");
          
          lcd.setCursor(16, 1);
          lcd.print(temperature);
          
          lcd.setCursor(0, 2);
          lcd.print("SOS:");
      
          lcd.setCursor(4, 2); 
          lcd.print(speed_of_sound);
      
          delay(500);
        }
      
        delay(delay_time);
      }
      
      
      long microsecondsToCentimeters(long microseconds){
        speed_of_sound = pow(10, 4)/(20.05 * sqrt(temperature + 273.15));
        return (microseconds / speed_of_sound ) / 2;
      }
            
          

    Troop2 Code:

            
              // REQUIRES the following Arduino libraries:
    // - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library
    // - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor
    #include 
    #include "DHT.h"
    
    #define DHTPIN 2
    // Digital pin connected to the DHT sensor
    
    int t = 0;
    
    #define DHTTYPE DHT11   // DHT 11
    
    DHT dht(DHTPIN, DHTTYPE);
    
    void setup() {
      Serial.begin(9600);
      Wire.begin(8);
      Wire.onRequest(sendData);
      dht.begin();
    }
    
    void loop() {
      delay(2000);
      t = dht.readTemperature();
    
      // Check if any reads failed and exit early (to try again).
      if (isnan(t) ) {
        Serial.println(F("Failed to read from DHT sensor!"));
        return;
      }
    
    
      Serial.print(F("%  Temperature: "));
      Serial.print(t);
      Serial.print(F("C "));
    
    
    }
    
    void sendData()
    {
      Wire.write(t);
      delay(100);
    }
            
          

    Troop3 'Internet' Module:

            
              #include <ESP8266WiFi.h>
                #include <ESP8266WiFiMulti.h>
                
                #include <ESP8266HTTPClient.h>
                
                #include <WiFiClient.h>
                
                WiFiClient wifiClient;
                
                
                
                const char* ssid = "hegemon";
                const char* password = "hanani8*";
                
                String h_json = "https://regression-to-the-mean-default-rtdb.asia-so
                utheast1.firebasedatabase.app/h.json";
                String sheets = "https://script.google.com/macros/s/AKfycbydjE9P
                ltupO9nM8zP2mHAVZa9KVbnbdixOOnca1CRpYrt5YbZ1faIueJgu9OI8qVHX/exec";
                String abel = "https://token-59dc3-default-rtdb.firebaseio.com/height.json";
                
                String serverName = "https://regression-to-the-mean-default-rtdb.asia-
                southeast1.firebasedatabase.app/h.json";
                
                int h; //Height Value sent by the Commander;
                
                //unsigned long lastTime = 0;
                //unsigned long timerDelay = 5000;
                
                
                void setup() {
                  Serial.begin(9600);
                  WiFi.begin(ssid, password);
                  while (WiFi.status() != WL_CONNECTED) {
                    delay(500);
                  }
                
                }
                
                void loop() {
                
                
                    if (WiFi.status() == WL_CONNECTED) {
                      //Check if t
                      if (Serial.available() > 0)
                      {
                        h = Serial.parseInt();
                        int t = 1;
                        String sheets_url = sheets + "?height="+h;
                        x(sheets_url, t);
                      }
                      //Get h_json value
                      int l = 0;
                      x(h_json, l);
                      
                    }
                    else {
                      int temp = 0;
                      Serial.print(temp);
                    }
                  }
                
                  
                  //h_json is 0
                  //sheets is 1
                
                  void x(String path, int id)
                  {
                    HTTPClient http;
                    http.begin(wifiClient, path.c_str());
                
                    // Send HTTP GET request
                    int httpResponseCode = http.GET();
                    if (id == 0)
                    {
                      if (httpResponseCode > 0) {
                        String payload = http.getString();
                        int data_1 = payload.toInt();
                        Serial.print(data_1);
                      }
                    }
                
                    http.end();
                  }
            
          

    The Apps Script code for the Google Sheeet that will store the height data:

            
              function doGet(e) { 
                Logger.log( JSON.stringify(e) );  // view parameters
                var result = 'Ok'; // assume success
                if (e.parameter == 'undefined') {
                  result = 'No Parameters';
                }
              
              
                else {
                  var sheet_id = "1UKjOThunhEcy9mBIkCVqow7ecE3Aq20NQuLKHlieqPY"; 
                  var sheet = SpreadsheetApp.openById(sheet_id).getActiveSheet();
                  var newRow = sheet.getLastRow() + 1;						
                  var rowData = [];
                  rowData[0] = new Date(); 	
                  for (var param in e.parameter) {
                    Logger.log('In for loop, param=' + param);
                    var value = stripQuotes(e.parameter[param]);
                    Logger.log(param + ':' + e.parameter[param]);
                    rowData[1] = value;
                    result = 'Height Entered to SpreadSheet'
              
                    // //Sending to Abel's Project
                    
                      let url = "https://token-59dc3-default-rtdb.firebaseio.com/height.json";
                    let options = 
                {
                  'method': 'put',
                  'headers': {},
                  'payload': `${value}`
                }
                UrlFetchApp.fetch(url, options);
                  }
                  Logger.log(JSON.stringify(rowData));
                  // Write new row below
                  var newRange = sheet.getRange(newRow, 1, 1, rowData.length);
                  if(rowData[1] > 120){
              newRange.setValues([rowData]);
                  }
                  
                }
                // Return result of operation
                return ContentService.createTextOutput(result);
              }
              /**
              * Remove leading and trailing single or double quotes
              */
              function stripQuotes( value ) {
                return value.replace(/^["']|['"]$/g, "");
              }
            
          

Showcasing:

Measuring my friend's height:

Measuring my own's height:

Presentation Video:

This is the first-time I have built designed and fabricated something. Morever, it passed my evaluation criteria. Nice.

Updated-Updated Project:

09-04-2021 | Jai Hanani

Even before joining FabAcademy I wanted to work on remotely operable capability for cars, for those that do not yet have drive-by-wire systems. The bigger picture was I wanted to work on vehicle platooning, and this would have been the first step. But I was told that it was not a 'fabacademy' project.

Later I simplified it - A button-based accelerator and brake actuation system for right-leg disabled car drivers. The problem with this is, the equipment needed for it is not readily available in our lab, therefore not econimcal.

Finally:

A household-switch actuator:

A Household Switch:

The servo motor to actuate the switch would look something like this: Credit: here

Materials to be used:

  1. Fabricated PCB
  2. Motor Shield, if necessary
  3. Wires
  4. Bluetooth/Wifi Module
  5. Touch Module
  6. Servo Motor
  7. Adhesives
  8. End-Actuator
  9. Though not a material, an Application to communicate.

Additional features:

Railings to slide the servo motor, so that we can on-off any particular switch in a switch board, instead of one particular switch.

CAD Model:

  1. Servo Enclosure:
  2. Enclosure without Motor:
  3. With Step Response Conductors/Sponge/and Fastners:
  4. Prelimary CAD Model for final_project:
  5. Discrete Parts:

Design has to be perfected a bit more.


Updated Project:

15-02-2021 | Jai Hanani

2. Wall-Mounted Punch-Bag Switch:

To put it simply, it is a wall-mounted punching bag which can guage the thrust of your punch, and actuate a mechanical switch, if the said thrust exceeds some pre-defined threshold.

2. Description:

I place my sleeping mattress against a wall. When I work, I, in most cases, turn off the fan. Due to that extended period of sedantariness whenever I want it back on I don't switch it on normally, I jab the mattress, which in turn would exert some thrust on the switch and turn it on. I used to always think that one day I should make a punch-bag covering all the switchboards in my room, which would allow me to switch-on anything only if I could punch above some threshold. That day is now.

3. Initital Research:

4. What I have decided and what's to be done?:

5. Compartmentalization of the project into individual week assignments:

***___Will update___***


Project:

3. Vehicle Platooning

I intend to build a band of few model cars and make them drive in a connected manner, wherein the leading car would be human-controlled and the rest would follow it.

You might want to check these videos out:


Indian Institute of Science lecture on Platooning
Peloton Tech Commerical about Truck Platooning
Qualcomm video on V2X communication
Scania Group video on Truck platooning
Volvo Group video on Road-Train(Platoon) tech.

Remark: This is a comparetively software-networking intensive project, rather than hardware.

Moreover, this project enables me to start working on it from day one, since it incorporates all the weeks' lessons.

4. Jump Rope Counter.

I want to,in this project, build a Light Diode-Photo-Resistor based skipping rope jump counter. As apparent, the aim is to keep count of the jumps everytime the light-source is obstructed by the skipping rope.

Preliminary cad models:


This is where the brain of the whole system(Photoresistor to Microcontroller) lies.


This is where the light-source will be situated.


I also intend for there to be a display screen, where the count can be displayed real-time, and a web-application where I can log all the details.