Posts | Comments

Planet Arduino

Archive for the ‘hx711’ Category

In the first part we looked at the HX711 hardware for implementing weigh scales systems.

This part will cover how software interacts with the hardware, requirements for a library and how to write a weigh scale application.

All the code described in this article can be found in my libraries code repository as the MD_HX711 library and examples.

Requirements

The most basic components of weighing machines a weight sensor, processing device and an interface (for example, these could be a load cell/HX711, a microprocessor and a display, respectively). They usually also have a method for taring the weight (eg, a switch). Other advanced features can be built into the device but they are refinements on the basics.

The simplest user interface for the scale is to continuously send to the interface the measured value. For a display output this would be just shown (like bathroom or kitchen scales) and/or it could be output through an external interface such as a serial port. Many industrial weight scales work exactly like this.

Therefore to implement a minimal weighing system we need a software framework, such as an Arduino library, that:

  1. Enables access to all the HX711 features (ie, both channels of data, resetting the device and Channel A gain selection).
  2. Can work in the background so that the application code implementing the weight scale functionality is free from dealing with hardware related operations. Preferably this works by either periodically polling the HX711 or by external interrupt.
  3. Allows the device to be tared and calibrated.
  4. As a minimum provides the readings from the device as raw, tared or calibrated values.

There are many HX711 libraries available and many provide lots of functions above the basics outlined above. However, I could not find one allowed easy access to Channel B or worked using an external interrupt. So I decided that it was time to write my own.

Library Implementation

Reading Device Data

The core of the library is a function used to implement the device communication protocol described in the previous post. The HX711ReadData() code is a straightforward sequential implementation of the CLK/DAT sequencing and timing required by the interface. The function returns the 24-bit DAC number received as a 32-bit integer.

int32_t MD_HX711::HX711ReadData(uint8_t mode)
// read data and set the mode for next read depending on what 
// options are selected in the library
{
  // local variables are faster for pins
  uint8_t clk = _pinClk;
  uint8_t data = _pinDat;

  // data read controls
  int32_t value = 0;
  uint32_t mask = 0x800000L;
    
  do   // Read data bits from the HX711
  {
    digitalWrite(clk, HIGH);

    delayMicroseconds(1);   // T2 typ 1us

    if (digitalRead(data) == HIGH) value |= mask;
    digitalWrite(clk, LOW); 

    delayMicroseconds(1);  // T3 typ 1us
    mask >>= 1;
  } while (mask > 0);

  // Set the mode for the next read (just keep clocking)
  do
  {
    digitalWrite(clk, HIGH);
    delayMicroseconds(1);
    digitalWrite(clk, LOW);
    delayMicroseconds(1);
    mode--;
  } while (mode > 0);

  return(value);
}

Note that the microsecond timing in this function is moot given that digitalWrite() and digitalRead() are quite slow compared to native processor register read/write.

HX711ReadData() is called from readNB() (read non-blocking), which puts the correct library context around the hardware call. This includes:

  • working out which channel we need to ask for in the next iteration.
  • setting the gain for the channel being requested.
  • managing the interrupt context.
  • saving the data received to the correct internal storage register.

The reason that we have a non-blocking read is that this method is designed to be called safely by an ISR for an external interrupt.

void MD_HX711::readNB(void)
// NON-Blocking read the data from the HX711 in an IRQ 
// safe manner.
{
  uint8_t extras = 0;
  int32_t value;

  _inISR = true;

  // set the next read channel
  if (_enableB) _nextReadA = !_nextReadA;

  // now work out how many extra clock cycles send when reading data
  if (!_nextReadA)            extras = 2; // Channel B gain 32
  else if (_mode == GAIN_128) extras = 1; // Channel A gain 128
  else                        extras = 3; // Channel B gain 64

  // do the read
  noInterrupts();
  value = HX711ReadData(extras);
  interrupts();

  // sign extend the returned data
  if (value & 0x800000) value |= 0xff000000;

  // save the data to the right index value
  channel_t ch = (_enableB && _nextReadA) ? CH_B : CH_A;
  _chanData[ch].raw = value;

  // increment the counter
  _readCounter++;

  _inISR = false;
}

The last received data for each channel is stored in library registers and can be retrieved using the getRaw(), getTared() and getCalibrated() methods, depending on what data the application needs.

Device Reset

The HX711 is reset by powering it down using the CLK pin held HIGH then back up again a very small time later.

inline void MD_HX711::powerDown(void)
// Set the CLK to low for at least 60us.
{
  digitalWrite(_pinClk, HIGH);
  delayMicroseconds(64);   // at least 60us HIGH
}

inline void MD_HX711::powerUp(void)
// set the CLK to high
{
  digitalWrite(_pinClk, LOW);
}

This resets the device into a default state, so the library implements a reset() method that does the same and keeps the library and device synchronized.

void MD_HX711::reset(void)
// set defaults and power cycle the hardware
{
  powerDown();
  powerUp();

  // set the library defaults
  enableChannelB(false);
  setGainA(GAIN_128);
  disableISR();
  _nextReadA = true;
  _readCounter = 0;
  for (uint8_t ch = 0; ch < NUM_CHAN; ch++)
  {
    _chanData[ch].raw = 0;
    _chanData[ch].tare = 0;
    _chanData[ch].calib = 0;
    _chanData[ch].range = 0.0;
  }
}

Tare and Calibration

The values returned from the hardware are 24-bit ADC values converting the amplified Wheatstone differential voltage to a number. This number must be calibrated to convert the value to a meaningful reading.

To calibrate the readings we first need to assume the Wheatstone bridge provides a linear response to the changes in weight (ie, there is a simple proportional relationship). This is the blue line in the figure. We know this assumption is not correct (see this article) but it is close enough if we choose the right load cell for the application.

The first part of calibration is to tare the readings with no force on the sensor (autoZeroTare() or setTare() methods). This provides the information to shift the ‘raw’ blue response curve to the green curve (line A0B0 shift to A1B1) by subtracting the tare ADC value. This locks in the zero point for the conversions and returned by the getTared() method.

The next part is to calibrate the actual slope of the conversion line – moving the green curve A1B1 to the red curve A1B2 in the diagram. This is done by applying a known force to the sensor (such as a known mass) and noting the ADC value returned (setCalibration()).

By setting the zero point and one known point, and assuming a linear response in the range of values being measured, the converted value y can be easily computed for any ADC value x using the getCalibrated() method.

Polled or External Interrupt?

The library supports both a polled and an interrupt driven approach to obtaining data from the HX711. Up to four separate HX711 devices on unique external interrupts are supported, using the technique described in this past post.

The enableInterruptMode() method is used by the application to toggle interrupt mode on/off as needed.

Polled Mode

This is the default operating mode for the library.

In polled mode the public read() method is synchronously invoked to wait for and obtain the next value from the hardware. If channel B is enabled the library will alternate reading channels (A, B, A, B, etc). The read() method returns the identifier of the channel last processed and the data is retrieved with getRaw(), getTared() and getCalibrated(), as required.

As the read() method is synchronous (it blocks waiting for the next data to be available read from the hardware) the isReady() method can be used to determine if there is data ready for processing. This allows an application to check before calling read() to avoid unnecessary application delays caused by the library.

Interrupt Mode

In interrupt mode the library will process data received from the HX711 in the background, based on an interrupt generated by the device DAT signal going low.

Interrupt mode requires that the I/O pin connected to the DAT signal supports external interrupts (eg, for an Arduino Uno this would be pins 2 or 3).

The application can monitor the getReadCount() method to determine when new data has been received. In interrupt mode the read() method becomes non-blocking and returns the id of the channel whose data was the last received so that it can be read with getRaw(), getTared() and getCalibrated().

Prototyping Weigh Scales

Once the basic hardware related functions of the library were coded and broadly tested, it was time to prototype a weight scale to complete the weigh scale code.

Hardware

I was testing with a 1kg bar-type load cell, so a small scale was adequate. A 100mm diameter top and a bottom plate were modelled in Fusion360, shown below, and 3D printed in ABS.

The top plate is a solid disc. The bottom is more open to save material and give access to the screws for joining the top plate and load cell. Both plates include a small pad to lift the load cell so that it is cantilevered it between the two plates. Machine screws (M4) connect all the components together.

Additional hardware required for this prototype was:

  • A 2 line by 20 character LCD module. In this instance it used an I2C interface to the processor, but any other size module and interface that works with LiquidCrystal (or clones) library will work.
  • A tact switch to tare and calibrate the scale.

The final configuration is shown in the photo above, along with a few of the objects used to test the scale and my 1kg bag of rice used to for calibration.

Software

As the library does most of the heavy lifting, the application software becomes straighforward.

The software described here is the MD_HX711_WeighScale example from the library.

This example implements a weigh scale that

  • Can be tared and calibrated using a tact single switch. A Single press of the switch sets the tare, double press sets the calibration to 1000g.
  • Tare and calibration settings are stored in EEPROM and loaded at startup.
  • Updates the LCD display with the current weight as soon as a new weight is available.
  • Demonstrates receiving data from the HX711 in either polled or interrupt driven mode, set by a #define at compile time.

Configuration Parameters are loaded at startup. The EEPROM data includes two signature bytes so that the software can detect a ‘first time’ run and initialize the data to sensible defaults. All changes to configuration values are immediately and transparently saved to EEPROM.

The tact switch is managed by the MD_UISwitch library (also described in this previous post). This allows the application to test for either a press/double press in the main loop() and do the necessary for each case.

Taring is done to set the scale ‘zero’ by a simple pressing of the tact switch. This is usually when the sale is empty by could equally be when the scale has a container on it.

Calibration is carried out by putting a known 1000g weight (my not-very-accurate bag of rice) on the scale and double pressing the switch.

This application needs to be non-blocking for the user switch to work properly. In this case it turns out there is minimal difference to the application’s structure between interrupt and polled modes. In polled mode it monitors isReady() before calling read() to read the data; in interrupt mode it checks getReadCount() to know when new data is available.

One wrinkle is that when the weight is zero, ADC noise fluctuation around the zero point causes the scale to display 0.0 and -0.0. To prevent what looks like a flickering minus sign, the application calculates and displays a ‘damped’ weight calculated as

float dampedWeight(float newReading)
// Dampen the fluctuations in readings value and make any small // negative values 0.0
{
  const float PORTION = 0.80;
  static float lastReading = 0.0;

  // dampen
  lastReading += PORTION * (newReading - lastReading);

  // kill small negative values
  if (lastReading < 0.0 && lastReading > -0.1)
    lastReading = 0.0;

  return(lastReading);
}

If a weight is negative by less that the least significant figure (ie between 0.0 and -0.1) then we can display it as zero. This completely eliminates the visual distraction of the ‘flickering’ minus.

Additionally, this function also dampens the changes to the displayed weight by only adding in PORTION (80%) of the change between the current and last reading. This dampens the ADC noise but also has the side effect of a pleasing ‘converging value’ animation on the weighscale display.

If you search for ‘Arduino’ and ‘weighing’ you very quickly come across the HX711 board module and an associated world of strain gauges and load cells.

All this looked interesting with some learning along the way. The result is that I took a dive into the subject and ended up with some new knowledge and ideas for the future.

In this first part I cover the hardware requirements and in the next how to write software to implement a weighing system.

The HX711 ADC

The HX711 is a precision 24-bit Analog to Digital Converter (ADC) designed for weigh scales and industrial control applications. It readily obtainable from all the usual online marketplaces as ready-made modules implementing the standard datasheet circuit.

The IC interfaces directly with a up to two Wheatstone Bridge load cell’s differential outputs and incorporate signal amplifiers.

Channel A differential input can be programmed with a gain of 128 or 64. Channel B has a fixed gain of 32.

Large gains are needed to accommodate the small output signal from the sensor. When a 5V supply is used for the sensor, the gain corresponds to a full-scale differential input voltage of ±20mV with gain 128, ±40mV for 64 and ±80mV for 32.

Load Cells

Load cells come in various shapes and are rated from 0.1kg to over 1000kg full scale. They come in many different types of form factors but the two most common are bar and strain gauge types.

Bar-type Load Cells

Bar type load cells are straight bars with strain gauges attached to the point where it has maximum bending. A variant of straight bar is the S type cell design for tension (pulling) applications.

Each load cell has four strain gauges connected in a Wheatstone Bridge formation. The labeled colors correspond to the color-coding convention coding of load cells. Red, black, green and white wires are connected to the load cell’s strain gauge and yellow is an optional ground or shield wire to lessen EMI.

The direction of the force arrow labels on the load cells must match the direction of resultant force. If the resultant force is straight down (the usual in a weighing application) then the load cells must be installed so with the force arrow labels pointing down.

Strain Gauge Load Cells

Strain gauge load cells are commonly seen on the corners of bathroom scales and similar ‘platform’ type applications. Each load cell is a half Wheatstone bridge, as shown below.

This type of load cell must be combined into a circuit of 2 or 4 gauges to create the full Wheatstone bridge, with each side of the bridge including the strain resistors from two of the strain gauge load cells. The circuit for combining four strain gauges is illustrated below.

A simple way to combine the wiring is to create a Combinator Board. Here the wires from the individual strain gauge cells are joined in a hub arrangement, producing the required Wheatstone Bridge connections. Shown below is the hub connection for a four sensor configuration.

Module Wire Connections

The HX711 module’s A channel interfaces to the load cell through four wires labeled E+ (or RED), E- (BLK), A-(WHT), A+(GRN), and an optional shielding ground SD(YLW) on the circuit board.

The B Channel interfaces to a separate load cell through the E+, E- (common with Channel A) and B+, B- connections on the circuit board.

E+ and E- are the positive voltage and ground connections to load cell; the A+/A-, B+/B- the differential outputs from the load cell.

The module is connected to the processor’s power supply (Vcc and GND) and 2 additional processor digital input pins to the module’s DAT (or DT) and CLK (or SCK). These digital pins are used to manage the limited configuration options available and read the data from the HX711.

Hardware Control

Sampling Rate

The HX711 can sample at 10 samples per second (SPS or Hz) or 80Hz, set by the RATE pin on the IC.

Some module boards have a jumper on the reverse side of the board to set the rate, as shown below. Connecting RATE to 1 (Vcc) sets 80Hz and 0 (GND) is 10Hz.

Data Read and Gain Control

CLK is set by the processor, DAT is read by the processor. These two
digital signals make up the serial interface to the HX711.

CLK should be kept LOW by the processor unless clocking during a read cycle.

The data is read as 24 bits clocked out, one bit per clock cycle, from the HX711. Additional clock transitions (+1 to +3) are used to set the mode for the next read cycle according to the handshaking sequence below.

  • When an ADC reading is not available, DAT is set HIGH by the HX711. CLK is held LOW by the processor.
  • When DAT goes to LOW, the next ADC conversion can be read by the processor.
  • The processor sends 25 to 27 positive (transition LOW to HIGH) CLK pulses to shift the data out through DAT one bit per clock pulse, starting with the most significant bit (MSB), until all 24 data bits are shifted out.
  • The HX711 will then hold DAT HIGH for the remainder of the clock pulses.
  • Channel and Gain selection for the next read is controlled by the number of additional CLK pulses (+1 to +3) send to the HX711, for a total of 25 to 27 clock pulses as shown in the table below.
Clock PulsesInput ChannelGain
25A128
26B32
27A64

Fewer than 25 and more than 27 clock pulses in one communication cycle will cause a serial communication error requiring a HX711 reset.

Reset and Power Down Sequence

When power is first applied, the power-on circuitry will reset the IC.

The CLK output from the processor is also used to reset the HX711 IC.

When CLK is

  • LOW, the HX711 is in normal working mode.
  • changed from LOW to HIGH and stays HIGH for longer than 60μs, the HX711 is powered down. It remains in this state while the signal remains high.
  • changed from HIGH to LOW, the HX711 resets and restarts normal working mode.

Following a reset the hardware defaults to Channel A input, gain 128.


In Part 2 we’ll look at the software for this module and how to use the hardware/software to implement a weigh scale system.

If you search for ‘Arduino’ and ‘weighing’ you very quickly come across the HX711 board module and an associated world of strain gauges and load cells.

All this looked interesting with some learning along the way. The result is that I took a dive into the subject and ended up with some new knowledge and ideas for the future.

In this first part I cover the hardware requirements and in the next how to write software to implement a weighing system.

The HX711 ADC

The HX711 is a precision 24-bit Analog to Digital Converter (ADC) designed for weigh scales and industrial control applications. It readily obtainable from all the usual online marketplaces as ready-made modules implementing the standard datasheet circuit.

The IC interfaces directly with a up to two Wheatstone Bridge load cell’s differential outputs and incorporate signal amplifiers.

Channel A differential input can be programmed with a gain of 128 or 64. Channel B has a fixed gain of 32.

Large gains are needed to accommodate the small output signal from the sensor. When a 5V supply is used for the sensor, the gain corresponds to a full-scale differential input voltage of ±20mV with gain 128, ±40mV for 64 and ±80mV for 32.

Load Cells

Load cells come in various shapes and are rated from 0.1kg to over 1000kg full scale. They come in many different types of form factors but the two most common are bar and strain gauge types.

Bar-type Load Cells

Bar type load cells are straight bars with strain gauges attached to the point where it has maximum bending. A variant of straight bar is the S type cell design for tension (pulling) applications.

Each load cell has four strain gauges connected in a Wheatstone Bridge formation. The labeled colors correspond to the color-coding convention coding of load cells. Red, black, green and white wires are connected to the load cell’s strain gauge and yellow is an optional ground or shield wire to lessen EMI.

The direction of the force arrow labels on the load cells must match the direction of resultant force. If the resultant force is straight down (the usual in a weighing application) then the load cells must be installed so with the force arrow labels pointing down.

Strain Gauge Load Cells

Strain gauge load cells are commonly seen on the corners of bathroom scales and similar ‘platform’ type applications. Each load cell is a half Wheatstone bridge, as shown below.

This type of load cell must be combined into a circuit of 2 or 4 gauges to create the full Wheatstone bridge, with each side of the bridge including the strain resistors from two of the strain gauge load cells. The circuit for combining four strain gauges is illustrated below.

A simple way to combine the wiring is to create a Combinator Board. Here the wires from the individual strain gauge cells are joined in a hub arrangement, producing the required Wheatstone Bridge connections. Shown below is the hub connection for a four sensor configuration.

Module Wire Connections

The HX711 module’s A channel interfaces to the load cell through four wires labeled E+ (or RED), E- (BLK), A-(WHT), A+(GRN), and an optional shielding ground SD(YLW) on the circuit board.

The B Channel interfaces to a separate load cell through the E+, E- (common with Channel A) and B+, B- connections on the circuit board.

E+ and E- are the positive voltage and ground connections to load cell; the A+/A-, B+/B- the differential outputs from the load cell.

The module is connected to the processor’s power supply (Vcc and GND) and 2 additional processor digital input pins to the module’s DAT (or DT) and CLK (or SCK). These digital pins are used to manage the limited configuration options available and read the data from the HX711.

Hardware Control

Sampling Rate

The HX711 can sample at 10 samples per second (SPS or Hz) or 80Hz, set by the RATE pin on the IC.

Some module boards have a jumper on the reverse side of the board to set the rate, as shown below. Connecting RATE to 1 (Vcc) sets 80Hz and 0 (GND) is 10Hz.

Data Read and Gain Control

CLK is set by the processor, DAT is read by the processor. These two
digital signals make up the serial interface to the HX711.

CLK should be kept LOW by the processor unless clocking during a read cycle.

The data is read as 24 bits clocked out, one bit per clock cycle, from the HX711. Additional clock transitions (+1 to +3) are used to set the mode for the next read cycle according to the handshaking sequence below.

  • When an ADC reading is not available, DAT is set HIGH by the HX711. CLK is held LOW by the processor.
  • When DAT goes to LOW, the next ADC conversion can be read by the processor.
  • The processor sends 25 to 27 positive (transition LOW to HIGH) CLK pulses to shift the data out through DAT one bit per clock pulse, starting with the most significant bit (MSB), until all 24 data bits are shifted out.
  • The HX711 will then hold DAT HIGH for the remainder of the clock pulses.
  • Channel and Gain selection for the next read is controlled by the number of additional CLK pulses (+1 to +3) send to the HX711, for a total of 25 to 27 clock pulses as shown in the table below.
Clock PulsesInput ChannelGain
25A128
26B32
27A64

Fewer than 25 and more than 27 clock pulses in one communication cycle will cause a serial communication error requiring a HX711 reset.

Reset and Power Down Sequence

When power is first applied, the power-on circuitry will reset the IC.

The CLK output from the processor is also used to reset the HX711 IC.

When CLK is

  • LOW, the HX711 is in normal working mode.
  • changed from LOW to HIGH and stays HIGH for longer than 60μs, the HX711 is powered down. It remains in this state while the signal remains high.
  • changed from HIGH to LOW, the HX711 resets and restarts normal working mode.

Following a reset the hardware defaults to Channel A input, gain 128.


In Part 2 we’ll look at the software for this module and how to use the hardware/software to implement a weigh scale system.

If you’re into amateur rocketry, you pretty quickly outgrow the dinky little Estes motors that they sell in the toy stores. Many hobbyists move on to building their own homebrew solid rocket motors and experimenting with propellant mixtures, but it’s difficult to know if you’re on the right track unless you have a way to quantify the thrust you’re getting. [ElementalMaker] decided he’d finally hit the point where he needed to put together a low-cost test stand for his motors, and luckily for us decided to document the process and the results.

The heart of the stand is a common load cell (the sort of thing you’d find in a digital scale) coupled with a HX711 amplifier board mounted between two plates, with a small section of vertical PVC pipe attached to the topmost plate to serve as a motor mount. This configuration is capable of measuring up to 10 kilograms with an 80Hz sample rate, which is critically important at this type of rocket motors only burn for a few seconds to begin with. The sensor produces hundreds of data points during the short duration of the build, which is perfect for graphing the motor’s thrust curve over time.

Given such a small window in which to make measurements, [ElementalMaker] didn’t want to leave anything to chance. So rather than manually igniting the motor and triggering the data collection, the stand’s onboard Arduino does both automatically. Pressing the red button on the stand starts a countdown procedure complete with flashing LED, after which a relay is used to energize a nichrome wire “electronic match” stuck inside the motor.

In the video after the break you can see that [ElementalMaker] initially had some trouble getting the Arduino to fire off the igniter, and eventually tracked the issue down to an overabundance of current that was blowing the nichrome wire too fast. Swapping out the big lead acid battery he was originally using with a simple 9V battery solved the problem, and afterwards his first test burns on the stand were complete successes.

If model rockets are your kind of thing, we’ve got plenty of content here to keep you busy. In the past we’ve covered building your own solid rocket motors as well as the electronic igniters to fire them off, and even a wireless test stand that lets you get a bit farther from the action at T-0.

[Thanks to Baldpower for the tip.]

If you’re into amateur rocketry, you pretty quickly outgrow the dinky little Estes motors that they sell in the toy stores. Many hobbyists move on to building their own homebrew solid rocket motors and experimenting with propellant mixtures, but it’s difficult to know if you’re on the right track unless you have a way to quantify the thrust you’re getting. [ElementalMaker] decided he’d finally hit the point where he needed to put together a low-cost test stand for his motors, and luckily for us decided to document the process and the results.

The heart of the stand is a common load cell (the sort of thing you’d find in a digital scale) coupled with a HX711 amplifier board mounted between two plates, with a small section of vertical PVC pipe attached to the topmost plate to serve as a motor mount. This configuration is capable of measuring up to 10 kilograms with an 80Hz sample rate, which is critically important at this type of rocket motors only burn for a few seconds to begin with. The sensor produces hundreds of data points during the short duration of the build, which is perfect for graphing the motor’s thrust curve over time.

Given such a small window in which to make measurements, [ElementalMaker] didn’t want to leave anything to chance. So rather than manually igniting the motor and triggering the data collection, the stand’s onboard Arduino does both automatically. Pressing the red button on the stand starts a countdown procedure complete with flashing LED, after which a relay is used to energize a nichrome wire “electronic match” stuck inside the motor.

In the video after the break you can see that [ElementalMaker] initially had some trouble getting the Arduino to fire off the igniter, and eventually tracked the issue down to an overabundance of current that was blowing the nichrome wire too fast. Swapping out the big lead acid battery he was originally using with a simple 9V battery solved the problem, and afterwards his first test burns on the stand were complete successes.

If model rockets are your kind of thing, we’ve got plenty of content here to keep you busy. In the past we’ve covered building your own solid rocket motors as well as the electronic igniters to fire them off, and even a wireless test stand that lets you get a bit farther from the action at T-0.

[Thanks to Baldpower for the tip.]

CPAP (Continuous Positive Airway Pressure) machines can be life-changing for people with sleep apnea. [Scott Clandinin] benefits from his CPAP machine and devised a way to improve his quality of life even further with a non-destructive modification to monitor his machine’s humidifier.

With a CPAP machine, all air the wearer breathes is air that has gone through the machine. [Scott]’s CPAP machine has a small water reservoir which is heated to humidify the air before it goes to the wearer. However, depending on conditions the water reservoir may run dry during use, leading to the user waking up dried out and uncomfortable.

To solve this in a non-invasive way that required no modifications to the machine itself, [Scott] created a two-part device. The first part is a platform upon which the CPAP machine rests. A load cell interfaced to an HX711 Load Cell Amplifier allows an Arduino Nano to measure the mass of the CPAP machine plus the integrated water reservoir. By taking regular measurements, the Arduino can detect when the reservoir is about to run dry and sound an alarm. Getting one’s sleep interrupted by an alarm isn’t a pleasant way to wake up, but it’s much more pleasant than waking up dried out and uncomfortable from breathing hot, dry air for a while.

The second part of the device is a simple button interfaced to a hanger for the mask itself. While the mask is hung up, the system is idle. When the mask is removed from the hook, the system takes measurements and goes to work. This makes activation hassle-free, not to mention also avoids spurious alarms while the user removes and fills the water reservoir.

Non-invasive modifications to medical or other health-related devices is common, and a perfect example of nondestructive interfacing is the Eyedriveomatic which won the 2015 Hackaday Prize. Also, the HX711 Load Cell Amplifier has an Arduino library that was used in this bathroom scale refurb project.


Filed under: Arduino Hacks, Medical hacks, The Hackaday Prize

SmartLitterBox

How can you not be interested in a project that uses load cells, Bluetooth, a Raspberry Pi, and Twitter. Even for those of our readers without a cat, [Scott's] tweeting litter box is worth the read.

Each aspect of this project can be re-purposed for almost any application. The inexpensive load cells, which available from eBay and other retailers, is used to sense when a cat is inside the litter box. Typically sensors like the load cell (that contain a strain gauge) this use a Wheatstone bridge, which is very important for maximizing the sensitivity of resistive sensor. The output then goes to a HX711, which is an ADC specifically built for load cells. A simple alternative would be using an instrumentation amplifier and the built-in ADC of the Arduino. Now, the magic happens. The weight reading is transmitted via an HC-06 Bluetooth module to a Raspberry Pi. Using a simple Perl script, the excreted weight, duration, and the cat’s resulting body weight is then tweeted!

Very nice work! This is a well thought out project that we could see being expanded to recognize the difference between multiple cats (or any other animal that goes inside).


Filed under: Arduino Hacks, Raspberry Pi, wireless hacks


  • Newsletter

    Sign up for the PlanetArduino Newsletter, which delivers the most popular articles via e-mail to your inbox every week. Just fill in the information below and submit.

  • Like Us on Facebook