Challenge

Project 2 - Design and develop the web based Temperature control system using Beagle Bone Black.

1. Declare Device Information in Device Tree:

    • Device Tree Source (DTS) File:
      • Open the appropriate DTS file for your BeagleBone Black.
      • Declare device information using the compatible string.
      • Example : -
      • sensor@48 { compatible = "manufacturer,mcp9808"; reg = <0x48>; /* Other properties and configurations */ };

2. Initialize I2C Interface:

    • Device Driver Code:
      • Include necessary headers and dependencies.
      • Use the i2c_register_driver() function to register the driver with the I2C subsystem.
      • Implement the probe() and remove() functions to manage device initialization and cleanup.
    • Example: -
  • static const struct i2c_device_id mcp9808_id[] = {
  •     { "mcp9808", 0 },
  •     { }
  • };
  • MODULE_DEVICE_TABLE(i2c, mcp9808_id);
  • static struct i2c_driver mcp9808_driver = {
  •     .driver = {
  •         .name = "mcp9808",
  •         .owner = THIS_MODULE,
  •     },
  •     .id_table = mcp9808_id,
  •     .probe = mcp9808_probe,
  •     .remove = mcp9808_remove,
  • };
  • module_i2c_driver(mcp9808_driver);
  • 3. Create Device Driver Structure:

    • Device Driver Code:
      • Define a structure with necessary callbacks.
      • Example:
  • static const struct file_operations mcp9808_fops = {
  •     .owner = THIS_MODULE,
  •     .read = mcp9808_read,
  •     /* Other optional functions */
  • };
  • static struct miscdevice mcp9808_misc_device = {
  •     .minor = MISC_DYNAMIC_MINOR,
  •     .name = "mcp9808",
  •     .fops = &mcp9808_fops,
  • };
  • 4. Register Platform Device:

    • Probe Function (mcp9808_probe):
      • In the probe() function, register the platform device under the driver/misc subsystem.
      • Example:
    • static int mcp9808_probe(struct i2c_client *client, const struct i2c_device_id *id) { /* Initialize device and register platform device */ misc_register(&mcp9808_misc_device); /* Other probe operations */ return 0; }
  • 5. Read Temperature Data:

    • Read Function (mcp9808_read):
      • In the read() function, send I2C messages to read temperature data from the sensor and copy it to user space.
      • Example:
    • static ssize_t mcp9808_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { /* Read from sensor and copy to user space */ return count; }

6. Set Up GPIO Interrupt:

  • Device Tree Configuration:
    • Declare GPIO pin and interrupt properties in the DTS file.

Interrupt Handler:

  • Set up the GPIO interrupt handler in the driver code.
  • Example:

static irqreturn_t mcp9808_interrupt(int irq, void *data) {

    /* Handle the interrupt, turn motor on/off based on temperature thresholds */

    return IRQ_HANDLED;

}

7. User Space Application and Web Interface:

  • User Space Application:
    • Write a user space application to read temperature data at regular intervals and store it in a database.
  • Web Interface (HTML and JavaScript):
    • Develop a simple HTML web page.
    • Use JavaScript to retrieve temperature data from the database and plot it as a graph.
      • #include
      • #include
      • #include
      • #include
      • /// Prints out a MySQL error message and exits
      • ///
      • /// This function should be called after a MySQL error has been encountered. This function will then
      • /// notify the user of the error that has occurred, clean up the existing MySQL connection, and then
      • /// exit the program.
      • ///
      • /// @param The MySQL connection to clean up before exiting
      • void error_exit(MYSQL *con)
      • {
      •     fprintf(stderr, "%sn", mysql_error(con));
      •     if (con != NULL)
      •     {
      •         mysql_close(con);
      •     }
      •     exit(1);
      • }
      • int main(int argc, const char *argv[])
      • {
      •     // Initialize a connection to MySQL
      •     MYSQL *con = mysql_init(NULL);
      •     if (con == NULL)
      •     {
      •         error_exit(con);
      •     }
      •     // Connect to MySQL
      •     // Here we pass in:
      •     //  host name => localhost
      •     //  user name => bone
      •     //  password => bone
      •     //  database name => TempDB
      •     if (mysql_real_connect(con, "localhost", "bone", "bone", "TempDB", 0, NULL, 0) == NULL)
      •     {
      •         error_exit(con);
      •     }
      •     // Create the TempMeas database (if it doesn't already exist)
      •     if (mysql_query(con, "CREATE TABLE IF NOT EXISTS TempMeas(MeasTime DATETIME, Temp DOUBLE)"))
      •     {
      •         error_exit(con);
      •     }
      •     // Initialize a MySQL statement
      •     MYSQL_STMT *stmt = mysql_stmt_init(con);
      •     if (stmt == NULL)
      •     {
      •         error_exit(con);
      •     }
      •     // Set out insert query as the MySQL statement
      •     const char *query = "INSERT INTO TempMeas(MeasTime, Temp) VALUES(NOW(), ?)";
      •     if (mysql_stmt_prepare(stmt, query, strlen(query)))
      •     {
      •         error_exit(con);
      •     }
      •     // Create the MySQL bind structure to store the data that we are going to insert
      •     double temp = 0.0;
      •     MYSQL_BIND bind;
      •     memset(&bind, 0, sizeof(bind));
      •     bind.buffer_type = MYSQL_TYPE_DOUBLE;
      •     bind.buffer = (char *)&temp;
      •     bind.buffer_length = sizeof(double);
      •     // Bind the data structure to the MySQL statement
      •     if (mysql_stmt_bind_param(stmt, &bind))
      •     {
      •         error_exit(con);
      •     }
      •     // Insert multiple records into the database,
      •     // with different data each time
      •     for (int i = 0; i < 10; i++)
      •     {
      •         temp = (float)i;
      •         if (mysql_stmt_execute(stmt) != 0)
      •         {
      •             error_exit(con);
      •         }
      •     }
      •     // Close the MySQL connection
      •     mysql_close(con);
      •     return 0;
      • }

Brief Description:

This project focuses on developing a comprehensive embedded system using a BeagleBone Black (BBB) as the target platform. The primary components of the project include a custom device driver for the MCP9808 Temperature Sensor, a user space application for temperature monitoring, and a web interface for control and visualization.

    • Key Learnings and Takeaways:

        1. Embedded Linux Build Process:

          • Building a custom kernel image for the BBB.
          • Configuration of U-Boot, Linux Kernel, and Root File System.
        2. Device Driver Development:

          • Writing a device driver for the MCP9808 Temperature Sensor.
          • Understanding and implementing probe and read functions.
          • Configuring GPIO pins and handling interrupts.
        3. Device Tree Source (DTS) Configuration:

          • Creating a DTS file for configuring GPIO pins and I2C instance.
          • Making the DTS file configurable for different hardware setups.
        4. Kernel Subsystem Understanding:

          • Gain insights into various kernel subsystems, including GPIO, I2C, and Interrupt Handling.
          • Understanding the role of Platform Device Drivers.
        5. User Space Application:

          • Developing a user space application for temperature monitoring.
          • Implementing database interactions using MySQL for data storage.
        6. Web Interface Development:

          • Creating a simple HTML web page for remote monitoring and control.
          • Enabling settable threshold temperatures and real-time graph plotting.
        7. Practical Hardware Connections:

          • Connecting the MCP9808 Temperature Sensor to I2C.
          • Integrating a DC motor with the LN293D Driver IC to GPIO pins.
        8. Remote Monitoring Concept:

          • Learning the concepts of remote monitoring through the internet.
          • Understanding the importance of presenting data in a user-friendly manner.
      • Application in Real World:

        The skills learned in this project are highly applicable in various real-world scenarios:

        1. Industrial IoT (IIoT):

          • Temperature monitoring and control are crucial in industrial processes. The learned concepts can be applied in IIoT systems for efficient process management.
        2. Home Automation:

          • The project lays the foundation for creating smart home systems where temperature control and monitoring play a significant role.
        3. Healthcare:

          • Remote temperature monitoring can be applied in healthcare settings, especially for patients requiring continuous temperature monitoring.
        4. Environmental Monitoring:

          • The skills gained are relevant in building systems for monitoring and controlling environmental parameters in smart cities or rural areas.
        5. Energy Management:

          • Implementing temperature control in energy systems can contribute to efficient energy management in buildings and industrial facilities.
        6. Research and Development:

          • The project's knowledge can be extended for R&D purposes in areas requiring embedded systems with sensor integration and control mechanisms.
    • Important Commands:

      1. Build Custom Kernel Image:

        • make ARCH=arm CROSS_COMPILE= bb.org_defconfig: Configures the kernel for BeagleBone Black.
        • make ARCH=arm CROSS_COMPILE= menuconfig: Opens a menu to configure kernel options.
        • make ARCH=arm CROSS_COMPILE=: Compiles the kernel.
      2. Compile Device Tree Source (DTS) File:

        • dtc -O dtb -o -b 0 -@ : Compiles DTS to Device Tree Blob (DTB) for the BeagleBone.
      3. Copy Files to BeagleBone Black:

        • scp debian@:: Copies files from the development machine to the BeagleBone.

      Header Files:

      1. : Linux kernel module framework.
      2. : Kernel module initialization and cleanup macros.
      3. : I2C bus communication functions and structures.
      4. : Error handling macros.
      5. : Memory allocation and deallocation functions.
      6. : Platform device and driver registration.
      7. : Functions and macros for interrupt handling.
      8. : GPIO subsystem functions and definitions.
      9. and : Device Tree support.
      10. : User-space memory access functions.
      11. : Registration of miscellaneous devices.
      12. : Filesystem-related functions and structures.
      13. : Kernel-related functions and macros.
      14. : Timer-related functions and structures.
      15. : High-resolution timer functions.
      16. : Sysfs-related functions and definitions.
      17. : GPIO consumer functions.
      18. : Kernel object management.
      19. : Character classification functions.
      20. and : Hardware monitoring subsystem.
      21. : Work queue functions.
      22. : Character device registration and management.

      These headers provide necessary functions and structures to develop the MCP9808 Temperature Sensor driver, configure GPIO pins, interact with the I2C subsystem, and implement user space application features. Each header corresponds to a specific kernel subsystem or functionality required for the project.

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.