/* Basic test to see if I can acquire the DHCP address of the XPort Direct. The XPort Direct is configured as follows: --- cut here --- *** basic parameters Hardware: Ethernet TPI IP addr - 0.0.5.0/DHCP, no gateway set DHCP device name : not set *** Security Telnet Setup is enabled TFTP Download is enabled Port 77FEh is enabled ECHO is disabled Enhanced Password is disabled Port 77F0h is enabled *** Channel 1 Baudrate 57600, I/F Mode 4C, Flow 00 Port 10001 Connect Mode : FE Send '+++' in Modem Mode enabled Show IP addr after 'RING' enabled Auto increment source port disabled Hostlist : No Entry ! Hostlist Retrycounter : 3 Hostlist Retrytimeout : 250 Disconn Mode : 00 Flush Mode : 00 *** Expert TCP Keepalive : 45s ARP cache timeout: 600s Monitor Mode @ bootup : enabled MTU Size: 1400 Alternate MAC: disabled Ethernet connection type: auto-negotiate --- cut here --- I've enabled Modem Mode with full response (connect mode FE), which allows a basic Hayes-like command process (AT). Baurd rate is 57600, any time I've set it less, characters are lost. Which is odd, you usually don't loose characters on lower baud rates. There are three (3) serial ports! The USB port is hardwired to the UART of the MegaAVR. The XPort direct appears as another serial port. And a SparkFun serial LCD is used for display. A 4-bit LCD could have been used instead, but that would have made it just that more complex. The basic flow is: * wait for the XPort to report NO CARRIER, which signifies a reset * send a test command, which is just an AT, which returns OK * set the device into Monitor Mode, by sending an empty dial string (ATD). Normally you use ATD with an IP address to connect to a remote system, but with an empty dial string, the device drops into Monitor Mode * Once setting monitor mode, check for a "good" command line, which is just the string "0>". There is no error checking, but if there were, the return "9>" signifies a bad command * Send the NC (network connection) command to acquire the address * Send the QUIT command to drop back to the command processor Once the IP address is acquired, it is returned in the format: IP xxx.xxx.xxx.xxx GW yyy.yyy.yyy.yyy MASK zzz.zzz.zzz.zzz All leading zeros. I'm not entirely interested in the gateway or the mask. Going with standard (non CIDR) masks of 255.255.255.0, and defacto standard of .1 for the gateway. But a four-line LCD should be sufficint to display this information if desired. Once the IP address is processed to display on the LCD, an eternal loop runs, which just echos ASCII characters to the telnet port of the XPort. This allows you to telnet to the XPort and verify that it's operating properly. The code is ugly. I'm a poor programmer. I've not used many Arduino-specific libraries, since many of them did not meet my specific needs (i.e., there is a SerLCD library, but that uses the hardware UART; and the Xport library "reset" call expects the Xport to be in default connect mode. */ #include #include #undef int() #include #include #include #include // linebuffer the Xport return string, set as a global to ease processing char linebuffer[256]; char ipaddr[20]; char * token; // The LCD only needs RX, which means we only need TX on this side SoftwareSerial lcd = SoftwareSerial(9,10); // instantiate an Xport. These are the default recommended // connections on the LadyAda tutorial. It's odd that CTS/RTS // are wired and enabled, yet slower baud rates are touchy AF_XPort xport = AF_XPort(2,3,4,5,7,6); void setup() { // Set up the serial LCD. Since RX to the Arduino is not needed // (and not even provided), I could probably skip pin 9. // The serial LCD defaults to 9600 pinMode(9,INPUT); pinMode(10,OUTPUT); lcd.begin(9600); // Set both the Arduino and the XPort to 57600. As above, I've // tried several baud rates, and the highest are the best performers xport.begin(57600); Serial.begin(57600); // This takes place of the xport.reset command, which expects // a different return sequence. In Modem Mode, the return // sequence is different. No error checking. digitalWrite(4,LOW); delay(50); digitalWrite(4,HIGH); delay(50); } void loop() { // Since I'm not using a serial LCD library, I need to control // the LCD directly. But I'm not doing any fancy scrolling, // so it's not too much of a pain. // set the LCD for the highest brightness lcd.print((char)0x7C); lcd.print((char)157); // clear the LCD display lcd.print((char)0xFE); lcd.print((char)0x01); // read the xport while (xread() == 0); { xread(); } // when the xport says "NO CARRIER", the reset has occured // There should be some error checking here, maybe later if ((strncmp (linebuffer,"NO CARRIER",10)) == 0) { Serial.println("good reset"); lcd.print("Reset occurs"); // move to line 2 of the LCD lcd.print((char)0xFE); lcd.print((char)191); delay(1000); } // send a test command just to make sure the command processor is ready xport.println("AT"); // and read the next incoming string, which should be an OK while (xread() == 0); { xread(); } if ((strncmp (linebuffer,"OK",2)) == 0) { Serial.println("command mode ready"); lcd.print("command mode ready"); // move to line 3 of the LCD lcd.print((char)0xFE); lcd.print((char)148); delay(1000); } // send the monitor mode command, which should return 0>. I'm // only testing the first character, as that is the only signficant // character; the other return is 9>, which flags an error in input xport.println("ATD"); while (xread() == 0); { xread(); } if ((strncmp (linebuffer,"0",0)) == 0) { Serial.println("monitor acquired"); lcd.print("monitor acquired"); // move to line 4 of the LCD lcd.print((char)0xFE); lcd.print((char)212); delay(1000); } // while in monitor mode, NC will get network connection parameters xport.println("NC"); while (xread() == 0); { xread(); } if ((strncmp (linebuffer,"IP",2)) == 0) { Serial.println("IP address acquired"); lcd.print("DHCP acquired"); // well, I am out of LCD lines, so I'll just overwrite the // DHCP status message lcd.print((char)0xFE); lcd.print((char)212); delay(1000); } // here is a recursive string search // the first token returns the text "IP", which is just discarded // the second token returns the numeric address char * ptr; token=strtok_r (linebuffer," ",&ptr); token=strtok_r (NULL," ",&ptr); Serial.println(token); lcd.print(token); // exit monitor mode so that the echo loop can proceed xport.println("QUIT"); delay(1000); // endless loop which just echos ASCII characters to the telnet // port of the XPort while(1) { for (int i=32; i <= 126; i++){ xport.print(i,BYTE); delay(100); } } // this is just a sub to make reading the XPort a little neater } int xread() { int xreadret; xreadret = xport.readline_timeout(linebuffer,255,1000); return xreadret; }