-
-
Hi, what's the best practice for making sure the SD card gets properly unmounted? Of course this could be done with a button, but that's cumbersome.
I'm developing a logger for my brainwave recorder which basically is supposed to write data to the SD card for hours at a low data rate. The way I'm currently doing it is I append the new data to a variable and every 5 seconds I append the contents of that variable to a file and immediately unmount the SD. I also turn on an LED while this takes place. That way, the user can easily turn off the device or remove the SD in the 5 second intervals while the LED is off.
Is there anything bad about unmounting and re-mounting the SD all the time? Any other reason why this is bad practice?
-
@d0773d, the NeuroSky Mindwave Mobile (sold by sparkfun) uses the exact same ASIC module (TGAM) and is actually made by the company who developed that chip. I know this headset because I have that one as well. The idea behind the product is that anybody should be able to develop EEG applications without having to care about hardware or interfacing a board. Besides the TGAM, the headset includes a Bluetooth module which can be paired with a computer or a smartphone. It also comes with a driver for PC and Mac which can be used from your own applications so you don't have to mess with the low level protocol. That product makes sense (this is why I bought it) and you can easily develop computer or mobile applications which use it.
However, for my lucidity project, I want to make an integrated self-contained device. I don't want to stream data over bluetooth, I want to have my Espruino directly in the unit. Furthermore I wouldn't want to sleep with that headset on, I'll rater make my own which should be more comfortable. A good thing about the headset is that it has great signal quality through the integrated electrodes. My own design with the penny electrodes still triggers a "poor signal" message and the chip refuses to calculate attention and meditation values if "poor signal" is greater than 0. I need to keep working on my electrodes.
If you're interested in the headset, I'd sell mine for a good price. I'm in Germany.
-
Anybody else working on brain waves?
I have successfully hooked up a TGAM (a tiny EEG module) to my Espruino board. I extracted my TGAM from a Mattel MindFlex game that I bought used for 20€ on ebay.
As electrodes I am using 1 cent coins from the US whose coating I removed with a dremel rotation tool. I have glued them onto a strap of tissue to be worn on the forehead. In order to measure brain waves, at least three electrodes are needed: a signal electrode, a ground electrode and a referece electrode. The TGAM basically measures the voltage between ground and signal and uses the voltage between ground and reference to determine noise.
Communication with the TGAM is nasty, but I developed an Espruino module for that. I just created a pull request for it, so hopefully it will soon be merged and available for the benefit of all.
So far I'm successfully dumping brain wave spectral data to console. My first goal with this project is to build a dream recorder which can be worn on the head at night and which simply dumps brain waves to an SD card. Once that is working, I want to develop an algorithm that detects REM sleep phases. The final goal is to turn it into a lucidity device, i.e. a device that detects when a person is dreaming and then informs that person that they are dreaming (without waking them up). The dreamer can then consciously interact with the dream and direct it. I have had a few short lucid dreams and they're awesome, but it's very hard for me to induce them, hence I need to build this tool :) The cue to the dreamer should be a short audio message played through an integrated speaker.
-
-
I am using the Espruino board to occasionally play back recorded voice waveforms through the DAC and a connected OpAmp. When not playing anything, there is a noise from bus signals leaking into the audio. Therefore I would like to only switch on the amplifier when audio is playing and then switch it off again.
I have currently connected the OpAmps power supply pins to GND and 3.3V pins on the board. The most straight-forward idea is to connect the VCC to a digital output and then switch it on and off using digitalWrite. But can the chip handle that load? If not, how should I wire it? I think that's what transistors are for but I know nothing about analog electronics.
The amplifier I use is a Digilent PModAmp1:
http://www.digilentinc.com/Products/Detail.cfm?Prod=PMOD-AMP1 -
Update: I just flashed the latest firmware onto the board and the behavior changed. Now the sampling rate seems to remain constant. The original issue (changing sampling rate) is fixed :-D Instead, I now get a different problem: little bits of the audio are repeating. This looks very much like the buffers cannot be re-filled fast enough and the playback runs into old data before the new data is ready. That sucks, but it's much less mysterious.
Some experimenting has shown that with a buffer size of 1024 samples, the maximum sampling rate achievable without audible artifacts is 10000 Hz. For a buffer size of 2048, it's 14000 Hz. I cannot make the buffer much bigger, since Espruino will run out of memory.
The documentation metions output rates of 20 KHz... has anybody achieved better results than me, while streaming from an SD?
-
The sample is long enough to fill 3 buffers (30 kbytes should fill 15 buffers of 2048 bytes). Note that this code comes from the original Espruino documentation. Even if I copy it without any changes (such as the button interface), I get that problem. The JavaScript should be fine and it looks fine to me... so the problem is perhaps rooted even deeper (in the firmware, on a level below the JS interpreter)?
I don't know what happens under the hood, so I can only speculate, but is it possible that something (reading from the SD?) is slowing down the waveform output loop (hence the lower output frequency) and then some regulative code in the firmware compares the actual output position to the supposed one and speeds up the output in order to "catch up" (hence the higher output frequency)?
Not sure if it matters, but I have a bluetooth module soldered onto the board (which I am not using at the same time)
-
Thank you, it is certainly a good thing to de-bounce the button.
The problem is not related to bouncing though, because the exact same problem occurs if I only send the contents of the play function to the board and no button is involved. It really sounds like the sample output rate changes every few thousand samples... which is strange, since it is only set once in w.startOutput. Any other ideas?
-
For convenience I added a watch to Button 1. When the button is pressed, the play function is run, which illuminates LED1 and streams the raw file from the SD card to analog pin A4 as a waveform. When playing is done, it turns off the LED.
function play() { var f = E.openFile("test16ku.raw","r"); var w = new Waveform(2048, {doubleBuffer:true}); // load first bits of sound file w.buffer.set(f.read(w.buffer.length)); w.buffer2.set(f.read(w.buffer.length)); var fileBuf = f.read(w.buffer.length); // when one buffer finishes playing, load the next one w.on("buffer", function(buf) { buf.set(fileBuf); fileBuf = f.read(buf.length); if (fileBuf===undefined) { w.stop(); // end of file LED1.write(0); } }); LED1.write(1); //turn on led1 analogWrite(A4, 0.5); w.startOutput(A4,16000,{repeat:true}); } function btnEvent() { if (digitalRead(BTN1) == 1) play(); } setWatch(btnEvent, BTN1, true);
-
I have wired a headphone amplifier to pin A4 and copied the last example from this page:
http://www.espruino.com/Waveform
to stream a waveform from the SD card.For some strange reason, the playback sampling rate does not remain constant. It seems that every time a new buffer is used, the sampling rate changes to a random value roughly in the range +/- 100%, so a recorded voice alternates between normal, Mickey Mouse and monster a few times per second.
What could be causing this? I am using the example code (only changed filenames). It doesn't matter if I try to play with 8, 11, 16 or 22 kHz, I always get this strange behavior.
-
@allObjects: I didn't mean to express any preference with regards to namespaces. My point was just that in a REPL, it doesn't make much sense to execute every new line in its own closure. Because the typical use case of a REPL is to try things out and that most likely relies on executing things in the same namespace. Once you have a complete program, it's a very different story.
I like Gordon's approach to have a REPL at all for communicating with a board, and to interpret source code directly on a board instead of compiling it. I just never liked the syntax of JavaScript. CoffeeScript fixes all that, this is why I code in CoffeeScript. I have an idea how to make the Espruino console work with CoffeeScript, I'm just waiting for my board...
-
There is a coffeescript REPL: http://coffeescript.org/documentation/docs/repl.html
You would have to run it on the client and modify the included eval function so that it sends the compiled JS to the board instead of executing it.
Or make your own REPL. Compiling little bits of coffeescript code into javascript interactively is quite easy to do:
coffeeCode = '((s)->console.log s) "hello"' jsCode = require('coffee-script').compile coffeeCode, {bare: true}
You would just have to read coffeeCode from stdIn and send jsCode to the board. The option bare=true is important because without it, the coffeescript compiler wraps everything in its own closure to keep the namespace clean. In that case, if you compile and run "a=5" and then compile and rund "console.log a", it would print "undefined", unless you specify bare=true
I will look into it once I get my Espruino board. Still waiting for it to ship...
I have this one:
http://www.adafruit.com/products/938
and I also have some of these that I got cheap somewhere:
http://www.sainsmart.com/sainsmart-0-96-spi-serial-128x64-oled-for-raspberry-pi-arduino-mega2560-uno-r3-arm.html
Indeed the Adafruit board can be modified, but I don't see how this could be done with the SainSmart one. It seems like it would be very handy to have an SPI version of the library (or even a unified one that can be used with either SPI or I2C)