Finally got XBee, BT Serial, and menu system working… oh and Nunchucks too!

This slideshow requires JavaScript.

Last night I discovered that the software serial library can’t really keep up with what I was trying to do (configuring one module, then configuring the other). I’m sure it was something wrong with my code, but eh. Another thing I discovered was how the Arduino uses 1k resistors to buffer the FTDI connector from anything that may be connected via the serial pins. Using 1k resistors on non-dominant pins, can let you manually choose a dominant port, such as the FTDI. Why would you need to do this? Well if you have the XBee on the Hardware serial, as well as your FTDI connector, you may have some problems downloading (I did).

So I moved the XBee to Hardware serial, with 1k resistors for both TX and RX, which means that I need to disconnect the FTDI connector if I want to use the XBee, which is pretty reasonable (much better than disconnecting the xbee). Once I got that working, I had a menu system that fully let me issue configuration commands, from within it. I do need to do some tweaking on it, but it is good enough to start working on other things. Things like a NunChuck.

I spent quite a few hours tonight bashing my head trying to get this to work. I referenced this diagram, which appears correct. I didn’t realize that it was backwards until I noticed this very helpful post. The diagram shown originally, was for the socket that the NunChuck plugs into, which isn’t what I was connecting to. So once I got that working, I was able to run this sketch, which shows the address of all i2c things on the bus. It was able to detect my MotionPlus and NunChuck knockoffs with ease ūüôā I’d like to also mention that I’m using 2.2K pullups on the CLK and DATA lines for the i2c bus.

So now that I have the NunChuck working, I’m going to make a little menu for it perhaps, or play with it even more, to understand how it works better. I should be receiving parts in the next few days, so the actual controller may be built.¬† I do realize that this will be a first version of it, but I intend to make it awesome!

Control.ino.

Nunchuck Library, from here.

i2C scanner code

Ugly Code of Control.ino.

#include <Wire.h>
#include <Nunchuck.h>

/* Controller 2.0
Includes the following:
20×4 LCD
XBee Connected to pins 0 and 1 of ATMEGA328
BTM-182 connected to pins 7 and 7
PS2 connector
Nunchuck connector
microSD adapter (using old microSD to SD converter)

Dustin Reynolds
2012-03-24
*/
#include <SoftwareSerial.h>
#include <ShiftRegLCD.h>
#include <Buttons.h>

#define HMENU 4
#define WMENU 20

//#define DEBUG 1

ShiftRegLCD lcd(4, 3, 5, 4);¬† //we have a 20×4 LCD data clock enable #lines

SoftwareSerial btser(7, 8);

//want simple XBEE config
#define XBEESLEEP 6  //Pin 12 for XBee sleep control, goes to pin 9 on xbee

#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)

#define XBEECONF 0
#define BTCONF   1
#define CONNCPU  2
#define CONNGAR  3
#define CONNSAB  4

#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 MAINSUB 0
#define MAINLEN 5 //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[] = “Connect to CPU”;
const prog_char PROGMEM MenuStr5[] = “Connect to Garden”;
const prog_char PROGMEM MenuStr6[] = “Connect to Sable”;
#define XBEESUB 6 //starts at 2

#define XBEELEN 3  //actual Р1
const prog_char PROGMEM Xbee1[] = “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 10

#define BTLEN 7 //actual – 1
const prog_char PROGMEM BTser1[] = “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”;
//currentmenu
#define MAIN   MAINSUB
#define XBEE   XBEESUB
#define BT     BTSUB

PGM_P PROGMEM MenuTable[] = {
MenuStr1,
MenuStr2,
MenuStr3,
MenuStr4,
MenuStr5,
MenuStr6,
Xbee1,
Xbee2,
Xbee3,
Xbee4,
BTser1,
BTser2,
BTser3,
BTser4,
BTser5,
BTser6,
BTser7,
BTser8,
};

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”;

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[20];
char currmenu = MAIN;  //current menu

int setup_ser(char ser, char * string, char init, char initcr,char justppp, unsigned long timeout, uint16_t analogpin);

void setup()
{
//xbee
Serial.begin(19200);
pinMode(XBEESLEEP,OUTPUT); //6
digitalWrite(XBEESLEEP, HIGH);
//bt
pinMode (7,INPUT);
pinMode (8,OUTPUT);

btser.begin(9600);

lcd.createChar(5, Select);

for(int i=0; i<20; i++)
index[i] = i;

//Nunchuck
lcd.print(“init starting”);
nunchuk_init();
lcd.clear();
lcd.print(“init finished”);
delay(1000);
while(1)
{
//lcd.clear();
nunchuk_send_request();
nunchuk_get_data();
Serial.print(“Z:”);
Serial.print((unsigned int)nunchuk_zbutton());
Serial.print(“C:”);
Serial.print((unsigned int)nunchuk_cbutton());
//rest of data
Serial.print(“Jx:”);
Serial.print((unsigned int)nunchuk_joy_x());
//Serial.setCursor(12,0);
Serial.print(“Jy:”);
Serial.print((unsigned int)nunchuk_joy_y());
//Serial.setCursor(0,1);
//accel
Serial.print(“AccX:”);
Serial.print((unsigned int)nunchuk_accelx());
//Serial.setCursor(0,2);
Serial.print(“AccY:”);
Serial.print((unsigned int)nunchuk_accely());
//Serial.setCursor(0,2);
Serial.print(“AccZ:”);
Serial.println((unsigned int)nunchuk_accelz());
//Serial.setCursor(0,2);
delay(500);
}

}

//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);
}
else if(menus == BTCONF)
{
menu=BTSUB;
menulen=BTLEN;
currmenu = BT;
}
else
menu = MAINSUB;
break;
case XBEE:
if(menus == BACKMAIN)
{
menu=MAINSUB; ;
menulen=MAINLEN;
currmenu = MAIN;
digitalWrite(XBEESLEEP, HIGH);
}
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;
break;
case BT:
if(menus == BACKMAIN)
{
menu=MAINSUB;
menulen=MAINLEN;
currmenu = MAIN;
}
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);
//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;
break;
default:
break;
}
menusel = 0;
}

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(char 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)temp);
//lcd.print((char)(state + ‘0’));
if(temp == ‘O’)
state++;
if(temp == ‘K’)
state++;
//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;
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s