Because we kept making things and forgetting how...we're making a blog to help us remember how. It will also help with progress reports! Most importantly, it will help us not make the same mistakes over and over again because I hate it when that happens.
Thursday, February 28, 2013
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.
Useful cmds (all prefixed with "AT" and suffixed by "\r" (a carriage return))
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
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!
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
| Setting | PINKYX | WHITEX |
| ID | 3332 | 3332 |
| CH | C | C |
| SH | 13A20013A20013A200 | 13A20013A20013A200 |
| SL | 40998CB340998CB3 | 40998D0040998D00 |
| MY | 0 | 0 |
| DH | 0 | 0 |
| DL | 0 | 0 |
| BD | 7 | 7 |
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:
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!
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 *
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.
Subscribe to:
Posts (Atom)