package stamp.rf; import stamp.core.*; /** * This class provides an interface to the XBee * Wireless communication module. * * @author Jon Keinath, www.jonkeinath.com, (jonkeinath@gmail.com) * @version 0.5 November 24, 2006 */ public class XBee { //------------------------------------CONSTANTS---------------------------- private static final String CR = "\r"; //0x0D; public static final int baud9600 = 3; //Default Baud public static final int baud1200 = 0; //Standard Bauds public static final int baud2400 = 1; // | public static final int baud4800 = 2; // | public static final int baud19200 = 4; // | public static final int baud38400 = 5; // | public static final int baud57600 = 6; // | //dBm Levels Default = 4 //XBEE-PRO | XBEE public static final int dBm10n10 = 0; // 10dBm | -10dBm public static final int dBm12n6 = 1; // 12dBm | - 6dBm public static final int dBm14n4 = 2; // 14dBm | - 4dBm public static final int dBm16n2 = 3; // 16dBm | - 2dBm public static final int dBm18n0 = 4; // 18dBm | 0dBm //--------------------------------VARIABLES-------------------------------- private static Uart rx, tx; //Communication Uarts private static int rxPin; //rx Communication Pin private static int txPin; //tx Communication Pin private static int myAddr; //Node Address in Hex private static int destAddr; //Destination in Hex private static int guardTime = 20000; //Guard Time private static int rtsPin; //RTS Pin private static StringBuffer buff = new StringBuffer(32); //Buffer for Commands //------------------------TEMPORARY VARIABLES------------------------------ private static int data; //Data variable private static int db; //db private static int i = 0; //i private static Timer t = new Timer(); //Timeout Timer /** * Creates a XBee Wireless Communication Object. * * @param rxIn Serial Receive Uart * @param txIn Serial Transmitter Uart * @param myAddress Current XBee Node Address * @param name Name for Current XBee Node * @param rtsIn Serial Ready to Send Pin */ public XBee(int txPinIn,int rxPinIn,int myAddress,String name,int rtsIn) { tx = new Uart(Uart.dirTransmit, //Uart for sending data txPinIn, //to XBee Uart.dontInvert, Uart.speed9600, Uart.stop1); rx = new Uart(Uart.dirReceive, //Uart for receiving rxPinIn, //data from XBee Uart.dontInvert, Uart.speed9600, Uart.stop1); rtsPin = rtsIn; //Ready To Send Pin guardTime = getGuardTime() * 100; //Read Guard Time setAddr((byte)myAddress); //Set Address of XBee enableRTS(); //Enable RTS control rxPin = rxPinIn; //Receive Pin txPin = txPinIn; //Transmit Pin setIdentify(name); //Identifier of Node } /** * Creates a XBee Wireless Communication Object. * * @param rxIn Serial Receive Uart * @param txIn Serial Transmitter Uart * @param myAddress Current XBee Node Address * @param name Name for Current XBee Node */ public XBee(int txPinIn,int rxPinIn,int myAddress,String name) { tx = new Uart(Uart.dirTransmit, //Uart for sending data txPinIn, //to XBee Uart.dontInvert, Uart.speed9600, Uart.stop1); rx = new Uart(Uart.dirReceive, //Uart for receiving rxPinIn, //data from XBee Uart.dontInvert, Uart.speed9600, Uart.stop1); setGuardTime(5); setAddr((byte)myAddress); //Set Address of XBee rxPin = rxPinIn; //Receive Pin txPin = txPinIn; //Transmit Pin setIdentify(name); //Identifier of Node } /** * Sends a String. * * @param toSend a string to send */ public void send(String toSend) { tx.sendString(toSend); } /** * Sends a string to a specific Node * * @param toSend a string to send * @param destNode Destination Address */ public void send(String toSend,int destNode) { if (destNode != destAddr) setDestNode(destNode); send(toSend); //use generic send method } /** * Sends a StringBuffer. * * @param toSend a StringBuffer to send */ public void send(StringBuffer toSend) { for (int i = 0; i < toSend.length(); i++) //Send String Buffer tx.sendByte((char)toSend.charAt(i)); //Split into bytes } /** * Sends a Int * * @param toSend an Int to send */ public void send(int toSend) { buff.clear(); buff.append(toSend); send(buff); } /** * Sends a StringBuffer to a specific Node. * * @param toSend a StringBuffer to send * @param destNode Destination Address */ public void send(StringBuffer toSend,int destNode) { if (destNode != destAddr) setDestNode(destNode); //change destnation if send(toSend); // required } /** * Set the Guard Time for entering Command Mode. * * @param time Guard Time */ public void setGuardTime(int time) { enterCmd(); send("ATGT "); send(time); send(CR); waitOK(); exitCmd(); guardTime = time * 100; } /** * Set the destination Node of the XBee. * * @param node Node Address see Xbee Docs for Values */ public void setDestNode(int node) { enterCmd(); send("ATDL "); send(node); send(CR); waitOK(); exitCmd(); } /** * Change communication speed of XBee. * * @param XbeeBaud 0-6, see CONSTANTS Above * @param uartBaud "Uart.speed#####" */ public void setCommSpeed(int XbeeBaud, int uartBaud) { enterCmd(); send("ATBD "); send(XbeeBaud); send(CR); waitOK(); exitCmd(); tx.restart(Uart.dirTransmit,txPin,Uart.dontInvert,uartBaud,Uart.stop1); rx.restart(Uart.dirReceive ,rxPin,Uart.dontInvert,uartBaud,Uart.stop1); } /** * setPacketSize for Transmission * * @param packetSize See XBee docs for details */ public void setPackets(int packetSize) { if (packetSize < 0xFF) { enterCmd(); send("ATRO "); send(packetSize); send(CR); waitOK(); exitCmd(); } } /** * Discover nodes in network. * * Returns info to debug screen (for now) */ public void discover() { enterCmd(); send("ATND"); send(CR); System.out.println("\nDISCOVERING NODES..."); while (rx.byteAvailable()) { data = (char)rx.receiveByte(); if (data == 0x0D ) System.out.print("\n"); else System.out.print((char)data); } exitCmd(); System.out.println("\n...DISCOVERY COMPLETE"); } /** * Set Power Level for Transmission. * * @param level 0-4, see vars above for details */ public void setPowerLevel(int level) { enterCmd(); send("ATPL"); send(level); send(CR); waitOK(); exitCmd(); } /** * Get RF Level of last Received Byte * * @return RF Level of last Received Byte */ public int getRFLevel() { enterCmd(); send("ATDB"); send(CR); db = 0; data = rx.receiveByte(); while (isDigit(data)) { db = 10 * db + (data - '0'); data = rx.receiveByte(); } exitCmd(); return db; } /** * Save settings into nonvolital memory for use on next startup. * */ public void save() { enterCmd(); send("ATWR"); send(CR); waitOK(); exitCmd(); } /** * Set XBee back to default values. * */ public void defaults() { enterCmd(); send("ATRE"); send(CR); waitOK(); exitCmd(); guardTime = getGuardTime() * 100; } /** * Get Guard Time from the XBee. * * @return The Guard Time Value */ public int getGuardTime() { enterCmd(); send("ATGT"); send(CR); db = 0; data = rx.receiveByte(); while (isDigit(data)) { db = 10 * db + (data - '0'); data = rx.receiveByte(); } exitCmd(); return db; } /** * Check if a byte is waiting in the RX Uart buffer. * * @return True if byte is available */ public boolean byteAvailable() { return rx.byteAvailable(); } /** * Wait for a Value and Return it. * * @return byte received via XBee and rx */ public int rxByte() { return ((int)rx.receiveByte()); } //==========================PRIVATE METHODS BELOW============================== /** * Set Identify of XBee Node. * * @param name Node Name for XBee */ private void setIdentify(String name) { enterCmd(); send("ATNI "); send(name); send(CR); waitOK(); exitCmd(); } /** * Enable RTS mode on XBee. * */ private void enableRTS() { enterCmd(); send("ATD6 1"); send(CR); waitOK(); exitCmd(); } /** * Set Node Address on XBee. * * @param address Node Address for XBee */ private void setAddr(int address) { enterCmd(); send("ATMY "); send(address); send(CR); waitOK(); exitCmd(); } /** * Enter Command Mode on XBee. * */ private void enterCmd() { CPU.delay(guardTime); //Command Mode Guard Time send("+++"); //Enter Command Mode CPU.delay(guardTime); //Command Mode Guard Time waitOK(); //wait for XBee to send 'OK' } /** * Exit Command Mode on XBee. * */ private void exitCmd() { send("ATCN"); //Exit Command Mode String send(CR); // waitOK(); } /** * Test if character is a digit. * * @param ch Character to be tested * @return True if ch is a digit */ public static boolean isDigit(int ch) { return ch<='F' && ch>='0'; //between 0 and 15 } /** * Wait for an 'OK' from the XBee * */ private static void waitOK() { t.mark(); //Clear timer for timeout chk while (rx.receiveByte() != 'O' | t.timeout( 8000) ); // wait for 'O' while (rx.receiveByte() != 'K' | t.timeout(16000) ); // wait for 'K' if (!t.timeout(16000)) rx.receiveByte(); // remove if (t.timeout(16000)) System.out.println("waitOK TIMEOUT"); } }// End Class