cancel
Showing results for 
Search instead for 
Did you mean: 

trying to interface with an HX711 load cell amp

GrantW
Associate II

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?

28 REPLIES 28
Uwe Bonnes
Principal III

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.

GrantW
Associate II

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.

Uwe Bonnes
Principal III

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"?

Ozone
Lead II

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.

GrantW
Associate II

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.

Attila_S
Associate II

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.​

Can u show your code and how u configured the clock & data pins?

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!

Could you share your code so maybe I can figure out something?

Thanks in advance!