libraries / Mitov / Mitov_7Segment.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_7SEGMENT_h
  11#define _MITOV_7SEGMENT_h
  12
  13#include <Mitov.h>
  14#include <Mitov_BasicDisplay.h>
  15
  16namespace Mitov
  17{
  18        const byte C_Segments[16] =
  19        {
  20                        0b0111111,  // = 0
  21                        0b0000110,  // = 1
  22                        0b1011011,  // = 2
  23                        0b1001111,  // = 3
  24                        0b1100110,  // = 4
  25                        0b1101101,  // = 5
  26                        0b1111101,  // = 6
  27                        0b0000111,  // = 7
  28                        0b1111111,  // = 8
  29                        0b1101111,  // = 9
  30                        0b1110111,  // = A
  31                        0b1111100,  // = B
  32                        0b1011000,  // = C
  33                        0b1011110,  // = D
  34                        0b1111001,  // = E
  35                        0b1110001   // = F
  36        };
  37//---------------------------------------------------------------------------
  38        template<typename T> class DisplayBasic7Segment : public Mitov::BasicDisplay<T>
  39        {
  40                typedef Mitov::BasicDisplay<T>  inherited;
  41
  42        public:
  43                Mitov::SimpleList<OpenWire::SourcePin>  SegmentPins;
  44
  45        public:
  46                bool InvertedSegments;
  47
  48        public:
  49                DisplayBasic7Segment() :
  50                        InvertedSegments( false )
  51                {
  52                        SegmentPins.SetCount(16);
  53                }
  54
  55        };
  56//---------------------------------------------------------------------------
  57        class Display7Segment : public Mitov::DisplayBasic7Segment<long>
  58        {
  59                typedef Mitov::DisplayBasic7Segment<long>       inherited;
  60
  61        protected:
  62                virtual void DoReceive( void *_Data )
  63                {
  64                        inherited::DoReceive( _Data );
  65                        UpdateDisplay();
  66                }
  67
  68                virtual void UpdateDisplay()
  69                {
  70                        int AValue = (Enabled) ? C_Segments[ FValue & 0xF ] : 0;
  71                        for( int i = 0; i < 16; ++i )
  72                        {
  73                                bool ABitValue = AValue & 1;
  74                                ABitValue ^= InvertedSegments;
  75                                SegmentPins[ i ].Notify( &ABitValue );
  76                                AValue >>= 1;
  77                        }
  78                }
  79
  80        };
  81//---------------------------------------------------------------------------
  82        template<typename T> class DisplayBasicDynamic7Segment : public Mitov::DisplayBasic7Segment<T>
  83        {
  84                typedef Mitov::DisplayBasic7Segment<T>  inherited;
  85
  86        public:
  87                Mitov::SimpleList<OpenWire::SourcePin>  DigitPins;
  88
  89        public:
  90                unsigned long   RefreshInterval = 1000;
  91                bool                    InvertedDigits = false;
  92
  93        protected:
  94                unsigned long   FLastTime = 0;
  95                int                             FDigit = 0;
  96
  97        protected:
  98                virtual int     GetSegmentsValue() = 0;
  99
 100                virtual void UpdateDisplay()
 101                {
 102                        int AValue;
 103                        if( inherited::Enabled )
 104                                AValue = GetSegmentsValue();
 105
 106                        else
 107                                AValue = 0;
 108
 109                        for( int i = 0; i < DigitPins.size(); ++i )
 110                        {
 111                                bool ABitValue = false;
 112                                ABitValue ^= InvertedDigits;
 113                                DigitPins[ i ].Notify( &ABitValue );
 114                        }
 115
 116                        for( int i = 0; i < 16; ++i )
 117                        {
 118                                bool ABitValue = AValue & 1;
 119                                ABitValue ^= inherited::InvertedSegments;
 120                                inherited::SegmentPins[ i ].Notify( &ABitValue );
 121                                AValue >>= 1;
 122                        }
 123
 124                        AValue = FDigit;
 125                        for( int i = 0; i < DigitPins.size(); ++i )
 126                        {
 127                                bool ABitValue = ( AValue-- == 0 );
 128                                ABitValue ^= InvertedDigits;
 129                                DigitPins[ i ].Notify( &ABitValue );
 130                        }
 131                }
 132
 133        public:
 134                virtual void SystemLoopBegin( unsigned long currentMicros )
 135                {
 136                        if( ( currentMicros - FLastTime ) < RefreshInterval )
 137                                return;
 138
 139                        ++FDigit;
 140
 141                        if( FDigit >= DigitPins.size() )
 142                                FDigit = 0;
 143
 144                        FLastTime = currentMicros;
 145                        UpdateDisplay();
 146                }
 147
 148        };
 149//---------------------------------------------------------------------------
 150        class DisplayIntegerDynamic7Segment : public Mitov::DisplayBasicDynamic7Segment<long>
 151        {
 152                typedef Mitov::DisplayBasicDynamic7Segment<long>        inherited;
 153
 154        public:
 155                bool    LeadingZeroes = false;
 156
 157        protected:
 158                Mitov::SimpleList<unsigned int> FPowers;
 159                long    FMaxValue; // The biggest possible to display value
 160                long    FMinValue; // The smallest possible to display value
 161
 162        protected:
 163                virtual int     GetSegmentsValue()
 164                {
 165                        int AValue;
 166                        if( FValue > FMaxValue )
 167                                AValue = 0b0000001;
 168
 169                        else if( FValue < FMinValue )
 170                                AValue = 0b0001000;
 171
 172                        else
 173                        {
 174                                AValue = ( (int)abs( FValue ) ) / FPowers[ FDigit ];
 175                                if( ( FValue < 0 ) && ( FDigit > 0 ))
 176                                {
 177                                        if( ( !LeadingZeroes ) && ( AValue == 0 ) )
 178                                        {
 179                                                int APreviousValue = ( -FValue ) / FPowers[ FDigit - 1 ];
 180                                                if( APreviousValue > 0 )
 181                                                        AValue = 0b1000000;
 182
 183                                                else
 184                                                        AValue = 0;
 185
 186                                        }
 187                                        else
 188                                        {
 189                                                if( FDigit == DigitPins.size() - 1 )
 190                                                        AValue = 0b1000000;
 191
 192                                                else
 193                                                {
 194                                                        int ADigitValue = AValue % 10;
 195                                                        AValue = C_Segments[ ADigitValue ];
 196                                                }
 197                                        }
 198                                }
 199                                else
 200                                {
 201                                        if( ( !LeadingZeroes ) && ( AValue == 0 ) )
 202                                                AValue = 0;
 203
 204                                        else
 205                                        {
 206                                                int ADigitValue = AValue % 10;
 207                                                AValue = C_Segments[ ADigitValue ];
 208                                        }
 209                                }
 210                        }
 211
 212                        return AValue;
 213                }
 214
 215                virtual void SystemInit()
 216                {
 217                        FPowers.SetCount( DigitPins.size() );
 218                        for( int i = 0; i < DigitPins.size(); ++i )
 219                                FPowers[ i ] = pow( 10, i ) + 0.5;
 220
 221                        FMaxValue = pow( 10, DigitPins.size() ) + 0.5 - 1;
 222                        FMinValue = -( pow( 10, DigitPins.size() - 1 ) + 0.5 - 1 );
 223
 224                        inherited::SystemInit();
 225                }
 226
 227        };
 228//---------------------------------------------------------------------------
 229        class DisplayAnalogDynamic7Segment : public Mitov::DisplayBasicDynamic7Segment<float>
 230        {
 231                typedef Mitov::DisplayBasicDynamic7Segment<float>       inherited;
 232
 233        public:
 234                unsigned char   Precision = 2;
 235
 236        protected:
 237                char    *FBuffer;
 238                char    *FStartChar;
 239                unsigned char   FTextLength;
 240                unsigned char   FFirstPos;
 241
 242                char                    FDecimalPointPos;
 243
 244        protected:
 245                virtual int     GetSegmentsValue()
 246                {
 247                        int AValue;
 248                        int ANumDigits = DigitPins.size();
 249                        if( ! FStartChar )
 250                        {
 251                                FStartChar = dtostrf( FValue, 1, Precision, FBuffer );
 252//                              Serial.println( FStartChar );
 253                                String AText( FStartChar );
 254                                FTextLength = AText.length(); // strlen( FStartChar ); 
 255//                              FTextLength = strlen( FStartChar ); 
 256//                              Serial.println( FTextLength );
 257                                FDecimalPointPos = AText.indexOf( '.' );
 258                                if( Precision == 0 )
 259                                {
 260                                        if( FTextLength <= ANumDigits )
 261                                                FFirstPos = FTextLength - 1;
 262
 263                                        else
 264                                                FFirstPos = ANumDigits - 1;
 265
 266                                
 267//                                      Serial.println( FStartChar );
 268//                                      Serial.println( FTextLength );
 269//                                      Serial.println( FFirstPos );
 270//                                      Serial.println( FDecimalPointPos );
 271                                }
 272
 273                                else
 274                                {
 275                                        if( FTextLength <= ANumDigits + 1 )
 276                                                FFirstPos = FTextLength - 1;
 277
 278                                        else
 279                                                FFirstPos = ANumDigits + 1 - 1;
 280                                }                               
 281
 282//                              Serial.println( FFirstPos );
 283                        }
 284
 285                        int ACorrectedTextLength = FTextLength;
 286                        if( Precision > 0 )
 287                                --ACorrectedTextLength;
 288
 289                        if( ( ACorrectedTextLength - Precision ) > ANumDigits )
 290                        {
 291                                if( FValue > 0 )
 292                                        AValue = 0b0000001; // Overflow +
 293
 294                                else
 295                                        AValue = 0b0001000; // Overflow -
 296                        }
 297
 298                        else
 299                        {
 300                                int ATextPos = FFirstPos - FDigit;
 301                                if( ATextPos < 0 )
 302                                        AValue = 0;
 303
 304                                else
 305                                {
 306                                        if( ATextPos < 0 )
 307                                                return( 0 );
 308
 309                                        bool ADecimalPoint = ( FStartChar[ ATextPos ] == '.' );
 310                                        if( ATextPos <= FDecimalPointPos )
 311                                                --ATextPos;
 312
 313//                                      if( ADecimalPoint )
 314//                                              --ATextPos;
 315
 316                                        if( ATextPos < 0 )
 317                                                return( 0 );
 318
 319/*
 320                                        if( FDigit == 0 )
 321                                        {
 322                                                Serial.println( FStartChar );
 323                                                Serial.println( ATextPos );
 324                                        }
 325*/
 326                                        if( FStartChar[ ATextPos ] == '-' )
 327                                                AValue = 0b1000000;
 328
 329                                        else
 330                                        {
 331                                                AValue = FStartChar[ ATextPos ] - '0';
 332                                                AValue = C_Segments[ AValue ];
 333                                        }
 334
 335                                        if( ADecimalPoint )
 336                                                AValue |= 0x80;
 337
 338                                }
 339                        }
 340
 341                        return AValue;
 342                }
 343
 344                virtual void DoReceive( void *_Data )
 345                {
 346                        FStartChar = NULL;
 347                        inherited::DoReceive( _Data );
 348                }
 349
 350        public:
 351                virtual void SystemInit()
 352                {
 353                        FBuffer = new char[ 15 + Precision ];
 354                        inherited::SystemInit();
 355                }
 356
 357/*
 358                virtual ~DisplayAnalogDynamic7Segment()
 359                {
 360                        delete [] FBuffer;
 361                }
 362*/
 363        };
 364
 365}
 366
 367#endif