libraries / Mitov / Mitov_Wii_Controller.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_WII_CONTROLLER_h
  11#define _MITOV_WII_CONTROLLER_h
  12
  13#include <Mitov.h>
  14
  15// http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Nunchuck
  16
  17namespace Mitov
  18{
  19//---------------------------------------------------------------------------
  20        class WiiNunchuck : public Mitov::EnabledComponent, public Mitov::ClockingSupport
  21        {
  22                typedef Mitov::EnabledComponent inherited;
  23
  24        private:
  25                const byte WII_NUNCHUK_I2C_ADDRESS = 0x52;
  26
  27        public:
  28                OpenWire::TypedSourcePin<float> AngleOutputPins[ 3 ];
  29                OpenWire::TypedSourcePin<float> StickOutputPins[ 2 ];
  30                OpenWire::TypedSourcePin<bool>  ButtonOutputPins[ 2 ];
  31
  32        public:
  33                uint32_t        ReadDelay = 100;
  34
  35        protected:
  36                bool    FStarted = false;
  37                unsigned long   FLastTime = 0;
  38                int             FClockedCount = 0;
  39
  40        protected:
  41                void DoClockReceive( void *_Data ) override
  42                {
  43                        ++ FClockedCount;
  44                        StartRead();
  45                }
  46
  47                void ReadData( bool AChangeOnly )
  48                {
  49                        if( ! Enabled )
  50                                return;
  51
  52                        ReadController( AChangeOnly );
  53                }
  54
  55                void StartRead()
  56                {
  57                        Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
  58                        Wire.write(0x00);
  59                        Wire.endTransmission();
  60
  61                        delayMicroseconds( 10 );
  62
  63                        Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
  64                        Wire.write(0x00);
  65                        Wire.endTransmission();
  66                        FLastTime = micros();
  67                }
  68
  69                void ReadController( bool AChangeOnly )
  70                {
  71                        uint8_t AData[6];
  72                        Wire.requestFrom(WII_NUNCHUK_I2C_ADDRESS, (byte)6);
  73
  74                        for( int i = 0; i < 6; ++i )
  75                                AData[ i ] = Wire.read();
  76
  77                        float AStickX = (float)AData[0] / 255;
  78                        float AStickY = (float)AData[1] / 255;
  79                        StickOutputPins[ 0 ].SetValue( AStickX, AChangeOnly );
  80                        StickOutputPins[ 1 ].SetValue( AStickY, AChangeOnly );
  81
  82                        float AAngleX = ((float)(((uint16_t)AData[2] ) << 2) + ((AData[5] >> 2) & 0x03)) / 1023;
  83                        float AAngleY = ((float)(((uint16_t)AData[3] ) << 2) + ((AData[5] >> 4) & 0x03)) / 1023;
  84                        float AAngleZ = ((float)(((uint16_t)AData[4] ) << 2) + ((AData[5] >> 6) & 0x03)) / 1023;
  85
  86                        AngleOutputPins[ 0 ].SetValue( AAngleX, AChangeOnly );
  87                        AngleOutputPins[ 1 ].SetValue( AAngleY, AChangeOnly );
  88                        AngleOutputPins[ 2 ].SetValue( AAngleZ, AChangeOnly );
  89
  90                        bool AButtonValue = !( AData[5] & 0b10 );
  91                        ButtonOutputPins[ 0 ].SetValue( AButtonValue, AChangeOnly );
  92
  93                        AButtonValue = !( AData[5] & 1 );
  94                        ButtonOutputPins[ 1 ].SetValue( AButtonValue, AChangeOnly );
  95
  96                        if( ( ! ClockInputPin.IsConnected() ) || FClockedCount )
  97                                StartRead();
  98                }
  99
 100        protected:
 101                virtual void SystemLoopBegin( unsigned long currentMicros ) override
 102                {
 103                        if( ! FClockedCount )
 104                                if( ! ClockInputPin.IsConnected() )
 105                                        ++ FClockedCount;
 106
 107                        if( FClockedCount )
 108                                if( currentMicros - FLastTime > ReadDelay )
 109                                {
 110                                        -- FClockedCount;
 111                                        ReadData( FStarted );
 112                                        FStarted = true;
 113                                }
 114
 115                        inherited::SystemLoopBegin( currentMicros );
 116                }
 117
 118                virtual void SystemStart() override
 119                {
 120                        // Init the controller
 121                        Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
 122                        Wire.write(0xF0);
 123                        Wire.write(0x55);
 124                        Wire.endTransmission();
 125
 126                        Wire.beginTransmission(WII_NUNCHUK_I2C_ADDRESS);
 127                        Wire.write(0xFB);
 128                        Wire.write(0x00);
 129                        Wire.endTransmission();
 130
 131                        StartRead();
 132                        inherited::SystemStart();
 133                }
 134
 135        };
 136//---------------------------------------------------------------------------
 137}
 138
 139#endif