/* FioV3wifiSetup.ino * This sketch sets up RN-43XV wifi module to run with a fixed ip:port on a wifi network * Load the sketch and then open the SerialMonitor within 10sec to monitor the results. * * (c)2013 Forward Computing and Control Pty. Ltd. * www.forward.com.au * This code may be freely used */ // set these strings to suit you local wifi network char *ipAddress = "10.1.1.100"; char *localPort = "4989"; char *accessPointNetworkName = "networkNameHere"; char *WPA_key = "wpaPassKey_here"; // if not using WPA-PSK you need to change the "set wlan auth 4" below see the WiFly docs for valid values // http://www.forward.com.au/pfod/ArduinoProgramming/FioV3/WiFly-RN-UM.pdf Stream *console = NULL; Stream *wifi = NULL; void setup() { // put your setup code here, to run once: // Open serial communications // this setting suits FioV3 // but for some boards wifi = Serial if there is not another serial available // wifi stream change this to suit your Arduino board Serial1.begin(9600); // this setting suits FioV3 + RN-42XV board wifi = &Serial1; // set this to the serial connected to your wifi as specified above in the .begin( ) i.e. Serial1 etc or SofwareSerial etc Serial.begin(9600); // console stream Almost all Arduino boards with USB connections use this. console = &Serial; // console it usually Serial Almost all Arduino boards with USB connections use this. // this setup also allows a little time to connect the serialMonitor before running the rest of the setup setupWifi(); // uses console and wifi } void loop() { // put your main code here, to run repeatedly: if ((console != wifi) && (console != NULL)) { // give the SerialMonitor access to the wifi board if (wifi->available()) { console->write(wifi->read()); } if (console->available()) { byte in = console->read(); console->write(in); // local echo wifi->write(in); } } } void setupWifi() { if (wifi == NULL) { streamPrint(console, F("wifi cannot be null."), true); } if (wifi == console) { // can not send debug console = NULL; } for (int i = 10; i > 0; i--) { delay(1000); streamPrint(console, F(" "), false); streamPrint(console, i, false); } streamPrint(console, F(""), true); boolean enteredCMDmode = false; write(F("$$$"), false, true); // no CR here, but echo to console enteredCMDmode = waitFor("CMD"); if (!enteredCMDmode) { // did not get into CMD mode. write(F(" ")); // send cr to terminate last command dumpReply(); streamPrint(console, F("Are we still in CMD mode? Trying 'exit' to exit CMD mode"), true); write(F("exit")); if (waitFor("EXIT")) { write(F("$$$"), false, true); // no CR here but echo to console enteredCMDmode = waitFor("CMD"); } if (!enteredCMDmode) { streamPrint(console, F("Could still not get into CMD mode. Try changing wifi BAUD rate. Skipping programmed config. Use console"), true); } } // skip all these cmds if did not get to CMD mode if (enteredCMDmode) { write(F("factory RESET")); // reset defaults waitFor("Set Factory Defaults"); write(F("set ip tcp-mode 0x10")); // disable remote config waitForAOK(); write(F("set comm close 0")); // removes the default *CLOS* message sent on the serial connection when the connection closes. waitForAOK(); write(F("set comm open 0")); // removes the default *OPEN* message sent on the serial connection when a connection is established waitForAOK(); write(F("set comm remote 0")); // removes the default *HELLO* message sent via wifi to the remote end when a TCP/IP connection is established waitForAOK(); write(F("set comm match 0")); // disables the match char used to send buffered chars waitForAOK(); write(F("set wlan rate 0")); // Increases the effect range waitForAOK(); write(F("set ip address "), false, false); write(ipAddress); // set static IP waitForAOK(); write(F("set ip localport "), false, false); write(localPort); // set local port waitForAOK(); write(F("set ip dhcp 0")); // disables the DHCP and prevents the static ip address being overwritten waitForAOK(); write(F("set ip protocol 2")); // Allow TCP/IP server connections waitForAOK(); write(F("set sys iofunc 0x40")); // enables the hardware connection indication. GPIO-6, high = connected, low = not connected. waitForAOK(); write(F("set sys printlvl 0")); // Suppress all the status messages. waitForAOK(); write(F("set wlan auth 4")); // Set the security setting, in my case WPA2-PSK waitForAOK(); write(F("set wlan join 1")); // Only join the access point that matches the stored SSID and passkey waitForAOK(); write(F("set wlan phrase "), false, false); write(WPA_key); // Set the secret WPA key waitForAOK(); write(F("set wlan ssid "), false, false); write(accessPointNetworkName); // Set the SSID name of your access point waitForAOK(); write(F("get everything")); dumpReply(); write(F("save")); waitFor("Storing in config"); write(F("reboot")); waitFor("*Reboot*"); // reboot exits CMD mode. if not rebooting then issue exit to exit CMD mode // write(F("exit")); // waitFor("EXIT"); } } // write to wifi only with no echo to console and with terminating cr nl void write(const __FlashStringHelper *ifsh) { write(ifsh,true,false); } // write to wifi only with no echo to console and with terminating cr nl void write(char *str) { write(str,true,false); } void write(char * str, boolean newLine, boolean echoToConsole) { if (echoToConsole) { streamPrint(console, str, newLine); } streamPrint(wifi, str, newLine); } void write(const __FlashStringHelper *ifsh, boolean newLine, boolean echoToConsole) { if (echoToConsole) { streamPrint(console, ifsh, newLine); } streamPrint(wifi, ifsh, newLine); } void streamPrint(Stream *stream, const __FlashStringHelper *ifsh, boolean newLine) { if (stream == NULL) { return; // nothing to write to } stream->print(ifsh); if (newLine) { stream->println(); } } void streamPrint(Stream *stream, int i, boolean newLine) { if (stream == NULL) { return; // nothing to write to } stream->print(i); if (newLine) { stream->println(); } } void streamPrint(Stream *stream, char *str, boolean newLine) { if (stream == NULL) { return; // nothing to write to } stream->print(str); if (newLine) { stream->println(); } } boolean waitForAOK() { return waitFor("AOK"); } boolean waitFor(char* str) { size_t targetLen = 0; char* target; size_t index = 0; target = str; targetLen = strlen(str); index = 0; long startTime = millis(); const long timeout = 1000; const long newLineTimeout = 10; while (millis() - startTime < timeout) { if (console && wifi && console->available()) { byte in = console->read(); //Serial.write(in); // local echo wifi->write(in); } if (targetLen == 0) { return true; } // else if (wifi->available()) { char c = wifi->read(); if (console) { console->write(c); } if (c != target[index]) { index = 0; // reset index if any char does not match } // no else here if (c == target[index]) { //Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1); if (++index >= targetLen) { // return true if all chars in the target match targetLen = 0; // finished matching this one // look for following \n or \r's for 10mS startTime = millis(); do { c = wifi->peek(); if (c >= 0) { if (c != '\n' && c != '\r') { return true; // did not find following newlines } wifi->read(); // consume it if (console) { console->write(c); } } } while (millis() - startTime < newLineTimeout); return true; } } } } streamPrint(console, "Timed out waiting for '", false); streamPrint(console, target, false); streamPrint(console, "'", true); return false; // timed out } // just dump chars from wifi to console until none found for 100mS void dumpReply() { long startTime = millis(); const long timeout = 500; while (millis() - startTime < timeout) { // else if (wifi->available()) { char c = wifi->read(); if ((console != wifi) && (console != NULL)) { console->write(c); // echo it } startTime = millis(); // reset start time } } }