added analog sensors and cleaned up the sensor data structure a bit
diff --git a/gyro_board/src/usb/CAN.c b/gyro_board/src/usb/CAN.c
index 591c6fc..35f811f 100644
--- a/gyro_board/src/usb/CAN.c
+++ b/gyro_board/src/usb/CAN.c
@@ -231,6 +231,10 @@
     vTaskDelete(NULL);
   }
 
+  // Set all of the CAN stuff to run at CCLK/6, which translates to about 1 Mbit
+  // (1.042).
+  SC->PCLKSEL0 |= 3 << 26 | 3 << 28 | 3 << 30;
+
   // Enable CAN
   SC->PCONP |= PCONP_PCCAN1;
 
diff --git a/gyro_board/src/usb/analog.c b/gyro_board/src/usb/analog.c
index 87d67ad..b00d1b4 100644
--- a/gyro_board/src/usb/analog.c
+++ b/gyro_board/src/usb/analog.c
@@ -1,50 +1,40 @@
-// ****************************************************************************
-// CopyLeft qwerk Robotics unINC. 2010 All Rights Reserved.
-// ****************************************************************************
-
 #include "analog.h"
 
-#include "FreeRTOS.h"
-#include "queue.h"
-#include "task.h"
+#include "LPC17xx.h"
 
 void analog_init(void) {
-  // b[1:0] CAN RD1 p0.0
-  // b[3:2] CAN TD1 p0.1
-  //PINCON->PINSEL0 = 0x00000005;
-
-  // b[29:28] USB_DMIN   p0.30
-  // b[27:26] USB_DPLUS  p0.29
-  // b[21:20] AD0.3  p0.26
-  // b[19:18] AD0.2  p0.25
-  // PINCON->PINSEL1 = 0x14140000;
-
-  // PINCON->PINSEL2 = 0x0;
-
-  // b[31:30] AD0.5  p1.31
-  // b[29:28] V_BUS  p1.30
-  // b[21:20] MCOB1  p1.26
-  // b[19:18] MCOA1  p1.25
-  // b[15:14] MCI1  p1.23
-  // b[13:12] MCOB0  p1.22
-  // b[09:08] MCI0  p1.20
-  // b[07:06] MCOA0  p1.19
-  // b[05:04] USB_UP_LED  p1.18
-  //PINCON->PINSEL3 = 0xE0145150;
   SC->PCONP |= PCONP_PCAD;
 
   // Enable AD0.0, AD0.1, AD0.2, AD0.3
-  PINCON->PINSEL1 &= 0xFFC03FFF;
-  PINCON->PINSEL1 |= 0x00D54000;
+  PINCON->PINSEL1 &= ~(2 << 14 | 2 << 16 | 2 << 18 | 2 << 20);
+  PINCON->PINSEL1 |= 1 << 14 | 1 << 16 | 1 << 18 | 1 << 20;
   ADC->ADCR = 0x00200500;
+  ADC->ADCR = (1 << 0 | 1 << 1 | 1 << 2 | 1 << 3) /* enable all 4 */ |
+      7 << 8 /* 100MHz / 8 = 12.5MHz */ |
+      1 << 16 /* enable burst mode */ |
+      1 << 21 /* turn on ADC */;
 }
 
+uint16_t analog(int channel) {
+  uint32_t value;
+  do {
+    switch (channel) {
+      case 0:
+        value = ADC->ADDR0;
+        break;
+      case 1:
+        value = ADC->ADDR1;
+        break;
+      case 2:
+        value = ADC->ADDR2;
+        break;
+      case 3:
+        value = ADC->ADDR3;
+        break;
+      default:
+        return 0xFFFF;
+    }
+  } while (!(value & 1 << 31));
 
-int analog(int channel) {
-  ADC->ADCR = ((ADC->ADCR & 0xF8FFFF00) | (0x01000000 | (1 << channel)));
-
-  // Poll until it is done.
-  while(!(ADC->ADGDR & 0x80000000));
-
-  return ((ADC->ADGDR & 0x0000FFF0) >> 4);
+  return ((value & 0xFFF0) >> 4);
 }
diff --git a/gyro_board/src/usb/analog.h b/gyro_board/src/usb/analog.h
index 1de38e7..5a06290 100644
--- a/gyro_board/src/usb/analog.h
+++ b/gyro_board/src/usb/analog.h
@@ -3,7 +3,13 @@
 
 #include <stdint.h>
 
+// Starts the hardware constantly doing conversions on all 4 of our analog
+// inputs.
 void analog_init(void);
-int analog(int channel);
+
+// Retrieves the most recent reading on channel (0-3).
+// Returns 0xFFFF for invalid channel.
+// 0 means 0V and 0x3FF means 3.3V.
+uint16_t analog(int channel);
 
 #endif  // __ANALOG_H__
diff --git a/gyro_board/src/usb/data_struct.h b/gyro_board/src/usb/data_struct.h
index 6c99195..8c069b9 100644
--- a/gyro_board/src/usb/data_struct.h
+++ b/gyro_board/src/usb/data_struct.h
@@ -17,9 +17,15 @@
       // Which robot (+version) the gyro board is sending out data for.
       // We should keep this in the same place for all gyro board software
       // versions so that the fitpc can detect when it's reading from a gyro
-      // board set up for a different robot than it is.
-      // 0 = 2013 competition/practice robot
-      // 1 = 2013 3rd robot
+      // board set up for a different robot (or version) than it is.
+      // The numbers listed below each robot are the values that have been used
+      // for it.
+      //
+      // 2013 competition/practice robot
+      //   0
+      //   2 added battery measurement + drivetrain analog hall effects
+      // 2013 3rd robot
+      //   1
       uint8_t robot_id;
       // This information should also be kept in the same place from year to
       // year so that the fitpc code can record the dip switch values when it
@@ -39,26 +45,17 @@
         uint8_t base_status;
       };
     };
-    uint16_t header;
+    uint32_t header;
   };
 
-  // This is a counter that gets incremented with each packet sent (and wraps
-  // around when it reaches 255).
-  uint8_t sequence;
+  // This is a counter that gets incremented with each packet sent.
+  uint32_t sequence;
+
+  // We are 64-bit aligned at this point if it matters for anything other than
+  // the gyro angle.
 
   union {
     struct {
-      union {
-        struct {
-          uint8_t wrist_hall_effect : 1;
-          uint8_t angle_adjust_bottom_hall_effect : 1;
-          uint8_t top_disc : 1;
-          uint8_t bottom_disc : 1;
-          uint8_t loader_top : 1;
-          uint8_t loader_bottom : 1;
-        };
-        uint16_t booleans;
-      };
       int32_t left_drive;
       int32_t right_drive;
       int32_t shooter_angle;
@@ -72,6 +69,10 @@
       int32_t capture_wrist_rise;
       int32_t capture_shooter_angle_rise;
 
+      uint16_t battery_voltage;
+      uint16_t left_drive_hall;
+      uint16_t right_drive_hall;
+
       int8_t top_rise_count;
 
       int8_t top_fall_count;
@@ -84,6 +85,15 @@
       int8_t wrist_rise_count;
 
       int8_t shooter_angle_rise_count;
+
+      struct {
+        uint8_t wrist_hall_effect : 1;
+        uint8_t angle_adjust_bottom_hall_effect : 1;
+        uint8_t top_disc : 1;
+        uint8_t bottom_disc : 1;
+        uint8_t loader_top : 1;
+        uint8_t loader_bottom : 1;
+      };
     } main;
     
     struct {
diff --git a/gyro_board/src/usb/encoder.c b/gyro_board/src/usb/encoder.c
index 205f44e..9277340 100644
--- a/gyro_board/src/usb/encoder.c
+++ b/gyro_board/src/usb/encoder.c
@@ -499,12 +499,15 @@
   if (is_bot3) {
     packet->robot_id = 1;
   } else {  // is main robot
-    packet->robot_id = 0;
+    packet->robot_id = 2;
 
     packet->main.shooter = encoder1_val;
     packet->main.left_drive = encoder5_val;
     packet->main.right_drive = encoder4_val;
     packet->main.indexer = encoder3_val;
+    packet->main.battery_voltage = analog(0);
+    packet->main.left_drive_hall = analog(1);
+    packet->main.right_drive_hall = analog(3);
 
     NVIC_DisableIRQ(EINT3_IRQn);
 
diff --git a/gyro_board/src/usb/gyro.c b/gyro_board/src/usb/gyro.c
index 866e890..ad49658 100644
--- a/gyro_board/src/usb/gyro.c
+++ b/gyro_board/src/usb/gyro.c
@@ -185,8 +185,9 @@
 }
 
 static portTASK_FUNCTION(gyro_read_task, pvParameters) {
-  // Connect power and clock.
   SC->PCONP |= PCONP_PCSSP0;
+
+  // Make sure that the clock is set up right.
   SC->PCLKSEL1 &= ~(3 << 10);
   SC->PCLKSEL1 |= 1 << 10;
 
diff --git a/gyro_board/src/usb/main.c b/gyro_board/src/usb/main.c
index 3ac21c8..4e74ce7 100644
--- a/gyro_board/src/usb/main.c
+++ b/gyro_board/src/usb/main.c
@@ -149,8 +149,8 @@
 
   setup_PLL1();
 
-  // Set CAN to run at CCLK/6, which should have it running about 1 Mbit (1.042)
-  SC->PCLKSEL0 = 0xff555555;
+  // Set everything to run at full CCLK by default.
+  SC->PCLKSEL0 = 0x55555555;
 
   /* Configure the LEDs. */
   vParTestInitialise();