Hardware

Hardware


We have genetically modified E. coli so as to detect formaldehyde, a toxic chemical for organisms. We constructed and transformed the recombinant plasmids pFrmR-dTomato and HxIR13A-dTomato into E. coli. The GM bacteria can synthesise red proteins and turn pink in the presence of formaldehyde. However, the process of producing red proteins requires a period of time so it has to be checked regularly. Thus, we decided to build a machine that can detect the colour change of the GM E. coli. by the auto detection of the colour change by the camera, we can know whether the surrounding air contains formaldehyde which is harmful for our health. If we can realise the presence of formaldehyde promptly, we can remove them as quickly as possible, which prevents the pollutants from harming our bodies.

The aims of our project are summarised in the following:



Features of ADAM

Figure 1. Mortise and tenon structure is used

We set out to include the Mortise and Tenon structures in the device. Chinese architects have been employing the structure in wooden buildings and furniture since 7000 years ago in China[1]. There are a number of advantages to utilising the structure in our machine. First, it has a cheaper manufacturing cost on the device as we only need to produce plates with mortise and tenon, and it is unnecessary to construct the whole device completely. Meanwhile, the WIP (work in progress) has a smaller size than a completed machine which lowers the cost of delivery. Finally, it is user-friendly for customers to construct the device themselves as the structure contributes to the ease of building the device. Apart from that, we originally planned to use plastic as the material for the device. Nevertheless, another investigation carried by other schoolmates uncovered that microplastic fragments will be produced from plastic products under UV light erosion[2]. These nanoplastics pollute the environment and lead to accumulation of them in animals. Owing to that, we soon object to the idea and consider using cardboards to build up our device. However, cardboards is vulnerable as it may be weakened by high humidity. Lastly, we selected fiberboard as our building material because of its biodegradability. Also, the fiberboard allows mass production by laser cutting.

FIgure 2. The petri dish containing E. coli is put in loading dock

The transparent plastic petri dish which enables clear observation can be placed on the dock which makes the replacement of E. coli easily. The petri dish is made in plastic as it is cheaper and it is less vulnerable than glass petri dish, making it more durable. This avoids users getting hurt if the glass petri dish is broken accidentally. Besides, a white plate is placed under the Petri dish for the ESP32CAM to detect the colour of E. coli more clearly. Therefore, a clearer and a more accurate colour change can be detected easily by the ESP32CAM. Also, the petri dish can be replaced easily.


Figure 3. The fan help drawing air in the machine

Formaldehyde is highly soluble in water, therefore the GM E. coli in bacterial culture can effectively sense formaldehyde in the air. However, when the bacterial culture is enclosed in a non-ventilated device, it cannot come into contact with the formaldehyde in the environment, reducing the effectiveness and accuracy of the detection. As a result, we added a fan for ventilation to the device. The fan is programmed to operate periodically to draw air into the machine. If the air contains certain formaldehyde, it will dissolve into bacterial culture and stimulate the GM E. coli to develop a pink colour and the change can be picked up by the ESP32CAM colour sensor. The case of our machine is made of fibre boards. We process these boards by laser-cutting. There are mortise and tenon structures which ease the difficulty of assembling the machine.

Figure 4. The ESP32CAM analyses the photo taken to see whether pirk colour is present

Regarding the electrical parts in our machine, we purchase and adopt ESP32CAM as a detector and processor. This is because ESP32CAM is integrated with light which allows photo-taking in a dark environment. Meanwhile, ESP32CAM can provide Wi-Fi functionality when it connects with other equipment. We bought an extension board for ESP32CAM which enables a direct linkage between the ESP32CAMand the battery. Also, the board allows us to control the operation of the fan by using ESP32CAM. We employ IFTTT as a medium connecting the machine and user. IFTTT is a web service and mobile app that help users automate web-based desks and boost productivity. It connects different app and services together into Applets which is an automation allowing users to do things that their apps and devices cannot do on their own. The name “IFTTT” stands for “If this, then that '' in programming language. The company calls it because Applet would have 1 trigger and 1 action: if this happens, then that happens. For instance, if I come home, then turn on the lights at the entrance. In our project, the case is: if ESP32CAM detects red colour on the petri dish, then sends a message to the user's phone. We adopt IFTTT because it is user-friendly and does not require coding skills. Also, it allows us to customise the notifications that are sent to users.

We write an Arduino program to instruct our device to:

Details of the coding part are as follow:

1. Connect to WiFi network and ifttt
const char* ssid = "ABCD";
const char* password = "00000000";
WiFi.begin(ssid, password);


2. Fan is turned on for 2mins, and closed after 28 mins
if (currentMillis - previousMillis >= fanOnDuration) {
digitalWrite(fanPin, LOW);
previousMillis = currentMillis;
} else if (currentMillis - previousMillis >= fanOffDuration) {
digitalWrite(fanPin, HIGH);
previousMillis = currentMillis;}


3. LED light flash every 3 seconds
if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis;
if (ledState) {
ledcWrite(0, 0);
ledState = false;
} else { ledcWrite(0, 18);
delay(ledOnDuration);
ledcWrite(0, 0);
ledState = false;} }

4. ESP32-CAM calculates the average rgb of the middle part of the flame
int pixelCount = (endPixel - startPixel) / 2;
int avgR = totalR / pixelCount;
int avgG = totalG / pixelCount;
int avgB = totalB / pixelCount;


5. If is pink/red, then the device will send IFTTT message
if (isRed) {
Serial.println("Red Color Detected!");
// Send an IFTTT request here
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(iftttWebhookURL);
int httpResponseCode = http.POST("");
if (httpResponseCode > 0) {
Serial.println("IFTTT request sent successfully");

The Complete Code For A.D.A.M.

    #include 
    #include 
    #include "esp_camera.h"
    
    const char* ssid = "ABCD";
    const char* password = "00000000";
    const char* iftttWebhookURL = "https://maker.ifttt.com/trigger/IGEM/json/with/key/wSVPLTFjTMq05vxEz3tl_";
    
    const int ledPin = 4;    // GPIO pin for your LED (previously 2)
    const int fanPin = 12;   // GPIO pin for controlling the fan (added)
    
    bool ledState = false;
    bool fanState = false;   // Initialize the fan state as off
    unsigned long previousMillis = 0;
    const long interval = 3000;
    const long ledOnDuration = 250;
    const long fanOnDuration = 5000; // Fan on for 5 seconds
    const long fanOffDuration = 5000; // Fan off for 5 seconds
    unsigned long fanPreviousMillis = 0; 
    
    void setup() {
      Serial.begin(115200);
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.println("Connecting to WiFi...");
      }
    
      static camera_config_t camera_config = {
          .pin_pwdn = 32,
          .pin_reset = -1,
          .pin_xclk = 0,
          .pin_sscb_sda = 26,
          .pin_sscb_scl = 27,
          .pin_d7 = 35,
          .pin_d6 = 34,
          .pin_d5 = 39,
          .pin_d4 = 36,
          .pin_d3 = 21,
          .pin_d2 = 19,
          .pin_d1 = 18,
          .pin_d0 = 5,
          .pin_vsync = 25,
          .pin_href = 23,
          .pin_pclk = 22,
          .xclk_freq_hz = 20000000,
          .ledc_timer = LEDC_TIMER_0,
          .ledc_channel = LEDC_CHANNEL_0,
          .pixel_format = PIXFORMAT_RGB565,
          .frame_size = FRAMESIZE_VGA,
          .fb_count = 1
        };
    
      if (esp_camera_init(&camera_config) != ESP_OK) {
        Serial.println("Camera initialization failed");
        return;
      }
    
      pinMode(ledPin, OUTPUT);
      pinMode(fanPin, OUTPUT);  // Set the fan pin as an output
      ledcAttachPin(ledPin, 0);
      ledcSetup(0, 5000, 8);
      ledcWrite(0, 18);
    }
    
    void loop() {
      unsigned long currentMillis = millis();
    
      // LED flash once every 3 seconds
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
    
        if (ledState) {
          ledcWrite(0, 0); // LED off (brightness 0)
          ledState = false;
        } else {
          ledcWrite(0, 18); // Set the LED brightness to 7% of maximum intensity (30/255)
          delay(ledOnDuration); // Wait for 1/4 second
          ledcWrite(0, 0); // LED off (brightness 0)
          ledState = false;
        }
      }
    
      // Control the fan based on a 5-second on and 5-second off cycle
      if (fanState) {
        if (currentMillis - fanPreviousMillis >= fanOnDuration) {
          digitalWrite(fanPin, LOW); // Turn the fan off
          fanState = false;
          fanPreviousMillis = currentMillis;
        }
      } else {
        if (currentMillis - fanPreviousMillis >= fanOffDuration) {
          digitalWrite(fanPin, HIGH); // Turn the fan on
          fanState = true;
          fanPreviousMillis = currentMillis;
        }
      }
    
      camera_fb_t* fb = esp_camera_fb_get();
      if (!fb) {
        Serial.println("Camera capture failed");
        return;
      }
    
      // Calculate the middle part of the frame (adjust these values as needed)
      int startPixel = fb->len / 3;
      int endPixel = 2 * fb->len / 3;
    
      int totalR = 0;
      int totalG = 0;
      int totalB = 0;
    
      for (int i = startPixel; i < endPixel; i += 2) {
        uint16_t pixel = fb->buf[i] | (fb->buf[i + 1] << 8);
        uint8_t r = (pixel >> 11) & 0x1F;
        uint8_t g = (pixel >> 5) & 0x3F;
        uint8_t b = pixel & 0x1F;
    
        // Convert the RGB565 values to 0-255
        r = r * 255 / 31;
        g = g * 255 / 63;
        b = b * 255 / 31;
    
        totalR += r;
        totalG += g;
        totalB += b;
      }
    
      // Calculate the average RGB values for the middle part
      int pixelCount = (endPixel - startPixel) / 2; // Number of pixels in the middle part
      int avgR = totalR / pixelCount;
      int avgG = totalG / pixelCount;
      int avgB = totalB / pixelCount;
    
      Serial.print("Average R: ");
      Serial.print(avgR);
      Serial.print(" G: ");
      Serial.print(avgG);
      Serial.print(" B: ");
      Serial.println(avgB);
    
      // Check if the color is "red" based on thresholds (you can adjust these thresholds)
      int redThreshold = 80; // Adjust as needed
      int greenThreshold = 110; // Adjust as needed
      int blueThreshold = 130; // Adjust as needed
      bool isRed = (avgR > redThreshold) && (avgG < greenThreshold) && (avgB < blueThreshold);
    
      if (isRed) {
        Serial.println("Red Color Detected!");
        // Send an IFTTT request here
        if (WiFi.status() == WL_CONNECTED) {
          HTTPClient http;
          http.begin(iftttWebhookURL);
          int httpResponseCode = http.POST("");
          if (httpResponseCode > 0) {
            Serial.println("IFTTT request sent successfully");
          } else {
            Serial.println("IFTTT request failed");
          }
          http.end();
        }
      }
    
      esp_camera_fb_return(fb);
    
      delay(100); // Adjust the delay time as needed for stability
    }

If you want to explore how to make a smart device with IFTTT, feel free to use the above coding as a reference.

Figure 5. This is the power unit which is rechargeable

We decided not to use dry cells as the power supply since replacement is tedious. As they are thrown away, they will also pollute the environment by leaking chemicals which are highly toxic to organisms. Additionally, the rechargeable battery would provide better experiences for users, as they do not need to replace the batteries regularly. This brings users convenience. With the rechargeable batteries, less waste would be produced so that the environment can be protected also. Hence we utilise rechargeable Lithium batteries as our energy source as it is greener than other primary batteries. It allows using a simpler structure in our machines as it is unnecessary for battery replacement. We use a transformer to overcome the voltage and current difference between the battery and ESP32CAM, battery and charging board. Moreover, we connect the battery with a charging board which allows the user to recharge the Lithium battery. Besides, the power control unit is separated from the Petri dish in order to avoid splashing which may damage the power supply. This ensures the durability of the machine.

The Cost of ADAM

The following table lists all the materials and accessories we used in the production of our prototype ADAM and their costs.

table 1: production costs

The total cost of making ADAM is about USD$20. Compare the inaccurate handheld formaldehyde detector in the market (USD$30), the professional instrument that can accurately detect formaldehyde (USD$350) and professional formaldehyde detection service (USD$90/room). , our products can be priced at USD$30-90.

The Prototype

Figure 6. The prototype of ADAM and a diagram showing the design



Limitations

Future directions

In order to have a deeper investigation and better improvement of the machine, we have figured out some ways to improve it:

Reference:

  1. 中国古代家具鉴定实例 ISBN: 9787801787224
  2. Combined Effects of UV Exposure Duration and Mechanical Abrasion on Microplastic Fragmentation by Polymer Type Young Kyoung Song, Sang Hee Hong, Mi Jang, Gi Myung Han, Seung Won Jung, and Won Joon Shim Environmental Science & Technology 2017 51 (8), 4368-4376 DOI: 10.1021/acs.est.6b06155