Program an Arduino board to do something. The examples in the Arduino Projects Book provide good starting points. You may also wish to use this assignment to build on the previous assignment.
Since the last assignment (kinetic sculptures) didn't quite lend itself to my final project, I decided to work on something that would benefit me in the long run this week: a digital scale.
The scale only has a few components: a load cell, an amplifier, a petentiometer, a button, and an LCD screen. The body of the scale is built out of the load cell, two acrylic plates, and two acrylic spacers. The output runs through the amplifier before displaying on a digital screen. To tare and ready the scale, the user has to hit one small button. Before getting to the programming component, though, I had to solder pins and the load cell to the amplifier, as seen below. Honestly, I did a pretty good job with the soldering, pretty proud of that. Soldering that is NOT shown: the button, because I am significantly less proud of that.
Before using the LCD for output, I had to figure out how to, well, use it. A few online tutorials later, and we have the following! The LCD has 16 pins, though we only need 12. We hook the LCD up to the potentiometer, which is set to be a variable resistor, to adjust the contrast of the LCD. Too high or low a voltage, and the text will not be visible.
#include <LiquidCrystal.h>
LiquidCrystal lcd(4, 5, 6, 7, 15, 16);
// start lcd
void setup() {
lcd.begin(16, 2);
}
// display and clear text
void loop() {
lcd.print("This is a test");
delay(3000);
lcd.clear();
}
Before the load cell can be used as a scale, we need to calibrate it. We calibrate by
zeroing the scale, placing an object of known weight on it, and then dividing the measured
weight by its known weight. This gives us a calibration factor that we will multiply all
future measurements by to ensure accuracy.
I chose to use my airpods case as my object of known weight. On another scale, I measured it
to be 50.8 grams. The calibration factor, for which the code is provided below, is roughly
212.5. After assembling the full scale and adding the wooden frame, the calibration factor
became 238. After measuring a few other objects, I can confirm that the weight it returns is
accurate-ish, within about a gram of error. One small source of frustration is the fact that
the load cell has huge fluctuations from measurement to measurement. Even when not weighing
anything, it returns values roughly between -1.0g and 1.0g. This leads to issues with
calibration, as one cannot get a "perfect" calibration factor due to the fluctuations. To
reduce this error, I have the scale return the average of 50 readings instead of a single,
which has helped a bit, though it increases the amount of time it takes to get the reading.
Below, I measured my Apple Pencil (real weight:
20.7g), my airpod case (real weight: 50.8g), and my airpod case with airpods included (real
weight: 61.4g).
#include <Arduino.h>
#include "soc/rtc.h"
#include "HX711.h"
#include "esp32-hal-cpu.h"
#include <LiquidCrystal.h>
// HX711 circuit wiring
const int LOADCELL_DOUT_PIN = 1;
const int LOADCELL_SCK_PIN = 2;
LiquidCrystal lcd(4, 5, 6, 7, 15, 16);
HX711 scale;
void setup() {
Serial.begin(57600);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
lcd.begin(16, 2);
lcd.print("Ok!");
}
void loop() {
if (scale.is_ready()) {
// get scale ready and set calibration factor, 212.5
scale.set_scale(212.5);
lcd.clear();
lcd.print("Ready");
delay(5000);
// tare the scale
scale.tare();
lcd.clear();
lcd.print("Tared, place.");
delay(5000);
lcd.clear();
// take 50 readings and return the average result
lcd.print("reading:");
lcd.print(scale.get_units(50));
delay(5000);
scale.power_down();
}
lcd.clear();
scale.power_up();
}
When we put all of the above together (and throw in a button to start the measurement process), we get the below! This was a lot of fun to make, and I feel I learned a lot in the process. Included below are photos of the scale and the cardboard prototype, a video of the scale in action, the schematic of the circuit, and the design for the three wooden plates that make up the body.
#include <Arduino.h>
#include "soc/rtc.h"
#include "HX711.h"
#include "esp32-hal-cpu.h"
#include <LiquidCrystal.h>
// Set pins for HX711 and button
const int LOADCELL_DOUT_PIN = 1;
const int LOADCELL_SCK_PIN = 2;
const int BUTTON = 42;
// Initialize input states
int button_state = 0;
// Instantiate LCD and HX711
LiquidCrystal lcd(4, 5, 6, 7, 15, 16);
HX711 scale;
void setup() {
Serial.begin(57600);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
lcd.begin(16, 2);
lcd.print("Ok!");
pinMode(BUTTON, INPUT);
}
void loop() {
button_state = digitalRead(BUTTON);
lcd.setCursor(0,0);
lcd.print("Press button to");
lcd.setCursor(0, 1);
lcd.print("use scale.");
if (button_state == HIGH) {
scale.power_up();
if (scale.is_ready()) {
// get scale ready and set calibration factor, 212.5
scale.set_scale(238);
lcd.clear();
// tare the scale
scale.tare();
lcd.setCursor(0,0);
lcd.print("Scale tared,");
lcd.setCursor(0,1);
lcd.print("place item.");
delay(5000);
lcd.clear();
// take 50 readings and return the average result
lcd.setCursor(0,0);
lcd.print("Reading, please");
lcd.setCursor(0, 1);
lcd.print("wait...");
long weight = scale.get_units(50);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Weight:");
lcd.setCursor(0, 1);
lcd.print(weight);
lcd.print("g");
delay(2000);
scale.power_down();
}
}
}