使用STM32和HX711AD模块制作人体秤并通过OLED显示数据
最近做一个人体秤,傻乎乎的只买了一个人体压力传感器(只有一根信号线输出)
买回来之后发现读不出来数据,数据一直固定不变的,我把hx711的电源线拔掉还是那个数值(当时觉得就离谱),看资料发现这个需要构成电桥,但是我当时只有这个
测量三根线后发现电阻关系可能是这样的,(猜测)
于是乎,我就在hx711上接了两个1k电阻构成电路
但是并没有什么卵用…然后又下单买了一块压力传感器
然后才读取到了数据,然后你就会发现这两个一起用的话,你同时给他们俩施加同一个方向的力,
一个传感器输出的信号会让你读取的数值减,一个传感器输出的信号会让你读取的数值增加,所以可以通过我上面的图发现我的两个传感器是一正一反的放着的,并且我通过3d建模给他们打印了外壳,因为我们需要对传感器的‘E’用力,才会数值变化。
这个压力传感器是有应变片在里面,有压力时会通过产生很微弱的电阻值变化,然后产生很微弱的电压值变化,hx711应该主要是增益电压信号然后把这个放大后的信号去变成数字信号。
下面是用stm32 hal库写的驱动代码
#include "HX711.h"
#include "tim.h"
unsigned long read_hx711 (void )
{
static unsigned long count =0;
static uint8_t i;
count =0;
HAL_GPIO_WritePin(hx711_SCK_GPIO_Port, hx711_SCK_Pin, GPIO_PIN_RESET) ;
Delay_us(2);
while (HAL_GPIO_ReadPin(hx711_DT_GPIO_Port, hx711_DT_Pin) );
for(i=0;i<24;i++){
HAL_GPIO_WritePin(hx711_SCK_GPIO_Port, hx711_SCK_Pin, GPIO_PIN_SET) ;
Delay_us(1);
count = count<<1;
HAL_GPIO_WritePin(hx711_SCK_GPIO_Port, hx711_SCK_Pin, GPIO_PIN_RESET) ;
Delay_us(1);
if(HAL_GPIO_ReadPin(hx711_DT_GPIO_Port, hx711_DT_Pin))count++;
}
HAL_GPIO_WritePin(hx711_SCK_GPIO_Port, hx711_SCK_Pin, GPIO_PIN_SET) ;
Delay_us(1);
count = count^0x800000;
HAL_GPIO_WritePin(hx711_SCK_GPIO_Port, hx711_SCK_Pin, GPIO_PIN_RESET) ;
delay_ms(1);
return count;
}
#ifndef __HX711_H
#define __HX711_H
#include "main.h"
#include "gpio.h"
#define HX711_SCK_0 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET)
#define HX711_SCK_1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET)
#define HX711_DOUT HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15)
unsigned long read_hx711 (void ) ;
#endif
当然,代码里的延时也可以去掉,.c中我并没有使用.h定义的HX711_SCK_0,HX711_SCK_1,想要去用的话直接调用就行。
下面的代码就是我自己用的代码了贴出来给大家参考,但是数据不是很稳定
#include "user.h"
#include "oled.h"
#include "hx711.h"
#include "tim.h"
char uart_show [8];
char hx711_show [8];
volatile int32_t hx711_ValueOut =0,hx711_start=0,hx711_value=0,hx_out;
uint8_t hx_count =0,hx_okFlag,jr6001_flag,jr6001_volume;
hx711_value_type hx711;
void my_int ()
{
static uint16_t i =0;
// for(i=0;i<10;i++){
// read_hx711();
// Delay_us(10);
// }
for(i=0;i<20;i++){
hx711.start += read_hx711();
OLED_DrawRect(0,20,i*128/20,23);
Delay_us(100);
}
hx711_start= (hx711.start/20) ;
OLED_Clear();
OLED_ShowString(0,0,(uint8_t *)"Initialize is OK",16);
}
void oled_show ()
{
// static uint16_t i ;
OLED_ShowString(40,0,(uint8_t *)" kg ",16); //擦除
hx_count ++;
hx711.out =0;
/***************数据处理****************/
hx711_value = read_hx711() ;
hx711_ValueOut =hx711_value-hx711_start;
hx711_ValueOut = hx711_ValueOut *0.0225;
if(hx711_ValueOut<=0)hx711_ValueOut=0;
OLED_DrawRect(0,20,hx_count*128/50,23);
if(hx_count==50){ //数据50次取平均值
hx_okFlag =1;
hx_count = 0;
hx_out =hx_out /50; //取平均值
sprintf (hx711_show ,"%03d.%03d",hx_out/1000,hx_out%1000);
OLED_ShowString(40,0,(uint8_t *)hx711_show,16);
// OLED_ShowNum(40,0,hx_out/1000,3,16);
// OLED_ShowChar(64,0,'.',16);
// OLED_ShowNum(72,0,hx_out%1000/10,3,16);
// OLED_ShowString(0,2,(uint8_t *)"OK",16);
/***JR6001输出数据**/
HAL_UART_Transmit(&huart2,(uint8_t *)"A7:00004",8,10);
delay_ms(2000);
sprintf (uart_show,"B7:%02d%02d10",hx_out/1000/10,hx_out/1000%10);
HAL_UART_Transmit(&huart2,(uint8_t *)uart_show,10,10);
hx_out =0;
}
hx_out =hx_out +hx711_ValueOut;
/***************数据输出****************/
// sprintf(uart_show,"start:%d\r\n",hx711_start);
// HAL_UART_Transmit(&huart1,(uint8_t *)uart_show,16,0xff);
// sprintf(uart_show,"value:%d\r\n",hx711_value);
// HAL_UART_Transmit(&huart1,(uint8_t *)uart_show,16,0xff);
// sprintf(uart_show,"out:%d\r\n",hx711_ValueOut);
// HAL_UART_Transmit(&huart1,(uint8_t *)uart_show,16,0xff);
// HAL_UART_Transmit(&huart1,(uint8_t *)"over",5,0xff);
OLED_ShowCHinese(0,0,0);
OLED_ShowCHinese(16,0,1);
OLED_ShowChar(32,0,':',16);
// OLED_ShowNum(0,2,hx711_start,8,16);
OLED_ShowNum(0,4,hx711_ValueOut,6,16);
OLED_ShowCHinese(0,6,2);
OLED_ShowCHinese(16,6,3);
OLED_ShowCHinese(32,6,4);
OLED_ShowCHinese(48,6,5);
OLED_ShowChar(64,6,':',16);
OLED_ShowNum(96,6,jr6001_volume,2,16);
my_JR6001();
delay_ms(1);
}
当我放了一瓶矿泉水在上面
E2F5B1BD6650869804D88CA0D4DA2E81_哔哩哔哩_bilibili
作者:阿哟阿哟