go_away

Author Topic: Modifying a homemade lie detector for micro controller use.  (Read 2209 times)

0 Members and 1 Guest are viewing this topic.

Offline Hawaii00000Topic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 347
  • Helpful? 2
Modifying a homemade lie detector for micro controller use.
« on: March 17, 2009, 03:13:05 PM »
I want to modify this home made lie detector for use with a microcontroller... http://www.instructables.com/id/Build-a-Lie-Detector!/
If I take out the speaker and capacitor, connect it to a i/o port, and set a trip point would that work?
"God chose to make the world according to very beautiful mathematics."
-Paul Dirac
**************************************************************
Its Hawaii Five-O. Get it?

Offline Soeren

  • Supreme Robot
  • *****
  • Posts: 4,672
  • Helpful? 227
  • Mind Reading: 0.0
Re: Modifying a homemade lie detector for micro controller use.
« Reply #1 on: March 17, 2009, 03:49:52 PM »
Hi,

In short, no.

Lots of circuits that can be used exists however, try locating an op-amp based circuit.
Regards,
Søren

A rather fast and fairly heavy robot with quite large wheels needs what? A lot of power?
Please remember...
Engineering is based on numbers - not adjectives

Offline MaltiK

  • Robot Overlord
  • ****
  • Posts: 300
  • Helpful? 2
Re: Modifying a homemade lie detector for micro controller use.
« Reply #2 on: March 17, 2009, 04:08:44 PM »
I am guessing it works the same way a GSR machine works, (measuring the resistance of skin). And yes it could be made with an MCU, although an OP-AMP seems more pratical.

Heres an OP-Amp based GSR schematic a quick google search yielded:



But if you DO wish to use an MCU still I found a schematic and .c files a while ago:




main.c
Code: [Select]
/* Truth Wristband!!!
/
/ A wearable device that dynamically reflects the your
/ psycho-emotional response to the world, promoting internal
/ states to be externalized and made into interactive forms
/ of expression. Measuring the galvanic skin response
/ (a marker of emotional arousal commonly used in lie detector
/ tests), this device’s lights turn from blue to red as the
/ wearer becomes aroused. Ask the wearer an evocative question
/ and reveal his or her inner Truth.
/
/ Skin resistance changes -> B->R waves over 5 LEDs
/ Fs = 50 Hz
/ 5 sec calibration delay on startup
/ Smoothed to 3.33Hz
/ Average skin resistance calculated using 1 second decay constant
/ VDD = 2.4-3V
/
/ Written by Sean M. Montgomery, 2009/02
/ http://www.produceconsumerobot.com/truth/
/
/ Truth Wristband by Sean M. Montgomery is licensed under a
/ Creative Commons Attribution-Noncommercial-Share Alike 3.0
/ United States License
/
*/

#include <p18f25k20.h>
#include <adc.h>
#include <timers.h>
#include <math.h>
#include "SetOutputs.h"
void high_isr(void);
void init(void);
void GetData(void);

// counter values to convert A/D sampling to 20ms
unsigned char t1_20msConversion = 5;
unsigned char t1_20msCounter = 0;

static unsigned char onBit = 1; // set ON output value

// counter to set startup calibration time
static int startupCounter = 0;
static int maxStartupCounter = 250; //50Hz * 5sec

static float dataBuffer = 0.0; // current skin resistance value
static float meanData = 0.0; // average skin resistance value

// period over which data is smoothed
static float smoothPeriod = 1.0;
static const float maxSmoothPeriod = 15.0; //50Hz/15=3.33Hz

// period over which average skin resistance is calculated
static float normPeriod = 1.0;
static const float maxNormPeriod = 50.0; //50Hz * 1sec

// initializes output arrays to use the SetOutputs function
#define NUMLEDS 5
#define NUMLEDPINS 10
volatile near unsigned char * outPorts[NUMLEDPINS] = {
&LATC,
&LATC,

&LATC, // for RGB LEDs
// &LATA, // for RBG LEDs
&LATA,

&LATC,
&LATC,

&LATB,
&LATB,

&LATB,
&LATA,
};
unsigned char  outBits[NUMLEDPINS] = {
0b00001000, // for RGB LEDs
// 0b00000100, // for RBG LEDs
0b00000010,

0b00000001, // for RGB LEDs
// 0b01000000, // for RBG LEDs
0b10000000,

0b00100000, // for RGB LEDs
// 0b01000000, // for RBG LEDs
0b10000000,

0b00000001, // for RGB LEDs
// 0b00000010, // for RBG LEDs
0b00000100,

0b00001000, // for RGB LEDs
// 0b00010000, // for RBG LEDs
0b00000100
};
unsigned char outVals[NUMLEDPINS] = {
0,
0,

0,
0,

0,
0,

0,
0,

0,
0
};

// RGB pointers for keeping track of LED outputs
typedef struct {
unsigned char * r;
unsigned char * g;
unsigned char * b;
} RGBpointers;
RGBpointers outLEDs[NUMLEDS];


void main(void) {
unsigned short j;
float diffData;
float threshold;
float threshFactor = 0.24;
float threshOffset = 0.01;
unsigned char hue = 0;

init();

while(1) {
// turn all lights red for startup calibration
if (startupCounter < maxStartupCounter) {
for (j=0; j<NUMLEDS; j++) {
*outLEDs[j].r = onBit;
*outLEDs[j].b = !onBit;
}
} else {
// subtract baseline average
diffData = meanData - dataBuffer;

// determine if skin resistance deviation crosses the
// threshold for each LED
for (j=0; j<NUMLEDS; j++) {
// uses cubic function for thresholds across 5 LEDs
threshold = (float) (j*j*j);
threshold = ((threshold*threshFactor)+threshOffset) ;
if (diffData > threshold) {
*outLEDs[j].r = onBit;
*outLEDs[j].b = !onBit;
} else {
*outLEDs[j].r = !onBit;
*outLEDs[j].b = onBit;
}
}
}
}
}

//interrupt code:
#pragma code high_interrupt=0x08
void high_interrupt(void) {
_asm goto high_isr _endasm
}
#pragma code
//handle interrupts
#pragma interrupt high_isr
void high_isr(void) {
int j;
if ( INTCONbits.TMR0IF ) { // timer 0
INTCONbits.TMR0IF = 0;
WriteTimer0(131);

// converts timer triggers to 20ms
t1_20msCounter++;
if (t1_20msCounter == t1_20msConversion) {
t1_20msCounter = 0;

// Set the LEDs
SetOutputs(NUMLEDPINS,outVals,outPorts,outBits);

GetData(); // reads data from A/D
if (startupCounter < maxStartupCounter) {
startupCounter++;
}
}
}
}

// Load data into dataBuffer
void GetData(void) {
unsigned int tempData;

while( BusyADC() ); // Wait for completion
tempData = ReadADC(); // Read result
ConvertADC(); // Start conversion

// smooth the data
dataBuffer = dataBuffer*(smoothPeriod-1.0);
dataBuffer = dataBuffer + ((float) tempData);
dataBuffer = dataBuffer/smoothPeriod;
if (smoothPeriod < maxSmoothPeriod) {
smoothPeriod = smoothPeriod + 1.0;
} else {
// average the data to calculate baseline skin resistance
meanData = meanData*(normPeriod-1.0);
meanData = meanData + dataBuffer;
meanData = meanData/normPeriod;
if (normPeriod < maxNormPeriod) {
normPeriod = normPeriod + 1.0;
}
}
}




void init(void) {
unsigned char j;

// map output vector onto red and blue arrays
for (j=0;j<NUMLEDS;j++) {
outLEDs[j].r = &outVals[j*2];
outLEDs[j].b = &outVals[j*2+1];
*outLEDs[j].r = onBit;
*outLEDs[j].b = !onBit;
}


// Set INTOSC bits; 110=8MHz
OSCCONbits.IRCF2 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 0;

// select system clock; 1x=internal osc, 00=primary oscillator
OSCCONbits.SCS1 = 0;
OSCCONbits.SCS0 = 0;

OSCTUNEbits.PLLEN = 1; // turn on 4x PLL clock multiplier

//set outputs
TRISA = 0;
TRISB = 0;
TRISC = 0;
PORTA = 0b11111111;
PORTB = 0b11111111;
PORTC = 0b11111111;

// set inputs
TRISAbits.TRISA5 = 1;
TRISAbits.TRISA3 = 1;

// set analog channels
ANSELbits.ANS4 = 1;
ANSELbits.ANS3 = 1;


// set up timer
OpenTimer0(TIMER_INT_ON & // interrupt on
T0_8BIT & // 8 bit
T0_SOURCE_INT & // internal clock
T0_PS_1_256); // 1/256 clock speed


// Set A/D Channel; 0000=AN0, 0100=AN4
  ADCON0bits.CHS3 = 0;
  ADCON0bits.CHS2 = 1;
  ADCON0bits.CHS1 = 0;
  ADCON0bits.CHS0 = 0;

// Set VREF; 00=VSS,VDD
ADCON1bits.VCFG1 = 0; //Negative Voltage Reference
ADCON1bits.VCFG0 = 1; //Positive Voltage Reference

// Set A/D Result Format; 1=right just
ADCON2bits.ADFM = 1;

// Set A/D Conv clock; 010=32TOSC; 110=64TOSC
ADCON2bits.ADCS2 = 0;
ADCON2bits.ADCS1 = 1;
ADCON2bits.ADCS0 = 0;

// Set A/D TAD; 001=2TAD
ADCON2bits.ACQT2 = 0;
ADCON2bits.ACQT1 = 0;
ADCON2bits.ACQT0 = 1;

//Turn on AD
ADCON0bits.ADON = 1;


INTCONbits.GIE=1; // needed to make timer interrupt catch
ConvertADC(); // Start conversion (preps for first read)
WriteTimer0(0); // sets PreLoad

}


SetOutputs.c

Code: [Select]
//void SetOutputs(unsigned char numOuts,
// unsigned char outVals[],
// volatile near unsigned char * outPorts[],
// unsigned char outBits[]) {
// function to set outputs with outVals array rather than explicitly
// keeping track of port/bit configurations
// written by Sean Montgomery, 2008.08
void SetOutputs(unsigned char numOuts,
unsigned char outVals[],
volatile near unsigned char * outPorts[],
unsigned char outBits[]) {
unsigned char j;

// for (j=0;j<(sizeof(outVals)/sizeof(outVals[0]));j++) {
for (j=0;j<numOuts;j++) {
if (outVals[j]) {
*outPorts[j] = ((*outPorts[j]) | outBits[j]);
} else {
*outPorts[j] = ((*outPorts[j]) & (0b11111111 - outBits[j]));
}
}
}

SetOutputs.h

Code: [Select]
extern void SetOutputs(unsigned char numOuts,
unsigned char outVals[],
volatile near unsigned char * outPorts[],
unsigned char outBits[]);
« Last Edit: March 17, 2009, 04:10:21 PM by MaltiK »
Warranty

Offline Hawaii00000Topic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 347
  • Helpful? 2
Re: Modifying a homemade lie detector for micro controller use.
« Reply #3 on: March 17, 2009, 05:26:09 PM »
Why can't the first one be use with a microcontroller, and why does it need two batteries of different voltages?
"God chose to make the world according to very beautiful mathematics."
-Paul Dirac
**************************************************************
Its Hawaii Five-O. Get it?

Offline Hawaii00000Topic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 347
  • Helpful? 2
Re: Modifying a homemade lie detector for micro controller use.
« Reply #4 on: March 17, 2009, 07:29:47 PM »
What if I amplified the signal from this circuit . http://www.hackcanada.com/ice3/wetware/lie_detector_circuit_2.html
« Last Edit: March 18, 2009, 09:41:13 PM by Hawaii00000 »
"God chose to make the world according to very beautiful mathematics."
-Paul Dirac
**************************************************************
Its Hawaii Five-O. Get it?

 


Get Your Ad Here