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