Detecting the skin was the most challenging part in this lab. We initially used a sample position and determined its RGB values and accordingly set the threshold for skin detection. However this method was not robust as it would get affected by the lighting conditions. Under improper lighting, the RGB values would be very low and thus the module wouldn't detect our hand. We searched for couple of algorithms online for skin detection. We found many methods, using HSL (Hue, Saturation, Lightness), or by using Normalized RGB, or by using YCbCr ( Luma, Blue-difference, Red-Difference). However the most simplest and yet effective one was by using normalized RGB values.
We created a layout of piano and drum notes on a green chart paper. For piano we used 16 notes and for drum we used 5 notes. We created modules inside the detect_control module to detect this paper and plot the keyboard on the VGA screen. This module looks for only green colour. The corners of the chart paper were detected by using linear equations concept. Once the corners were detected, the distance between them was divided into 16 equal parts for the piano and 5 equal parts for the drum. This would thus be in sync to the keys layout on the paperfor the piano and the drum. The green_keyboard module generates the two corner for the keyboard by detecting the green chart paper edges. The gen_keys module generates the keyboard on the screen. In this module we create another signal called is_inside_key[i], where i denotes the key number, that determines if the current pixel is inside the keyboard or not. We use a wire from the previous skin detection module called is_finger that would be set if finger (skin) is detected on the screen. Using this signal and is_inside_key[i] we can find out if there is a finger inside the keyboard and thus create another wire called is_key_pressed[i] where i denotes the key number. This signal is given out of the detect_control module and is then used by the piano synthesis module or the drum synthesis module to play sound whenever key is pressed.
![]()



We used a single state machine that computes a 10x10 node matrix. This state machine used a M4K block to store the node values instead of registers. Now for implementing the Finite Differences wave equation, we needed four blocks of M4K memory. One to store the initial excitation values, one to store the value of the nodes at current instant (u1), one to store the value of the nodes at next instant (u) and one to store the values of the node at previous instant (u2). We removed the memory required to store the initial excitation values by calculating it each time dynamically whenever KEY3 was pressed. We also removed the memory required to store the next value (u). We instead stored the next value calculated, in the block of memory that was used to store the previous value (u2); since once a particular node from the previous instant block (u2) was used, it was no longer needed, thereby replacing that node with its next value (u). Thus from four blocks of memory we came down to just two blocks thereby reducing the size of the M4K RAM. This optimization helped in increasing the number of state machine modules.| Project by Sandeep Gangundi, Xiyu Wang and Marc Vaz | Webpage designed by Sandeep Gangundi |