WM Internship Code
To actually use the Arduino to complete its function, please take a look at the code attached below. The Calibration Code must be used before the Post-Calibration Code since the Calibration Code is used to calibrate the scale so that the Post-Calibration Code can record the mass of the trash in the trashcans.
Note: This code is heavily inspired by and also reuses some methods by Brainy Bits, which you can find here ↗.
Calibration Code
/*
This is the calibration code for the both the load cells connected
to the Arduino. After the Arduino is wired up, run this code in the
Arduino IDE, which can be found at this link: <https://www.arduino.cc/
en/software> This code is important to run, as the load cells need to
calibrated in order to be used.In order to run this program, use the
inbuilt Library Manager (tools > Library Manager) to download the
HX711.h and U8glib.h libraries; they are necessary to run the
programs. Then, copy this code to the Arduino, and then start the
serial monitor at the 9600 band.This code, when "#define DOUT 11" and
"#define CLK 12" is commented out, will give the calibration value
for Load Cell 1 on the schematic. Please note this value down:
"loadcell_1_calibration"; Then uncomment out "#define DOUT 11" and
"#define CLK 12" and comment out "#define DOUT 6" and "#define CLK
5" so that the calibration value for Load Cell 2 on the schematic can
be found. Please also note this value down: "loadcell_2_calibration".
Also, please fully read the comments in this code to understand the
procedure (more procedures are written below).
*/
#include "HX711.h"
// Arduino pin 6 connect to HX711 DOUT --> Loadcell 1 (Part of pair 1)
#define DOUT 6
// Arduino pin 5 connect to HX711 CLK --> Loadcell 1 (Part of pair 1)
#define CLK 5
// Arduino pin 11 connect to HX711 DOUT -> Loadcell 2 (Part of pair 2)
// #define DOUT 11
// Arduino pin 12 connect to HX711 CLK -> Loadcell 2 (Part of pair 2)
// #define CLK 12
HX711 scale(DOUT, CLK); // Init of library
void setup()
{
Serial.begin(9600);
scale.set_scale(); // Start scale
scale.tare(); // Reset scale to zero
}
void loop()
{
double knownWeight = 0.174;
/*
It is important to already have the mass of an object when
calibrating the scale; it has to be in kilograms for this
calibration, I used the mass of an iPhone X without the case,
which has a mass of 174g or .174kg after letting the load cell sit
for about 5 seconds, the known mass was placed on the scale and
then I waited for 5 more seconds to get the calibration value
after this, comment out the current pair of DOUT and CLK values,
and uncomment out the second pair of values repeat the steps of
uploading the program, waiting, placing the known mass, waiting
again, and noting the values found, we are now free to use the
second program.
*/
// get average of 20 scale readings
float current_weight = scale.get_units(20);
// divide the result by a known weight
float scale_factor = (current_weight / knownWeight);
// Print the scale factor to use
Serial.println(scale_factor);
}
Post-Calibration Code
// This is the second Arduino program, which can be used once the
// calibration values are found.
// Please scroll down to the "void tare_scale(void)" method.
#include "U8glib.h"
#include "HX711.h"
volatile boolean TurnDetected;
volatile int Rotary_Flag = 0;
// Rotary Encoder Module connections
#define RotaryCLK 2
pin 2 of Arduino
#define RotaryDT 3
pin 3
#define RotarySW 4
to pin 4
// Rotary encoder CLK pin connected to
// Rotary encoder DT pin connected to
// Rotary encoder Switch pin connected
// once the 2 calibration values
// HX711 Module connections
// CLK of HX711 connected to pin 5 of Arduino -> Load Cell 1
#define CLK_1 5
// DOUT of HX711 connected to pin 6 of Arduino -> Load Cell 1
#define DOUT_1 6
// CLK of HX711 connected to pin 5 of Arduino -> Load Cell 2
#define CLK_2 12
// DOUT of HX711 connected to pin 6 of Arduino -> Load Cell 2
#define DOUT_2 11
int reset_screen_counter = 0;
volatile int current_units = 0;
float unit_conversion;
int decimal_place;
// Init of the HX711 --> Load
HX711 scale_1(DOUT_1, CLK_1);
// Init of the HX711 --> Load
Cell 1 HX711 scale_2(DOUT_2, CLK_2);
// Init of the OLED screen
Cell 2 U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_FAST);
// Interrupt routine runs if Rotation detected from Rotary encoder
void rotarydetect()
{
Rotary_Flag = 1; // Set Rotary flag from 0 to 1
delay(500);
}
// Used to change the measurement units (0=grams, 1=KG,2=pounds)
void change_units()
{
if (current_units == 0)
current_units = 1;
else if (current_units == 1)
current_units = 2;
else if (current_units == 2)
current_units = 0;
}
// Run at Startup and when Resetting with Rotary encoder switch
void startupscreen(void)
{
u8g.setFont(u8g_font_unifont);
u8g.firstPage();
do
{
u8g.drawStr(0, 10, "Clear Scale");
u8g.drawStr(0, 28, "Click to zero...");
} while (u8g.nextPage());
}
// Reset Scale to zero
void tare_scale(void)
{
/*
Here, the calibration values that are found with the other
program are inputted. The "loadcell_1_calibration" is the
calibration value for the load cell (and in turn the hx711)
connected to the pins 5 & 6 on the arduino (load cell 1 on the
schematic, the first value we found). The "loadcell_2_calibration"
is the calibration value for the load cell (and in turn the hx711)
connected to pins 11 & 12 on the arduino (load cell 2 on the
schematic, the second value we found).
*/
long loadcell_1_calibration = 103725;
long loadcell_2_calibration = 110490;
// Calibration Factor obtained from calibration sketch --> Load Cell 1
scale_1.set_scale(loadcell_1_calibration);
// Reset the scale to 0 --> Load Cell 1
scale_1.tare();
// Calibration Factor obtained from calibration sketch --> Load Cell 2
scale_2.set_scale(loadcell_2_calibration);
// Reset the scale to 0 --> Load Cell 2
scale_2.tare();
}
// Start Displaying information on OLED
void start_scale(void)
{
char temp_current_units[15];
String KG = "KG";
String GRAMS = "GRAMS";
String LBS = "POUNDS";
if (current_units == 0)
{
GRAMS.toCharArray(temp_current_units, 15);
unit_conversion = 1000;
decimal_place = 0;
}
else if (current_units == 1)
{
KG.toCharArray(temp_current_units, 15);
unit_conversion = 1;
decimal_place = 3;
}
else
{
LBS.toCharArray(temp_current_units, 15);
unit_conversion = 2.2046226218;
decimal_place = 3;
}
u8g.setFont(u8g_font_unifont);
u8g.firstPage();
do
{
u8g.drawStr(0, 10, temp_current_units);
u8g.setPrintPos(38, 28);
float final_mass;
final_mass = scale_1.get_units(3) +
scale_2.get_units(3);
u8g.print(final_mass * unit_conversion,
decimal_place);
} while (u8g.nextPage());
}
void setup(void)
{
// Set pinmode for Rotary encoder pins
pinMode(RotarySW, INPUT_PULLUP);
pinMode(RotaryCLK, INPUT_PULLUP);
pinMode(RotaryDT, INPUT_PULLUP);
attachInterrupt(0, rotarydetect, RISING);
u8g.setRot180();
u8g.setColorIndex(1);
u8g.setFont(u8g_font_unifont);
String start_count_string = "Starting up....";
char start_count[15]; // Used to String to Char
conversion for (int x = 12; x < 16; x++)
{
start_count_string.toCharArray(start_count, x);
u8g.firstPage();
do
{
u8g.drawStr(0, 10, "ARDUINO SCALE");
u8g.drawStr(0, 28, start_count);
} while (u8g.nextPage());
delay(500); // Delay between dots
}
}
void loop(void)
{
if (!digitalRead(RotarySW))
{
if (reset_screen_counter == 1)
{
tare_scale();
reset_screen_counter = 2;
delay(500);
}
else
{
if (reset_screen_counter == 2)
{
reset_screen_counter = 0;
delay(500);
}
}
}
if (Rotary_Flag == 1)
{
change_units(); // change the measuring units
Rotary_Flag = 0; // reset flag to zero
}
if (reset_screen_counter == 0)
{
startupscreen();
reset_screen_counter = 1; // set to 1 and wait for Rotary
click to zero scale
}
if (reset_screen_counter == 2)
{
start_scale();
}
}