commit 1019d31f021c1c964c308e824b3386e77ce636fb
Author: Tom Mullins <tmullins@andrew.cmu.edu>
Date:   Wed Apr 17 14:13:12 2013 -0400

    Adding Maung's paintboard i2c code

diff --git a/scout/painter/CMakeLists.txt b/scout/painter/CMakeLists.txt
index 9f5a865..ccaea8b 100644
--- a/scout/painter/CMakeLists.txt
+++ b/scout/painter/CMakeLists.txt
@@ -21,7 +21,7 @@ set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
 #uncomment if you have defined services
 #rosbuild_gensrv()
 
-rosbuild_add_executable(painter src/painter.cpp)
+rosbuild_add_executable(painter src/painter.cpp src/paint-i2c.cpp)
 
 #common commands for building c++ executables and libraries
 #rosbuild_add_library(${PROJECT_NAME} src/example.cpp)
diff --git a/scout/painter/src/paint-i2c.cpp b/scout/painter/src/paint-i2c.cpp
new file mode 100644
index 0000000..021b312
--- /dev/null
+++ b/scout/painter/src/paint-i2c.cpp
@@ -0,0 +1,157 @@
+/**
+ * Copyright (c) 2013 Colony Project
+ * 
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file paint_i2c.cpp
+ * @brief Contains i2c communication for the paintboard.
+ *
+ * @author Colony Project, CMU Robotics Club
+ * @author Maung Aung (mza)
+ * @author Tom Mullins (tmullins)
+ *
+ */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <linux/i2c-dev.h>
+#include "paint-i2c.h"
+
+#define TRACKING_ID 0x43
+#define SERIAL_NUMBER 0x12
+
+// indicies for paintboard internal data
+#define PAINT_TRACKING_ID      0 // ro
+#define PAINT_SERIAL_NUMBER    1 // ro
+#define PAINT_MOTOR_A          2 // rw
+#define PAINT_MOTOR_B          3 // rw
+#define PAINT_SERVO_A          4 // rw
+#define PAINT_SERVO_B          5 // rw
+#define PAINT_12V_1            6 // rw
+#define PAINT_12V_2            7 // rw
+#define PAINT_12V_3            8 // rw
+#define PAINT_12V_4            9 // rw
+#define PAINT_INPUT_1         10 // ro
+#define PAINT_INPUT_2         11 // ro
+#define PAINT_INPUT_3         12 // ro
+
+#define PAINT_DATA_LEN        13
+
+int fd;
+
+/*
+ * This function opens communication to I2C.
+ */
+void i2c_start(void) {
+  /* TODO error check */
+  fd = open("/dev/i2c-3", O_RDWR);
+  ioctl(fd, I2C_SLAVE, TRACKING_ID);
+}
+
+/*
+ * This function ends communication with I2C.
+ */
+void i2c_stop(void) {
+  if (fd) {
+    close(fd);
+  }
+}
+
+/*
+ * This function writes a value to a given destination using I2C.
+ */
+void i2c_write(int dest, int val) {
+  char buf[2];
+  buf[0] = (char) dest;
+  buf[1] = (char) val;
+
+  write(fd, buf, 2);
+}
+
+/*
+ * This function reads a value from the given address using I2C
+ */
+char i2c_read(int src) {
+  char buf;
+
+  buf = src;
+  write(fd, &buf, 1);
+  read(fd, &buf, 1);
+  return buf;
+}
+
+/*
+ * This function takes in an int representing the motor to be modified and an 
+ * int representing the value to which to set the motor.
+ */
+void set_motor(int motor, int val) {
+  if (motor == 0) {
+    i2c_write(PAINT_MOTOR_A, val);
+  } else {
+    i2c_write(PAINT_MOTOR_B, val);
+  }
+}
+
+/*
+ * This function takes in an int representing the servo to be modified and an 
+ * int representing the value to which to set the servo.
+ */
+void set_servo(int servo, int val) {
+  if (servo == 0) {
+    i2c_write(PAINT_SERVO_A, val);
+  } else {
+    i2c_write(PAINT_SERVO_B, val);
+  }
+}
+
+/*
+ * This function takes in an int representing the solenoid to be modified and
+ * an int representing the value to which to set the solenoid.
+ */
+void set_solenoid(int solenoid, int val) {
+  if (solenoid == 0) {
+    i2c_write(PAINT_12V_1, val);
+  } else if (solenoid == 1) {
+    i2c_write(PAINT_12V_2, val);
+  } else if (solenoid == 2) {
+    i2c_write(PAINT_12V_3, val);
+  } else {
+    i2c_write(PAINT_12V_4, val);
+  }
+}
+
+/*
+ * This funciton takes an int representing which of the spare inputs to read.
+ */
+int get_input(int input) {
+  switch (input) {
+    case 0: return i2c_read(PAINT_INPUT_1);
+    case 1: return i2c_read(PAINT_INPUT_2);
+    case 2: return i2c_read(PAINT_INPUT_3);
+    default: return 0;
+  }
+}
diff --git a/scout/painter/src/paint-i2c.h b/scout/painter/src/paint-i2c.h
new file mode 100644
index 0000000..ce8dcad
--- /dev/null
+++ b/scout/painter/src/paint-i2c.h
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2013 Colony Project
+ * 
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file paint_i2c.h
+ * @brief Contains i2c communication for the paintboard.
+ *
+ * @author Colony Project, CMU Robotics Club
+ * @author Maung Aung (mza)
+ * @author Tom Mullins (tmullins)
+ *
+ */
+
+void i2c_start(void);
+void i2c_stop(void);
+void set_motor(int motor, int val);
+void set_servo(int servo, int val);
+void set_solenoid(int solenoid, int val);
+int get_input(int input);
diff --git a/scout/painter/src/painter.cpp b/scout/painter/src/painter.cpp
index ad2253c..d1887d6 100644
--- a/scout/painter/src/painter.cpp
+++ b/scout/painter/src/painter.cpp
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011 Colony Project
+ * Copyright (c) 2013 Colony Project
  * 
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -39,14 +39,19 @@
 #include <messages/set_paintboard.h>
 #include <messages/query_paintboard.h>
 #include <messages/query_metal_detector.h>
+#include "paint-i2c.h"
 
 using namespace std;
 
+int painter_value;
+
 /**
  * @brief ROS callback to turn the paint output on or off
  */
 void paint_set(const ::messages::set_paintboard::ConstPtr& msg)
 {
+  painter_value = msg->setting;
+  set_servo(0, painter_value);
 }
 
 /**
@@ -55,6 +60,7 @@ void paint_set(const ::messages::set_paintboard::ConstPtr& msg)
 bool paint_query(::messages::query_paintboard::Request &req,
                  ::messages::query_paintboard::Response &res)
 {
+  res.setting = painter_value;
   return true;
 }
 
@@ -64,6 +70,7 @@ bool paint_query(::messages::query_paintboard::Request &req,
 bool metal_query(::messages::query_metal_detector::Request &req,
                  ::messages::query_metal_detector::Response &res)
 {
+  res.metal = get_input(0);
   return true;
 }
 
@@ -78,6 +85,10 @@ int main(int argc, char **argv)
     ros::init(argc, argv, "painter");
     ros::NodeHandle node;
 
+    i2c_start();
+    set_motor(0, 0);
+    set_servo(0, 0);
+
     ros::Subscriber painter_sub = node.subscribe("/set_paintboard", QUEUE_SIZE,
         paint_set);
     ros::ServiceServer painter_srv = node.advertiseService("/query_paintboard",
@@ -88,5 +99,7 @@ int main(int argc, char **argv)
     ROS_INFO("Painter node ready.");
     ros::spin();
 
+    i2c_stop();
+
     return 0;
 }
