前言
本章结合之前的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