What is ?

From a server to a SBC (Single Board Computer) or the board of your last robotic project it is not rare nor strange the need to keep the system and the container box under control avoiding excessive shocking vibrations, too much heating, adding a reliable digital power on/off system or reset automatically the entire device under certain conditions, as well as the availability of constantly updated parameters like the internal device temperature, the buttons pressed by the user (or state of some external digital input or sensor), the number of hours the system is up e.g. to test the battery durability or battery level.


The Circuit health control Arduino compatible is based on a previous project ( Microcontroller Health Status Controller Board based on AVR328p ) developed to control a SBC server. Then with some modifications to the original circuit based on the Atmel AVR328pAVR328p this board become general purpose, easy customizable and compatible with most of the popular Arduino boards.


Note: the board can be used together with any kind of device as it runs independently but the controlled device.

The board kit is available now on Drobott.com! (don't forget the special Element14 users 10% discount code: W0E49MYQ when buying)


Arduino compatibility features

Not only this board is based on the ATMega328p micro controller IC, the same hosted on the Arduino UNO boards, but the firmware has been developed including the Arduino bootloader. This means that the software can be opened as a normal Arduino sketch with the Arduino IDE (compatibility starts from the version 1.6.x of the IDE).


The Circuit health control is provided natively with a booloader version of the firmware as explained in this article; the software, released as Open Source under the Apache license can be cloned from the github repository and customized following the user needs. As the on-board IC micro controller include the Arduino bootloader the board can be programmed by any user with... another Arduino ! When programming the board firmware a USB powered Arduino UNO is sufficient to power the connected board without any extra power source.



How does it works?

The following video shows the main features of the work on the testing bench.


The components

The system consists of the control board and a set of accessories processing external data, plus the connection with the controlled system if needed.


LCD display


The 16x2 alphanumeric LCD display continuously monitor the system health status by default: temperature, fan percentage speed, up-time in hrs, min, sec. When an alarm condition occur (shock risk or overheating) the display shows the alarm condition. The display is also used to show message feedback to the user interaction.


Temperature sensor


The temperature sensor is based on the IC LM35. The internal calculations for the read values have one decimal C precision while the display only shows integer values. By default the maximum temperature working value without overheating risk is 60C and the minimum temperature value to start the fan (10% of the max speed) is 30C. These values can be set as well, depending on the environment where the board is used and where the sensor is positioned.


Vibration sensor


The vibration sensor sensitivity can be regulated with the trimmer on the board; the regulation should be done to trim the vibration alarm in different conditions depending on the environment where it is installed. The sensor generates a digital signal every received vibration in the sensitivity range.

By default the board firmware react to the first detected vibration generating a shock risk warning on the display. If the  vibrations continue for five seconds the warning become an alarm; then the board can automatically power off the controlled device.


Cooler fan


The cooler fan is controlled as direct feedback by the temperature sensor. Depending on the instant detected temperature with a resolution of about 0.5C the fan speed is updated between 10% and 100% or 0% (stopped when the temperature is under the minimum of the configured range). The fine tuning of the fan response to the temperature depends on the respective position of the sensor and the fan, the size of the environment where the control board is installed and the heating of the system when it is running. The control board can support different fan sizes working at a voltage between 6 and 24V. The Fan power VCC is separated by the control board power.


Note: the fan speed control uses the PWM but works with cheap fan devices without the PWM control line; the shown used model is a 12V fan motor with two power cables only.


User programmable buttons


The two user programmable buttons can be associated to any action of the controller. Typically the two buttons can be used for reset and power on/off where the action on the controlled board is managed by the controller, for example sending a long press for power-on or a press sequence to reach certain results.


Programmable digital output signals


The board provide two digital output signals. These can be used to simulate a button-press or a button-sequence. The two signals are amplified by a couple of  2N22222N2222 acting as switch The signals can also be connected to a 5V coil relais to manage higher currents


Separate power lines


The board is provided with two separate power lines: a 5V to power the board (can be replaced by the Arduino board while programming the micro controller) and a power line for the cooler fan.


Schematics and layout

The two images below shows the circuit schematics and the PCB layout.

Circuit Health Control Schematics.png Circuit Health Control Layout.png

... and the board on the test bench connected to the Arduino ISP programmer




The Circuit health control is provided with a pre-installed firmware including the Arduino bootloader. This makes the original sketch available to any customisation and configuration. The main source is divided in four parts.


1. Application definitions

This includes the parameter constants that can be changed to change the behavior of the board in the different conditions

//! Minimum PWM frequency to start fan
#define FANSPEED_MIN 60
//! Maximum PWM frequency to reach
#define FANSPEED_MAX 255
//! Minimum temperature to start fan
#define TEMP_MIN 30
//! Maximum temperature before overheating error
#define TEMP_MAX 90

//! Loop update frequency
#define UPDATE_FREQ 10
//! Fan full speed test during initialisation
#define FAN_TEST_MS 2500

//! PWM Pin conntrolling the fan speed
#define PWM_FAN 3
//! Analog pin controlling the temperature
#define ANALOG_TEMP 0
//! Reset button pin
#define RESET_BUTTON 2
//! Power on/off button pin
#define POWER_BUTTON 7
//! Vibration sensor pin
//! Server control power simulated button pin
//! Server control reset simulated button pin

#define SERVER_ON  1    ///< Server powered on
#define SERVER_OFF 2    ///< Server powered off
#define SERVER_RESET 3  ///< Server restarting after reset
#define SERVER_POWER_TIME  10000   ///< msec for server going up (power On and Reset)
#define SERVER_POWEROFF_TIME 5000  ///< msec for server goind down
#define SERVER_RESET_TIME 5000    ///< msec for server goind down
#define BUTTON_PRESS_TIMEOUT 5000  ///< msec Timeout when a button remain pressed
#define POWER_ON_DELAY 5000    ///< Power on message delay before starting server
#define ALARM_TIMEOUT 5000     ///< If shock alarm is longer, the system is shutdown
#define FIRST_SHOCK_DELAY 1000    ///< ms before checking the alaram persistance
#define SENSOR_READINGS 500       ///< Number of vibration sensors reading for persistance check
#define PRESS_POWER_FIRST 1    ///< Power button has been pressed
#define PRESS_POWER_SECOND 2   ///< Power button pressed again to confirm (Only for shutdown)
#define PRESS_RESET_FIRST 3    ////< Reset button pressed
#define PRESS_RESET_SECOND 4   ///< Reset button pressed again to confirm
#define BUTTON_PRESS_NONE 0    ///< No buttons has been pressed
#define MIN_FANSPEED_PERC 10   ///< Minimum fan speed PWM percentage to start the fan motor
#define RESET_CYCLE_DURATION 500      ///< ms the simulated server reset button should remain pressed
#define POWERON_CYCLE_DURATION 500    ///< ms the simulated server power button should remain pressed to power off
#define POWEROFF_CYCLE_DURATION 5000  ///< ms the simulated server power button should remain pressed to power off


2. Setup and main loop

Defines the logic of the board in the various conditions

//! Main loop application
void loop(void) {
  // ==============================
  // Check the schock risk status
  // ==============================
  // Shock alarm is checked only when the server is running
  if( (digitalRead(VIBRATION_SENSOR) == HIGH) && (serverStatus != SERVER_OFF) ){
    // Shock alarm - Initialise the count
    // wait a few second(s) to reduce the sensor sensitivity before checking
    // for risk condition persistance. This value is calibrated experimentally
    shockAlarmTimeout = millis();
    int numberShock; // counter of the detected vibrations
    // Exit from the alarm loop only when the alarm ends or the system shutdown process is started.
    boolean alarmSet = true;
    numberShock = 0;
    while(alarmSet) {
      // Read 100 times the sensor.
      for(int j = 0; j < SENSOR_READINGS; j++)  {
        if(digitalRead(VIBRATION_SENSOR) == HIGH)
      } // vibration counter loop
      // If alarm condition persists, update the display
      // to create a blinking effect at the end of every loop
      if(numberShock > 0)
      // Check for alarm timeout
      if( (millis() - shockAlarmTimeout) > ALARM_TIMEOUT)
        alarmSet = false; // just exit from the loop
    } // alarm timeout loop
    // If alarm condition persisted for too much time, the server is
    // powered off, else restore the normal conditions
    if(numberShock > 0) {
      serverStatus = SERVER_OFF;
      buttonPressed = BUTTON_PRESS_NONE;
    else {
      // Restore the normal condition
      buttonPressed = BUTTON_PRESS_NONE;
      serverStatus = SERVER_ON;
  } // end vibration alarm check

  // ==============================
  // Check the state of the buttons
  // ==============================
  // Manage Reset button ------------------------------------------
  if (checkPushReleaseButton(RESET_BUTTON) == LOW) {
      // Reset button
      if( (buttonPressed == PRESS_RESET_FIRST) && (serverStatus == SERVER_RESET) ){
        buttonPressed = PRESS_RESET_SECOND;
      } // Second button accepted
    else {
      if(serverStatus == SERVER_ON) {
        buttonPressed = PRESS_RESET_FIRST;
      } // Server on, can reset
      else {
        buttonPressed = BUTTON_PRESS_NONE;
      } // Server off, reset impossible
    } // First press
  } // Reset button pressed

  // Manage Power on/off button -----------------------------------
  else if(checkPushReleaseButton(POWER_BUTTON) == LOW) {
    if( (buttonPressed == PRESS_POWER_FIRST) && (serverStatus == SERVER_ON) ) {
        buttonPressed = PRESS_POWER_SECOND;
    } // First button already pressed with server on
    else {
      // Power on the server
        buttonPressed = PRESS_POWER_FIRST;
  } // Power Button pressed

  // =========================================
  // Process the current buttons status action
  // =========================================
  switch(buttonPressed) {

    // No action request, check health status and go ahead
    startTimeSec = millis(); // Initialise the timeout counter

    if( (millis() - startTimeSec) > BUTTON_PRESS_TIMEOUT) {
      buttonPressed = BUTTON_PRESS_NONE;
      } // First button timeout
    else {
      if(serverStatus == SERVER_OFF) {
        delay(SERVER_POWER_TIME);  // Wait for server power on and start
        serverStatus = SERVER_ON;
        buttonPressed = BUTTON_PRESS_NONE;
      else {
        // Ask for confirmation to start poweroff sequence
    } // No timeout

    serverStatus = SERVER_OFF;
    buttonPressed = BUTTON_PRESS_NONE;

    if( (millis() - startTimeSec) > BUTTON_PRESS_TIMEOUT) {
      serverStatus = SERVER_ON;
      buttonPressed = BUTTON_PRESS_NONE;
    } // First button timeout
    else {
      serverStatus = SERVER_RESET;

    // Reset sequence
    serverStatus = SERVER_ON;
    buttonPressed = BUTTON_PRESS_NONE;



3 & 4. Management functions and Display functions

This part of the main sketch includes all the functions and methods used to display the different status and the methods to manage the hardware, sensor reading, I/O setting etc.


Software repository

The last updated firmware version can be downloaded from the GitHub repository at the following address: alicemirror/CHC