Skip to content

Commit

Permalink
add support for weighing sensor HX710/HX711
Browse files Browse the repository at this point in the history
  • Loading branch information
GuoGeTiertime committed Sep 22, 2023
1 parent e9bf2d4 commit a40debf
Show file tree
Hide file tree
Showing 3 changed files with 230 additions and 1 deletion.
88 changes: 88 additions & 0 deletions klippy/extras/hx71x.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# HX710/HX711 weighing sensor support
#
# Copyright (C) 2023 guoge <[email protected]>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging
import mcu

######################################################################
# Compatible Sensors:
# HX710A / HX711 / HX712
######################################################################


class HX71X:
def __init__(self, config):
self.printer = config.get_printer()
self.name = config.get_name().split()[-1]
self.reactor = self.printer.get_reactor()
self.mcu = mcu.get_printer_mcu(self.printer,
config.get('hx71x_mcu', 'mcu'))
self.oid = self.mcu.create_oid()

# Determine pin from config
ppins = config.get_printer().lookup_object("pins")
sck_params = ppins.lookup_pin(config.get('hx71x_sck_pin'))
dout_params = ppins.lookup_pin(config.get('hx71x_dout_pin'))

self.mcu.add_config_cmd(
"config_hx71x oid=%d sck_pin=%s dout_pin=%s"
% (self.oid, sck_params['pin'], dout_params['pin']))

#update period
self.report_time = config.getfloat('hx71x_report_time', 2,
minval=0.02)

#unit scale
self.scale = config.getfloat('hx71x_scale', 0.001)

self.weight = 0.0
self.sample_timer = self.reactor.register_timer(self._sample_hx71x)
self.printer.add_object("hx71x " + self.name, self)
self.printer.register_event_handler("klippy:connect",
self.handle_connect)

self.cmd_queue = self.mcu.alloc_command_queue()
self.mcu.register_config_callback(self.build_config)

def handle_connect(self):
self.reactor.update_timer(self.sample_timer, self.reactor.NOW)
return

def build_config(self):
self.read_hx71x_cmd = self.mcu.lookup_query_command(
"read_hx71x oid=%c read_len=%u",
"read_hx71x_response oid=%c response=%*s", oid=self.oid,
cq=self.cmd_queue)

def read_hx71x(self, read_len):
return self.read_hx71x_cmd.send([self.oid, read_len])

def setup_callback(self, cb):
self._callback = cb

def get_report_time_delta(self):
return self.report_time

def _sample_hx71x(self, eventtime):
params = self.read_hx71x(4)

response = bytearray(params['response'])
w = int.from_bytes(response, byteorder='little', signed=True)
self.weight = w * self.scale # weight scale

logging.info(" read hx711 @ %.3f , weight:%.2f", eventtime, self.weight)
return eventtime + self.report_time

def get_status(self, eventtime):
return {
'weight': round(self.weight, 2)
}


def load_config(config):
return HX71X(config)

def load_config_prefix(config):
return HX71X(config)
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Main code build rules

src-y += sched.c command.c basecmd.c debugcmds.c
src-y += sched.c command.c basecmd.c debugcmds.c hx71x.c
src-$(CONFIG_HAVE_GPIO) += initial_pins.c gpiocmds.c stepper.c endstop.c \
trsync.c
src-$(CONFIG_HAVE_GPIO_ADC) += adccmds.c
Expand Down
141 changes: 141 additions & 0 deletions src/hx71x.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Commands for read weight from HX710A/HX711/HX712.
//
// Copyright (C) 2023 guoge <[email protected]>
//
// This file may be distributed under the terms of the GNU GPLv3 license.

#include <string.h> // memcpy
#include "autoconf.h" //
#include "basecmd.h" //oid_alloc
#include "command.h" //sendf
#include "sched.h" //DECL_COMMAND
#include "board/gpio.h" //GPIO/read/setup
#include "generic/armcm_timer.h" // udelay


struct hx71x_s {
struct gpio_out sck_out;
struct gpio_in dt_in;
long weight_tare;
long pulse_count;
};

long HX711_Read(struct hx71x_s *dev);
void HX711_Get_WeightTare(struct hx71x_s *dev);
long HX711_Get_Weight(struct hx71x_s *dev);


void command_config_hx71x(uint32_t *args)
{
struct hx71x_s *hx71x = oid_alloc(args[0], command_config_hx71x
, sizeof(*hx71x));
hx71x->sck_out = gpio_out_setup(args[1], 1);
hx71x->dt_in = gpio_in_setup(args[2], 1);
gpio_out_write(hx71x->sck_out, 0);

hx71x->weight_tare = 0;
}
DECL_COMMAND(command_config_hx71x,
"config_hx71x oid=%c sck_pin=%u dout_pin=%u");


struct hx71x_s * hx71x_oid_lookup(uint8_t oid)
{
return oid_lookup(oid, command_config_hx71x);
}


void command_read_hx71x(uint32_t * args)
{
static int s_nCnt = 0;
s_nCnt++;

uint8_t oid = args[0];
struct hx71x_s *dev = hx71x_oid_lookup(args[0]);
dev->pulse_count = args[1];
uint8_t data_len = 4;
uint8_t data[data_len];

long weight = HX711_Get_Weight(dev);
data[0] = weight & 0xFF;
data[1] = (weight>>8) & 0xFF;
data[2] = (weight>>16) & 0xFF;
data[3] = (weight>>24) & 0xFF;
sendf("read_hx71x_response oid=%c response=%*s", oid, data_len, data);
}
DECL_COMMAND(command_read_hx71x, "read_hx71x oid=%c read_len=%u");


//read data form HX711
long HX711_Read(struct hx71x_s *dev)
{
//gpio_out_reset(dev->sck_out, 0);
gpio_out_write(dev->sck_out, 0);
udelay(1);

//wait dout to low.
//gpio_in_reset(dev->dt_in, 1);
int nCnt = 0;
while ( gpio_in_read(dev->dt_in) )
{
udelay(1);
if (nCnt++> 100 * 1000)
return 0;
}

//read 24bit data.
unsigned long count=0;
for (int i = 0; i < 24; i++)
{
gpio_out_write(dev->sck_out, 1);
udelay(1);

count = count << 1;

gpio_out_write(dev->sck_out, 0);
udelay(1);

if( gpio_in_read(dev->dt_in) )
count++;
}

//last clk, total 25/26/27
int n = 1;
if( dev->pulse_count==26 )
n = 2;
else if( dev->pulse_count==27 )
n = 3;

for (int i = 0; i < n; i++)
{
gpio_out_write(dev->sck_out, 1);
udelay(1);
gpio_out_write(dev->sck_out, 0);
udelay(1);
}

count ^= 0x800000;
return count;
}

//set weight tare.
void HX711_Get_WeightTare(struct hx71x_s* dev)
{
dev->weight_tare = HX711_Read(dev);
}

//get weight
long HX711_Get_Weight(struct hx71x_s* dev)
{
static int s_nCnt = 0;

long value = HX711_Read(dev);

if( s_nCnt<2 ) //reset weight tare at 1/2 times.
{
s_nCnt++;
dev->weight_tare = value;
}

return value - dev->weight_tare;
}

0 comments on commit a40debf

Please sign in to comment.