1 #include <Wire.h> 2 #include <Servo.h> 3 4 #include <Max3421e.h> 5 #include <Usb.h> 6 #include <AndroidAccessory.h> 7 8 #include <CapSense.h> 9 10 #define LED3_RED 2 11 #define LED3_GREEN 4 12 #define LED3_BLUE 3 13 14 #define LED2_RED 5 15 #define LED2_GREEN 7 16 #define LED2_BLUE 6 17 18 #define LED1_RED 8 19 #define LED1_GREEN 10 20 #define LED1_BLUE 9 21 22 #define SERVO1 11 23 #define SERVO2 12 24 #define SERVO3 13 25 26 #define TOUCH_RECV 14 27 #define TOUCH_SEND 15 28 29 #define RELAY1 A0 30 #define RELAY2 A1 31 32 #define LIGHT_SENSOR A2 33 #define TEMP_SENSOR A3 34 35 #define BUTTON1 A6 36 #define BUTTON2 A7 37 #define BUTTON3 A8 38 39 #define JOY_SWITCH A9 // pulls line down when pressed 40 #define JOY_nINT A10 // active low interrupt input 41 #define JOY_nRESET A11 // active low reset output 42 43 AndroidAccessory acc("Google, Inc.", 44 "DemoKit", 45 "DemoKit Arduino Board", 46 "1.0", 47 "http://www.android.com", 48 "0000000012345678"); 49 Servo servos[3]; 50 51 // 10M ohm resistor on demo shield 52 CapSense touch_robot = CapSense(TOUCH_SEND, TOUCH_RECV); 53 54 void setup(); 55 void loop(); 56 57 void init_buttons() 58 { 59 pinMode(BUTTON1, INPUT); 60 pinMode(BUTTON2, INPUT); 61 pinMode(BUTTON3, INPUT); 62 pinMode(JOY_SWITCH, INPUT); 63 64 // enable the internal pullups 65 digitalWrite(BUTTON1, HIGH); 66 digitalWrite(BUTTON2, HIGH); 67 digitalWrite(BUTTON3, HIGH); 68 digitalWrite(JOY_SWITCH, HIGH); 69 } 70 71 72 void init_relays() 73 { 74 pinMode(RELAY1, OUTPUT); 75 pinMode(RELAY2, OUTPUT); 76 } 77 78 79 void init_leds() 80 { 81 digitalWrite(LED1_RED, 1); 82 digitalWrite(LED1_GREEN, 1); 83 digitalWrite(LED1_BLUE, 1); 84 85 pinMode(LED1_RED, OUTPUT); 86 pinMode(LED1_GREEN, OUTPUT); 87 pinMode(LED1_BLUE, OUTPUT); 88 89 digitalWrite(LED2_RED, 1); 90 digitalWrite(LED2_GREEN, 1); 91 digitalWrite(LED2_BLUE, 1); 92 93 pinMode(LED2_RED, OUTPUT); 94 pinMode(LED2_GREEN, OUTPUT); 95 pinMode(LED2_BLUE, OUTPUT); 96 97 digitalWrite(LED3_RED, 1); 98 digitalWrite(LED3_GREEN, 1); 99 digitalWrite(LED3_BLUE, 1); 100 101 pinMode(LED3_RED, OUTPUT); 102 pinMode(LED3_GREEN, OUTPUT); 103 pinMode(LED3_BLUE, OUTPUT); 104 } 105 106 void init_joystick(int threshold); 107 108 byte b1, b2, b3, b4, c; 109 void setup() 110 { 111 Serial.begin(115200); 112 Serial.print("\r\nStart"); 113 114 init_leds(); 115 init_relays(); 116 init_buttons(); 117 init_joystick( 5 ); 118 119 // autocalibrate OFF 120 touch_robot.set_CS_AutocaL_Millis(0xFFFFFFFF); 121 122 servos[0].attach(SERVO1); 123 servos[0].write(90); 124 servos[1].attach(SERVO2); 125 servos[1].write(90); 126 servos[2].attach(SERVO3); 127 servos[2].write(90); 128 129 130 b1 = digitalRead(BUTTON1); 131 b2 = digitalRead(BUTTON2); 132 b3 = digitalRead(BUTTON3); 133 b4 = digitalRead(JOY_SWITCH); 134 c = 0; 135 136 acc.powerOn(); 137 } 138 139 void loop() 140 { 141 byte err; 142 byte idle; 143 static byte count = 0; 144 byte msg[3]; 145 long touchcount; 146 147 if (acc.isConnected()) { 148 int len = acc.read(msg, sizeof(msg), 1); 149 int i; 150 byte b; 151 uint16_t val; 152 int x, y; 153 char c0; 154 155 if (len > 0) { 156 // assumes only one command per packet 157 if (msg[0] == 0x2) { 158 if (msg[1] == 0x0) 159 analogWrite(LED1_RED, 255 - msg[2]); 160 else if (msg[1] == 0x1) 161 analogWrite(LED1_GREEN, 255 - msg[2]); 162 else if (msg[1] == 0x2) 163 analogWrite(LED1_BLUE, 255 - msg[2]); 164 else if (msg[1] == 0x3) 165 analogWrite(LED2_RED, 255 - msg[2]); 166 else if (msg[1] == 0x4) 167 analogWrite(LED2_GREEN, 255 - msg[2]); 168 else if (msg[1] == 0x5) 169 analogWrite(LED2_BLUE, 255 - msg[2]); 170 else if (msg[1] == 0x6) 171 analogWrite(LED3_RED, 255 - msg[2]); 172 else if (msg[1] == 0x7) 173 analogWrite(LED3_GREEN, 255 - msg[2]); 174 else if (msg[1] == 0x8) 175 analogWrite(LED3_BLUE, 255 - msg[2]); 176 else if (msg[1] == 0x10) 177 servos[0].write(map(msg[2], 0, 255, 0, 180)); 178 else if (msg[1] == 0x11) 179 servos[1].write(map(msg[2], 0, 255, 0, 180)); 180 else if (msg[1] == 0x12) 181 servos[2].write(map(msg[2], 0, 255, 0, 180)); 182 } else if (msg[0] == 0x3) { 183 if (msg[1] == 0x0) 184 digitalWrite(RELAY1, msg[2] ? HIGH : LOW); 185 else if (msg[1] == 0x1) 186 digitalWrite(RELAY2, msg[2] ? HIGH : LOW); 187 } 188 } 189 190 msg[0] = 0x1; 191 192 b = digitalRead(BUTTON1); 193 if (b != b1) { 194 msg[1] = 0; 195 msg[2] = b ? 0 : 1; 196 acc.write(msg, 3); 197 b1 = b; 198 } 199 200 b = digitalRead(BUTTON2); 201 if (b != b2) { 202 msg[1] = 1; 203 msg[2] = b ? 0 : 1; 204 acc.write(msg, 3); 205 b2 = b; 206 } 207 208 b = digitalRead(BUTTON3); 209 if (b != b3) { 210 msg[1] = 2; 211 msg[2] = b ? 0 : 1; 212 acc.write(msg, 3); 213 b3 = b; 214 } 215 216 b = digitalRead(JOY_SWITCH); 217 if (b != b4) { 218 msg[1] = 4; 219 msg[2] = b ? 0 : 1; 220 acc.write(msg, 3); 221 b4 = b; 222 } 223 224 switch (count++ % 0x10) { 225 case 0: 226 val = analogRead(TEMP_SENSOR); 227 msg[0] = 0x4; 228 msg[1] = val >> 8; 229 msg[2] = val & 0xff; 230 acc.write(msg, 3); 231 break; 232 233 case 0x4: 234 val = analogRead(LIGHT_SENSOR); 235 msg[0] = 0x5; 236 msg[1] = val >> 8; 237 msg[2] = val & 0xff; 238 acc.write(msg, 3); 239 break; 240 241 case 0x8: 242 read_joystick(&x, &y); 243 msg[0] = 0x6; 244 msg[1] = constrain(x, -128, 127); 245 msg[2] = constrain(y, -128, 127); 246 acc.write(msg, 3); 247 break; 248 249 case 0xc: 250 touchcount = touch_robot.capSense(5); 251 252 c0 = touchcount > 750; 253 254 if (c0 != c) { 255 msg[0] = 0x1; 256 msg[1] = 3; 257 msg[2] = c0; 258 acc.write(msg, 3); 259 c = c0; 260 } 261 262 break; 263 } 264 } else { 265 // reset outputs to default values on disconnect 266 analogWrite(LED1_RED, 255); 267 analogWrite(LED1_GREEN, 255); 268 analogWrite(LED1_BLUE, 255); 269 analogWrite(LED2_RED, 255); 270 analogWrite(LED2_GREEN, 255); 271 analogWrite(LED2_BLUE, 255); 272 analogWrite(LED3_RED, 255); 273 analogWrite(LED3_GREEN, 255); 274 analogWrite(LED3_BLUE, 255); 275 servos[0].write(90); 276 servos[0].write(90); 277 servos[0].write(90); 278 digitalWrite(RELAY1, LOW); 279 digitalWrite(RELAY2, LOW); 280 } 281 282 delay(10); 283 } 284 285 // ============================================================================== 286 // Austria Microsystems i2c Joystick 287 void init_joystick(int threshold) 288 { 289 byte status = 0; 290 291 pinMode(JOY_SWITCH, INPUT); 292 digitalWrite(JOY_SWITCH, HIGH); 293 294 pinMode(JOY_nINT, INPUT); 295 digitalWrite(JOY_nINT, HIGH); 296 297 pinMode(JOY_nRESET, OUTPUT); 298 299 digitalWrite(JOY_nRESET, 1); 300 delay(1); 301 digitalWrite(JOY_nRESET, 0); 302 delay(1); 303 digitalWrite(JOY_nRESET, 1); 304 305 Wire.begin(); 306 307 do { 308 status = read_joy_reg(0x0f); 309 } while ((status & 0xf0) != 0xf0); 310 311 // invert magnet polarity setting, per datasheet 312 write_joy_reg(0x2e, 0x86); 313 314 calibrate_joystick(threshold); 315 } 316 317 318 int offset_X, offset_Y; 319 320 void calibrate_joystick(int dz) 321 { 322 char iii; 323 int x_cal = 0; 324 int y_cal = 0; 325 326 // Low Power Mode, 20ms auto wakeup 327 // INTn output enabled 328 // INTn active after each measurement 329 // Normal (non-Reset) mode 330 write_joy_reg(0x0f, 0x00); 331 delay(1); 332 333 // dummy read of Y_reg to reset interrupt 334 read_joy_reg(0x11); 335 336 for(iii = 0; iii != 16; iii++) { 337 while(!joystick_interrupt()) {} 338 339 x_cal += read_joy_reg(0x10); 340 y_cal += read_joy_reg(0x11); 341 } 342 343 // divide by 16 to get average 344 offset_X = -(x_cal>>4); 345 offset_Y = -(y_cal>>4); 346 347 write_joy_reg(0x12, dz - offset_X); // Xp, LEFT threshold for INTn 348 write_joy_reg(0x13, -dz - offset_X); // Xn, RIGHT threshold for INTn 349 write_joy_reg(0x14, dz - offset_Y); // Yp, UP threshold for INTn 350 write_joy_reg(0x15, -dz - offset_Y); // Yn, DOWN threshold for INTn 351 352 // dead zone threshold detect requested? 353 if (dz) 354 write_joy_reg(0x0f, 0x04); 355 } 356 357 358 void read_joystick(int *x, int *y) 359 { 360 *x = read_joy_reg(0x10) + offset_X; 361 *y = read_joy_reg(0x11) + offset_Y; // reading Y clears the interrupt 362 } 363 364 char joystick_interrupt() 365 { 366 return digitalRead(JOY_nINT) == 0; 367 } 368 369 370 #define JOY_I2C_ADDR 0x40 371 372 char read_joy_reg(char reg_addr) 373 { 374 char c; 375 376 Wire.beginTransmission(JOY_I2C_ADDR); 377 Wire.send(reg_addr); 378 Wire.endTransmission(); 379 380 Wire.requestFrom(JOY_I2C_ADDR, 1); 381 382 while(Wire.available()) 383 c = Wire.receive(); 384 385 return c; 386 } 387 388 void write_joy_reg(char reg_addr, char val) 389 { 390 Wire.beginTransmission(JOY_I2C_ADDR); 391 Wire.send(reg_addr); 392 Wire.send(val); 393 Wire.endTransmission(); 394 } 395