HX711 conversion period and program structure

Thread Starter

moomo

Joined Jul 14, 2017
41
I am wanting to write some arduino code that interprets the output of a HX711 ADC (This will be the output voltage from a Wheatstone bridge with strain gauges in 2's compliment form). I know that there are libraries available but I want to have a crack at it myself so I know exactly how it works and as the project matures I can be in a better position to develop on it.

How much time do you have to give between conversion periods so that the HX711 applies the correct gain and doesn't apply the wrong gain and start the new conversion period sooner than was wanted? I am looking at the data sheet but can't see where this information is given.

Here is what I am thinking the basic logic of the program would be (assuming that I am wanting a gain of 128 on Input channel A):

1. Apply 2.7~5.5V to DVDD, VSUP, BASE, VFB, VAVDD & Load Cell - I.e provide power to the circuit

2. Pulse PD_SCK on for 1 micro second and then off for 1 micro second

3. Read and store bit that is shifted out of DOUT output pin

4. Repeat 2 and 3 for 25 pulses

5. Combine the bits into one binary number with the first being the most significant bit and the last being the least significant.

Seen as this is 24-bits would anything be outputted on the 25th pulse? If so would you just discount this from the 2's compliment number?

6. Convert 2's complement back to voltage value

7. Apply relationship to turn voltage reading into a value for force. This will be multiplied by a correction factor that will be determined through experimentation.

Is there anything that I have misunderstood or missed out? I appreciate that 6 and 7 each involve a few steps.

Thanks a lot for your time and help.
 
Last edited:

ericgibbs

Joined Jan 29, 2010
18,849
hi m,
Which programming language and PIC are you using.?
The conversion cycle is fixed by the HX711 its set for 10/sec, Dout goes low when its ready to be clocked out.
Dout is Read on the falling edge of the CLK pulse.

E
 

Thread Starter

moomo

Joined Jul 14, 2017
41
I will just be doing everything with an Arduino UNO. So is it on a timer where DOUT is high for 50 milliseconds and then low for 50 milliseconds, where the 2's compliment output is only read during the low phase? When you say the falling edge of the clock pulse do you mean each PD_SCK pulse?

Seen as the pulses are only around 1 micro seconds each, 50 milliseconds for the conversion period seems quite high. Is it possible to change this?

Thanks again for your help. Really appreciated.
 

ericgibbs

Joined Jan 29, 2010
18,849
hi m,
This is a clip from an earlier thread about the HX711
Clip:
Conversion from 10Samp/s to 80Samp/sec done, works OK,.!
Using a small safety pin, form a very small hook on the sharp end of the pin.

Place hook under pin #15 , apply your solder iron to pin 15, , gently prise the HX711 leg, upward off the PCB pad, leave a gap of approx 1mm between the leg and the PCB.
Cut a 0.125W 1k thru 10k resistor to length [ the 0.125Watt resistor have thinner connecting wires]
Carefully scrape the copper track clean, removing the green lacquer, tin the track.
Solder in the resistor.
Refer to attached image for directions.

It is important that you ensure that you do not cause damage to the HX711 IC, so observe electrostatic procedures.

link to other thread:
https://forum.allaboutcircuits.com/posts/1149773/
E
 

Attachments

Thread Starter

moomo

Joined Jul 14, 2017
41
That is really useful, thanks for that. Please could you clarify what you mean by DOUT is read on the falling edge of the clock pulse? Is this after each of the pulses on PD_SCK or at the end of the conversion period? The way I thought that it worked is that it has some kind of memory and the 2s complement value is a snapshot in time of the value at the start of the conversion period. At the leading edge of each of the pulses on the PD_SCK the relevant value is pushed to DOUT (one by one at the leading edge of each of the pulses on PD_SCK). Have I got that right or am I off? If so, would you be able to try and explain?

Thanks again :)
 

ericgibbs

Joined Jan 29, 2010
18,849
hi,
Look at this marked up clip from the d/s.
E
Note: Corrected the d/s error the 27 pulse cycle.
HX711timing1.gif
 
Last edited:

ericgibbs

Joined Jan 29, 2010
18,849
That is awesome, thanks very much.
hi m,
I understand that you want to write your own Arduino Sketch for the HX711 and also not use any existing libs.??

My advice would be to use the existing HX Sketches and Libs for the HX, also for now do no not increase the Dout rate to 80.

Once you have debugged your hardware and it works OK with the standard libs, then you could start writing your own Sketches and Libs, using the existing libs as a reference.

It should be possible to reverse engineer the Lib routines, one at a time, into your Main Sketch, debug as you go.

E
 

Thread Starter

moomo

Joined Jul 14, 2017
41
I have already had it working with the standard lib, so I am looking to now understand what is actually happening under the hood. Rather than using the 10 SPS or 80 SPS could I not just use the arduino to provide an external clock signal?
 

ericgibbs

Joined Jan 29, 2010
18,849
hi,
The Arduino checks for the Low Dout when the Clk is Low, the Arduino program decides when to act on that condition, so the HX711 will wait.
Read the Table in Fig #1.
The 10 and 80 are the maximum rates at which the HX711 can run.
E
 

Attachments

Thread Starter

moomo

Joined Jul 14, 2017
41
On page 4 it say:

When using external clock or crystal, output data rate is directly proportional to the clock or crystal frequency.

I was thinking that meant it could be more than 80 SPS. Have I missunderstood that?

For the 24 bit output do you know how it works if you have a decimal number? Which of the 24 bits represent the number after the decimal point?

Thanks again for your help.
 

ericgibbs

Joined Jan 29, 2010
18,849
When using external clock or crystal, output data rate is directly proportional to the clock or crystal frequency.
This means if you used an external crystal that was half the frequency of the internal crystal the update would 5 or 40 smp/s
Do you plan to use an external xtal.?

I was thinking that meant it could be more than 80 SPS. Have I missunderstood that?
If you look at this Table, you must observe the minimum times for the T1 thru T4 periods, you would choose the max xtal frequency that would meet this requirement.

For the 24 bit output do you know how it works if you have a decimal number? Which of the 24 bits represent the number after the decimal point?

The output is only a count from 0 bits thru 23 bits [ highest 24 bit is polarity] the 0 to 23 bits are not a value.
To turn this count into a value you have to do maths in your program to make it Scale to your required units.
eg:
Say you had a count of 10000 [decimal] and you had calibrated your load cell so that a count of 1000 was equal to say 500kG, that would be [10000/1000]*500kG = 5000kG

Using a 'float' define in your program will give a a value to two decimal places.
hi m,
If you tell me exactly what you want to do, it would help me to answer specific questions.

E
 

Attachments

Last edited:

ericgibbs

Joined Jan 29, 2010
18,849
hi m,
This is a clip from a HX711 Lib, it shows the 24 bit Read cycle, padding for the MSBit and the conversion that is required for the ADC count from Binary to Decimal
Note: also the Channel and Gain factor bits for the next Read Cycle.

E

Code:
    unsigned long value = 0;
    uint8_t data[3] = { 0 };
    uint8_t filler = 0x00;

    // pulse the clock pin 24 times to read the data
    data[2] = shiftIn(DOUT, PD_SCK, MSBFIRST);
    data[1] = shiftIn(DOUT, PD_SCK, MSBFIRST);
    data[0] = shiftIn(DOUT, PD_SCK, MSBFIRST);

    // set the channel and the gain factor for the next reading using the clock pin
    for (unsigned int i = 0; i < GAIN; i++) {
        digitalWrite(PD_SCK, HIGH);
        digitalWrite(PD_SCK, LOW);
    }

    // Replicate the most significant bit to pad out a 32-bit signed integer
    if (data[2] & 0x80) {
        filler = 0xFF;
    } else {
        filler = 0x00;
    }

    // Construct a 32-bit signed integer
    value = ( static_cast<unsigned long>(filler) << 24
            | static_cast<unsigned long>(data[2]) << 16
            | static_cast<unsigned long>(data[1]) << 8
            | static_cast<unsigned long>(data[0]) );

    return static_cast<long>(value);
}
 
Top