Electromyogram Switch

This is the C code from electromyogram switch that we worked through in class today. I’ll add the circuit diagram once i get a chance to draw it up.

//
// dsPIC30F4011 Electromyogram switch
// Written by Ted Burke
// Last updated 22-11-2012
//
// This program records an EMG signal from a biopotential
// amplifier. It acts as a simple classifier, distinguishing
// between relaxed and tensed muscle. I tried it out with
// two electrodes about 5cm apart on my bicep (in addition
// to a reference electrode on my left shin) and it worked
// really well. The feature used in the classifier is the
// standard deviation of a 20-sample window of data recorded
// at 100Hz. When this value exceeds a threshold, pin RD0 is
// set high (switching on an LED in my circuit). The gain of
// my biopotential amplifier is approximately 200 Ohms and it
// has an input impedance of 1kOhm. The reference voltage of
// the amplifier is 2.5V, so that's the DC level of the signal
// when it arrives at the analog input of the dsPIC.
//

#include <xc.h>
#include <stdio.h>
#include <libpic30.h>

// Configuration settings
_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, Fcy=30MHz
_FWDT(WDT_OFF);                  // Watchdog timer off
_FBORPOR(MCLR_DIS);              // Disable reset pin

unsigned int read_analog_channel(int n);

int main()
{
	int n, voltage, data[20];
	double average, difference, sd;
	
	// Configure RD0 as digital output, RD1-3 as digital inputs
	TRISD = 0b1110;

	// Configure AN0-AN8 as analog inputs
	ADCON3bits.ADCS = 15;  // Tad = 266ns, conversion time is 12*Tad
	ADCON1bits.ADON = 1;   // Turn ADC ON

	// Setup UART
	U1BRG = 48;            // 38400 baud @ 30 MIPS
	U1MODEbits.UARTEN = 1; // Enable UART

	// Flash five times at power on time
	for (n=0 ; n<5 ; ++n)
	{
		_LATD0 = 1; __delay32(7500000);
		_LATD0 = 0; __delay32(7500000);
	}
	
	while(1)
	{
		// Record 20 samples at Fs=100Hz
		average = 0;
		for (n=0 ; n<20 ; ++n)
		{
			// Read a voltage from AN0
			data[n] = read_analog_channel(0);
			average = average + data[n];
			
			// 10ms delay
			__delay32(300000);
		}
		// Calculate average value
		average = average / 20;
		
		// Find standard deviation, sd
		sd = 0;
		for (n=0 ; n<20 ; ++n)
		{
			difference = data[n] - average;
			if (difference < 0) difference = -difference;
			sd = sd + difference;
		}
		sd = sd / 20;
	
		// Compare sd to threshold to classify signal as
		// either relaxed or tensed muscle (LED on or off)
		if (sd > 10.0) _LATD0 = 1;
		else _LATD0 = 0;
		
		// Print standard deviation via serial port
		printf("%f\n", sd);
		__delay32(300000); // 10ms delay
	}
	
	return 0;
}

// This function reads a single sample from the specified
// analog input. It should take less than 5us when the
// microcontroller is running at 30 MIPS.
// The dsPIC30F4011 has a 10-bit ADC, so the value
// returned is between 0 and 1023 inclusive.
unsigned int read_analog_channel(int channel)
{
	ADCHS = channel;          // Select the requested channel
	ADCON1bits.SAMP = 1;      // Start sampling
	__delay32(30);            // 1us delay @ 30 MIPS
	ADCON1bits.SAMP = 0;      // Start Converting
	while (!ADCON1bits.DONE); // Should take 12 * Tad = 3.2us
	return ADCBUF0;
}
Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s