Ben’s Updates – 2 Weeks to Touchdown

Hey, guys. If you’ve been reading William’s blog, you know that we were at the VIMS Eastern Shore Lab last week, tagging sharks and generally having a great time. We’ve already got about 15 days of accelerometer-only data from some other tags as well as one (soon to be five) day(s) of data from our own, so we must now analyze the data and see what we can get out of it. However, since I skipped last week’s post, I ought to bring everybody up to speed on what I’ve been doing – it has indeed been a real doozy.

Burst Gyros

After finally getting through the burst-gyro reads debacle, I pulled out the oscilloscope to check for improvements in power consumption – and there were indeed improvements. I was now pulling data from the gyroscope at a much slower rate, so power consumption from that was reduced by a factor of about 32. Unfortunately, this activity probably took up about 10% of our power use, and as Amdahl’s law states, a big increase in efficiency in a small part of the system is not that big in the long run.

The bigger reduction comes from the fact that SD writes are now 1.5 times less frequent. The SD takes up about 75% of our current draw, so this is a decent improvement. However, as I’ll later show, this improvement was quickly overshadowed.

Bit-Packing

I also decided to give the accelerometer a little TLC through some bit-packing. Bit-packing is a way of using some bit-level manipulations to efficiently “pack” data. Programmers think of the “memory” for a program as a giant array of “words”, with each word having its own address. For the Arduino, each word is just a byte (we call this system “byte-addressable”), and each byte has 8 bits.

For example, we could store a char (1 byte) at address 0x100. We store larger values across multiple bytes, so a short goes from 0x100 to 0x101. However, we can’t naturally have values that start or end in the middle of a byte – the idea of storing a char between 0x100.5 and 0x101.5 doesn’t make any sense. A 12-bit integer will therefore take up the same amount of space as a 16-bit one, and the unused space is known as “padding”.

However, with some clever bit-level manipulation, we can in fact store values in between bytes. This is the original structure for storing accelerometer data:

struct accel_data {
    short x: 12;
    short y: 12;
    short z: 12;
}

Like I said, each 12-bit integer takes up 16 bits of space, so there are 12 bits of padding. In other words, 25% of our buffer was just wasted space. To get around this, I split each x, y, and z value into its lower 8 bits (“least significant byte”) and upper 4 bits (“most significant nibble”, nibble meaning 4 bits). The result is a “pack” that combines two accelerometer reads with no padding:

struct accel_pack {
    // These are the lower 8 bits of each data point.
    // This part of the struct takes up 6 bytes.
    struct {
        byte x1, y1, z1;
        byte x2, y2, z2;
    } lsb;
    // These are the higher 4 bits of each data point.
    // The compiler will pack this into 3 bytes for me.
    struct {
        byte x1: 4; byte x2: 4;
        byte y1: 4; byte y2: 4;
        byte z1: 4; byte z2: 4;
    } msb;
}

Astute readers might be wondering why the bytes in msb are laid out with no padding. In truth, the C compiler is adding some behind the scenes code. x1 and x2, for example, are stored in the same byte. If I want to read from x1, it has to isolate x1 and copy it into a different byte before I can play with it. If I write to x1, it has to avoid overwriting x2 in the process.

So, with that massive text dump out of the way, what are the actual gains from this? To be completely honest… nothing, at least not yet. The tag currently bit-packs perfectly, but in order to take advantage of that I need to precisely set a few constants. Since one of my future goals is to organize the various constants floating around in my code, I’m going to put that off for just a little bit. Hopefully, I can get back to you guys on that later.

Binary SD Writes

I’m way over limit right now, and I haven’t even gotten to Shark Week yet. But this next part is pretty dang awesome, for two reasons. First off, I made a new file format, and second off, I may have dropped the SD card’s power consumption by a factor of eight.

Up until now, we’ve been writing to the SD card in plain-text. This was very convenient, and it’s standard for many tags, but it’s wasteful. While the SD card is open, every CPU cycle counts, and the Arduino needs to convert every single sensor value into a string, write it to the SD card, do a lot of looping and branching… it’s tedious.

The alternative is to just write the raw data in binary and parse it into plaintext from our computers. I had tried this many months back, but it seemed to fail – it actually took longer to write to the SD card than the plaintext method. I still don’t know why that happened, but I tried it again on a hunch and found something amazing.

The Arduino originally reported that it took around 400ms to write to the SD card. Now, it took 50. I checked and re-checked the data, and it all came out right. I can’t explain how satisfying that is, but it’s pretty satisfying.

I ended up writing my own file format for the tag, called .SRK for obvious reasons, and a parser in C++ that converted the data into a CSV. That took the better part of a week, thanks to a myriad of small errors, but the end result is pretty good, especially the parser. Since I’m potentially working with Windows users who might not have C++ compilers, I might rewrite the parser later in Python or figure out cross-compilation, but it was a fun exercise and will do for now.

Overall – and this is a bit sketchy – Amdahl’s law and my oscilloscope tell me that the combined optimizations reduced the tag’s power consumption by a factor of 5. We haven’t had time to measure the tag’s battery life, but it’s at least 40 hours on a 450mA. We can thus estimate that the tag will now last for over 200, which was what we were aiming for at the start of the project.

Shark Week

After all that, I finally got to what I’ll call “Shark Week” – the time William and I spent as interns per se at the Wachapreague Eastern Shore Lab. A lot of what went down is hardware-related, so you should check William’s blog for that, but I personally had a lot of fun. We managed to get our tags in the water, didn’t hurt any sharks, and have quite a bit of data to analyze. The question now becomes how to analyze it.

It’s inconvenient to constantly record sharks. Even if you stick a GoPro in the water – sharks think electronics are food due to electrical impulses, so you need to be careful – you need to scrub through days of footage later. In lieu of that, we decided to get a bit of important video data and a feeding schedule for reference. We can then see to what extent (and how) our machine learning algorithms can reliably distinguish between feeding and non-feeding patterns. We can also do similar thing with day and night or other factors. This is what I plan to spend my last two weeks doing. I’ll tell you how it all goes.

See you then.

Weekly Update 7-18-2016 to 7-24-2016

This was quite a week. On Monday I packed my bags and headed out to the VIMS Eastern Shore Lab (ESL) in wachapreague Virginia. Once out there I spent the week working with the animals they had in captivity and helping out the marine scientists out there. They had a large tank of Sandbar Sharks that we were working with for the tag data. On Monday when I arrived they gave me and Ben a lot of data they had collected from a commercial accelerometer system on the animals so we got started on that. That evening they caught more sharks for research and I helped to tag them and put them into the tank. The next morning we pulled two sharks out of the tank and attached more of the commercial accelerometers to them. Then after that we fed the sharks, we haven’t looked closely at that data yet but hopefully we get something interesting from the feeding. The next day it was time to retrieve the accelerometers, we caught the sharks again and pulled the tags off. Unfortunately the waterproofing on one of the tags failed, it got waterlogged, and we were not able to recover any data from it. The silver lining is now I have a commercial accelerometer tag that I can disable and look at how it’s made. Also the other tag was okay and we were able to get the data from it.

Next it was time to start thinking out the tags I have made over the summer. We initially thought that the prototype tags were too big to attach to the animals. However it was decided that we could probably get away with attaching prototype 4 to one of the larger sharks for a little while. Before we could do this though we had to find a fast and nondestructive way to waterproof the tag. The PVC we came with was to bulky for the small animals we had there. We came to the conclusion that we could use large heat shrink tubing for the waterproofing by selling a few inches on each side together. To test this we filled some of the tubing with paper towels, sealed the ends with an iron and through the whole thing into the tank tied to a cinder block. When we pulled it back out the paper towels were dry so it was time to put the tag in. That evening we sealed configured the tag and sealed it up. We then caught the shark we were using (code name: scratch) and attached the tag.

Prototype 4 half inserted into the waterproof heat shrink

Prototype 4 half inserted into the waterproof heat shrink

The next morning we went back out to the tank, re-caught scratch and removed the tag. We then took it back to the lab, opened it up, and it was dry! we Popped the SD card into a computer and saw that we had good looking data and it appeared that everything had gone off without a hitch. We looked at the data for a while and then started to recharge the battery for the tag and prep it for another deployment. We picked out another one of the larger sharks to try the tag on, and once the tag was ready we sealed it in a new piece of heat shrink. When we pulled the shark out of the water to attach it and saw that its stitches from a surgery it had a few days early were coming undone. We restitched the shark and decided not attach the accelerometer to it so it could have more of a chance to heal. Since we did not have a shark to attach the tag to, but it was packaged for deployment we decided to attach it to a cinder block and through it in for a battery and waterproofing test. In hindsight it was a good idea that we did this stress test.

When we pulled the tag out of the water the next day it looked fine, but when we cut it open at the lab a bunch of water poured out onto the lab bench. The heat shrink had not sealed properly and the tag flooded. The tag was destroyed but we were able to recover a partially corrupted data file from the SD card. From this we learned that it took three hours in the water for the flooding to get bad enough to kill the arduino, and that we can recover some amount of data from a uSD card exposed to salt water.

After this setback we went about trying to determine a better procedure for sealing the heatshrink. Eventually we were able to develop a system that revolved around heating the iron to around 300c and then sitting it on the heatshrink unplugged for ten minutes. When we felt confident with this system we sealed up prototype 3 for deployment. This was pretty nerve racking as prototype 3 is our last functioning prototype with a gyroscope on it. We went out to the tank, attached it to scratch the shark, and then it was time for me to leave the eastern shore. Prototype 3 is still on the animal at time of writing, I will let you know if it survives when I find out.

When I got back to Williamsburg all the pieces to assemble the sharkduinov1 boards had arrived. I put together a layer 1 board that worked, and then took a layer 2 board and arduino with it to try to assemble a full sharkduino. This is still very much a work in progress but hopefully next week I’ll have a few to show you.

Assembled layer 1 board

Assembled layer 1 board

Finally the layer three boards came in. These boards have a pressure and temperature sensor on them and were designed to be exposed form water and physically separated from the other boards.

Layer 3 boards

Layer 3 boards

I will post some pictures of the sharks and the device on the sharks when I have time to go through those photos.

Weekly Update 7-11-2016 to 7-17-2016

This week I dipped back into data analysis for a while, and made some exciting progress with the hardware.

I began the week by writing some documentation for the boards I had designed. I figured it would probably be good to have a record of how the board’s work and some of the design rationale that went into them. This is important work but it was pretty boring to do. I also finished up the layer three designs and sent it off to be printed.

I then went to work reviewing some Ben’s analysis code. For the past few weeks we fell into just working on our own parts of the project and not really looking at what the other one was doing. This is a good way to make mistakes and not notice them. So to hopefully prevent any problems I went through all of Ben’s code and looked for errors or just things I did not understand, and asked him about it. This was most helpful for the MATLAB code but I did it for the Arduino code as well even though I didn’t understand a lot of it.

Looking at Ben’s code I noticed we hadn’t done anything with the pressure sensor data yet, so I made a quick function that would convert from pressure in mBar to depth in meters. This is a pretty straightforward problem with a simple formula. The only tricky part is that you have to remember that the ocean is an open system and because of that you have to account for both air pressure and water pressure. The code appears operationally but I will need to check it against real data later.

Finally on Thursday afternoon the boards came in! I had the parts to assemble the layer two boards already so I just jumped in and started laying everything out. I put the board in the oven and when it came out one of the capacitors had flipped up to be perpendicular to the board. I tried to use the soldering iron to melt its solder and lay it back down, and when that didn’t work I tried to solder a through hole capacitor into the proper place. When that didn’t work I figured I didn’t really need a decoupling capacitor anyway and I would just go for it. I started by testing the battery charging mechanism. This worked but the charging indicator LED did not. This is annoying but not a big deal, more likely then not I just put the LED on backwards. I then tried to test the RTC and it did not work.

Layer 1 and 2 printed boards

Layer 1 and 2 printed boards

I started trying to troubleshoot the RTC and first discovered that I installed the coin cell battery holder for the RTC incorrectly. It was a simple mistake that I can avoid in the future. After I fixed this the RTC still did not work so I connected up to the logic analyzer and I did not see promising signs. It seemed that the chip was receiving data and either not responding at all or sending out weird noise like signals. My theory right now is while I was using the soldering iron on the capacitor I overheated the chip and burnt it out. Oh well, try again the next day and be more careful.

Assembled layer 2 board.

Assembled layer 2 board.

The next day I tried to assemble another layer two board. This time I did not make the battery holder mistake again and the capacitor stayed put, but I made a different mistake. I did not line up the uSB adaptor properly, so it did not make good connections. This means that we can not use this board to charge the LiPo battery. I tried to realign the uUSB using hot air reflow but that did not work. Luckily the power from the battery works, just not the charging. Additionally the RTC worked perfectly. This means that I have one board that can charge the battery but can’t take time data and one board that can take time data but can’t charge the battery. Hopefully on the third try I can get all the parts working at once.

Next week I will be at the VIMS Eastern Shore Lab (ESL) so I won’t work on assembling the printed boards but I will be up to a lot of other fun stuff I’ll tell you about next week.

Weekly Update 7-4-16 to 7-10-16

This was a short week due to the 4th of July holiday. In addition I had to prepare and give a presentation this week for the REU program, but don’t worry I still got some good work done this week.

First off I reflowed the remaining two gyro boards, one worked and one did not. The non working one I connected to the logic analyzer and saw that the Arduino was initiating communication and the board was just not responding. I do not know what is wrong but if I find some time I will try to troubleshoot it more thoroughly.

In addition to looking at the gyro boards I finalized the design for the layered boards. The layered boards are all of the components we are using at this stage (accelerometer, gyroscope, real time clock, uSD reader, and usb LiPo charger) and consolidating them down to two boards that stack with the Arduino pro mini. I have finished the design of these boards, created a bill of materials and sent them off to be manufactured. In the process of finding the boards I did notice something odd, and that is the accelerometer I2C address does not appear correct. The I2C address is used to distinguish between the different devices connected with I2C. The accelerometer chip has a pin on it that if pulled low gives the chip one address and if pulled high gives it a second address. Currently the design for the board we are using shows this pin pulled high, but the actual address I am reading off the board is the low address. I spent awhile trying to account for this discrepancy. I ended up connecting the pin in the way the design does, however it does not matter too much since we are not using any device with a similar address. If I accidentally set the chip to the wrong address I will just change the code to reflect that.

Finally this week I began work on a board that combines the pressure and temperature sensors. This is an interesting board to design since we want it as small as possible and one part of it will be exposed to the water.

Weekly Update 6-27-16 to 7-3-16

I began this week by repairing prototype three. I ordered a new uSD reader and swapped out the old one. After I got the new reader installed properly everything worked perfectly. I still do not know what exactly happened with the old uSD reader but hopefully whatever it was won’t happen again. If it does I will have to try to look at the connections on the breakout board and see what is breaking there and figure out if I can design one that won’t break.

In addition to repairing prototype 3 I created prototype 4. I figured that it would probably be good to have redundant devices with gyroscopes in case an uSD reader or something else broke we wouldn’t be stuck until I could fix it. Prototype 4 also had the side purpose of providing a test platform for the homemade gyroscope breakout boards. I built the prototype before I had the new gyroscopes so I made sure to build it in such a way that I could easily slide the commercial or new gyroscope on depending on what worked. I ended up being able to use the new gyroscope which meant that prototype 4 is approximately 30mm shorter than prototype 3.

Top: prototype 3 Bottom: prototype 4

Top: prototype 3
Bottom: prototype 4

This leads to the biggest accomplishment of the week, the new gyroscope. Is was rocky going getting it up and running but I eventually got there. The first task was to learn how to use the new solder reflow oven. A solder reflow oven is a fancy convection oven that cycles through different temperatures for different amounts of time so that it can melt and cool solder past in the ideal way for surface mount soldering. The instructions that came from it were in chinese and badly translated english, so they were not the most helpful. Once I figured out how to use the oven I found out that it does not heat as quickly as I would have liked so I had to spend time trying to set the cook times and temperatures in such a way to get the temperatures I actually wanted for the amount of time I actually wanted them. After that I had to figure out how to apply solder paste to spots that in some cases were only a few millimeters in size with a couple millimeters separating them for the pads next to them. This was a very slow and meticulous process. The first time I tried it, it did not work. There was a short somewhere on board. This was really scary since I didn’t know what was wrong. There were a huge number of possibilities, the board had a design problem in it, if I just applied the solder wrong, if I reflowed, wrong or simply that the solder paste I was using was expired so it flowed strangely. After the first one didn’t work I did not know what to do, so I got some new solder past and just tried again praying for the best, and it worked. I successfully designed a board in eagle, solder surface mount components onto it and connected it to a prototype device to take real data.

The homemade gyroscope

The homemade gyroscope

All the time this week I didn’t spend soldering either the new prototype of the gyro board I spend in google designing breakout boards with all the necessary components integrated onto a couple boards. I am nearly done and can hopefully send the designs off to be printed sometime next week.