element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Sci Fi Your Pi
  • Challenges & Projects
  • Design Challenges
  • Sci Fi Your Pi
  • More
  • Cancel
Sci Fi Your Pi
Blog Meditech: Control panel software update
  • Blog
  • Forum
  • Documents
  • Files
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: balearicdynamics
  • Date Created: 6 Jul 2015 9:41 AM Date Created
  • Views 669 views
  • Likes 4 likes
  • Comments 2 comments
  • doxygen
  • meditech_project
  • mpide
  • github
  • sources_repository
  • sources
  • raspberry-pi
  • chipkit_pi
  • sci_fi_your_pi
  • software_documentation
  • automated_documentation
  • c++
  • git
Related
Recommended

Meditech: Control panel software update

balearicdynamics
balearicdynamics
6 Jul 2015

Introduction

image

This update affects the ChipKit PI software for the control panel; the development lifecycle is part of the entire project but it is organised in a dedicated repository.

A series of general updates has been done for better reachability of the sources and documentation described in the list below:

 

  • http://meditech.balearicdynamics.com application and user manual, project documentation and technical information. The pages are under construction and only the home page is shown.
  • The GitHub repository has been organised in a better way for more readability. The master branch includes the sources updates (v 1.0 build 0023 at the actual date) while the automatically generated documentation (Doxygen) is regularly updated in the gh-pages repository.
  • The documentation is accessible also from the GithHub repository documentation pages for the better understandability. The GitHub documentation is only affected by the source code and algorithms.

 

The same methodology describe above will be adopted for all the software modules of the project.

 

Cooler fan speed control

The cooler fan speed is controlled on the temperature periodically checked by a LM32 temperature sensor positioned to the bottom of the RPI master board. The internal temperature is also shown with continuous updates on the rightmost top corner of the display. The proportional speed is set by a PWM frequency so that the RPM speed respect the spot temperature is almost continuous, following the rules described below:

 

  1. Fan Speed PWM frequency will vary between 35 and 255; lower values than 35 has no effect and the motor is always stopped.
  2. The temperature range is between 38C and 60C.
  3. A temperature under 38C keeps the fan stopped and a temperature over 60C generates a overheating error.

 

Every reading of the temperature maps a proportional updated speed (the corresponding PWM frequency) of the cooler fan. In this way, the entire temperature monitoring and control period is controlled by a single short function

 

void setFanSpeed(float temp) {

  //! The filtered temperature to control the out-of-range values
  float filteredTemp;

  // Check the temperature range
  if (temp < MIN_TEMP)
    filteredTemp = MIN_TEMP;
  else
    if (temp > MAX_TEMP)
      filteredTemp = MAX_TEMP;
      else
        filteredTemp = temp;

  int pwmSpeed = map(temp, MIN_TEMP, MAX_TEMP, MIN_FANSPEED, MAX_FANSPEED);

  SoftPWMServoPWMWrite(FAN_SPEED, pwmSpeed);
}

 

Non-invasive and simple debug logging to the serial

Logging events and program flow states as serial messages is probably one of the most efficient ways to implement fast debugging features in the methods. The problem is finding a method to disable it as simple and fast when the logging should be disabled: simple as changing a #define to #undef in a single include header.

So the DebugStrings.h file has been created, to be included in any source that should use it.

The general architecture of the debug/log header file is almost simple:

 

// #define to enable, #undef to disable
#undef __DEBUG

#ifdef __DEBUG
// Debug - log messages strings

#define DEBG_PREFIX "[DEBUG]"
#define DEBG_LIDOPEN  "LID OPEN"
#define DEBG_LIDCLOSED  "LID CLOSED"
#else
// Empty definitions if disabled
#define DEBG_PREFIX ""
#define DEBG_LIDOPEN  "
#define DEBG_LIDCLOSED  ""
#endif

 

For every log string defined, the corresponding empty definition should be created in the bottom section of the file. In every source where the debug should be - eventually - used a debug() function should be defined. It's up to you how the serial log should be sent, the following is a very simple example.

 

void debug(String msg) {
#ifdef __DEBUG
  Serial1 << DEBG_PREFIX << "> " << msg << endl;
#endif
}

 

The everywhere in the source that it is needed a runtime message sent to the serial, it is sufficient to call the function passing the message as a parameter, e.g.

 

debug("Test message");
debug(DEBG_LIDOPEN);

 

As you see above, it is not mandatory to define all the log strings in the DebugStrings.h file. It is a good solution only because when the serial logging is not needed anymore the memory space occupied by the strings is automatically freed, making the application smaller and faster.

 

Working with interrupts and tasks

There are two ChipKit core features that simplified a lot the management of the program priorities: timers and the tasks. The most important difference is that the scheduled tasks are driven by a general interrupt with an approximated triggering, but can operate on long timing in the order of seconds or more. Timers instead make available to trigger more precise events (milliseconds) along periods not greater than 90 seconds.

The ChipKit control panel application should manage two different class of tasks that in some cases has a reciprocal influence; e.g. if the Meditech panel lid is open all the other functions should stop. So the teperature status and cover lid status are checked with two interrupt Timers while the other low priority events (i.e. the display update) are controlled by tasks.

The other class of tasks that are managed by the micro controller program are the command dialog through the serial, controlled externally by the RPI master. This second groups of events is under the control of the program flow, depending on what action the user has requested to the RPI master interacting with the system so no interrupt is required.

 

The setup() function starts two timer services:

 

  // Set and start the timer for lid status
  attachCoreTimerService(isLidStatusChanged);
  // Set and start the timer for fan cooler speed regulation
  attachCoreTimerService(fanSpeedRegulation);

 

The first timer check for the lid status switch through the callback function isLidStatusChanged() every second while the second task updates the fan speed over the internal temperature every 5 seconds.

 

The control panel LCD display has some areas showing information depending on the state of the system but there are some reserver areas, i.e. the rightmost top corner that show the internal temperature every second (no matter the precise frequency this should occur). The updateDisplay() function is scheduled as a task in the setup() function on startup as shown in the code below.

 

  // Create the display update task.
  // This task updates automatically only the reserved display
  // areas, i.e. the temperature monitor and other information.
  updateDispalyTaskID = createTask(updateDisplay, TASK_UPDATEDISPLAY, TASK_ENABLE, NULL);

 

Applying this strategy the loop() function results very simple and fast:

 

/**
  \brief Main loop method

  The main application loop is interrupted by the lid open status generating
  a high priority alarm. Also the internal temperature is checked periodically
  to set the fan speed to the correct value.\n
  When serial data are present (a command waiting from the PI main) the data are
  parsed as needed.
  */
void loop(void) {
  // Check if the lid is open
  if(lidStatus == LIDCLOSED) {
    // Test only !!!
    int pValue = analogRead(CALIBRATION_POT);  // Read the pot value
    steth.updateDisplay(map(pValue, 0, ANALOGDIVIDER, MINGAIN, MAXGAIN));
    checkSerial();
  }
  else {
    // Show the error message
    lcd.clear();
    message(_LID_OPEN, 5, LCDTOPROW);
  }
}

 

The following video shows the startup sequence and the Stethoscope gain setting, while the task updates the internal temperature on the display. As the lid cover is opened the other timer immediately detects the event showing the alert on the display.

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

  • Sign in to reply

Top Comments

  • DAB
    DAB over 10 years ago +1
    Good start. I like your simple design approach. You can always add the bells and whistles later. DAB
  • balearicdynamics
    balearicdynamics over 10 years ago in reply to DAB

    Thank you DAB, in general I am following a circular approach to the software development, trying to keep a good level of documentation, first for myself. Then when a project is though to be open source it needs a strong documentation support so the better way is update it on-the-way. I have never trusted on those developers that make a post-documentation; soon it is something confused and detached by the effective features. What is missing for now it is just the user guide but this - at least in my vision - should be one of the last things to be done.

     

    Enrico

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • DAB
    DAB over 10 years ago

    Good start.

     

    I like your simple design approach.

    You can always add the bells and whistles later.

     

    DAB

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube