Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: main.cpp
- Revision:
- 0:7a3f4ba1851c
- Child:
- 1:fac5c6ba2f07
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Sun Jun 02 16:04:19 2013 +0000
@@ -0,0 +1,235 @@
+/* Mindwave Mobile demo - Bob Stone June 2013
+ * Basic demo of reading data packets from Neurosky's Mindwave Mobile headset
+ * via BlueSMIRF Silver bluetooth modem.
+ * Adapted from http://developer.neurosky.com/docs/doku.php?id=mindwave_mobile_and_arduino
+ *
+ * Connect pin9 to BlueSMIRF's RX and pin10 to BlueSMIRF's TX,
+ * also hook up GND to GND and VCC to the mbed's 3V3 supply.
+ *
+ * To prepare the BlueSMIRF to auto-connect to the Mindwave Mobile:
+ *
+ * First wire it up and power it using the mbed's power pins. Once it's powered,
+ * pair your computer to the Mindwave Mobile headset to you can
+ * find out its MAC address. Write that down as you will need it.
+ *
+ * Next pair your computer to the BlueSMIRF so we can configure it. It will
+ * appear as RN-42-5922 or similar (it's a Roving Networks RN-42 unit).
+ *
+ * Now we can use a terminal program to connect to the serial modem created on
+ * your computer that connects wirelessly to the BlueSMIRF - by default it's at
+ * 115200 baud, 8 N 1 - when you're connected the light will go green.
+ *
+ * If you've got a successful serial connection, put it into command mode by
+ * typing three dollar signs $$$ - if successful you should see a prompt saying
+ * 'CMD'. If not, power it down and try again till you get a CMD prompt.
+ *
+ * At that prompt we need to change some defaults so that the BlueSMIRF is set to
+ * master mode, 57600 baud and sends a pincode of '0000', and seeks to connect to
+ * the headset's MAC address. To do this, type:
+ * SP,0000
+ * SM,3
+ * SR,<the 12 digit MAC address of the headset written down earlier>
+ * SU,57.6
+ * D
+ * You should see AOK after each line, and after the D it will print out its
+ * settings so you can check it's now AUTO, 57600, using 0000 and the right MAC
+ * address. All being well, type three minuses '---' to exit command mode.
+ *
+ * To check it's working, close the terminal you've been using, reboot the
+ * BlueSMIRF (flashing red light) and switch on the Mindwave Mobile headset
+ * - the light on the BlueSMIRF should go green when it connects and the
+ * flashing blue light on the Mindwave Mobile headset should go steady blue.
+ */
+#include "mbed.h"
+Serial pc(USBTX, USBRX); //for debug
+Serial blueSmirf(p9, p10); //for bluetooth comms (TX, RX)
+
+//*****************************
+//User routines to process data
+//*****************************
+
+//This will be called if you blink.
+void blinked(void)
+{
+ printf("\nBlink!\n\n");
+}
+
+//This will be called when processed eSense data comes in, about once a second. If the
+//connection's good, poorQuality will be zero, if the connection's useless (e.g. ear clip
+//or forehead electrode not connected)it will be 200, and it can be somewhere in between
+//for varying degrees of confidence in the data. Values for attention and meditation are
+//0-100, and the time since last packet is in milliseconds.
+void eSenseData(int poorQuality, int attention, int meditation, int timeSinceLastPacket)
+{
+ if (poorQuality < 200) {
+ printf("PoorQuality: %d", poorQuality);
+ }
+ if (attention > 0) {
+ printf(" Attention: %d", attention);
+ }
+ if (meditation > 0) {
+ printf(" Meditation: %d", meditation);
+ }
+ printf(" Time since last packet: %d", timeSinceLastPacket);
+ printf("\n");
+}
+
+//This will be called when processed meter reading data arrives, about once a second.
+//This is a breakdown of frequencies in the wave data into 8 named bands, these are:
+// 0: Delta (0.5-2.75 Hz)
+// 1: Theta (3.5-6.75 Hz)
+// 2: Low-Alpha (7.5-9.25 Hz)
+// 3: High-Alpha (10-11.75 Hz)
+// 4: Low-Beta (13-16.75 Hz)
+// 5: High-Beta (18-29.75 Hz)
+// 6: Low-Gamma (31-39.75 Hz)
+// 7: High-Gamma (41-49.75 Hz)
+void meterData(int meter[8])
+{
+ printf("Meters: ");
+ for (int j=0; j<8; j++) {
+ printf("%d = %d, ", j, meter[j]);
+ }
+ printf("\n");
+}
+
+//This will be called when wave data arrives. There will be a lot of these,
+//512 a second, so if you're planning to do anything here, don't let it take long.
+//Best not to printf this out as it will just choke.
+void waveData(int wave)
+{
+}
+
+//*****************
+//End User routines
+//*****************
+
+//System routines to obtain and parse data
+//Simplify serial comms
+unsigned char ReadOneByte()
+{
+ int ByteRead;
+
+ while(!blueSmirf.readable());
+ ByteRead = blueSmirf.getc();
+
+ return ByteRead;
+}
+//Main loop, sets up and keeps listening for serial
+int main()
+{
+ Timer t; //packet timer
+ t.start();
+ Timer blinkTimer; //used for detecting blinks
+ int time;
+ int generatedChecksum = 0;
+ int checksum = 0;
+ int payloadLength = 0;
+ int payloadData[64] = {0};
+ int poorQuality = 0;
+ int attention = 0;
+ int meditation = 0;
+ int wave = 0;
+ int meter[8] = {0};
+
+ bool eSensePacket = false;
+ bool meterPacket = false;
+ bool wavePacket = false;
+
+ blueSmirf.baud(57600);
+ pc.baud(115200);
+ printf("\n\nStarted\n\n");
+ blinkTimer.reset();
+
+ while(1) {
+ // Look for sync bytes
+ if(ReadOneByte() == 170) {
+ if(ReadOneByte() == 170) {
+ //Synchronised to start of packet
+ payloadLength = ReadOneByte();
+ if(payloadLength > 169) //Payload length can not be greater than 169
+ return;
+
+ generatedChecksum = 0;
+ for(int i = 0; i < payloadLength; i++) {
+ payloadData[i] = ReadOneByte(); //Read payload into memory
+ generatedChecksum += payloadData[i];
+ }
+
+ checksum = ReadOneByte(); //Read checksum byte from stream
+ generatedChecksum = 255 - (generatedChecksum & 0xFF); //Take one's compliment of generated checksum
+
+ if(checksum == generatedChecksum) {
+ //Packet seems OK
+ poorQuality = 200;
+ attention = 0;
+ meditation = 0;
+ wave = 0;
+ for(int i = 0; i < payloadLength; i++) { // Parse the payload
+ switch (payloadData[i]) {
+ case 2: //quality
+ i++;
+ poorQuality = payloadData[i];
+ eSensePacket = true;
+ break;
+ case 4: //attention
+ i++;
+ attention = payloadData[i];
+ eSensePacket = true;
+ break;
+ case 5: //meditation
+ i++;
+ meditation = payloadData[i];
+ eSensePacket = true;
+ break;
+ case 0x80: //wave
+ wave = payloadData[i+2] * 256 + payloadData[i+3];
+ //We also want to try to detect blinks via analysing wave data
+ time = blinkTimer.read_ms();
+ if (wave > 32767) wave -= 65535; //cope with negatives
+ if (wave>200 && blinkTimer.read_ms() == 0) {
+ blinkTimer.start();
+ } else if (wave<-90 && time > 10 && time < 100) {
+ blinkTimer.stop();
+ blinkTimer.reset();
+ blinked();
+ } else if (time>500) {
+ blinkTimer.stop();
+ blinkTimer.reset();
+ }
+ i = i + 3;
+ wavePacket = true;
+ break;
+ case 0x83: //meter readings for different frequency bands
+ for (int j=0; j<8; j++) {
+ meter[j] = payloadData[i+j*3+2] + payloadData[i+j*3+3]*256 + payloadData[i+j*3+4]*65536;
+ }
+ meterPacket = true;
+ i = i + 25;
+ break;
+ default:
+ break;
+ } // switch
+ } // for loop
+
+ //Call routines to process data
+ if(eSensePacket) {
+ eSenseData(poorQuality, attention, meditation, t.read_ms());
+ eSensePacket = false;
+ }
+ if (meterPacket) {
+ meterData(meter);
+ t.reset();
+ meterPacket=false;
+ }
+ if (wavePacket) {
+ waveData(wave);
+ wavePacket=false;
+ }
+ } else {
+ // Checksum Error
+ } // end if else for checksum
+ } // end if read 0xAA byte
+ } // end if read 0xAA byte
+ }
+}
\ No newline at end of file