Society of Robots - Robot Forum
Electronics => Electronics => Topic started by: Hawaii00000 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 (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?
-
Hi,
In short, no.
Lots of circuits that can be used exists however, try locating an op-amp based circuit.
-
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:
(http://courses.cit.cornell.edu/ee476/FinalProjects/s2005/ck245/476Web/476Web/gsr.gif)
But if you DO wish to use an MCU still I found a schematic and .c files a while ago:
(http://www.produceconsumerobot.com/truth/content/TruthKit_08_Eagle_200.png)
(http://www.produceconsumerobot.com/truth/content/TruthKit_08_Eagle_board_600.png)
main.c
/* 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
//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
extern void SetOutputs(unsigned char numOuts,
unsigned char outVals[],
volatile near unsigned char * outPorts[],
unsigned char outBits[]);
-
Why can't the first one be use with a microcontroller, and why does it need two batteries of different voltages?
-
What if I amplified the signal from this circuit . http://www.hackcanada.com/ice3/wetware/lie_detector_circuit_2.html (http://www.hackcanada.com/ice3/wetware/lie_detector_circuit_2.html)