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
#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
#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;
}