WIFI Week: Connecting The Wifi Sensor to a Network

Wifi sensor for LEGO MINDSTORMS NXTOur first installment of Wifi Week goes over how to connect to setup the wifi sensor and then connect to a wifi network.

  • First, we’ll walk you through, step-by-step, conceptually, on how you setup the sensor and connect to a network.
  • Then we’ll put the actual code down at the bottom.  The code example is in RobotC.

The first step in getting your robot on the internet is to connect to a wifi network.  Wifi networks typically come either encrypted or unencrypted.  Encrypted wifi networks can be WEP or WPA.  We will go over getting on both. ** In all of these examples you will want to make sure that your debug stream window is open.  We have written all of our examples so that the dialog between the NXT and the Wifi sensor will show up on RobotC’s debug stream.

Initialization

Initialization requires a few steps.  We will outline here how we prefer to setup our wifi sensor, but in no way is it the only way to set the sensor up.

  1. Setup the High Speed Link: Here we setup Port 4 for serial operations.  We initialize the port to 9600 baud; the sensor can operate at much faster rates.  We borrowed (with permission of course!) some code written by Xander that scans the baud rate the sensor is currently operating on.  The sensor ships with a baud rate preset of 9600, but at times you may want to increase the speed and then forget that you did this.  The routine Xander wrote scans Port4 for the proper baud rate and connects at that baud rate.
  2. Turn the Echo Off: This is the first thing we configure on the Wifi sensor.  The wifi sensor defaults to echo, meaning that what you type in echos back.  We want to turn this off.  The command is “ATE0”.
  3. Software Flow Control: Next we set the software flow control.  This again is a parameter we need to set to be able to communicate with the Wifi sensor.
  4. Verbose: Turn verbose on.  As we mentioned earlier, the sensor responds to each command.  The sensor can respond in a verbose manner, with a sentence describing the problem or response.  This is called verbose mode.  The sensor can also respond with a number code, making the communications faster.  These codes can be found in Wifi Commands on our download page.
  5. Infrastructure Mode: You can operate the sensor in infrastructure mode or not.  To connect directly to another wifi module (such as a phone or computer) infrastructure mode should be off.  To connect to a network, such as your home wifi network, infrastructure should be on.  Since we’re connecting to either WPA or WEP networks, we will leave our network on.
  6. Set DHCP: DHCP stands for Dynamic Host Configuration Protocol.  By initiating this, you will automatically obtain an IP after connecting to a network that is connected to the internet.
  7. Disassociate: Optional, but it is good housekeeping.  In case our sensor has already connected to a network, we will want to make sure it is disconnected.
  8. Keep Alive: Optional.  After connecting to a network, the wifi sensor will disconnect after around 2 minutes if no communication occurs.  In our example, we extend the “keep alive” time to 10 minutes.

WPA

After initialization, connecting to a WPA network is easy.

  1. Set the PSK: WPA networks use Pre Shared Keys for encryption and authentication.  The wifi module will calculate this from your SSID and Network key.  In our example, these are specified as character arrays “SSID” and “wpa_psk”.  Calculating the key can take a few seconds.
  2. Connect to the Network: The wifi sensor now has your PSK in memory and all you need to do is direct it to connect to the network (connect to an “SSID” – service set identifier . . . your wifi network name).  This is done in our examples as “connect_to_ssid”.  Notice that the command we structured will attempt to connect until receives a positive connection.  With many networks, you may need to try multiple times to connect.
  3. Done. You should see an IP Number flash across the Debug console. You’re now on the internet!

WEP

Connecting to a WEP (wired equivalent privacy) network is just as easy.

  1. Set the WEP Key: The WEP key is like a password.  We will set the key and the Wifi sensor will save it to temporary memory.
  1. Associate with the Network: WEP networks use an SSID.  When you call this command, you will specify the SSID you are connecting to.  The WEP key will be called on automatically behind the scenes.  Like the WPA network, you may need to try multiple times to connect.  We have a quick routine that retries until connected.
  1. Done. Again, you should see an IP number flash across the Debug Stream.  Your robot is now on the internet!

Examples:

Below are copies of the code we wrote for connecting the Wifi Sensor, in all their glorious comments.  We’ve tried to comment these examples well, but if we’re missing something, please let us know in the comments section.

DIWIFI-Connect_WEP.C

[sourcecode language=”cpp”]

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Setup for Wifi Sensor, and Associate with a WEP Network
//
// This scrip will connect the DI Wifi sensor to a WEP network. After connecting the
// NXT will query the network status and print it out on the debugging console.
//
// Output is in the debugging console of RobotC. So be sure to turn on the debugging console.
//
// You must replace the values of SSID and WEP_KEY for your system.
//
// For more information and documentation please see our website: http://dexterindustries.com/manual/wifi/
//
////////////////////////////////////////////////////////////////////////////////////////////////////////

#define DEBUG_WIFI 1
#ifdef DEBUG_WIFI
#define writeRawHS(X, Y) debugnxtWriteRawHS(X, Y)
#else
#define writeRawHS(X, Y) nxtWriteRawHS(X, Y)
#endif

// Declare the SSID we’re connecting to, character by character. Nothing at the end of the array.
ubyte ssid[] = {‘D’, ‘E’, ‘X’, ‘T’, ‘E’, ‘R’,’_’,’W’,’A’,’N’};
// Declaring the WEP_KEY: This example has a 26-digit WEP Key.
// If you have a 10-digit WEP Key, delete the extra spaces.
// Don’t put line returns at the end of this array.
ubyte wep_key[] = {‘*’,’*’,’*’,’*’,’5′,’*’,’5′,’*’,’5′,’*’,’5′,’*’,’5′,’*’,’4′,’*’,’5′,’*’,’4′,’*’,’5′,’*’,’5′,’*’,’5′,’*’}; // Space for 10 digit WEP key.

#include "drivers/common.h"

#include "DIWIFI-Connect_WEP.h"

void wifi_startup(){
config_wifi();
set_wep_key(1); // Setup the WEP key.
setDHCP(1); // Get us an IP number
wifi_auth_mode(1); // Set the authentication mode.
// 0 is none or WPA // 1 is Open network // 2 is Shared with WEP
associate_with_network(); // Connect to Wifi network

getInfo(); // Get current lan status.
getInfoWLAN(); // Get current lan status.

}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Main Task
//
////////////////////////////////////////////////////////////////////////////////////////////////////////

task main()
{
eraseDisplay();
bNxtLCDStatusDisplay = true; // Enable top status line display
wifi_startup();
PlaySound(soundBeepBeep); // Make some noise when we’re connected.
PlayTone(500, 100); // Make some noise when we’re connected.
}

[/sourcecode]

DIWIFI-Connect_WEP.H

[sourcecode language=”cpp”] ubyte BytesRead[8];
const ubyte newline[] = {0x0D};
typedef ubyte buff_t[128];
buff_t buffer;

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Setup High Speed on Port 4.
////////////////////////////////////////////////////////////////////////////////////////////////////////

void setupHighSpeedLink(const bool bMaster)
{
// Initialize port S$ to "high speed" mode.
nxtEnableHSPort();
nxtSetHSBaudRate(9600);
nxtHS_Mode = hsMsgModeMaster;
return;
}

void debugnxtWriteRawHS(const ubyte &pData, const short nLength)
{
string tmpString;
ubyte buff[30];
memset(buff[0], 0, 30);
memcpy(buff[0], pData, nLength);
StringFromChars(tmpString, buff);
writeDebugStream("%s", tmpString);
nxtWriteRawHS(pData, nLength);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Receive Bytes
// Reads whatever is in the buffer and prints to debug
////////////////////////////////////////////////////////////////////////////////////////////////////////

void Receive(bool wait=false)
{
if (wait)
while (nxtGetAvailHSBytes() == 0) wait1Msec(5);

while (nxtGetAvailHSBytes() > 0) {
nxtReadRawHS(BytesRead[0], 1);
writeDebugStream("%c", BytesRead[0]);
wait1Msec(2);
}
}

int appendToBuff(buff_t &buf, const long index, const ubyte &pData, const long nLength)
{
if (index == 0) memset(buf, 0, sizeof(buf));

memcpy(buf[index], pData, nLength);
return index + nLength;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Clear Read Buffer
// Run this to clear out the reading buffer.
// Simply sends a carriage return, then clears the buffer out.
////////////////////////////////////////////////////////////////////////////////////////////////////////

void clear_read_buffer()
{
ubyte nData[] = {13};
writeRawHS(nData[0], 1); // Send the carriage return
wait10Msec(100);
while(BytesRead[0] < 0){
nxtReadRawHS(BytesRead[0], 1); // Read the response. Probably an error.
}
wait10Msec(100);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Echo All Input Off – Turns off the echo effect on the wifi.
// Sending the serial command "ate0" which turns off the echo effect.
// Sends one single byte at a time, pauses.
// Drains receiver with a read each time.
////////////////////////////////////////////////////////////////////////////////////////////////////////

void echo_all_input_off()
{
writeDebugStreamLine("echo_all_input_off");
ubyte nData[] = {‘a’,’t’,’e’,’0′,13};

for(int i = 0; i < 5; i++){
writeRawHS(nData[i], 1); // Send the command, byte by byte.
nxtReadRawHS(BytesRead[0], 8); // Clear out the echo.
wait10Msec(10);
}

Receive(true);
eraseDisplay();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Software Flow Control On
// Send string "at&k1" and carriage return.
// Shouldn’t need the wait or read now that we’ve got the echo off.
////////////////////////////////////////////////////////////////////////////////////////////////////////
void software_flow_control()
{
writeDebugStreamLine("sfwr_flw_cntrl");
ubyte nData[] = {‘a’,’t’,’&’,’k’,’1′,13};
writeRawHS(nData[0], 6); // Send the command, byte by byte.
// wait10Msec(100);

Receive(true);
// wait10Msec(100);
}

//////////////////////////////////////////////////////////////////
// Configure the verbose mode of the wifi sensor.
// n = 0, verbose disabled.
// n = 1, verbose enable.
//////////////////////////////////////////////////////////////////
void set_verbose(int n)
{
if(n>1) n = 1; // Shouldn’t be larger than 1 so set it back.
n = n+48;
writeDebugStreamLine("set_verbose");
ubyte nData[] = {‘a’,’t’,’v’,n,13};
writeRawHS(nData[0], sizeof(nData)); // Send the command, byte by byte.
Receive(true);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Set the Infrastructure Mode.
// Send string "AT+WM = n" and carriage return.
// This sets the infrastructure mode as either infrastructure or ad-hoc network.
////////////////////////////////////////////////////////////////////////////////////////////////////////

void infrastructure_mode(int state)
{
writeDebugStreamLine("wifi_infra_mode.");
char state_n = state+48;
ubyte nData[] = {‘a’,’t’,’+’,’w’,’m’,’=’,state_n,13};
writeRawHS(nData[0], sizeof(nData)); // Send the command, byte by byte.
Receive(true);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Disassociate from any networks.
// Send string "AT+WD" and carriage return.
// This dissaciates from any networks we’re currently connected to.
////////////////////////////////////////////////////////////////////////////////////////////////////////

void disass()
{
writeDebugStream("discon_frm_networks");
ubyte nData[] = {‘a’,’t’,’+’,’w’,’d’,13};
writeRawHS(nData[0], sizeof(nData)); // Send the command, byte by byte.
writeRawHS(newline[0], sizeof(newline)); // send new line
Receive(true);
}

void set_network_config()
{
ubyte wpa_psk_cmd[] = {‘A’,’T’,’S’,’1′,’=’,’1′,’0′,’0′,’0′};
int index = 0;

index = appendToBuff(buffer, index, wpa_psk_cmd, sizeof(wpa_psk_cmd));
index = appendToBuff(buffer, index, newline, sizeof(newline));

writeRawHS(buffer[0], index);
Receive(true);
}

// Keep Association Alive for 20 Minutes
void Keep_Alive() {
int index = 0;
ubyte Keep_Alive_cmd[] = {‘A’,’T’,’+’,’P’,’S’,’P’,’O’,’L’,’L’,’I’,’N’,’T’,’R’,’L’,’=’,’1′,’2′,’0′,’0′};

index = appendToBuff(buffer, index, Keep_Alive_cmd, sizeof(Keep_Alive_cmd));
index = appendToBuff(buffer, index, newline, sizeof(newline));
writeRawHS(buffer[0], index);
Receive(true);
}

void max_transmit_power() {
writeDebugStreamLine("Set Max Xmit Power");
ubyte status_cmd[] = {‘a’,’t’,’+’,’W’,’P’,’=’, ‘7’, 13};
writeRawHS(status_cmd[0], sizeof(status_cmd)); // Send the command, byte by byte.
Receive(true);
}

void config_wifi(){

setupHighSpeedLink(true);
// Configure the link for raw read and write. User program will have complete control over the link.
// User program will be responsible for managing the half-duplex operation and must prevent collisions!
nxtHS_Mode = hsRawMode;

clear_read_buffer(); // Clear out the buffer and test TX/RX.
wait10Msec(100);
echo_all_input_off(); // Turn off serial echo.
software_flow_control(); // Turn on software flow control
set_verbose(1); // Turn on verbose responses.
infrastructure_mode(0); // Setup as infrastructure. 1 would be adhoc network. 0 is infrastructure.
disass(); // Disassociate from any networks we might be hooked to.
set_network_config();
Keep_Alive(); // Keep association with network alive.
max_transmit_power(); // Max transmit power . . . rock out and forget about the batteries.
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// WIFI: Set Authentication Mode
// Security of the wifi system we’re connecting to.
// Send string "at+wauth=<n>" and carriage return.
// n = 0 –> No security mode
// n = 1 –> Open security mode
// n = 2 –> Shared with WEP
////////////////////////////////////////////////////////////////////////////////////////////////////////

void wifi_auth_mode(int state)
{
writeDebugStreamLine("wifi_auth_mode");
char state_n = state+48;
ubyte nData[] = {‘a’,’t’,’+’,’w’,’a’,’u’,’t’,’h’,’=’,state_n,13};
writeRawHS(nData[0], sizeof(nData)); // Send the command, byte by byte.
//wait10Msec(100);
Receive(true);
//wait10Msec(100);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Dynamic Host Configuration Protocol
// Sends the command AT+NDHCP=<n>
// We’re gong to turn it on or turn it off. This will acquire an IP address automatically.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////

void setDHCP(int n)
{
writeDebugStreamLine("setDHCP");
ubyte dhcp_cmd[] = {‘a’,’t’,’+’,’N’,’D’,’H’,’C’,’P’, ‘=’, n+48, 13};
writeRawHS(dhcp_cmd[0], sizeof(dhcp_cmd)); // Send the command, byte by byte.
//wait10Msec(100);
//wait10Msec(400);
Receive(true);
//wait10Msec(00);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set the WEP Key
// Send string "AT+WWEPn=<10-DigitKey>" and carriage return.
// n is the key index (1 for each 10 characters)
// Sets the 10-digit WEP key.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////

void set_wep_key(int n){
writeDebugStreamLine("- – – – – – – – -");
writeDebugStreamLine("Set WEP Key");
int i_n = n+48; // Turn the int into a character.

ubyte wep_cmd[] = {‘A’,’T’,’+’,’W’,’W’,’E’,’P’,i_n,’=’}; //

int index = 0;
index = appendToBuff(buffer, index, wep_cmd, sizeof(wep_cmd)); // Put the WEP command into the buffer

//writeRawHS(buffer, index);
//index = 0;

index = appendToBuff(buffer, index, wep_key, sizeof(wep_key)); // Put the WEP Key into the buffer
index = appendToBuff(buffer, index, newline, sizeof(newline)); // Put a new line into the buffer.
writeRawHS(buffer, index); // Send the assembled buffer to the wifi sensor.

wait10Msec(100);
Receive();
}

bool Receive_connect(bool wait=false)
{
int i = 0;
ubyte Bytes_Error[128];
if (wait)
while (nxtGetAvailHSBytes() == 0) wait1Msec(5);

while (nxtGetAvailHSBytes() > 0) {
nxtReadRawHS(BytesRead[0], 1);
writeDebugStream("%c", BytesRead[0]);
wait1Msec(2);
Bytes_Error[i] = BytesRead[0];
i++;
}

writeDebugStream("%c", Bytes_Error[0]);
writeDebugStream("%c", Bytes_Error[1]);
writeDebugStream("%c", Bytes_Error[2]);
writeDebugStream("%c", Bytes_Error[3]);

if(Bytes_Error[2] == ‘E’ && Bytes_Error[3] == ‘R’){
return false;
}
return true;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Associate With Network
// Send string "AT+WA = <network name>" and carriage return.
// This will connect us to the wifi network.
////////////////////////////////////////////////////////////////////////////////////////////////////////

void associate_with_network() {
writeDebugStreamLine("- – – – – – – – -");
writeDebugStreamLine("assoc_w_network");
ubyte ssid_cmd[] = {‘a’,’t’,’+’,’W’,’A’,’=’};

int index = 0;
index = appendToBuff(buffer, index, ssid_cmd, sizeof(ssid_cmd));
index = appendToBuff(buffer, index, ssid, sizeof(ssid));
index = appendToBuff(buffer, index, newline, sizeof(newline));

writeRawHS(buffer, index);
while (nxtGetAvailHSBytes() == 0){
wait1Msec(5);
writeRawHS(newline, 0);
}
wait10Msec(100);
Receive();
wait10Msec(100);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Get Status
// Sends the command AT+NSTAT=?
// Upon deployment of this command, the adapter reports the current network configuration to the NXT
//
////////////////////////////////////////////////////////////////////////////////////////////////////////

void getInfo() {
writeDebugStreamLine("getInfo");
ubyte status_cmd[] = {‘a’,’t’,’+’,’N’,’S’,’T’,’A’,’T’, ‘=’, ‘?’, 13};
writeRawHS(status_cmd[0], sizeof(status_cmd)); // Send the command, byte by byte.

wait10Msec(100);
Receive();
wait10Msec(100);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Get LAN Information
// Sends the command AT+WSTATUS=?
// Upon deployment of this command, the adapter reports the current network configuration to the NXT
//
////////////////////////////////////////////////////////////////////////////////////////////////////////

void getInfoWLAN() {
writeDebugStreamLine("getInfo");
ubyte status_cmd[] = {‘a’,’t’,’+’,’W’,’S’,’T’,’A’,’T’,’U’,’S’, 13};
writeRawHS(status_cmd[0], sizeof(status_cmd)); // Send the command, byte by byte.
wait10Msec(100);
Receive();
wait10Msec(100);
}

[/sourcecode]

DIWIFI-Connect_WPA.C

[sourcecode language=”cpp”]

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Setup for Wifi Sensor, Associate with a WPA Network
//
// This scrip will connect the DI Wifi sensor to a WPA network. Output is in the debugging console of RobotC.
// Be sure to turn on the debugging console.
//
// You must replace the values of SSID and WPA_PAK
//
// For more information and documentation please see our website: http://dexterindustries.com/manual/wifi/
//
////////////////////////////////////////////////////////////////////////////////////////////////////////

#define DEBUG_WIFI 1
#ifdef DEBUG_WIFI
#define writeRawHS(X, Y) debugnxtWriteRawHS(X, Y)
#else
#define writeRawHS(X, Y) nxtWriteRawHS(X, Y)
#endif

// Declare the SSID and WPA_PSK we’re connecting to
ubyte ssid[] = {‘d’, ‘e’, ‘x’, ‘t’, ‘r’};
ubyte wpa_psk[] = {‘*’,’*’,’*’,’*’,’*’,’*’,’*’,’*’,’*’,’*’,’*’,’*’,’*’,’*’,’*’,’*’,’*’,’*’,’*’};

#include "drivers/common.h"
#include "DIWIFI-Connect_WPA.h"

void wifi_startup(){

config_wifi(); // This function sets up the wifi sensor for operation. Basic housekeeping.
wifi_auth_mode(2); // Set the authentication mode.
// 0 is none or WPA // 1 is Open network // 2 is Shared with WEP
setDHCP(1); // Get us an IP number
set_wpa_psk(); // Calculates your psk
Receive(true); // Housekeeping
Receive(true); // Housekeeping
connect_to_ssid(); // Connects to the wifi network you’ve designated
PlaySound(soundBeepBeep); // After connection, announce to the world you’re connected.
Receive(true); // Housekeeping.
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Main Task
////////////////////////////////////////////////////////////////////////////////////////////////////////

task main()
{
eraseDisplay();
bNxtLCDStatusDisplay = true; // Enable top status line display
wifi_startup(); // This is where the work is done.
PlaySound(soundBeepBeep); // Make some noise when we’re connected.
PlayTone(500, 100); // Make some noise when we’re connected.
}

[/sourcecode]

DIWIFI-Connect_WPA.H

[sourcecode language=”cpp”] ubyte BytesRead[8];
const ubyte newline[] = {0x0D};
typedef ubyte buff_t[128];
buff_t buffer;

long baudrates[] = {9600, 19200, 38400, 57600, 115200, 230400,460800, 921600};

// This function sends the array out Port 4.

void debugnxtWriteRawHS(const ubyte &pData, const short nLength)
{
string tmpString;
ubyte buff[30];
memset(buff[0], 0, 30);
memcpy(buff[0], pData, nLength);
StringFromChars(tmpString, buff);
writeDebugStream("%s", tmpString);
nxtWriteRawHS(pData, nLength);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Clear Read Buffer
// Run this to clear out the reading buffer.
// Simply sends a carriage return, then clears the buffer out.
////////////////////////////////////////////////////////////////////////////////////////////////////////

void clear_read_buffer()
{
ubyte nData[] = {13};
writeRawHS(nData[0], 1); // Send the carriage return
wait10Msec(100);
while(BytesRead[0] < 0){
nxtReadRawHS(BytesRead[0], 1); // Read the response. Probably an error.
}
wait10Msec(100);
}

/////////////////////////////////////////////////////////
//Scan Baud Rate – Scans the baud rate, sets up the sensor.
/////////////////////////////////////////////////////////
long scanBaudRate() {
ubyte tmpbuff[8];
string tmpString;
ubyte attention[] = {‘+’,’+’,’+’,13};
for (int i = 0; i < 8; i++) {
memset(tmpbuff, 0, sizeof(tmpbuff));
nxtDisableHSPort();
wait1Msec(10);
nxtEnableHSPort();
nxtSetHSBaudRate(baudrates[i]);
nxtHS_Mode = hsRawMode;
clear_read_buffer();
wait1Msec(1000);
nxtWriteRawHS(attention, sizeof(attention));
nxtReadRawHS(tmpbuff, 7); // make sure last ubyte is always NULL
StringFromChars(tmpString, tmpbuff);
if ((StringFind(tmpString, "ERR") > -1) ||
(StringFind(tmpString, "OK") > -1) ||
(StringFind(tmpString, "0") > -1) ||
(StringFind(tmpString, "2") > -1)) {
clear_read_buffer();
return baudrates[i];
}
}
clear_read_buffer();
return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Receive Bytes
// Reads whatever is in the buffer and prints to debug
////////////////////////////////////////////////////////////////////////////////////////////////////////

void Receive(bool wait=false)
{
if (wait)
while (nxtGetAvailHSBytes() == 0) wait1Msec(5);

while (nxtGetAvailHSBytes() > 0) {
nxtReadRawHS(BytesRead[0], 1);
writeDebugStream("%c", BytesRead[0]);
wait1Msec(2);
}
}

int appendToBuff(buff_t &buf, const long index, const ubyte &pData, const long nLength)
{
if (index == 0) memset(buf, 0, sizeof(buf));

memcpy(buf[index], pData, nLength);
return index + nLength;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Echo All Input Off – Turns off the echo effect on the wifi.
// Sending the serial command "ate0" which turns off the echo effect.
// Sends one single byte at a time, pauses.
// Drains receiver with a read each time.
////////////////////////////////////////////////////////////////////////////////////////////////////////

void echo_all_input_off()
{
writeDebugStreamLine("echo_all_input_off");
ubyte nData[] = {‘a’,’t’,’e’,’0′,13};

for(int i = 0; i < 5; i++){
writeRawHS(nData[i], 1); // Send the command, byte by byte.
nxtReadRawHS(BytesRead[0], 8); // Clear out the echo.
wait10Msec(10);
}

Receive(true);
eraseDisplay();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Software Flow Control On
// Send string "at&k1" and carriage return.
// Shouldn’t need the wait or read now that we’ve got the echo off.
////////////////////////////////////////////////////////////////////////////////////////////////////////
void software_flow_control()
{
writeDebugStreamLine("sfwr_flw_cntrl");
ubyte nData[] = {‘a’,’t’,’&’,’k’,’1′,13};
writeRawHS(nData[0], 6); // Send the command, byte by byte.
// wait10Msec(100);

Receive(true);
// wait10Msec(100);
}

//////////////////////////////////////////////////////////////////
// Configure the verbose mode of the wifi sensor.
// n = 0, verbose disabled.
// n = 1, verbose enable.
//////////////////////////////////////////////////////////////////
void set_verbose(int n)
{
if(n>1) n = 1; // Shouldn’t be larger than 1 so set it back.
n = n+48;
writeDebugStreamLine("set_verbose");
ubyte nData[] = {‘a’,’t’,’v’,n,13};
writeRawHS(nData[0], sizeof(nData)); // Send the command, byte by byte.
Receive(true);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Set the Infrastructure Mode.
// Send string "AT+WM = n" and carriage return.
// This sets the infrastructure mode as either infrastructure or ad-hoc network.
////////////////////////////////////////////////////////////////////////////////////////////////////////

void infrastructure_mode(int state)
{
writeDebugStreamLine("wifi_infra_mode.");
char state_n = state+48;
ubyte nData[] = {‘a’,’t’,’+’,’w’,’m’,’=’,state_n,13};
writeRawHS(nData[0], sizeof(nData)); // Send the command, byte by byte.
Receive(true);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// Disassociate from any networks.
// Send string "AT+WD" and carriage return.
// This dissaciates from any networks we’re currently connected to.
////////////////////////////////////////////////////////////////////////////////////////////////////////

void disass()
{
writeDebugStream("discon_frm_networks");
ubyte nData[] = {‘a’,’t’,’+’,’w’,’d’,13};
writeRawHS(nData[0], sizeof(nData)); // Send the command, byte by byte.
writeRawHS(newline[0], sizeof(newline)); // send new line
Receive(true);
}

void set_network_config()
{
ubyte wpa_psk_cmd[] = {‘A’,’T’,’S’,’1′,’=’,’1′,’0′,’0′,’0′};
int index = 0;

index = appendToBuff(buffer, index, wpa_psk_cmd, sizeof(wpa_psk_cmd));
index = appendToBuff(buffer, index, newline, sizeof(newline));

writeRawHS(buffer[0], index);
Receive(true);
}

// Keep Association Alive for 20 Minutes
void Keep_Alive() {
int index = 0;
ubyte Keep_Alive_cmd[] = {‘A’,’T’,’+’,’P’,’S’,’P’,’O’,’L’,’L’,’I’,’N’,’T’,’R’,’L’,’=’,’1′,’2′,’0′,’0′};

index = appendToBuff(buffer, index, Keep_Alive_cmd, sizeof(Keep_Alive_cmd));
index = appendToBuff(buffer, index, newline, sizeof(newline));
writeRawHS(buffer[0], index);
Receive(true);
}

void max_transmit_power() {
writeDebugStreamLine("Set Max Xmit Power");
ubyte status_cmd[] = {‘a’,’t’,’+’,’W’,’P’,’=’, ‘7’, 13};
writeRawHS(status_cmd[0], sizeof(status_cmd)); // Send the command, byte by byte.
Receive(true);
}

void config_wifi(){

scanBaudRate(); // This function scans the baud rate and sets up the server. You can also call the "setupHighSpeedLink" function
// if you want a specific baud rate. If the baud rate of the wifi sensor was a different rate, this will
// connect the sensor to the wifi server.
// Configure the link for raw read and write. User program will have complete control over the link.
// User program will be responsible for managing the half-duplex operation and must prevent collisions!
nxtHS_Mode = hsRawMode;

clear_read_buffer(); // Clear out the buffer and test TX/RX.
wait10Msec(100);
echo_all_input_off(); // Turn off serial echo.
software_flow_control(); // Turn on software flow control
set_verbose(1); // Turn on verbose responses.
infrastructure_mode(0); // Setup as infrastructure. 1 would be adhoc network. 0 is infrastructure.
disass(); // Disassociate from any networks we might be hooked to.
set_network_config();
Keep_Alive(); // Keep association with network alive.
max_transmit_power(); // Max transmit power . . . rock out and forget about the batteries.
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// WIFI: Set Authentication Mode
// Security of the wifi system we’re connecting to.
// Send string "at+wauth=<n>" and carriage return.
// n = 0 –> No security mode
// n = 1 –> Open security mode
// n = 2 –> Shared with WEP
////////////////////////////////////////////////////////////////////////////////////////////////////////

void wifi_auth_mode(int state)
{
writeDebugStreamLine("wifi_auth_mode");
char state_n = state+48;
ubyte nData[] = {‘a’,’t’,’+’,’w’,’a’,’u’,’t’,’h’,’=’,state_n,13};
writeRawHS(nData[0], sizeof(nData)); // Send the command, byte by byte.
//wait10Msec(100);
Receive(true);
//wait10Msec(100);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Dynamic Host Configuration Protocol
// Sends the command AT+NDHCP=<n>
// We’re gong to turn it on or turn it off. This will acquire an IP address automatically.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////

void setDHCP(int n)
{
writeDebugStreamLine("setDHCP");
ubyte dhcp_cmd[] = {‘a’,’t’,’+’,’N’,’D’,’H’,’C’,’P’, ‘=’, n+48, 13};
writeRawHS(dhcp_cmd[0], sizeof(dhcp_cmd)); // Send the command, byte by byte.
//wait10Msec(100);
//wait10Msec(400);
Receive(true);
//wait10Msec(00);
}

void set_wpa_psk()
{
ubyte wpa_psk_cmd[] = {‘A’,’T’,’+’,’W’,’P’,’A’,’P’,’S’,’K’,’=’};
unsigned byte dummy[] = {‘,’};
int index = 0;

index = appendToBuff(buffer, index, wpa_psk_cmd, sizeof(wpa_psk_cmd));
index = appendToBuff(buffer, index, ssid, sizeof(ssid));
index = appendToBuff(buffer, index, dummy, sizeof(dummy));
index = appendToBuff(buffer, index, wpa_psk, sizeof(wpa_psk));
index = appendToBuff(buffer, index, newline, sizeof(newline));

writeRawHS(buffer[0], index);
}

bool Receive_connect(bool wait=false)
{
int i = 0;
ubyte Bytes_Error[128];
if (wait)
while (nxtGetAvailHSBytes() == 0) wait1Msec(5);

while (nxtGetAvailHSBytes() > 0) {
nxtReadRawHS(BytesRead[0], 1);
writeDebugStream("%c", BytesRead[0]);
wait1Msec(2);
Bytes_Error[i] = BytesRead[0];
i++;
}

writeDebugStream("%c", Bytes_Error[0]);
writeDebugStream("%c", Bytes_Error[1]);
writeDebugStream("%c", Bytes_Error[2]);
writeDebugStream("%c", Bytes_Error[3]);

if(Bytes_Error[2] == ‘E’ && Bytes_Error[3] == ‘R’){
return false;
}
return true;
}

void set_ssid() {
ubyte ssid_cmd[] = {‘A’,’T’,’+’,’W’,’A’,’=’};
int index = 0;

index = appendToBuff(buffer, index, ssid_cmd, sizeof(ssid_cmd));
index = appendToBuff(buffer, index, ssid, sizeof(ssid));
index = appendToBuff(buffer, index, newline, sizeof(newline));
writeRawHS(buffer, index);
}

// This repeatedly tries to connect until succesful.
void connect_to_ssid(){
disass();
bool quit = false;
while(quit == false){
set_ssid();
quit = Receive_connect(true);
}
}

[/sourcecode]

9 Comments

  1. This tutorial is very very good. Got up and running very quickly
    One error I noticed with the WPA exampe is the wifi_auth_mode(2); shoud be wifi_auth_mode(0);

    So excited now. Planning to take over the world now!

  2. ray holt July 29, 2012

    Can two wifi modules be connected to the same router? can more than two? I would like to have four robots each running robotc from a remote gameport via the internet playing a playfield game such as soccer.. Is that possible with 4 wifi modules and one router?

    thanks, Ray

    • Dexter Industries July 30, 2012

      Hello Ray,
      Yes, multiple WIFI units can connect to the same network. The number of wifi devices that can connect depends on your router/wifi station, but in general most can handle multiple WIFI connections. You should be able to connect 4 WIFI modules and control them as you suggest. If you end up doing this project, please let us know, it sounds really fantastic!

  3. ray holt August 8, 2012

    I will be assigning this as a project for my senior high school robotics students. It will be a one year project. I will keep in touch and I am sure they will also make contact.

  4. Dexter Industries August 8, 2012

    Ray, We look forward to hearing from them this year. Please do have them reach out.

    Best,

    John

  5. kevin October 17, 2012

    Hi can you provide some example of how to use it on RobotC 3.51 version

  6. Redouan November 10, 2012

    Hi everybody,

    I have been searching for almost a week to find out how the dwifi is working. I don’t get it. So please can somebody help this nOOb.

    Here are my questions;

    1)
    I don’t know nothing about “at commands”. Where in windows of mac can I input those kinds of commands? Can I put those command in a shell terminal? How to setup a connection with the NXT dwifi??

    2)
    Can I confige the dWifi also without the bluetooth but over the USB connection?

    I hope anyone can help this beginner..

    • Dexter Industries November 27, 2012

      Redouan,

      The WIFI sensor is made to work with the LEGO MINDSTORMS NXT. Unfortunately, you can’t connect it to your computer via USB. Take a look at most of our examples throughout the website: there are a lot of great examples for RobotC and the WIFI sensor. You hook the WIFI sensor to Port 4, and you should be able to run these examples.

Leave a reply