This repository was archived by the owner on Dec 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathhx711_periph.go
149 lines (127 loc) · 3.81 KB
/
hx711_periph.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// +build !windows,!gpiomem
package hx711
import (
"fmt"
"time"
"periph.io/x/periph/conn/gpio"
"periph.io/x/periph/conn/gpio/gpioreg"
"periph.io/x/periph/host"
)
// HostInit calls periph.io host.Init(). This needs to be done before Hx711 can be used.
func HostInit() error {
_, err := host.Init()
return err
}
// NewHx711 creates new Hx711.
// Make sure to set clockPinName and dataPinName to the correct pins.
// https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/hx711_english.pdf
func NewHx711(clockPinName string, dataPinName string) (*Hx711, error) {
hx711 := &Hx711{numEndPulses: 1}
hx711.clockPin = gpioreg.ByName(clockPinName)
if hx711.clockPin == nil {
return nil, fmt.Errorf("clockPin is nill")
}
hx711.dataPin = gpioreg.ByName(dataPinName)
if hx711.dataPin == nil {
return nil, fmt.Errorf("dataPin is nill")
}
err := hx711.dataPin.In(gpio.PullNoChange, gpio.FallingEdge)
if err != nil {
return nil, fmt.Errorf("dataPin setting to in error: %v", err)
}
return hx711, nil
}
// setClockHighThenLow sets clock pin high then low
func (hx711 *Hx711) setClockHighThenLow() error {
err := hx711.clockPin.Out(gpio.High)
if err != nil {
return fmt.Errorf("set clock pin to high error: %v", err)
}
err = hx711.clockPin.Out(gpio.Low)
if err != nil {
return fmt.Errorf("set clock pin to low error: %v", err)
}
return nil
}
// Reset starts up or resets the chip.
// The chip needs to be reset if it is not used for just about any amount of time.
func (hx711 *Hx711) Reset() error {
err := hx711.clockPin.Out(gpio.Low)
if err != nil {
return fmt.Errorf("set clock pin to low error: %v", err)
}
err = hx711.clockPin.Out(gpio.High)
if err != nil {
return fmt.Errorf("set clock pin to high error: %v", err)
}
time.Sleep(70 * time.Microsecond)
err = hx711.clockPin.Out(gpio.Low)
if err != nil {
return fmt.Errorf("set clock pin to low error: %v", err)
}
return nil
}
// Shutdown puts the chip in powered down mode.
// The chip should be shutdown if it is not used for just about any amount of time.
func (hx711 *Hx711) Shutdown() error {
err := hx711.clockPin.Out(gpio.High)
if err != nil {
return fmt.Errorf("set clock pin to high error: %v", err)
}
return nil
}
// waitForDataReady waits for data to go to low which means chip is ready
func (hx711 *Hx711) waitForDataReady() error {
err := hx711.clockPin.Out(gpio.Low)
if err != nil {
return fmt.Errorf("set clock pin to low error: %v", err)
}
var level gpio.Level
// looks like chip often takes 80 to 100 milliseconds to get ready
// but somettimes it takes around 500 milliseconds to get ready
// WaitForEdge sometimes returns right away
// So will loop for 11, which could be more than 1 second, but usually 500 milliseconds
for i := 0; i < 11; i++ {
level = hx711.dataPin.Read()
if level == gpio.Low {
return nil
}
hx711.dataPin.WaitForEdge(100 * time.Millisecond)
}
return ErrTimeout
}
// ReadDataRaw will get one raw reading from chip.
// Usually will need to call Reset before calling this and Shutdown after.
func (hx711 *Hx711) ReadDataRaw() (int, error) {
err := hx711.waitForDataReady()
if err != nil {
return 0, fmt.Errorf("waitForDataReady error: %v", err)
}
var level gpio.Level
var data int
for i := 0; i < 24; i++ {
err = hx711.setClockHighThenLow()
if err != nil {
return 0, fmt.Errorf("setClockHighThenLow error: %v", err)
}
level = hx711.dataPin.Read()
data = data << 1
if level == gpio.High {
data++
}
}
for i := 0; i < hx711.numEndPulses; i++ {
err = hx711.setClockHighThenLow()
if err != nil {
return 0, fmt.Errorf("setClockHighThenLow error: %v", err)
}
}
// if high 24 bit is set, value is negtive
// 100000000000000000000000
if (data & 0x800000) > 0 {
// flip bits 24 and lower to get negtive number for int
// 111111111111111111111111
data |= ^0xffffff
}
return data, nil
}