Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Controller 2.0
- Created by Dustin Reynolds at Mecharobotics.wordpress.com
- You may share this library with Creative Commons - Share Alike
- license 2.0.
- This is released via the Creative Commons Share Alike 2.0 license:
- http://creativecommons.org/licenses/by-sa/2.0/
- You can copy it and use it in whatever, just attribute my name,
- Dustin Reynolds, and my blog when you do.
- I'll appreciate if you let me know that you've used it,
- so I can show off your project on my blog :)
- Copyright 2012 Dustin Reynolds
- *****************************************************************************
- Includes the following:
- 20x4 LCD
- XBee Connected to pins 0 and 1 of ATMEGA328
- BTM-182 connected to pins 7 and 8
- PS2 connector
- Nunchuck connector
- microSD adapter (using old microSD to SD converter)
- Size comparisons:
- with SD enabled
- Everything Enabled: 29024 Bytes
- Only LCD debug: 27252 Bytes
- Only NUN LCD debug, PS2 disabled: 22550
- Only PS2 LCD debug, NUN disabled: 25900
- Only PS2 & Nun, no debug: 24690
- Only PS2, no debug: 24484
- No ps2 or Nun: 20972
- With SD disabled
- Nun and PS2 disabled:13488
- BT disabled + SD + NUN PS2
- Xbee: 11910
- Everything Disabled:
- 11886 bytes
- Recommended Flags enabled:
- SD_enable, NUN_Enable, NUN_DBG_LCD
- -ps2 library takes about 5k of space, nun takes 3.6k
- -Nun can do plenty, can improvise with buttons + joystick
- Circuit: Description of the circuit Textually:
- 3.3v VReg (MCP1702-3302E)
- 1-GND
- 2- + of battery, 0.1u to gnd*
- 3-3.3v, 0.1u*
- *-1uF across 3.3V and gnd, 0.1 accross 3.3v and gnd
- ATMEGA328
- 1-connected to Pin 6 of FTDI cable
- 2-Connected to pin 4 of FTDI Cable, To pin 2 of xbee (through a 1k resistor)
- 3-Connected to pin 5 of FTDI cable, to pin 3 of xbee (through a 1k resistor)
- http://www.billporter.info/how-to-add-multiple-uart-connections/
- 4-Pin 9 of XBee
- 5-Pin 11 of shift register
- 6-Pin 14 of shift register
- 7-3.3V
- 8-gnd
- 9-left lead of 16MHz resonator (center to gnd)
- 10-right lead of 16MHz resonator(center to gnd)
- 11-connected to 100 ohm resistor, which is connected to + term of piezo, other conn to gnd.
- 13-Pin 9 of BTM-182 BT serial module
- 14-Pin 10 of BTM-182 BT serial module
- 15-Pin 6 of PS2 controller
- 16-Pin 1 of SD adapter
- 17-pin 2 of PS2 controller, Pin 2 of SD card
- 18-Pin 1 of PS2 controller, Pin 7 of SD card
- 19-Pin 7 of PS2 controller, pin 5 of SD card
- 20-3.3V
- 21-3.3V
- 22-GND
- 23-1k to gnd, one end of button, other is connected to 10Kohm, connected to 3.3v
- 24-
- 25-
- 26-
- 27-2.2k to 3.3v, pin 1 of nunchuck(datapin)
- 28-2.2k to 3.3v, pin 2 of nunchuck(clk)
- SD card (Notch to Left, not counting end connections)
- 1-pin 16 of cpu //SD chip select pin
- 2-pin 17 of cpu
- 3-gnd
- 4-3.3v
- 5-pin 19 of cpu
- 6-gnd
- 7-pin 18 of cpu
- XBee Series 1 Module
- X-CTU:http://www.digi.com/support/productdetail?pid=3352&osvid=0&type=utilities
- Wireless dl:http://www.sparkfun.com/tutorials/122
- 1-3.3v
- 2-1k connected to pin 2 of mcu
- 3-1k connected to pin 3 of mcu
- 9-connected to pin 4 of mcu
- 10-gnd
- BTM-182 BT serial module
- http://www.sparkfun.com/products/9913
- AT commands:http://www.robot-r-us.com/downloads/sparkfun/wigwrl/812-wrl09977-lm400-data-sheet-dss-ver-1-2/download.html
- 9-pin 13 of mcu
- 10-pin 14 of mcu
- 15-3.3v
- 16-gnd
- Shift Register 74LS164N
- http://code.google.com/p/arduinoshiftreglcd/ (using 2 wire connection
- 1-pin 2 of shift reg, pin 6 of atmega328
- 2-pin 1 of shift reg, 1k to pin 6 of LCD
- 3-NC
- 4-NC
- 5-pin 4 of LCD
- 6-pin 11 of LCD
- 7-GND
- 8-pin 5 of atmega328
- 9-3.3v
- 10-pin 12 of lcd
- 11-pin 13 of lcd
- 12-pin 14 of lcd
- 13-diode from pin 6 of lcd, with line towards shift reg
- 14-3.3v
- LCD 3.3V NewHaven 20x4 character LCD
- 1-gnd
- 2-3.3V
- 3-middle pin of 10k pot, other pins at 3.3v and gnd
- 4-pin 5 of shift reg
- 5-gnd
- 6-1k from pin 2 of shift, diode to pin 13 of shift reg, line towards shift
- 7,8,9,10-nc
- 11-pin 6 of shift
- 12-pin 10 of shift
- 13-pin 11 of shift
- 14-pin 12 of shift
- 15-nc(can be conn to 3.3v for backlight)
- 16-gnd
- PS2 (round end down)
- http://www.billporter.info/playstation-2-controller-arduino-library-v1-0/
- 1-pin 18 of mcu
- 2-pin 17 of mcu
- 3-nc(for motors)
- 4-gnd
- 5-3.3v
- 6-pin 15 of mcu
- 7-pin 19 of mcu
- Nunchuck - dealextreme knockoff < $7
- (nunchuck conn facing you, looks like a U not a n)
- http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1273496638
- 1(upper left)-pin 27 of mcu, 2.2k pullup to 3.3v (clock)
- 2(upper right)-gnd
- 3(lower left)-3.3v
- 4(lower right)-pin 28 of mcu, 2.2k pullup to 3.3v (data)
- Xbee is run using HW serial, BT using sw serial
- PS2 run on SPI bus, SD on SPI bus
- Nun run on I2C bus
- LCD only uses 2 pins using shift reg
- entire system at 3.3v
- Notes:
- How do I create a menu?
- 1. Add your menu in section 1. Edit the main menu to have your desired name in it.
- Be sure to do yournameSUB and yournameLEN correctly, follow the examples. Bakmain is
- still counted, since this references the table in sec 4.
- 2. Add a yournameCONF to the list of confs, create a unique #define for each menu item.
- 3. Add a #define for your menu, set it to be the same as yournameSUB. These are used in a
- big switch statement in the select function
- 4. Add your prog_char's defined in step 1, to this table, in the correct space.
- 5. Goto select function, create a if statement in case: MAIN. Create a case for your menu
- name defined in step 3.
- Dustin Reynolds
- 2012-03-24
- */
- #include <Wire.h>
- #include <Nunchuck.h>
- #include <PS2X_lib.h> //for v1.6
- #include <SoftwareSerial.h>
- #include <ShiftRegLCD.h>
- #include <SD.h>
- #include <avr/pgmspace.h>
- #include <EEPROM.h>
- //Comment out these to disable specific features. Won't disable menus, since that is complicated
- //#define PS2_ENABLE
- //#define PS2_DBG_SER
- //#define PS2_DBG_LCD
- #define NUN_ENABLE
- //#define NUN_DBG_SER
- #define NUN_DBG_LCD //adds 1184 bytes
- //#define MUSIC_ENABLE //takes 2566 bytes for 1 song
- #define TONE_PIN 5
- #define OCTAVE_OFFSET 0
- // if cpu is 16 MHz, leave defined, if 8 MHz, comment out.
- #define CPU16MHZ 1
- #define XBEE_ENABLE
- #define BT_ENABLE
- #define SD_ENABLE
- #define FILENAME_OFFSET 20 //single byte stored in EEPROM
- #define HMENU 4
- #define WMENU 20
- #define THIS_ID 100 //d <-ascii for 100
- #define RC_CAR_ID 101 //e
- #define ADC_MONITOR_ID 102 //f
- const prog_char PROGMEM adc_monitor_id[] = "ATD=0123456789ab";
- //types
- #define TYPE_UTHERE 0
- #define TYPE_DISPTHIS 1
- #define TYPE_NUN_CONTROL 2
- #define TYPE_PS2_CONTROL 3
- #define TYPE_END_COMM 253
- #define TYPE_ACK 254
- #define TYPE_ERROR 255
- #define MAX_PKT_SIZE 30
- //options
- #define OPTION_SEND_CTL 0x01
- #define OPTION_NUN_CTL 0x02
- #define OPTION_PS2_CTL 0x04
- #define TIMEOUT 10
- #define SUCCESS 1
- #define FAILURE 0
- File logFile;
- #define SDCHIPSEL 10
- PS2X ps2x; // create PS2 Controller Class
- //#define DEBUG 1
- ShiftRegLCD lcd(4, 3, TWO_WIRE, 4); //we have a 20x4 LCD data clock enable #lines
- #ifdef BT_ENABLE
- SoftwareSerial btser(7, 8);
- #endif
- //want simple XBEE config
- #define XBEESLEEP 2//6 //Pin 12 for XBee sleep control, goes to pin 9 on xbee
- //Music
- #ifdef MUSIC_ENABLE
- #define NOTE_C4 262
- #define NOTE_CS4 277
- #define NOTE_D4 294
- #define NOTE_DS4 311
- #define NOTE_E4 330
- #define NOTE_F4 349
- #define NOTE_FS4 370
- #define NOTE_G4 392
- #define NOTE_GS4 415
- #define NOTE_A4 440
- #define NOTE_AS4 466
- #define NOTE_B4 494
- #define NOTE_C5 523
- #define NOTE_CS5 554
- #define NOTE_D5 587
- #define NOTE_DS5 622
- #define NOTE_E5 659
- #define NOTE_F5 698
- #define NOTE_FS5 740
- #define NOTE_G5 784
- #define NOTE_GS5 831
- #define NOTE_A5 880
- #define NOTE_AS5 932
- #define NOTE_B5 988
- #define NOTE_C6 1047
- #define NOTE_CS6 1109
- #define NOTE_D6 1175
- #define NOTE_DS6 1245
- #define NOTE_E6 1319
- #define NOTE_F6 1397
- #define NOTE_FS6 1480
- #define NOTE_G6 1568
- #define NOTE_GS6 1661
- #define NOTE_A6 1760
- #define NOTE_AS6 1865
- #define NOTE_B6 1976
- #define NOTE_C7 2093
- #define NOTE_CS7 2217
- #define NOTE_D7 2349
- #define NOTE_DS7 2489
- #define NOTE_E7 2637
- #define NOTE_F7 2794
- #define NOTE_FS7 2960
- #define NOTE_G7 3136
- #define NOTE_GS7 3322
- #define NOTE_A7 3520
- #define NOTE_AS7 3729
- #define NOTE_B7 3951
- //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";
- //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";
- //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.";
- 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";
- //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";
- int notes[] = { 0,
- NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
- NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
- NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
- NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
- };
- #endif
- #define BTNU (( uint8_t)13)
- #define BTND (( uint8_t)14)
- #define BTNL (( uint8_t)15)
- #define BTNR (( uint8_t)16)
- #define BTNA (( uint8_t)17)
- #define BTNB (( uint8_t)18)
- #define YES (( uint8_t)1)
- #define NO (( uint8_t)0)
- #define DEBOUNCE 200 //ms/sample
- #define PRESSHOLD 1000
- #define UPARROW ((uint8_t)3)
- #define DOWNARROW ((uint8_t)4)
- #define SELECT ((uint8_t)5)
- #define HEART ((uint8_t)0)
- #define SMILE ((uint8_t)2)
- #define KEY ((uint8_t)1)
- /***********************************SECTION 2 *****************************************/
- #define XBEECONF 0
- #define BTCONF 1
- #define NUNCONF 2
- #define PS2CONF 3
- #define SDCONF 4
- #define RC_CONF 5
- #define CONNADCSERVO 6
- #define CONNSAB 7
- #define BACKMAIN 0
- #define XBEEPPP 1
- #define XBEESM1 2
- #define XBEECLOSE 3
- #define BTPPP 1
- #define BTATR0 2
- #define BTATH 3
- #define BTATF 4
- #define BTATD 5
- #define BTATA 6
- #define BTCLOSE 7
- #define NUNPRES 1
- #define NUNINIT 2
- #define NUNCAL 3
- #define NUNDLCD 4
- #define NUNDSER 5
- #define PS2PRES 1
- #define PS2INIT 2
- #define PS2DLCD 3
- #define PS2DSER 4
- #define SDPRES 1
- #define SDCNGI 2
- #define SDPREV 3
- /*****************************END OF SECTION 2 *****************************************/
- /***********************************SECTION 1 *****************************************/
- #define MAINSUB 0
- #define MAINLEN 7 //actual - 1
- const prog_char PROGMEM MenuStr1[] = "XBee Configure";
- const prog_char PROGMEM MenuStr2[] = "BT Configure";
- const prog_char PROGMEM MenuStr3[] = "NunChuck Configure";
- const prog_char PROGMEM MenuStr4[] = "PS2 Configure";
- const prog_char PROGMEM MenuStr5[] = "SD Configure";
- const prog_char PROGMEM MenuStr6[] = "Connect to RC Car";
- const prog_char PROGMEM MenuStr7[] = "Conn 2 ADC Servo";
- const prog_char PROGMEM MenuStr8[] = "Connect to Sable";
- #define XBEESUB 8 //actual - 1
- #define XBEELEN 3 //actual - 1
- const prog_char PROGMEM Bakmain[] = "Back to Main";
- const prog_char PROGMEM Xbee2[] = "+++";
- const prog_char PROGMEM Xbee3[] = "SM1,ST3e8,SO1";
- const prog_char PROGMEM Xbee4[] = "WN,CN";
- #define BTSUB 12
- #define BTLEN 7 //actual - 1
- //const prog_char PROGMEM Bakmain[] = "Back to Main";
- const prog_char PROGMEM BTser2[] = "+++ <-not alneeded";
- const prog_char PROGMEM BTser3[] = "ATR0";
- const prog_char PROGMEM BTser4[] = "ATH (drops conn)";
- const prog_char PROGMEM BTser5[] = "ATF?";
- const prog_char PROGMEM BTser6[] = "ATD";
- const prog_char PROGMEM BTser7[] = "ATA";
- const prog_char PROGMEM BTser8[] = "ATO closes conn";
- #define NUNSUB 20
- #define NUNLEN 5 //actual - 1
- //const prog_char PROGMEM Bakmain[] = "Back to Main"; <-count it, but only use one
- const prog_char PROGMEM NUN2[] = "Nunchuk Present?";
- const prog_char PROGMEM NUN3[] = "Init";
- const prog_char PROGMEM NUN4[] = "SetCal";
- const prog_char PROGMEM NUN5[] = "Disp LCD";
- const prog_char PROGMEM NUN6[] = "Disp Serial";
- #define PS2SUB 26
- #define PS2LEN 4 //actual - 1
- //const prog_char PROGMEM Bakmain[] = "Back to Main"; <-count it, but only use one
- const prog_char PROGMEM PS22[] = "PS2 Ctl Present?";
- //const prog_char PROGMEM NUN3[] = "Init";
- const prog_char PROGMEM PS24[] = "Disp LCD";
- const prog_char PROGMEM PS25[] = "Disp Serial";
- #define SDSUB 31
- #define SDLEN 3 //actual - 1
- //const prog_char PROGMEM Bakmain[] = "Back to Main"; <-count it, but only use one
- const prog_char PROGMEM uSD2[] = "SD Present?";
- const prog_char PROGMEM uSD3[] = "Change File Index";
- const prog_char PROGMEM uSD4[] = "Preview Top File";
- /*****************************END OF SECTION 1 *****************************************/
- /***********************************SECTION 3 *****************************************/
- //currentmenu
- #define MAIN MAINSUB
- #define XBEE XBEESUB
- #define BT BTSUB
- #define NUN NUNSUB
- #define PS2 PS2SUB
- #define uSD SDSUB
- /*****************************END OF SECTION 3 *****************************************/
- /***********************************SECTION 4 *****************************************/
- PGM_P PROGMEM MenuTable[] = {
- MenuStr1,
- MenuStr2,
- MenuStr3,
- MenuStr4,
- MenuStr5,
- MenuStr6,
- MenuStr7,
- MenuStr8,
- Bakmain,
- Xbee2,
- Xbee3,
- Xbee4,
- Bakmain,
- BTser2,
- BTser3,
- BTser4,
- BTser5,
- BTser6,
- BTser7,
- BTser8,
- Bakmain,
- NUN2,
- NUN3,
- NUN4,
- NUN5,
- NUN6,
- Bakmain,
- PS22,
- NUN3,
- PS24,
- PS25,
- Bakmain,
- uSD2,
- uSD3,
- uSD4,
- };
- /*****************************END OF SECTION 4 *****************************************/
- const prog_char PROGMEM ppplus[] = "+++";
- const prog_char PROGMEM sm1[] = "ATSM1,ST3E8,SO1";
- const prog_char PROGMEM wncn[] = "ATWN,CN";
- const prog_char PROGMEM atr0[] = "ATR0";
- const prog_char PROGMEM ath[] = "ATH";
- const prog_char PROGMEM atf[] = "ATF?";
- const prog_char PROGMEM atd[] = "ATD?";
- const prog_char PROGMEM ata[] = "ATA";
- const prog_char PROGMEM ato[] = "ATO";
- const prog_char PROGMEM Timeout[] = "TimeOut";
- const prog_char PROGMEM Exit[] = "Exit";
- //******************************************************************************
- //
- // Button Definitions
- //
- //******************************************************************************
- //2-dimensional array for asigning the buttons and there high and low values
- const uint16_t PROGMEM Button[21][3] = {{1, 834, 845}, // button 1
- {2, 712, 721}, // button 2
- {3, 603, 613}, // button 3
- {4, 315, 326}, // button 4
- {5, 173, 185}, // button 5
- {6, 85, 97}, // button 6
- {7, 888, 898}, // button 1 + button 2
- {8, 872, 882}, // button 1 + button 3
- {9, 849, 858}, // button 1 + button 4
- {10, 844, 848}, // button 1 + button 5
- {11, 838, 843}, // button 1 + button 6
- {12, 805, 815}, // button 2 + button 3
- {13, 748, 758}, // button 2 + button 4
- {14, 729, 740}, // button 2 + button 5
- {15, 719, 728}, // button 2 + button 6
- {16, 668, 678}, // button 3 + button 4
- {17, 636, 646}, // button 3 + button 5
- {18, 619, 629}, // button 3 + button 6
- {19, 405, 415}, // button 4 + button 5
- {20, 359, 369}, // button 4 + button 6
- {21, 237, 247}}; // button 5 + button 6
- byte Select[8]={ B01000, B01100, B00110, B11111, B11111, B00110, B01100, B01000};
- char menu = 0; //0 = main
- char menulen = MAINLEN;
- char menusel = 0; //cursor
- char index[40];
- char currmenu = MAIN; //current menu
- byte fileNum = 0;
- char file[20];
- int setup_ser(byte ser, char * string, char init, char initcr,char justppp, unsigned long timeout, uint16_t analogpin);
- uint8_t buttonWait(uint16_t analogpin, uint8_t toggle, uint8_t hold);
- uint8_t buttonCheck( uint16_t analogpin);
- int send_pkt(byte iface, byte dest, byte type, int count, char * buffer)
- {
- int checksum;
- //send header info:XYZA
- if(iface == XBEE)
- {
- //X
- Serial.write(0x0a); //LF
- Serial.write(dest);
- //Y
- Serial.write(THIS_ID);//100 is controller
- //Z Type
- Serial.write(type);
- //A count
- Serial.write(count);
- }
- else //BT, assumption is that we are already connected to the thing
- {
- //X
- btser.write(0x0a); //LF
- btser.write(dest);
- //Y
- btser.write(THIS_ID);//100 is controller
- //Z Type
- btser.write(type);
- //A count
- btser.write(count);
- }
- //intialize checksum
- checksum = dest+THIS_ID+type+count;
- //get checksum for data
- for(int j=0; j<count; j++)
- checksum +=buffer[j];
- //send data
- if(iface == XBEE)
- for(int j=0; j<count; j++)
- Serial.write(buffer[j]);
- else
- for(int j=0; j<count; j++)
- btser.write(buffer[j]);
- while (checksum > 256)
- checksum -= 256;
- if(iface == XBEE)
- {
- Serial.write(checksum);
- Serial.write(0x0d); //LF
- }
- else
- {
- btser.write(checksum);
- btser.write(0x0d); //LF
- }
- return 1;
- }
- byte get_pkt(byte iface, char* buffer, byte size, uint16_t timeout)
- {
- byte temp;
- byte gotchar = 0;
- byte type;
- byte count = 0;
- byte checksum = 0;
- byte theirchecksum = 0;
- byte theirid;
- byte buffoffset = 0;
- byte state = 0; //0 - wait for LF
- //1 - next is THIS_ID
- //2 - their ID
- //3 - type
- //4 - count
- //5-count - packet
- //last checksum
- unsigned long time1 = millis();
- while(1){
- if(millis() > time1 + timeout)
- {
- //timeout, abort
- memset(buffer, 0, size);
- //lcd.print("Ti");
- return TIMEOUT;
- }
- //button escape
- if(analogRead(A0) > 70)
- {
- lcd.print((__FlashStringHelper *)Exit);
- while(analogRead(A0) > 70){};
- if(iface == XBEE)
- digitalWrite(XBEESLEEP, HIGH);
- return FAILURE;
- }
- if(iface == XBEE)
- {
- gotchar = 0; //only iterate on times in which we received something
- //don't want to be stuck in 1 big if statement though
- if(Serial.available())
- {
- temp = Serial.read();
- //lcd.print(temp);
- gotchar = 1;
- }
- if(gotchar == 0)
- continue;
- }
- else
- {
- gotchar = 0; //only iterate on times in which we received something
- //don't want to be stuck in 1 big if statement though
- if(btser.available())
- {
- temp = btser.read();
- //lcd.print(temp);
- gotchar = 1;
- }
- if(gotchar == 0)
- continue;
- //nothing here, so break
- }
- //state machine
- if(state == 0)
- {
- if(temp == 0x0A) //only start processing iff LF received
- {
- state++;
- }
- }
- else if(state == 1)
- {
- if(temp == THIS_ID)
- {
- state++;
- checksum += THIS_ID;
- }
- else
- {
- //lcd.print("Wrong ID");
- //delay(2000);
- state = 0;
- count = 0;
- checksum = 0;
- buffoffset = 0;
- }
- }
- else if(state == 2)
- {
- theirid = temp;
- checksum += temp;
- state++;
- *(buffer + buffoffset++) = theirid;
- }
- else if(state == 3)
- {
- type = temp; //save type, not sure what to do with it now
- checksum += type;
- state++;
- *(buffer + buffoffset++) = type;
- }
- else if(state == 4)
- {
- count = temp; //save count
- checksum += count;
- if(count == 0) //empty packet?
- state++; //skip packet step, go straight to checksum
- state++;
- *(buffer + buffoffset++) = count;
- }
- else if(state == 5)
- {
- //stay in this state until count bytes arrive, or until timeout
- //count guaranteed to be > 0 initially
- *(buffer + buffoffset++) = temp; //save in buffer
- checksum += temp;
- if(--count == 0)
- {
- state++;
- }
- }
- else if(state == 6)
- {
- //checksum
- theirchecksum = temp;
- if(theirchecksum == checksum)
- {
- //Buffer valid, return to calling program
- return SUCCESS; //data stored in provided buffer
- }
- else
- {
- //checksum not valid, return to state 0
- state = 0;
- memset(buffer, 0, size);
- lcd.print((int)checksum);
- lcd.print("checksum wrong");
- }
- }
- }
- }
- /* Handle packet - Does everything conceivable for a received packet
- -displays data
- -sends control packet every time_sendctl milli seconds
- -times out after timeout, if no communication
- -exits if button held
- */
- byte handle_pkt(byte iface, byte dest, byte options, uint16_t sendctl, uint16_t timeout)
- {
- unsigned long time_timeout = millis() + timeout;
- unsigned long time_sendctl = millis() + sendctl;
- char buffer[MAX_PKT_SIZE];
- char outbuffer[MAX_PKT_SIZE];
- byte thisdest;
- byte type;
- byte nthings;
- byte col;
- byte row;
- char disp_str[WMENU+1];
- byte error;
- int tempx,tempy,tempz;
- int i = 0;
- if(iface == XBEE)
- digitalWrite(XBEESLEEP, LOW);
- #ifdef NUN_ENABLE
- if(options & OPTION_NUN_CTL)
- {
- nunchuk_init();
- }
- #endif
- #ifdef PS2_ENABLE
- if (options & OPTION_PS2_CTL)
- {
- error = ps2x.config_gamepad(13,11,9,12, true, false);
- }
- #endif
- while(1)
- {
- //update device, if we are using it
- #ifdef NUN_ENABLE
- if(options & OPTION_NUN_CTL)
- {
- nunchuk_send_request();
- nunchuk_get_data();
- }
- #endif
- #ifdef PS2_ENABLE
- if (options & OPTION_PS2_CTL)
- {
- ps2x.read_gamepad(false, 0);
- }
- #endif
- if(millis() > time_timeout)
- {
- lcd.print((__FlashStringHelper *)Timeout);
- break;
- }
- if(millis() > time_sendctl)
- {
- if(options & OPTION_SEND_CTL)
- {
- memset(buffer,0,MAX_PKT_SIZE);
- i = 0;
- //get packet ready to send
- #ifdef NUN_ENABLE
- if(options & OPTION_NUN_CTL)
- {
- //send bare values, calib occurs on remote dest
- buffer[i++] = nunchuk_zbutton();
- buffer[i++] = nunchuk_cbutton();
- buffer[i++] = nunchuk_joy_x();
- buffer[i++] = nunchuk_joy_y();
- lcd.setCursor(1,1);
- lcd.print((int)nunchuk_joy_x());
- tempx = nunchuk_accelx();
- tempy = nunchuk_accely();
- tempz = nunchuk_accelz();
- buffer[i++] = (char)(tempx >> 8);
- buffer[i++] = (char)(tempx % 256);
- buffer[i++] = (char)(tempy >> 8);
- buffer[i++] = (char)(tempy % 256);
- buffer[i++] = (char)(tempz >> 8);
- buffer[i++] = (char)(tempz % 256);
- send_pkt(iface,dest,TYPE_NUN_CONTROL,i,buffer);
- }
- #endif
- #ifdef PS2_ENABLE
- if (options & OPTION_PS2_CTL)
- {
- //send bare values, calib occurs on remote dest
- buffer[i++] = ps2x.Analog(PSS_RX);
- buffer[i++] = ps2x.Analog(PSS_RY);
- buffer[i++] = ps2x.Analog(PSS_LX);
- buffer[i++] = ps2x.Analog(PSS_LY);
- buffer[i++] = ps2x.Button(PSB_L3);
- buffer[i++] = ps2x.Button(PSB_R3);
- buffer[i++] = ps2x.Analog(PSAB_PAD_UP);
- buffer[i++] = ps2x.Analog(PSAB_PAD_DOWN);
- buffer[i++] = ps2x.Analog(PSAB_PAD_LEFT);
- buffer[i++] = ps2x.Analog(PSAB_PAD_RIGHT);
- buffer[i++] = ps2x.Analog(PSAB_CROSS);
- buffer[i++] = ps2x.Analog(PSAB_TRIANGLE);
- buffer[i++] = ps2x.Analog(PSAB_SQUARE);
- buffer[i++] = ps2x.Analog(PSAB_CIRCLE);
- buffer[i++] = ps2x.Analog(PSAB_L1);
- buffer[i++] = ps2x.Analog(PSAB_R1);
- buffer[i++] = ps2x.Analog(PSAB_L2);
- buffer[i++] = ps2x.Analog(PSAB_R2);
- buffer[i++] = ps2x.Button(PSB_START);
- buffer[i++] = ps2x.Button(PSB_SELECT);
- send_pkt(iface,dest,TYPE_PS2_CONTROL,i,buffer);
- }
- #endif
- }
- time_sendctl = millis() + sendctl;
- }
- //exit condition?
- if(analogRead(A0) > 70)
- {
- lcd.print((__FlashStringHelper *)Exit);
- while(analogRead(A0) > 70){};
- if(iface == XBEE)
- digitalWrite(XBEESLEEP, HIGH);
- return 1;
- }
- //handle received packets (shorter delay if sending ctl since need quick feedback (can't wait around forever)
- if(options & OPTION_SEND_CTL)
- error = get_pkt(iface, buffer, MAX_PKT_SIZE, 100); //once 100 ms elapses, it abort packet reception
- else
- error = get_pkt(iface, buffer, MAX_PKT_SIZE, 1000); //longer delay since not actively controlling something
- //process packet
- // if(error == TIMEOUT)
- // send_pkt(iface,dest,TYPE_ERROR,0,buffer);
- if (error == FAILURE)
- return FAILURE;
- else if(error == SUCCESS)
- {
- i = 0;
- //their id
- thisdest = buffer[i++];
- if(thisdest!= dest)
- {
- //should we process this? leave it for now
- }
- else
- {
- //reset time, since we recently received something.
- time_timeout = millis() + timeout;
- }
- //lcd.clear();
- //lcd.print((int)thisdest);lcd.print("-");
- //read type
- type = buffer[i++];
- memset(outbuffer,0,sizeof(outbuffer));
- //lcd.print((int)type);lcd.print("-");
- switch(type)
- {
- case TYPE_UTHERE:
- {
- nthings = buffer[i++];
- outbuffer[0] = 'Y';
- if(buffer[i] == 'P')
- send_pkt(iface,thisdest,TYPE_UTHERE,1,outbuffer);
- //else, do nothing, no response needed
- break;
- }
- case TYPE_DISPTHIS:
- {
- //disp can be on controller, or remote thing!
- nthings = buffer[i++]; //size
- //lcd.print((int)nthings);lcd.print("-");
- if(nthings == 0) //clear screen if type dispthis, and size is 0
- {
- lcd.clear();
- break;
- }
- col = buffer[i++];
- row = buffer[i++];
- strncpy(disp_str, buffer+i, WMENU); //max of 1 row at a time, received string
- //should be null terminated.
- disp_str[nthings-2] = 0; //ensure it is null terminated at desired spot to prevent overflow
- //lcd.print(col);lcd.print("-");
- //lcd.print(row);
- lcd.setCursor(col,row);
- lcd.print(disp_str);
- //send Ack?
- //send_pkt(iface,thisdest,TYPE_ACK,0,outbuffer);
- break;
- }
- case TYPE_NUN_CONTROL:
- {
- //for controller, what does this mean?
- #ifdef NUN_ENABLE
- #endif
- break;
- }
- case TYPE_PS2_CONTROL:
- {
- //for controller, what does this mean?
- #ifdef PS2_ENABLE
- #endif
- break;
- }
- case TYPE_ACK:
- {
- //last packet received OK
- break;
- }
- case TYPE_ERROR:
- {
- //last packet not received, resend depending on mode perhaps?
- break;
- }
- case TYPE_END_COMM:
- {
- //remote requests end of comm
- send_pkt(iface,thisdest,TYPE_END_COMM,0,outbuffer);//send packet acking this
- break;
- }
- default:
- {
- //future type?
- lcd.print((int)type);
- break;
- }
- }
- }
- }
- return 0;
- }
- #ifdef MUSIC_ENABLE
- //globals
- char * _currsong;
- uint8_t _default_dur;
- uint8_t _default_oct;
- uint32_t _wholenote;
- uint32_t _duration;
- uint16_t _bpm;
- char * _songptr;
- uint8_t _repeat;
- char buffer[500]; //space to store song
- long _waittime;
- void musicInit(const char * song)
- {
- int num;
- //fill buffer This works perfectly!
- _songptr = strcpy_P(buffer,song);
- //lcd->print((char) _songptr[1]); //worked!
- //delay(2000);
- //c = *_songptr; worked!
- //lcd->print((char) c);
- // lcd->print(_songptr);
- //delay(2000);
- //process beginning of music file
- // format: d=N,o=N,b=NNN:
- // find the start (skip name, etc)
- while(*_songptr != ':') _songptr++; // ignore name
- _songptr++; // skip ':'
- // get default duration
- if(*_songptr == 'd')
- {
- _songptr++; _songptr++; // skip "d="
- num = 0;
- while(isdigit(*_songptr))
- {
- num = (num * 10) + (*_songptr++ - '0');
- }
- if(num > 0) _default_dur = num;
- _songptr++; // skip comma
- }
- // get default octave
- if(*_songptr == 'o')
- {
- _songptr++; _songptr++; // skip "o="
- num = *_songptr++ - '0';
- if(num >= 3 && num <=7) _default_oct = num;
- _songptr++; // skip comma
- }
- // get BPM
- if(*_songptr == 'b')
- {
- _songptr++; _songptr++; // skip "b="
- num = 0;
- while(isdigit(*_songptr))
- {
- num = (num * 10) + (*_songptr++ - '0');
- }
- _bpm = num;
- _songptr++; // skip colon
- }
- // BPM usually expresses the number of quarter notes per minute
- _wholenote = (60 * 1000L / _bpm) * 4; // this is the time for whole note (in milliseconds)
- //save location of beginning
- _currsong = _songptr; //points to beginning of song hopefully
- //primed to start playing
- while(1)
- {
- uint16_t num = 0;
- byte note;
- byte scale;
- if(*_songptr == ' ')
- {
- *_songptr++;
- }
- if(*_songptr == 0)
- {
- //null terminated string, repeat?
- if(_repeat)
- {
- _songptr = _currsong;
- }
- else
- {
- return;
- }
- }
- // first, get note duration, if available
- num = 0;
- while(isdigit(*_songptr))
- {
- num = (num * 10) + (*_songptr++ - '0');
- }
- if(num) _duration = _wholenote / num;
- else _duration = _wholenote / _default_dur; // we will need to check if we are a dotted note after
- // now get the note
- note = 0;
- //if statements faster than switch
- //default == 0
- if(*_songptr == 'c')
- note = 1;
- if(*_songptr == 'd')
- note = 3;
- if(*_songptr == 'e')
- note = 5;
- if(*_songptr == 'f')
- note = 6;
- if(*_songptr == 'g')
- note = 8;
- if(*_songptr == 'a')
- note = 10;
- if(*_songptr == 'b')
- note = 12;
- _songptr++;
- // now, get optional '#' sharp
- if(*_songptr == '#')
- {
- note++;
- _songptr++;
- }
- // now, get optional '.' dotted note
- if(*_songptr == '.')
- {
- _duration += _duration>>1;///2;//>>1;
- _songptr++;
- }
- // now, get scale
- if(isdigit(*_songptr))
- {
- scale = *_songptr - '0';
- _songptr++;
- }
- else
- {
- scale = _default_oct;
- }
- scale += OCTAVE_OFFSET;
- if(*_songptr == ',')
- _songptr++; // skip comma for next note (or we may be at the end)
- noTone(TONE_PIN);
- // now play the note
- if(note)
- {
- tone(TONE_PIN, notes[(scale - 4) * 12 + note], _duration);
- }
- //next interrupt at duration
- #ifdef CPU16MHZ
- // OCR1A = (_duration*4); //times 4, 16MHz proc
- delay(_duration);
- #else
- // OCR1A = (_duration*8); //times 8, 8MHz proc
- delay(_duration);
- #endif
- //_waittime = _duration+1; //+1 because 1 is check value, not 0
- }
- }
- #endif
- void setup()
- {
- //xbee
- Serial.begin(19200);
- pinMode(XBEESLEEP,OUTPUT); //6
- digitalWrite(XBEESLEEP, HIGH);
- #ifdef BT_ENABLE
- //bt
- pinMode (7,INPUT);
- pinMode (8,OUTPUT);
- btser.begin(9600);
- #endif
- #ifdef SD_ENABLE
- pinMode(10, OUTPUT);
- #endif
- lcd.createChar(5, Select);
- for(int i=0; i<40; i++)
- index[i] = i;
- strncpy(file,"File",5);
- fileNum = EEPROM.read(FILENAME_OFFSET);
- #ifdef MUSIC_ENABLE
- //timer_1a_init(); //init timer1
- musicInit(MusicSongPlay19);
- //musicstart(0);
- #endif
- }
- //good for numbers < 100
- byte convert_string(char * string, short n)
- {
- byte count = 0;
- if(n>=10)
- {
- count = convert_string(string, n/10);
- n = n%10;
- }
- *(string + count) = n+'0';
- return count+1;
- }
- //handle things here, not in loop
- void select(uint8_t cmenu, uint8_t menus)
- {
- switch(cmenu)
- {
- case MAIN:
- if(menus == XBEECONF)
- {
- menu=XBEESUB;
- menulen=XBEELEN;
- currmenu = XBEE;
- digitalWrite(XBEESLEEP, LOW);
- menusel = 0;
- }
- else if(menus == BTCONF)
- {
- menu=BTSUB;
- menulen=BTLEN;
- currmenu = BT;
- menusel = 0;
- }
- else if(menus == NUNCONF)
- {
- menu=NUNSUB;
- menulen=NUNLEN;
- currmenu = NUN;
- menusel = 0;
- }
- else if(menus == PS2CONF)
- {
- menu=PS2SUB;
- menulen=PS2LEN;
- currmenu = PS2;
- menusel = 0;
- }
- else if(menus == SDCONF)
- {
- menu=SDSUB;
- menulen=SDLEN;
- currmenu = uSD;
- menusel = 0;
- }
- else if(menus == RC_CONF)
- {
- char buffer[10];
- byte error = 0;
- byte options = 0;
- lcd.clear();
- digitalWrite(XBEESLEEP, LOW);
- delay(32);
- //connect via xbee
- while(1)
- {
- //send P to see if present
- memset(buffer,0,sizeof(buffer));
- buffer[0] = 'P';
- send_pkt(XBEE,RC_CAR_ID,TYPE_UTHERE,1,buffer);//send P to RC car
- error = get_pkt(XBEE, buffer, 10, 10000); //expect 1 byte back, need space for 2 more(type and id
- //timeout for 1 second from this get packet
- if(error == TIMEOUT)
- {
- //timeout occured
- lcd.print("T");
- send_pkt(XBEE,RC_CAR_ID,TYPE_ERROR,0,buffer);
- }
- else if(error == SUCCESS) //if we successfully get something
- {
- //now communication is established, start main communication
- options = OPTION_SEND_CTL | OPTION_NUN_CTL;
- handle_pkt(XBEE, RC_CAR_ID, options, 100, 5000);
- }
- //break if button pushed, abort
- if(analogRead(A0) > 70)
- {
- digitalWrite(XBEESLEEP, HIGH);
- return;
- }
- }
- //once connected, run send pkt
- digitalWrite(XBEESLEEP, HIGH);
- break;
- }
- else if (menus == CONNADCSERVO)
- {
- char buffer[10];
- byte error = 0;
- byte options = 0;
- lcd.clear();
- //connect via BT, send control as expected
- //btser.print((__FlashStringHelper *)adc_monitor_id);
- //btser.write(0x0D);
- //delay(100);
- //connect
- while(btser.available() > 0){btser.read();};
- setup_ser(BT,ppplus,YES,YES,YES,10000,A0);
- lcd.clear();
- setup_ser(BT,adc_monitor_id,NO,NO,NO,10000,A0);
- lcd.clear();
- setup_ser(BT,ata,NO,NO,NO,10000,A0);
- lcd.clear();
- //btser.print((__FlashStringHelper *)ata);
- //btser.write(0x0D);
- while(1)
- {
- //send P to see if present
- memset(buffer,0,sizeof(buffer));
- buffer[0] = 'P';
- send_pkt(BT,ADC_MONITOR_ID,TYPE_UTHERE,1,buffer);//send P to RC car
- error = get_pkt(BT, buffer, 1000, 10000); //expect 1 byte back, need space for 2 more(type and id
- //timeout for 1 second from this get packet
- if(error == TIMEOUT)
- {
- //timeout occured
- lcd.print("T");
- send_pkt(BT,ADC_MONITOR_ID,TYPE_ERROR,0,buffer);
- }
- else if(error == SUCCESS) //if we successfully get something
- {
- //now communication is established, start main communication
- options = OPTION_SEND_CTL | OPTION_NUN_CTL;
- handle_pkt(BT, ADC_MONITOR_ID, options, 100, 5000);
- }
- //break if button pushed, abort
- if(analogRead(A0) > 70)
- {
- digitalWrite(XBEESLEEP, HIGH);
- return;
- }
- break;
- }
- break;
- }
- else
- menu = MAINSUB;
- break;
- case XBEE:
- if(menus == BACKMAIN)
- {
- menu=MAINSUB; ;
- menulen=MAINLEN;
- currmenu = MAIN;
- digitalWrite(XBEESLEEP, HIGH);
- menusel = 0;
- }
- #ifdef XBEE_ENABLE
- else if (menus == XBEEPPP)
- {
- //do code here, or move to other function?
- lcd.clear();
- setup_ser(XBEE,wncn,YES,NO,NO,10000,A0);
- //delay(2000);
- }
- else if (menus == XBEECLOSE)
- {
- //do code here, or move to other function?
- lcd.clear();
- setup_ser(XBEE,wncn,YES,NO,NO,10000,A0);
- //delay(2000);
- }
- else
- menu = XBEESUB;
- #endif
- break;
- case BT:
- if(menus == BACKMAIN)
- {
- menu=MAINSUB;
- menulen=MAINLEN;
- currmenu = MAIN;
- menusel = 0;
- }
- #ifdef BT_ENABLE
- else if (menus == BTPPP)
- {
- //do code here, or move to other function?
- lcd.clear();
- setup_ser(BT,ppplus,YES,YES,YES,10000,A0);
- //delay(2000);
- }
- else if (menus == BTATR0)
- {
- //do code here, or move to other function?
- lcd.clear();
- setup_ser(BT,atr0,NO,NO,NO,10000,A0);
- //delay(2000);
- }
- else if (menus == BTATH)
- {
- //do code here, or move to other function?
- lcd.clear();
- setup_ser(BT,ath,NO,NO,NO,10000,A0);
- //delay(2000);
- }
- else if (menus == BTATF)
- {
- //do code here, or move to other function?
- lcd.clear();
- setup_ser(BT,atf,NO,NO,NO,10000,A0);
- //scan_bt_menuize(10000);
- //delay(2000);
- }
- else if (menus == BTATD)
- {
- //do code here, or move to other function?
- lcd.clear();
- setup_ser(BT,atd,NO,NO,NO,10000,A0);
- //delay(2000);
- }
- else if (menus == BTATA)
- {
- //do code here, or move to other function?
- lcd.clear();
- setup_ser(BT,ata,NO,NO,NO,10000,A0);
- //delay(2000);
- }
- else if (menus == BTCLOSE)
- {
- //do code here, or move to other function?
- lcd.clear();
- setup_ser(BT,ato,NO,NO,NO,10000,A0);
- //delay(2000);
- }
- else
- menu = BTSUB;
- #endif
- break;
- case NUN:
- if(menus == BACKMAIN)
- {
- menu=MAINSUB;
- menulen=MAINLEN;
- currmenu = MAIN;
- menusel = 0;
- }
- #ifdef NUN_ENABLE
- else if (menus == NUNPRES)
- {
- lcd.clear();
- Wire.begin();
- Wire.beginTransmission(0x52);
- if( Wire.endTransmission() == 0)
- lcd.print(F("Nunchuck Found"));
- else
- lcd.print((__FlashStringHelper *)Timeout);
- delay(1000);
- }
- else if (menus == NUNINIT)
- {
- nunchuk_init();
- nunchuk_send_request();
- nunchuk_get_data();
- }
- else if (menus == NUNDLCD || menus == NUNDSER || menus == NUNCAL)
- {
- lcd.clear();
- digitalWrite(XBEESLEEP, LOW);
- while(1)
- {
- nunchuk_send_request();
- nunchuk_get_data();
- #ifdef NUN_DBG_SER
- //lcd.clear();
- if( menus == NUNDSER)
- {
- Serial.print("Z ");
- Serial.print((unsigned int)nunchuk_zbutton());
- Serial.print("\tC ");
- Serial.print((unsigned int)nunchuk_cbutton());
- //rest of data
- Serial.print("\tJx ");
- Serial.print((unsigned int)nunchuk_joy_x());
- Serial.print("\tJy ");
- Serial.print((unsigned int)nunchuk_joy_y());
- Serial.print("\tcJx ");
- Serial.print((signed int)nunchuk_cjoy_x());
- Serial.print("\tcJy ");
- Serial.print((signed int)nunchuk_cjoy_y());
- //accel
- Serial.print("\tAcX ");
- Serial.print((unsigned int)nunchuk_accelx());
- Serial.print("\tAcY ");
- Serial.print((unsigned int)nunchuk_accely());
- Serial.print("\tAcZ ");
- Serial.print((unsigned int)nunchuk_accelz());
- Serial.print("\tcAcX ");
- Serial.print((signed int)nunchuk_caccelx());
- Serial.print("\tcAcY ");
- Serial.print((signed int)nunchuk_caccely());
- Serial.print("\tcAcZ ");
- Serial.println((signed int)nunchuk_caccelz());
- delay(250);
- }
- #endif
- if( menus == NUNDLCD || menus == NUNCAL)
- {
- #ifdef NUN_DBG_LCD
- lcd.home();
- lcd.print("Z ");
- lcd.print((unsigned int)nunchuk_zbutton());
- lcd.print("C ");
- lcd.print((unsigned int)nunchuk_cbutton());
- //rest of data
- lcd.print("Jx ");
- lcd.setCursor(8,0);
- lcd.print((unsigned int)nunchuk_joy_x());
- lcd.setCursor(11,0);
- lcd.print("Jy ");
- lcd.setCursor(13,0);
- lcd.print((unsigned int)nunchuk_joy_y());
- //accel - non cal
- lcd.setCursor(0,1);
- lcd.print("aX ");
- lcd.setCursor(3,1);
- lcd.print((unsigned int)nunchuk_accelx());
- lcd.setCursor(6,1);
- lcd.print("aY ");
- lcd.setCursor(9,1);
- lcd.print((unsigned int)nunchuk_accely());
- lcd.setCursor(12,1);
- lcd.print("aZ ");
- lcd.setCursor(15,1);
- lcd.print((unsigned int)nunchuk_accelz());
- //cal acc
- lcd.setCursor(0,2);
- lcd.print("cX ");
- lcd.setCursor(2,2);
- lcd.print((signed int)nunchuk_caccelx());
- lcd.setCursor(6,2);
- lcd.print("cY ");
- lcd.setCursor(9,2);
- lcd.print((signed int)nunchuk_caccely());
- lcd.setCursor(12,2);
- lcd.print("cZ ");
- lcd.setCursor(15,2);
- lcd.print((signed int)nunchuk_caccelz());
- //cal joy
- lcd.setCursor(0,3);
- lcd.print("cJx ");
- lcd.setCursor(3,3);
- lcd.print((signed int)nunchuk_cjoy_x());
- lcd.setCursor(7,3);
- lcd.print("cJy ");
- lcd.setCursor(10,3);
- lcd.print((signed int)nunchuk_cjoy_y());
- //angle of joy
- // lcd.setCursor(0,2);
- // lcd.print("Ang ");
- // lcd.setCursor(4,2);
- // lcd.print((signed int)nunchuk_joyangle());
- // lcd.setCursor(10,2);
- // lcd.print("rol ");
- // lcd.setCursor(14,2);
- // lcd.print((signed int)nunchuk_rollangle());
- // lcd.setCursor(0,3);
- // lcd.print("pitch ");
- // lcd.setCursor(6,3);
- // lcd.print((signed int)nunchuk_pitchangle());
- if(nunchuk_zbutton() == 1 && menus == NUNCAL)
- {
- nunchuk_calibrate_joy();
- nunchuk_calibrate_accelxy();
- nunchuk_calibrate_accelz();
- lcd.print((__FlashStringHelper *)Exit);
- while(nunchuk_zbutton() == 1){
- nunchuk_send_request();
- nunchuk_get_data();
- }
- break;
- }
- #endif
- }
- if(analogRead(A0) > 70)
- {
- lcd.print((__FlashStringHelper *)Exit);
- while(analogRead(A0) > 70){};
- digitalWrite(XBEESLEEP, HIGH);
- break;
- }
- }
- }
- else
- {
- menu = NUNSUB;
- }
- #endif
- break;
- case PS2:
- if(menus == BACKMAIN)
- {
- menu=MAINSUB;
- menulen=MAINLEN;
- currmenu = MAIN;
- menusel = 0;
- }
- #ifdef PS2_ENABLE
- else if(menus == PS2PRES)
- {
- lcd.clear();
- error = ps2x.config_gamepad(13,11,9,12, true, false);
- if(error == 1)
- lcd.print((__FlashStringHelper *)Timeout);
- else
- lcd.print(F("PS2 Ctl Found"));
- lcd.print((char)error + '0');
- delay(1000);
- }
- else if(menus == PS2INIT)
- {
- lcd.clear();
- error = ps2x.config_gamepad(13,11,9,12, true, false);
- lcd.print((char)error);
- delay(1000);
- }
- else if(menus == PS2DLCD || menus == PS2DSER)
- {
- lcd.clear();
- digitalWrite(XBEESLEEP, LOW);
- error = ps2x.config_gamepad(13,11,9,12, true, false);
- while(1){
- ps2x.read_gamepad(false, 0);
- if(menus == PS2DLCD)
- {
- //Joysticks
- #ifdef PS2_DBG_LCD
- lcd.home();
- lcd.print("rX ");
- lcd.setCursor(2,0);
- lcd.print((unsigned int)ps2x.Analog(PSS_RX));
- lcd.setCursor(5,0);
- lcd.print("Y ");
- lcd.setCursor(6,0);
- lcd.print((unsigned int)ps2x.Analog(PSS_RY));
- lcd.setCursor(9,0);
- lcd.print("lX ");
- lcd.setCursor(11,0);
- lcd.print((unsigned int)ps2x.Analog(PSS_LX));
- lcd.setCursor(14,0);
- lcd.print("Y ");
- lcd.setCursor(15,0);
- lcd.print((unsigned int)ps2x.Analog(PSS_LY));
- lcd.setCursor(18,0);
- lcd.print("3 ");
- lcd.setCursor(19,0);
- lcd.print((unsigned int)ps2x.Button(PSB_L3));
- lcd.setCursor(0,1);
- lcd.print("X ");
- lcd.setCursor(1,1);
- lcd.print((unsigned int)ps2x.Analog(PSAB_CROSS));
- lcd.setCursor(4,1);
- lcd.print("T ");
- lcd.setCursor(5,1);
- lcd.print((unsigned int)ps2x.Analog(PSAB_TRIANGLE));
- lcd.setCursor(8,1);
- lcd.print("Sq ");
- lcd.setCursor(10,1);
- lcd.print((unsigned int)ps2x.Analog(PSAB_SQUARE));
- lcd.setCursor(13,1);
- lcd.print("O ");
- lcd.setCursor(14,1);
- lcd.print((unsigned int)ps2x.Analog(PSAB_CIRCLE));
- lcd.setCursor(17,1);
- lcd.print("R3 ");
- lcd.setCursor(19,1);
- lcd.print((unsigned int)ps2x.Button(PSB_R3));
- lcd.setCursor(0,2);
- lcd.print("U ");
- lcd.setCursor(1,2);
- lcd.print((unsigned int)ps2x.Analog(PSAB_PAD_UP));
- lcd.setCursor(4,2);
- lcd.print("D ");
- lcd.setCursor(5,2);
- lcd.print((unsigned int)ps2x.Analog(PSAB_PAD_DOWN));
- lcd.setCursor(8,2);
- lcd.print("L ");
- lcd.setCursor(10,2);
- lcd.print((unsigned int)ps2x.Analog(PSAB_PAD_LEFT));
- lcd.setCursor(13,2);
- lcd.print("R ");
- lcd.setCursor(14,2);
- lcd.print((unsigned int)ps2x.Analog(PSAB_PAD_RIGHT));
- lcd.setCursor(17,2);
- lcd.print("ST ");
- lcd.setCursor(19,2);
- lcd.print((unsigned int)ps2x.Button(PSB_START));
- lcd.setCursor(0,3);
- lcd.print("L ");
- lcd.setCursor(1,3);
- lcd.print((unsigned int)ps2x.Analog(PSAB_L2));
- lcd.setCursor(4,3);
- lcd.print("R ");
- lcd.setCursor(5,3);
- lcd.print((unsigned int)ps2x.Analog(PSAB_R2));
- lcd.setCursor(8,3);
- lcd.print("L1 ");
- lcd.setCursor(10,3);
- lcd.print((unsigned int)ps2x.Analog(PSAB_L1));
- lcd.setCursor(13,3);
- lcd.print("R ");
- lcd.setCursor(14,3);
- lcd.print((unsigned int)ps2x.Analog(PSAB_R1));
- lcd.setCursor(17,3);
- lcd.print("Se ");
- lcd.setCursor(19,3);
- lcd.print((unsigned int)ps2x.Button(PSB_SELECT));
- #endif
- }
- else
- {
- #ifdef PS2_DBG_SER
- Serial.print("rX ");
- Serial.print((unsigned int)ps2x.Analog(PSS_RX));
- Serial.print("Y ");
- Serial.print((unsigned int)ps2x.Analog(PSS_RY));
- Serial.print("lX ");
- Serial.print((unsigned int)ps2x.Analog(PSS_LX));
- Serial.print("Y ");
- Serial.print((unsigned int)ps2x.Analog(PSS_LY));
- Serial.print("3 ");
- Serial.print((unsigned int)ps2x.Button(PSB_L3));
- Serial.print("X ");
- Serial.print((unsigned int)ps2x.Analog(PSAB_CROSS));
- Serial.print("T ");
- Serial.print((unsigned int)ps2x.Analog(PSAB_TRIANGLE));
- Serial.print("Sq ");
- Serial.print((unsigned int)ps2x.Analog(PSAB_SQUARE));
- Serial.print("O ");
- Serial.print((unsigned int)ps2x.Analog(PSAB_CIRCLE));
- Serial.print("R3 ");
- Serial.print((unsigned int)ps2x.Button(PSB_R3));
- Serial.print("U ");
- Serial.print((unsigned int)ps2x.Analog(PSAB_PAD_UP));
- Serial.print("D ");
- Serial.print((unsigned int)ps2x.Analog(PSAB_PAD_DOWN));
- Serial.print("L ");
- Serial.print((unsigned int)ps2x.Analog(PSAB_PAD_LEFT));
- Serial.print("R ");
- Serial.print((unsigned int)ps2x.Analog(PSAB_PAD_RIGHT));
- Serial.print("ST ");
- Serial.print((unsigned int)ps2x.Button(PSB_START));
- Serial.print("L ");
- Serial.print((unsigned int)ps2x.Analog(PSAB_L2));
- Serial.print("R ");
- Serial.print((unsigned int)ps2x.Analog(PSAB_R2));
- Serial.print("L1 ");
- Serial.print((unsigned int)ps2x.Analog(PSAB_L1));
- Serial.print("R ");
- Serial.print((unsigned int)ps2x.Analog(PSAB_R1));
- Serial.print("Se ");
- Serial.println((unsigned int)ps2x.Button(PSB_SELECT));
- #endif
- }
- if(analogRead(A0) > 70)
- {
- lcd.print((__FlashStringHelper *)Exit);
- while(analogRead(A0) > 70){};
- digitalWrite(XBEESLEEP, HIGH);
- break;
- }
- }
- }
- #endif
- break;
- case uSD:
- if(menus == BACKMAIN)
- {
- menu=MAINSUB; ;
- menulen=MAINLEN;
- currmenu = MAIN;
- menusel = 0;
- }
- #ifdef SD_ENABLE
- else if (menus == SDPRES)
- {
- if (!SD.begin(SDCHIPSEL))
- {
- lcd.clear();
- lcd.print((__FlashStringHelper *)Timeout);
- }
- else
- {
- lcd.print(F("Card Found"));
- }
- delay(1000);
- }
- else if (menus == SDCNGI)
- {//fileNum fileNum
- //filename in array file
- //idea is to write to array
- //if Nunchuck present, use it to scroll up and down on menu
- //Wire.beginTransmission(0x52);
- //if( Wire.endTransmission() == 0)
- nunchuk_init();
- lcd.clear();
- while(1)
- {
- nunchuk_send_request();
- nunchuk_get_data();
- lcd.home();
- lcd.print(F("Filename:File "));
- lcd.setCursor(13,0);
- if(nunchuk_joy_y() > 170)
- fileNum++;
- if(nunchuk_joy_y() < 100)
- fileNum--;
- lcd.print((byte)fileNum );
- delay(100);
- if(analogRead(A0) > 60)
- {
- lcd.setCursor(0,1);
- //write changes
- EEPROM.write(FILENAME_OFFSET, fileNum); //1 byte file name
- memset(file+4,0,3);
- convert_string(&file[4], fileNum);
- file[8] = 0;
- lcd.print(file);
- lcd.print((__FlashStringHelper *)Exit);
- while(analogRead(A0) > 70){};
- break;
- }
- }
- }
- else if (menus == SDPREV)
- {
- //idea is to preview first page of file, or perhaps
- //let you scroll with a attached joystick.
- lcd.clear();
- //show file name
- lcd.print(file);
- //load file
- convert_string(&file[4], fileNum);
- file[8] = 0; //make sure it is null terminated
- //card present, open file
- logFile = SD.open(file);
- delay(1000);
- if(logFile)
- {
- //logFile.println("testing");
- int i = 0;
- lcd.clear();
- while(logFile.available())
- {
- lcd.print((char)logFile.read());
- i++;
- if(i >= 40)
- {
- if(analogRead(A0) > 60)
- {
- lcd.print((__FlashStringHelper *)Exit);
- while(analogRead(A0) > 70){};
- break;
- }
- delay(2000);
- i=0;
- }
- }
- logFile.close();
- delay(2000);
- }
- delay(2000);
- }
- #endif
- break;
- default:
- break;
- }
- }
- void loop()
- {
- uint8_t button;
- lcd.clear();
- //simple menu here
- for(int i=0; i<HMENU && index[i+menu]-currmenu <= menulen ; i++)
- {
- lcd.setCursor(1,i);
- lcd.print((__FlashStringHelper *)MenuTable[index[i+menu]]);
- }
- //draw select
- lcd.setCursor(0,menusel);
- lcd.write(SELECT);
- #ifdef DEBUG
- lcd.print((char)(menu + '0'));
- lcd.print(' ');
- lcd.print((char)(menusel + '0'));
- #endif
- button = buttonWait(A0,NO,YES);
- if(button == BTND)
- {
- if(index[menu] - currmenu + HMENU-1 < menulen) //space to potentially go down
- menu++;//increment menu
- else if(index[menusel + menu] - currmenu < menulen)
- menusel++;
- else
- {
- //at bottom of menu, go back to top
- menu = currmenu;
- menusel = 0;
- }
- }
- if(button == BTNB)
- select(currmenu, index[menusel+menu]-currmenu);
- }
- int setup_ser(byte ser, PGM_P PROGMEM string, char init, char initcr, char justppp, unsigned long timeout,uint16_t analogpin)
- {
- char state=0, temp;
- //unsigned long time1 = millis();
- if(ser == BT)
- {
- if(init){
- //delay(1000);
- lcd.print((__FlashStringHelper *)ppplus);
- btser.print((__FlashStringHelper *)ppplus);
- if(initcr)
- btser.write(0x0D);
- delay(1000);
- }
- else
- state = 3;
- while(1)
- {
- if(state == 3)
- {
- state++;
- if(justppp)
- continue;
- lcd.print((__FlashStringHelper *)string);
- btser.print((__FlashStringHelper *)string);
- btser.write(0x0D);
- delay(100);
- }
- if(btser.available())
- {
- temp = btser.read();
- if(temp == 0x0D)
- {
- state++;
- continue;
- }
- //lcd.print((char)(state + '0'));
- if(temp == 'O')
- state++;
- if(temp == 'K')
- state++;
- lcd.print((char)temp);
- //if(temp == 'E' || temp == 'R')
- // return 0; //error
- }
- if(analogRead(analogpin) > 70)
- {
- lcd.print((char)temp);
- lcd.print((__FlashStringHelper *)Exit);
- while(analogRead(analogpin) > 70){};
- return 0;
- }
- }
- }
- else //XBEE HW serial
- {
- if(init){
- //delay(1000);
- lcd.print((__FlashStringHelper *)ppplus);
- Serial.print((__FlashStringHelper *)ppplus);
- if(initcr)
- Serial.write(0x0D);
- delay(1000);
- }
- else
- state = 3;
- while(state != 6)
- {
- if(state == 3)
- {
- state++;
- lcd.print((__FlashStringHelper *)string);
- Serial.print((__FlashStringHelper *)string);
- Serial.write(0x0D);
- delay(100);
- }
- if(Serial.available())
- {
- temp = Serial.read();
- if(temp == 0x0D)
- {
- state++;
- continue;
- }
- //lcd.print((char)(state + '0'));
- if(temp == 'O')
- state++;
- if(temp == 'K')
- state++;
- //if(temp == 'E' || temp == 'R')
- // return 0; //error
- lcd.print((char)temp);
- }
- if(analogRead(analogpin) > 70)
- {
- lcd.print((char)temp);
- lcd.print((__FlashStringHelper *)Exit);
- while(analogRead(analogpin) > 70){};
- return 0;
- }
- }
- }
- return 1;
- }
- uint8_t parse_buttons(uint16_t button)
- {
- //given the channel and button, return corresponding actual button
- //hardware specific
- switch(button)
- {
- case 1:
- return BTNU;
- case 2:
- return BTND;
- case 3:
- return BTNL;
- case 4:
- return BTNR;
- case 5:
- return BTNA;
- case 6:
- return BTND; //correct for using 10k resistor
- case 16:
- return BTNB;
- default:
- break;
- };
- return 255;
- }
- uint8_t buttonCheck( uint16_t analogpin)
- {
- uint16_t upper, lower;
- uint8_t button = 0;
- uint16_t analogval;
- analogval = analogRead(analogpin);
- //find what button it corresponds to
- for( uint16_t i = 0; i < 21; i++)
- {
- // checks the _analogval against the high and low vales in the array
- upper = pgm_read_word(&(Button[i][1]));
- lower = pgm_read_word(&(Button[i][2]));
- if(analogval >= upper && analogval <= lower)
- {
- // stores the button number to a variable
- button = pgm_read_word(&(Button[i][0]));
- return button;
- }
- }
- return button;
- }
- uint8_t buttonWait(uint16_t analogpin, uint8_t toggle, uint8_t hold)
- {
- //if toggle set, wait until button comes back to 0 position
- uint16_t init_butt=0,state = 0, offset=0;
- uint32_t time;
- uint8_t buffer[10];
- uint8_t value;
- //consider sleep code here
- while(1){
- while(state == 0)
- {
- for( uint16_t j=0; j<10; j++)
- {
- buffer[j] = buttonCheck(analogpin);
- delay(1);
- }
- value = buffer[0];
- for( uint16_t j=1; j<10;j++)
- {
- if(value != buffer[j])
- {
- //mismatch, discard
- value =255;
- break;
- }
- }
- if((value != 255) && (value != 0))
- {
- state = 2;
- init_butt = value;
- time = millis();
- }
- }
- if(toggle == YES)
- {
- state = 1;
- }
- while(state == 1)
- {
- if(millis() - time > DEBOUNCE)
- {
- return parse_buttons(init_butt);
- }
- }
- while (state == 2)
- {
- //wait for button fall
- for( uint16_t j=0; j<10; j++)
- {
- buffer[j] = buttonCheck(analogpin);
- }
- value = buffer[0];
- for( uint16_t j=1; j<10;j++)
- {
- if(value != buffer[j])
- {
- //mismatch, discard
- value =254;
- break;
- }
- }
- if( hold == YES && millis() - time > PRESSHOLD)
- {
- offset = 10;
- }
- if( value == 0)
- {
- return parse_buttons(offset+init_butt);
- }
- }
- }
- return 0;
- }
- //reserved for future
- #if 0
- int scan_bt_menuize(byte timeout)
- {
- char state=0, temp, skip, devicenum;
- char sindex[20];
- char buffer[10][20];
- char mac[10][15];
- unsigned long time1 = millis();
- lcd.clear();
- //send ATF?
- btser.print((__FlashStringHelper *)atf); //ATF?
- btser.write(0x0D);
- //create own menu system here, pretty much. Need to be able to select, and connect to it
- while(skip < 25) //17
- {
- if(btser.available())
- {
- temp = btser.read();
- //lcd.print((char)temp);
- //delay(250);
- skip++;
- }
- //if(millis() > time1 + timeout)
- //{
- // lcd.print((__FlashStringHelper *)Timeout);
- // delay(1000);
- // break;
- //}
- if(analogRead(A0) > 70)
- return 0;
- }
- //process each result from BT module, displaying it as you go
- while(1)
- {
- temp = 0;
- int i = 0; //cnt of number of BT things around
- skip = 0;
- while(skip < 3) //skip LF and first number. Land in space region before name
- {
- if(btser.available())
- {
- temp = btser.read();
- //lcd.print((char)temp);
- skip++;
- }
- if(analogRead(A0) > 70)
- return 0;
- }
- //now read spaces until nonspace
- while(temp == ' ')
- {
- if(btser.available())
- {
- temp = btser.read();
- //lcd.print((char)temp);
- }
- if(analogRead(A0) > 70)
- return 0;
- }
- //lcd.clear();
- //lcd.print("proc Name");lcd.print((int)devicenum);
- //lcd.setCursor(0,1);
- //Now process this name
- buffer[devicenum][i++] = temp;
- //lcd.print((char)temp);
- while(temp != ' ')
- {
- if(btser.available())
- {
- temp = btser.read();
- //lcd.print((char)temp);
- //delay(250);
- if(temp != ' ')
- buffer[devicenum][i++]=temp; //save name
- }
- //if(analogRead(A0) > 70)
- // return 0;
- if(analogRead(A0) > 70)
- {
- lcd.print((int)i);
- while(analogRead(A0) > 70){};
- //return 0;
- }
- }
- buffer[devicenum][i] = 0; //null terminated
- //delay(2000);
- //lcd.clear();
- //lcd.print("remove space");
- //lcd.setCursor(0,1);
- //now read spaces until nonspace
- while(temp == ' ')
- {
- if(btser.available())
- {
- temp = btser.read();
- //lcd.print((char)temp);
- }
- if(analogRead(A0) > 70)
- return 0;
- }
- i=0;
- //delay(2000);
- //lcd.clear();
- //lcd.print("proc Mac");
- //lcd.setCursor(0,1);
- //now BT mac, need to save this too!
- mac[devicenum][i++]=temp; //temp is first nonzero from above
- while(i < 14) //expect XXXX-XX-XXXXXX
- {
- if(btser.available())
- {
- temp = btser.read();
- //lcd.print((char)temp);
- //delay(250);
- if(temp != 0x0A) //should never be 0x0A, if it is, we missed a character
- mac[devicenum][i++]=temp; //save name
- }
- if(analogRead(A0) > 70)
- {
- lcd.print((__FlashStringHelper *)Exit);
- while(analogRead(A0) > 70){};
- return 0;
- }
- }
- mac[devicenum][i] = 0;
- //lcd.clear();
- //now we have device name, and mac, both null terminated. Display device name
- lcd.setCursor(1,devicenum); //leave space for cursor
- lcd.print(buffer[devicenum++]); //hopefully it is less than 19 chars long
- delay(1000);
- time1=millis();
- while(millis() < time1 + 4000)
- {
- if(btser.available())
- {
- temp = btser.read();
- //lcd.print((char)temp);
- //delay(250);
- break;
- }
- }
- if(millis() < time1 + 4000)
- return 0;
- }
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement