Electronic – arduino – HX711 adc read functions gives different accuracy

adcarduinostm32

I'm reading data from HX711 with stm32F1 but accuracy of the data are awful. when i read data with arduino the data ten times good if we compare with stm32 results. these are my read functions.

Arduino function:

long HX711::read() {

// Wait for the chip to become ready.
wait_ready();

// Define structures for reading data into.
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);
}

enter image description here

STM32F1 Function:

    long hx711_read(){


        unsigned long Count;
        unsigned char i;

        Count=0;
        while( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==SET){}
        for(volatile uint32_t n = 0; n < 3; n++){}


        for (i=0;i<24;i++){ 
            HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);
            for(volatile uint32_t n = 0; n < 10; n++){}
            Count=Count<<1;
            HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);
            if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==SET){ Count++;}
             for(volatile uint32_t n = 0; n < 2; n++){}

        }
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);
        Count=Count^0x800000;  
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);


        return Count;

}

enter image description here

what could be the reason why these two functions give different accuracy?

Best Answer

Both functions appear to work essentially identically, except for how bits 31:24 are handled - but I do not think this is your issue.

You did not specify which Arduino you were using though, and since shiftIn is a simple bit-banging function it will run att different speeds depending on what processor and speed you are working with, so if you are using an Uno or something even slower this will limit the resulting clock frequency to the HX711. Also, it internally uses digitalWrite/Read, which are notoriously slow, further limiting the frequency.

The same set-up is true for your STM32F1 function - it does bit-banging without timing. However the STM32F1 may be considerably faster than your Arduino and you are using HAL functions which typically get optimized very well, not unlikely to a single instruction. This should result in an SPI frequency considerably higher than the Arduino equivalent.

My guess is that it is so fast that it does not conform to the timing specifications of the HX711, leading to data corruption.

If this is the case, introducing hard delays after each WritePin call would slow things down and let you verify whether or not this is the issue. Something like for(volatile uint32_t n = 0; n < (DELAY); n++); should do the trick (volatile prevents the delay from being optimized out).

You should measure (using a scope or logic analyzer) the resulting signals to verify that they are within specification.

I assume you cannot use the SPI peripheral for some reason, but if you can - that is a much better solution.