1////////////////////////////////////////////////////////////////////////////////
2// //
3// This software is supplied under the terms of a license agreement or //
4// nondisclosure agreement with Mitov Software and may not be copied //
5// or disclosed except in accordance with the terms of that agreement. //
6// Copyright(c) 2002-2016 Mitov Software. All Rights Reserved. //
7// //
8////////////////////////////////////////////////////////////////////////////////
9
10#ifndef _MITOV_HX711_WEIGHT_h
11#define _MITOV_HX711_WEIGHT_h
12
13#include <Mitov.h>
14
15namespace Mitov
16{
17 template<int T_CLOCK_PIN, int T_DATA_PIN> class HX711_Weight : public Mitov::CommonSource, public Mitov::ClockingSupport
18 {
19 typedef Mitov::CommonSource inherited;
20
21 public:
22 OpenWire::SinkPin ZeroInputPin;
23 OpenWire::SinkPin CalibrateInputPin;
24
25 public:
26 float ScaleDivider = 1.0f;
27 float Offset = 0.0f;
28
29 bool UseChannelB : 1;
30 bool Gain128 : 1;
31 bool Powered : 1;
32
33 int32_t Average = 1;
34
35 public:
36 void SetScaleDivider( float AValue )
37 {
38 if( ScaleDivider == AValue )
39 return;
40
41 ScaleDivider = AValue;
42 SendOutput();
43 }
44
45 void SetOffset( float AValue )
46 {
47 if( Offset == AValue )
48 return;
49
50 Offset = AValue;
51 SendOutput();
52 }
53
54 void SetUseChannelB( bool AValue )
55 {
56 if( UseChannelB == AValue )
57 return;
58
59 UseChannelB = AValue;
60 UpdateGain();
61 }
62
63 void SetGain128( bool AValue )
64 {
65 if( Gain128 == AValue )
66 return;
67
68 Gain128 = AValue;
69 UpdateGain();
70 }
71
72 void SetAverage( int32_t AValue )
73 {
74 if( AValue < 1 )
75 Average = 1;
76
77 else
78 Average = AValue;
79
80 }
81
82 void SetPowered( bool AValue )
83 {
84 if( Powered == AValue )
85 return;
86
87 Powered = AValue;
88 UpdatePower();
89 }
90
91 protected:
92 bool FNeedsRead = false;
93 float FCurrentValue = 0.0f;
94
95 protected:
96 virtual void SystemInit() override
97 {
98 pinMode( T_CLOCK_PIN, OUTPUT );
99 UpdatePower();
100 inherited::SystemInit();
101 }
102
103 virtual void SystemLoopBegin( unsigned long currentMicros ) override
104 {
105 if( FNeedsRead || ( ! ClockInputPin.IsConnected() ))
106 ReadSensor();
107
108 inherited::SystemLoopBegin( currentMicros );
109 }
110
111 protected:
112 void ReadSensor()
113 {
114 if( OutputPin.IsConnected() )
115 {
116 if( Powered )
117 {
118// if( SensorDataInputPin.Value )
119 if( digitalRead( T_DATA_PIN ) == HIGH )
120 {
121 FNeedsRead = true;
122 return;
123 }
124
125 uint32_t AAccumulator = 0;
126 for( int i = 0; i < Average; ++i )
127 AAccumulator += ReadSensorOnes();
128
129 FCurrentValue = AAccumulator / Average;
130 FNeedsRead = false;
131 }
132
133 SendOutput();
134 }
135 }
136
137 uint32_t ReadSensorOnes()
138 {
139 while( digitalRead( T_DATA_PIN ) == HIGH )
140 ;
141
142 uint32_t AValue = 0;
143 for( int i = 0; i < 24; ++i )
144 {
145 AValue <<= 1;
146 digitalWrite( T_CLOCK_PIN, HIGH );
147// SensorClockOutputPin.SendValue( true );
148
149 if( digitalRead( T_DATA_PIN ) == HIGH )
150 AValue |= 1;
151
152 digitalWrite( T_CLOCK_PIN, LOW );
153// SensorClockOutputPin.SendValue( false );
154 }
155
156// Serial.println( AValue );
157 int ACount;
158 if( UseChannelB )
159 ACount = 2;
160
161 else if( Gain128 )
162 ACount = 1;
163
164 else
165 ACount = 3;
166
167 // set the channel and the gain factor for the next reading using the clock pin
168 for (int i = 0; i < ACount; i++)
169 {
170 digitalWrite( T_CLOCK_PIN, HIGH );
171 digitalWrite( T_CLOCK_PIN, LOW );
172// SensorClockOutputPin.SendValue( true );
173// SensorClockOutputPin.SendValue( false );
174 }
175
176 return AValue;
177 }
178
179 void SendOutput()
180 {
181 float AValue = ( FCurrentValue + Offset ) / ScaleDivider;
182 OutputPin.Notify( &AValue );
183 }
184
185 void UpdateGain()
186 {
187 if( ! Powered )
188 return;
189
190 digitalWrite( T_CLOCK_PIN, LOW );
191// SensorClockOutputPin.SendValue( false );
192 ReadSensorOnes();
193 }
194
195 void UpdatePower()
196 {
197 digitalWrite( T_CLOCK_PIN, LOW );
198// SensorClockOutputPin.SendValue( false );
199 if( Powered )
200 UpdateGain();
201
202 else
203 digitalWrite( T_CLOCK_PIN, HIGH );
204// SensorClockOutputPin.SendValue( true );
205 }
206
207 protected:
208 virtual void DoClockReceive( void *_Data ) override
209 {
210 ReadSensor();
211 }
212
213 void DoZeroReceive( void *_Data )
214 {
215// Serial.print( "TEST---------------: " );
216 Offset = -FCurrentValue;
217// Serial.println( Offset );
218 }
219
220 void DoCalibrateReceive( void *_Data )
221 {
222 ScaleDivider = ( FCurrentValue + Offset );
223 if( ! ScaleDivider )
224 ScaleDivider = 1.0;
225 }
226
227 public:
228 HX711_Weight() :
229 UseChannelB( false ),
230 Gain128( false ),
231 FNeedsRead( false ),
232 Powered( true )
233 {
234 ZeroInputPin.SetCallback( MAKE_CALLBACK( HX711_Weight::DoZeroReceive ));
235 CalibrateInputPin.SetCallback( MAKE_CALLBACK( HX711_Weight::DoCalibrateReceive ));
236 }
237
238 };
239}
240
241#endif