秤是一种在生活中经常使用的测量工具,随着科学技术的发展,传统的机械结构的秤逐渐被淘汰,电子秤能够准确、快速的测量并且显示直观操作灵活方便等诸多优点备受人们的青睐。
和传统秤相比较,电子秤利用新型传感器、高精度AD转换器件、单片机设计实现,具有精度高、功能强等特点。该电子秤的测量范围为0-5Kg,测量精度达到1g,有高精度,低成本的特点。电子秤采用液晶显示汉字和数值,比传统秤具有更高的准确性和直观性。另外,该电子秤电路简单,使用寿命长,应用范围广。
系统由RK2206+Openharmony+2.4寸LCD显示模块+hx711ad模块+按键模块+5kg压力传感器构成。
部分相关软件代码
void HX711_GPIO_Init()
{
PinctrlSet(HX711_DOUT, MUX_FUNC0, PULL_UP, DRIVE_KEEP);
LzGpioInit(HX711_DOUT);
LzGpioSetDir(HX711_DOUT, LZGPIO_DIR_IN);
LOS_Msleep(10);
PinctrlSet(HX711_SCK, MUX_FUNC0, PULL_KEEP, DRIVE_KEEP);
LzGpioInit(HX711_SCK);
LzGpioSetDir(HX711_SCK, LZGPIO_DIR_OUT);
LOS_Msleep(10);
}
uint32_t HX711_Read(void) //增益128
{
uint32_t count;
uint8_t i;
uint8_t val;
HX711_SCK_L();
count = 0;
uint_tick ts = get_current_tick();
do{
LzGpioGetVal(HX711_DOUT, &val);
}while (val && get_time_us(ts) < 500000);
for (i = 0; i < 24; i++)
{
HX711_SCK_H();
count = count << 1;
HX711_SCK_L();
LzGpioGetVal(HX711_DOUT, &val);
if (val)
count++;
}
HX711_SCK_H();
count = count ^ 0x800000; //第25个脉冲下降沿来时,转换数据
ToyUdelay(7);
HX711_SCK_L();
return (count);
}
uint32_t e53_es_get_adc_average(void)
{
uint8_t cnt;
uint32_t val;
uint64_t sum = 0;
uint32_t min = -1;
uint32_t max = 0;
for (cnt = 0; cnt < 5; cnt++)
{
val = HX711_Read();
sum += val;
if (val > max)
max = val;
if (val < min)
min = val;
}
return (sum - max - min) / (cnt-2);
}
float e53_es_get_weight(float w, uint32_t peel_w, float percision)
{
float weight = ES_GET_WEIGHT_VAL(HX711_Read(), peel_w); //通过公式将ad值转换为重量值
if(percision == 0.0) percision = 0.01;
if (abs(w - weight) < percision) //浮动小于percision不改变值
{
weight = w;
}
if (weight < 0 || weight > 10000.0)
{
weight = 0;
}
return weight;
}
unsigned int lcd_init(uint8_t dir)
{
static bool init = false;
if(!init)
{
init = true;
if (LOS_SemCreate(1, &m_sem_lcd) != LOS_OK)
{
init = false;
printf("\n\n%s Falied to create Semaphore!!!\n\n", __FUNCTION__);
}
}
/* 重启lcd */
LCD_RES_Clr();
LOS_Msleep(100);
LCD_RES_Set();
LOS_Msleep(100);
LOS_Msleep(500);
lcd_wr_reg(0x11);
/* 等待LCD 100ms */
LOS_Msleep(100);
/* 启动LCD配置,设置显示和颜色配置 */
lcd_wr_reg(0X36);
switch (dir)
{
case 0:
g_lcd_size.w = LCD_W;
g_lcd_size.h = LCD_H;
lcd_wr_data8(0x00);
break;
case 1:
g_lcd_size.w = LCD_W;
g_lcd_size.h = LCD_H;
lcd_wr_data8(0xC0);
break;
case 2:
g_lcd_size.w = LCD_H;
g_lcd_size.h = LCD_W;
lcd_wr_data8(0x70);
break;
default:
g_lcd_size.w = LCD_H;
g_lcd_size.h = LCD_W;
lcd_wr_data8(0xA0);
break;
}
lcd_wr_reg(0X3A);
lcd_wr_data8(0X05);
/* ST7789S帧刷屏率设置 */
lcd_wr_reg(0xb2);
lcd_wr_data8(0x0c);
lcd_wr_data8(0x0c);
lcd_wr_data8(0x00);
lcd_wr_data8(0x33);
lcd_wr_data8(0x33);
lcd_wr_reg(0xb7);
lcd_wr_data8(0x35);
/* ST7789S电源设置 */
lcd_wr_reg(0xbb);
lcd_wr_data8(0x35);
lcd_wr_reg(0xc0);
lcd_wr_data8(0x2c);
lcd_wr_reg(0xc2);
lcd_wr_data8(0x01);
lcd_wr_reg(0xc3);
lcd_wr_data8(0x13);
lcd_wr_reg(0xc4);
lcd_wr_data8(0x20);
lcd_wr_reg(0xc6);
lcd_wr_data8(0x0f);
lcd_wr_reg(0xca);
lcd_wr_data8(0x0f);
lcd_wr_reg(0xc8);
lcd_wr_data8(0x08);
lcd_wr_reg(0x55);
lcd_wr_data8(0x90);
lcd_wr_reg(0xd0);
lcd_wr_data8(0xa4);
lcd_wr_data8(0xa1);
/* ST7789S gamma设置 */
lcd_wr_reg(0xe0);
lcd_wr_data8(0xd0);
lcd_wr_data8(0x00);
lcd_wr_data8(0x06);
lcd_wr_data8(0x09);
lcd_wr_data8(0x0b);
lcd_wr_data8(0x2a);
lcd_wr_data8(0x3c);
lcd_wr_data8(0x55);
lcd_wr_data8(0x4b);
lcd_wr_data8(0x08);
lcd_wr_data8(0x16);
lcd_wr_data8(0x14);
lcd_wr_data8(0x19);
lcd_wr_data8(0x20);
lcd_wr_reg(0xe1);
lcd_wr_data8(0xd0);
lcd_wr_data8(0x00);
lcd_wr_data8(0x06);
lcd_wr_data8(0x09);
lcd_wr_data8(0x0b);
lcd_wr_data8(0x29);
lcd_wr_data8(0x36);
lcd_wr_data8(0x54);
lcd_wr_data8(0x4b);
lcd_wr_data8(0x0d);
lcd_wr_data8(0x16);
lcd_wr_data8(0x14);
lcd_wr_data8(0x21);
lcd_wr_data8(0x20);
lcd_wr_reg(0x29);
return 0;
}
void e53_es_thread(uint32_t args)
{
float w = 0, last_w = 0;
uint32_t *flag = (uint32_t *)args;
e53_es_init(*flag);
m_c12.peel.flag = false;
m_c12.add.flag = false;
m_c12.dec.flag = false;
m_c12.add.w = 0;
m_c12.dec.w = 0;
m_c12.init_peel = e53_es_get_adc_average();
m_c12.peel.w = m_c12.init_peel;
m_c12.lcd_msg.e53_c12.data.peel_w = ES_GET_WEIGHT_VAL(m_c12.peel.w , m_c12.init_peel);
while (1)
{
if(m_c12.add.flag)
{
m_c12.lcd_msg.e53_c12.data.weight -= m_c12.add.w;
}
else if(m_c12.dec.flag)
{
m_c12.lcd_msg.e53_c12.data.weight += m_c12.weight;
}
m_c12.weight = e53_es_get_weight(m_c12.lcd_msg.e53_c12.data.weight, m_c12.peel.w, 0.01);
if(m_c12.add.flag)
{
m_c12.lcd_msg.e53_c12.data.weight = m_c12.add.w+m_c12.weight;
}
else if(m_c12.dec.flag)
{
m_c12.lcd_msg.e53_c12.data.weight = m_c12.dec.w-m_c12.weight;
}
else
{
m_c12.lcd_msg.e53_c12.data.weight = m_c12.weight;
}
m_c12.lcd_msg.e53_c12.data.peel_flag = m_c12.peel.flag;
m_c12.lcd_msg.e53_c12.data.add_flag = m_c12.add.flag;
m_c12.lcd_msg.e53_c12.data.dec_flag = m_c12.dec.flag;
if(last_w != m_c12.lcd_msg.e53_c12.data.weight)
{
if(m_c12.add.flag)
{
printf("add:%f,%.0f\n", m_c12.add.w, m_c12.weight);
}
else if(m_c12.dec.flag)
{
printf("dec:%f,%.0f\n", m_c12.dec.w, m_c12.weight);
}
printf("weight:%6.1f,peel:%6.1f\n", m_c12.lcd_msg.e53_c12.data.weight, m_c12.lcd_msg.e53_c12.data.peel_w);
}
last_w = m_c12.lcd_msg.e53_c12.data.weight;
e53_c12_msg_send(&m_c12);
}
}
void e53_es_example()
{
unsigned int ret = LOS_OK;
unsigned int thread_id;
TSK_INIT_PARAM_S task = {0};
task.pfnTaskEntry = (TSK_ENTRY_FUNC)e53_es_thread;
task.uwStackSize = 10240;
task.pcName = "e53_es_example";
task.usTaskPrio = 2;
ret = LOS_TaskCreate(&thread_id, &task);
if (ret != LOS_OK)
{
printf("Falied to create e53_es_example ret:0x%x\n", ret);
return;
}
}
APP_FEATURE_INIT(e53_es_example);
实际展示效果
上电后显示
20g砝码称重显示
电路板称重显
电路板+砝码显示
去皮20g砝码显示