This code is a temperature logging and monitoring system using...

September 1, 2025 at 05:44 PM

#include "mbed.h" #include "MSCFileSystem.h" #include "EthernetInterface.h" #include "TextLCD.h" #include "rtos.h" #define SERVER_PORT 20 #define FSNAME "msc" // Temperature Structure typedef struct { float tempC; float tempF; float timeStamp; float avgC; // average change in celsius per second float avgF; //average change in farenheit per second } Temperature; /******* Defines all Analog/Digital devices connected to microcontroller*******/ MSCFileSystem myUSBPort(FSNAME); DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); TextLCD lcd(p10, p12, p15, p16, p29, p30, TextLCD::LCD20x4); // rs, e, d0-d3 AnalogIn tempSensor(p17); //Temeperature sensor PwmOut Speaker(p21); Mail<Temperature, 16> mail_box; // allocatable queue - very similar to FIFO Timer t; //timer FILE *fp; //temperature logging File bool cont = true, pause = false; //boolean for stopping and pausing application int numOfReadings = 0; //total number of temperatures read float totalC = 0, totalF = 0; //total temp read int TimeToRun = 0, timeInterval = 0; //how long the application runs given by JAVA application TCPSocketConnection client; //client connecting to JAVA app int pauseFlag = 5; /********** This function takes the pointer to mail and shared buffer to calculate and store temperature from sensor *******/ void calcTemp(Temperature *mail, void const *args){ Temperature* myTemp = (Temperature*)args; float holdC, holdF; //conversion to degrees C holdC = myTemp->tempC; holdF = myTemp->tempF; mail->tempC = ((tempSensor*3.3)-0.600)*100.0; myTemp->tempC = ((tempSensor*3.3)-0.600)*100.0; //convert to degrees F mail->tempF = (9.0*mail->tempC)/5.0 + 32.0; myTemp->tempF = (9.0*mail->tempC)/5.0 + 32.0; //storing time mail->timeStamp = t.read(); myTemp->timeStamp = t.read(); //computing average change in temperature printf("%.1f + %.1f - %.1f = ", myTemp->avgF, myTemp->tempF, holdF); mail->avgC = mail->avgC + (mail->tempC - holdC); myTemp->avgC = myTemp->avgC + (myTemp->tempC - holdC); mail->avgF = mail->avgF + (mail->tempF - holdF); myTemp->avgF = myTemp->avgF + (myTemp->tempF - holdF); printf("%.1f\n", myTemp->avgF); numOfReadings++; //increase total number of readings totalC += myTemp->tempC; //increase total temperature read in C totalF += myTemp->tempF; //increase total temperature read in F } void TextLCD(void const *args){ Temperature* myTemp = (Temperature*)args; char buffer[20]; while(cont) { // loop to update LCD interface lcd.cls(); lcd.locate(0,0); lcd.printf("Temperature Logger"); lcd.locate(0,1); lcd.printf(" Time = %.1f", t.read()); lcd.locate(0,2); lcd.printf("C = %.1f F = %.1f", myTemp->tempC, myTemp->tempF); lcd.locate(0,3); lcd.printf("C/s= %.1f F/s= %.1f", (myTemp->avgC/t.read()), (myTemp->avgF/t.read())); Thread::wait(50); // wait 0.5ns to reduce the number of double sent times if (t.read() >= TimeToRun) //break loop if time to end cont = false; } snprintf(buffer, sizeof(buffer), ",#,%.1f,%.1f,%.1f, \n", (float)totalF/numOfReadings, (myTemp->avgF/t.read()), t.read()); //puts final data to application in buffer client.send_all(buffer, sizeof(buffer));//sends final data to application lcd.cls(); /***** Display all final data on LCD*****/ lcd.locate(0,0); lcd.printf("COMPLETE"); lcd.locate(0,1); lcd.printf("AvgC= %.1f", (float)totalC/numOfReadings); lcd.locate(0,2); lcd.printf("AvgF= %.1f", (float)totalF/numOfReadings); lcd.locate(0,3); lcd.printf("C/s= %.1f F/s= %.1f", (myTemp->avgC/t.read()), (myTemp->avgF/t.read())); /***** Play final noise on speaker******/ Speaker.period(1.0/500.0); // 500hz period Speaker =0.01; //50% duty cycle - max volume Thread::wait(1500); // wait 1.5s Speaker=0.0; // turn off audio led1 = 1; led2 = 1; led3 = 1; led4 = 1; cont = false; } //write temp from analalog port 17 to shared buffer args //This is a real-time task and will only execute every given interval from application void readTemp(void const *args){ if (pause == true){ while(1){ if ((int)t.read()%timeInterval == 0 && pause == false){ break; } } } //turn on LED's when reading temp led1 = 1; led2 = 1; led3 = 1; led4 = 1; Temperature *mail = mail_box.alloc(); //allocate mailbox to memory calcTemp(mail, args); mail_box.put(mail); //put it on the mailbox mail_box.free(mail); } // Speaker/LED thread - will play noise and flash LED everytime temp is read void speaker(void const *args) { while(cont) { if(led1 == 1){ //use LED as a flag Speaker.period(1.0/1000.0); // 500hz period Speaker =0.05; //50% duty cycle - max volume Thread::wait(1); // short wait Speaker=0.0; // turn off audio Thread::wait(500); // wait 0.5s led1 = 0; led2 = 0; led3 = 0; led4 = 0; } } } void Pause(void const *args) //will await message from application for pausing/resume { char buffer[5]; while(cont) { client.receive(buffer, sizeof(buffer)); //will wait until info recieved printf("%s\n", buffer); if (strcmp(buffer, "Pause") == 0){ //pauses all except for temp reader (stops timer) t.stop(); pause = true; } else if (strcmp(buffer, "Resum") == 0){ //resumes all threads t.start(); pause = false; } else if (strcmp(buffer, "Stopn") == 0){ // stops all threads cont = false; break; } memset(&buffer, 0, sizeof(buffer)); //clear buffer } } /****** Thread responsible for writing to the USB Flash Drive**********/ void USBWrite(void const *args) { FILE *fp = fopen( "/" FSNAME "/Temperature_Log.txt", "w"); //open file on flash drive if ( fp == NULL ) //if error { error("Could not open file for write\n"); } else printf("File opened successfuly\n"); while(cont){ if (pause == false){ osEvent evt = mail_box.get(); // this will wait until something is put onto the mailbox if (evt.status == osEventMail && pause == false && cont == true) { //if there is mail and application is not paused or stopped Temperature *mail = (Temperature*)evt.value.p; fprintf(fp, "Timestamp(s): | %.1f Temperature(C) = %.1f Average Change = %.1f | ", mail->timeStamp, mail->tempC, (mail->avgC/t.read())); printf("Timestamp: %.1f Temperature(C) = %.1f Average Change = %.1f | ", mail->timeStamp, mail->tempC, (mail->avgC/t.read())); fprintf(fp, "%.1f Temperature(F) = %.1f Average Change = %.1f\r\n", mail->tempF, (mail->avgF/t.read())); printf("Temperature(F) = %.1f Average Change = %.1f\n", mail->tempF, (mail->avgF/t.read())); mail_box.free(mail); } } } fclose(fp); //closes file } int main() { Temperature myTemp; myTemp.avgF = 0; myTemp.avgC = 0; myTemp.tempC = ((tempSensor*3.3)-0.600)*100.0; myTemp.tempF = (9.0*myTemp.tempC)/5.0 + 32.0; led1 = 0; led2 = 0; led3 = 0; led4 = 0; DIR *d; struct dirent *p; char* runtime; char* interval; int n = 0; char buffer[15]; d = opendir("/" FSNAME); /*** Display all files on the flash drive ***/ printf("\nList of files on the flash drive:\n"); if ( d != NULL ) { while ( (p = readdir(d)) != NULL ) { printf(" - %s\n", p->d_name); } } else { error("Could not open directory!"); } EthernetInterface eth; eth.init(); //Use DHCP eth.connect(); printf("\nIP Address is %s\n", eth.getIPAddress()); //print IP of MBED lcd.locate(0,0); lcd.printf("Wait for connection..."); TCPSocketServer server; server.bind(SERVER_PORT); server.listen(); printf("\nWait for new connection...\n"); server.accept(client); //wait and accept new client client.set_blocking(true, 1500); // Set to blocking printf("Connection from: %s\n", client.get_address()); //print JAVA IP on COM port /***** Print Ethernet Info on LCD Interface ****/ lcd.cls(); lcd.locate(0,0); lcd.printf("My IP: %s", eth.getIPAddress()); lcd.locate(0,1); lcd.printf("Wait for info from"); lcd.locate(0,2); lcd.printf("%s", client.get_address()); n = client.receive(buffer, sizeof(buffer)); //will wait until info recieved frin

This code is a temperature logging and monitoring system using an embedded device like an mbed microcontroller. Here's an explanation of what it does:

Overview:

The code sets up a multi-threaded system for measuring temperature using a temperature sensor connected to the mbed microcontroller. It processes and logs temperature data, interfaces with an external USB flash drive for saving logs, communicates with an external application over Ethernet, and displays relevant information on an LCD screen. Here's the main functionality broken down by components:


Functionality:

  1. Temperature Sensor Setup:

    • Reads analog voltage from the temperature sensor (p17) and converts it to temperature values in Celsius (tempC) and Fahrenheit (tempF).
  2. Temperature Logging and Computation:

    • Calculates and logs temperature readings in real-time.
    • Computes the change/average rate of temperature over time for Celsius and Fahrenheit:
      • AvgC = Average change in Celsius per second.
      • AvgF = Average change in Fahrenheit per second.
    • Keeps track of the total number of readings, total temperature, and time elapsed.
  3. User Interaction via LCD:

    • Displays dynamic data (temperature, time elapsed, average rates, etc.) on an LCD screen (TextLCD setup).
    • Includes a final display of average temperature values and rates at the end of execution.
  4. USB Flash Drive Logging:

    • Logs temperature data in real-time to a Temperature_Log.txt file on an external USB flash drive connected to the system.
    • Ensures clean and organized logging with a timestamp, temperature readings, and average rates.
  5. Ethernet Communication:

    • Sets up an Ethernet connection to communicate with an external client (e.g., a Java application).
    • Waits for commands from the client: Pause, Resume, Stopn (stop the application). These commands control the system behavior:
      • Pause: Halts certain functionalities temporarily (keeps temperature reading thread running).
      • Resume: Resumes the paused functionalities.
      • Stopn: Terminates all the threads and operations.
  6. LED and Speaker Notifications:

    • Activates all four LEDs (LED1 to LED4) and produces audio feedback from the connected speaker each time a temperature reading is taken.
    • Turns off the LEDs and sound after completing each cycle.
  7. Multi-Threading:

    • The program leverages multiple threads to handle different tasks simultaneously, including:
      • Reading temperature (readTemp).
      • Logging data to USB (USBWrite).
      • Updating the LCD (TextLCD).
      • Managing speaker/LED notifications (speaker).
      • Responding to Ethernet-based commands (Pause).
  8. Thread Communication via Mailbox:

    • Uses an RTOS-based mailbox (FIFO buffer) to share temperature readings and metadata between threads without conflicts.
  9. Timer Management:

    • Precise timing is handled via an onboard timer to measure elapsed time and ensure consistent intervals between actions.
  10. Finalization:

    • When the defined application runtime ends (or a stop command is received):
      • The system finalizes logging.
      • Displays final average statistics on the LCD.
      • Plays audio and flashes LEDs to signal completion.

Initialization:

  • The main function initializes various components like the USB file system, Ethernet interface, LEDs, LCD, temperature sensor, mailboxes, etc.
  • It also sets up the embedded device as an Ethernet server, waiting for a client to connect and send runtime configuration (such as total runtime and time intervals).

Summary:

In summary, this code implements a sophisticated real-time temperature monitoring and logging solution. It:

  • Measures and logs temperature from a sensor.
  • Provides user feedback on an LCD.
  • Alerts users with LED flashes and sound.
  • Stores organized logs on a USB flash drive.
  • Interfaces with an external application over Ethernet.
  • Uses multi-threading and mailbox communication for efficiency and parallelism.
Generate your own explanations
Download our vscode extension
Read other generated explanations

Built by @thebuilderjr
Sponsored by beam analytics
Read our terms and privacy policy
Forked from openai-quickstart-node