【luckfox】3、计算重量差

前言

本章结合之前的hx711驱动,实现读取质量,记录时间及剩余质量并存入csv文件,计算质量差并总计。

代码

luckfox-pico\project\app\test_app\hx711\hx711_app_addtime.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
// #include <linux/delay.h>
#include <sys/time.h>
#include <string.h>
#include <time.h>

#define IIO_DEVICE "/sys/bus/iio/devices/iio:device0"
#define SENSOR_CALI_PATH_OFFSET "/root/hx711_cal_offset"
#define SENSOR_CALI_PATH_SCALE "/root/hx711_cal_scale"

static int cal_offset = 8500000;    // save raw value without test items

static int cal_scale = 475;         // when set phone, 1g is 475
static int cal_weight = 187;  // the weight of phone

// static float weight = 0;
static int weight = 0;


//--------------- hx711 value process ---------------
#define LIST_NUM_MAX 64
#define CSV_PATH "/root/hx711.csv"

int v1,v2;
int flag_change;

struct weight_data{
    int weight;
    time_t time;
};

struct weight_data list[LIST_NUM_MAX];
int current_list_num=0;

int drink_water=0;

//--------------- hx711 value process ---------------

// float convert_to_weight(int sensor_data) {
int convert_to_weight(int sensor_data) {
    int weight;
    // weight = (float)(sensor_data - cal_offset) / cal_scale;

    // printf("\nsensor_raw=%d,cal_offset=%d,cal_scale=%d\n",sensor_data,cal_offset,cal_scale);
    if(cal_scale != 0)
        weight = (sensor_data - cal_offset) / cal_scale;
    else
        weight = 0;

    // printf("Sensor data: %.1f\n", weight);
    // printf("Sensor data: %d\n", weight);

    return weight;
}


int get_hx711_raw(){
    int fd;
    char buf[64];
    ssize_t num_read;

    fd = open(IIO_DEVICE "/in_voltage0_raw", O_RDONLY);
    if (fd < 0) {
        perror("Failed to open iio device");
        return 1;
    }

    num_read = read(fd, buf, sizeof(buf) - 1);
    if (num_read < 0) {
        perror("Failed to read sensor data");
        close(fd);
        return 1;
    }
 
    close(fd);
 
    buf[num_read] = '\0';
    int sensor_data = atoi(buf);
    // printf("  raw sensor_data=%d\n",sensor_data);

    return sensor_data;
}

// float get_hx711_value(){
int get_hx711_value(){

    int sensor_data = get_hx711_raw();

    weight = convert_to_weight(sensor_data);

    return weight;
}

// save scale&offset to file 
void set_cal_value(){
    int fd;
    char tmp_char[64];

    fd = open(SENSOR_CALI_PATH_OFFSET, O_CREAT|O_RDWR ,0777);
    if (fd < 0) {
        perror("Failed to open cal offset.");
        return;
    }
 
    // printf("-------\ncal_offset=%d\n",cal_offset);
    memset(tmp_char,0,sizeof(tmp_char));
    sprintf(tmp_char,"%d\0",cal_offset);
    // printf("xxx tmp_char=[%s]\n",tmp_char);
    write(fd, tmp_char, sizeof(tmp_char));

    close(fd);

    fd = open(SENSOR_CALI_PATH_SCALE, O_CREAT|O_RDWR ,0777);
    if (fd < 0) {
        perror("Failed to open cal offset.");
        return;
    }

    // printf("cal_scale=%d\n",cal_scale);
    memset(tmp_char,0,sizeof(tmp_char));
    sprintf(tmp_char,"%d\0",cal_scale) ;
    // printf("xxx tmp_char=[%s]\n-------\n",tmp_char);
 
    write(fd, tmp_char, sizeof(tmp_char)-1);
    close(fd);
}

void print_cal_value_and_raw(int sensor_raw_tmp){
    printf("cal&raw:\n");
    printf("   cal_offset=%d sensor_raw=%d\n", cal_offset, sensor_raw_tmp);
    printf("   test_offset\t%d\n   cal_weight\t%d\n   cal_scale\t%d\n",
            sensor_raw_tmp - cal_offset, cal_weight, cal_scale);
    printf("\n");
}

void print_cal_value(){
    printf("hx711 calibration value\n");
    printf("   cal_offset\t%d\n   cal_weight\t%d\n   cal_scale\t%d\n",
            cal_offset, cal_weight, cal_scale);
    printf("\n");
}

void sns_calibration(){
    int cal_test_num = 10;
    int cal_average = 0;
    int cal_test_tmp = 0;
    int cal_scale_raw = 0;

    // test 10 times to get offset average
    for(int i=0; i<cal_test_num; i++){
        cal_test_tmp = get_hx711_raw();
        usleep(10);
        cal_average = (cal_average * i + cal_test_tmp)/(i+1);
    }

    cal_offset=cal_average;

    usleep(20);

    printf("!!! Please put test items on the board whose weight same with cmd3\nWaiting input char to continue ...\n");
    getchar();

    cal_test_tmp = get_hx711_raw();
    cal_scale_raw = cal_test_tmp - cal_offset;
    cal_scale = (cal_scale_raw)/cal_weight;

    print_cal_value_and_raw(cal_test_tmp);

    set_cal_value();
}


void get_cal_value(){
    int tmp_offset;
    int tmp_scale;
    char tmp_file_value[64];
    int fd;

    // printf("get_cal_value\n");

    fd = open(SENSOR_CALI_PATH_OFFSET, O_RDWR,0777);
    if (fd < 0) {
        perror("Failed to open cal offset.");
        return;
    }

    read(fd, tmp_file_value, sizeof(tmp_file_value) - 1);
    // printf("tmp_file_value=%s\n",tmp_file_value);
    tmp_offset = atoi(tmp_file_value);
    // printf("tmp_offset=%d\n",tmp_offset);
 
    close(fd);

    fd = open(SENSOR_CALI_PATH_SCALE, O_RDWR,0777);
    if (fd < 0) {
        perror("Failed to open cal offset.");
        return;
    }
 
    memset(tmp_file_value,0,sizeof(tmp_file_value));
    read(fd, tmp_file_value, sizeof(tmp_file_value) - 1);
    tmp_scale = atoi(tmp_file_value);
    // printf("tmp_offset=%d\n",tmp_scale);
 
    close(fd);

    cal_offset = tmp_offset;
    cal_scale = tmp_scale;
}

#define LEN_MAX 30

void save_to_csv(struct weight_data value)
{
    char tmp_c[LEN_MAX];
    char * tmp;

    FILE *fp = fopen(CSV_PATH, "a+");
    if (fp == NULL) {
        fprintf(stderr, "fopen() failed.\n");
        exit(EXIT_FAILURE);
    }

    struct tm *tm_t;
    tm_t = localtime(&value.time);
    strftime(tmp_c,LEN_MAX,"%F %T",tm_t);
    printf("time:%s\t",tmp_c);

    fprintf(fp, tmp_c);
    fprintf(fp, " | ");

    memset(tmp_c,0,LEN_MAX);
    sprintf(tmp_c, "%d", value.weight);
    printf("weight:%s\n",tmp_c);
    fprintf(fp, tmp_c);
    fprintf(fp, "\n");

    fclose(fp);
}


int value_changed(int value1, int value2)
{
    if(value1 != value2)
    {
        flag_change = 1;
        // printf("change value v1=%d  v2=%d\n",value1,value2);
    }else{
        if(flag_change == 1 && value1 != 0){
            // save value
            // printf("change value %d\n",value1);
            list[current_list_num].weight = value1;
            // printf("change value %d\n",list[current_list_num].weight);

            // save time
            time_t tnow = time(0);
            // printf("当前时间为:%ld\r\n",tnow);
            list[current_list_num].time = tnow;

            if(list[current_list_num].weight < list[current_list_num-1].weight){
                drink_water = drink_water + 
                    list[current_list_num-1].weight - list[current_list_num].weight;
                printf("== drink %dmL\n",drink_water);
            }
            // save value to file
            save_to_csv(list[current_list_num]);

            current_list_num++;

            flag_change = 0;
        }
    }
    return flag_change;
}


int get_value()
{
    int value = 0;

    // get value
    value = get_hx711_value();

    // save value to v1&v2
    v1 = v2;
    v2 = value;

    // judge
    value_changed(v1,v2);

    return value;
}


int main(int argc, char *argv[]) {

    char cmd1[16];
    char cmd2[16];
    char cmd3[16];
    int ret;
    int val_tmp=0;

    // calibration: put the items whose weight is known. weight sends to cmd3
    // ./hx771_app -c 187
    if(argc == 3){
        strcpy(cmd2,argv[1]);
        strcpy(cmd3,argv[2]);
        printf("cmd2=%s cmd3=%s\n",cmd2,cmd3);
        if(strcmp(cmd2, "-c") == 0){
            printf("get cal cal_weight %s\n",cmd3);
            cal_weight=atoi(cmd3);        // save the weight of cal items
        } else {
            printf("hx711 no cal_weight\n");
            return 0;
        }

        sns_calibration();

		sleep(1);

        // test the calibration result
        val_tmp = get_hx711_value();
        printf("sensor value: %d\n", val_tmp);

		return 0;
    }

    printf("-------------test-------------\n");

    get_cal_value();
    print_cal_value();

    int sensor_data;
    while(1){
        // val_tmp = get_hx711_value();
        val_tmp = get_value();
        // if(val_tmp != 0)
        //     printf("%02d: %d\n",50 - test_num,val_tmp);
        sleep(1);
    }

    printf("--------------------------\n");

    return 0;
}

编译

luckfox-pico\project\app\test_app\hx711\build.sh

export PATH=/home/youkai/0_pro/luckfox/luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin:$PATH
source ~/.bashrc  
cd ~/0_pro/luckfox/luckfox-pico/project/app/test_app/hx711
arm-rockchip830-linux-uclibcgnueabihf-gcc hx711_app_addtime.c -o hx711_app_addtime

运行

运行bat可以进行快速测试,放在windows本地

time_get_hx711.bat

scp youkai@192.168.206.130:/home/youkai/0_pro/luckfox/luckfox-pico/project/app/test_app/hx711/hx711_app_addtime .

adb push hx711_app_addtime /root/
adb shell "chmod 777 /root/hx711_app_addtime"
adb shell "./root/hx711_app_addtime"

结果

代码实现了测试重量,并计算出喝水的毫升数。
在这里插入图片描述

读取保存的时间和重量。

# cat hx711.csv
2023-11-15 19:42:55 | 68
2023-11-15 19:43:07 | 194
2023-11-15 19:43:14 | 3
2023-11-15 19:43:27 | 68
2023-11-15 19:43:38 | 10

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/149319.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

故障演练的关键要素及重要性

故障演练是一种有计划的、模拟真实生产环境故障的活动。通过故意引入故障、模拟系统组件失效或模拟其他异常条件&#xff0c;团队可以观察并评估系统在这些情况下的反应。这有助于发现潜在的问题、改进应急响应和提高系统整体的可用性。 一、故障演练的关键要素 计划性&#xf…

今年跳槽成功测试工程师原来是掌握了这3个“潜规则”

随着金九银十逐渐进入尾声&#xff0c;还在观望机会的朋友们已经开始焦躁&#xff1a;“为什么我投的简历还没有回音&#xff1f;要不要趁现在裸辞好好找工作&#xff1f;” “金九银十”作为人们常说的传统“升职加薪”的黄金季节&#xff0c;也是许多人跳槽的理想时机。然而…

基于消息队列+多进程编写的银行模拟系统

银行模拟系统 概述客户端 client.c服务端 serve.c开户 enroll.c存款 save.c转账 transfer.c取款 take.cmakefile文件 概述 该案例大体过程为&#xff0c;服务器先启动&#xff0c;初始化消息队列和信号&#xff0c;用多线程技术启动开户、存钱、转账、取钱模块&#xff0c;并且…

人力项目框架解析新增修改方法

在迁移项目但是遇到了一些问题&#xff0c;迁移项目的时候发现项目的整体框架很有趣&#xff0c;但是苦于项目框架太大了&#xff0c;竟然只能完整迁移&#xff0c;做不到部分迁移&#xff0c;于是我也只能从一半的角度来进行解释整个项目。 雇员 我们雇员这个为对象讲解一下…

软件测试项目案例哪里找?【银行/教育/商城/金融/等等....】

项目一&#xff1a;ShopNC商城 项目概况&#xff1a; ShopNC商城是一个电子商务B2C电商平台系统&#xff0c;功能强大&#xff0c;安全便捷。适合企业及个人快速构建个性化网上商城。 包含PCIOS客户端Adroid客户端微商城&#xff0c;系统PC后台是基于ThinkPHP MVC构架开发的跨…

一个用于操作Excel文件的.NET开源库

推荐一个高性能、跨平台的操作Excel文件的.NET开源库。 01 项目简介 ClosedXML是一个.NET第三方开源库&#xff0c;支持读取、操作和写入Excel 2007 (.xlsx&#xff0c; .xlsm)文件&#xff0c;是基于OpenXML封装的&#xff0c;让开发人员无需了解OpenXML API底层API&#xf…

阿里云今年服务器是真便宜,看看哪些云服务器值得买!

2023年双十一&#xff0c;阿里云推出了一项令人惊喜的独家优惠活动&#xff01;在这次活动中&#xff0c;阿里云开放了老用户购买权限&#xff0c;以超低的价格购买云服务器ECS经济型e实例。这款服务器配置了2核2G内存、3M固定带宽和40G ESSD entry系统盘。而且&#xff0c;更棒…

Playwright测试自动化工具

作者观点&#xff1a;很长时间以来&#xff0c;Selenium是QA工程师寻求测试自动化解决方案的首选测试框架。它能够测试任何浏览器&#xff08;这在IE浏览器的统治时期尤其重要&#xff09;和任何平台。然而&#xff0c;现在看来&#xff0c;那个时代已经过去了。 今天&#xf…

flutter实用笔记

前言 写下这一篇文章是为了记录这段时间使用flutter 制作项目中一些比较常用的组件&#xff0c;以及具体怎么使用&#xff0c;获得怎样的效果。我使用的貌似是flutter4。由于官方更新迭代的差别比较明显&#xff0c;可能之后许多内容对应最新的flutter不适用&#xff0c;在此只…

IDEA导入jar包

通过maven导入本地包 mvn install:install-file -DfileD:\WebProject\ERP\zhixing-heyue-erp-server\zxhy-service-api\src\main\java\com\zxhy\service\api\invoice\baiwang\lib\com_baiwang_bop_sdk_outer_3_4_393.jar -DgroupIdcom.baiwang -DartifactIdbaiwang.open -Dver…

比较器应用之一_窗口比较器/极限比较器

窗口比较器&#xff1a;用处能在一个&#xff0c;电压落在规定的范围之内&#xff0c;报警或者不报警 当输入电压u1 > URa时&#xff0c;必然大于UaL&#xff0c;所以集成运放A1的输出uo1Uow&#xff0c;A2的输出u02-Uow。使得二极管D1导通&#xff0c;D2截止&#xff0c;电…

接口自动化测试用例编写规范

一、接口自动化测试用例设计方法 1.1接口参数覆盖 接口测试通过输入使用参数组合&#xff0c;获得服务器返回值&#xff0c;并根据预先设定的规则判断是否符合预期值。在接口测试中&#xff0c;根据接口的功能不同&#xff0c;需要侧重检测的方面也不同。主要从以下几个方面考…

(Matalb时序预测)GWO-BP灰狼算法优化BP神经网络的多维时序回归预测

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分代码展示&#xff1a; 四、完整代码数据说明手册下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于M…

年薪百万的人怎么做好工作复盘和总结

我们在为谁工作&#xff1f; 在大山宏泰《我们为什么工作》一书中有提到过&#xff1a; 70%左右的人认为工作只是维持生计的存在&#xff1b; 20%左右的人认为工作是个人价值的体现&#xff1b; 不到10%的人才会认为工作是幸福的。 人类的终极幸福有四重&#xff1a;被爱&…

PDF自动打印

​ 最近接到用户提过来的需求&#xff0c;需要一个能够自动打印图纸的功能&#xff0c;经过几天的研究整出来个初版了的&#xff0c;分享出来给大家&#xff0c;希望能有帮助。 需求描述: ​ 生产车间现场每天都有大量的图纸需要打印&#xff0c;一个一个打印太慢了&#xff0…

响应系统的作用与实现

首先讨论什么是响应式数据和副作用函数&#xff0c;然后尝试实现一个相对完善的响应系统。在这个过程中&#xff0c;我们会遇到各种各样的问题&#xff0c;例如如何避免无限递归&#xff1f;为什么需要嵌套的副作用函数&#xff1f;两个副作用函数之间会产生哪些影响&#xff1…

Leetcode——岛屿的最大面积

1. 题目链接&#xff1a;695. 岛屿的最大面积 2. 题目描述&#xff1a; 给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相邻的 1 (代表土地) 构成的组合&#xff0c;这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都…

23000 个恶意流量代理的 IPStorm 僵尸网络被拆除

美国司法部今天宣布&#xff0c;联邦调查局取缔了名为 IPStorm 的僵尸网络代理服务的网络和基础设施。 IPStorm 使网络犯罪分子能够通过世界各地的 Windows、Linux、Mac 和 Android 设备匿名运行恶意流量。 与此案相关的俄罗斯裔摩尔多瓦籍公民谢尔盖马基宁 (Sergei Makinin)…

VUE基础的一些总结

首先推荐观看VUE官方文档 目录 创建一个 Vue 应用 要创建一个 Vue 应用&#xff0c;你需要按照以下步骤操作&#xff1a; 步骤 1&#xff1a;安装 Node.js 和 npm 确保你的计算机上已经安装了 Node.js。你可以在 Node.js 官网 上下载并安装它。安装完成后&#xff0c;npm&…

Spring中的BeanFactory和ApplicationContext的区别

我用一个例子去测试BeanFactory和ApplicationContext的区别 首先建立一个bean public class User { //声明无参构造&#xff0c;打印一句话&#xff0c;监测对象创建时机public User(){System.out.println("User对象初始化");} } 然后再建立测试类 ublic class User…