examples/hx711: add new program to test hx711 chip

Signed-off-by: Michał Łyszczek <michal.lyszczek@bofc.pl>
This commit is contained in:
Michał Łyszczek 2024-02-27 16:39:24 +01:00 committed by Xiang Xiao
parent 7ad4a3dcb7
commit 8669861312
5 changed files with 481 additions and 0 deletions

View File

@ -0,0 +1,31 @@
# ##############################################################################
# apps/examples/hx711/CMakeLists.txt
#
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
# license agreements. See the NOTICE file distributed with this work for
# additional information regarding copyright ownership. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# ##############################################################################
if(CONFIG_EXAMPLES_HX711)
nuttx_add_application(
NAME
${CONFIG_EXAMPLES_HX711_PROGNAME}
SRCS
hx711_main.c
STACKSIZE
${CONFIG_EXAMPLES_HX711_STACKSIZE}
PRIORITY
${CONFIG_EXAMPLES_HX711_PRIORITY})
endif()

32
examples/hx711/Kconfig Normal file
View File

@ -0,0 +1,32 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config EXAMPLES_HX711
tristate "HX711 driver example"
default n
select ADC_HX711
---help---
Enable the HX711 example. This program is also useful during
development as it's possible to manipulate and dump hx711
settings, as well as print conversions to terminal.
if EXAMPLES_HX711
config EXAMPLES_HX711_PROGNAME
string "Program name"
default "hx711"
---help---
This is the name of the program that will be used when the NSH ELF
program is installed.
config EXAMPLES_HX711_PRIORITY
int "hx711 task priority"
default 100
config EXAMPLES_HX711_STACKSIZE
int "hx711 stack size"
default DEFAULT_TASK_STACKSIZE
endif

23
examples/hx711/Make.defs Normal file
View File

@ -0,0 +1,23 @@
############################################################################
# apps/examples/hx711/Make.defs
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
ifneq ($(CONFIG_EXAMPLES_HX711),)
CONFIGURED_APPS += $(APPDIR)/examples/hx711
endif

34
examples/hx711/Makefile Normal file
View File

@ -0,0 +1,34 @@
############################################################################
# apps/examples/hx711/Makefile
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
include $(APPDIR)/Make.defs
# hx711 built-in application info
PROGNAME = $(CONFIG_EXAMPLES_HX711_PROGNAME)
PRIORITY = $(CONFIG_EXAMPLES_HX711_PRIORITY)
STACKSIZE = $(CONFIG_EXAMPLES_HX711_STACKSIZE)
MODULE = $(CONFIG_EXAMPLES_HX711)
# hx711 example
MAINSRC = hx711_main.c
include $(APPDIR)/Application.mk

361
examples/hx711/hx711_main.c Normal file
View File

@ -0,0 +1,361 @@
/****************************************************************************
* apps/examples/hx711/hx711_main.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/analog/hx711.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <sys/ioctl.h>
/****************************************************************************
* Private Types
****************************************************************************/
struct hx711_config
{
char dev[32];
char dump;
char channel;
unsigned char gain;
unsigned average;
unsigned loops;
float precision;
int val_per_unit;
int sign;
} g_hx711_config;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: hx711_print_help
*
* Description:
* Prints help onto stdout.
*
****************************************************************************/
static void hx711_print_help(const char *progname)
{
printf("usage: %s [-d <device>] [options]\n"
"\n"
"\t-h print this help message\n"
"\t-d<path> path to hx711 device, default: /dev/hx711_0\n"
"\t-t<prec> tares the scale with specified precision, might"
"take few seconds to complete.\n"
"\t If you set value per unit, precision is in units, "
"otherwise it's raw values.\n"
"\t If units are used, float can be passed like 0.1\n"
"\t-v<val> value read that coresponds to one unit. This value "
"has to be\n"
"\t calibrated first before it's known\n"
"\t-s reverse sign, if values decreses when mass increases, "
"pass this\n"
"\t-D dumps current device settings (like, average, channel, "
"gain etc.)\n"
"\t-a<avg> set how many samples should be averaged before "
"returning value,\n"
"\t values [1..%d] are valid\n"
"\t-c<chan> set channel to read (either 'a' or 'b' is valid)\n"
"\t-g<gain> set adc gain, for channel 'a' 64 and 128 are valid,\n"
"\t for channel 'b', only 64 is valid\n"
"\t-r<num> read this number of samples before exiting, samples "
"will be printed\n"
"\t on stdout as string, one sample per line\n"
"\n"
"Check documentation for full description\n",
progname, HX711_MAX_AVG_SAMPLES);
}
/****************************************************************************
* Name: hx711_parse_args
*
* Description:
* Parses command line arguments
*
****************************************************************************/
static int hx711_parse_args(int argc, FAR char *argv[])
{
int opt;
memset(&g_hx711_config, 0x00, sizeof(g_hx711_config));
while ((opt = getopt(argc, argv, "hd:Dt:a:c:g:r:v:s")) != -1)
{
switch (opt)
{
case 'h':
hx711_print_help(argv[0]);
return 1;
case 'd':
strcpy(g_hx711_config.dev, optarg);
break;
case 't':
g_hx711_config.precision = atof(optarg);
break;
case 'D':
g_hx711_config.dump = 1;
break;
case 'a':
g_hx711_config.average = atoi(optarg);
break;
case 'c':
g_hx711_config.channel = optarg[0];
break;
case 'g':
g_hx711_config.gain = atoi(optarg);
break;
case 'r':
g_hx711_config.loops = atoi(optarg);
break;
case 's':
g_hx711_config.sign = -1;
break;
case 'v':
g_hx711_config.val_per_unit = atoi(optarg);
break;
default:
fprintf(stderr, "Invalid option, run with -h for help\n");
return 1;
}
}
if (g_hx711_config.dev[0] == '\0')
{
strcpy(g_hx711_config.dev, "/dev/hx711_0");
}
return 0;
}
/****************************************************************************
* Name: hx711_set_options
*
* Description:
* Set hx711 options if they were specified on command line
*
* Input Parameters:
* fd - opened hx711 instance
*
****************************************************************************/
int hx711_set_options(int fd)
{
int ret;
/* Set channel to read */
if (g_hx711_config.channel > 0)
{
if ((ret = ioctl(fd, HX711_SET_CHANNEL, g_hx711_config.channel)))
{
fprintf(stderr, "Failed to set channel to %c, error: %s\n",
g_hx711_config.channel, strerror(errno));
return -1;
}
}
/* Set channel ADC gain */
if (g_hx711_config.gain > 0)
{
if ((ret = ioctl(fd, HX711_SET_GAIN, g_hx711_config.gain)))
{
fprintf(stderr, "Failed to set gain to %d, error: %s\n",
g_hx711_config.gain, strerror(errno));
return -1;
}
}
/* Set how many samples to average before printing value */
if (g_hx711_config.average > 0)
{
if ((ret = ioctl(fd, HX711_SET_AVERAGE, g_hx711_config.average)))
{
fprintf(stderr, "Failed to set average to %d, error: %s\n",
g_hx711_config.average, strerror(errno));
return -1;
}
}
/* Set if sign should be reversed or not */
if (g_hx711_config.sign)
{
if ((ret = ioctl(fd, HX711_SET_SIGN, &g_hx711_config.sign)))
{
fprintf(stderr, "Failed to set sign to %d, error: %s\n",
g_hx711_config.sign, strerror(errno));
return -1;
}
}
/* Set what value coresponds to 1 unit */
if (g_hx711_config.val_per_unit > 0)
{
if ((ret = ioctl(fd, HX711_SET_VAL_PER_UNIT,
g_hx711_config.val_per_unit)))
{
fprintf(stderr, "Failed to set val per unit to %d, error: %s\n",
g_hx711_config.val_per_unit, strerror(errno));
return -1;
}
}
return 0;
}
/****************************************************************************
* Name: hx711_dump_options
*
* Description:
* Reads current hx711 settings from kernel driver and dumps them on stdout
*
****************************************************************************/
static void hx711_dump_options(int fd)
{
unsigned average;
unsigned char gain;
char channel;
unsigned val_per_unit;
ioctl(fd, HX711_GET_GAIN, &gain);
ioctl(fd, HX711_GET_CHANNEL, &channel);
ioctl(fd, HX711_GET_AVERAGE, &average);
ioctl(fd, HX711_GET_VAL_PER_UNIT, &val_per_unit);
printf("Current settings for: %s\n", g_hx711_config.dev);
printf("average.............: %u\n", average);
printf("channel.............: %c\n", channel);
printf("gain................: %d\n", gain);
printf("value per unit......: %u\n", val_per_unit);
}
/****************************************************************************
* Name: hx711_read_and_dump
*
* Description:
* Reads configured number of samples, and dumps them to terminal.
*
****************************************************************************/
static int hx711_read_and_dump(int fd)
{
int32_t sample;
while (g_hx711_config.loops--)
{
if (read(fd, &sample, sizeof(sample)) != sizeof(sample))
{
fprintf(stderr, "Error reading from %s, error %s\n",
g_hx711_config.dev, strerror(errno));
return -1;
}
printf("%"PRId32"\n", sample);
}
return 0;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* hx711
****************************************************************************/
int main(int argc, FAR char *argv[])
{
int fd;
if (hx711_parse_args(argc, argv))
{
return 1;
}
fd = open(g_hx711_config.dev, O_RDONLY);
if (fd < 0)
{
fprintf(stderr, "Failed to open %s, error: %s\n", g_hx711_config.dev,
strerror(errno));
return 1;
}
if (hx711_set_options(fd))
{
close(fd);
return 1;
}
if (g_hx711_config.precision)
{
ioctl(fd, HX711_GET_VAL_PER_UNIT, &g_hx711_config.val_per_unit);
if (g_hx711_config.val_per_unit)
{
printf("Taring with %fg precision\n", g_hx711_config.precision);
}
if (ioctl(fd, HX711_TARE, &g_hx711_config.precision))
{
perror("Failed to tare the scale");
close(fd);
return 1;
}
}
if (g_hx711_config.dump)
{
hx711_dump_options(fd);
}
if (g_hx711_config.loops)
{
hx711_read_and_dump(fd);
}
close(fd);
return 0;
}