libraries / Mitov / Mitov_Display4DSystems.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_DISPLAY_4D_SYSTEMS_h
  11#define _MITOV_DISPLAY_4D_SYSTEMS_h
  12
  13#include <Mitov.h>
  14#include <genieArduino.h>
  15
  16namespace Mitov
  17{
  18
  19
  20/*
  21        void myGenieEventHandler(void)
  22        {
  23                Serial.println( "myGenieEventHandler" );
  24        }
  25*/
  26        class Display4DSystems;
  27//---------------------------------------------------------------------------
  28        class ViSiGenieBasicObject : public OpenWire::Object
  29        {
  30        protected:
  31                Display4DSystems &FOwner;
  32
  33        public:
  34                virtual void Start() {}
  35                virtual void Process() {}
  36
  37        public:
  38                ViSiGenieBasicObject( Display4DSystems &AOwner );
  39
  40        };
  41//---------------------------------------------------------------------------
  42        class ViSiGenieBasicOutObject
  43        {
  44        public:
  45                virtual bool ProcessOut( Genie &AGenie, genieFrame &Event ) = 0;
  46
  47        public:
  48                ViSiGenieBasicOutObject( Display4DSystems &AOwner );
  49
  50        };
  51//---------------------------------------------------------------------------
  52        template<int V_OBJECT, int V_INDEX> class ViSiGenieBasicTypedOutObject : public ViSiGenieBasicOutObject
  53        {
  54                typedef ViSiGenieBasicOutObject inherited;
  55
  56        protected:
  57                virtual void PrcessInValue( uint16_t AValue ) = 0;
  58
  59        public:
  60                virtual bool ProcessOut( Genie &AGenie, genieFrame &Event ) override
  61                {
  62//                      Serial.println( "ProcessOut" );
  63                        if( Event.reportObject.cmd == GENIE_REPORT_EVENT )
  64                        {
  65/*
  66                                Serial.println( "GENIE_REPORT_EVENT" );
  67                                Serial.print( Event.reportObject.object );
  68                                Serial.print( " - " );
  69                                Serial.println( Event.reportObject.index );
  70*/
  71                                if( Event.reportObject.object == V_OBJECT )
  72                                        if( Event.reportObject.index == V_INDEX )
  73                                        {
  74                                                uint16_t AValue = AGenie.GetEventData(&Event);
  75//                                              Serial.println( AValue );
  76                                                PrcessInValue( AValue );
  77
  78                                                return true;
  79                                        }
  80
  81                                return false;
  82                        }
  83                }
  84
  85
  86        public:
  87                using inherited::inherited;
  88
  89        };
  90//---------------------------------------------------------------------------
  91        template<int V_OBJECT, int V_INDEX> class ViSiGenieTypedCharOut : public ViSiGenieBasicTypedOutObject<V_OBJECT, V_INDEX>
  92        {
  93                typedef ViSiGenieBasicTypedOutObject<V_OBJECT, V_INDEX> inherited;
  94
  95        public:
  96                OpenWire::SourcePin     OutputPin;
  97
  98//      public:
  99//              bool    EnterNewLine;
 100
 101        protected:
 102                virtual void PrcessInValue( uint16_t AValue ) override
 103                {
 104                        char *ATypedValue = (char *)AValue;
 105                        OutputPin.Notify( &ATypedValue );
 106//                      if( EnterNewLine )
 107//                              if( *ATypedValue == '\r' )
 108//                                      OutputPin.SendValue( '\n' );
 109                }
 110
 111        public:
 112                using inherited::inherited;
 113
 114        };
 115//---------------------------------------------------------------------------
 116        class ViSiGenieBasicIn : public ViSiGenieBasicObject
 117        {
 118                typedef ViSiGenieBasicObject inherited;
 119
 120        public:
 121                OpenWire::SinkPin       InputPin;
 122
 123        protected:
 124                virtual void DoReceive( void *_Data ) = 0;
 125
 126        public:
 127                ViSiGenieBasicIn( Display4DSystems &AOwner ) :
 128                        inherited( AOwner )
 129                {
 130                        InputPin.SetCallback( this, (OpenWire::TOnPinReceive)&ViSiGenieBasicIn::DoReceive );
 131                }
 132
 133        };
 134//---------------------------------------------------------------------------
 135        template<int V_OBJECT, int V_INDEX, typename T_DATA> class ViSiGenieBasicTypedIn : public ViSiGenieBasicIn
 136        {
 137                typedef ViSiGenieBasicIn inherited;
 138
 139        public:
 140                OpenWire::SinkPin       RefreshInputPin;
 141
 142        public:
 143                bool    OnlyChanged : 1;
 144
 145        public:
 146                bool            FStarted : 1;
 147                bool            FReceived : 1;
 148
 149        public:
 150                T_DATA          FOldValue;
 151                T_DATA          FValue;
 152
 153                
 154        protected:
 155                virtual void DoReceive( void *_Data );
 156
 157                virtual void DoRefreshReceive( void *_Data )
 158                {
 159                        FStarted = false;
 160                }
 161
 162        public:
 163                ViSiGenieBasicTypedIn( Display4DSystems &AOwner, T_DATA AInitialValue ) :
 164                        inherited( AOwner ),
 165                        FValue( AInitialValue ),
 166                        FOldValue( AInitialValue ),
 167                        FStarted( false ),
 168                        FReceived( false ),
 169                        OnlyChanged( true )
 170                {
 171                        RefreshInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&ViSiGenieBasicTypedIn::DoRefreshReceive );
 172                }
 173        };
 174//---------------------------------------------------------------------------
 175        template<int V_OBJECT, int V_INDEX, typename T_DATA> class ViSiGenieTypedIn : public ViSiGenieBasicTypedIn<V_OBJECT, V_INDEX, T_DATA>
 176        {
 177                typedef ViSiGenieBasicTypedIn<V_OBJECT, V_INDEX, T_DATA> inherited;
 178
 179        protected:
 180                virtual uint16_t        GetValue()      { return inherited::FValue; };
 181
 182        public:
 183                virtual void Process();
 184
 185        public:
 186                using inherited::inherited;
 187
 188        };
 189//---------------------------------------------------------------------------
 190        template<int V_OBJECT, int V_INDEX, typename T_DATA> class ViSiGenieTypedInOut : public ViSiGenieTypedIn<V_OBJECT, V_INDEX, T_DATA>, public ViSiGenieBasicTypedOutObject<V_OBJECT, V_INDEX>
 191        {
 192                typedef ViSiGenieTypedIn<V_OBJECT, V_INDEX, T_DATA> inherited;
 193
 194        public:
 195                OpenWire::SourcePin     OutputPin;
 196/*
 197        public:
 198                virtual bool ProcessOut( Genie &AGenie, genieFrame &Event )
 199                {
 200                }
 201*/
 202        protected:
 203                virtual void PrcessInValue( uint16_t AValue ) override
 204                {
 205                        T_DATA ATypedValue = (T_DATA)AValue;
 206                        OutputPin.Notify( &ATypedValue );
 207                }
 208
 209        public:
 210                ViSiGenieTypedInOut( Display4DSystems &AOwner, T_DATA AInitialValue ) :
 211                        inherited( AOwner, AInitialValue ),
 212                        ViSiGenieBasicTypedOutObject<V_OBJECT, V_INDEX>( AOwner )
 213                {
 214                }
 215        };
 216//---------------------------------------------------------------------------
 217/*
 218        template<int V_OBJECT, int V_INDEX> class ViSiGenieTypedAnalogIn : public ViSiGenieTypedIn<V_OBJECT, V_INDEX, float>
 219        {
 220                typedef ViSiGenieTypedIn<V_OBJECT, V_INDEX, float> inherited;
 221
 222        protected:
 223                virtual uint16_t        GetValue()      { return inherited::FValue + 0.5; } override;
 224
 225        public:
 226                ViSiGenieTypedAnalogIn( Display4DSystems &AOwner ) :
 227                        inherited( AOwner, 0.0 )
 228                {
 229                }
 230        };
 231*/
 232//---------------------------------------------------------------------------
 233        template<int V_OBJECT, int V_INDEX> class ViSiGenieTypedUnsignedIn : public ViSiGenieTypedIn<V_OBJECT, V_INDEX, uint32_t>
 234        {
 235                typedef ViSiGenieTypedIn<V_OBJECT, V_INDEX, uint32_t> inherited;
 236
 237        public:
 238                using inherited::inherited;
 239        };
 240//---------------------------------------------------------------------------
 241        template<int V_OBJECT, int V_INDEX> class ViSiGenieTypedUnsignedInOut : public ViSiGenieTypedInOut<V_OBJECT, V_INDEX, uint32_t>
 242        {
 243                typedef ViSiGenieTypedInOut<V_OBJECT, V_INDEX, uint32_t> inherited;
 244
 245        public:
 246                using inherited::inherited;
 247        };
 248//---------------------------------------------------------------------------
 249        template<int V_OBJECT, int V_INDEX> class ViSiGenieTypedDigitalIn : public ViSiGenieTypedIn<V_OBJECT, V_INDEX, bool>
 250        {
 251                typedef ViSiGenieTypedIn<V_OBJECT, V_INDEX, bool> inherited;
 252
 253        protected:
 254                virtual uint16_t        GetValue() override { return inherited::FValue ? 1 : 0; }
 255
 256        public:
 257                ViSiGenieTypedDigitalIn( Display4DSystems &AOwner ) :
 258                        inherited( AOwner, false )
 259                {
 260                }
 261        };
 262//---------------------------------------------------------------------------
 263        template<int V_OBJECT, int V_INDEX> class ViSiGenieTypedDigitalInOut : public ViSiGenieTypedInOut<V_OBJECT, V_INDEX, bool>
 264        {
 265                typedef ViSiGenieTypedInOut<V_OBJECT, V_INDEX, bool> inherited;
 266
 267        protected:
 268                virtual uint16_t        GetValue() override     { return inherited::FValue ? 1 : 0; } 
 269
 270        protected:
 271                bool    FOldReceivedValue = false;
 272
 273        protected:
 274                virtual void PrcessInValue( uint16_t AValue )
 275                {
 276                        bool ATypedValue = (bool)AValue;
 277                        if( ! FOldReceivedValue )
 278                                if( ! ATypedValue )
 279                                        inherited::OutputPin.SendValue( true );
 280
 281                        FOldReceivedValue = ATypedValue;
 282                        inherited::OutputPin.Notify( &ATypedValue );
 283                }
 284
 285        public:
 286                ViSiGenieTypedDigitalInOut( Display4DSystems &AOwner ) :
 287                        inherited( AOwner, false )
 288                {
 289                }
 290        };
 291//---------------------------------------------------------------------------
 292        template<int V_OBJECT, int V_INDEX> class ViSiGenieTypedColorInOut : public ViSiGenieTypedInOut<V_OBJECT, V_INDEX, Mitov::TColor>
 293        {
 294                typedef ViSiGenieTypedInOut<V_OBJECT, V_INDEX, Mitov::TColor> inherited;
 295
 296        protected:
 297                virtual uint16_t        GetValue() override     
 298                { 
 299                        return ( ( inherited::FValue.Red >> 3 ) << ( 6 + 5 )) | ( ( inherited::FValue.Green >> 2 ) & 0b111111 ) << 5 | ( ( inherited::FValue.Blue >> 3 ) & 0b11111 );
 300                }
 301
 302                virtual void PrcessInValue( uint16_t AValue ) override
 303                {
 304                        Mitov::TColor ATypedValue; // = AValue;
 305                        ATypedValue.Red = ( AValue & 0b1111100000000000 ) >> ( 6 + 5 - 3 ); //0b1111100000000000 
 306                        ATypedValue.Green = ( AValue & 0b11111100000 ) >> ( 5 - 2 ); 
 307                        ATypedValue.Blue = ( AValue & 0b11111 ) << 3; 
 308                        inherited::OutputPin.Notify( &ATypedValue );
 309                }
 310
 311        public:
 312                ViSiGenieTypedColorInOut( Display4DSystems &AOwner ) :
 313                        inherited( AOwner, false )
 314                {
 315                }
 316        };
 317//---------------------------------------------------------------------------
 318        template<int V_OBJECT, int V_INDEX> class ViSiGenieTypedStringIn : public ViSiGenieBasicTypedIn<V_OBJECT, V_INDEX, String>
 319        {
 320                typedef ViSiGenieBasicTypedIn<V_OBJECT, V_INDEX, String> inherited;
 321
 322        protected:
 323                virtual void DoReceive( void *_Data ) override;
 324                virtual void Process() override;
 325
 326        public:
 327                ViSiGenieTypedStringIn( Display4DSystems &AOwner ) :
 328                        inherited( AOwner, "" )
 329                {
 330                }
 331        };
 332//---------------------------------------------------------------------------
 333        template<int V_OBJECT, int V_INDEX> class ViSiGenieTypedClockInOut : public ViSiGenieBasicIn, public ViSiGenieBasicOutObject
 334        {
 335                typedef ViSiGenieBasicIn inherited;
 336
 337        public:
 338                OpenWire::SourcePin     OutputPin;
 339
 340        protected:
 341                virtual void DoReceive( void *_Data ) override;
 342
 343                virtual bool ProcessOut( Genie &AGenie, genieFrame &Event ) override
 344                {
 345//                      Serial.println( "ProcessOut" );
 346                        if( Event.reportObject.cmd == GENIE_REPORT_EVENT )
 347                        {
 348/*
 349                                Serial.println( "GENIE_REPORT_EVENT" );
 350                                Serial.print( Event.reportObject.object );
 351                                Serial.print( " - " );
 352                                Serial.println( Event.reportObject.index );
 353*/
 354                                if( Event.reportObject.object == V_OBJECT )
 355                                        if( Event.reportObject.index == V_INDEX )
 356                                        {
 357                                                OutputPin.Notify( NULL );
 358//                                              uint16_t AValue = AGenie.GetEventData(&Event);
 359//                                              Serial.println( AValue );
 360//                                              PrcessInValue( AValue );
 361
 362                                                return true;
 363                                        }
 364
 365                                return false;
 366                        }
 367                }
 368
 369        public:
 370                ViSiGenieTypedClockInOut( Display4DSystems &AOwner ) :
 371                        inherited( AOwner ),
 372                        ViSiGenieBasicOutObject( AOwner )
 373                {
 374                }
 375        };
 376//---------------------------------------------------------------------------
 377        template<int V_INDEX> class ViSiGenieSpectrum : public ViSiGenieBasicObject
 378        {
 379                typedef ViSiGenieBasicObject inherited;
 380
 381        public:
 382                Mitov::SimpleList<OpenWire::VlaueChangeSinkPin<bool> > ColumnsInputPins;
 383
 384        public:
 385                virtual void Process() override;
 386
 387        public:
 388                using inherited::inherited;
 389
 390        };
 391//---------------------------------------------------------------------------
 392        class Display4DSystems : public OpenWire::Component
 393        {
 394                typedef OpenWire::Component inherited;
 395
 396        public:
 397                OpenWire::SourcePin     ResetOutputPin;
 398
 399        public:
 400                float   Contrast = 1.0f;
 401
 402        public:
 403                Mitov::SimpleList<ViSiGenieBasicObject *>               FElements;
 404                Mitov::SimpleList<ViSiGenieBasicOutObject *>    FOutElements;
 405                bool    FModified = true;
 406
 407        public:
 408                Genie FGenie;
 409
 410        public:
 411                void    SetContrast( float AValue )
 412                {
 413                        AValue = constrain( AValue, 0.0, 1.0 );
 414                        if( AValue == Contrast )
 415                                return;
 416
 417                        Contrast = AValue;
 418                        FGenie.WriteContrast( Contrast * 15 + 0.5 );
 419                }
 420
 421        protected:
 422                Mitov::BasicSerialPort &FSerial;
 423
 424        protected:
 425                virtual void SystemStart() 
 426                {
 427                        FGenie.Begin( FSerial.GetStream() );
 428
 429  //FGenie.AttachEventHandler(myGenieEventHandler); // Attach the user function Event Handler for processing events
 430                        bool AValue = true;
 431                        ResetOutputPin.Notify( &AValue );
 432
 433                        delay( 100 );
 434
 435                        AValue = false;
 436                        ResetOutputPin.Notify( &AValue );
 437
 438                        delay( 3500 );
 439                        FGenie.WriteContrast( Contrast );
 440
 441                        for( int i = 0; i < FElements.size(); ++ i )
 442                                FElements[ i ]->Start();
 443
 444                        inherited::SystemStart();
 445                }
 446
 447                virtual void SystemLoopEnd() 
 448                {
 449                        FGenie.DoEvents(false); // This calls the library each loop to process the queued responses from the display
 450
 451                        if( FModified )
 452                                for( int i = 0; i < FElements.size(); ++ i )
 453                                        FElements[ i ]->Process();
 454
 455                        genieFrame AEvent;
 456                        if( FGenie.DequeueEvent(&AEvent))
 457                        {
 458//                              Serial.println( "DequeueEvent" );
 459                                for( int i = 0; i < FOutElements.size(); ++ i )
 460                                        if( FOutElements[ i ]->ProcessOut( FGenie, AEvent ))
 461                                                break;
 462                        }
 463
 464                        inherited::SystemLoopEnd();
 465                }
 466
 467
 468        public:
 469                Display4DSystems( Mitov::BasicSerialPort &ASerial ) :
 470                        FSerial( ASerial )
 471                {
 472                }
 473        };
 474//---------------------------------------------------------------------------
 475        class ViSiGenieSounds : public ViSiGenieBasicObject
 476        {
 477                typedef ViSiGenieBasicObject inherited;
 478
 479        public:
 480                Mitov::SimpleList<OpenWire::IndexedSinkPin> TracksStartInputPins;
 481
 482        public:
 483                OpenWire::SinkPin       StopInputPin;
 484                OpenWire::SinkPin       PauseInputPin;
 485                OpenWire::SinkPin       ResumeInputPin;
 486
 487        public:
 488                float   Volume;
 489
 490        public:
 491                void    SetVolume( float AValue )
 492                {
 493                        AValue = constrain( AValue, 0.0, 1.0 );
 494                        if( AValue == Volume )
 495                                return;
 496
 497                        Volume = AValue;
 498                        FOwner.FGenie.WriteObject( GENIE_OBJ_SOUND, 1, Volume * 100 + 0.5 );
 499                }
 500
 501        public:
 502                virtual void Start() 
 503                {
 504                        for( int i = 0; i < TracksStartInputPins.size(); i ++ )
 505                        {
 506                                TracksStartInputPins[ i ].Index = i;
 507                                TracksStartInputPins[ i ].SetCallback( this, (OpenWire::TOnPinIndexedReceive)&ViSiGenieSounds::DoIndexReceive );
 508                        }
 509
 510                        FOwner.FGenie.WriteObject( GENIE_OBJ_SOUND, 1, Volume * 100 + 0.5 );
 511                }
 512
 513        protected:
 514                void DoIndexReceive( int AIndex, void *_Data )
 515                {
 516                        FOwner.FGenie.WriteObject( GENIE_OBJ_SOUND, 0, AIndex );
 517                }
 518
 519                void DoReceiveStop( void *_Data )
 520                {
 521                        FOwner.FGenie.WriteObject( GENIE_OBJ_SOUND, 4, 0 );
 522                }
 523
 524                void DoReceivePause( void *_Data )
 525                {
 526                        FOwner.FGenie.WriteObject( GENIE_OBJ_SOUND, 2, 0 );
 527                }
 528
 529                void DoReceiveResume( void *_Data )
 530                {
 531                        FOwner.FGenie.WriteObject( GENIE_OBJ_SOUND, 3, 0 );
 532                }
 533
 534        public:
 535                ViSiGenieSounds( Display4DSystems &AOwner ) :
 536                        inherited( AOwner )
 537                {
 538                        StopInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&ViSiGenieSounds::DoReceiveStop );
 539                        PauseInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&ViSiGenieSounds::DoReceivePause );
 540                        ResumeInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&ViSiGenieSounds::DoReceiveResume );
 541                }
 542        };
 543//---------------------------------------------------------------------------
 544        ViSiGenieBasicObject::ViSiGenieBasicObject( Display4DSystems &AOwner ) :
 545                FOwner( AOwner )
 546        {
 547                FOwner.FElements.push_back( this );
 548        }
 549//---------------------------------------------------------------------------
 550        ViSiGenieBasicOutObject::ViSiGenieBasicOutObject( Display4DSystems &AOwner )
 551        {
 552                AOwner.FOutElements.push_back( this );
 553        }
 554//---------------------------------------------------------------------------
 555        template<int V_OBJECT, int V_INDEX, typename T_DATA> void ViSiGenieBasicTypedIn<V_OBJECT, V_INDEX, T_DATA>::DoReceive( void *_Data )
 556        {
 557                FValue = *(T_DATA *)_Data;
 558                if( OnlyChanged && FStarted )
 559                        if( FValue == FOldValue )
 560                                return;
 561
 562                FReceived = true;
 563                FOwner.FModified = true;
 564        }
 565//---------------------------------------------------------------------------
 566        template<int V_OBJECT, int V_INDEX, typename T_DATA> void ViSiGenieTypedIn<V_OBJECT, V_INDEX, T_DATA>::Process()
 567        {
 568                if( inherited::OnlyChanged && inherited::FStarted )
 569                        if( inherited::FOldValue == inherited::FValue )
 570                                return;
 571
 572                if( ! inherited::FReceived )
 573                        return;
 574
 575                inherited::FStarted = true;
 576                inherited::FOldValue = inherited::FValue;
 577
 578                inherited::FOwner.FGenie.WriteObject(V_OBJECT, V_INDEX, GetValue() );
 579        }
 580//---------------------------------------------------------------------------
 581        template<int V_INDEX> void ViSiGenieSpectrum<V_INDEX>::Process() 
 582        {
 583                for( int i = 0; i < ColumnsInputPins.size(); i ++ )
 584                        if( ColumnsInputPins[ i ].OldValue != ColumnsInputPins[ i ].Value )
 585                        {
 586                                uint16_t AValue = ( i << 8 ) | ( ColumnsInputPins[ i ].Value & 0xFF );
 587                                FOwner.FGenie.WriteObject( GENIE_OBJ_SPECTRUM, V_INDEX, AValue );
 588                        }
 589
 590        }
 591//---------------------------------------------------------------------------
 592        template<int V_OBJECT, int V_INDEX> void ViSiGenieTypedStringIn<V_OBJECT, V_INDEX>::DoReceive( void *_Data )
 593        {
 594                inherited::FValue = (char *)_Data;
 595                if( inherited::OnlyChanged && inherited::FStarted )
 596                        if( inherited::FValue == inherited::FOldValue )
 597                                return;
 598
 599                inherited::FReceived = true;
 600                inherited::FOwner.FModified = true;
 601        }
 602//---------------------------------------------------------------------------
 603        template<int V_OBJECT, int V_INDEX> void ViSiGenieTypedStringIn<V_OBJECT, V_INDEX>::Process()
 604        {
 605                if( inherited::OnlyChanged && inherited::FStarted )
 606                        if( inherited::FOldValue == inherited::FValue )
 607                                return;
 608
 609                if( ! inherited::FReceived )
 610                        return;
 611
 612                inherited::FStarted = true;
 613                inherited::FOldValue = inherited::FValue;
 614
 615                inherited::FOwner.FGenie.WriteStr(V_INDEX, inherited::FValue.c_str() );
 616        }
 617//---------------------------------------------------------------------------
 618        template<int V_OBJECT, int V_INDEX> void ViSiGenieTypedClockInOut<V_OBJECT, V_INDEX>::DoReceive( void *_Data )
 619        {
 620                FOwner.FGenie.WriteObject( V_OBJECT, V_INDEX, 0 );
 621        }
 622//---------------------------------------------------------------------------
 623}
 624
 625#endif