libraries / Mitov / Mitov_UltrasonicRanger.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_ULTRASONIC_RANGE_h
  11#define _MITOV_ULTRASONIC_RANGE_h
  12
  13#include <Mitov.h>
  14
  15namespace Mitov
  16{
  17        enum UltrasonicRangerUnits { rdTime, rdCm, rdInch };
  18
  19        class UltrasonicRanger : public Mitov::CommonSource, public Mitov::ClockingSupport
  20        {
  21                typedef Mitov::CommonSource inherited;
  22
  23                enum State { sStartUp, sStartDown, sListeningEdgeUp, sListeningEdgeDown, sEchoDetected, sPause };
  24
  25        public:
  26                OpenWire::SinkPin       EchoInputPin;
  27                OpenWire::SourcePin     PingOutputPin;
  28                OpenWire::SourcePin     TimeoutOutputPin;
  29
  30        public:
  31                int             Timeout = 1000;
  32                int             PingTime = 2;
  33                int             PauseTime = 100;
  34                float   TimeoutValue = -1;
  35
  36                UltrasonicRangerUnits   Units : 2;
  37
  38                bool    Enabled : 1;
  39
  40        protected:
  41                State                   FState : 3;
  42                bool                    FClocked : 1;
  43
  44                unsigned long   FStartTime;
  45                unsigned long   FEchoStartTime;
  46                unsigned long   FEndTime;
  47
  48        protected:
  49                void DoReceive( void *_Data )
  50                {
  51                        if( ( FState != sListeningEdgeUp ) && ( FState != sListeningEdgeDown ) )
  52                                return;
  53
  54                        bool AValue = *(bool *)_Data;
  55                        if( FState == sListeningEdgeDown )
  56                        {
  57                          if( AValue )
  58                                  return;
  59
  60                                FEndTime = micros();
  61                                FState = sEchoDetected;
  62                        }
  63
  64                        else
  65                        {
  66                          if( ! AValue )
  67                                  return;
  68
  69                          FState = sListeningEdgeDown;
  70                          FEchoStartTime = micros();
  71                        }
  72
  73                }
  74
  75        protected:
  76                virtual void SystemLoopBegin( unsigned long currentMicros ) override
  77                {
  78                        if( !Enabled )
  79                                return;
  80
  81                        switch ( FState )
  82                        {
  83                                case sPause:
  84                                {
  85                                        if( ( currentMicros - FStartTime ) < ((unsigned long)PauseTime ) * 1000 )
  86                                                return;
  87
  88                                        if( ClockInputPin.IsConnected() )
  89                                                if( ! FClocked )
  90                                                        return;
  91
  92                                        FClocked = false;
  93                                }
  94
  95                                case sStartUp:
  96                                {
  97//                                      Serial.println( "start" );
  98                                        bool AValue = true;
  99                                        PingOutputPin.Notify( &AValue );
 100                                        FStartTime = currentMicros;
 101                                        FState = sStartDown;
 102                                        break;
 103                                }
 104
 105                                case sStartDown:
 106                                {
 107                                        if( ( currentMicros - FStartTime ) < PingTime )
 108                                                return;
 109
 110                                        bool AValue = false;
 111                                        PingOutputPin.Notify( &AValue );
 112                                        FStartTime = currentMicros;
 113                                        FState = sListeningEdgeUp;
 114                                        break;
 115                                }
 116
 117                                case sListeningEdgeUp:
 118                                case sListeningEdgeDown:
 119                                {
 120                                        if( ( currentMicros - FStartTime ) < ((unsigned long)Timeout ) * 1000 )
 121                                                return;
 122
 123                                        OutputPin.Notify( &TimeoutValue );
 124                                        bool ABoolValue = true;
 125                                        TimeoutOutputPin.Notify( &ABoolValue );
 126                                        FState = sPause;
 127                                        break;
 128                                }
 129
 130                                case sEchoDetected:
 131                                {
 132                                        unsigned long APeriod = FEndTime - FEchoStartTime;
 133                                        float AValue;
 134                                        switch( Units )
 135                                        {
 136                                                case rdTime:
 137                                                        AValue = APeriod;
 138                                                        break;
 139
 140                                                case rdCm:
 141                                                        AValue = ((float)APeriod) / 29 / 2; // / 58.2;
 142                                                        break;
 143
 144                                                case rdInch:
 145                                                        AValue = ((float)APeriod) / 74 / 2;
 146                                                        break;
 147                                        }
 148
 149                                        OutputPin.Notify( &AValue );
 150                                        bool ABoolValue = false;
 151                                        TimeoutOutputPin.Notify( &ABoolValue );
 152                                        FState = sPause;
 153                                        break;
 154                                }
 155                        }
 156                }
 157
 158                virtual void DoClockReceive( void *_Data ) override
 159                {
 160                        FClocked = true;
 161                }
 162
 163        public:
 164                UltrasonicRanger() :
 165                        FState( sStartUp ),
 166                        Enabled( true ),
 167                        Units( rdCm ),
 168                        FClocked( false )
 169                {
 170                        EchoInputPin.SetCallback( MAKE_CALLBACK( UltrasonicRanger::DoReceive ));
 171                }
 172
 173        };
 174}
 175
 176#endif