Saturday, March 30, 2013

SPI Shenanigans



Arduino SPI Fun featuring ADS1298!

SPI Library

- SPI.setDataMode(SPI_MODE1);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV4);

Different ways of communication we tried:
1) SPI.transfer(byte) only
We are not sure if this toggles SS before and after each byte sent. If this is so, then we cannot use this to send multi-byte commands.

2) digitalWrite(SS, LOW);
    shiftIn(dataPin, clockPin, bitOrder) or shiftOut(dataPin, clockPin, bitOrder, value)
    digitalWrite(SS, HIGH);

- According to the ADS1298 manual, we need a delay of >= 4 SCLK cycles before sending the next command. For our 4MHz clock this is 0.25uS * 4 = 1 uS.

Neither is working so far...

We can use analogWrite(pin, value) to generate an analog signal we can use to test the ADS1298 A-D coverter. *Only works on certain pins!

Some (maybe) helpful discussions on the TI forums:
http://e2e.ti.com/support/data_converters/precision_data_converters/f/73/t/188917.aspx
http://e2e.ti.com/support/data_converters/precision_data_converters/f/73/t/168648.aspx

SPI Connections we made to our toy A-D converter:




Saturday, March 23, 2013

Threading

There is an excellent blog on threading in Python at http://www.tutorialspoint.com/python/python_multithreading.htm.

After reading this, I wrote some threaded code in thread_graph.py. It seems to work great!

(I chose to use the Threading module, not the Thread module, as recommended on the website, although it gives examples for using both).

Finally, in super_threading.py, I wrote some truly multi-threaded code with separate threads that are interdependent. That is the fastest code yet!

Sunday, March 17, 2013

GUI Wrapper for graphing library

One problem we have with our currently python plotting (besides buffer overflow) is the lack of interactivity with the plotting window itself. Whenever we click the plotting window, it freezes up. The buttons for modifying the plot in matplotlib on work after the graph has finished plotting, which is useless for us since it will never be done. Therefore we need a GUI wrapper to contain our graphing module, that has buttons and other modes to interact with the plot. Daniel found a matplotlib example that uses the wxPython wrapper: http://eli.thegreenplace.net/2008/08/01/matplotlib-with-wxpython-guis/ , and Anand found a graphing module built from scratch using Tkinter, the "default" GUI library for Python: (insert link here).

The wxPython example requires wxPython to be installed, along with the following two lines to be placed before import wx:

import wxversion
wxversion.select('2.8')

SimPlot is another plotting tool, but it's just like Stamplot, so we don't think there's much use for it now.

Happy St. Patrick's Day!

Saturday, March 16, 2013

Blitting and animating

Blitting Resources
http://stackoverflow.com/questions/8955869/why-is-plotting-with-matplotlib-so-slow

http://stackoverflow.com/questions/4222344/clearing-background-in-matplotlib-using-wxpython
http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg06565.html

Friday, March 15, 2013

Re-evaluating Library Options for Python Graphing

So we figured out that matplotlib by itself may not be optimal for real time graphing. We looked around and found the following alternatives:
wxPython + matplotlib (came with a piece of code, testing this now) Stack Overflow Post
- wxPython is a GUI wrapper for Python, which will supposedly make matplotlib faster

chaco: recommended by official Python page for real-time plotting
Some other possible options (last post on page):
http://pyqwt.sourceforge.net/
http://code.google.com/p/guiqwt/
http://luke.campagnola.me/code/pyqtgraph/

Another option is to store a fixed amount of data in a buffer and plot the contents at once, reducing the frequency of graph updates. To make the updates appear as smooth real-time plotting, we can animate the plotting. From our (Daniel & Anand) discussion, we concluded that the quality of the data updates will determine the quality of our ECG GUI, which we will measure by the following metrics:
- Smoothness: does the graph appear to be constantly updating, without any abrupt pauses
- sequential cycle: collect data --> plot --> collect --> plot ...
- this will work under the assumption that collecting data takes a negligible amount of time (ie. no pauses)
- if not, then we will have to look into multithreading (painful!) so that the updates will be smooth

- Delay: what is the delay between when the data is collected off the patient's skin to when it's displayed on the computer screen? ideally this number should be small, but more importantly it should remain constant (increasing means that data is accumulating in the serial buffer, very bad!)

- Data accumulation in buffer - 0, else we risk a buffer overflow as t --> infinity

Some possible algorithm designs considerations:
- Create a rotating buffer of two arrays. At any time, one is being plotted and covering up the other. During the first iteration, the array being replaced is empty, so there are no ugly effects from replacing a zero'd array.

-

Monday, February 18, 2013

Rachel and Karen's Deceptive Adventures with Physiological Signals 02/16/13

Things we did:
  • Analog signal measurement and transmission
    • Got an Arduino to measure the analog input from a circuit using the +5V output and a circuit with a resistor and then send it to another Arduino
    • Used the SimpleXBeeReceive code for the receiving module
  • Battery power
    • Connected the Arduino to the 9V battery then disconnected the USB and saw that the Arduino  continued to measure and transmit signals
    • The area on the Arduino board around the battery adapter port heated up a little, but remained comfortable to touch

Things we did not do:
  • Measure biological signals
    • Surface electrical signals are way too small to be measured by the Arduino without the instrumentation amplifier and the better A/D converter, which we already knew, so yeah.

Saturday, February 16, 2013

The New XBee Chronicles: Setting Baud Rate

2/16 Chronicles: We spent the entire afternoon trying to set the parameters of our XBee modules.

Sources:
http://www.libelium.com/squidbee/index.php?title=How_to_set_XBee_parameters

- To send a command to the XBee: Serial.print(cmd), where cmd is a string
- A 2 second delay is required before the next command, perhaps more.

- To enter command mode: send "+++" until OK is returned.

Useful cmds (all prefixed with "AT" and suffixed by "\r" (a carriage return))
1. Check/set something (suffix with the setting)
a. BD - baud rate
b. - network id -Arduino website is down right now :(
c. CH - channel
d -
* whenever we set something, the command is sent twice...?

Configuration
SettingPINKYXWHITEX
ID33323332
CHCC
SH13A20013A20013A20013A20013A20013A200
SL40998CB340998CB340998D0040998D00
MY00
DH00
DL00
BD77


2. WR - write settings to memory so power off will not erase them

3. CN - exits command mode
- after each command you should receive an OK
* instead of OK, we get a random character after ATWR, and our script completely resets...

We managed the change the baud rate setting and save it using ATWR (even with the anomaly described above), but running our 5 sine wave signal generation code seems to break the setting. We thought this was why our other XBee was not receiving anything until we realized that they were on different network IDs...

_________________________________________________________________


2/23 Chronicles: After Anand found that XBees may have a bug that prevents them from transmitting at 115200 bits/s, we tried 57600 bits/s instead and it seems to be working well! We can graph data generated by our FiveSinLongGen script nicely in Python. However,  buffer overflow appears to be a potentially crippling issue, since our Python script is not processing data quickly enough as it is being sent through the air. See Python Adventures post for more information on our (possible brewing) solution!




Thursday, February 14, 2013

Anand & Daniel's Adventures in Python

Valentine's Day - Planning Meeting
Essential:
- pyserial
- numpy/scipy (based off numpy)
? GTK runtime + pyGTK: GUI widget library used by matplotlib in certain implementations

All Python graphing library options (with examples)
1. matplotlib
http://yassinebenabbas.wordpress.com/article/creer-un-graphe-dynamique-avec-pyplot-31z31ug7b5vz5-26/

http://eli.thegreenplace.net/2008/08/01/matplotlib-with-wxpython-guis/

http://stackoverflow.com/questions/7663263/reading-real-time-values-with-pyserial-while-plotting


2. pylab
http://www.gossamer-threads.com/lists/python/dev/439302

3. Chaco
http://docs.enthought.com/chaco/user_manual/chaco_tutorial.html#tutorial

4. pyqtgraph


- glumpy, visvis (OpenGL-based)


- Anand: we will probably be using matplotlib in the end
- pylab is used for a lot of toy examples on the internet

Feb 15 Meeting
- let's run through the matplotlib examples and understand how they work
- construct real-time signal reader that works

Friday update:
Someone in Germany viewed our blog! We're famous now.
It turns out pylab is actually part of matplotlib! Actually, it's a metapackage related to numpy and stuff. They're not competitors. We're using pylab from matplotlib. This can be done using any of the following:

1. import matplotlib
OR 
2. from matplotlib import *
OR
 3. from matplotlib import pylab
OR
4. from matplotlib.pylab import *
OR 
5. import pylab
OR
6. from pylab import *

Noticing a pattern here? A quick note on importing Python modules: let's say we have a Python module x that contains some other sub-module y. For example, x could be matplotlib, and y could be pylab. If we use "import x" and we want to use stuff in y, we have to call it "x.y" in our code. If we use "from x import *" and then we want to use y, we can just call it "y". Therefore our choice of the above will affect how our code looks. I lean towards "from pylab import *" since it makes the later code easier to write.

We played around a bit with the example code in the "cookbook" file on GitHub. We discovered the following:

1. Interactive mode must be on. Call ion() at the beginning.
2. Call draw() to update the graph as desired.

We validated this by also running the example code from http://mindseye.no/2011/04/03/animating-plots-and-waves-in-python-using-matplotlib/ using pylab

Then we combined pylab with our serial code successfully!

Next, we ran Karen's awesome simultaneous 5-channel sine generation Arduino code, and graphed the output from that as well! Daniel also made pretty fireworks by graphing the wrong thing.

Finally, we made Karen's code way more intense by graphing gigantic sine waves using the long data type, allowing us to test graphing 20 bytes at a time (4 bytes per channel times 5 channels) in real time! It worked, even at 115,200 baud with only 2 microseconds delay! Woohoo!

Saturday, February 2, 2013

Multichannel Signal Processing - Take Two

Instead of stringing up four signal generators across the space between benches in the BE lab to get multichannel inputs and create a tripping hazard, we decided to create different signals by passing a single signal through a couple of resistors, and then reading the signal before it passes through each resistor. Therefore each A-D channel on the Arduino receives a sine wave with a different voltage amplitude. We used a common ground all the readings, so the voltage fell in steps at each reading across our resistor circuit.

The other option we considered was to use a LC circuit to modulate the frequency, but we do not have inductors, so bleh.

Here is a picture of the circuit:
(Karen/Rachel post the picture)

Materials we used:
4 0.5Mohm resistors
big breadboard
wires, so many wires

Final signal generator settings:
Waveform: Sine Wave
Amplitude (Peak2Peak?): 3V
Offset: 1.5V
Frequency: 20Hz

We used the MultiChannelExample Arduino sketch to receive the data, delimiting the values using a comma:
    Serial.print(sensorValue0);      
    Serial.print(",");                       
    Serial.print(sensorValue1);  
    Serial.print(",");                       
    Serial.print(sensorValue2);  
    Serial.print(",");                       
    Serial.println(sensorValue3);

Baud rate: 115200
Delay: 20 microseconds

We then plotted the data in Processing, using the Graph sketch:
Conveniently, Processing has a function to split strings!
String[] list = split(inString, ',');

We plotted the points in different shapes and colors, and it looked like a aluminum Christmas tree (which we don't really see anymore because of the Charlie Brown Christmas Special). Effectively, the plot looked like four sine waves of different amplitudes stacked on top of each other.

We then found some code to overclock our Arduino processor here. Not really sure what the code means yet, and not sure if there was even an improvement on the graph... work in progress.

Next time, plotting using a different library (Python perhaps?) and more studies in overclocking.

We also investigated how we could emulate the multichannel A-D conversion on our ECG chip before we solder it onto the breadboard.

Options:
1) Buy 6 MCP3002 A-D converters from Sparkfun
- Good: 75 kHz sampling rate
- Bad: breadboard nightmare, still only 10-bits

2) Buy an ATMega32 from Sparkfun
- Good: not a nightmare
- Bad: same as processor on Arduino, still only 10-bits, and same sampling rate and other restrictions

Maybe it's just better to solder the ECG chip. That only costs ~$50 anyways...

Saturday, January 26, 2013

XBEEEEEEEE


  • So we started playing the with XBee!  Things we learned:
  • We can transmit stuffs!
  • Made an LED flash on the receiving end
  • We can replace the act of plugging and unplugging the XBee shield by toggling the shield switch from UART to DLINE.  In UART is transmission mode, DLINE is code upload mode.
  • We learned how to write to the serial monitor and transmit directly to STAMP plot
  • Receiving XBee:

//const int ledPin = 13; // the pin that the LED is attached to
int incomingByte;      // a variable to read incoming serial data into
// int cr = 13;
void setup() {
 // initialize serial communication:
 Serial.begin(9600);
 // initialize the LED pin as an output:
 //pinMode(ledPin, OUTPUT);
}

void loop() {
 // see if there's incoming serial data:
 if (Serial.available() > 0) {
   // read the oldest byte in the serial buffer:
   incomingByte = Serial.read();
   // if it's a capital H (ASCII 72), turn on the LED:
   Serial.print(incomingByte);
   //Serial.write(cr);
    Serial.print("\n");
   //if (incomingByte == 'H') {
     //Serial.print('H');
     //digitalWrite(ledPin, HIGH);
   //} 
   // if it's an L (ASCII 76) turn off the LED:
   //if (incomingByte == 'L') {
     //Serial.print('L');
     //digitalWrite(ledPin, LOW);
   //}
 }
}

  • Transmitting XBee:

//RAAAMP Code
int i = 0;

void setup() {
 Serial.begin(9600);
}

void loop() {
 if (i < 500) {
   i+=10; 
 } 
 else {
   i = 0;
 }

 Serial.print(i);

 delay(100);
}


  • Flawed because Serial.print() writes individual ASCII characters, e.g. 100 -> "1" "0" "0"
  • Possible fix? Serial.write (binary) transmitting, Serial.print receiving --> printing "as is"
  • Other problem: Serial.write() can only send one byte at a time (0-255), so 260 -> 4
  • One solution: still send ASCII characters using Serial.print() and receive as 8-bit integers, then convert into the corresponding inputNumber:

int inputChar;
int inputNumber=0;

void setup()
{
 Serial.begin(9600);
}
void loop()
{
 if (Serial.available()>0){
   delay(5);
   while(Serial.available()>0){
     inputChar=Serial.read();
     inputNumber=inputNumber*10+(inputChar - '0');
   }
  
       Serial.println(inputNumber);
   inputNumber=0;
   inputChar=0;
 }
}

  • This method is more data-intensive than necessary. For example, if we want to send the number 1020, we would have to send four 8-bit integers representing each character, for a total of 32 bits. However since 1020 can be represented by 10-bits (0-1023), we really only need to send 2 8-bit packets of data. We can achieve this by using the following send code:

  upper = i >> 8;
  lower = i & 255;
  
  Serial.write(upper);
  Serial.write(lower);

  • Receiving end loop:

// make sure both upper and lower bits have been received  
if (Serial.available() >= 2) {
    // read the oldest byte in the serial buffer:
    upper = Serial.read();
    lower = Serial.read();
    
    incomingByte = (upper << 8) | lower;
    Serial.println(incomingByte);
}

Wednesday, January 23, 2013

Jan 22 2013 Progress + How to fix Arduino port problem without restarting your computer!

The progress report looks good. Rachel and I edited it yesterday. We also managed to replicate the result we had on Monday several times, so we're now sure the blinking light is due to transmission and not some coincidence. However it didn't work every single time, and we're having trouble having the receiving Arduino output data to the serial monitor at the same time. There has to be some better way than installing the Xbee shield every time, after uploading our code.

Also the way to fix 'COM# already in use' without restarting is to close the Arduino program and plug the Arduino into a different USB port. It seems that USB ports are reusable, just as long as you change ports each time this occurs.

Saturday, January 19, 2013

Using the A to D converter!

We had to simultaneously figure out how to use the SPI interface to talk to the A to D converter, and how to connect the Arduino and signal generator to the A to D converter.

Key for SPI Interface:
VCC and VDD stand for positive voltage
VSS stands for ground

First, here is the code we came up with:

// inslude the SPI library:
#include <SPI.h>

// set pin 10 as the slave select for the digital pot:
const int CS = 10;
const int out = 11;
const int in = 12;
const int clock = 13;
int fst = 0;
int snd = 0;

void setup() {
 // initialize serial communications at 9600 bps:
 Serial.begin(38400); 
 
 // set the slaveSelectPin as an output:
 pinMode (CS, OUTPUT);
 pinMode (out, OUTPUT);
 pinMode (in, INPUT);
 pinMode (clock, OUTPUT);
 
 // initialize SPI:
 SPI.begin();
 SPI.setBitOrder(MSBFIRST);
 SPI.setClockDivider(SPI_CLOCK_DIV32);
 digitalWrite(CS, HIGH);
}

void loop() {
 digitalWrite(CS, LOW);
 fst = SPI.transfer(120);
 snd = SPI.transfer(0);
 Serial.println(((fst & 7) << 8) | snd);
 digitalWrite(CS, HIGH);
 
 delayMicroseconds(100);
}

We spent time trying to figure out how to connect the A to D converter to the Arduino. Here's the circuit (to match the code) we came up with.



Replacing the Serial Monitor

The Arduino development environment is nice in some ways, but the serial monitor sucks. Seriously. It opens by default to 9600 baud with autoscroll, and if the serial port is communicating at any other data transmission rate, the serial monitor spews out nonsense and slows down your computer to the point that it is hard to even move the mouse to the dropdown menu to change the rate to the actual rate being used (e.g. 115,200 baud). Furthermore, it just displays text.

Ideally, we want to be able to graph our data in real time. Can we do this? Yes, there are several options available for alternative displays. One option is an Arduino graphing library known a MegunoLink developed by a third party called Blue Leaf Software (1).

Another option is demonstrated on the Arduino website in a graphing tutorial (2). As shown in this example, Processing  can be used to access data from the serial port and graph it on a computer. Processing is a popular programming language and development environment (3). In fact, the Arduino development environment was based on Processing, according to the Arduino home page (4). It turns out that the Arduino project also has a Processing library that uses Firmata to communicate with the Arduino using Processing code directly (5). Firmata is a generic protocol for communicating with microcontrollers from a computer (6).

There is at least one entire discussion thread on the Arduino forums dedicated solely to replacing the serial monitor (7). One post there mentions the use of Firmata and Silverlight together, although the exact purpose of using this combination of these softwares is not clear.

We are going to explore these various alternatives until we find one that works.

1. http://www.blueleafsoftware.com/Resources/EmbeddedSand/Plotting_Arduino_Data
2. http://arduino.cc/en/Tutorial/Graph
3. http://processing.org/
4. http://www.arduino.cc/
5. http://playground.arduino.cc/interfacing/processing
6. http://www.firmata.org/wiki/Main_Page
7. http://arduino.cc/forum/index.php?topic=122167.0

Saturday, January 12, 2013

Proof of Concept: multiple signal input processing


First, we did single signal input processing. You know, to get the hang of it.
  • connect electronic test cables from computer's signal out put to Arduino (see image 1)
    • two cables to Arduino, one in A0 and one in ground
  • set up signal on easy scope 

  • connect Arduino to computer and set up sampling rate
      •  remember to install the drivers!
    • Put in the following code
  • Start the signal generator on easy scope
      • the signal looked weird. It only looked weird when we plugged it into the Arduino. The solution was to plug the ground into the breadboard. EDIT don't do that.
    • 300, 14400, 28800 didn't work.EDIT  these still don't work after later edit/solution.  The rest worked until anything past 19200 froze the computer:( 
      • we think this is because the serial monitor couldn't handle those speeds, so we researched alternatives to the serial monitor (standard with the Arduino program.)
      • We discovered this in addition to an Arduino graphing library. Why aren't we using this (the graphing library) already? I guess we'll find out! 

        • The graphing library would allow us to either graph from serial (not helpful) or 
        • EDIT the solution is to print on new lines, the serial monitor doesn't handle horizontal scrolling well 
  • The highest sampling speed (115200) works! We copied a bunch of the data and graphed it in MatLab but it looked like a wandering sine wave (sad).
    • Sad wandering sine wave




      • Upon re evaluating what we did before we realized they hall had to be in the same ground.

      • Additionally, we noticed that our signals would get cut off at 700 , so, we changed our peak to peak voltage output from 5 to 2 and it all fit so we had a full signal! This would be disturbing (in case we needed a larger peak to peak voltage output) but since it worked from a lower ppv, we attributed it to the arduino's Ato D converter, and since we will be using a different one, we let it go...for now...
      • Then we changed the sampling delay from 2ms to .2ms to give us a cleaner signal
      • Finally, we raised the frequency to 54 Hz (which is what we needed to be clinically applicable) and it worked! check it out :D