Drumbeat Identification


% Signals and Systems Lab
% Drumbeat identification
% Written by David Egan
% DT021/2A

function drum = drumbeats(signal)                   % Setting the function

a = 0;                                              % using 'a' variable as counter

beat = max(signal)*.99;                             % Setting 99% of max amplitude as beat

for (k = 1 : length(signal))                        % Looping through the signal length

     if(signal(k) > beat)                           % Checking to see if the magnitude is greather that 99% of max

         a = a + 1;                                 % Using 'a' to count the beats if > 99%

         segment = signal(k : k + 20000);           % Using k to segment a part of each beat for further anaylsis

         fft_segment = fft(segment);                % Getting the Fourier Transform of the segment

         mag_values = abs(fft_segment);             % Gets the magnitude of the frequencies of the segment

         if (max(mag_values(1:500)) > 500)          % Checks the maximum magnitude to distinguish between tom sounds

             tom = 2;                               % Sets variable 'tom' to 2 for the second tom

         else

             tom = 1;                               % Sets variable 'tom' to 1 for the first tom

         end

         str = ['Drumbeat ',num2str(a),' at ', num2str(k),' is tom ',num2str(tom)];    % setting a string with variables
         disp(str);                                 % Displaying the string with beat position and tom type for each beat

     end
end
 str1 = ['There are ', num2str(a), ' drumbeats in total. '];  % Displaying the total number of beats
 disp(str1);

R_C Second time round


%Gerard Riney & David Egan DT021/2
%
%This is a function to test an RC Circuit

function rcvalues= sintestA(res,cap)

tconst=res*cap                                              % calculate time constant
totalt=5*tconst;                                            % total charge time
frequency=1000;                                             % Frequency
t=0:1/frequency:8;                                          % time
sigFreq=1;

for sigFreq=10:5:20
    for amp=63.5:63.5:127

            signal=round(amp*(cos(2*pi*sigFreq*t)+1));

            signalin=daq_lite(signal,1000,'plot_off');

            t(end)=[];

            signalin(1:(6*tconst*frequency))=[];            % Allow the circuit to settle(to charge),

            big=max(signalin);                              % getting the range of the input signal

            small=min(signalin);

            range=big-small                                 % Measured value of Vc

            Xc=(1/(j*2*pi*sigFreq*cap))                     % Xc, calculate capacitor impedance

            calXc=(amp*2)*(Xc/(res+Xc))                     % Voltage across cap (voltage divider)

            rangecal=sqrt((real(calXc)^2)+(imag(calXc)^2))  % Magnitude of Vc

             check=range/rangecal;                          % This line calculates the percentage of measured range
                                                            % against calculated range.

                      if check<0.85||check>1.15             % +-15 percent tolerances, if outside print error

                              disp('Circuit not functioning correctly')
                              return

                      end

    end
end
disp('Circuit functioning correctly');

RC Circuit test (daq lite) 1st attempt


%Gerard Riney & David Egan DT021/2
%
%This is a function to test an RC Circuit, by synthesizing a square wave
% in matlab, sending it out onto the daq_lite into the circuit, and
% subsequently reading the voltage across the capacitor.
% The user is required to input both the capacitance and resistance values
% for their respective circuit.
%
%           r_c(resistance,capacitance)
%

function rcvalues= r_c(res,cap)
tconst=res*cap;                  %calculate time constant
disp('The time constant is');
disp(tconst);
totalt=5*tconst;                %calculate total time to charge/
                                %discharge
frequency=100;
sqrwvt=(-1/(3*totalt));
                        %I picked 3 times the totalt as to allow for
                        %inaccurate RC values, ie allow capacitor
                        %time to fully charge with added time for
                        %error.

                        %the '-' before the 1 is just to get an inver                        %se square wave,
                        %starting at 0, and is not of major
                        %importantance

time = 0:(1/frequency):(6*totalt);  %the total time, twice the period
                                    % of the square wave so as to get                                    %2 oscillations.
signal=(square(2*pi*sqrwvt*time)+1)*127;     % this is generating the                                             %signal to send out to
                                             %the circuit via the daq                                             %_lite
signalin=daq_lite(signal,frequency);   %this is sending the daq_lite
                                       %the signal, and reading the
                                       %analog input
time(end)=[];
figure(2)                          %The next 5 lines are generating a                                   %plot against time, rather than
                                   %samples
plot(time,signalin);
title('Signal versus time');
xlabel('Time(seconds)');
ylabel('Amplitude');

                       %Now to check if the RC circuit is functioning                       %properly

chng=(1.5*totalt);     %First instance of change in square wave in                          %seconds
sample=chng*frequency; %First instance of change in square wave in
                       %samples
Check1=signalin(sample); %Checking at first instance of change,                               %should be close to zero.
Check1
sample=sample+(totalt*frequency);      %From first instance of change                                       %to fully charged, should be
                                       %close to 255
Check2=signalin(sample);
Check2

chng2=(3*totalt);                     %When square wave changes from                                      %high to low, plus 5 time                                          %constants, should be close to 0

sample2=(chng2*frequency)+(totalt*frequency);
Check3=signalin(sample2);
Check3
if Check1<10&&Check2>240&&Check3<10
    disp('Circuit working correctly');

else
    disp('Circuit not working correctly');

end

The first attempt at testing an R.C. circuit using the daq lite worked well but with only one test signal to test the circuit the test proved not to be thorough enough.

More work required.

Speech code


speech=wavrecord(16000*5,16000);
plot (speech)
f=16000;
T=(1/f);
time=(0:T:5);
time(end)=[];
plot(time,speech)
speech(16000:19200)=0;
plot(time,speech)
title('speech with silenced section')
xlabel('time (s)')
ylabel('Amplitude')
figure
segment1=speech(1:16000);
plot(time,segment1)
time1=(0:T:1)
time1(end)=[];
plot(time1,segment1)
subplot(2,2,1);plot(time1,segment1);
title('1st second segment');
xlabel('Time (s)');ylabel('Amplitude');
time2=(1:T:2);
time2(end)=[];
segment2=speech(16001:32000);
subplot(2,2,2);plot(time2,segment2,'r');
title('2nd second segment');xlabel('Time (s)');ylabel('Amplitude');
time3=(2:T:3);time3(end)=[];
segment3=(32001:48000);
subplot(2,2,3);plot(time3,segment3,'y');
time3=(2:T:3);time3(end)=[];
segment3=speech(32001:48000);
subplot(2,2,3);plot(time3,segment3,'y');
time4=(3:T:4)time4(end)=[];
time4=(3:T:4);time4(end)=[];
segment4=speech(48001:64000);
subplot(2,2,4);plot(time4,segment4,'m');
title('4th second segment');xlabel('Time (s)');ylabel('Amplitude');
subplot(2,2,3);title('3rd second segment');xlabel('Time (s)');ylabel('Amplitude');
wavwrite(speech,16000,16,'speech');

Had a bit of trouble with the wavwrite function at the start but have rectified it now.
Function added on last line and all code working correctly.

Image

Weight loss

After the final build we weighted the robot at 880g. This was without the battery pack or the outer cover and we thought it would be under the 1Kg limit. But with the addition the robot tipped the scales at 1.04Kg.

So the only coures of action was to cut away sections of the outer cover as the rest of the chassis is essential for mounting sensors and the breadboard.

With the cut away sections the robot weighted in at 990g and under the limit. So all set for the fight.

Test Run

After compleating the build and programming the robot we ran a few tests on the robosumo table to debug the robot. We ran into a few problems but nothing major. There is a short video of the robot searching for a target and charging at the target.

The test went well and now just fine tuning for the final fight next Thursday.

Pics of the final build

As promised earlier here are the pic of the final mechanical build of our robot.

Firstly we mounted the sensors on brackets for placement in positions we think we’ll need them.

This is the light sensors and the range finder on their brackets for mounting.

 

This is a pic of the touch sensor mounted on a bracket. There is another sensor on the other end of the bracket for mounting on either side of the chassis.

 

This is the touch sensor mounted on its support with the hinged side of the robot actuates the sensor along the full side of the robot.

 

This is the parts all lined up. The bread board goes on the chassis and the battery pack will be mounted to the outer case. Removal of the outer case is by means of 4 nuts and batteries can be changed in about one minute. The other components can be removed by removing another 2 nuts to gain access to the sensors and motors should any problems arise during the competition.

 

Robot build

Ger and I spent a good deal of time in the workshop yesterday trying to finalize the mechanical build for the Robosumo competition. After a long day we have gotten the robot to a point we are happy with. The sensors are all mounted in position, there is space for the bread board and the battery pack and a cover for all the components to be protected. We are happy so far but with a few tests to follow things might change. Pics of the build will be up shortly.

State Machine (so far)

This is a sample of the state machine we decided on in Lab last week. It’s still a work in progress so alterations will have to be made and tested on the robot to see their viability for the competition. Should have things up and running next week.

void main(void)
{
    int range;		//assign variables
	int light1;
	int light2;
	int touch1;
	int touch2;
	int state=1;
	int counter=0;

    setup(); // Configure the PIC

    while(1)
    {

		range = read_analog_channel(0);  //read sensors
		light1 = read_analog_channel(1);
		light2 = read_analog_channel(2);
		touch1 = PORTCbits.RC4;
		touch2 = PORTCbits.RC5;

		// Put in a short delay - approx 1ms to act as a timer
		Delay10KTCYx(20);
		counter = counter + 1;

		 if (state == 1)
        {
            // STATE 1: WAIT FOR BUTTON TO BE PRESSED

            // What does the robot do in this state?
            LATD = 0b00000000; // motors stopped

            // Does the robot need to change state?
            if (touch1 == 1) state = 2;
	     }
        else if (state == 2)
        {
            // STATE 2: WAIT FOR BUTTON TO BE RELEASED

            // What does the robot do in this state?
            LATD = 0b00000000; // motors stopped

            // Does the robot need to change state?
            if (touch1 == 0) state = 3;
        }
		else if (state == 3)
		{
			// STATE 3: SCAN RIGHT
			// What does the robot do in this state?
			LATD = 0b00001001;  //Turn right

			// Does the robot need to change state?
			if ( counter >= 1000)
			{
				counter = 0;
				state = 4;
			}

            else if (range > 140) state=5;
			else if (light1<550) state = 6;
			else if (light2<550) state = 7;

		}
		else if ( state == 4)
		{
			// STATE 4: SCAN LEFT
			// What does the robot do in this state?
			LATD = 0b00000110;  //Turn left

			// Does the robot need to change state?
            if (range > 140) state=5;
			else if (light1<550) state = 6;
			else if (light2<550) state = 7;
		}
		else if ( state == 5)
		{
			// STATE 5: ATTACK
			// What does the robot do in this state?
			LATD = 0b00000101;  //Forward

			if (range <140) state = 3;
			else if (light1<550) state = 6;
			else if (light2<550) state = 7;
		}
		else if (state == 6)
		{
			// STATE 6: back from white
			// What does the robot do in this state?
			while (counter < 1000)
			{
				LATD = 0b00001010;  //Back
			}
			counter = 0;
			state = 3;
		}
		else if (state == 7)
		{
			// STATE 7: Forward from white
			// What does the robot do in this state?
			while ( counter < 1000)
			{
				LATD = 0b00000101;  //Forward
			}
			counter = 0;
			state = 3;
		}
		else if ( state == 8)
		{

			// STATE 8: Turn if touched right
			// What does the robot do in this state?
			while (touch1 ==1)
			{
				LATD = 0b00001001;  //Turn right
			}
			state = 3;
		}
		else if ( state == 9)
		{

			// STATE 9: Turn if touched left
			// What does the robot do in this state?
			while (touch2 == 1)
			{
				LATD = 0b00000110;  //Turn left
			}
			state = 3;
		}

    }
}