This is an old revision of the document!
A polygraph test is an instrument that measures and records physiological responses such as heart rate and electrical activity in the skin to assess whether or not someone is lying. With an Arduino Uno R3 ATmega328P, a heart rate sensor, an EKG/ECG sensor module, a precision temperature and humidity sensor SHT21, and a Bluetooth module (Master/Slave HC-05), you can build a custom polygraph system that can wirelessly transmit and record physiological data and analyze the results for deception detection or other purposes.
The concept arose from a basic curiosity about the mystery behind a lie detector, which led to a project in which, in addition to the device's already recognized utility, we have the possibility to study natural reactions of the human body in many scenarios that are difficult to manage.
The device employs three sensors: GY-21, AD8232, and HW-827, which are used to analyze uncontrolled reactions of a person in specific situations. These are processed by an ATmega328P in the loop function and a timer set every 100 ms, both collecting and processing the information received by the sensors and then sending it via Bluetooth to the phone.
I utilized Visual Studio Code (Platform.io) for software development and only SoftwareSerial.h and Wire.h as third-party libraries. Several constants are defined in the code, including the GY21 sensor address, temperature and humidity reading commands, and the threshold value for detecting heartbeats. It also specifies variables for recording the number of heartbeats, the period between heartbeats, and the latest heartbeat value. The threshold value is constantly adjusting itself in response to background noise.
The code has an ISR (Interrupt Service Routine) that is triggered by a timer (every 100 milliseconds). Based on the signal threshold, the ISR reads the analog signal from the heart monitor and updates the heartbeat count and time between heartbeats. It also sends the analog signal and the last bpm value to the Bluetooth interface. If the Hearth monitor does not detect anything and goes high on LO+ and LO-, the interrupt will be terminated.
ISR(TIMER1_COMPA_vect) { if((PINB & (1 << PB3)) || (PINB & (1 << PB2))) return; int signal = readADC(0); Threshold = (Threshold + signal) / 2; if(signal > Threshold && count == 0) { count = 1; if(beat == 0) time = micros() / 1000; } else if (signal < Threshold && count == 1) { beat++; count = 0; if(beat == 6) { time = micros() / 1000 - time; lastBeat = !lastBeat ? 60000 * 2 / time : (lastBeat + 60000 * 2 / time) / 2; lastBeat = lastBeat <= 0 ? 0 : lastBeat; time = 0; count = 0; beat = 0; } } signal = readADC(1); char result[60]; sprintf(result,"BMP %lu ECG %d",lastBeat,signal); BTserial.println(result); }
The loop() function uses I2C communication to read the temperature and humidity data from the GY21 sensor and displays them on the serial monitor and the Bluetooth terminal using the “USART0_transmit_string()” and “BTserial.println()” functions. It also incorporates a 5-second delay to prevent data overwhelming the Bluetooth interface.
void loop() { Wire.beginTransmission(GY21_ADDR); Wire.write(CMD_TEMP_HOLD); Wire.endTransmission(); delay(100); Wire.requestFrom(GY21_ADDR, 3); if (Wire.available() == 3) { uint16_t rawTemp = (Wire.read() << 8) | Wire.read(); rawTemp &= ~0x0003; tempC = -46.85 + 175.72 * (rawTemp / 65536.0); } Wire.beginTransmission(GY21_ADDR); Wire.write(CMD_HUMIDITY_HOLD); Wire.endTransmission(); delay(100); Wire.requestFrom(GY21_ADDR, 3); if (Wire.available() == 3) { uint16_t rawHumidity = (Wire.read() << 8) | Wire.read(); rawHumidity &= ~0x0003; humidity = -6.0 + 125.0 * (rawHumidity / 65536.0); } USART0_transmit_string(String("Temperature: " + String(tempC) + " C Humidity: " + String(humidity) + "%").c_str()); BTserial.println(String("Temperature: " + String(tempC) + " C Humidity: " + String(humidity) + "%")); delay(5000); }
Fişierele se încarcă pe wiki folosind facilitatea Add Images or other files. Namespace-ul în care se încarcă fişierele este de tipul :pm:prj20??:c? sau :pm:prj20??:c?:nume_student (dacă este cazul). Exemplu: Dumitru Alin, 331CC → :pm:prj2009:cc:dumitru_alin.