Skip to main content
Visitor II
June 5, 2019
Question

trying to interface with an HX711 load cell amp

  • June 5, 2019
  • 15 replies
  • 12218 views

The HX711 requires the MCU to send an exact number of clock pulses to capture a 24 bit value, then the clock signal must remain low until the HX711 indicates its ready to transmit again, using the data line. I tried to use a GPIO pin to generate the clock signal manually with pin_set and pin_reset calls, which works in that it creates a clock signal at the frequency of the APB, but the amplitude is only 100 mv. When I plug the clock signal into the HX711 the signal becomes low level noise. Here is the pin config:

 /*Configure GPIO pin : SCLK_Pin */
 GPIO_InitStruct.Pin = SCLK_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(SCLK_GPIO_Port, &GPIO_InitStruct);

and here is the clock gen code:

	// read 24 data bits
	for (i = 0; i < 24; i++) {
	 HAL_GPIO_WritePin (SCLK_GPIO_Port, SCLK_Pin, GPIO_PIN_SET);
	 buffer <<= 1;
	 HAL_GPIO_WritePin (SCLK_GPIO_Port, SCLK_Pin, GPIO_PIN_RESET);
	 buffer += HAL_GPIO_ReadPin (SDATA_GPIO_Port, SDATA_Pin);
	}

I should be getting a 3.3V clock signal. Any suggestions?

    This topic has been closed for replies.

    15 replies

    Graduate II
    June 5, 2019

    Read the datasheet carefully again. You need at least 25 bit cycles. And when, for example, some interrupt prolongs your SCK high for longer than 50 us, you get a reset. So you better read with interrupts disabled. With 26 or 27 bit you select the other channel ot another gain.

    GrantWAuthor
    Visitor II
    June 5, 2019

    Uwe, thats good information but doesn't address the problem: a weak clock signal. My code snippet is not the whole app, just the parts that deal with this issue.

    Graduate II
    June 6, 2019

    What SCK frequency do you get with above code? How is the HX711 connected? Maybe GPIO_SPEED_FREQ_LOW will result in the setup above in a "weak clock signal"?

    Explorer
    June 6, 2019

    Do you have the clock to the "SCLK_Port" enabled ?

    SCLK_Port is just a define for a "real" port like A, B, ...

    Anything other connected to that pin ?

    This is a common issue with ST's Discovery board.

    > ... , then the clock signal must remain low until the HX711 indicates its ready to transmit again ...

    This suggests you want a pull-down resistor, rather then the pull-up you configured.

    An external pull-down would be better, as it works even with unconfigured GPIOs, avoiding troublesome transitional signals during startup.

    GrantWAuthor
    Visitor II
    June 6, 2019

    I tried another pin and am now getting a nice 3.3v signal. For reference, I am using the Nucleo F413 (aka Nucleo 144). The pin that gave me trouble was PE2. Pin PA6 works. As I mentioned in my initial question, the clock speed is the speed of the APB that the port is driven by. Thanks for your suggestions.

    Visitor II
    November 27, 2019

    Hey!

    I am a newby, but i am i a school project where i have to do a scale.

    I set up the hx711 and the load cell with my nucleo card, but the card does not se

    d clock signal to the hx711.

    I am using a hx711 library i found at:

    github.com/freakone/HX711

    Could you please help me?!:folded_hands:

    Thanks in advance.​

    GrantWAuthor
    Visitor II
    November 28, 2019
    Can u show your code and how u configured the clock & data pins?
    Visitor II
    November 28, 2019

    Of course,

    I use CubeMX to configurate the pins as u can see in the first picture.0690X00000AsbMWQAZ.png

    And here is my code:

    1. main
    2. hx711.c
    3. hx711.h
    /* USER CODE BEGIN Header */
    /**
     ******************************************************************************
     * @file : main.c
     * @brief : Main program body
     ******************************************************************************
     * @attention
     *
     * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
     * All rights reserved.</center></h2>
     *
     * This software component is licensed by ST under BSD 3-Clause license,
     * the "License"; You may not use this file except in compliance with the
     * License. You may obtain a copy of the License at:
     * opensource.org/licenses/BSD-3-Clause
     *
     ******************************************************************************
     */
    /* USER CODE END Header */
     
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    #include "dma.h"
    #include "usart.h"
    #include "gpio.h"
     
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    #include "hx711.h"
    #include "string.h"
    /* USER CODE END Includes */
     
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
     
    /* USER CODE END PTD */
     
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
     
    /* USER CODE END PD */
     
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
     
    /* USER CODE END PM */
     
    /* Private variables ---------------------------------------------------------*/
     
    /* USER CODE BEGIN PV */
    volatile int meres =0;
    volatile int meresAtlag =0;
    /* USER CODE END PV */
     
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    /* USER CODE BEGIN PFP */
     
    /* USER CODE END PFP */
     
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
     
    /* USER CODE END 0 */
     
    /**
     * @brief The application entry point.
     * @retval int
     */
    int main(void)
    {
     /* USER CODE BEGIN 1 */
     HX711 hx11;
     hx11.gpioSck = HS711SCK_GPIO_Port;
     hx11.gpioData = HX711OUTPUT_GPIO_Port;
     hx11.pinSck = HS711SCK_Pin;
     hx11.pinData = HX711OUTPUT_Pin;
     hx11.offset = 0;
     hx11.gain = 64;
     
     /* USER CODE END 1 */
     
     
     /* MCU Configuration--------------------------------------------------------*/
     
     /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
     HAL_Init();
     
     /* USER CODE BEGIN Init */
     
     /* USER CODE END Init */
     
     /* Configure the system clock */
     SystemClock_Config();
     
     /* USER CODE BEGIN SysInit */
     
     /* USER CODE END SysInit */
     
     /* Initialize all configured peripherals */
     MX_GPIO_Init();
     MX_USART2_UART_Init();
     MX_DMA_Init();
     /* USER CODE BEGIN 2 */
     HX711_Init(hx11);
     
    uint8_t masage[100];
    //uint8_t times = 4;
     
    //uint8_t times = 4;
    //meresAtlag = HX711_AverageValue(hx11, times);
     /* USER CODE END 2 */
     
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
    	 meres = HX711_Value(hx11);
    	 //meres = HX711_AverageValue(hx11, times);
    	 HAL_Delay(500);
    	 HAL_UART_Transmit(&huart2, masage, sprintf(masage,"%d\n\r", meres),1000);
     /* USER CODE END WHILE */
     
     /* USER CODE BEGIN 3 */
     }
     /* USER CODE END 3 */
    }
     
    /**
     * @brief System Clock Configuration
     * @retval None
     */
    void SystemClock_Config(void)
    {
     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
     
     /** Initializes the CPU, AHB and APB busses clocks 
     */
     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
     RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
     {
     Error_Handler();
     }
     /** Initializes the CPU, AHB and APB busses clocks 
     */
     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
     |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
     
     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
     {
     Error_Handler();
     }
    }
     
    /* USER CODE BEGIN 4 */
     
    /* USER CODE END 4 */
     
    /**
     * @brief This function is executed in case of error occurrence.
     * @retval None
     */
    void Error_Handler(void)
    {
     /* USER CODE BEGIN Error_Handler_Debug */
     /* User can add his own implementation to report the HAL error return state */
     
     /* USER CODE END Error_Handler_Debug */
    }
     
    #ifdef USE_FULL_ASSERT
    /**
     * @brief Reports the name of the source file and the source line number
     * where the assert_param error has occurred.
     * @param file: pointer to the source file name
     * @param line: assert_param error line source number
     * @retval None
     */
    void assert_failed(uint8_t *file, uint32_t line)
    { 
     /* USER CODE BEGIN 6 */
     /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
     /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */
     
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
    #include "hx711.h"
     
    void HX711_Init(HX711 data)
    {
    //	GPIO_InitTypeDef GPIO_InitStruct;
    //	GPIO_InitStruct.Pin = data.pinSck;
    //	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    //	GPIO_InitStruct.Pull = GPIO_NOPULL;
    //	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    //	HAL_GPIO_Init(data.gpioSck, &GPIO_InitStruct);
    //
    //	GPIO_InitStruct.Pin = data.pinData;
    //	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    //	GPIO_InitStruct.Pull = GPIO_PULLUP;
    //	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    //	HAL_GPIO_Init(data.gpioData, &GPIO_InitStruct);
     
    	HAL_GPIO_WritePin(data.gpioSck, data.pinSck, GPIO_PIN_SET);
    	HAL_Delay(50);
    	HAL_GPIO_WritePin(data.gpioData, data.pinSck, GPIO_PIN_RESET);
     
    }
     
    int HX711_Average_Value(HX711 data, uint8_t times)
    {
     int sum = 0;
     for (int i = 0; i < times; i++)
     {
     sum += HX711_Value(data);
     }
     
     return sum / times;
    }
     
    int HX711_Value(HX711 data)
    {
     int buffer;
     buffer = 0;
     
     while (HAL_GPIO_ReadPin(data.gpioData, data.pinData)==1)
     ;
     
     for (uint8_t i = 0; i < 24; i++)
     {
     	HAL_GPIO_WritePin(data.gpioSck, data.pinSck, GPIO_PIN_SET);
     
     buffer = buffer << 1 ;
     
     if (HAL_GPIO_ReadPin(data.gpioData, data.pinData))
     {
     buffer ++;
     }
     
     HAL_GPIO_WritePin(data.gpioSck, data.pinSck, GPIO_PIN_RESET);
     }
     
     for (int i = 0; i < data.gain; i++)
     {
     	HAL_GPIO_WritePin(data.gpioSck, data.pinSck, GPIO_PIN_SET);
     	HAL_GPIO_WritePin(data.gpioSck, data.pinSck, GPIO_PIN_RESET);
     }
     
     buffer = buffer ^ 0x800000;
     
     return buffer;
    }
     
    HX711 HX711_Tare(HX711 data, uint8_t times)
    {
     int sum = HX711_Average_Value(data, times);
     data.offset = sum;
     return data;
    }
     
    #ifndef HX711_H_
    #define HX711_H_
     
    //#include "stm32f3xx_hal.h"
    #include "main.h"
     
    typedef struct _hx711
    {
    	GPIO_TypeDef* gpioSck;
    	GPIO_TypeDef* gpioData;
    	uint16_t pinSck;
    	uint16_t pinData;
    	int offset;
    	int gain;
    	// 1: channel A, gain factor 128
    	// 2: channel B, gain factor 32
     // 3: channel A, gain factor 64
    } HX711;
     
     
    void HX711_Init(HX711 data);
    HX711 HX711_Tare(HX711 data, uint8_t times);
    int HX711_Value(HX711 data);
    int HX711_AverageValue(HX711 data, uint8_t times);
     
    #endif /* HX711_H_ */

    And it retuns 8388608 in the meres variable.

    :(

    Thanks for helping me!

    GrantWAuthor
    Visitor II
    December 3, 2019

    It may be working. The clock signals are generated in HX711_Value() by toggling the clock pin. Its a peculiar protocol. The rate is limited by the speed of the clock controlling that pin (APB1 or APB2). This must be less than 5 MHz for the load cell to keep up. Did you try pressing on the load cell to see it the number changes?

    GrantWAuthor
    Visitor II
    December 3, 2019

    I just re-read your question and saw that the amplitude is too low. Try using another pin (I had the same problem). On an stmf413 pins PA5, PA6 or PA7 work well.

    Visitor II
    December 3, 2019

    Hi again!

    I added some function to my code so now I am getting the clock signal:

    void power_down() {
    	HAL_GPIO_WritePin(HS711SCK_GPIO_Port, HS711SCK_Pin, 0);
    	HAL_GPIO_WritePin(HS711SCK_GPIO_Port, HS711SCK_Pin, 1);
    }
     
    void power_up() {
    	HAL_GPIO_WritePin(HS711SCK_GPIO_Port, HS711SCK_Pin, 0);
    }

    I use it like that:

    while (1)
     {
    	 power_up();
    	 meres =HX711_Average_Value(hx11, 1);
    			 //HX711_Value(hx11);
    	 meres = meres-offs;
    	 HAL_Delay(100);
    	 power_down();
    	 //meres = HX711_AverageValue(hx11, times);
    	 HAL_Delay(500);
    	 HAL_UART_Transmit(&huart2, masage, sprintf(masage,"%d\n\r", meres),1000);
     /* USER CODE END WHILE */
     
     /* USER CODE BEGIN 3 */
     }

    So now I'am finally getting back something else than 8388608 but they are still random numbers for some reason.

    0690X00000AtFl2QAF.png

    Here is my setup:

    0690X00000AtFmyQAF.jpg

    0690X00000AtFmtQAF.jpg

    GrantWAuthor
    Visitor II
    December 3, 2019

    ok, got a bit confused there. I was reading MY original question. Ha!

    Visitor II
    February 21, 2020

    Hİ Atilla_S, Did you solve the problem? "8388608" value is seen when I follow the same steps.

    Visitor II
    February 21, 2020

    Hi same thing here, working on it :persevering_face:​

    GrantWAuthor
    Visitor II
    February 23, 2020
    See my response on the discussion thread. Good luck!