top of page

Blog 4: Project Development🛠️

  • Feb 19, 2025
  • 9 min read

Updated: Feb 26, 2025



Guys, is this really the last blog 🥹


I don't know whether to be happy or sad


but that's not what we're here for so..


let us begin!




Starting with our very own ✨chemical device




Our Chemical Device


Meet Trap, the gas detector. it. detects. gas.🤯


Why? because..


In rural areas, indoor biomass cooking🔥🪵 is a common practice, deeply rooted in tradition.


However, it comes with a hidden danger—poor ventilation traps toxic gases like carbon monoxide (CO) and smoke indoors💨, putting families at risk of serious health issues🤒🤧


That’s where our solution steps in to make a difference💡


Once Trap detects high levels of CO🚨, the ventilation system kicks into action, keeping the air clean and safe to breathe🍃



The first sketch of our gas detector, drawn by Fiona✍🏼



Moving on to the team⤵️


Team Planning, Allocation and Execution


yes we have our own logo🤩

Our work allocation

CEO🔥:

Oversee the entire operation & ̶s̶i̶t̶ ̶i̶n̶ ̶o̶f̶f̶i̶c̶e̶ ̶a̶l̶l̶ ̶d̶a̶y̶ handle cardboard during building process


CFO💸:

Track our finances & create the aesthetic for Trap


CSO🦺:

Ensure safe working environment (using Risk Assessment) & write Arduino program for Trap


COO🐦‍⬛:

(birds when u give them bread)

Track progress on Gantt Chart & design 3D models for printing



Our Gantt Chart

Legend:

Yellow - Plan to complete by

Grey - Actually completed by


Using this chart, we planned ahead all of the specific tasks and assigned them accordingly🔢

You can see we had to rush a lot of things on the 4th week😭



Final Bill of Materials (BOM)

we almost hit the budget of $100😬

Time for the execution!💪🏼


Design and Build Process


our first model of Trap
our final model of Trap



vs








Let's watch a video🔊 of the 3D modelling process:


I had to cut out some parts in the video since we decided not to print out the top+bottom of Trap as that would take another 2-3 hours of printing time (and use more resources😢💸)

Instead, we chose to be more sustainable and used cardboard📦😎


While waiting for the 3D prints,

Rakshan & I worked on the cardboard parts that will become the skeleton for Trap📏✂️


I even brought them back and tried piecing them together🧩


Our first look at Trap:

fyi: the middle part is a failed print😅

Once we had all the parts ready, it was time for decorating!🖌️


Thanks to Fiona, our plain cardboard parts transformed into much more colorful pieces!🟥🟩


more pictures can be found here👈🏼


At the same time, Muhsin, our programmer was busy tweaking the code🧑🏾‍💻

and making sure each of our electronics worked (smoke sensor👃🏼, LCD screen🔤, LED🚨)


Here's the code:

Trap's internal programming🤖

#include <LiquidCrystal_I2C.h>

#include <Wire.h>


// Pin Definitions

const int gasSensorPin = A0;

const int ledPin = 5;

const int buzzerPin = 8;

const int fanPin = 7;  // Pin for the fan


// Sensor Constants

const float RL = 10000.0;  // Load resistance (Ω)

float freshAirRatio = 1.52;  


// LPG Sensor Calibration (from sensor datasheet)

// (Replace with values from your sensor's datasheet)

const float m = -0.473;

const float b = 1.413;


// Threshold for alert (PPM)

const float gasThresholdPPM = 1000.0;


// Variables

float gasPPM;

int gasValue;

float R0;


// LCD Setup

LiquidCrystal_I2C lcd(0x27, 16, 2);


void setup() {

  pinMode(ledPin, OUTPUT);

  pinMode(buzzerPin, OUTPUT);

  pinMode(fanPin, OUTPUT);  // Set fan pin as output

  Serial.begin(9600);


  lcd.init();

  lcd.backlight();

  lcd.clear();


  // Calibrate R0 in clean air

  R0 = calculateR0();

  Serial.print("Calibrated R0: ");

  Serial.println(R0);

  Serial.println("Calibration Complete. Monitoring Gas Levels.");

}


void loop() {

  const int numReadings = 10; // Number of readings to average

  float total = 0;

  float sensorResistance;

  float ratio;


  // Take multiple readings for stability

  for (int i = 0; i < numReadings; i++) {

    gasValue = analogRead(gasSensorPin);

    if (gasValue > 1023) gasValue = 1023;

    sensorResistance = ((1023.0 / gasValue) - 1) * RL;

    ratio = sensorResistance / R0;

    total += pow(10, (log10(ratio) - b) / m);

    delay(50);

  }

  gasPPM = total / numReadings;


  // Debug prints

  Serial.print("Raw Analog: ");

  Serial.println(gasValue);

  Serial.print("Calculated PPM: ");

  Serial.println(gasPPM);


  // Update LCD display

  lcd.clear();

  lcd.setCursor(0, 0);

  lcd.print("Conc: ");

  lcd.print(gasPPM);

  lcd.print(" PPM");


  if (gasPPM > gasThresholdPPM) {

    lcd.setCursor(0, 1);

    lcd.print("Status: HIGH!");

    digitalWrite(fanPin, HIGH);


    // For high gas concentrations, run the alarm routine repeatedly for 1 second

    unsigned long alarmStart = millis();

    while (millis() - alarmStart < 1000) {

      triggerAlarm(gasPPM);

    }

  } else {

    lcd.setCursor(0, 1);

    lcd.print("Status: Normal");

    digitalWrite(fanPin, LOW);

    blinkLED();

    delay(1000);

  }

}


/*

 * triggerAlarm() produces a beep on the buzzer and a flash on the LED.

 * The on-time is fixed at 50ms. The off-time is mapped from 200ms (at 1,000 PPM)

 * down to 50ms (at 5,000 PPM), so the beep rate increases as gas concentration rises.

 */

void triggerAlarm(float concentration) {

  const float maxConcentration = 5000.0;

 

  int onTime = 50; // beep on-time in ms

  // Map concentration to offTime: at gasThresholdPPM (1000 PPM) offTime ~200ms, at maxConcentration offTime ~50ms.

  int offTime = map(concentration, gasThresholdPPM, maxConcentration, 200, 50);

  offTime = constrain(offTime, 50, 200);


  // Activate buzzer and LED together for the beep

  tone(buzzerPin, 1000); // 1kHz tone

  digitalWrite(ledPin, HIGH);

  delay(onTime);

  noTone(buzzerPin);

  digitalWrite(ledPin, LOW);

  delay(offTime);

}


/*

 * blinkLED() is used when gas concentration is normal.

 * It makes the LED blink slowly (1 second on, 1 second off).

 */

void blinkLED() {

  digitalWrite(ledPin, HIGH);

  delay(1000);

  digitalWrite(ledPin, LOW);

  delay(1000);

}


/*

 * calculateR0() calibrates the sensor in clean air.

 * It reads the sensor several times and calculates the baseline resistance R0.

 */

float calculateR0() {

  float sumRs = 0;

  int samples = 50;

  float sensorResistance;


  Serial.println("Calibrating R0 (Clean Air)...");


  for (int i = 0; i < samples; i++) {

    int sensorVal = analogRead(gasSensorPin);

    sensorResistance = ((1023.0 / sensorVal) - 1) * RL;

    sumRs += sensorResistance;

    delay(50);

    Serial.print("Sample ");

    Serial.print(i + 1);

    Serial.print(": Rs = ");

    Serial.println(sensorResistance);

  }


  float R0_calibrated = sumRs / (samples * freshAirRatio);

  Serial.print("Calibrated R0: ");

  Serial.println(R0_calibrated);


  return R0_calibrated;

}

(it takes me 3 scrolls to go through the whole thing 💀)

🤯🤯🤯


From what I understand, here's how the code works:

  • Power on, the gas sensor starts calibration📊 & ppm reading on LCD screen might spike📈

  • Once done, the reading goes back down to "Normal" range (<1000ppm)

  • At this range, LED blinks slowly🚨

  • When high level detected (>1000ppm), buzzer goes off🔊 and LED blinks faster🚨🚨🚨


With the code complete, it was time to assemble🔨 all the components together..


Trap's skeleton💀


Adding the electronics🔌


..and with that, Trap was born🙌🏼🤖

Another video🔊, showing how Trap works:



Oh yea, Trap is also a chicken 🐔



But wait, that's not all..😵


Problems and Solutions


As you can see from the first video, I had to change the Fusion360 model too many times because there were some problems with the prints and we printed 3.5 times (one failed halfway🫤) before it was finally successful✨


Here are some problems we faced, along with our solutions:


Problem 1: No mechanism💀


During the designing process, after finishing the sketches and 3D modelling

we realized we forgot to include a mechanism to our device🫠


So we brainstormed different ideas, like using gears to open the lid⚙️


Eventually, we decided on this latch/lock mechanism that can be found in water bottles:


After more 3D modelling, since we were making a larger,

simpler version of the mechanism, I worried it might not work😟


But in the end, it was the only print that functioned properly on the first try😭



Problem 2: Print-in-place hinge🤝


The hinges kept fusing together☹️

..even after increasing the tolerance from 0.2mm to 0.3mm😖

I don't even know why I tried making it print-in-place


To fix this, we changed it into 2 parts with a rod to join them together, and the hinge worked🥳



Problem 3: Broken parts⛓️‍💥


Originally we wanted to secure the gas sensor using the method shown below:

but the pegs kept breaking off🥲 so we completely removed it,

and we decided to use pins📍instead



..also, you can even make your very own Trap!⤵️


Project Design Files


The Fusion360 files:

Gas detector middle + rod


Lever mechanism

⬆️This is scaled up, so adjust accordingly to your preference in the 3D slicer👍🏼



The 156 lines of code✨:



Lastly, reflection time🫠


Personal Learning Reflection



Our first chemical device

Looking back now,

I remember feeling excited for this project because I would get to do more 3D modelling🤓💀


Then about halfway through,

there were so many 3D printing issues that it felt like we were spending more time troubleshooting than actually building😅

(all of it could've been easily avoided if I had just put more thought into it😭)


But honestly, it was still fun, though I did not expect there to be so many things to do just to make a gas detector😣


And I am glad that everything happened the way it did, because it taught me a few lessons:


  1. There is strength in unity🫱🏼‍🫲🏾

A friend of mine once told me,


"a good CPDD group needs at least 1 member who can handle

3D modelling/programming/designing/presenting"


..and luckily for us, we have just that.


But even so, it would mean nothing if we did hadn't worked together

A better team is one that communicates, supports each other, and grows together🔥

Because those skills can be taught, but teamwork relies on everyone's effort💪🏼


Without Fiona sketching our design & buying the extra parts,

I wouldn't know what to model, and no model means no Trap, same goes for missing parts❌


Without Muhsin writing the code,

Trap would just be like a flashlight without batteries—born to shine, but left in the dark🌃


Without Rakshan working on most of the slides,

we would have ran out of time to complete everything



  1. Plan before you print😭

At first we only had a rough idea of what Trap would look like,

but I got too kiasu, for lack of a better term, and rushed the 3D modelling😅

and as you know, that backfired with all the printing issues🙃


I realized too late that I should have discussed with the team what we want specifically😔

That way simple mistakes like the print-in-place hinge fusing could be easily avoided by designing a different hinge, and it would have saved us a lot of time from re-printing over and over🤔



In the end,

I was quite surprised with how it went, I mean it was the second time I had worked on a project of this size (prototyping was like OSIP all over again) and this time it was a chemical product so I was mostly worried about the electronics not working.

But I'm pretty sure the code worked before the 3D printed parts💀


I think for this project, the key takeaway for me would be that it is best to check through with the team before rushing into action, that is if you want to save time, effort, and a lot of headaches😵‍💫


As for this module,

throughout the many practicals and lessons, there was always something new to learn and areas for improvement. We learnt to trust our own skills, a bit of programming (with the help of ChatGPT of course🤖), and that gambling is bad Practical 3


and blogging,

even though writing is probably not my thing (this blog took 3 days😭),

it was still enjoyable when I get to express my creativity🎨🖌️

Whether it is through editing videos or making memes to put on the blog,

things like those were what made each blog more fun to write😆



speaking of memes..

uh oh


..and that's it, goodbye👋🏼




End.

Comments


© 2035 by Design for Life.
Powered and secured by Wix

bottom of page