# HX711 ADC interfacing with PIC16F887A

#### PasanJay

Joined Mar 19, 2021
9
Hello guy, I'm trying to interface hx711 adc with pi16f877a.. I've found the reference C program in the datasheet for hx711.. from that i was able to get raw readings from the hx711, i am using mikroC complier. my question is how can i get this readings to represent a weight.. is there any formula..? and i guess the initial raw reading under no load is the OFFSET value which you subtract from next readings to balance the zero position.. but when i do that the readings fluctuate here and there and will not zero the readings.. but when i connect the same setup to arduino.. readings are normal and most importantly the no load value stays at zero without fluctuating... what am i missing?

C:
#define LOW  0
#define HIGH 1

#define INPUT  1
#define OUTPUT 0

sbit HX711_SCLK at RB5_bit;
sbit HX711_DOUT at RB4_bit;

sbit HX711_SCLK_Direction at TRISB5_bit;
sbit HX711_DOUT_Direction at TRISB4_bit;

sbit LCD_RS at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;

sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;

char txt[10];
float offset = 0;
float gram = 0;
float val1;
float val2;
int k;

unsigned long count = 0;
unsigned char i; //, highest = 0, higher = 0, hi = 0, lo = 0;

HX711_DOUT_Direction = OUTPUT;
HX711_SCLK_Direction = OUTPUT;

HX711_DOUT = 1;
HX711_SCLK = 0;

HX711_DOUT_Direction = INPUT;

while(HX711_DOUT);

for(i = 0; i < 24; i++) { // gain 128
HX711_SCLK = 1;
count <<= 1;
HX711_SCLK = 0;

if(HX711_DOUT)count++;
}

HX711_SCLK = 1;
count ^= 0x800000;
HX711_SCLK = 0;

return(count);
}
double sum = 0;
for (k = 0; k < 10; k++) {
}
sum = sum /10;
return sum;
}
void main(void) {

LCD_Init();
LCD_Cmd(_LCD_CURSOR_OFF);
LCD_Cmd(_LCD_CLEAR);

while (1) {
gram = val1;
} else {
gram = val2;

}//////////////////////////////////////////////////////////////////////////////
floatToStr_FixLen(gram, txt,6);
LCD_Out(1,4,txt);
//gram value is fluctuating
}

}

#### ericgibbs

Joined Jan 29, 2010
16,031
hi PJ,
This is an Arduino sketch similar to C++, it may help, you need to calibrate the scale.
E
C++:
#include "HX711.h"

HX711 scale;

void setup() {
Serial.begin(38400);
Serial.println("HX711 80 sam/sec Demo");

Serial.println("Initializing the scale");
// parameter "gain" is ommited; the default value 128 is used by the library
// HX711.DOUT    - pin #A1
// HX711.PD_SCK    - pin #A0

scale.begin(A1, A0);
Serial.println("Uncalibrated Data");
Serial.print("Raw Data: \t\t");

Serial.println(scale.get_value(5));        // print the average of 5 readings from the ADC minus the tare weight (not set yet)

Serial.println(scale.get_units(5), 1);    // print the average of 5 readings from the ADC minus tare weight (not set) divided
// by the SCALE parameter (not set yet)

// 2280 this value is obtained by calibrating the scale with known weights; see the README for details
scale.set_scale(98.f);    // mytest 30kG L/C resolution 1gm

// reset the scale to 0////
scale.tare();

Serial.println("After setting up the scale:");

Serial.print("get value: \t\t");
// print the average of 85 readings from the ADC minus the tare weight, set with tare()
Serial.println(scale.get_value(8));

Serial.print("get units: \t\t");

// print the average of 8 readings from the ADC minus tare weight, divided
// by the SCALE parameter set with set_scale
Serial.println(scale.get_units(8), 1);

}

void loop() {
scale.begin(A1, A0);
Serial.print("A=:");
Serial.print(scale.get_units(), 1);
Serial.print(" Avg=");
Serial.println(scale.get_units(10), 0);

// scale.begin(A1, A0);
// Serial.print("  B=:");
// Serial.println(scale.get_units(), 1);

// Serial.print("Bvg=");
// Serial.println(scale.get_units(8), 1);

// scale.power_down();                    // put the ADC in sleep mode
// delay(5000);
// scale.power_up();
}

#### click_here

Joined Sep 22, 2020
545
The quickest/easiest way would be to compare your readings to known weights

#### PasanJay

Joined Mar 19, 2021
9
i guess calibration wont be an issue... issue is the values are fluctuating under no load i want the value to be zero under no load.. i guess it is called zero balancing(correct me if i'm wrong)

#### ericgibbs

Joined Jan 29, 2010
16,031
hi,
Thats where the Tare correction is applied.
// reset the scale to 0////
scale.tare();

Get 80 raw readings, then when you want to zero the weight, subtract that Tare weight.
Sum of say 80 raw readings divided by 80=== the required subtract weight. [save in EEPROM]

E

#### PasanJay

Joined Mar 19, 2021
9
hello eric, im using MikroC compiler and PIC16f877A mcu... it don't have the hx711 library

#### ericgibbs

Joined Jan 29, 2010
16,031
hi,
The last work I did on a PIC was 5 years ago, 18F4520, using Oshonsoft Basic. [ attached a file]

The Basic and the image I prepared may help.
E

#### Attachments

• 2.5 KB Views: 32
• 46.2 KB Views: 27

#### PasanJay

Joined Mar 19, 2021
9
thank you very much eric... i'll look into it... is there an offset in the hx711 module itself (without connecting a load cell)?

#### ericgibbs

Joined Jan 29, 2010
16,031
hi,

They will drift around.You can make a dummy bridge for testing, by connecting two 1k's in series across the Vext pads, connect the junction of the two resistors to one of the input pins,

Using a 2k 20 turn trim pot, connect the two outer pins across the Vext pins [ in parallel with the two 1ks.
Then connect the wiper of the trim pot to the other input pin.

Use a DVM and adjust the pot so the voltage across the two input pins is zero.

Then by turning the trim pot you can simulate load cell voltages.
It is a very coarse way of making a resistor bridge.!

Ask if you need a sketch.

E
This image is like the type I used.
A L/C is much better,

#### Attachments

• 4.7 KB Views: 9
Last edited:

#### PasanJay

Joined Mar 19, 2021
9
thank you for your reply.. i tried several times and came up to some extend... ok this is the new issue...when there is no load applied on the LC, the raw readings are between 836900 - 837000. then i took 80 readings and got the average reading.. this new average reading is my offset? am i right? so if i substract the new offset value from the next raw reading, i should get a 0 (zero)? but instead i am getting 4.2964... something... how to get this thing to start reading values from zero?

C:
 offset = read_average(); // setting offset by reading the average of 80 readings
while (1) {

weight = (Read_HX711()- offset); // subtracting the offset from new raw readings
if (weight<0){                    // sometimes the readings goes negative.. so assigned all negatives values as zero
weight = 0;
Lcd_Out(1,3,"               ");}

floatToStr_FixLen(weight, txt,7);
LCD_Out(1,4,txt);
delay_ms(100);
}

#### Ian Rogers

Joined Dec 12, 2012
1,015
836900 seems awfully high for a Zero...

The datasheet has sample code in C.. ( appologies... Shows how to call from C, the asm is easy to follow though)
Microsoft Word - hx71_english.doc (sparkfun.com)

Last edited:

#### ericgibbs

Joined Jan 29, 2010
16,031
hi PJ,
Your Offset [Tare] is typical of what is used for setting the Zero, by subtracting the Offset count.

I am of the same opinion as Ian. those individual values are very High.???

E

#### Ian Rogers

Joined Dec 12, 2012
1,015
One thing I did notice.... 24 bit resolution.... If you just read 16 bit it will still be very accurate and a lot more stable..

#### PasanJay

Joined Mar 19, 2021
9
thank you Ian and Eric.... the individual values are raw readings straight from the hx711... and i took the average by utilizing a for loop.. as they done in hx711 master arduino library.. anyway i have the same feeling that the 24 resolution make things more unstable... i'll try 16bit.. when we using hx711 with arduino, what is the default resolution?

#### ericgibbs

Joined Jan 29, 2010
16,031
Hi PJ,
I have finally located all the bits for that earlier HX711 project, using an Arduino, with a 2kG load cell.
If you get stuck let me know and I will rebuild the project.

Which load cell are you using.?
E

#### PasanJay

Joined Mar 19, 2021
9
Thank you eric.. thats very kind of you... i did several projects using hx711 with Atmega238p... but i had never encountered this issue.. when using tare function in arduino(in hx711 library) , the scale reads would easily starts from zero... in my MikroC I'm using the gain as 128... what is the default gain in hx711 library in arduino...?

#### ericgibbs

Joined Jan 29, 2010
16,031
hi PJ<
I have set it up, bit of a birds nest, but it shows the performance.
Used two HX711, with and without JP2 .
These are the results with this program.
E
C++:
// 010521_ PJ AAC  Test EG57
// 5kG L/C Arduino Nano
// Test weight 2kG Calibrated Mass
#include <HX711.h>

HX711 scale;

void setup() {
Serial.begin(38400);
Serial.println("HX711 PJ Demo");

Serial.println("Initializing the scale");
// parameter "gain" is ommited; the default value 128 is used by the library
// HX711.DOUT    - pin #A1
// HX711.PD_SCK    - pin #A0
scale.begin(A1, A0);

Serial.println("Before setting up the scale:");

Serial.print("get value: \t\t");
Serial.println(scale.get_value(5));        // print the average of 5 readings from the ADC minus the tare weight (not set yet)

Serial.print("get units: \t\t");
Serial.println(scale.get_units(5), 1);    // print the average of 5 readings from the ADC minus tare weight (not set) divided
// by the SCALE parameter (not set yet)
// this value is obtained by calibrating the scale with known weights;
scale.set_scale(90.f);
scale.tare();// reset the scale to 0

Serial.println("After setting up the scale:");

Serial.print("get value: \t\t");
Serial.println(scale.get_value(5));        // print the average of 5 readings from the ADC minus the tare weight, set with tare()

Serial.print("get units: \t\t");
Serial.println(scale.get_units(5), 1);        // print the average of 5 readings from the ADC minus tare weight, divided
// by the SCALE parameter set with set_scale

}

void loop() {
Serial.print("A= ");
Serial.print(scale.get_units(), 1);
Serial.print("  Avg= ");
Serial.println(scale.get_units(10), 1);

// scale.power_down();                    // put the ADC in sleep mode
delay(1000);
// scale.power_up();
}

#### Attachments

• 27.9 KB Views: 20
• 29.4 KB Views: 15

#### ericgibbs

Joined Jan 29, 2010
16,031
hi,
Ref the Gain,
Image clips from program and lib.
E

A clip ref the bits used values ie: 16Bit Hi & Lo WORD

#### Attachments

• 12.2 KB Views: 18
• 6.4 KB Views: 16
• 9.6 KB Views: 18
Last edited:

#### Ian Rogers

Joined Dec 12, 2012
1,015
thank you Ian and Eric.... the individual values are raw readings straight from the hx711... and i took the average by utilizing a for loop.. as they done in hx711 master arduino library.. anyway i have the same feeling that the 24 resolution make things more unstable... i'll try 16bit.. when we using hx711 with arduino, what is the default resolution?
24 bits... But read it the same way and divide the reading by 256 ( >>= 8 )... Tada 16 bits..