Show Posts
Pages: [1]
1  Forum 2005-2010 (read only) / Exhibition / Re: ArduDreamer on: March 13, 2010, 02:00:16 pm
Thanks

Here's the schematic

2  Forum 2005-2010 (read only) / Exhibition / Re: ArduDreamer on: March 11, 2010, 12:13:16 pm
KST file for graphing the data (part 2).   I'll post schematic for the board soon.

Code:

  <curve>
    <tag>8</tag>
    <xvectag>DS-dream/1</xvectag>
    <yvectag>DS-dream/8</yvectag>
    <legend>REM Timeout</legend>
    <interp>0</interp>
    <hasMinus/>
    <color>#4f4c51</color>
    <hasLines/>
    <lineWidth>0</lineWidth>
    <lineStyle>0</lineStyle>
    <pointType>0</pointType>
    <pointDensity>0</pointDensity>
    <barStyle>0</barStyle>
  </curve>
  <plot>
    <border color="#000000" width="0" padding="0" margin="0" />
    <tag>P1</tag>
    <aspect x="0" y="0" w="1" h="1" />
    <idealsize w="1062" h="764" />
    <name>P1</name>
    <borderColor>#000000</borderColor>
    <borderWidth>0</borderWidth>
    <foregroundColor>#000000</foregroundColor>
    <backgroundColor>#ffffff</backgroundColor>
    <margin>0</margin>
    <padding>0</padding>
    <xscalemode>0</xscalemode>
    <yscalemode>6</yscalemode>
    <xscalemodedefault>0</xscalemodedefault>
    <yscalemodedefault>5</yscalemodedefault>
    <xmin>1268324681.1026</xmin>
    <xmax>1268325026.1234</xmax>
    <ymin>0</ymin>
    <ymax>1024</ymax>
    <xreversed>0</xreversed>
    <yreversed>0</yreversed>
    <yminexp>0</yminexp>
    <ymaxexp>1024</ymaxexp>
    <toplabel>
      <text></text>
      <interpret/>
      <rotation>0</rotation>
      <justify>1</justify>
      <fontfamily>DejaVu Sans</fontfamily>
      <size>12</size>
    </toplabel>
    <xlabel>
      <text>Column 1</text>
      <interpret/>
      <rotation>0</rotation>
      <fontfamily>DejaVu Sans</fontfamily>
      <size>12</size>
    </xlabel>
    <ylabel>
      <text></text>
      <interpret/>
      <rotation>270</rotation>
      <fontfamily>DejaVu Sans</fontfamily>
      <size>12</size>
    </ylabel>
    <xticklabel>
      <text>[0]</text>
      <interpret/>
      <rotation>0</rotation>
      <fontfamily>DejaVu Sans</fontfamily>
      <size>12</size>
    </xticklabel>
    <yticklabel>
      <text>1000</text>
      <interpret/>
      <rotation>0</rotation>
      <fontfamily>DejaVu Sans</fontfamily>
      <size>12</size>
    </yticklabel>
    <xfullticklabel>
      <text>03/11/2010 10:30:00 [seconds]</text>
      <interpret/>
      <rotation>0</rotation>
      <fontfamily>DejaVu Sans</fontfamily>
      <size>12</size>
    </xfullticklabel>
    <xlogbase>10</xlogbase>
    <ylogbase>10</ylogbase>
    <curvetag>4</curvetag>
    <curvetag>8</curvetag>
    <curvetag>5</curvetag>
    <curvetag>6</curvetag>
    <curvetag>7</curvetag>
    <curvetag>3</curvetag>
    <xmajorgrid>0</xmajorgrid>
    <ymajorgrid>0</ymajorgrid>
    <xminorgrid>0</xminorgrid>
    <yminorgrid>0</yminorgrid>
    <majorgridcolor>#808080</majorgridcolor>
    <minorgridcolor>#808080</minorgridcolor>
    <majorgridcolordefault>1</majorgridcolordefault>
    <minorgridcolordefault>1</minorgridcolordefault>
    <majorpenwidth>1</majorpenwidth>
    <minorpenwidth>1</minorpenwidth>
    <axispenwidth>1</axispenwidth>
    <xminorticks>-1</xminorticks>
    <yminorticks>-1</yminorticks>
    <xmajorticks>5</xmajorticks>
    <ymajorticks>5</ymajorticks>
    <xticksinplot>1</xticksinplot>
    <xticksoutplot>0</xticksoutplot>
    <yticksinplot>1</yticksinplot>
    <yticksoutplot>0</yticksoutplot>
    <suppresstop>0</suppresstop>
    <suppressbottom>0</suppressbottom>
    <suppressleft>0</suppressleft>
    <suppressright>0</suppressright>
    <xtransformed>0</xtransformed>
    <ytransformed>0</ytransformed>
    <xtransformedexp></xtransformedexp>
    <ytransformedexp></ytransformedexp>
    <xinterpret>1</xinterpret>
    <xinterpretas>1</xinterpretas>
    <xdisplayas>4</xdisplayas>
    <yinterpret>0</yinterpret>
    <yinterpretas>1</yinterpretas>
    <ydisplayas>4</ydisplayas>
    <xoffsetmode>0</xoffsetmode>
    <yoffsetmode>0</yoffsetmode>
    <stylemarker>0</stylemarker>
    <widthmarker>0</widthmarker>
    <colormarker>#000000</colormarker>
    <defaultcolormarker>1</defaultcolormarker>
    <autoLabelTop>1</autoLabelTop>
    <autoLabelX>1</autoLabelX>
    <autoLabelY>1</autoLabelY>
  </plot>
  <window>
    <tag>W1</tag>
    <restore x="2" y="2" w="1062" h="764" />
    <internal x="2" y="2" w="1062" h="764" />
    <name>W1</name>
    <backgroundColor>#efefef</backgroundColor>
    <Plot>
      <tag>P1</tag>
      <Legend>
        <border color="#000000" width="2" padding="0" margin="0" />
        <border color="#000000" width="2" padding="0" margin="0" />
        <tag>Object 165</tag>
        <aspect x="0.028248587570621" y="0.73429319371728" w="0.2" h="0.1" />
        <idealsize w="1" h="1" />
        <name>unnamed</name>
        <borderColor>#000000</borderColor>
        <borderWidth>2</borderWidth>
        <foregroundColor>#000000</foregroundColor>
        <backgroundColor>#ffffff</backgroundColor>
        <margin>0</margin>
        <padding>0</padding>
        <font></font>
        <fontSize>1</fontSize>
        <transparent>false</transparent>
        <trackContents>false</trackContents>
        <legendMargin>5</legendMargin>
        <vertical>true</vertical>
        <title></title>
        <curvetag>3</curvetag>
        <curvetag>5</curvetag>
        <curvetag>6</curvetag>
        <curvetag>7</curvetag>
        <curvetag>8</curvetag>
      </Legend>
    </Plot>
  </window>
</kstdoc>
3  Forum 2005-2010 (read only) / Exhibition / Re: ArduDreamer on: March 11, 2010, 12:12:28 pm
KST file for graphing the data (part 1)

Code:
<?xml version="1.0" encoding="UTF-8"?>
<kstdoc version="1.3">
  <windowsize>
    <width>1066</width>
    <height>853</height>
    <active name="W1"/>
  </windowsize>
  <graphicsautosave time="1" enabled="false" format="PNG" xsize="640" ysize="480" display="0" square="false" />
  <kstfile>
    <tag>DS-dream</tag>
    <filename>/home/user/dream</filename>
    <type>ASCII</type>
    <index vector="INDEX" interpretation="1"/>
    <comment delimiters="#/c!;"/>
    <columns type="2" delimiters=","/>
    <header start="10"/>
  </kstfile>
  <scalar>
    <tag>P1/XMin</tag>
    <orphan/>
    <value>1268324681.1026</value>
  </scalar>
  <scalar>
    <tag>P1/XMax</tag>
    <orphan/>
    <value>1268325026.1234</value>
  </scalar>
  <scalar>
    <tag>P1/YMin</tag>
    <orphan/>
    <value>0</value>
  </scalar>
  <scalar>
    <tag>P1/YMax</tag>
    <orphan/>
    <value>1024</value>
  </scalar>
  <vector>
    <tag>DS-dream/1</tag>
    <provider>DS-dream</provider>
    <filename>/home/user/dream</filename>
    <field>1</field>
    <start>0</start>
    <num>-1</num>
  </vector>
  <vector>
    <tag>DS-dream/1-1</tag>
    <provider>DS-dream</provider>
    <filename>/home/user/dream</filename>
    <field>1</field>
    <start>0</start>
    <num>-1</num>
  </vector>
  <vector>
    <tag>DS-dream/3</tag>
    <provider>DS-dream</provider>
    <filename>/home/user/dream</filename>
    <field>3</field>
    <start>0</start>
    <num>-1</num>
  </vector>
  <vector>
    <tag>DS-dream/4</tag>
    <provider>DS-dream</provider>
    <filename>/home/user/dream</filename>
    <field>4</field>
    <start>0</start>
    <num>-1</num>
  </vector>
  <vector>
    <tag>DS-dream/5</tag>
    <provider>DS-dream</provider>
    <filename>/home/user/dream</filename>
    <field>5</field>
    <start>0</start>
    <num>-1</num>
  </vector>
  <vector>
    <tag>DS-dream/6</tag>
    <provider>DS-dream</provider>
    <filename>/home/user/dream</filename>
    <field>6</field>
    <start>0</start>
    <num>-1</num>
  </vector>
  <vector>
    <tag>DS-dream/7</tag>
    <provider>DS-dream</provider>
    <filename>/home/user/dream</filename>
    <field>7</field>
    <start>0</start>
    <num>-1</num>
  </vector>
  <vector>
    <tag>DS-dream/8</tag>
    <provider>DS-dream</provider>
    <filename>/home/user/dream</filename>
    <field>8</field>
    <start>0</start>
    <num>-1</num>
  </vector>
  <curve>
    <tag>1-1</tag>
    <xvectag>DS-dream/1</xvectag>
    <yvectag>DS-dream/1-1</yvectag>
    <legend></legend>
    <interp>0</interp>
    <hasMinus/>
    <color>#00aa00</color>
    <hasLines/>
    <lineWidth>0</lineWidth>
    <lineStyle>0</lineStyle>
    <pointType>0</pointType>
    <pointDensity>0</pointDensity>
    <barStyle>0</barStyle>
  </curve>
  <curve>
    <tag>3</tag>
    <xvectag>DS-dream/1</xvectag>
    <yvectag>DS-dream/3</yvectag>
    <legend>EOG</legend>
    <interp>0</interp>
    <hasMinus/>
    <color>#009999</color>
    <hasLines/>
    <lineWidth>0</lineWidth>
    <lineStyle>0</lineStyle>
    <pointType>0</pointType>
    <pointDensity>0</pointDensity>
    <barStyle>0</barStyle>
  </curve>
  <curve>
    <tag>4</tag>
    <xvectag>DS-dream/1</xvectag>
    <yvectag>DS-dream/4</yvectag>
    <legend></legend>
    <interp>0</interp>
    <hasMinus/>
    <color>#000001</color>
    <lineWidth>0</lineWidth>
    <lineStyle>0</lineStyle>
    <pointType>0</pointType>
    <pointDensity>0</pointDensity>
    <hasBars/>
    <barStyle>1</barStyle>
  </curve>
  <curve>
    <tag>5</tag>
    <xvectag>DS-dream/1</xvectag>
    <yvectag>DS-dream/5</yvectag>
    <legend>Delay Timeout</legend>
    <interp>0</interp>
    <hasMinus/>
    <color>#990099</color>
    <hasLines/>
    <lineWidth>0</lineWidth>
    <lineStyle>0</lineStyle>
    <pointType>0</pointType>
    <pointDensity>0</pointDensity>
    <barStyle>0</barStyle>
  </curve>
  <curve>
    <tag>6</tag>
    <xvectag>DS-dream/1</xvectag>
    <yvectag>DS-dream/6</yvectag>
    <legend>REM Threshold (R)</legend>
    <interp>0</interp>
    <hasMinus/>
    <color>#ff0000</color>
    <hasLines/>
    <lineWidth>0</lineWidth>
    <lineStyle>0</lineStyle>
    <pointType>0</pointType>
    <pointDensity>0</pointDensity>
    <barStyle>0</barStyle>
  </curve>
  <curve>
    <tag>7</tag>
    <xvectag>DS-dream/1</xvectag>
    <yvectag>DS-dream/7</yvectag>
    <legend>REM Threshold (L)</legend>
    <interp>0</interp>
    <hasMinus/>
    <color>#1717c8</color>
    <hasLines/>
    <lineWidth>0</lineWidth>
    <lineStyle>0</lineStyle>
    <pointType>0</pointType>
    <pointDensity>0</pointDensity>
    <barStyle>0</barStyle>
  </curve>
4  Forum 2005-2010 (read only) / Exhibition / Re: ArduDreamer on: March 11, 2010, 12:08:49 pm
I use this on the PC side to collect the data from arduino and output it to the file KST monitors for graphing.  Theres no flow control between the arduino and PC so it does some checks to make sure the data "looks" correct since it sometimes gets messed up if the receive buffer overflows

Code:
#include <sys/timeb.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc,char *argv[])
{
        struct timeb tp;
        ftime(&tp);

        FILE * outfile;
        FILE * serial;

        serial = fopen(argv[1], "w+");
        outfile = fopen("dream", "w");

        //sync time on arduino
        fprintf(serial, "#startTime=startTime");

        char data[100];
        char buff[100];

        char *pdata = data;
        char *pbuff = buff;

        int seps = 0;

        unsigned long a_ms;
        int a_eog;
        int a_rem;
        int a_delay;
        int a_eoghi;
        int a_eoglo;
        int a_remt;

        unsigned long pa_ms = 0;

        int go = 0;

        while (1)
        {
                pdata = data;
                pbuff = buff;
                a_ms = 0;
                a_rem = -1;
                a_delay = -1;
                a_eoghi = -1;
                a_eoglo = -1;
                a_remt = -1;
                seps = 0;

                fgets(data, 100, serial);

                //parse string from arduino
                while(*pdata != '\0') {
                        if(*pdata == ',' || *pdata == '\r' || *pdata == '\n') {
                                *pbuff = '\0';
                                if(seps == 0)
                                        a_ms = atoi(buff);
                                else if(seps == 1)
                                        a_eog = atoi(buff);
                                else if(seps == 2)
                                        a_rem = atoi(buff);
                                else if(seps == 3)
                                        a_delay = atoi(buff);
                                else if(seps == 4)
                                        a_eoghi = atoi(buff);
                                else if(seps == 5)
                                        a_eoglo = atoi(buff);
                                else if(seps == 6)
                                        a_remt = atoi(buff);
                                seps++;

                                pbuff = buff;
                                pdata++;
                                continue;
                                if(*pdata == '\r' || *pdata == '\n')
                                        break;
                        } else {
                                *pbuff++ = *pdata++;
                        }
                }

                //do some data sanity checks
                if(seps != 8)
                        continue;
                if(a_ms < 1)
                        continue;
                if(a_eog < 0 || a_eog > 1024)
                        continue;
                if(a_rem != 0 && a_rem != 1024)
                        continue;
                if(a_delay < 0  || a_delay > 1024)
                        continue;
                if(a_eoghi < 512 || a_eoghi > 1024)
                        continue;
                if(a_eoglo < 0 || a_eoglo > 512)
                        continue;
                if(a_remt < 0 || a_remt > 1024)
                        continue;

                //dont log until timer resets on arduino
                if(!go) {
                        if(a_ms > 1000) {
                                printf("%i,%d\n", go, a_ms);
                                continue;
                        } else {
                                printf("%i,%d\n", go, a_ms);
                                go = 1;
                        }
                }

                //use timer from arduino as offset to start time
                int msec = a_ms % 1000;
                a_ms = a_ms/1000 + tp.time;
                if(a_ms > pa_ms + 1) {
                        pa_ms = a_ms;
                        continue;
                }
                msec = msec + tp.millitm;
                if(msec > 999) {
                        msec = msec - 1000;
                        a_ms++;
                }

                //need msec displayed as thousandths with no leading 0
                char fs[10];
                float f = msec;
                sprintf(fs, "%.3f", f/1000);
                char *fp = fs[1];

                //write to log
                fprintf(outfile,"%ld%s,%s",a_ms,fp,data);
        }
        fclose(serial);
        fclose(outfile);
        return 0;
}
5  Forum 2005-2010 (read only) / Exhibition / Re: ArduDreamer on: March 11, 2010, 12:05:28 pm
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..

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();
  
  }  
}
6  Forum 2005-2010 (read only) / Exhibition / Re: ArduDreamer on: March 06, 2010, 12:32:32 pm
Hah cool, I think EOG is the way to go with this type of thing (and it's just cool).

The Serial C# grapher that got posted inspired me to write an app to go with this.  I've been using KST in linux to do the graphing, but now I'm going to try writing my own specifically for this, maybe with an integrated dream journal to tie journal entries with the graphs.  And it'd be nice to configure everything from an app instead of accessing a menu through minicom.
7  Forum 2005-2010 (read only) / Exhibition / Re: ArduDreamer on: March 06, 2010, 10:59:16 am
Cool.  I'm waiting on a couple different types of sleep masks and the reusable electrodes to come in.  The adhesive ones I've been using leave nasty red marks next to my eyes after wearing them so my GF has kindly asked my to stop using them =)
8  Forum 2005-2010 (read only) / Exhibition / Re: ArduDreamer on: March 06, 2010, 09:47:56 am
I got the ICs from Texas Instruments (INA126P & TLV2472), Analog Devices (AD5204), and Maxim (DS1307).  The passive components and atmega168 I got from digikey.   If you want to try building one I would recommend the atmega328 instead, digi was just out of them when I ordered stuff.

The only schematic I have right now is from when I was figuring out the EOG circuit in pspice:



Some things I changed since that schematic: I just power it from FTDI now so I got rid of the 9V battery and 7805.    I took out the TLV2472 from the virtual ground circuit and replaced it with an LM358.   I reused the TLV2472 to cascade two more 40Hz low pass filters before the final amplification.   I replaced the 280ohm resistor in the instrumentation amplifier with a channel on the AD5204.  I replaced the 270K resistor on the final amp circuit with a 150K, and I replaced the 10K resistor on the final amp circuit with another channel on the AD5204.  

The rest of it I just made as I went on the breadboard so I dont have any schematics right now, but Im going to build a PCB for this and I can post the full schematic after I get it in to eagle
9  Forum 2005-2010 (read only) / Exhibition / Re: ArduDreamer on: March 04, 2010, 02:28:07 pm
Thanks!  I found a company that was kind enough to send me a couple samples of some really nice electrodes to use with this so hopefully that will clean up the signal a bit.  
10  Forum 2005-2010 (read only) / Exhibition / ArduDreamer on: March 04, 2010, 01:18:48 pm
I built this as I went so the layout is pretty messy =)

The user wears a headband that has electrodes placed at the temples.  The left and right eye movements are tracked.  The gain of the op amps in the electrooculogram circuit are controlled by the arduino through an AD5204 digital pot to allow for an automatic calibration routine.

You put on the headband and power up the board, and it outputs eye movement, unix timestamp and REM status to a computer for graphing.   It waits a set amount of time for you to fall asleep, and then monitors your eye movements to detect the REM stage of sleep (when you are dreaming).  When it detects REM, it blinks LEDs mounted in front of your eyes to give you a hint that you are dreaming to help you become lucid (http://en.wikipedia.org/wiki/Lucid_dream).  When the REM ends, it can wake you up so you can remember the dream better.

Since your physical eye movements match your dream eye movements, movement sequences can be programmed so that you can interact with it while you are in a lucid dream (like turn the flashing LEDs off, or make notes in the log, i.e. I'm Lucid)

It also has a built in alarm clock that can wake you up at a set time in the morning.  

I got the idea from some experiments Stephen Laberge did at Stanford university

http://www.lucidity.com/slbbs/index.html

I had found a device called "RemDreamer" that could flash LEDs when you were in REM but it couldn't output a graph of exact eye movements and was pretty expensive so I decided to make my own.

It's working but I still need to make a PCB for it and integrate it into a sleep mask.


I was able to get all of the ICs except the atmega168 as free samples so the cost for this was about $15.

It uses an LM358, INA126P, 2x TLV2472, AD5204, DS1307, Atmega168 w/arduino bootloader and is powered via FTDI cable.




This is the eye movement output of a 3 hour afternoon nap:

I'm pretty happy that it all actually works and just wanted to share =)
Pages: [1]