Advertisement
dustinrobotics

Controller 2.0 4-19-2012

Apr 19th, 2012
504
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 64.67 KB | None | 0 0
  1. /* Controller 2.0
  2. Created by Dustin Reynolds at Mecharobotics.wordpress.com
  3.  
  4. You may share this library with Creative Commons - Share Alike
  5. license 2.0.  
  6.  
  7. This is released via the Creative Commons Share Alike 2.0 license:
  8. http://creativecommons.org/licenses/by-sa/2.0/  
  9.  
  10. You can copy it and use it in whatever, just attribute my name,
  11. Dustin Reynolds, and my blog when you do.  
  12. I'll appreciate if you let me know that you've used it,
  13. so I can show off your project on my blog :)
  14.  
  15. Copyright 2012 Dustin Reynolds
  16. *****************************************************************************
  17.   Includes the following:
  18.   20x4 LCD
  19.   XBee Connected to pins 0 and 1 of ATMEGA328
  20.   BTM-182 connected to pins 7 and 8
  21.   PS2 connector
  22.   Nunchuck connector
  23.   microSD adapter (using old microSD to SD converter)
  24.  
  25.   Size comparisons:
  26. with SD enabled
  27.   Everything Enabled: 29024 Bytes
  28.   Only LCD debug: 27252 Bytes
  29.   Only NUN LCD debug, PS2 disabled: 22550
  30.   Only PS2 LCD debug, NUN disabled: 25900
  31.   Only PS2 & Nun, no debug: 24690
  32.   Only PS2, no debug: 24484
  33.   No ps2 or Nun: 20972
  34. With SD disabled
  35.   Nun and PS2 disabled:13488
  36. BT disabled + SD + NUN PS2
  37.   Xbee: 11910
  38. Everything Disabled:
  39.   11886 bytes
  40.  
  41. Recommended Flags enabled:
  42.   SD_enable, NUN_Enable, NUN_DBG_LCD
  43.     -ps2 library takes about 5k of space, nun takes 3.6k
  44.     -Nun can do plenty, can improvise with buttons + joystick
  45.    
  46. Circuit:  Description of the circuit Textually:
  47.   3.3v VReg (MCP1702-3302E)
  48.     1-GND
  49.     2- + of battery, 0.1u to gnd*
  50.     3-3.3v, 0.1u*
  51.     *-1uF across 3.3V and gnd, 0.1 accross 3.3v and gnd
  52.   ATMEGA328
  53.     1-connected to Pin 6 of FTDI cable
  54.     2-Connected to pin 4 of FTDI Cable, To pin 2 of xbee (through a 1k resistor)
  55.     3-Connected to pin 5 of FTDI cable, to pin 3 of xbee (through a 1k resistor)
  56.             http://www.billporter.info/how-to-add-multiple-uart-connections/
  57.     4-Pin 9 of XBee
  58.     5-Pin 11 of shift register
  59.     6-Pin 14 of shift register
  60.     7-3.3V
  61.     8-gnd
  62.     9-left lead of 16MHz resonator (center to gnd)
  63.     10-right lead of 16MHz resonator(center to gnd)
  64.     11-connected to 100 ohm resistor, which is connected to + term of piezo, other conn to gnd.
  65.     13-Pin 9 of BTM-182 BT serial module
  66.     14-Pin 10 of BTM-182 BT serial module  
  67.     15-Pin 6 of PS2 controller
  68.     16-Pin 1 of SD adapter
  69.     17-pin 2 of PS2 controller, Pin 2 of SD card
  70.     18-Pin 1 of PS2 controller, Pin 7 of SD card
  71.     19-Pin 7 of PS2 controller, pin 5 of SD card
  72.     20-3.3V
  73.     21-3.3V
  74.     22-GND
  75.     23-1k to gnd, one end of button, other is connected to 10Kohm, connected to 3.3v
  76.     24-
  77.     25-
  78.     26-
  79.     27-2.2k to 3.3v, pin 1 of nunchuck(datapin)
  80.     28-2.2k to 3.3v, pin 2 of nunchuck(clk)
  81.   SD card (Notch to Left, not counting end connections)
  82.     1-pin 16 of cpu  //SD chip select pin
  83.     2-pin 17 of cpu
  84.     3-gnd
  85.     4-3.3v
  86.     5-pin 19 of cpu
  87.     6-gnd
  88.     7-pin 18 of cpu
  89.   XBee Series 1 Module
  90.      X-CTU:http://www.digi.com/support/productdetail?pid=3352&osvid=0&type=utilities
  91.      Wireless dl:http://www.sparkfun.com/tutorials/122
  92.     1-3.3v
  93.     2-1k connected to pin 2 of mcu
  94.     3-1k connected to pin 3 of mcu
  95.     9-connected to pin 4 of mcu
  96.     10-gnd
  97.   BTM-182 BT serial module
  98.      http://www.sparkfun.com/products/9913
  99.      AT commands:http://www.robot-r-us.com/downloads/sparkfun/wigwrl/812-wrl09977-lm400-data-sheet-dss-ver-1-2/download.html
  100.     9-pin 13 of mcu
  101.     10-pin 14 of mcu
  102.     15-3.3v
  103.     16-gnd
  104.   Shift Register 74LS164N
  105.      http://code.google.com/p/arduinoshiftreglcd/ (using 2 wire connection
  106.     1-pin 2 of shift reg, pin 6 of atmega328
  107.     2-pin 1 of shift reg, 1k to pin 6 of LCD
  108.     3-NC
  109.     4-NC
  110.     5-pin 4 of LCD
  111.     6-pin 11 of LCD
  112.     7-GND
  113.     8-pin 5 of atmega328
  114.     9-3.3v
  115.     10-pin 12 of lcd
  116.     11-pin 13 of lcd
  117.     12-pin 14 of lcd
  118.     13-diode from pin 6 of lcd, with line towards shift reg
  119.     14-3.3v
  120.   LCD 3.3V NewHaven 20x4 character LCD
  121.     1-gnd
  122.     2-3.3V
  123.     3-middle pin of 10k pot, other pins at 3.3v and gnd
  124.     4-pin 5 of shift reg
  125.     5-gnd
  126.     6-1k from pin 2 of shift, diode to pin 13 of shift reg, line towards shift
  127.     7,8,9,10-nc
  128.     11-pin 6 of shift
  129.     12-pin 10 of shift
  130.     13-pin 11 of shift
  131.     14-pin 12 of shift
  132.     15-nc(can be conn to 3.3v for backlight)
  133.     16-gnd
  134.   PS2 (round end down)
  135.      http://www.billporter.info/playstation-2-controller-arduino-library-v1-0/
  136.     1-pin 18 of mcu
  137.     2-pin 17 of mcu
  138.     3-nc(for motors)
  139.     4-gnd
  140.     5-3.3v
  141.     6-pin 15 of mcu
  142.     7-pin 19 of mcu
  143.   Nunchuck - dealextreme knockoff < $7
  144.      (nunchuck conn facing you, looks like a U not a n)
  145.      http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1273496638
  146.     1(upper left)-pin 27 of mcu, 2.2k pullup to 3.3v (clock)
  147.     2(upper right)-gnd
  148.     3(lower left)-3.3v
  149.     4(lower right)-pin 28 of mcu, 2.2k pullup to 3.3v (data)
  150.   Xbee is run using HW serial, BT using sw serial
  151.   PS2 run on SPI bus, SD on SPI bus
  152.   Nun run on I2C bus
  153.   LCD only uses 2 pins using shift reg
  154.   entire system at 3.3v
  155.  
  156. Notes:
  157.   How do I create a menu?
  158.     1. Add your menu in section 1. Edit the main menu to have your desired name in it.
  159.        Be sure to do yournameSUB and yournameLEN correctly, follow the examples.  Bakmain is
  160.        still counted, since this references the table in sec 4.
  161.     2. Add a yournameCONF to the list of confs, create a unique #define for each menu item.
  162.     3. Add a #define for your menu, set it to be the same as yournameSUB.  These are used in a
  163.        big switch statement in the select function
  164.     4. Add your prog_char's defined in step 1, to this table, in the correct space.
  165.     5. Goto select function, create a if statement in case: MAIN.  Create a case for your menu
  166.        name defined in step 3.
  167.   Dustin Reynolds
  168.   2012-03-24
  169. */
  170. #include <Wire.h>
  171. #include <Nunchuck.h>
  172. #include <PS2X_lib.h>  //for v1.6
  173. #include <SoftwareSerial.h>
  174. #include <ShiftRegLCD.h>
  175. #include <SD.h>
  176. #include <avr/pgmspace.h>
  177. #include <EEPROM.h>
  178.  
  179. //Comment out these to disable specific features.  Won't disable menus, since that is complicated
  180. //#define PS2_ENABLE
  181.   //#define PS2_DBG_SER
  182.   //#define PS2_DBG_LCD
  183. #define NUN_ENABLE
  184.   //#define NUN_DBG_SER
  185.   #define NUN_DBG_LCD  //adds 1184 bytes
  186.  
  187. //#define MUSIC_ENABLE  //takes 2566 bytes for 1 song
  188. #define TONE_PIN                5
  189. #define OCTAVE_OFFSET           0
  190.  
  191. // if cpu is 16 MHz, leave defined, if 8 MHz, comment out.
  192. #define CPU16MHZ 1
  193.  
  194. #define XBEE_ENABLE
  195. #define BT_ENABLE
  196.  
  197. #define SD_ENABLE
  198.   #define FILENAME_OFFSET 20 //single byte stored in EEPROM
  199. #define HMENU 4
  200. #define WMENU 20
  201.  
  202. #define THIS_ID 100  //d <-ascii for 100
  203. #define RC_CAR_ID 101  //e
  204. #define ADC_MONITOR_ID   102  //f
  205. const prog_char PROGMEM adc_monitor_id[] = "ATD=0123456789ab";
  206. //types
  207. #define TYPE_UTHERE       0
  208. #define TYPE_DISPTHIS     1
  209. #define TYPE_NUN_CONTROL  2
  210. #define TYPE_PS2_CONTROL  3
  211. #define TYPE_END_COMM     253
  212. #define TYPE_ACK          254
  213. #define TYPE_ERROR        255
  214. #define MAX_PKT_SIZE 30
  215. //options
  216. #define OPTION_SEND_CTL 0x01
  217. #define OPTION_NUN_CTL  0x02
  218. #define OPTION_PS2_CTL  0x04
  219.  
  220. #define TIMEOUT 10
  221. #define SUCCESS 1
  222. #define FAILURE 0
  223.  
  224. File logFile;
  225. #define SDCHIPSEL 10
  226.  
  227. PS2X ps2x; // create PS2 Controller Class
  228.  
  229. //#define DEBUG 1
  230.  
  231. ShiftRegLCD lcd(4, 3, TWO_WIRE, 4);  //we have a 20x4 LCD data clock enable #lines
  232. #ifdef BT_ENABLE
  233. SoftwareSerial btser(7, 8);
  234. #endif
  235. //want simple XBEE config
  236. #define XBEESLEEP 2//6  //Pin 12 for XBee sleep control, goes to pin 9 on xbee
  237.  
  238. //Music
  239. #ifdef MUSIC_ENABLE
  240.  
  241. #define NOTE_C4  262
  242. #define NOTE_CS4 277
  243. #define NOTE_D4  294
  244. #define NOTE_DS4 311
  245. #define NOTE_E4  330
  246. #define NOTE_F4  349
  247. #define NOTE_FS4 370
  248. #define NOTE_G4  392
  249. #define NOTE_GS4 415
  250. #define NOTE_A4  440
  251. #define NOTE_AS4 466
  252. #define NOTE_B4  494
  253. #define NOTE_C5  523
  254. #define NOTE_CS5 554
  255. #define NOTE_D5  587
  256. #define NOTE_DS5 622
  257. #define NOTE_E5  659
  258. #define NOTE_F5  698
  259. #define NOTE_FS5 740
  260. #define NOTE_G5  784
  261. #define NOTE_GS5 831
  262. #define NOTE_A5  880
  263. #define NOTE_AS5 932
  264. #define NOTE_B5  988
  265. #define NOTE_C6  1047
  266. #define NOTE_CS6 1109
  267. #define NOTE_D6  1175
  268. #define NOTE_DS6 1245
  269. #define NOTE_E6  1319
  270. #define NOTE_F6  1397
  271. #define NOTE_FS6 1480
  272. #define NOTE_G6  1568
  273. #define NOTE_GS6 1661
  274. #define NOTE_A6  1760
  275. #define NOTE_AS6 1865
  276. #define NOTE_B6  1976
  277. #define NOTE_C7  2093
  278. #define NOTE_CS7 2217
  279. #define NOTE_D7  2349
  280. #define NOTE_DS7 2489
  281. #define NOTE_E7  2637
  282. #define NOTE_F7  2794
  283. #define NOTE_FS7 2960
  284. #define NOTE_G7  3136
  285. #define NOTE_GS7 3322
  286. #define NOTE_A7  3520
  287. #define NOTE_AS7 3729
  288. #define NOTE_B7  3951
  289.  
  290. //const prog_char PROGMEM MusicSongPlay16[] = "smb:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6";
  291.  
  292. //const prog_char PROGMEM MusicSongPlay17[] = "SMBUndergr:d=16,o=6,b=100:c,c5,a5,a,a#5,a#,2p,8p,c,c5,a5,a,a#5,a#,2p,8p,f5,f,d5,d,d#5,d#,2p,8p,f5,f,d5,d,d#5,d#,2p,32d#,d,32c#,c,p,d#,p,d,p,g#5,p,g5,p,c#,p,32c,f#,32f,32e,a#,32a,g#,32p,d#,b5,32p,a#5,32p,a5,g#5";
  293.  
  294. //const prog_char PROGMEM MusicSongPlay18[] = "SMBWater:d=8,o=6,b=225:4d5,4e5,4f#5,4g5,4a5,4a#5,b5,b5,b5,p,b5,p,2b5,p,g5,2e.,2d#.,2e.,p,g5,a5,b5,c,d,2e.,2d#,4f,2e.,2p,p,g5,2d.,2c#.,2d.,p,g5,a5,b5,c,c#,2d.,2g5,4f,2e.,2p,p,g5,2g.,2g.,2g.,4g,4a,p,g,2f.,2f.,2f.,4f,4g,p,f,2e.,4a5,4b5,4f,e,e,4e.,b5,2c.";
  295.  
  296. const prog_char PROGMEM MusicSongPlay19[] = "smbdeath:d=4,o=5,b=90:32c6,32c6,32c6,8p,16b,16f6,16p,16f6,16f.6,16e.6,16d6,16c6,16p,16e,16p,16c";
  297.  
  298. //const prog_char PROGMEM MusicSongPlay24[] = "20thCenFox:d=16,o=5,b=140:b,8p,b,b,2b,p,c6,32p,b,32p,c6,32p,b,32p,c6,32p,b,8p,b,b,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,g#,32p,a,32p,b,8p,b,b,2b,4p,8e,8g#,8b,1c#6,8f#,8a,8c#6,1e6,8a,8c#6,8e6,1e6,8b,8g#,8a,2b";
  299.  
  300. int notes[] = { 0,
  301. NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
  302. NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
  303. NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
  304. NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
  305. };
  306.  
  307. #endif
  308.  
  309. #define BTNU                    (( uint8_t)13)
  310. #define BTND                    (( uint8_t)14)
  311. #define BTNL                    (( uint8_t)15)
  312. #define BTNR                    (( uint8_t)16)
  313. #define BTNA                    (( uint8_t)17)
  314. #define BTNB                    (( uint8_t)18)
  315. #define YES                     (( uint8_t)1)
  316. #define NO                      (( uint8_t)0)
  317. #define DEBOUNCE                200  //ms/sample
  318. #define PRESSHOLD               1000
  319.  
  320. #define UPARROW                 ((uint8_t)3)
  321. #define DOWNARROW               ((uint8_t)4)
  322. #define SELECT                  ((uint8_t)5)
  323. #define HEART                   ((uint8_t)0)
  324. #define SMILE                   ((uint8_t)2)
  325. #define KEY                     ((uint8_t)1)
  326. /***********************************SECTION 2 *****************************************/
  327. #define XBEECONF 0
  328. #define BTCONF   1
  329. #define NUNCONF  2
  330. #define PS2CONF  3
  331. #define SDCONF   4
  332. #define RC_CONF  5
  333. #define CONNADCSERVO  6
  334. #define CONNSAB  7
  335.  
  336. #define BACKMAIN  0
  337. #define XBEEPPP   1
  338. #define XBEESM1   2
  339. #define XBEECLOSE 3
  340.  
  341. #define BTPPP   1
  342. #define BTATR0  2
  343. #define BTATH   3
  344. #define BTATF   4
  345. #define BTATD   5
  346. #define BTATA   6
  347. #define BTCLOSE 7
  348.  
  349. #define NUNPRES 1
  350. #define NUNINIT 2
  351. #define NUNCAL  3
  352. #define NUNDLCD 4
  353. #define NUNDSER 5
  354.  
  355. #define PS2PRES 1
  356. #define PS2INIT 2
  357. #define PS2DLCD 3
  358. #define PS2DSER 4
  359.  
  360. #define SDPRES 1
  361. #define SDCNGI 2
  362. #define SDPREV 3
  363. /*****************************END OF SECTION 2 *****************************************/
  364. /***********************************SECTION 1 *****************************************/
  365. #define MAINSUB 0
  366. #define MAINLEN 7 //actual - 1
  367. const prog_char PROGMEM MenuStr1[] = "XBee Configure";
  368. const prog_char PROGMEM MenuStr2[] = "BT Configure";
  369. const prog_char PROGMEM MenuStr3[] = "NunChuck Configure";
  370. const prog_char PROGMEM MenuStr4[] = "PS2 Configure";
  371. const prog_char PROGMEM MenuStr5[] = "SD Configure";
  372. const prog_char PROGMEM MenuStr6[] = "Connect to RC Car";
  373. const prog_char PROGMEM MenuStr7[] = "Conn 2 ADC Servo";
  374. const prog_char PROGMEM MenuStr8[] = "Connect to Sable";
  375. #define XBEESUB 8 //actual - 1
  376.  
  377. #define XBEELEN 3  //actual - 1
  378. const prog_char PROGMEM Bakmain[] = "Back to Main";
  379. const prog_char PROGMEM Xbee2[] = "+++";
  380. const prog_char PROGMEM Xbee3[] = "SM1,ST3e8,SO1";
  381. const prog_char PROGMEM Xbee4[] = "WN,CN";
  382. #define BTSUB 12
  383.  
  384. #define BTLEN 7 //actual - 1
  385. //const prog_char PROGMEM Bakmain[] = "Back to Main";
  386. const prog_char PROGMEM BTser2[] = "+++ <-not alneeded";
  387. const prog_char PROGMEM BTser3[] = "ATR0";
  388. const prog_char PROGMEM BTser4[] = "ATH (drops conn)";
  389. const prog_char PROGMEM BTser5[] = "ATF?";
  390. const prog_char PROGMEM BTser6[] = "ATD";
  391. const prog_char PROGMEM BTser7[] = "ATA";
  392. const prog_char PROGMEM BTser8[] = "ATO closes conn";
  393. #define NUNSUB 20
  394.  
  395. #define NUNLEN 5 //actual - 1
  396. //const prog_char PROGMEM Bakmain[] = "Back to Main";   <-count it, but only use one
  397. const prog_char PROGMEM NUN2[] = "Nunchuk Present?";
  398. const prog_char PROGMEM NUN3[] = "Init";
  399. const prog_char PROGMEM NUN4[] = "SetCal";
  400. const prog_char PROGMEM NUN5[] = "Disp LCD";
  401. const prog_char PROGMEM NUN6[] = "Disp Serial";
  402. #define PS2SUB 26
  403.  
  404. #define PS2LEN 4 //actual - 1
  405. //const prog_char PROGMEM Bakmain[] = "Back to Main";   <-count it, but only use one
  406. const prog_char PROGMEM PS22[] = "PS2 Ctl Present?";
  407. //const prog_char PROGMEM NUN3[] = "Init";
  408. const prog_char PROGMEM PS24[] = "Disp LCD";
  409. const prog_char PROGMEM PS25[] = "Disp Serial";
  410. #define SDSUB 31
  411.  
  412. #define SDLEN 3 //actual - 1
  413. //const prog_char PROGMEM Bakmain[] = "Back to Main";   <-count it, but only use one
  414. const prog_char PROGMEM uSD2[] = "SD Present?";
  415. const prog_char PROGMEM uSD3[] = "Change File Index";
  416. const prog_char PROGMEM uSD4[] = "Preview Top File";
  417. /*****************************END OF SECTION 1 *****************************************/
  418. /***********************************SECTION 3 *****************************************/
  419. //currentmenu
  420. #define MAIN   MAINSUB
  421. #define XBEE   XBEESUB
  422. #define BT     BTSUB
  423. #define NUN    NUNSUB
  424. #define PS2    PS2SUB
  425. #define uSD    SDSUB
  426. /*****************************END OF SECTION 3 *****************************************/
  427. /***********************************SECTION 4 *****************************************/
  428. PGM_P PROGMEM MenuTable[] = {
  429.   MenuStr1,
  430.   MenuStr2,
  431.   MenuStr3,
  432.   MenuStr4,
  433.   MenuStr5,
  434.   MenuStr6,
  435.   MenuStr7,
  436.   MenuStr8,
  437.   Bakmain,
  438.   Xbee2,
  439.   Xbee3,
  440.   Xbee4,
  441.   Bakmain,
  442.   BTser2,
  443.   BTser3,
  444.   BTser4,
  445.   BTser5,
  446.   BTser6,
  447.   BTser7,
  448.   BTser8,
  449.   Bakmain,
  450.   NUN2,
  451.   NUN3,
  452.   NUN4,
  453.   NUN5,
  454.   NUN6,
  455.   Bakmain,
  456.   PS22,
  457.   NUN3,
  458.   PS24,
  459.   PS25,
  460.   Bakmain,
  461.   uSD2,
  462.   uSD3,
  463.   uSD4,
  464. };
  465. /*****************************END OF SECTION 4 *****************************************/
  466. const prog_char PROGMEM ppplus[] = "+++";
  467. const prog_char PROGMEM sm1[] = "ATSM1,ST3E8,SO1";
  468. const prog_char PROGMEM wncn[] = "ATWN,CN";
  469. const prog_char PROGMEM atr0[] = "ATR0";
  470. const prog_char PROGMEM ath[] = "ATH";
  471. const prog_char PROGMEM atf[] = "ATF?";
  472. const prog_char PROGMEM atd[] = "ATD?";
  473. const prog_char PROGMEM ata[] = "ATA";
  474. const prog_char PROGMEM ato[] = "ATO";
  475. const prog_char PROGMEM Timeout[] = "TimeOut";
  476. const prog_char PROGMEM Exit[] = "Exit";
  477.  
  478. //******************************************************************************
  479. //
  480. // Button Definitions
  481. //
  482. //******************************************************************************
  483. //2-dimensional array for asigning the buttons and there high and low values
  484. const uint16_t PROGMEM Button[21][3]  = {{1, 834, 845}, // button 1
  485.                      {2, 712, 721}, // button 2
  486.                      {3, 603, 613}, // button 3
  487.                      {4, 315, 326}, // button 4
  488.                      {5, 173, 185}, // button 5
  489.                      {6, 85, 97}, // button 6
  490.                      {7, 888, 898}, // button 1 + button 2
  491.                      {8, 872, 882}, // button 1 + button 3
  492.                      {9, 849, 858}, // button 1 + button 4
  493.                      {10, 844, 848}, // button 1 + button 5
  494.                      {11, 838, 843}, // button 1 + button 6
  495.                      {12, 805, 815}, // button 2 + button 3
  496.                      {13, 748, 758}, // button 2 + button 4
  497.                      {14, 729, 740}, // button 2 + button 5
  498.                      {15, 719, 728}, // button 2 + button 6
  499.                      {16, 668, 678}, // button 3 + button 4
  500.                      {17, 636, 646}, // button 3 + button 5
  501.                      {18, 619, 629}, // button 3 + button 6
  502.                      {19, 405, 415}, // button 4 + button 5
  503.                      {20, 359, 369}, // button 4 + button 6
  504.                      {21, 237, 247}}; // button 5 + button 6
  505.  
  506. byte Select[8]={  B01000,  B01100,  B00110,  B11111,  B11111,  B00110,  B01100,  B01000};
  507.  
  508. char menu = 0; //0 = main
  509. char menulen = MAINLEN;
  510. char menusel = 0;  //cursor
  511. char index[40];
  512. char currmenu = MAIN;  //current menu
  513. byte fileNum = 0;
  514. char file[20];
  515. int setup_ser(byte ser, char * string, char init, char initcr,char justppp, unsigned long timeout, uint16_t analogpin);
  516. uint8_t buttonWait(uint16_t analogpin, uint8_t toggle, uint8_t hold);
  517. uint8_t buttonCheck( uint16_t analogpin);
  518.  
  519. int send_pkt(byte iface, byte dest, byte type, int count, char * buffer)
  520. {
  521.   int checksum;
  522.  
  523.   //send header info:XYZA
  524.   if(iface == XBEE)
  525.   {
  526.     //X
  527.     Serial.write(0x0a); //LF
  528.     Serial.write(dest);
  529.     //Y
  530.     Serial.write(THIS_ID);//100 is controller
  531.     //Z Type
  532.     Serial.write(type);
  533.     //A count
  534.     Serial.write(count);
  535.   }
  536.   else //BT, assumption is that we are already connected to the thing
  537.   {
  538.     //X
  539.     btser.write(0x0a); //LF
  540.     btser.write(dest);
  541.     //Y
  542.     btser.write(THIS_ID);//100 is controller
  543.     //Z Type
  544.     btser.write(type);
  545.     //A count
  546.     btser.write(count);
  547.   }
  548.   //intialize checksum
  549.   checksum = dest+THIS_ID+type+count;
  550.  
  551.   //get checksum for data
  552.   for(int j=0; j<count; j++)
  553.     checksum +=buffer[j];
  554.  
  555.   //send data
  556.   if(iface == XBEE)
  557.     for(int j=0; j<count; j++)
  558.       Serial.write(buffer[j]);
  559.   else
  560.     for(int j=0; j<count; j++)
  561.       btser.write(buffer[j]);
  562.  
  563.   while (checksum > 256)
  564.     checksum -= 256;
  565.   if(iface == XBEE)
  566.   {
  567.     Serial.write(checksum);
  568.     Serial.write(0x0d); //LF
  569.   }
  570.   else
  571.   {
  572.     btser.write(checksum);
  573.     btser.write(0x0d); //LF
  574.   }
  575.  
  576.   return 1;
  577. }
  578.  
  579. byte get_pkt(byte iface, char* buffer, byte size, uint16_t timeout)
  580. {
  581.   byte temp;
  582.   byte gotchar = 0;
  583.   byte type;
  584.   byte count = 0;
  585.   byte checksum = 0;
  586.   byte theirchecksum = 0;
  587.   byte theirid;
  588.   byte buffoffset = 0;
  589.   byte state = 0;  //0 - wait for LF
  590.                    //1 - next is THIS_ID
  591.                    //2 - their ID
  592.                    //3 - type
  593.                    //4 - count
  594.                    //5-count - packet
  595.                    //last checksum
  596.   unsigned long time1 = millis();
  597.   while(1){
  598.     if(millis() > time1 + timeout)
  599.     {
  600.       //timeout, abort
  601.       memset(buffer, 0, size);
  602.       //lcd.print("Ti");
  603.       return TIMEOUT;
  604.     }
  605.    
  606.     //button escape
  607.     if(analogRead(A0) > 70)
  608.     {
  609.       lcd.print((__FlashStringHelper *)Exit);
  610.       while(analogRead(A0) > 70){};
  611.       if(iface == XBEE)
  612.         digitalWrite(XBEESLEEP, HIGH);
  613.       return FAILURE;
  614.     }
  615.    
  616.     if(iface == XBEE)
  617.     {
  618.       gotchar = 0; //only iterate on times in which we received something
  619.                    //don't want to be stuck in 1 big if statement though
  620.       if(Serial.available())
  621.       {
  622.         temp = Serial.read();
  623.         //lcd.print(temp);
  624.         gotchar = 1;
  625.       }
  626.       if(gotchar == 0)
  627.         continue;
  628.     }
  629.     else
  630.     {
  631.       gotchar = 0; //only iterate on times in which we received something
  632.                    //don't want to be stuck in 1 big if statement though
  633.       if(btser.available())
  634.       {
  635.         temp = btser.read();
  636.         //lcd.print(temp);
  637.         gotchar = 1;
  638.       }
  639.       if(gotchar == 0)
  640.         continue;
  641.       //nothing here, so break
  642.     }
  643.    
  644.     //state machine
  645.     if(state == 0)
  646.     {
  647.       if(temp == 0x0A)  //only start processing iff LF received
  648.       {
  649.         state++;
  650.       }
  651.     }
  652.     else if(state == 1)
  653.     {
  654.       if(temp == THIS_ID)
  655.       {
  656.         state++;
  657.         checksum += THIS_ID;
  658.       }
  659.       else
  660.       {
  661.         //lcd.print("Wrong ID");
  662.         //delay(2000);
  663.         state = 0;
  664.         count = 0;
  665.         checksum = 0;
  666.         buffoffset = 0;
  667.       }
  668.     }
  669.     else if(state == 2)
  670.     {
  671.       theirid = temp;
  672.       checksum += temp;
  673.       state++;
  674.       *(buffer + buffoffset++) = theirid;
  675.     }
  676.     else if(state == 3)
  677.     {
  678.       type = temp; //save type, not sure what to do with it now
  679.       checksum += type;
  680.       state++;
  681.       *(buffer + buffoffset++) = type;
  682.     }
  683.     else if(state == 4)
  684.     {
  685.       count = temp; //save count
  686.       checksum += count;
  687.       if(count == 0) //empty packet?
  688.         state++; //skip packet step, go straight to checksum
  689.       state++;
  690.       *(buffer + buffoffset++) = count;
  691.     }
  692.     else if(state == 5)
  693.     {
  694.       //stay in this state until count bytes arrive, or until timeout
  695.       //count guaranteed to be > 0 initially
  696.       *(buffer + buffoffset++) = temp;  //save in buffer
  697.       checksum += temp;
  698.       if(--count == 0)
  699.       {
  700.         state++;
  701.       }
  702.     }
  703.     else if(state == 6)
  704.     {
  705.       //checksum
  706.       theirchecksum = temp;
  707.      
  708.       if(theirchecksum == checksum)
  709.       {
  710.         //Buffer valid, return to calling program
  711.         return SUCCESS; //data stored in provided buffer
  712.       }
  713.       else
  714.       {
  715.         //checksum not valid, return to state 0
  716.         state = 0;
  717.         memset(buffer, 0, size);
  718.         lcd.print((int)checksum);
  719.         lcd.print("checksum wrong");
  720.       }
  721.     }
  722.   }
  723. }
  724.  
  725. /* Handle packet - Does everything conceivable for a received packet
  726.     -displays data
  727.     -sends control packet every time_sendctl milli seconds
  728.     -times out after timeout, if no communication
  729.     -exits if button held
  730.  
  731. */
  732. byte handle_pkt(byte iface, byte dest, byte options, uint16_t sendctl, uint16_t timeout)
  733. {
  734.   unsigned long time_timeout = millis() + timeout;
  735.   unsigned long time_sendctl = millis() + sendctl;
  736.   char buffer[MAX_PKT_SIZE];
  737.   char outbuffer[MAX_PKT_SIZE];
  738.   byte thisdest;
  739.   byte type;
  740.   byte nthings;
  741.   byte col;
  742.   byte row;
  743.   char disp_str[WMENU+1];
  744.   byte error;
  745.   int tempx,tempy,tempz;
  746.   int i = 0;
  747.  
  748.   if(iface == XBEE)
  749.     digitalWrite(XBEESLEEP, LOW);
  750.  
  751. #ifdef NUN_ENABLE    
  752.   if(options & OPTION_NUN_CTL)
  753.   {
  754.     nunchuk_init();
  755.   }
  756. #endif
  757. #ifdef PS2_ENABLE
  758.   if (options & OPTION_PS2_CTL)
  759.   {
  760.     error = ps2x.config_gamepad(13,11,9,12, true, false);
  761.   }
  762. #endif
  763.  
  764.   while(1)
  765.   {
  766.     //update device, if we are using it
  767. #ifdef NUN_ENABLE
  768.     if(options & OPTION_NUN_CTL)
  769.     {
  770.       nunchuk_send_request();
  771.       nunchuk_get_data();
  772.     }
  773. #endif
  774. #ifdef PS2_ENABLE
  775.     if (options & OPTION_PS2_CTL)
  776.     {
  777.       ps2x.read_gamepad(false, 0);
  778.     }
  779. #endif
  780.     if(millis() > time_timeout)
  781.     {
  782.       lcd.print((__FlashStringHelper *)Timeout);
  783.       break;
  784.     }
  785.     if(millis() > time_sendctl)
  786.     {
  787.       if(options & OPTION_SEND_CTL)
  788.       {
  789.         memset(buffer,0,MAX_PKT_SIZE);
  790.         i = 0;
  791.        
  792.         //get packet ready to send
  793. #ifdef NUN_ENABLE
  794.         if(options & OPTION_NUN_CTL)
  795.         {
  796.           //send bare values, calib occurs on remote dest
  797.           buffer[i++] = nunchuk_zbutton();
  798.           buffer[i++] = nunchuk_cbutton();
  799.           buffer[i++] = nunchuk_joy_x();
  800.           buffer[i++] = nunchuk_joy_y();
  801.           lcd.setCursor(1,1);
  802.           lcd.print((int)nunchuk_joy_x());
  803.           tempx = nunchuk_accelx();
  804.           tempy = nunchuk_accely();
  805.           tempz = nunchuk_accelz();
  806.          
  807.           buffer[i++] = (char)(tempx >> 8);
  808.           buffer[i++] = (char)(tempx % 256);
  809.           buffer[i++] = (char)(tempy >> 8);
  810.           buffer[i++] = (char)(tempy % 256);
  811.           buffer[i++] = (char)(tempz >> 8);
  812.           buffer[i++] = (char)(tempz % 256);
  813.          
  814.          
  815.           send_pkt(iface,dest,TYPE_NUN_CONTROL,i,buffer);
  816.          
  817.         }
  818. #endif
  819. #ifdef PS2_ENABLE
  820.         if (options & OPTION_PS2_CTL)
  821.         {
  822.           //send bare values, calib occurs on remote dest
  823.           buffer[i++] = ps2x.Analog(PSS_RX);
  824.           buffer[i++] = ps2x.Analog(PSS_RY);
  825.           buffer[i++] = ps2x.Analog(PSS_LX);
  826.           buffer[i++] = ps2x.Analog(PSS_LY);
  827.           buffer[i++] = ps2x.Button(PSB_L3);
  828.           buffer[i++] = ps2x.Button(PSB_R3);
  829.           buffer[i++] = ps2x.Analog(PSAB_PAD_UP);
  830.           buffer[i++] = ps2x.Analog(PSAB_PAD_DOWN);
  831.           buffer[i++] = ps2x.Analog(PSAB_PAD_LEFT);
  832.           buffer[i++] = ps2x.Analog(PSAB_PAD_RIGHT);
  833.           buffer[i++] = ps2x.Analog(PSAB_CROSS);
  834.           buffer[i++] = ps2x.Analog(PSAB_TRIANGLE);
  835.           buffer[i++] = ps2x.Analog(PSAB_SQUARE);
  836.           buffer[i++] = ps2x.Analog(PSAB_CIRCLE);
  837.           buffer[i++] = ps2x.Analog(PSAB_L1);
  838.           buffer[i++] = ps2x.Analog(PSAB_R1);
  839.           buffer[i++] = ps2x.Analog(PSAB_L2);
  840.           buffer[i++] = ps2x.Analog(PSAB_R2);
  841.           buffer[i++] = ps2x.Button(PSB_START);
  842.           buffer[i++] = ps2x.Button(PSB_SELECT);
  843.          
  844.           send_pkt(iface,dest,TYPE_PS2_CONTROL,i,buffer);
  845.         }
  846. #endif
  847.       }
  848.       time_sendctl = millis() + sendctl;
  849.     }
  850.  
  851.     //exit condition?
  852.     if(analogRead(A0) > 70)
  853.     {
  854.       lcd.print((__FlashStringHelper *)Exit);
  855.       while(analogRead(A0) > 70){};
  856.       if(iface == XBEE)
  857.         digitalWrite(XBEESLEEP, HIGH);
  858.       return 1;
  859.     }
  860.    
  861.     //handle received packets (shorter delay if sending ctl since need quick feedback (can't wait around forever)
  862.     if(options & OPTION_SEND_CTL)
  863.       error = get_pkt(iface, buffer, MAX_PKT_SIZE, 100); //once 100 ms elapses, it abort packet reception
  864.     else
  865.       error = get_pkt(iface, buffer, MAX_PKT_SIZE, 1000); //longer delay since not actively controlling something
  866.    
  867.     //process packet
  868.    // if(error == TIMEOUT)
  869.     //  send_pkt(iface,dest,TYPE_ERROR,0,buffer);
  870.     if (error == FAILURE)
  871.       return FAILURE;
  872.     else if(error == SUCCESS)
  873.     {
  874.       i = 0;
  875.       //their id
  876.       thisdest = buffer[i++];
  877.       if(thisdest!= dest)
  878.       {
  879.         //should we process this?  leave it for now
  880.       }
  881.       else
  882.       {
  883.         //reset time, since we recently received something.
  884.         time_timeout = millis() + timeout;
  885.       }
  886.       //lcd.clear();
  887.       //lcd.print((int)thisdest);lcd.print("-");
  888.       //read type
  889.       type = buffer[i++];
  890.      
  891.       memset(outbuffer,0,sizeof(outbuffer));
  892.      
  893.       //lcd.print((int)type);lcd.print("-");
  894.       switch(type)
  895.       {
  896.         case TYPE_UTHERE:
  897.         {
  898.           nthings = buffer[i++];
  899.          
  900.           outbuffer[0] = 'Y';
  901.          
  902.           if(buffer[i] == 'P')
  903.             send_pkt(iface,thisdest,TYPE_UTHERE,1,outbuffer);
  904.            
  905.           //else, do nothing, no response needed
  906.           break;
  907.         }
  908.         case TYPE_DISPTHIS:
  909.         {
  910.           //disp can be on controller, or remote thing!
  911.           nthings = buffer[i++]; //size
  912.           //lcd.print((int)nthings);lcd.print("-");
  913.           if(nthings == 0)  //clear screen if type dispthis, and size is 0
  914.           {
  915.             lcd.clear();
  916.             break;
  917.           }
  918.           col = buffer[i++];
  919.           row = buffer[i++];
  920.          
  921.           strncpy(disp_str, buffer+i, WMENU);  //max of 1 row at a time, received string
  922.                                              //should be null terminated.
  923.           disp_str[nthings-2] = 0; //ensure it is null terminated at desired spot to prevent overflow
  924.           //lcd.print(col);lcd.print("-");
  925.           //lcd.print(row);
  926.           lcd.setCursor(col,row);
  927.           lcd.print(disp_str);
  928.          
  929.           //send Ack?
  930.           //send_pkt(iface,thisdest,TYPE_ACK,0,outbuffer);
  931.           break;
  932.         }
  933.         case TYPE_NUN_CONTROL:
  934.         {
  935.           //for controller, what does this mean?
  936. #ifdef NUN_ENABLE
  937. #endif
  938.           break;
  939.         }
  940.         case TYPE_PS2_CONTROL:
  941.         {
  942.           //for controller, what does this mean?
  943. #ifdef PS2_ENABLE
  944. #endif
  945.           break;
  946.         }
  947.         case TYPE_ACK:
  948.         {
  949.           //last packet received OK
  950.           break;
  951.         }
  952.         case TYPE_ERROR:
  953.         {
  954.           //last packet not received, resend depending on mode perhaps?
  955.           break;
  956.         }
  957.         case TYPE_END_COMM:
  958.         {
  959.           //remote requests end of comm
  960.           send_pkt(iface,thisdest,TYPE_END_COMM,0,outbuffer);//send packet acking this
  961.           break;
  962.         }
  963.         default:
  964.         {
  965.           //future type?
  966.           lcd.print((int)type);
  967.           break;
  968.         }
  969.       }
  970.      
  971.     }
  972.    
  973.    
  974.   }
  975.   return 0;
  976. }
  977.  
  978. #ifdef MUSIC_ENABLE
  979. //globals
  980. char * _currsong;
  981. uint8_t  _default_dur;
  982. uint8_t  _default_oct;
  983. uint32_t _wholenote;
  984. uint32_t _duration;
  985. uint16_t _bpm;
  986. char * _songptr;
  987. uint8_t _repeat;
  988. char buffer[500]; //space to store song
  989. long _waittime;
  990.  
  991. void musicInit(const char * song)
  992. {
  993.   int num;
  994.  
  995.   //fill buffer    This works perfectly!
  996.   _songptr = strcpy_P(buffer,song);
  997.  
  998.  
  999.   //lcd->print((char) _songptr[1]);  //worked!
  1000.  
  1001.   //delay(2000);
  1002.  
  1003.    //c = *_songptr;              worked!
  1004.    //lcd->print((char) c);
  1005.  
  1006.  
  1007.  // lcd->print(_songptr);
  1008.   //delay(2000);
  1009.  
  1010.  
  1011.  //process beginning of music file
  1012.  // format: d=N,o=N,b=NNN:
  1013.   // find the start (skip name, etc)
  1014.  
  1015.   while(*_songptr != ':') _songptr++;    // ignore name
  1016.   _songptr++;                     // skip ':'
  1017.  
  1018.   // get default duration
  1019.   if(*_songptr == 'd')
  1020.   {
  1021.     _songptr++; _songptr++;              // skip "d="
  1022.     num = 0;
  1023.     while(isdigit(*_songptr))
  1024.     {
  1025.       num = (num * 10) + (*_songptr++ - '0');
  1026.     }
  1027.     if(num > 0) _default_dur = num;
  1028.     _songptr++;                   // skip comma
  1029.   }
  1030.  
  1031.   // get default octave
  1032.   if(*_songptr == 'o')
  1033.   {
  1034.     _songptr++; _songptr++;              // skip "o="
  1035.     num = *_songptr++ - '0';
  1036.     if(num >= 3 && num <=7) _default_oct = num;
  1037.     _songptr++;                   // skip comma
  1038.   }
  1039.  
  1040.   // get BPM
  1041.   if(*_songptr == 'b')
  1042.   {
  1043.     _songptr++; _songptr++;              // skip "b="
  1044.     num = 0;
  1045.     while(isdigit(*_songptr))
  1046.     {
  1047.       num = (num * 10) + (*_songptr++ - '0');
  1048.     }
  1049.     _bpm = num;
  1050.     _songptr++;                   // skip colon
  1051.   }
  1052.  
  1053.   // BPM usually expresses the number of quarter notes per minute
  1054.   _wholenote = (60 * 1000L / _bpm) * 4;  // this is the time for whole note (in milliseconds)
  1055.  
  1056.   //save location of beginning
  1057.   _currsong = _songptr;  //points to beginning of song hopefully
  1058.   //primed to start playing
  1059.  
  1060.   while(1)
  1061.   {
  1062.  
  1063.  
  1064.     uint16_t num = 0;
  1065.     byte note;
  1066.     byte scale;
  1067.  
  1068.     if(*_songptr == ' ')
  1069.     {
  1070.        *_songptr++;
  1071.     }
  1072.    
  1073.     if(*_songptr == 0)
  1074.     {
  1075.       //null terminated string, repeat?
  1076.      if(_repeat)
  1077.      {
  1078.        _songptr =  _currsong;
  1079.      }
  1080.      else
  1081.      {
  1082.       return;
  1083.      }
  1084.     }
  1085.  
  1086.   // first, get note duration, if available
  1087.       num = 0;
  1088.       while(isdigit(*_songptr))
  1089.       {
  1090.         num = (num * 10) + (*_songptr++ - '0');
  1091.       }
  1092.      
  1093.       if(num) _duration = _wholenote / num;
  1094.       else _duration = _wholenote / _default_dur;  // we will need to check if we are a dotted note after
  1095.  
  1096.       // now get the note
  1097.       note = 0;
  1098.  
  1099.       //if statements faster than switch
  1100.       //default == 0
  1101.       if(*_songptr == 'c')
  1102.           note = 1;
  1103.       if(*_songptr == 'd')
  1104.           note = 3;
  1105.       if(*_songptr == 'e')
  1106.           note = 5;
  1107.       if(*_songptr == 'f')
  1108.           note = 6;
  1109.       if(*_songptr == 'g')
  1110.           note = 8;
  1111.       if(*_songptr == 'a')
  1112.           note = 10;
  1113.       if(*_songptr == 'b')
  1114.           note = 12;
  1115.  
  1116.       _songptr++;
  1117.  
  1118.       // now, get optional '#' sharp
  1119.       if(*_songptr == '#')
  1120.       {
  1121.         note++;
  1122.         _songptr++;
  1123.       }
  1124.  
  1125.       // now, get optional '.' dotted note
  1126.       if(*_songptr == '.')
  1127.       {
  1128.         _duration += _duration>>1;///2;//>>1;
  1129.         _songptr++;
  1130.       }
  1131.    
  1132.       // now, get scale
  1133.       if(isdigit(*_songptr))
  1134.       {
  1135.         scale = *_songptr - '0';
  1136.         _songptr++;
  1137.       }
  1138.       else
  1139.       {
  1140.         scale = _default_oct;
  1141.       }
  1142.  
  1143.       scale += OCTAVE_OFFSET;
  1144.  
  1145.       if(*_songptr == ',')
  1146.         _songptr++;       // skip comma for next note (or we may be at the end)
  1147.  
  1148.       noTone(TONE_PIN);
  1149.       // now play the note
  1150.       if(note)
  1151.       {
  1152.         tone(TONE_PIN, notes[(scale - 4) * 12 + note], _duration);
  1153.       }
  1154.      
  1155.     //next interrupt at duration
  1156.   #ifdef CPU16MHZ
  1157.   //  OCR1A = (_duration*4);  //times 4, 16MHz proc
  1158.     delay(_duration);
  1159.   #else
  1160.   //  OCR1A = (_duration*8);  //times 8, 8MHz proc
  1161.     delay(_duration);
  1162.   #endif
  1163.     //_waittime = _duration+1;  //+1 because 1 is check value, not 0
  1164.   }
  1165. }
  1166. #endif
  1167.  
  1168. void setup()
  1169. {
  1170.   //xbee
  1171.   Serial.begin(19200);
  1172.   pinMode(XBEESLEEP,OUTPUT); //6
  1173.   digitalWrite(XBEESLEEP, HIGH);
  1174. #ifdef BT_ENABLE
  1175.   //bt
  1176.   pinMode (7,INPUT);
  1177.   pinMode (8,OUTPUT);
  1178.   btser.begin(9600);
  1179. #endif
  1180. #ifdef SD_ENABLE
  1181.   pinMode(10, OUTPUT);
  1182. #endif
  1183.   lcd.createChar(5, Select);
  1184.  
  1185.   for(int i=0; i<40; i++)
  1186.     index[i] = i;
  1187.   strncpy(file,"File",5);
  1188.  
  1189.   fileNum = EEPROM.read(FILENAME_OFFSET);
  1190.  
  1191. #ifdef MUSIC_ENABLE
  1192.   //timer_1a_init();  //init timer1
  1193.   musicInit(MusicSongPlay19);
  1194.   //musicstart(0);
  1195. #endif
  1196. }
  1197. //good for numbers < 100
  1198. byte convert_string(char * string, short n)
  1199. {
  1200.   byte count = 0;
  1201.   if(n>=10)
  1202.   {
  1203.     count = convert_string(string, n/10);
  1204.     n = n%10;
  1205.   }
  1206.   *(string + count) = n+'0';
  1207.   return count+1;
  1208. }
  1209.  
  1210. //handle things here, not in loop
  1211. void select(uint8_t cmenu, uint8_t menus)
  1212. {
  1213.   switch(cmenu)
  1214.   {
  1215.     case MAIN:
  1216.       if(menus == XBEECONF)
  1217.       {
  1218.         menu=XBEESUB;
  1219.         menulen=XBEELEN;
  1220.         currmenu = XBEE;
  1221.         digitalWrite(XBEESLEEP, LOW);
  1222.         menusel = 0;
  1223.       }
  1224.       else if(menus == BTCONF)
  1225.       {
  1226.         menu=BTSUB;
  1227.         menulen=BTLEN;
  1228.         currmenu = BT;
  1229.         menusel = 0;
  1230.       }
  1231.       else if(menus == NUNCONF)
  1232.       {
  1233.         menu=NUNSUB;
  1234.         menulen=NUNLEN;
  1235.         currmenu = NUN;
  1236.         menusel = 0;
  1237.       }
  1238.       else if(menus == PS2CONF)
  1239.       {
  1240.         menu=PS2SUB;
  1241.         menulen=PS2LEN;
  1242.         currmenu = PS2;
  1243.         menusel = 0;
  1244.       }
  1245.       else if(menus == SDCONF)
  1246.       {
  1247.         menu=SDSUB;
  1248.         menulen=SDLEN;
  1249.         currmenu = uSD;
  1250.         menusel = 0;
  1251.       }
  1252.       else if(menus == RC_CONF)
  1253.       {
  1254.         char buffer[10];
  1255.         byte error = 0;
  1256.         byte options = 0;
  1257.        
  1258.         lcd.clear();
  1259.         digitalWrite(XBEESLEEP, LOW);
  1260.         delay(32);
  1261.         //connect via xbee
  1262.         while(1)
  1263.         {
  1264.           //send P to see if present
  1265.           memset(buffer,0,sizeof(buffer));
  1266.           buffer[0] = 'P';
  1267.           send_pkt(XBEE,RC_CAR_ID,TYPE_UTHERE,1,buffer);//send P to RC car
  1268.           error = get_pkt(XBEE, buffer, 10, 10000); //expect 1 byte back, need space for 2 more(type and id
  1269.                                           //timeout for 1 second from this get packet
  1270.           if(error == TIMEOUT)
  1271.           {
  1272.             //timeout occured
  1273.             lcd.print("T");
  1274.             send_pkt(XBEE,RC_CAR_ID,TYPE_ERROR,0,buffer);
  1275.           }
  1276.           else if(error == SUCCESS) //if we successfully get something
  1277.           {
  1278.             //now communication is established, start main communication
  1279.             options = OPTION_SEND_CTL | OPTION_NUN_CTL;
  1280.             handle_pkt(XBEE, RC_CAR_ID, options, 100, 5000);
  1281.           }
  1282.           //break if button pushed, abort
  1283.           if(analogRead(A0) > 70)
  1284.           {
  1285.             digitalWrite(XBEESLEEP, HIGH);
  1286.             return;
  1287.            
  1288.           }
  1289.         }
  1290.         //once connected, run send pkt
  1291.         digitalWrite(XBEESLEEP, HIGH);
  1292.         break;
  1293.       }
  1294.      
  1295.       else if (menus == CONNADCSERVO)
  1296.       {
  1297.         char buffer[10];
  1298.         byte error = 0;
  1299.         byte options = 0;
  1300.        
  1301.         lcd.clear();
  1302.        
  1303.         //connect via BT, send control as expected
  1304.         //btser.print((__FlashStringHelper *)adc_monitor_id);
  1305.         //btser.write(0x0D);
  1306.         //delay(100);
  1307.         //connect
  1308.         while(btser.available() > 0){btser.read();};
  1309.        
  1310.         setup_ser(BT,ppplus,YES,YES,YES,10000,A0);
  1311.         lcd.clear();
  1312.         setup_ser(BT,adc_monitor_id,NO,NO,NO,10000,A0);
  1313.         lcd.clear();
  1314.         setup_ser(BT,ata,NO,NO,NO,10000,A0);
  1315.         lcd.clear();
  1316.         //btser.print((__FlashStringHelper *)ata);
  1317.         //btser.write(0x0D);
  1318.        
  1319.         while(1)
  1320.         {
  1321.           //send P to see if present
  1322.           memset(buffer,0,sizeof(buffer));
  1323.           buffer[0] = 'P';
  1324.           send_pkt(BT,ADC_MONITOR_ID,TYPE_UTHERE,1,buffer);//send P to RC car
  1325.           error = get_pkt(BT, buffer, 1000, 10000); //expect 1 byte back, need space for 2 more(type and id
  1326.                                           //timeout for 1 second from this get packet
  1327.           if(error == TIMEOUT)
  1328.           {
  1329.             //timeout occured
  1330.             lcd.print("T");
  1331.             send_pkt(BT,ADC_MONITOR_ID,TYPE_ERROR,0,buffer);
  1332.           }
  1333.           else if(error == SUCCESS) //if we successfully get something
  1334.           {
  1335.             //now communication is established, start main communication
  1336.             options = OPTION_SEND_CTL | OPTION_NUN_CTL;
  1337.             handle_pkt(BT, ADC_MONITOR_ID, options, 100, 5000);
  1338.           }
  1339.           //break if button pushed, abort
  1340.           if(analogRead(A0) > 70)
  1341.           {
  1342.             digitalWrite(XBEESLEEP, HIGH);
  1343.             return;
  1344.           }
  1345.           break;
  1346.         }
  1347.         break;
  1348.       }
  1349.       else
  1350.         menu = MAINSUB;
  1351.       break;
  1352.     case XBEE:
  1353.       if(menus == BACKMAIN)
  1354.       {
  1355.         menu=MAINSUB; ;
  1356.         menulen=MAINLEN;
  1357.         currmenu = MAIN;
  1358.         digitalWrite(XBEESLEEP, HIGH);
  1359.         menusel = 0;
  1360.       }
  1361. #ifdef XBEE_ENABLE
  1362.       else if (menus == XBEEPPP)
  1363.       {
  1364.         //do code here, or move to other function?
  1365.         lcd.clear();
  1366.         setup_ser(XBEE,wncn,YES,NO,NO,10000,A0);
  1367.         //delay(2000);
  1368.       }
  1369.       else if (menus == XBEECLOSE)
  1370.       {
  1371.         //do code here, or move to other function?
  1372.         lcd.clear();
  1373.         setup_ser(XBEE,wncn,YES,NO,NO,10000,A0);
  1374.         //delay(2000);
  1375.       }
  1376.       else
  1377.         menu = XBEESUB;
  1378. #endif
  1379.       break;
  1380.     case BT:
  1381.       if(menus == BACKMAIN)
  1382.       {
  1383.         menu=MAINSUB;
  1384.         menulen=MAINLEN;
  1385.         currmenu = MAIN;
  1386.         menusel = 0;
  1387.       }
  1388. #ifdef BT_ENABLE
  1389.       else if (menus == BTPPP)
  1390.       {
  1391.         //do code here, or move to other function?
  1392.         lcd.clear();
  1393.         setup_ser(BT,ppplus,YES,YES,YES,10000,A0);
  1394.         //delay(2000);
  1395.       }
  1396.       else if (menus == BTATR0)
  1397.       {
  1398.         //do code here, or move to other function?
  1399.         lcd.clear();
  1400.         setup_ser(BT,atr0,NO,NO,NO,10000,A0);
  1401.         //delay(2000);
  1402.       }
  1403.       else if (menus == BTATH)
  1404.       {
  1405.         //do code here, or move to other function?
  1406.         lcd.clear();
  1407.         setup_ser(BT,ath,NO,NO,NO,10000,A0);
  1408.         //delay(2000);
  1409.       }
  1410.       else if (menus == BTATF)
  1411.       {
  1412.         //do code here, or move to other function?
  1413.         lcd.clear();
  1414.         setup_ser(BT,atf,NO,NO,NO,10000,A0);
  1415.         //scan_bt_menuize(10000);
  1416.         //delay(2000);
  1417.       }
  1418.       else if (menus == BTATD)
  1419.       {
  1420.         //do code here, or move to other function?
  1421.         lcd.clear();
  1422.         setup_ser(BT,atd,NO,NO,NO,10000,A0);
  1423.         //delay(2000);
  1424.       }
  1425.       else if (menus == BTATA)
  1426.       {
  1427.         //do code here, or move to other function?
  1428.         lcd.clear();
  1429.         setup_ser(BT,ata,NO,NO,NO,10000,A0);
  1430.         //delay(2000);
  1431.       }
  1432.       else if (menus == BTCLOSE)
  1433.       {
  1434.         //do code here, or move to other function?
  1435.         lcd.clear();
  1436.         setup_ser(BT,ato,NO,NO,NO,10000,A0);
  1437.         //delay(2000);
  1438.       }
  1439.       else
  1440.         menu = BTSUB;
  1441. #endif
  1442.       break;
  1443.     case NUN:
  1444.       if(menus == BACKMAIN)
  1445.       {
  1446.         menu=MAINSUB;
  1447.         menulen=MAINLEN;
  1448.         currmenu = MAIN;
  1449.         menusel = 0;
  1450.       }
  1451. #ifdef NUN_ENABLE
  1452.       else if (menus == NUNPRES)
  1453.       {
  1454.         lcd.clear();
  1455.         Wire.begin();
  1456.         Wire.beginTransmission(0x52);
  1457.         if( Wire.endTransmission() == 0)
  1458.           lcd.print(F("Nunchuck Found"));
  1459.         else
  1460.           lcd.print((__FlashStringHelper *)Timeout);
  1461.         delay(1000);
  1462.       }
  1463.       else if (menus == NUNINIT)
  1464.       {
  1465.         nunchuk_init();
  1466.         nunchuk_send_request();
  1467.         nunchuk_get_data();
  1468.       }
  1469.       else if (menus == NUNDLCD || menus == NUNDSER || menus == NUNCAL)
  1470.       {
  1471.         lcd.clear();
  1472.         digitalWrite(XBEESLEEP, LOW);
  1473.         while(1)
  1474.         {
  1475.         nunchuk_send_request();
  1476.         nunchuk_get_data();
  1477.  
  1478. #ifdef NUN_DBG_SER
  1479.         //lcd.clear();
  1480.         if( menus == NUNDSER)
  1481.         {
  1482.           Serial.print("Z ");
  1483.           Serial.print((unsigned int)nunchuk_zbutton());
  1484.           Serial.print("\tC ");
  1485.           Serial.print((unsigned int)nunchuk_cbutton());
  1486.           //rest of data
  1487.           Serial.print("\tJx ");
  1488.           Serial.print((unsigned int)nunchuk_joy_x());
  1489.           Serial.print("\tJy ");
  1490.           Serial.print((unsigned int)nunchuk_joy_y());
  1491.  
  1492.           Serial.print("\tcJx ");
  1493.           Serial.print((signed int)nunchuk_cjoy_x());
  1494.           Serial.print("\tcJy ");
  1495.           Serial.print((signed int)nunchuk_cjoy_y());
  1496.          
  1497.           //accel
  1498.           Serial.print("\tAcX ");
  1499.           Serial.print((unsigned int)nunchuk_accelx());
  1500.           Serial.print("\tAcY ");
  1501.           Serial.print((unsigned int)nunchuk_accely());
  1502.           Serial.print("\tAcZ ");
  1503.           Serial.print((unsigned int)nunchuk_accelz());
  1504.          
  1505.           Serial.print("\tcAcX ");
  1506.           Serial.print((signed int)nunchuk_caccelx());
  1507.           Serial.print("\tcAcY ");
  1508.           Serial.print((signed int)nunchuk_caccely());
  1509.           Serial.print("\tcAcZ ");
  1510.           Serial.println((signed int)nunchuk_caccelz());
  1511.           delay(250);
  1512.         }
  1513. #endif
  1514.         if( menus == NUNDLCD || menus == NUNCAL)
  1515.         {
  1516. #ifdef NUN_DBG_LCD
  1517.           lcd.home();
  1518.           lcd.print("Z ");
  1519.           lcd.print((unsigned int)nunchuk_zbutton());
  1520.           lcd.print("C ");
  1521.           lcd.print((unsigned int)nunchuk_cbutton());
  1522.           //rest of data
  1523.           lcd.print("Jx   ");
  1524.           lcd.setCursor(8,0);
  1525.           lcd.print((unsigned int)nunchuk_joy_x());
  1526.           lcd.setCursor(11,0);
  1527.           lcd.print("Jy   ");
  1528.           lcd.setCursor(13,0);
  1529.           lcd.print((unsigned int)nunchuk_joy_y());
  1530.          
  1531.           //accel - non cal
  1532.           lcd.setCursor(0,1);
  1533.           lcd.print("aX    ");
  1534.           lcd.setCursor(3,1);
  1535.           lcd.print((unsigned int)nunchuk_accelx());
  1536.           lcd.setCursor(6,1);
  1537.           lcd.print("aY    ");
  1538.           lcd.setCursor(9,1);
  1539.           lcd.print((unsigned int)nunchuk_accely());
  1540.           lcd.setCursor(12,1);
  1541.           lcd.print("aZ    ");
  1542.           lcd.setCursor(15,1);
  1543.           lcd.print((unsigned int)nunchuk_accelz());
  1544.          
  1545.           //cal acc
  1546.           lcd.setCursor(0,2);
  1547.           lcd.print("cX    ");
  1548.           lcd.setCursor(2,2);
  1549.           lcd.print((signed int)nunchuk_caccelx());
  1550.           lcd.setCursor(6,2);
  1551.           lcd.print("cY    ");
  1552.           lcd.setCursor(9,2);
  1553.           lcd.print((signed int)nunchuk_caccely());
  1554.           lcd.setCursor(12,2);
  1555.           lcd.print("cZ    ");
  1556.           lcd.setCursor(15,2);
  1557.           lcd.print((signed int)nunchuk_caccelz());
  1558.          
  1559.           //cal joy
  1560.           lcd.setCursor(0,3);
  1561.           lcd.print("cJx    ");
  1562.           lcd.setCursor(3,3);
  1563.           lcd.print((signed int)nunchuk_cjoy_x());
  1564.           lcd.setCursor(7,3);
  1565.           lcd.print("cJy    ");
  1566.           lcd.setCursor(10,3);
  1567.           lcd.print((signed int)nunchuk_cjoy_y());
  1568.  
  1569.           //angle of joy
  1570.           // lcd.setCursor(0,2);
  1571.           // lcd.print("Ang       ");
  1572.           // lcd.setCursor(4,2);
  1573.           // lcd.print((signed int)nunchuk_joyangle());
  1574.           // lcd.setCursor(10,2);
  1575.           // lcd.print("rol       ");
  1576.           // lcd.setCursor(14,2);
  1577.           // lcd.print((signed int)nunchuk_rollangle());
  1578.           // lcd.setCursor(0,3);
  1579.           // lcd.print("pitch           ");
  1580.           // lcd.setCursor(6,3);
  1581.           // lcd.print((signed int)nunchuk_pitchangle());
  1582.          
  1583.           if(nunchuk_zbutton() == 1 && menus == NUNCAL)
  1584.           {
  1585.             nunchuk_calibrate_joy();
  1586.             nunchuk_calibrate_accelxy();
  1587.             nunchuk_calibrate_accelz();
  1588.             lcd.print((__FlashStringHelper *)Exit);
  1589.             while(nunchuk_zbutton() == 1){
  1590.               nunchuk_send_request();
  1591.               nunchuk_get_data();
  1592.             }
  1593.             break;
  1594.           }
  1595. #endif
  1596.         }
  1597.         if(analogRead(A0) > 70)
  1598.         {
  1599.           lcd.print((__FlashStringHelper *)Exit);
  1600.           while(analogRead(A0) > 70){};
  1601.           digitalWrite(XBEESLEEP, HIGH);
  1602.           break;
  1603.         }
  1604.         }
  1605.       }
  1606.       else
  1607.       {
  1608.         menu = NUNSUB;
  1609.       }
  1610. #endif
  1611.       break;
  1612.     case PS2:
  1613.       if(menus == BACKMAIN)
  1614.       {
  1615.         menu=MAINSUB;
  1616.         menulen=MAINLEN;
  1617.         currmenu = MAIN;
  1618.         menusel = 0;
  1619.       }
  1620. #ifdef PS2_ENABLE
  1621.       else if(menus == PS2PRES)
  1622.       {
  1623.         lcd.clear();
  1624.         error = ps2x.config_gamepad(13,11,9,12, true, false);
  1625.         if(error == 1)
  1626.           lcd.print((__FlashStringHelper *)Timeout);
  1627.         else
  1628.           lcd.print(F("PS2 Ctl Found"));
  1629.         lcd.print((char)error + '0');
  1630.         delay(1000);
  1631.       }
  1632.       else if(menus == PS2INIT)
  1633.       {
  1634.         lcd.clear();
  1635.         error = ps2x.config_gamepad(13,11,9,12, true, false);
  1636.         lcd.print((char)error);
  1637.         delay(1000);
  1638.       }
  1639.       else if(menus == PS2DLCD || menus == PS2DSER)
  1640.       {
  1641.         lcd.clear();
  1642.         digitalWrite(XBEESLEEP, LOW);
  1643.         error = ps2x.config_gamepad(13,11,9,12, true, false);
  1644.         while(1){
  1645.           ps2x.read_gamepad(false, 0);
  1646.           if(menus == PS2DLCD)
  1647.           {
  1648.           //Joysticks
  1649. #ifdef PS2_DBG_LCD
  1650.           lcd.home();
  1651.           lcd.print("rX   ");
  1652.           lcd.setCursor(2,0);
  1653.           lcd.print((unsigned int)ps2x.Analog(PSS_RX));
  1654.           lcd.setCursor(5,0);
  1655.           lcd.print("Y   ");
  1656.           lcd.setCursor(6,0);
  1657.           lcd.print((unsigned int)ps2x.Analog(PSS_RY));
  1658.           lcd.setCursor(9,0);
  1659.           lcd.print("lX   ");
  1660.           lcd.setCursor(11,0);
  1661.           lcd.print((unsigned int)ps2x.Analog(PSS_LX));
  1662.           lcd.setCursor(14,0);
  1663.           lcd.print("Y   ");
  1664.           lcd.setCursor(15,0);
  1665.           lcd.print((unsigned int)ps2x.Analog(PSS_LY));
  1666.           lcd.setCursor(18,0);
  1667.           lcd.print("3 ");
  1668.           lcd.setCursor(19,0);
  1669.           lcd.print((unsigned int)ps2x.Button(PSB_L3));
  1670.        
  1671.           lcd.setCursor(0,1);
  1672.           lcd.print("X   ");
  1673.           lcd.setCursor(1,1);
  1674.           lcd.print((unsigned int)ps2x.Analog(PSAB_CROSS));
  1675.           lcd.setCursor(4,1);
  1676.           lcd.print("T   ");
  1677.           lcd.setCursor(5,1);
  1678.           lcd.print((unsigned int)ps2x.Analog(PSAB_TRIANGLE));
  1679.           lcd.setCursor(8,1);
  1680.           lcd.print("Sq   ");
  1681.           lcd.setCursor(10,1);
  1682.           lcd.print((unsigned int)ps2x.Analog(PSAB_SQUARE));
  1683.           lcd.setCursor(13,1);
  1684.           lcd.print("O   ");
  1685.           lcd.setCursor(14,1);
  1686.           lcd.print((unsigned int)ps2x.Analog(PSAB_CIRCLE));
  1687.           lcd.setCursor(17,1);
  1688.           lcd.print("R3 ");
  1689.           lcd.setCursor(19,1);
  1690.           lcd.print((unsigned int)ps2x.Button(PSB_R3));
  1691.          
  1692.           lcd.setCursor(0,2);
  1693.           lcd.print("U   ");
  1694.           lcd.setCursor(1,2);
  1695.           lcd.print((unsigned int)ps2x.Analog(PSAB_PAD_UP));
  1696.           lcd.setCursor(4,2);
  1697.           lcd.print("D   ");
  1698.           lcd.setCursor(5,2);
  1699.           lcd.print((unsigned int)ps2x.Analog(PSAB_PAD_DOWN));
  1700.           lcd.setCursor(8,2);
  1701.           lcd.print("L    ");
  1702.           lcd.setCursor(10,2);
  1703.           lcd.print((unsigned int)ps2x.Analog(PSAB_PAD_LEFT));
  1704.           lcd.setCursor(13,2);
  1705.           lcd.print("R   ");
  1706.           lcd.setCursor(14,2);
  1707.           lcd.print((unsigned int)ps2x.Analog(PSAB_PAD_RIGHT));
  1708.           lcd.setCursor(17,2);
  1709.           lcd.print("ST ");
  1710.           lcd.setCursor(19,2);
  1711.           lcd.print((unsigned int)ps2x.Button(PSB_START));
  1712.          
  1713.           lcd.setCursor(0,3);
  1714.           lcd.print("L   ");
  1715.           lcd.setCursor(1,3);
  1716.           lcd.print((unsigned int)ps2x.Analog(PSAB_L2));
  1717.           lcd.setCursor(4,3);
  1718.           lcd.print("R   ");
  1719.           lcd.setCursor(5,3);
  1720.           lcd.print((unsigned int)ps2x.Analog(PSAB_R2));
  1721.           lcd.setCursor(8,3);
  1722.           lcd.print("L1   ");
  1723.           lcd.setCursor(10,3);
  1724.           lcd.print((unsigned int)ps2x.Analog(PSAB_L1));
  1725.           lcd.setCursor(13,3);
  1726.           lcd.print("R   ");
  1727.           lcd.setCursor(14,3);
  1728.           lcd.print((unsigned int)ps2x.Analog(PSAB_R1));
  1729.           lcd.setCursor(17,3);
  1730.           lcd.print("Se ");
  1731.           lcd.setCursor(19,3);
  1732.           lcd.print((unsigned int)ps2x.Button(PSB_SELECT));
  1733. #endif
  1734.           }
  1735.           else
  1736.           {
  1737. #ifdef PS2_DBG_SER
  1738.           Serial.print("rX ");
  1739.           Serial.print((unsigned int)ps2x.Analog(PSS_RX));
  1740.           Serial.print("Y  ");
  1741.           Serial.print((unsigned int)ps2x.Analog(PSS_RY));
  1742.           Serial.print("lX ");
  1743.           Serial.print((unsigned int)ps2x.Analog(PSS_LX));
  1744.           Serial.print("Y  ");
  1745.           Serial.print((unsigned int)ps2x.Analog(PSS_LY));
  1746.           Serial.print("3  ");
  1747.           Serial.print((unsigned int)ps2x.Button(PSB_L3));
  1748.        
  1749.           Serial.print("X  ");
  1750.           Serial.print((unsigned int)ps2x.Analog(PSAB_CROSS));
  1751.           Serial.print("T  ");
  1752.           Serial.print((unsigned int)ps2x.Analog(PSAB_TRIANGLE));
  1753.           Serial.print("Sq ");
  1754.           Serial.print((unsigned int)ps2x.Analog(PSAB_SQUARE));
  1755.           Serial.print("O  ");
  1756.           Serial.print((unsigned int)ps2x.Analog(PSAB_CIRCLE));
  1757.           Serial.print("R3 ");
  1758.           Serial.print((unsigned int)ps2x.Button(PSB_R3));
  1759.          
  1760.           Serial.print("U  ");
  1761.           Serial.print((unsigned int)ps2x.Analog(PSAB_PAD_UP));
  1762.           Serial.print("D  ");
  1763.           Serial.print((unsigned int)ps2x.Analog(PSAB_PAD_DOWN));
  1764.           Serial.print("L  ");
  1765.           Serial.print((unsigned int)ps2x.Analog(PSAB_PAD_LEFT));
  1766.           Serial.print("R  ");
  1767.           Serial.print((unsigned int)ps2x.Analog(PSAB_PAD_RIGHT));
  1768.           Serial.print("ST ");
  1769.           Serial.print((unsigned int)ps2x.Button(PSB_START));
  1770.          
  1771.           Serial.print("L  ");
  1772.           Serial.print((unsigned int)ps2x.Analog(PSAB_L2));
  1773.           Serial.print("R  ");
  1774.           Serial.print((unsigned int)ps2x.Analog(PSAB_R2));
  1775.           Serial.print("L1 ");
  1776.           Serial.print((unsigned int)ps2x.Analog(PSAB_L1));
  1777.           Serial.print("R  ");
  1778.           Serial.print((unsigned int)ps2x.Analog(PSAB_R1));
  1779.           Serial.print("Se ");
  1780.           Serial.println((unsigned int)ps2x.Button(PSB_SELECT));
  1781. #endif
  1782.           }
  1783.         if(analogRead(A0) > 70)
  1784.         {
  1785.           lcd.print((__FlashStringHelper *)Exit);
  1786.           while(analogRead(A0) > 70){};
  1787.           digitalWrite(XBEESLEEP, HIGH);
  1788.           break;
  1789.         }
  1790.         }
  1791.       }
  1792. #endif
  1793.       break;
  1794.     case uSD:
  1795.       if(menus == BACKMAIN)
  1796.       {
  1797.         menu=MAINSUB; ;
  1798.         menulen=MAINLEN;
  1799.         currmenu = MAIN;
  1800.         menusel = 0;
  1801.       }
  1802. #ifdef SD_ENABLE
  1803.       else if (menus == SDPRES)
  1804.       {
  1805.         if (!SD.begin(SDCHIPSEL))
  1806.         {
  1807.           lcd.clear();
  1808.           lcd.print((__FlashStringHelper *)Timeout);
  1809.         }
  1810.         else
  1811.         {
  1812.           lcd.print(F("Card Found"));
  1813.         }
  1814.         delay(1000);
  1815.       }
  1816.       else if (menus == SDCNGI)
  1817.       {//fileNum fileNum
  1818.         //filename in array file
  1819.         //idea is to write to array
  1820.        
  1821.         //if Nunchuck present, use it to scroll up and down on menu
  1822.         //Wire.beginTransmission(0x52);
  1823.         //if( Wire.endTransmission() == 0)
  1824.        
  1825.         nunchuk_init();
  1826.         lcd.clear();
  1827.         while(1)
  1828.         {
  1829.           nunchuk_send_request();
  1830.           nunchuk_get_data();
  1831.          
  1832.           lcd.home();
  1833.           lcd.print(F("Filename:File   "));
  1834.           lcd.setCursor(13,0);
  1835.           if(nunchuk_joy_y() > 170)
  1836.             fileNum++;
  1837.           if(nunchuk_joy_y() < 100)
  1838.             fileNum--;
  1839.           lcd.print((byte)fileNum );
  1840.          
  1841.          
  1842.          
  1843.           delay(100);
  1844.          
  1845.          
  1846.           if(analogRead(A0) > 60)
  1847.           {
  1848.             lcd.setCursor(0,1);
  1849.             //write changes
  1850.             EEPROM.write(FILENAME_OFFSET, fileNum);  //1 byte file name
  1851.             memset(file+4,0,3);
  1852.             convert_string(&file[4], fileNum);
  1853.             file[8] = 0;
  1854.             lcd.print(file);
  1855.             lcd.print((__FlashStringHelper *)Exit);
  1856.             while(analogRead(A0) > 70){};
  1857.             break;
  1858.          
  1859.           }
  1860.         }
  1861.       }
  1862.       else if (menus == SDPREV)
  1863.       {
  1864.         //idea is to preview first page of file, or perhaps
  1865.         //let you scroll with a attached joystick.
  1866.         lcd.clear();
  1867.        
  1868.         //show file name
  1869.         lcd.print(file);
  1870.        
  1871.         //load file
  1872.         convert_string(&file[4], fileNum);
  1873.         file[8] = 0;  //make sure it is null terminated
  1874.  
  1875.         //card present, open file
  1876.         logFile = SD.open(file);
  1877.         delay(1000);
  1878.         if(logFile)
  1879.         {
  1880.           //logFile.println("testing");
  1881.           int i = 0;
  1882.           lcd.clear();
  1883.           while(logFile.available())
  1884.           {
  1885.             lcd.print((char)logFile.read());
  1886.             i++;
  1887.             if(i >= 40)
  1888.             {
  1889.             if(analogRead(A0) > 60)
  1890.             {
  1891.               lcd.print((__FlashStringHelper *)Exit);
  1892.               while(analogRead(A0) > 70){};
  1893.               break;
  1894.             }
  1895.             delay(2000);
  1896.             i=0;
  1897.             }
  1898.           }
  1899.           logFile.close();
  1900.           delay(2000);
  1901.         }
  1902.         delay(2000);
  1903.       }
  1904. #endif
  1905.       break;
  1906.     default:
  1907.       break;
  1908.   }
  1909.  
  1910. }
  1911.  
  1912. void loop()
  1913. {
  1914.   uint8_t button;
  1915.  
  1916.   lcd.clear();
  1917.   //simple menu here
  1918.   for(int i=0; i<HMENU && index[i+menu]-currmenu <= menulen ; i++)
  1919.   {
  1920.     lcd.setCursor(1,i);
  1921.     lcd.print((__FlashStringHelper *)MenuTable[index[i+menu]]);
  1922.    
  1923.   }
  1924.  
  1925.   //draw select
  1926.   lcd.setCursor(0,menusel);
  1927.   lcd.write(SELECT);
  1928. #ifdef DEBUG
  1929.   lcd.print((char)(menu + '0'));
  1930.   lcd.print(' ');
  1931.   lcd.print((char)(menusel + '0'));
  1932. #endif
  1933.   button = buttonWait(A0,NO,YES);
  1934.  
  1935.   if(button == BTND)
  1936.   {
  1937.     if(index[menu] - currmenu + HMENU-1  < menulen)  //space to potentially go down
  1938.       menu++;//increment menu
  1939.     else if(index[menusel + menu] - currmenu < menulen)
  1940.       menusel++;
  1941.     else
  1942.     {
  1943.       //at bottom of menu, go back to top
  1944.      menu = currmenu;
  1945.      menusel = 0;
  1946.     }
  1947.   }
  1948.   if(button == BTNB)
  1949.     select(currmenu, index[menusel+menu]-currmenu);
  1950. }
  1951.  
  1952. int setup_ser(byte ser, PGM_P PROGMEM string, char init, char initcr, char justppp, unsigned long timeout,uint16_t analogpin)
  1953. {
  1954.   char state=0, temp;
  1955.   //unsigned long time1 = millis();
  1956.   if(ser == BT)
  1957.   {
  1958.   if(init){
  1959.     //delay(1000);
  1960.     lcd.print((__FlashStringHelper *)ppplus);
  1961.     btser.print((__FlashStringHelper *)ppplus);
  1962.     if(initcr)
  1963.       btser.write(0x0D);
  1964.     delay(1000);
  1965.   }
  1966.   else
  1967.     state = 3;
  1968.   while(1)
  1969.   {
  1970.     if(state == 3)
  1971.     {
  1972.       state++;
  1973.       if(justppp)
  1974.         continue;
  1975.       lcd.print((__FlashStringHelper *)string);
  1976.       btser.print((__FlashStringHelper *)string);
  1977.       btser.write(0x0D);
  1978.       delay(100);
  1979.     }
  1980.     if(btser.available())
  1981.     {
  1982.       temp = btser.read();
  1983.       if(temp == 0x0D)
  1984.       {
  1985.         state++;
  1986.         continue;
  1987.       }
  1988.      
  1989.       //lcd.print((char)(state + '0'));
  1990.       if(temp == 'O')
  1991.         state++;
  1992.       if(temp == 'K')
  1993.         state++;
  1994.  
  1995.       lcd.print((char)temp);
  1996.       //if(temp == 'E' || temp == 'R')
  1997.       //  return 0; //error
  1998.     }
  1999.     if(analogRead(analogpin) > 70)
  2000.     {
  2001.       lcd.print((char)temp);
  2002.       lcd.print((__FlashStringHelper *)Exit);
  2003.       while(analogRead(analogpin) > 70){};
  2004.       return 0;
  2005.     }
  2006.   }
  2007.   }
  2008.   else  //XBEE HW serial
  2009.  
  2010.   {
  2011.     if(init){
  2012.     //delay(1000);
  2013.     lcd.print((__FlashStringHelper *)ppplus);
  2014.     Serial.print((__FlashStringHelper *)ppplus);
  2015.     if(initcr)
  2016.       Serial.write(0x0D);
  2017.     delay(1000);
  2018.   }
  2019.   else
  2020.     state = 3;
  2021.   while(state != 6)
  2022.   {
  2023.     if(state == 3)
  2024.     {
  2025.       state++;
  2026.       lcd.print((__FlashStringHelper *)string);
  2027.       Serial.print((__FlashStringHelper *)string);
  2028.       Serial.write(0x0D);
  2029.       delay(100);
  2030.     }
  2031.     if(Serial.available())
  2032.     {
  2033.       temp = Serial.read();
  2034.       if(temp == 0x0D)
  2035.       {
  2036.         state++;
  2037.         continue;
  2038.       }
  2039.       //lcd.print((char)(state + '0'));
  2040.       if(temp == 'O')
  2041.         state++;
  2042.       if(temp == 'K')
  2043.         state++;
  2044.       //if(temp == 'E' || temp == 'R')
  2045.       //  return 0; //error  
  2046.       lcd.print((char)temp);
  2047.     }
  2048.     if(analogRead(analogpin) > 70)
  2049.     {
  2050.       lcd.print((char)temp);
  2051.       lcd.print((__FlashStringHelper *)Exit);
  2052.       while(analogRead(analogpin) > 70){};
  2053.       return 0;
  2054.     }
  2055.   }
  2056.   }
  2057.  return 1;
  2058. }
  2059.  
  2060. uint8_t parse_buttons(uint16_t button)
  2061. {
  2062. //given the channel and button, return corresponding actual button
  2063. //hardware specific
  2064.   switch(button)
  2065.   {
  2066.       case 1:
  2067.           return BTNU;
  2068.       case 2:
  2069.           return BTND;
  2070.       case 3:
  2071.           return BTNL;
  2072.       case 4:
  2073.           return BTNR;
  2074.       case 5:
  2075.           return BTNA;
  2076.       case 6:
  2077.           return BTND;  //correct for using 10k resistor
  2078.       case 16:
  2079.           return BTNB;
  2080.       default:
  2081.           break;
  2082.   };
  2083.   return 255;
  2084. }
  2085.  
  2086. uint8_t buttonCheck( uint16_t analogpin)
  2087. {
  2088.     uint16_t upper, lower;
  2089.     uint8_t button = 0;
  2090.     uint16_t analogval;
  2091.     analogval = analogRead(analogpin);
  2092.     //find what button it corresponds to
  2093.     for( uint16_t i = 0; i < 21; i++)
  2094.     {
  2095.         // checks the _analogval against the high and low vales in the array
  2096.         upper = pgm_read_word(&(Button[i][1]));
  2097.         lower = pgm_read_word(&(Button[i][2]));
  2098.        
  2099.         if(analogval >= upper && analogval <= lower)
  2100.         {
  2101.             // stores the button number to a variable
  2102.             button = pgm_read_word(&(Button[i][0]));
  2103.             return button;    
  2104.         }
  2105.     }
  2106.     return button;
  2107. }
  2108.  
  2109. uint8_t buttonWait(uint16_t analogpin, uint8_t toggle, uint8_t hold)
  2110. {  
  2111.     //if toggle set, wait until button comes back to 0 position
  2112.     uint16_t init_butt=0,state = 0, offset=0;
  2113.     uint32_t time;
  2114.     uint8_t buffer[10];
  2115.     uint8_t value;
  2116.     //consider sleep code here
  2117.  
  2118.     while(1){
  2119.         while(state == 0)
  2120.         {
  2121.           for( uint16_t j=0; j<10; j++)
  2122.           {
  2123.               buffer[j] = buttonCheck(analogpin);
  2124.               delay(1);
  2125.              
  2126.           }
  2127.           value = buffer[0];
  2128.           for( uint16_t j=1; j<10;j++)
  2129.           {
  2130.               if(value != buffer[j])
  2131.               {
  2132.                   //mismatch, discard
  2133.                   value =255;
  2134.                   break;
  2135.               }
  2136.           }
  2137.           if((value != 255) && (value != 0))
  2138.           {
  2139.               state = 2;
  2140.               init_butt = value;
  2141.               time = millis();
  2142.           }
  2143.         }
  2144.         if(toggle == YES)
  2145.         {
  2146.             state = 1;  
  2147.         }
  2148.         while(state == 1)
  2149.         {
  2150.             if(millis() - time > DEBOUNCE)
  2151.             {
  2152.                 return parse_buttons(init_butt);
  2153.             }
  2154.         }
  2155.         while (state == 2)
  2156.         {
  2157.             //wait for button fall
  2158.             for( uint16_t j=0; j<10; j++)
  2159.             {
  2160.                 buffer[j] = buttonCheck(analogpin);
  2161.             }
  2162.             value = buffer[0];
  2163.             for( uint16_t j=1; j<10;j++)
  2164.             {
  2165.                 if(value != buffer[j])
  2166.                 {
  2167.                     //mismatch, discard
  2168.                     value =254;
  2169.                     break;
  2170.                 }
  2171.             }
  2172.             if( hold == YES && millis() - time > PRESSHOLD)
  2173.             {
  2174.               offset = 10;
  2175.             }
  2176.             if( value == 0)
  2177.             {
  2178.                 return parse_buttons(offset+init_butt);
  2179.             }
  2180.         }
  2181.     }
  2182.     return 0;        
  2183. }
  2184.  
  2185.  
  2186. //reserved for future
  2187. #if 0
  2188. int scan_bt_menuize(byte timeout)
  2189. {
  2190.   char state=0, temp, skip, devicenum;
  2191.   char sindex[20];
  2192.   char buffer[10][20];
  2193.   char mac[10][15];
  2194.   unsigned long time1 = millis();
  2195.   lcd.clear();
  2196.  
  2197.   //send ATF?
  2198.   btser.print((__FlashStringHelper *)atf); //ATF?
  2199.   btser.write(0x0D);
  2200.   //create own menu system here, pretty much.  Need to be able to select, and connect to it
  2201.   while(skip < 25) //17
  2202.   {
  2203.     if(btser.available())
  2204.     {
  2205.       temp = btser.read();
  2206.       //lcd.print((char)temp);
  2207.       //delay(250);
  2208.       skip++;
  2209.     }
  2210.     //if(millis() > time1 + timeout)
  2211.     //{
  2212.     //  lcd.print((__FlashStringHelper *)Timeout);
  2213.     //  delay(1000);
  2214.     //  break;
  2215.     //}
  2216.     if(analogRead(A0) > 70)
  2217.       return 0;
  2218.   }
  2219.  
  2220.  
  2221.   //process each result from BT module, displaying it as you go
  2222.   while(1)
  2223.   {
  2224.     temp = 0;
  2225.     int i = 0;  //cnt of number of BT things around
  2226.     skip = 0;
  2227.     while(skip < 3)  //skip LF and first number.  Land in space region before name
  2228.     {
  2229.       if(btser.available())
  2230.       {
  2231.         temp = btser.read();
  2232.         //lcd.print((char)temp);
  2233.         skip++;
  2234.       }
  2235.       if(analogRead(A0) > 70)
  2236.         return 0;
  2237.     }
  2238.     //now read spaces until nonspace
  2239.     while(temp == ' ')
  2240.     {
  2241.       if(btser.available())
  2242.       {
  2243.         temp = btser.read();
  2244.         //lcd.print((char)temp);
  2245.       }
  2246.       if(analogRead(A0) > 70)
  2247.         return 0;
  2248.     }
  2249.     //lcd.clear();
  2250.     //lcd.print("proc Name");lcd.print((int)devicenum);
  2251.     //lcd.setCursor(0,1);
  2252.     //Now process this name
  2253.     buffer[devicenum][i++] = temp;
  2254.     //lcd.print((char)temp);
  2255.     while(temp != ' ')
  2256.     {
  2257.       if(btser.available())
  2258.       {
  2259.         temp = btser.read();
  2260.         //lcd.print((char)temp);
  2261.         //delay(250);
  2262.         if(temp != ' ')
  2263.           buffer[devicenum][i++]=temp; //save name
  2264.       }
  2265.       //if(analogRead(A0) > 70)
  2266.       //  return 0;
  2267.       if(analogRead(A0) > 70)
  2268.       {
  2269.         lcd.print((int)i);
  2270.         while(analogRead(A0) > 70){};
  2271.         //return 0;
  2272.       }
  2273.     }
  2274.     buffer[devicenum][i] = 0; //null terminated
  2275.     //delay(2000);
  2276.    
  2277.     //lcd.clear();
  2278.     //lcd.print("remove space");
  2279.     //lcd.setCursor(0,1);
  2280.     //now read spaces until nonspace
  2281.     while(temp == ' ')
  2282.     {
  2283.       if(btser.available())
  2284.       {
  2285.         temp = btser.read();
  2286.         //lcd.print((char)temp);
  2287.       }
  2288.       if(analogRead(A0) > 70)
  2289.         return 0;
  2290.     }
  2291.     i=0;
  2292.     //delay(2000);
  2293.     //lcd.clear();
  2294.     //lcd.print("proc Mac");
  2295.     //lcd.setCursor(0,1);
  2296.     //now BT mac, need to save this too!
  2297.     mac[devicenum][i++]=temp;  //temp is first nonzero from above
  2298.     while(i < 14)  //expect XXXX-XX-XXXXXX
  2299.     {
  2300.       if(btser.available())
  2301.       {
  2302.         temp = btser.read();
  2303.         //lcd.print((char)temp);
  2304.         //delay(250);
  2305.         if(temp != 0x0A)  //should never be 0x0A, if it is, we missed a character
  2306.           mac[devicenum][i++]=temp; //save name
  2307.       }
  2308.       if(analogRead(A0) > 70)
  2309.       {
  2310.         lcd.print((__FlashStringHelper *)Exit);
  2311.         while(analogRead(A0) > 70){};
  2312.         return 0;
  2313.       }
  2314.     }
  2315.     mac[devicenum][i] = 0;
  2316.    
  2317.    
  2318.     //lcd.clear();
  2319.     //now we have device name, and mac, both null terminated.  Display device name
  2320.     lcd.setCursor(1,devicenum); //leave space for cursor
  2321.     lcd.print(buffer[devicenum++]);  //hopefully it is less than 19 chars long
  2322.     delay(1000);
  2323.     time1=millis();
  2324.     while(millis() < time1 + 4000)
  2325.     {
  2326.       if(btser.available())
  2327.       {
  2328.         temp = btser.read();
  2329.         //lcd.print((char)temp);
  2330.         //delay(250);
  2331.         break;
  2332.       }
  2333.     }
  2334.     if(millis() < time1 + 4000)
  2335.       return 0;
  2336.   }
  2337.  
  2338. }
  2339. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement