Author Topic: Moteino Bathroom Scale  (Read 361 times)

moallen

  • NewMember
  • *
  • Posts: 12
Moteino Bathroom Scale
« on: January 05, 2020, 10:04:44 AM »
The subject of this project was a Healthometer bathroom scale, Model: HDL826KD-01. It was bought about 5 years ago. Itís a typical $20 digital scale. The circuit board and display appeared to be proprietary. I couldnít find any circuitry/chip documentation. But I didn't plan to use or keep the circuit board and display anyway.

Instead my plan was to disconnect the (4) load sensors from the circuit board and install a Sparkfun load sensor amplifier HX711, Moteino M0, and a Sparkfun SERLCD display in the scale.

I snipped all the load sensor wires where they connected to the circuit board/display. There were 12 load sensor wires plus 2 more for a switch under one of the load sensors. The purpose of the switch was to wake the original circuit board up when someone stepped on the scale.

There was also a switch for pounds or kilograms, which I thought I might use to turn off the 3.7 volt battery power to the Moteno M0. The next phase will include a sleep function that can be awakened by the other switch under the load sensor I mentioned earlier.

The most difficult part of this project was to figure out the color coding used for the load sensor wires. Iím sure none of these off the shelf digital bathroom scales use any sort of standard colors for the wires. In this case, there was an orange, yellow, and brown wire coming out of each load sensor.

Similar load cells available at such places as Sparkfun use red, white, and blue wires. Using my meter, I was able to match my orange to their red, my brown to their blue, and my yellow to their white. I then connected the load cells as per the attached schematic.

Iíve included working code (phase 1) for both the client and server. The Moteino client runs the scale, which transmits a personís weight once per second back to the Moteino server, which is connected to my laptop. The client has print capability for troubleshooting via the Serial1 com port. The server uses the USB com port for printing the received weight.

While the code works, it needs a lot of enhancement. As an example, briefly stepping on the right corner load sensor activates the switch that I use to zero the scale. Thatís not working as smoothly and consistently as I would like.

In the next phase Iíll improve some of those functions, and include a sleep function, so the battery can be left on all the time.

And, of course, fitting all of this inside the scale.

Moteino client (scale) code:

Code: [Select]
#include "HX711.h"
#define calibration_factor 5970.0
#define DOUT  3
#define CLK  2
#define ZER 4
HX711 scale;

#include <SPI.h>
#include <Wire.h>
#include <RH_RF95.h>
#include <RHReliableDatagram.h>

#define DISPLAY_ADDRESS1 0x72

#define SERVER_ADDRESS   1
#define MY_ADDRESS     3

RH_RF95 rf95(A2, 9);

struct dataStruct {
  float value1;
} SensorReadings;

byte sendbuf[sizeof(SensorReadings)] = {0};
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];

RHReliableDatagram rf95_manager(rf95, MY_ADDRESS);

int16_t packetnum = 0; 

void setup()
{
  Serial1.begin(115200);
  if (!rf95_manager.init())
  Serial1.println("init failed");
  rf95.setFrequency(915.0);
  Serial1.println("Ready...");
  rf95.setTxPower(23, false);

  pinMode(ZER, INPUT_PULLUP);
  scale.begin(DOUT, CLK);
  scale.set_scale(calibration_factor);
  scale.tare();
  Wire.begin();
  SensorReadings.value1 = 0;
}

void loop()
{
  Wire.beginTransmission(DISPLAY_ADDRESS1);
  Wire.write('|');
  Wire.write('-');
 
  float weight = scale.get_units();
  Wire.print(weight, 1);
  Wire.print(" lbs");
  Wire.endTransmission();

  int zeroVal = digitalRead(ZER);

  if (zeroVal == LOW) {
    delay(3000);
    scale.set_scale(calibration_factor);
    scale.tare();
   
  }

  SensorReadings.value1 = weight;
  Serial1.println(SensorReadings.value1);

  byte zize = sizeof(SensorReadings);
  memcpy(sendbuf, &SensorReadings, zize);

  Serial1.println("Sending weight...");

  if (rf95_manager.sendtoWait(sendbuf, zize, SERVER_ADDRESS)) {
    uint8_t len = sizeof(buf);
    uint8_t from;   
    if (rf95_manager.recvfromAckTimeout(buf, &len, 2000, &from)) {
      buf[len] = 0;
     
    } else {     
    }
  } else {   
  }
  delay(500);
}

Moteino Servo code:

Code: [Select]
#include <SPI.h>
#include <RH_RF95.h>
#include <RHReliableDatagram.h>

#define SERVER_ADDRESS     1

RH_RF95 rf95(A2, 9);

RHReliableDatagram rf95_manager(rf95, SERVER_ADDRESS);

int16_t packetnum = 0; 

struct dataStruct {
  float tempValue;
} SensorReadings;

uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t data[] = "message received";

#if defined (MOTEINO_M0)
  #define Serial SerialUSB
#endif

int led = 9;

void setup()
{
  pinMode(led, OUTPUT);     
  Serial.begin(115200);
  while (!Serial) ;
  if (!rf95_manager.init())
    Serial.println("init failed");   
  rf95.setFrequency(915.0);
  Serial.println("Ready to receive..."); 
  rf95.setTxPower(23, false);
}

void loop()
{
  delay(1000);

  if (rf95_manager.available())
  {
    uint8_t len = sizeof(buf);
    uint8_t from;
    if (rf95_manager.recvfromAck(buf, &len, &from)) {
      memcpy(&SensorReadings, buf, sizeof(SensorReadings));
      Serial.print("Weight: ");
      Serial.println(round(SensorReadings.tempValue),0);           
    }
    else {
      Serial.println("No data received..."); 
    }
  }
}



TomWS

  • Hero Member
  • *****
  • Posts: 1929
Re: Moteino Bathroom Scale
« Reply #1 on: February 09, 2020, 08:54:26 AM »
Looks like an interesting project!  I'm not sure how I missed this original posting...

In any case, keep us updated on your progress.  I've gotten a couple of load cells to play around with, but haven't come up with a useful project yet.  I'm not sure that weighing myself is at all interesting, however   ::)