-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add support for weighing sensor HX710/HX711
- Loading branch information
1 parent
e9bf2d4
commit a40debf
Showing
3 changed files
with
230 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |