<mosaic.cnfolio.com>
Monome Hacking

Program to test connectivity to a monome board




Note: Use C style commenting to increase portability of the software. The double forward slash style is really a C++ styled format, which is tolerated by compilers which are not in strict mode.


Board Test Code - Commented Version (Incomplete) - Commenting syntax corrected for portability
BoardTest_Commented.c
#include <windows.h>
#include <stdio.h>
#include "ftd2xx.h"

/* Add FILE_FLAG_OVERLAPPED to use overlap IO mode */
#define MONOME_CONNECTION_ATTRIBUTES       ( FILE_ATTRIBUTE_NORMAL | FT_OPEN_BY_SERIAL_NUMBER )

#define MONOME_BUFFER_IDX_COMD             0
#define MONOME_BUFFER_IDX_DATA             1
#define MONOME_BUFFER_SIZE                 2

#define REPEAT_COUNT_TO_EXIT               6
#define BLINK_ROW_COLUMN_MODE              1

#define SET_MONOME_COMD_BOARDMODE(bf)      ( bf = ((6 & 0x0f) << 4) | (0 & 0x0f) )
#define SET_MONOME_COMD_LED_ON(bf)         ( bf = ((2 & 0x0f) << 4) | (1 & 0x0f) )
#define SET_MONOME_COMD_LED_OFF(bf)        ( bf = ((2 & 0x0f) << 4) | (0 & 0x0f) )
#define SET_MONOME_COMD_LED_ROW(bf,rn)     ( bf = ((8 & 0x0f) << 4) | (rn & 0x0f) )
#define SET_MONOME_COMD_LED_COL(bf,rn)     ( bf = ((7 & 0x0f) << 4) | (rn & 0x0f) )
#define SET_MONOME_DATA_BOARD_ON(bf)       ( bf = 1 )
#define SET_MONOME_DATA_BOARD_OFF(bf)      ( bf = 0 )
#define SET_MONOME_DATA_LED_ROWCOL_ON(bf)  ( bf = 255 )
#define SET_MONOME_DATA_LED_ROWCOL_OFF(bf) ( bf = 0 )

#define GET_MONOME_KEY_ROW(kp)             ( kp >> 4 )
#define GET_MONOME_KEY_COL(kp)             ( kp & 0x0f )

#define IS_MONOME_KEYPRESS_DOWN(bf)        ( bf == 1 )
#define IS_MONOME_KEYPRESS_UP(bf)          ( bf == 0 )

#define TEMP_BUFFER_SIZE                   128

int main( void )
{
   FT_STATUS ftConnectionStatus; /*stores connection status value*/
   FT_HANDLE ftConnectionHandle; /*stores connection handle value*/
   DWORD     dwBufferSize = MONOME_BUFFER_SIZE;  /*sets buffer size*/
   DWORD     dwBufferActualSize;
   char      sBuffer[ TEMP_BUFFER_SIZE ] = { '\0' }/*sets sBuffer array size according to the value of TEMP_BUFFER_SIZE*/
   byte      bMonomeData[ MONOME_BUFFER_SIZE ];  /*sets the maximum buffer packet size to be used*/
   int       iRepeatKeyRow = 0, iRepeatKeyCol = 0, iRepeatKeyCount = 0;  /*sets all repeat key press counts to 0*/
   int       iBlinkRow = -1, iBlinkCol = -1, iRowBlinking = 0, iColBlinking = 0/*sets all light blinking settings to off*/

   ftConnectionStatus = FT_ListDevices( 0, sBuffer, FT_LIST_BY_INDEX | FT_OPEN_BY_SERIAL_NUMBER );  /*stores connected device number and serial number (if multiple devices are connnected, the index value will be incremented)*/
   ftConnectionHandle = FT_W32_CreateFile( sBuffer, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, MONOME_CONNECTION_ATTRIBUTES, 0 )/*read sBuffer for connection details and store these values*/

   if ( ftConnectionHandle == INVALID_HANDLE_VALUE )  /*checks if connection exists*/ 
   {
     printf( "ERR: Monome board is not connected\n" );      /*displays failed connection message*/
     return 0;  /*returns program exit value*/
   }

   printf( "OK: Found Monome board using serial number %s\n", sBuffer );   /*displays successful connection message along with device serial number stored in sBuffer*/
   SET_MONOME_COMD_BOARDMODE( bMonomeData[ MONOME_BUFFER_IDX_COMD ] );
   SET_MONOME_DATA_BOARD_ON( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
   FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );

   while ( 1 )
   {
     bMonomeData[ MONOME_BUFFER_IDX_COMD ] = bMonomeData[ MONOME_BUFFER_IDX_DATA ] = 0;   /*resets buffer packets*/

     if ( FT_W32_ReadFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL ) )  /*if connection details are true (exist), continue*/
     {
        if ( dwBufferSize == dwBufferActualSize )
        {
           if ( IS_MONOME_KEYPRESS_DOWN( bMonomeData[ MONOME_BUFFER_IDX_COMD ] ) )    /*if a button has been pressed*/
           {
              if ( ( iRepeatKeyRow == GET_MONOME_KEY_ROW( bMonomeData[ MONOME_BUFFER_IDX_DATA ] ) ) && ( iRepeatKeyCol == GET_MONOME_KEY_COL( bMonomeData[ MONOME_BUFFER_IDX_DATA ] ) ) )  /*if the same key is pressed more than once, continue*/
              {
                 iRepeatKeyCount++; /*increment repeat button press counter (iRepeatKeyCount)*/
                 if ( iRepeatKeyCount == REPEAT_COUNT_TO_EXIT )   /*if repeat count press equals max count level (REPEAT_COUNT_TO_EXIT) then exit program*/
                    break;
              }
              else
                 iRepeatKeyCount = 0/*if a different key has been pressed, reset iRepeatKeyCount*/

              iRepeatKeyRow = GET_MONOME_KEY_ROW( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );      /*store the row of the pressed button*/
              iRepeatKeyCol = GET_MONOME_KEY_COL( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );      /*store the column of the pressed button*/
              printf( "OK: Received keypress at row=%d, column=%d\n", iRepeatKeyRow, iRepeatKeyCol );  /*print recieved key press confirmation message with button coordinates*/
              SET_MONOME_COMD_LED_ON( bMonomeData[ MONOME_BUFFER_IDX_COMD ] );      /*set to turn on button LED*/
              FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );   /*send changed information to monome*/ 

              if ( iBlinkRow == iRepeatKeyRow ) iRowBlinking = 1;       /*sets iRowBlinking flag when iRepeatKeyRow equals iBlinkRow*/
              if ( iBlinkCol == iRepeatKeyCol ) iColBlinking = 1;  /*sets iColBlinking flag when iRepeatKeyCol equals iBlinkCol*/
              iBlinkRow = iRepeatKeyRow;  /*copies the value of iRepeatKeyRow to iBlinkRow*/
              iBlinkCol = iRepeatKeyCol;  /*copies the value of iRepeatKeyCol to iBlinkCol*/

              if ( BLINK_ROW_COLUMN_MODE && iRowBlinking )    /*if both BLINK_ROW_COLUMN_MODE and iRowBlinking are not 0, continue*/
              {
            SET_MONOME_COMD_LED_ROW( bMonomeData[ MONOME_BUFFER_IDX_COMD ], iBlinkRow );
                 SET_MONOME_DATA_LED_ROWCOL_ON( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
                 FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );
              }

              if ( BLINK_ROW_COLUMN_MODE && iColBlinking )    /*if both BLINK_ROW_COLUMN_MODE and iColBlinking are not 0, continue*/
              {
                 SET_MONOME_COMD_LED_COL( bMonomeData[ MONOME_BUFFER_IDX_COMD ], iBlinkCol );
                 SET_MONOME_DATA_LED_ROWCOL_ON( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
                 FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );
              }
           }
           else
           {
              if ( IS_MONOME_KEYPRESS_UP( bMonomeData[ MONOME_BUFFER_IDX_COMD ] ) )
              {
                 SET_MONOME_COMD_LED_OFF( bMonomeData[ MONOME_BUFFER_IDX_COMD ] );
                 FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );

                 if ( BLINK_ROW_COLUMN_MODE && iRowBlinking )  /*if BLINK_ROW_COLUMN_MODE and iRowBlinking are enabled, reset row blinking to off*/
                 {
                    iRowBlinking = 0;
                    SET_MONOME_COMD_LED_ROW( bMonomeData[ MONOME_BUFFER_IDX_COMD ], iBlinkRow );
                    SET_MONOME_DATA_LED_ROWCOL_OFF( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
                    FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );
                 }

                 if ( BLINK_ROW_COLUMN_MODE && iColBlinking )  /*if BLINK_ROW_COLUMN_MODE and iColBlinking are enabled, reset column blinking to off*/
                 {
                    iColBlinking = 0;
                    SET_MONOME_COMD_LED_COL( bMonomeData[ MONOME_BUFFER_IDX_COMD ], iBlinkCol );
                    SET_MONOME_DATA_LED_ROWCOL_OFF( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
                    FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );
                 }
              }
           }
        }
        else
           printf( "ERR: Timed out while trying to read data" )/*return error message stating no button press was detected*/
     }
     else
        printf( "ERR: Failed to read data\n" )/*print error message to state a failed device connection*/
   }
   
   SET_MONOME_COMD_BOARDMODE( bMonomeData[ MONOME_BUFFER_IDX_COMD ] );
   SET_MONOME_DATA_BOARD_OFF( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
   FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );
   FT_W32_CloseHandle( ftConnectionHandle );
   return 1;   /*returns exit status value*/
}




Board Test Code - Original
BoardTest.c
#include <windows.h>
#include <stdio.h>
#include "ftd2xx.h"

/* Add FILE_FLAG_OVERLAPPED to use overlap IO mode */
#define MONOME_CONNECTION_ATTRIBUTES       ( FILE_ATTRIBUTE_NORMAL | FT_OPEN_BY_SERIAL_NUMBER )

#define MONOME_BUFFER_IDX_COMD             0
#define MONOME_BUFFER_IDX_DATA             1
#define MONOME_BUFFER_SIZE                 2

#define REPEAT_COUNT_TO_EXIT               6
#define BLINK_ROW_COLUMN_MODE              1

#define SET_MONOME_COMD_BOARDMODE(bf)      ( bf = ((6 & 0x0f) << 4) | (0 & 0x0f) )
#define SET_MONOME_COMD_LED_ON(bf)         ( bf = ((2 & 0x0f) << 4) | (1 & 0x0f) )
#define SET_MONOME_COMD_LED_OFF(bf)        ( bf = ((2 & 0x0f) << 4) | (0 & 0x0f) )
#define SET_MONOME_COMD_LED_ROW(bf,rn)     ( bf = ((8 & 0x0f) << 4) | (rn & 0x0f) )
#define SET_MONOME_COMD_LED_COL(bf,rn)     ( bf = ((7 & 0x0f) << 4) | (rn & 0x0f) )
#define SET_MONOME_DATA_BOARD_ON(bf)       ( bf = 1 )
#define SET_MONOME_DATA_BOARD_OFF(bf)      ( bf = 0 )
#define SET_MONOME_DATA_LED_ROWCOL_ON(bf)  ( bf = 255 )
#define SET_MONOME_DATA_LED_ROWCOL_OFF(bf) ( bf = 0 )

#define GET_MONOME_KEY_ROW(kp)             ( kp >> 4 )
#define GET_MONOME_KEY_COL(kp)             ( kp & 0x0f )

#define IS_MONOME_KEYPRESS_DOWN(bf)        ( bf == 1 )
#define IS_MONOME_KEYPRESS_UP(bf)          ( bf == 0 )

#define TEMP_BUFFER_SIZE                   128

int main( void )
{
   FT_STATUS ftConnectionStatus;
   FT_HANDLE ftConnectionHandle;
   DWORD     dwBufferSize = MONOME_BUFFER_SIZE;
   DWORD     dwBufferActualSize;
   char      sBuffer[ TEMP_BUFFER_SIZE ] = { '\0' };
   byte      bMonomeData[ MONOME_BUFFER_SIZE ];
   int       iRepeatKeyRow = 0, iRepeatKeyCol = 0, iRepeatKeyCount = 0;
   int       iBlinkRow = -1, iBlinkCol = -1, iRowBlinking = 0, iColBlinking = 0;

   ftConnectionStatus = FT_ListDevices( 0, sBuffer, FT_LIST_BY_INDEX | FT_OPEN_BY_SERIAL_NUMBER );
   ftConnectionHandle = FT_W32_CreateFile( sBuffer, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, MONOME_CONNECTION_ATTRIBUTES, 0 );

   if ( ftConnectionHandle == INVALID_HANDLE_VALUE )
   {
     printf( "ERR: Monome board is not connected\n" );
     return 0;
   }

   printf( "OK: Found Monome board using serial number %s\n", sBuffer );
   SET_MONOME_COMD_BOARDMODE( bMonomeData[ MONOME_BUFFER_IDX_COMD ] );
   SET_MONOME_DATA_BOARD_ON( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
   FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );

   while ( 1 )
   {
     bMonomeData[ MONOME_BUFFER_IDX_COMD ] = bMonomeData[ MONOME_BUFFER_IDX_DATA ] = 0;

     if ( FT_W32_ReadFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL ) )
     {
        if ( dwBufferSize == dwBufferActualSize )
        {
           if ( IS_MONOME_KEYPRESS_DOWN( bMonomeData[ MONOME_BUFFER_IDX_COMD ] ) )
           {
              if ( ( iRepeatKeyRow == GET_MONOME_KEY_ROW( bMonomeData[ MONOME_BUFFER_IDX_DATA ] ) ) &&
                   ( iRepeatKeyCol == GET_MONOME_KEY_COL( bMonomeData[ MONOME_BUFFER_IDX_DATA ] ) ) )
              {
                 iRepeatKeyCount++;
                 if ( iRepeatKeyCount == REPEAT_COUNT_TO_EXIT )
                    break;
              }
              else
                 iRepeatKeyCount = 0;

              iRepeatKeyRow = GET_MONOME_KEY_ROW( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
              iRepeatKeyCol = GET_MONOME_KEY_COL( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
              printf( "OK: Received keypress at row=%d, column=%d\n", iRepeatKeyRow, iRepeatKeyCol );
              SET_MONOME_COMD_LED_ON( bMonomeData[ MONOME_BUFFER_IDX_COMD ] );
              FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );

              if ( iBlinkRow == iRepeatKeyRow ) iRowBlinking = 1;
              if ( iBlinkCol == iRepeatKeyCol ) iColBlinking = 1;
              iBlinkRow = iRepeatKeyRow;
              iBlinkCol = iRepeatKeyCol;

              if ( BLINK_ROW_COLUMN_MODE && iRowBlinking )
              {
                 SET_MONOME_COMD_LED_ROW( bMonomeData[ MONOME_BUFFER_IDX_COMD ], iBlinkRow );
                 SET_MONOME_DATA_LED_ROWCOL_ON( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
                 FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );
              }

              if ( BLINK_ROW_COLUMN_MODE && iColBlinking )
              {
                 SET_MONOME_COMD_LED_COL( bMonomeData[ MONOME_BUFFER_IDX_COMD ], iBlinkCol );
                 SET_MONOME_DATA_LED_ROWCOL_ON( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
                 FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );
              }
           }
           else
           {
              if ( IS_MONOME_KEYPRESS_UP( bMonomeData[ MONOME_BUFFER_IDX_COMD ] ) )
              {
                 SET_MONOME_COMD_LED_OFF( bMonomeData[ MONOME_BUFFER_IDX_COMD ] );
                 FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );

                 if ( BLINK_ROW_COLUMN_MODE && iRowBlinking )
                 {
                    iRowBlinking = 0;
                    SET_MONOME_COMD_LED_ROW( bMonomeData[ MONOME_BUFFER_IDX_COMD ], iBlinkRow );
                    SET_MONOME_DATA_LED_ROWCOL_OFF( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
                    FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );
                 }

                 if ( BLINK_ROW_COLUMN_MODE && iColBlinking )
                 {
                    iColBlinking = 0;
                    SET_MONOME_COMD_LED_COL( bMonomeData[ MONOME_BUFFER_IDX_COMD ], iBlinkCol );
                    SET_MONOME_DATA_LED_ROWCOL_OFF( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
                    FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );
                 }
              }
           }
        }
        else
           printf( "ERR: Timed out while trying to read data" );
     }
     else
        printf( "ERR: Failed to read data\n" );
   }
   
   SET_MONOME_COMD_BOARDMODE( bMonomeData[ MONOME_BUFFER_IDX_COMD ] );
   SET_MONOME_DATA_BOARD_OFF( bMonomeData[ MONOME_BUFFER_IDX_DATA ] );
   FT_W32_WriteFile( ftConnectionHandle, bMonomeData, dwBufferSize, &dwBufferActualSize, NULL );
   FT_W32_CloseHandle( ftConnectionHandle );
   return 1;
}