ArduDreamer

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();
  
  }  
}