blob: 931fd18e147b5fbe9ca869927b50e78bf84bf6ae [file] [log] [blame]
Erik Gilling3edead52011-03-08 15:59:23 -08001#include <Wire.h>
2#include <Servo.h>
3
Erik Gilling9c16e962011-03-16 17:27:09 -07004#include <Max3421e.h>
5#include <Usb.h>
6#include <AndroidAccessory.h>
Erik Gilling3edead52011-03-08 15:59:23 -08007
Erik Gillingccfe9392011-04-04 10:21:14 -07008#include <CapSense.h>
9
Erik Gilling3edead52011-03-08 15:59:23 -080010#define LED3_RED 2
Erik Gillingea909002011-03-16 15:07:07 -070011#define LED3_GREEN 4
12#define LED3_BLUE 3
Erik Gilling3edead52011-03-08 15:59:23 -080013
14#define LED2_RED 5
Erik Gillingea909002011-03-16 15:07:07 -070015#define LED2_GREEN 7
16#define LED2_BLUE 6
Erik Gilling3edead52011-03-08 15:59:23 -080017
18#define LED1_RED 8
Erik Gillingea909002011-03-16 15:07:07 -070019#define LED1_GREEN 10
20#define LED1_BLUE 9
Erik Gilling3edead52011-03-08 15:59:23 -080021
22#define SERVO1 11
23#define SERVO2 12
24#define SERVO3 13
25
Erik Gillingccfe9392011-04-04 10:21:14 -070026#define TOUCH_RECV 14
27#define TOUCH_SEND 15
Erik Gilling3edead52011-03-08 15:59:23 -080028
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
Erik Gilling9c16e962011-03-16 17:27:09 -070043AndroidAccessory acc("Google, Inc.",
44 "DemoKit",
45 "DemoKit Arduino Board",
46 "1.0",
47 "http://www.android.com",
48 "0000000012345678");
Erik Gilling3edead52011-03-08 15:59:23 -080049Servo servos[3];
50
Erik Gillingc91d5882011-05-06 08:52:22 -070051// 10M ohm resistor on demo shield
52CapSense touch_robot = CapSense(TOUCH_SEND, TOUCH_RECV);
Erik Gillingccfe9392011-04-04 10:21:14 -070053
Erik Gilling3edead52011-03-08 15:59:23 -080054void setup();
55void loop();
56
Erik Gilling3edead52011-03-08 15:59:23 -080057void init_buttons()
58{
Erik Gillingc91d5882011-05-06 08:52:22 -070059 pinMode(BUTTON1, INPUT);
60 pinMode(BUTTON2, INPUT);
61 pinMode(BUTTON3, INPUT);
62 pinMode(JOY_SWITCH, INPUT);
Erik Gilling3edead52011-03-08 15:59:23 -080063
Erik Gillingc91d5882011-05-06 08:52:22 -070064 // enable the internal pullups
65 digitalWrite(BUTTON1, HIGH);
66 digitalWrite(BUTTON2, HIGH);
67 digitalWrite(BUTTON3, HIGH);
68 digitalWrite(JOY_SWITCH, HIGH);
Erik Gilling3edead52011-03-08 15:59:23 -080069}
70
71
72void init_relays()
73{
Erik Gillingc91d5882011-05-06 08:52:22 -070074 pinMode(RELAY1, OUTPUT);
75 pinMode(RELAY2, OUTPUT);
Erik Gilling3edead52011-03-08 15:59:23 -080076}
77
78
79void init_leds()
80{
Erik Gillingc91d5882011-05-06 08:52:22 -070081 digitalWrite(LED1_RED, 1);
82 digitalWrite(LED1_GREEN, 1);
83 digitalWrite(LED1_BLUE, 1);
Erik Gilling3edead52011-03-08 15:59:23 -080084
Erik Gillingc91d5882011-05-06 08:52:22 -070085 pinMode(LED1_RED, OUTPUT);
86 pinMode(LED1_GREEN, OUTPUT);
87 pinMode(LED1_BLUE, OUTPUT);
Erik Gilling3edead52011-03-08 15:59:23 -080088
Erik Gillingc91d5882011-05-06 08:52:22 -070089 digitalWrite(LED2_RED, 1);
90 digitalWrite(LED2_GREEN, 1);
91 digitalWrite(LED2_BLUE, 1);
Erik Gilling3edead52011-03-08 15:59:23 -080092
Erik Gillingc91d5882011-05-06 08:52:22 -070093 pinMode(LED2_RED, OUTPUT);
94 pinMode(LED2_GREEN, OUTPUT);
95 pinMode(LED2_BLUE, OUTPUT);
Erik Gilling3edead52011-03-08 15:59:23 -080096
Erik Gillingc91d5882011-05-06 08:52:22 -070097 digitalWrite(LED3_RED, 1);
98 digitalWrite(LED3_GREEN, 1);
99 digitalWrite(LED3_BLUE, 1);
Erik Gilling3edead52011-03-08 15:59:23 -0800100
Erik Gillingc91d5882011-05-06 08:52:22 -0700101 pinMode(LED3_RED, OUTPUT);
102 pinMode(LED3_GREEN, OUTPUT);
103 pinMode(LED3_BLUE, OUTPUT);
Erik Gilling3edead52011-03-08 15:59:23 -0800104}
105
Erik Gillingc91d5882011-05-06 08:52:22 -0700106void init_joystick(int threshold);
Erik Gilling3edead52011-03-08 15:59:23 -0800107
Erik Gilling894c5eb2011-04-04 10:46:13 -0700108byte b1, b2, b3, b4, c;
Erik Gilling3edead52011-03-08 15:59:23 -0800109void setup()
110{
Erik Gillingc91d5882011-05-06 08:52:22 -0700111 Serial.begin(115200);
Erik Gilling3edead52011-03-08 15:59:23 -0800112 Serial.print("\r\nStart");
113
114 init_leds();
115 init_relays();
116 init_buttons();
Erik Gillingc91d5882011-05-06 08:52:22 -0700117 init_joystick( 5 );
Erik Gilling3edead52011-03-08 15:59:23 -0800118
Erik Gillingc91d5882011-05-06 08:52:22 -0700119 // autocalibrate OFF
120 touch_robot.set_CS_AutocaL_Millis(0xFFFFFFFF);
Erik Gilling3edead52011-03-08 15:59:23 -0800121
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
Erik Gilling9c16e962011-03-16 17:27:09 -0700129
130 b1 = digitalRead(BUTTON1);
131 b2 = digitalRead(BUTTON2);
132 b3 = digitalRead(BUTTON3);
Erik Gilling894c5eb2011-04-04 10:46:13 -0700133 b4 = digitalRead(JOY_SWITCH);
Erik Gillingccfe9392011-04-04 10:21:14 -0700134 c = 0;
Erik Gilling9c16e962011-03-16 17:27:09 -0700135
136 acc.powerOn();
Erik Gilling3edead52011-03-08 15:59:23 -0800137}
138
Erik Gilling3edead52011-03-08 15:59:23 -0800139void loop()
140{
Erik Gilling3edead52011-03-08 15:59:23 -0800141 byte err;
Erik Gilling9c16e962011-03-16 17:27:09 -0700142 byte idle;
143 static byte count = 0;
144 byte msg[3];
Erik Gillingccfe9392011-04-04 10:21:14 -0700145 long touchcount;
Erik Gilling3edead52011-03-08 15:59:23 -0800146
Erik Gilling9c16e962011-03-16 17:27:09 -0700147 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;
Erik Gilling3edead52011-03-08 15:59:23 -0800154
Erik Gilling9c16e962011-03-16 17:27:09 -0700155 if (len > 0) {
Erik Gillingc91d5882011-05-06 08:52:22 -0700156 // assumes only one command per packet
Erik Gilling9c16e962011-03-16 17:27:09 -0700157 if (msg[0] == 0x2) {
158 if (msg[1] == 0x0)
Erik Gillingc91d5882011-05-06 08:52:22 -0700159 analogWrite(LED1_RED, 255 - msg[2]);
Erik Gilling9c16e962011-03-16 17:27:09 -0700160 else if (msg[1] == 0x1)
Erik Gillingc91d5882011-05-06 08:52:22 -0700161 analogWrite(LED1_GREEN, 255 - msg[2]);
Erik Gilling9c16e962011-03-16 17:27:09 -0700162 else if (msg[1] == 0x2)
Erik Gillingc91d5882011-05-06 08:52:22 -0700163 analogWrite(LED1_BLUE, 255 - msg[2]);
Erik Gilling9c16e962011-03-16 17:27:09 -0700164 else if (msg[1] == 0x3)
Erik Gillingc91d5882011-05-06 08:52:22 -0700165 analogWrite(LED2_RED, 255 - msg[2]);
Erik Gilling9c16e962011-03-16 17:27:09 -0700166 else if (msg[1] == 0x4)
Erik Gillingc91d5882011-05-06 08:52:22 -0700167 analogWrite(LED2_GREEN, 255 - msg[2]);
Erik Gilling9c16e962011-03-16 17:27:09 -0700168 else if (msg[1] == 0x5)
Erik Gillingc91d5882011-05-06 08:52:22 -0700169 analogWrite(LED2_BLUE, 255 - msg[2]);
Erik Gilling9c16e962011-03-16 17:27:09 -0700170 else if (msg[1] == 0x6)
Erik Gillingc91d5882011-05-06 08:52:22 -0700171 analogWrite(LED3_RED, 255 - msg[2]);
Erik Gilling9c16e962011-03-16 17:27:09 -0700172 else if (msg[1] == 0x7)
Erik Gillingc91d5882011-05-06 08:52:22 -0700173 analogWrite(LED3_GREEN, 255 - msg[2]);
Erik Gilling9c16e962011-03-16 17:27:09 -0700174 else if (msg[1] == 0x8)
Erik Gillingc91d5882011-05-06 08:52:22 -0700175 analogWrite(LED3_BLUE, 255 - msg[2]);
Erik Gilling9c16e962011-03-16 17:27:09 -0700176 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)
Erik Gillingc91d5882011-05-06 08:52:22 -0700184 digitalWrite(RELAY1, msg[2] ? HIGH : LOW);
Erik Gilling9c16e962011-03-16 17:27:09 -0700185 else if (msg[1] == 0x1)
Erik Gillingc91d5882011-05-06 08:52:22 -0700186 digitalWrite(RELAY2, msg[2] ? HIGH : LOW);
Erik Gilling3edead52011-03-08 15:59:23 -0800187 }
Erik Gilling3edead52011-03-08 15:59:23 -0800188 }
189
Erik Gilling9c16e962011-03-16 17:27:09 -0700190 msg[0] = 0x1;
Erik Gilling3edead52011-03-08 15:59:23 -0800191
Erik Gilling9c16e962011-03-16 17:27:09 -0700192 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
Erik Gilling894c5eb2011-04-04 10:46:13 -0700216 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
Erik Gilling9c16e962011-03-16 17:27:09 -0700224 switch (count++ % 0x10) {
Erik Gilling9c16e962011-03-16 17:27:09 -0700225 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
Erik Gilling9c16e962011-03-16 17:27:09 -0700249 case 0xc:
Erik Gillingccfe9392011-04-04 10:21:14 -0700250 touchcount = touch_robot.capSense(5);
251
252 c0 = touchcount > 750;
253
Erik Gilling9c16e962011-03-16 17:27:09 -0700254 if (c0 != c) {
255 msg[0] = 0x1;
256 msg[1] = 3;
Erik Gillingccfe9392011-04-04 10:21:14 -0700257 msg[2] = c0;
Erik Gilling9c16e962011-03-16 17:27:09 -0700258 acc.write(msg, 3);
259 c = c0;
260 }
Erik Gillingccfe9392011-04-04 10:21:14 -0700261
Erik Gilling9c16e962011-03-16 17:27:09 -0700262 break;
Erik Gilling9c16e962011-03-16 17:27:09 -0700263 }
Rob Tsukb63ed7a2011-05-05 16:39:13 -0700264 } else {
Erik Gillingc91d5882011-05-06 08:52:22 -0700265 // reset outputs to default values on disconnect
Rob Tsukb63ed7a2011-05-05 16:39:13 -0700266 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);
Erik Gilling3edead52011-03-08 15:59:23 -0800280 }
281
Erik Gilling9c16e962011-03-16 17:27:09 -0700282 delay(10);
Erik Gilling3edead52011-03-08 15:59:23 -0800283}
284
285// ==============================================================================
286// Austria Microsystems i2c Joystick
Erik Gillingc91d5882011-05-06 08:52:22 -0700287void init_joystick(int threshold)
Erik Gilling3edead52011-03-08 15:59:23 -0800288{
Erik Gillingc91d5882011-05-06 08:52:22 -0700289 byte status = 0;
Erik Gilling3edead52011-03-08 15:59:23 -0800290
Erik Gillingc91d5882011-05-06 08:52:22 -0700291 pinMode(JOY_SWITCH, INPUT);
292 digitalWrite(JOY_SWITCH, HIGH);
Erik Gilling3edead52011-03-08 15:59:23 -0800293
Erik Gillingc91d5882011-05-06 08:52:22 -0700294 pinMode(JOY_nINT, INPUT);
295 digitalWrite(JOY_nINT, HIGH);
Erik Gilling3edead52011-03-08 15:59:23 -0800296
Erik Gillingc91d5882011-05-06 08:52:22 -0700297 pinMode(JOY_nRESET, OUTPUT);
Erik Gilling3edead52011-03-08 15:59:23 -0800298
Erik Gillingc91d5882011-05-06 08:52:22 -0700299 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);
Erik Gilling3edead52011-03-08 15:59:23 -0800315}
316
317
318int offset_X, offset_Y;
319
Erik Gillingc91d5882011-05-06 08:52:22 -0700320void calibrate_joystick(int dz)
Erik Gilling3edead52011-03-08 15:59:23 -0800321{
Erik Gillingc91d5882011-05-06 08:52:22 -0700322 char iii;
323 int x_cal = 0;
324 int y_cal = 0;
Erik Gilling3edead52011-03-08 15:59:23 -0800325
Erik Gillingc91d5882011-05-06 08:52:22 -0700326 // 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);
Erik Gilling3edead52011-03-08 15:59:23 -0800332
Erik Gillingc91d5882011-05-06 08:52:22 -0700333 // dummy read of Y_reg to reset interrupt
334 read_joy_reg(0x11);
Erik Gilling3edead52011-03-08 15:59:23 -0800335
Erik Gillingc91d5882011-05-06 08:52:22 -0700336 for(iii = 0; iii != 16; iii++) {
337 while(!joystick_interrupt()) {}
Erik Gilling3edead52011-03-08 15:59:23 -0800338
Erik Gillingc91d5882011-05-06 08:52:22 -0700339 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);
Erik Gilling3edead52011-03-08 15:59:23 -0800355}
356
357
Erik Gillingc91d5882011-05-06 08:52:22 -0700358void read_joystick(int *x, int *y)
Erik Gilling3edead52011-03-08 15:59:23 -0800359{
Erik Gillingc91d5882011-05-06 08:52:22 -0700360 *x = read_joy_reg(0x10) + offset_X;
361 *y = read_joy_reg(0x11) + offset_Y; // reading Y clears the interrupt
Erik Gilling3edead52011-03-08 15:59:23 -0800362}
363
364char joystick_interrupt()
365{
Erik Gillingc91d5882011-05-06 08:52:22 -0700366 return digitalRead(JOY_nINT) == 0;
Erik Gilling3edead52011-03-08 15:59:23 -0800367}
368
369
370#define JOY_I2C_ADDR 0x40
371
Erik Gillingc91d5882011-05-06 08:52:22 -0700372char read_joy_reg(char reg_addr)
Erik Gilling3edead52011-03-08 15:59:23 -0800373{
Erik Gillingc91d5882011-05-06 08:52:22 -0700374 char c;
375
376 Wire.beginTransmission(JOY_I2C_ADDR);
Joe Fernandez7dfe7f82012-05-30 16:19:51 -0700377 Wire.write(reg_addr);
Erik Gillingc91d5882011-05-06 08:52:22 -0700378 Wire.endTransmission();
379
380 Wire.requestFrom(JOY_I2C_ADDR, 1);
381
382 while(Wire.available())
Joe Fernandez7dfe7f82012-05-30 16:19:51 -0700383 c = Wire.read();
Erik Gillingc91d5882011-05-06 08:52:22 -0700384
385 return c;
Erik Gilling3edead52011-03-08 15:59:23 -0800386}
387
Erik Gillingc91d5882011-05-06 08:52:22 -0700388void write_joy_reg(char reg_addr, char val)
Erik Gilling3edead52011-03-08 15:59:23 -0800389{
Erik Gillingc91d5882011-05-06 08:52:22 -0700390 Wire.beginTransmission(JOY_I2C_ADDR);
Joe Fernandez7dfe7f82012-05-30 16:19:51 -0700391 Wire.write(reg_addr);
392 Wire.write(val);
Erik Gillingc91d5882011-05-06 08:52:22 -0700393 Wire.endTransmission();
Erik Gilling3edead52011-03-08 15:59:23 -0800394}