基于小凌派RK2206开发板的电子秤功能实现 原创 精华

发布于 2022-7-4 10:35
浏览
2收藏

秤是一种在生活中经常使用的测量工具,随着科学技术的发展,传统的机械结构的秤逐渐被淘汰,电子秤能够准确、快速的测量并且显示直观操作灵活方便等诸多优点备受人们的青睐。
和传统秤相比较,电子秤利用新型传感器、高精度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);

实际展示效果
上电后显示
基于小凌派RK2206开发板的电子秤功能实现-开源基础软件社区
20g砝码称重显示
基于小凌派RK2206开发板的电子秤功能实现-开源基础软件社区
电路板称重显
基于小凌派RK2206开发板的电子秤功能实现-开源基础软件社区
电路板+砝码显示
基于小凌派RK2206开发板的电子秤功能实现-开源基础软件社区
去皮20g砝码显示
基于小凌派RK2206开发板的电子秤功能实现-开源基础软件社区

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
2
收藏 2
回复
举报
回复
添加资源
添加资源将有机会获得更多曝光,你也可以直接关联已上传资源 去关联
    相关推荐