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.