libraries / Mitov / Mitov_LiquidCrystalDisplay.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_IQUID_CRYSTAL_DISPLAY_h
  11#define _MITOV_IQUID_CRYSTAL_DISPLAY_h
  12
  13#include <Mitov.h>
  14
  15namespace Mitov
  16{
  17//---------------------------------------------------------------------------
  18        class LiquidCrystalDisplay;
  19//---------------------------------------------------------------------------
  20        class LiquidCrystalElementBasic : public OpenWire::Component
  21        {
  22                typedef OpenWire::Component inherited;
  23
  24        public: // Public for the print access
  25                LCD     *FLcd;
  26
  27        public:
  28                virtual void DisplayInit() {}
  29                virtual void DisplayStart() {}
  30
  31        public:
  32                LiquidCrystalElementBasic( Mitov::LiquidCrystalDisplay &AOwner );
  33
  34        };
  35//---------------------------------------------------------------------------
  36        class LiquidCrystalElementBasicPositionedField : public LiquidCrystalElementBasic
  37        {
  38                typedef Mitov::LiquidCrystalElementBasic inherited;
  39
  40        public:
  41                unsigned long Column = 0;
  42                unsigned long Row = 0;
  43
  44        public:
  45                using inherited::inherited;
  46
  47        };
  48//---------------------------------------------------------------------------
  49        class LiquidCrystalElementBasicPositionedWidthField : public LiquidCrystalElementBasicPositionedField
  50        {
  51                typedef Mitov::LiquidCrystalElementBasicPositionedField inherited;
  52
  53        public:
  54                unsigned long Width = 16;
  55
  56        public:
  57                void ClearLine()
  58                {
  59                        FLcd->setCursor( Column, Row );
  60                }
  61
  62                void NewLine( int AClearSize )
  63                {
  64                        for( int i = 0; i < Width - AClearSize; ++ i )
  65                                FLcd->print( ' ' );
  66                }
  67
  68        public:
  69                using inherited::inherited;
  70
  71        };
  72//---------------------------------------------------------------------------
  73        class LiquidCrystalElementTextField : public LiquidCrystalElementBasicPositionedWidthField
  74        {
  75                typedef Mitov::LiquidCrystalElementBasicPositionedWidthField inherited;
  76
  77        public:
  78                String  InitialValue;
  79
  80        protected:
  81                virtual void SystemStart() override
  82                {
  83                        inherited::SystemStart();
  84                        ClearLine();
  85                        int AClearSize = FLcd->print( InitialValue );
  86                        NewLine( AClearSize );
  87                }
  88
  89        public:
  90                using inherited::inherited;
  91
  92        };
  93//---------------------------------------------------------------------------
  94        template<typename T> class LiquidCrystalElementBasicPositionedWidthTypedField : public LiquidCrystalElementBasicPositionedWidthField
  95        {
  96                typedef Mitov::LiquidCrystalElementBasicPositionedWidthField inherited;
  97
  98        public:
  99                T       InitialValue;
 100
 101        public:
 102                OpenWire::SinkPin       InputPin;
 103
 104        protected:
 105                virtual int PrintValue( T AValue ) = 0;
 106
 107                void ClearPrintValue( T AValue )
 108                {
 109                        InitialValue = AValue;
 110//                      Serial.println( AValue );
 111                        ClearLine();
 112                        int AClearSize = PrintValue( AValue );
 113                        NewLine( AClearSize );
 114                }
 115
 116        protected:
 117                virtual void SystemStart() override
 118                {
 119                        inherited::SystemStart();
 120//                      char AText[ 50 ];
 121//                      itoa( InitialValue, AText, Base );
 122//                      int AClearSize = FLcd->print( AText );
 123                        ClearPrintValue( InitialValue );
 124                }
 125
 126                void DoReceiveData( void *_Data )
 127                {
 128                        ClearPrintValue( *(T*)_Data );
 129                }
 130
 131        public:
 132                LiquidCrystalElementBasicPositionedWidthTypedField( Mitov::LiquidCrystalDisplay &AOwner, T AInitialValue ) :
 133                        inherited( AOwner ),
 134                        InitialValue( AInitialValue )
 135                {
 136                        InputPin.SetCallback( this, (OpenWire::TOnPinReceive)&LiquidCrystalElementBasicPositionedWidthTypedField::DoReceiveData );
 137                }
 138
 139        };
 140//---------------------------------------------------------------------------
 141        class LiquidCrystalElementIntegerField : public LiquidCrystalElementBasicPositionedWidthTypedField<long>
 142        {
 143                typedef Mitov::LiquidCrystalElementBasicPositionedWidthTypedField<long> inherited;
 144
 145        public:
 146                int     Base = 10;
 147
 148        protected:
 149                virtual int PrintValue( long AValue ) override
 150                {
 151                        char AText[ 50 ];
 152                        itoa( AValue, AText, Base );
 153                        return FLcd->print( AText );
 154                }
 155
 156        public:
 157                LiquidCrystalElementIntegerField( Mitov::LiquidCrystalDisplay &AOwner ) :
 158                        inherited( AOwner, 0 )
 159                {
 160                }
 161
 162        };
 163//---------------------------------------------------------------------------
 164        class LiquidCrystalElementAnalogField : public LiquidCrystalElementBasicPositionedWidthTypedField<float>
 165        {
 166                typedef Mitov::LiquidCrystalElementBasicPositionedWidthTypedField<float> inherited;
 167
 168        public:
 169                int     MinWidth = 1;
 170                int     Precision = 3;
 171
 172        protected:
 173                virtual int PrintValue( float AValue ) override
 174                {
 175                        char AText[ 50 ];
 176                        dtostrf( AValue,  MinWidth, Precision, AText );
 177                        return FLcd->print( AText );
 178                }
 179
 180        public:
 181                LiquidCrystalElementAnalogField( Mitov::LiquidCrystalDisplay &AOwner ) :
 182                        inherited( AOwner, 0 )
 183                {
 184                }
 185
 186        };
 187//---------------------------------------------------------------------------
 188        class LiquidCrystalElementDigitalField : public LiquidCrystalElementBasicPositionedWidthTypedField<bool>
 189        {
 190                typedef Mitov::LiquidCrystalElementBasicPositionedWidthTypedField<bool> inherited;
 191
 192        public:
 193                String  TrueValue = "true";
 194                String  FalseValue = "false";
 195
 196        protected:
 197                virtual int PrintValue( bool AValue ) override
 198                {
 199                        if( AValue )
 200                                return FLcd->print( TrueValue );
 201
 202                        return FLcd->print( FalseValue );
 203                }
 204
 205        public:
 206                LiquidCrystalElementDigitalField( Mitov::LiquidCrystalDisplay &AOwner ) :
 207                        inherited( AOwner, 0 )
 208                {
 209                }
 210
 211        };
 212//---------------------------------------------------------------------------
 213        // TODO: Implement setCursor() and createChar()
 214        class LiquidCrystalDisplay : public OpenWire::Component
 215        {
 216                typedef OpenWire::Component inherited;
 217
 218        public:
 219                OpenWire::SinkPin       ScrollLeftInputPin;
 220                OpenWire::SinkPin       ScrollRightInputPin;
 221                OpenWire::SinkPin       ClearInputPin;
 222                OpenWire::SinkPin       HomeInputPin;
 223
 224        public:
 225                bool Enabled : 1;
 226                bool AutoScroll : 1;
 227                bool RightToLeft : 1;
 228                bool ShowCursor : 1;
 229                bool Blink : 1;
 230
 231        protected:
 232                uint8_t FCols;
 233                uint8_t FRows;
 234                uint8_t FCursorLine = 0;
 235                uint8_t FCursorPos = 0;
 236
 237        public: // Public for the print access
 238                LCD     *FLcd;
 239                Mitov::SimpleList<LiquidCrystalElementBasic *>  FElements;
 240
 241        public:
 242                void ClearLine()
 243                {
 244                        FLcd->setCursor( 0, FCursorLine );
 245                        FCursorPos = 0;
 246//                      for( int i = 0; i < FCols; ++ i )
 247//                              FLcd->print( ' ' );
 248
 249//                      FLcd->setCursor( 0, FCursorLine );
 250                }
 251
 252                void NewLine( int AClearSize )
 253                {
 254                        for( int i = 0; i < FCols - FCursorPos - AClearSize; ++ i )
 255                                FLcd->print( ' ' );
 256
 257                        ++FCursorLine;
 258                        FCursorPos = 0;
 259                        if( FCursorLine >= FRows )
 260                                FCursorLine = 0;
 261
 262//                      FLcd->setCursor( 0, FCursorLine );
 263                }
 264
 265                void MoveChars( int ACount )
 266                {
 267                        ++FCursorPos;
 268                }
 269
 270        public:
 271                void SetEnabled( bool AValue )
 272                {
 273                        if( Enabled == AValue )
 274                                return;
 275
 276                        Enabled = AValue;
 277                        UpdateEnabled();
 278                }
 279
 280                void SetAutoScroll( bool AValue )
 281                {
 282                        if( AutoScroll == AValue )
 283                                return;
 284
 285                        AutoScroll = AValue;
 286                        UpdateAutoScroll();
 287                }
 288
 289                void SetRightToLeft( bool AValue )
 290                {
 291                        if( RightToLeft == AValue )
 292                                return;
 293
 294                        RightToLeft = AValue;
 295                        UpdateRightToLeft();
 296                }
 297
 298                void SetShowCursor( bool AValue )
 299                {
 300                        if( ShowCursor == AValue )
 301                                return;
 302
 303                        ShowCursor = AValue;
 304                        UpdateShowCursor();
 305                }
 306
 307                void SetBlink( bool AValue )
 308                {
 309                        if( Blink == AValue )
 310                                return;
 311
 312                        Blink = AValue;
 313                        UpdateBlink();
 314                }
 315
 316        protected:
 317                void UpdateEnabled()
 318                {
 319                        if( Enabled )
 320                                FLcd->display();
 321
 322                        else
 323                                FLcd->noDisplay();
 324
 325                }
 326
 327                void UpdateAutoScroll()
 328                {
 329                        if( AutoScroll )
 330                                FLcd->autoscroll();
 331
 332                        else
 333                                FLcd->noAutoscroll();
 334
 335                }
 336
 337                void UpdateRightToLeft()
 338                {
 339                        if( RightToLeft )
 340                                FLcd->rightToLeft();
 341
 342                        else
 343                                FLcd->leftToRight();
 344
 345                }
 346
 347                void UpdateShowCursor()
 348                {
 349                        if( ShowCursor )
 350                                FLcd->cursor();
 351
 352                        else
 353                                FLcd->noCursor();
 354
 355                }
 356
 357                void UpdateBlink()
 358                {
 359                        if( Blink )
 360                                FLcd->blink();
 361
 362                        else
 363                                FLcd->noBlink();
 364
 365                }
 366
 367                void DoScrollLeft( void * )
 368                {
 369                        FLcd->scrollDisplayLeft();
 370                }
 371
 372                void DoScrollRight( void * )
 373                {
 374                        FLcd->scrollDisplayRight();
 375                }
 376
 377                void DoClear( void * )
 378                {
 379                        FLcd->clear();
 380                }
 381
 382                void DoHome( void * )
 383                {
 384                        FLcd->home();
 385                }
 386
 387        public:
 388                virtual void SystemInit() override
 389                {
 390                        inherited::SystemInit();
 391
 392                        FLcd->begin( FCols, FRows );
 393                        UpdateEnabled();
 394                        UpdateAutoScroll();
 395                        UpdateRightToLeft();
 396                        UpdateShowCursor();
 397                        UpdateBlink();
 398
 399                        for( Mitov::SimpleList<LiquidCrystalElementBasic *>::iterator Iter = FElements.begin(); Iter != FElements.end(); ++Iter )
 400                                ( *Iter)->DisplayInit();
 401
 402//                      FLcd->setCursor(0,0);
 403                }
 404
 405                virtual void SystemStart() override
 406                {
 407                        inherited::SystemStart();
 408
 409                        for( Mitov::SimpleList<LiquidCrystalElementBasic *>::iterator Iter = FElements.begin(); Iter != FElements.end(); ++Iter )
 410                                ( *Iter)->DisplayStart();
 411                }
 412
 413        public:
 414                LiquidCrystalDisplay( LCD *ALcd, unsigned int ACols, unsigned int ARows ) :
 415                        FLcd( ALcd ),
 416                        FCols( ACols ),
 417                        FRows( ARows ),
 418                        Enabled( true ),
 419                        AutoScroll( false ),
 420                        RightToLeft( false ),
 421                        ShowCursor( false ),
 422                        Blink( false )
 423                {
 424                        ScrollLeftInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&LiquidCrystalDisplay::DoScrollLeft );
 425                        ScrollRightInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&LiquidCrystalDisplay::DoScrollRight );
 426                        ClearInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&LiquidCrystalDisplay::DoClear );
 427                        HomeInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&LiquidCrystalDisplay::DoHome );
 428                }
 429
 430/*
 431                virtual ~LiquidCrystalDisplay()
 432                {
 433                        delete FLcd;
 434                }
 435*/
 436        };
 437//---------------------------------------------------------------------------
 438        class LiquidCrystalDisplayI2C : public LiquidCrystalDisplay
 439        {
 440                typedef Mitov::LiquidCrystalDisplay inherited;
 441
 442        public:
 443                bool    Backlight = true;
 444
 445        public:
 446                void SetBacklight( bool AValue )
 447                {
 448                        if( Backlight == AValue )
 449                                return;
 450
 451                        Backlight = AValue;
 452                        UpdateBacklight();
 453                }
 454
 455        public:
 456                virtual void SystemInit() override
 457                {
 458                        inherited::SystemInit();
 459                        UpdateBacklight();
 460                }
 461
 462        public:
 463                void UpdateBacklight()
 464                {
 465                        if( Backlight )
 466                                inherited::FLcd->setBacklight( 255 );
 467
 468                        else
 469                                inherited::FLcd->setBacklight( 0 );
 470
 471                }
 472
 473        public:
 474                using inherited::inherited;
 475
 476        };
 477//---------------------------------------------------------------------------
 478        class LiquidCrystalElementDefineCustomCharacter : public LiquidCrystalElementBasic
 479        {
 480                typedef Mitov::LiquidCrystalElementBasic inherited;
 481
 482        protected:
 483                uint8_t FCharMap[ 8 ];
 484
 485                uint8_t FIndex;
 486
 487        public:
 488                virtual void DisplayInit() override
 489                {
 490                        FLcd->createChar( FIndex, FCharMap );
 491                }
 492
 493        public:
 494                LiquidCrystalElementDefineCustomCharacter( Mitov::LiquidCrystalDisplay &AOwner, uint8_t AIndex, uint8_t Byte0, uint8_t Byte1, uint8_t Byte2, uint8_t Byte3, uint8_t Byte4, uint8_t Byte5, uint8_t Byte6, uint8_t Byte7 ) :
 495                        inherited( AOwner ),
 496                        FIndex( AIndex )
 497                {
 498                        AOwner.FElements.push_back( this );
 499
 500                        FCharMap[ 0 ] = Byte0;
 501                        FCharMap[ 1 ] = Byte1;
 502                        FCharMap[ 2 ] = Byte2;
 503                        FCharMap[ 3 ] = Byte3;
 504                        FCharMap[ 4 ] = Byte4;
 505                        FCharMap[ 5 ] = Byte5;
 506                        FCharMap[ 6 ] = Byte6;
 507                        FCharMap[ 7 ] = Byte7;
 508                }
 509
 510        };
 511//---------------------------------------------------------------------------
 512        class LiquidCrystalElementCustomCharacterField : public LiquidCrystalElementBasicPositionedField
 513        {
 514                typedef Mitov::LiquidCrystalElementBasicPositionedField inherited;
 515
 516        public:
 517                long    Index = 0;
 518
 519        protected:
 520                bool    FModified = false;
 521
 522        public:
 523                void SetIndex( long     AValue )
 524                {
 525                        if( AValue > 7 )
 526                                AValue = 7;
 527
 528                        else if( AValue < 0 )
 529                                AValue = 0;
 530
 531                        if( Index == AValue )
 532                                return;
 533
 534                        Index = AValue;
 535                        FModified = true;
 536                }
 537
 538                void SetColumn( unsigned long AValue )
 539                {
 540                        if( AValue < 0 )
 541                                AValue = 0;
 542
 543                        if( Column == AValue )
 544                                return;
 545
 546                        Column = AValue;
 547                        FModified = true;
 548                }
 549
 550                void SetRow( unsigned long AValue )
 551                {
 552                        if( AValue < 0 )
 553                                AValue = 0;
 554
 555                        if( Row == AValue )
 556                                return;
 557
 558                        Row = AValue;
 559                        FModified = true;
 560                }
 561
 562        public:
 563                virtual void DisplayStart() override
 564                {
 565                        DisplayCharacter();
 566                }
 567
 568                virtual void SystemLoopBegin( unsigned long currentMicros ) override
 569                {
 570                        inherited::SystemLoopBegin( currentMicros );
 571                        if( FModified )
 572                        {
 573                                DisplayCharacter();
 574                                FModified = false;
 575                        }
 576                }
 577
 578        protected:
 579                void DisplayCharacter()
 580                {
 581                        FLcd->setCursor( Column, Row );
 582                        FLcd->write( (uint8_t) Index );
 583                }
 584
 585        public:
 586                LiquidCrystalElementCustomCharacterField( Mitov::LiquidCrystalDisplay &AOwner ) :
 587                        inherited( AOwner )
 588                {
 589                        AOwner.FElements.push_back( this );
 590                }
 591
 592        };
 593//---------------------------------------------------------------------------
 594        template<typename T_LCD, T_LCD *T_LCD_INSTANCE, typename T> class LiquidCrystalDisplayInput : public Mitov::CommonSink
 595        {
 596                typedef Mitov::CommonSink       inherited;
 597
 598        protected:
 599                virtual void DoReceive( void *_Data ) override
 600                {
 601                        T_LCD_INSTANCE->ClearLine();
 602                        int AClearSize = T_LCD_INSTANCE->FLcd->print( *(T*)_Data );
 603                        T_LCD_INSTANCE->NewLine( AClearSize );
 604                }
 605        };
 606//---------------------------------------------------------------------------
 607        template<typename T_LCD, T_LCD *T_LCD_INSTANCE> class LiquidCrystalDisplayCharInput : public Mitov::CommonSink
 608        {
 609                typedef Mitov::CommonSink       inherited;
 610
 611        protected:
 612                virtual void DoReceive( void *_Data ) override
 613                {
 614//                      Serial.print( (char*)_Data );
 615//                      if( *(byte*)_Data < ' ' )
 616//                              return;
 617
 618                        if( *(char*)_Data == '\r' )
 619                                T_LCD_INSTANCE->NewLine( 0 );
 620
 621                        else if( *(char*)_Data == '\n' )
 622                                T_LCD_INSTANCE->ClearLine();
 623
 624                        else if( *(char*)_Data >= ' ' )
 625                        {
 626                                int AClearSize = T_LCD_INSTANCE->FLcd->print( *(char*)_Data );
 627                                T_LCD_INSTANCE->MoveChars( AClearSize );
 628                        }
 629//                      int AClearSize = T_LCD_INSTANCE->FLcd->print( (char*)_Data );
 630//                      T_LCD_INSTANCE->NewLine( AClearSize );
 631                }
 632        };
 633//---------------------------------------------------------------------------
 634        template<typename T_LCD, T_LCD *T_LCD_INSTANCE> class LiquidCrystalDisplayStringInput : public Mitov::CommonSink
 635        {
 636                typedef Mitov::CommonSink       inherited;
 637
 638        protected:
 639                virtual void DoReceive( void *_Data )
 640                {
 641//                      Serial.print( (char*)_Data );
 642//                      if( *(byte*)_Data < ' ' )
 643//                              return;
 644
 645                        T_LCD_INSTANCE->ClearLine();
 646                        int AClearSize = T_LCD_INSTANCE->FLcd->print( (char*)_Data );
 647                        T_LCD_INSTANCE->NewLine( AClearSize );
 648                }
 649        };
 650//---------------------------------------------------------------------------
 651        template<typename T_LCD, T_LCD *T_LCD_INSTANCE, typename T_OBJECT> class LiquidCrystalDisplayObjectInput : public Mitov::CommonSink
 652        {
 653                typedef Mitov::CommonSink       inherited;
 654
 655        protected:
 656                virtual void DoReceive( void *_Data )
 657                {
 658                        T_LCD_INSTANCE->ClearLine();
 659                        int AClearSize = T_LCD_INSTANCE->FLcd->print( ((T_OBJECT *)_Data)->ToString().c_str() );
 660                        T_LCD_INSTANCE->NewLine( AClearSize );
 661                }
 662        };
 663//---------------------------------------------------------------------------
 664//---------------------------------------------------------------------------
 665//---------------------------------------------------------------------------
 666//---------------------------------------------------------------------------
 667        LiquidCrystalElementBasic::LiquidCrystalElementBasic( LiquidCrystalDisplay &AOwner ) :
 668                FLcd( AOwner.FLcd )
 669        {
 670        }
 671//---------------------------------------------------------------------------
 672}
 673
 674#endif