Skip to content

1 project development

This part will be about the process of making our final project. We will start from the sketch of the final project, passing by the design of the boxes, the electronic production to finish on the final presentation of the project.

I hope you will like my project.🤗

  • At first I wanted to make a bracelet but for aesthetic reasons I decided to make a box because it is more partique.

Follow me to discover how I worked to achieve this result

I. Electronic design

I decided to start with the printed circuit board.

For the printed circuit board of our module we used the kicad software for more details you can consult our week 08 electronic design.

After printing the circuit we got the following results.

II. Application programming

For this week, we decided to develop an application for our final project. For this we used FLUTTERFLOW and flutter framework on VScode sofware, a free online website. For more details, please consult our week14

To get started, we’ll open flutterflow, register and start building our application interface as shown below.

After our registration we are ready to create our project. On the left we have the menu for work organization and profile. To start our project, we’ll click on the right as shown in the image.

We now need to name our project, and we’re ready to continue.

We can choose the colors for our application and then continue

After creating our different pages we can see the interconnections you have made the back-end programming on VScode with the flutter framework.

III. Making BOX

For the box, we modeled it using solidworks software and cut it using a lazer cutting machine. For more details on laser cutting, please see our week03

  • Face up and face down

  • Left and right face

We also made a box to house our power battery. For printing details, please see our week04.

The first one we printed wasn’t very successful, so we printed another one.

IV. Programming

For the programming, we took our inspiration from the code we found on the microcontrollerslab website. This code was initially designed for an ESP32 classic controller, but we’ve adapted it to our needs by adding HTTPS protocol communication.

1. Library Inclusions

#include <Adafruit_MLX90614.h>  // For the infrared thermometer
#include <Arduino.h>            // Base library for Arduino
#include <Adafruit_GFX.h>       // Core graphics library for the display
#include <Adafruit_SSD1306.h>   // Library to drive the SSD1306 display
#include <Fonts/FreeMonoBold18pt7b.h>  // Library for a custom font
#include <WiFi.h>               // Library for WiFi connectivity
#include <AsyncHTTPSRequest_Generic.h> // Library for asynchronous HTTPS requests

These libraries provide the necessary functionalities to control the infrared thermometer, the OLED display, manage WiFi connectivity, and perform HTTPS requests.

2. Initialization of Objects and Variables

Adafruit_SSD1306 display(128, 64);            // Create an object for the OLED display with a resolution of 128x64 pixels
Adafruit_MLX90614 mlx = Adafruit_MLX90614();  // Create an object for the MLX90614 infrared thermometer

float temp = 0;  // Variable to store the measured temperature
int dess = 0;  // Variable for drawing the temperature on the display
bool state = false;  // Indicator for the device state
bool initialise = true;  // Indicator for display initialization
bool temperature = false;  // Indicator for taking the temperature
bool saveTemp = false;  // Indicator for saving the temperature
bool off = false;  // Indicator for the "off" state
char lien[300];  // Character array to store the URL of the HTTPS request

#define ASYNC_HTTPS_REQUEST_GENERIC_VERSION_MIN_TARGET "AsyncHTTPSRequest_Generic v2.2.1"
#define ASYNC_HTTPS_REQUEST_GENERIC_VERSION_MIN 2002001

// Debug level from 0 to 4
#define ASYNC_HTTPS_DEBUG_PORT Serial

#define _ASYNC_TCP_SSL_LOGLEVEL_ 1
#define _ASYNC_HTTPS_LOGLEVEL_ 1

// HTTPS request interval in seconds (300s = 5 minutes to avoid flooding)
#define HTTPS_REQUEST_INTERVAL 60

// Heartbeat interval in seconds
#define HEARTBEAT_INTERVAL 10

#define BUZZER D3  // Define the pin for the buzzer

int status;  // Status variable (not used in the provided code)

// WiFi credentials
const char* ssid = "Annick's Galaxy S10";  // WiFi network name
const char* password = "mfeg1008";  // WiFi network password

AsyncHTTPSRequest request;  // Object for asynchronous HTTPS requests

3. Helper Functions

heartBeatPrint Function

void heartBeatPrint() {
  static int num = 1;

  if (WiFi.status() == WL_CONNECTED)
    Serial.print(F("H"));  // H means connected to WiFi
  else
    Serial.print(F("F"));  // F means not connected to WiFi

  if (num == 80) {
    Serial.println();
    num = 1;
  } else if (num++ % 10 == 0) {
    Serial.print(F(" "));
  }
}

This function prints “H” or “F” to the serial console to indicate whether the device is connected to WiFi or not. The number of characters printed is limited to avoid cluttering the serial output. sendRequest Function

void sendRequest(float temp) {
  static bool requestOpenResult;

  if (request.readyState() == readyStateUnsent || request.readyState() == readyStateDone) {
    Serial.println("J'ouvre");
    sprintf(lien, "https://angouan-box.up.railway.app/saveTest?temperature=%f&glycemie=14&pression_arterielle=19&poules=11&taux_oxygenisation=20", temp);
    Serial.println(lien);

    requestOpenResult = request.open("GET", lien);

    if (requestOpenResult) {
      request.send();
    } else {
      Serial.println(F("Can't send bad request"));
    }
  } else {
    Serial.println(F("Can't send request"));
  }
}

This function sends an HTTPS GET request to the server to save the measured temperature. The URL is formatted to include the current temperature and fixed values for other parameters (blood glucose, blood pressure, pulse, oxygenation rate).

requestCB Function

void requestCB(void *optParm, AsyncHTTPSRequest *request, int readyState) {
  (void) optParm;
  Serial.println("j'ai reçu");
  if (readyState == readyStateDone) {
    AHTTPS_LOGDEBUG0(F("\n**************************************\n"));
    AHTTPS_LOGDEBUG1(F("Response Code = "), request->responseHTTPString());

    if (request->responseHTTPcode() == 200) {
      Serial.println(F("\n**************************************"));
      Serial.println(request->responseText());
      Serial.println(F("**************************************"));
    } else {
      Serial.println(request->responseText());
    }

    request->setDebug(false);
  }
}

This function is called when the state of the HTTPS request changes. It prints the response code and the response text if the request is completed (readyStateDone).

4. ISR (Interrupt Service Routine) Functions

onOff Function

void IRAM_ATTR onOff() {
  state = !state;
  temperature = false;
}

This function toggles the device state (state) and resets the temperature indicator (temperature) when an interrupt is triggered (e.g., by a button).

takeTemp Function

void IRAM_ATTR takeTemp() {
  temperature = !temperature;
}

This function toggles the temperature taking indicator (temperature) when an interrupt is triggered.

urgence Function

void IRAM_ATTR urgence() {
  // Code for emergency handling (not implemented)
}

This function is intended to handle emergency interrupts. The emergency handling code is not implemented in this fragment.

5. Initial Setup

void setup() {
  Serial.begin(115200);
  delay(200);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  request.setDebug(false);
  request.onReadyStateChange(requestCB);

  delay(200);
  pinMode(D0, INPUT);  // Red emergency contact
  pinMode(D1, INPUT);  // Replace on/off
  pinMode(D2, INPUT);  // Take temperature
  pinMode(BUZZER, OUTPUT); // Buzzer for taking temperature
  pinMode(D10, OUTPUT);  // Another output
  attachInterrupt(D0, urgence, RISING);
  attachInterrupt(D1, onOff, RISING);
  attachInterrupt(D2, takeTemp, RISING);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // Initialize the display with I2C address 0x3C
  display.clearDisplay();  // Clear the display buffer
  display.setTextColor(BLACK);  // Set text color to black
  display.display();
  mlx.begin();  // Start the infrared thermometer
}

The setup() function initializes the serial connection, configures WiFi in station mode (WIFI_STA), attempts to connect to the WiFi network, sets up interrupts for various buttons, initializes the OLED display, and initializes the infrared thermometer.

6. Main Loop

void loop() {
  if (state) {
    if (initialise) {
      display.clearDisplay();
      display.setTextColor(WHITE);
      display.display();
      initialise = false;
      tone(BUZZER, 3000, 500);
    }

    digitalWrite(D10, HIGH);
    delay(100);
    digitalWrite(D10, LOW);
    delay(100);

    if (temperature) {
      tone(BUZZER, 5000, 500);
      display.clearDisplay();
      temp = mlx.readObjectTempC();
      char string[10];
      dtostrf(temp, 3, 0, string);
      display.setFont();
      display.setCursor(45, 10);
      display.println("TEMPERATURE");
      display.fillCircle(18, 55, 7, WHITE);
      for (int i = 6; i <= 45; i += 3) {
        display.drawLine(21, i, 22, i, WHITE);
      }
      dess = temp * 0.43;
      display.draw

How the module acts on application data

  • 1 : When the application is open and a shot is taken on the module, the new data can be seen directly on the home page. To see the details of the shot, the user must click on “see more” (voir plus) where it says recent constant shots(prise de constante recentes).

  • 2 : For the moment, our modukle only acts on temperature because it’s the only sensor at our disposal.

  • 3 : And now it’s able to see the temperature taken.

other examples

  • 28°C for this temperature taken

  • 33°C for this temperature taken

  • 32°C for this temperature taken

RESULT

FILES


Last update: November 3, 2024