libraries / Mitov / Mitov_HX711_Weight.hon commit Added link to project report (97a3ba0)
   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