From fabbe14814233e635b95906f5d00285794c0ed80 Mon Sep 17 00:00:00 2001 From: dakkar Date: Fri, 29 Apr 2016 16:10:41 +0100 Subject: start using a vcs --- eeg.ino | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 eeg.ino diff --git a/eeg.ino b/eeg.ino new file mode 100644 index 0000000..ccdae1e --- /dev/null +++ b/eeg.ino @@ -0,0 +1,168 @@ +#include +#include + +#include + +#define MK_FREQ 49600L // Set clock to 50kHz (actualy 49.6kHz seems to work better) +#define SOUND (byte)0x52 // Sound controller (device ID 82). Write to 0xA4, read from 0xA5. +#define BUTTON (byte)0x50 // Button controller (device ID 80). Write to 0xA0, read from 0xA1. +#define MOTOR (byte)0x55 // Motor controller (device ID 85). Write to 0xAA, read from 0xAB. + +class Keepon { + private: + struct Command { + byte device; + byte command; + byte arg; + }; + static const byte qLen = 10; + static const byte maxAttempts = 50; + Command queue[qLen]; + byte qHead,qTail; + byte attempts; + + bool queue_empty() { + return qHead == qTail; + } + bool queue_full() { + return ((qHead+qLen-1)%qLen) == qTail; + } + Command* queue_current() { + return &queue[qHead]; + } + void queue_remove() { + if (queue_empty()) return; + qHead++; + qHead %= qLen; + } + void queue_add(byte d,byte c, byte a) { + if (queue_full()) return; + + queue[qTail].device=d; + queue[qTail].command=c; + queue[qTail].arg=a; + + qTail++; + qTail %= qLen; + } + + public: + Keepon() { + qHead = 0; + qTail = 0; + attempts = 0; + } + void begin() { + pinMode(SDA, OUTPUT); // Data wire on My Keepon + pinMode(SCL, OUTPUT); // Clock wire on My Keepon + digitalWrite(SDA, LOW); + digitalWrite(SCL, LOW); + } + void bootup(void(*cb)(bool)) { + digitalWrite(SDA, LOW); + digitalWrite(SCL, LOW); + cb(false); + while (analogRead(0) < 512); // Wait until we see voltage on A0 pin + cb(true); + delay(1000); + Wire.begin(); + TWBR = ((F_CPU / MK_FREQ) - 16) / 2; + } + void send() { + if (attempts > maxAttempts) { + attempts = 0; + queue_remove(); + } + if (queue_empty()) return; + + Command* current = queue_current(); + Wire.beginTransmission(current->device); + Wire.write(current->command); + Wire.write(current->arg); + int result = (int)Wire.endTransmission(); + if (result == 0) { + queue_remove(); + attempts = 0; + } + else { + attempts++; + } + } + + void pan(byte pos) { + queue_add(MOTOR,4,pos); + } + void tilt(byte pos) { + queue_add(MOTOR,2,pos); + } +}; + +Brain brain(Serial); +Keepon keepon; + +void kscan_callback(bool found) { + if (not found) { + uView.clear(PAGE); + uView.setCursor(0,0);uView.println("K?"); + uView.display(); + } + else { + uView.clear(PAGE); + uView.setCursor(0,0);uView.println("K!"); + uView.display(); + } +} + +void setup() { + Serial.begin(9600); + + uView.begin(); + uView.clear(ALL); + uView.setFontType(0); + + keepon.begin(); + keepon.bootup(&kscan_callback); +} + +const int hist_width=3; +const int hist_pad=1; +int samples_delay; + +void loop() { + byte attention, meditation, quality; + if (brain.update()) { + uView.clear(PAGE); + + uView.setCursor(0,0); uView.print(quality=brain.readSignalQuality()); + + uView.setCursor(0,9); uView.print(attention=brain.readAttention()); + uView.setCursor(18,9); uView.print(meditation=brain.readMeditation()); + + const uint32_t* power = brain.readPowerArray(); + uint32_t max_value=0; + for (int x=0;x<8;++x) { + if (power[x] > max_value) { + max_value = power[x]; + } + } + + for (int x=0;x<8;++x) { + int x0 = (hist_width + hist_pad) * x; + // we have 30 vertical pixels + int height = power[x] * 30 / max_value; + for (int o=0;o 5) { + keepon.pan(attention); + keepon.tilt(meditation); + samples_delay=0; + + uView.setCursor(5,0);uView.print("sent"); + } + + uView.display(); + } + keepon.send(); +} \ No newline at end of file -- cgit v1.2.3