I got the code somewhat cleaned up. I removed the speaker since it kept waking up my GF. I removed the DS1307 in favor of using a running timer and syncing time on the PC. The PC can give commands to the arduino by sending "#key=value" over the serial connection. The PC gets updates from the arduino at about 375Hz using 115200 baud.
I decided to skip doing a custom app, not worth the work since I got my issues with KST resolved
The autocalibration didn't work all that great, I found it easier to look at the graph and adjust the gains by hand. Would be nice to get it working tho.
Here's the arduino code..
#include <EEPROM.h>
#include <string.h>
#define BAUDRATE 115200
//pins
#define pLED 7
#define pMOSI 11
#define pMISO 12
#define pSCK 13
#define pCS 10
#define pAMP1OUT 2
#define pAMP2OUT 3
//rheostats
#define rAMP1 3
#define rAMP2 1
#define rLED 2
//button interrupts
#define bDELAY 0
#define bTEST 1
struct config_t {
int ledBrightness;
int ledOnTime;
int ledOffTime;
int delayTime;
int REMAlarm;
int EOGREMHi;
int EOGREMLo;
int amp1Gain;
int amp2Gain;
int REMTime;
int testTime;
} config;
unsigned long thisMillis = 0;
unsigned long lastMillis = 0;
unsigned long REMStop = 0;
unsigned long testStop = 0;
unsigned long delayStop = 0;
unsigned long startTime = 0;
int ledOn = 0;
char buff[100];
template <class T> int EEPROM_write(int ee, const T& value)
{
const byte* p = (const byte*)(const void*)&value;
int i;
for (i = 0; i < sizeof(value); i++)
EEPROM.write(ee++, *p++);
return i;
}
template <class T> int EEPROM_read(int ee, T& value)
{
byte* p = (byte*)(void*)&value;
int i;
for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++);
return i;
}
char spi_transfer(volatile char data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
{
};
return SPDR; // return the received byte
}
byte write_pot(int address, int value)
{
digitalWrite(pCS,LOW);
//2 byte opcode
spi_transfer(address);
spi_transfer(value);
digitalWrite(pCS,HIGH); //release chip, signal end transfer
}
void setDelay() {
delayStop = config.delayTime;
delayStop = delayStop * 1000 + millis();
REMStop = 0;
digitalWrite(pLED, LOW);
}
void reality() {
testStop = config.testTime;
testStop = testStop * 1000 + millis();
}
void setup()
{
Serial.begin(BAUDRATE);
byte clr;
pinMode(pMOSI, OUTPUT);
pinMode(pMISO, INPUT);
pinMode(pSCK, OUTPUT);
pinMode(pCS, OUTPUT);
pinMode(pLED, OUTPUT);
digitalWrite(pCS, HIGH);
SPCR = (1<<SPE)|(1<<MSTR);
clr = SPSR;
clr = SPDR;
delay(10);
EEPROM_read(0, config);
write_pot(rAMP1, config.amp1Gain);
write_pot(rAMP2, config.amp2Gain);
write_pot(rLED, config.ledBrightness);
attachInterrupt(bDELAY, setDelay, LOW);
attachInterrupt(bTEST, reality, LOW);
}
void doInput() {
char key[25];
char value[25];
if(Serial.read() != '#') {
Serial.flush();
return;
}
for(int i = 0; i < 25; i++) {
char c = Serial.read();
if(c == '=') {
key[i] = '\0';
break;
} else {
key[i] = c;
}
}
for(int i = 0; i < 25; i++) {
char c = Serial.read();
if(c == '\r' || c == '\n') {
value[i] = '\0';
break;
} else {
value[i] = c;
}
}
if(!strcmp("amp1Gain", key)) {
if(!strcmp("u", value)) {
if(config.amp1Gain < 255)
config.amp1Gain++;
} else if(!strcmp("d", value)) {
if(config.amp1Gain > 0)
config.amp1Gain--;
} else {
config.amp1Gain = atoi(value);
}
write_pot(rAMP1, config.amp1Gain);
} else if(!strcmp("amp2Gain", key)) {
if(!strcmp("u", value)) {
if(config.amp2Gain < 255)
config.amp2Gain++;
} else if(!strcmp("d", value)) {
if(config.amp2Gain > 0)
config.amp2Gain--;
} else {
config.amp2Gain = atoi(value);
}
write_pot(rAMP2, config.amp2Gain);
} else if(!strcmp("EOGREMHi", key)) {
if(!strcmp("u", value)) {
if(config.EOGREMHi < 1024)
config.EOGREMHi++;
} else if(!strcmp("d", value)) {
if(config.EOGREMHi > 0)
config.EOGREMHi--;
} else {
config.EOGREMHi = atoi(value);
}
} else if(!strcmp("EOGREMLo", key)) {
config.EOGREMLo = atoi(value);
} else if(!strcmp("ledBrightness", key)) {
config.ledBrightness = atoi(value);
write_pot(rLED, config.ledBrightness);
} else if(!strcmp("ledOnTime", key)) {
config.ledOnTime = atoi(value);
} else if(!strcmp("ledOffTime", key)) {
config.ledOffTime = atoi(value);
} else if(!strcmp("delayTime", key)) {
config.delayTime = atoi(value);
} else if(!strcmp("REMAlarm", key)) {
config.REMAlarm = atoi(value);
} else if(!strcmp("REMTime", key)) {
config.REMTime = atoi(value);
} else if(!strcmp("testTime", key)) {
config.testTime = atoi(value);
} else if(!strcmp("startTime", key)) {
startTime = millis();
}
EEPROM_write(0, config);
}
void loop()
{
if(Serial.available()) {
doInput();
} else {
thisMillis = millis();
int eog = analogRead(pAMP2OUT);
if(eog >= config.EOGREMHi || eog <= config.EOGREMLo) {
if(thisMillis < delayStop) {
delayStop = config.delayTime;
delayStop = delayStop * 1000 + thisMillis;
} else if(!REMStop) {
REMStop = config.REMTime;
REMStop = REMStop * 1000 + thisMillis;
digitalWrite(pLED, HIGH);
ledOn = 1;
lastMillis = thisMillis;
} else {
REMStop = config.REMTime;
REMStop = REMStop * 1000 + thisMillis;
}
}
if(REMStop && thisMillis > REMStop) {
REMStop = 0;
digitalWrite(pLED, LOW);
}
if(REMStop || thisMillis < testStop) {
if(!ledOn) {
if(thisMillis - lastMillis >= config.ledOffTime) {
digitalWrite(pLED, HIGH);
ledOn = 1;
lastMillis = thisMillis;
}
} else {
if(thisMillis - lastMillis >= config.ledOnTime) {
digitalWrite(pLED, LOW);
ledOn = 0;
lastMillis = thisMillis;
}
}
}
if(testStop && thisMillis > testStop) {
testStop = 0;
digitalWrite(pLED, LOW);
}
//EOG,REM,SLEEPDELAY,AMP1GAIN,AMP1OUT,AMP2GAIN,EOGREMHI,EOGREMLO,REMTIMEOUT
Serial.print(thisMillis - startTime);
Serial.print(",");
Serial.print(eog);
Serial.print(",");
if(REMStop) { Serial.print("1024"); } else { Serial.print("0"); }
Serial.print(",");
if(delayStop > thisMillis) {
unsigned long x = config.delayTime;
Serial.print(map(delayStop - thisMillis, 0, x * 1000, 0, 1024));
} else {
Serial.print("0");
}
Serial.print(",");
//Serial.print(map(config.amp1Gain,0,255,0,1024));
//Serial.print(",");
//Serial.print(analogRead(pAMP1OUT));
//Serial.print(",");
//Serial.print(map(config.amp2Gain,0,255,0,1024));
//Serial.print(",");
Serial.print(config.EOGREMHi);
Serial.print(",");
Serial.print(config.EOGREMLo);
Serial.print(",");
if(thisMillis > REMStop) {
Serial.print("0");
} else {
unsigned long y = config.REMTime;
Serial.print(map(REMStop - thisMillis, 0, y * 1000, 0, 1024));
}
Serial.println();
}
}