Jump to content
43oh

Switching the CC3200 from AP to Station mode


Recommended Posts

Been working on an application that would:

 

1. Start the CC3200 and setup a webserver on 192.168.1.1 on port 80.

2. The user connects to the WiFi networks created by the CC3200 and subsequently this webserver and enters their network credentials.

3. The CC3200 parses these credentials and stores it in a buffer called credential_buffer and the SSID and password are pointed to by accSSID and accPWD. 

 

I now want to use these credentials to connect to the users WiFi network and this is where I run aground. I swtich the CC3200 from the AP to STN mode using sl_WlanSetMode(ROLE_STA) but that does not seem to be working. Any ideas? The code is listed below: 

 

EDIT: I kinda found the solution here: http://forum.43oh.com/topic/6250-cc3200-cant-connect-to-wlan-after-being-set-as-ap/. However, this is not implemented in the recent Energia release. Any particular reason?

// AP credentials.
const char ssid[] = "MyCC3200AP";
const char wifipw[] = "password";

// Buffer for the new credentials acquired from the user.
char credential_buffer[MAX_STORE_BUFFER_LEN];

// pointers to the actual credential values in the buffer
char *accSSID;
char *accPWD;

boolean isConnected;

boolean connectCompleteFlag = false;

WiFiServer server(SERVER_PORT); // Server port is defined as 80

void setup()
{
  byte counter;
  unsigned long t_time;
  
  // Begin serial comms.
  Serial.begin(115200);

  // Switch OFF all LaunchPad LEDs.
  pinMode(RED_LED, OUTPUT);
  digitalWrite(RED_LED, LOW);

  pinMode(GREEN_LED, OUTPUT);
  digitalWrite(GREEN_LED, LOW);

  pinMode(YELLOW_LED, OUTPUT);
  digitalWrite(YELLOW_LED, LOW);

  // Setup an AP.
  Serial.print("Setting up Access Point named: ");
  Serial.println(ssid);
  Serial.print("AP uses WPA and password is: ");
  Serial.println(wifipw);
  
  WiFi.beginNetwork((char *)ssid, (char *)wifipw);

  while (WiFi.localIP() == INADDR_NONE) {
    // print dots while we wait for the AP config to complete
    Serial.print('.');
    delay(500);
  }

  Serial.println("AP active.");

  // start the web server on port 80
  server.begin();
  Serial.print("Webserver started on http://");
  Serial.print( WiFi.localIP() );
  Serial.print(" port: ");
  Serial.println(SERVER_PORT);
  Serial.println("\n");

  // Let the user connect to the webserver and enter their network credentials.
  // We exit this loop with the credentials stored in credential_buffer
  while (!connectCompleteFlag)
  {
    connectClient(); // This function reads credentials from the user and stores them in the credential_buffer.
  }
  
  // Try to connect to the new WiFi network
  counter = 0;

  // Disconnect first, if currently connected
  
  sl_WlanDisconnect();
  sl_WlanSetMode(ROLE_STA);
  
  Serial.print("Attempting to connect to WiFi network...");
  
  // Open connection to WiFi
  WiFi.begin(accSSID, accPWD);
  while ( WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
    counter++;
    if(counter==10)
    {
      break;
    }
  }
  
  if(counter==10)
  {
    Serial.println("\nUnable to connect to wifi");
    isConnected = false;
    failure_state(); // This function just blinks the red LED at 1 sec intervals indefinitely.
  }
  
  Serial.println("\nConnected to wifi");
  isConnected = true;  

  // Try to get local IP     
  Serial.print("Waiting for IP...");
  
  t_time = millis();

  while( WiFi.localIP() == INADDR_NONE )
  {
    Serial.print(".");
    delay(500);
    
    if( ( millis() - t_time ) > 5000 )
    {
      Serial.println("Timeout! Unable to get IP...");
      failure_state();
    }
  }

  // Print out local IP
  Serial.print("\nMy IP is: ");
  Serial.println( WiFi.localIP() );

}
Link to post
Share on other sites

OK I got this figured. The challenge was switching back to AP once STA mode was activated. This code switches back to AP from whatever earlier mode was set. 'ssid' and 'wifipw' is the SSID and password defined for the AP.

extern "C" {
    #include "utility/udma_if.h"
}

void switchToAP()
{
  UDMAInit();
  sl_Start(NULL, NULL, NULL);

  sl_WlanDisconnect();
  
  sl_NetAppMDNSUnRegisterService(0, 0);
  
  sl_WlanRxStatStart();

  sl_WlanSetMode(ROLE_AP);
  
  sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID, strlen(ssid),
                              (unsigned char *)ssid);
  
  unsigned char  val = SL_SEC_TYPE_WPA;
  sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, 1, (unsigned char *)&val);

  sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, strlen(wifipw),
                              (unsigned char *)wifipw);

  /* Restart Network processor */
  sl_Stop(30);

  sl_Start(NULL, NULL, NULL);
}

To switch to the STA mode it was suggested in an earlier post to add WiFi._initialized = false; and WiFi._connecting = false; before doing a WiFi.being() but this was a hit and miss with my LP (rev 4.1). So this code switches it to STA mode. This is still not very reliable. Out of every 6 attempts to connect to a WiFi network, 1 attempt fails but here is the code anyway:

void switchToSTA()
{
  UDMAInit();
  sl_Start(NULL, NULL, NULL);

  sl_WlanDisconnect();
  
  sl_NetAppMDNSUnRegisterService(0, 0);
  
  sl_WlanRxStatStart();
  
  sl_WlanSetMode(ROLE_STA);

  /* Restart Network processor */
  sl_Stop(30);

  sl_Start(NULL, NULL, NULL);
}

Link to post
Share on other sites
  • 5 months later...
  • 3 weeks later...

Here is my code ....

Everything is working as expected.

 

#include <WiFi.h>


#define AP_MODE  0
#define STA_MODE 1
#include <udma_if.h>
uint8_t mode = 0;


const char ssid[] = "CC3200";
const char wifipw[] = "password";


const char s[2] = "-";
char *token;


String y = "";
char Rssid[100],Rpsk[100];


unsigned int Port =2390;
char packetBuffer[255];
IPAddress Ip(255,255,255,255);
char b[1024];
int j=0;


WiFiUDP Udp;


void setup()
{
  Serial.begin(115200);
  pinMode(RED_LED, OUTPUT);
  pinMode(PUSH2, INPUT_PULLUP);
  if(WiFi.begin() !=WL_CONNECT_FAILED)
  {
  Serial.println("Connecting to stored profile");


    Serial.print("Connected to SSID: ");
    Serial.println(WiFi.SSID());


    while (WiFi.localIP() == INADDR_NONE) 
    {
      // print dots while we wait for an ip addresss
      Serial.print(".");
      delay(300);
    }


    Serial.println("\nIP Address obtained");
    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());


    mode = STA_MODE;
  }


}


void loop()
{ 
  if( digitalRead(PUSH2)) 
  {
    Serial.println("Starting AP Mode");
    mode = AP_MODE;
  Serial.print("Setting up Access Point named: ");
  Serial.println(ssid);
  Serial.print("AP uses WPA and password is: ");
  Serial.println(wifipw);
  
  WiFi.beginNetwork((char *)ssid, (char *)wifipw);


  while (WiFi.localIP() == INADDR_NONE) 
  {
    // print dots while we wait for the AP config to complete
    Serial.print('.');
    delay(300);
  }
  Serial.println();
  Serial.println("AP active.");
  printWifiStatus();
  digitalWrite(RED_LED,HIGH);
    // Your AP mode setup code goes here..
  } 
  if(mode==AP_MODE)
  {
  ap_loop();
  }
  if(mode==STA_MODE)
  {
  sta_loop();
  }
  
}


void sta_loop()
{
  // STA mode loop code goes here
}


void ap_loop()
{ Udp.begin(Port);
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    int len = Udp.read(packetBuffer, 255);
    if (len > 0)packetBuffer[len] = 0;
    //unit=atoi(packetBuffer);
    Serial.println(packetBuffer);
         
                 /* get the first token */
                token = strtok(packetBuffer, s);
                int w = 0;
   
                while( token != NULL ) 
               {
                  
                  if(w == 0)
                  {
                  strcpy(Rssid,token);
                  Serial.println(Rssid);
                  w++;
                  }
                  else if(w == 1)
                  {
                    strcpy(Rpsk,token);
                    Serial.println(Rpsk);
                  }
                  token = strtok(NULL, s);
               }


                /*int retVal;
                retVal = sl_WlanSetMode(ROLE_STA);
                retVal = sl_Stop(0);
                retVal= sl_Start(NULL, NULL, NULL);*/
               
               UDMAInit();
  sl_Start(NULL, NULL, NULL);


  sl_WlanDisconnect();
  
  sl_NetAppMDNSUnRegisterService(0, 0);
  
  sl_WlanRxStatStart();
  
  sl_WlanSetMode(ROLE_STA);


  // Restart Network processor 
  sl_Stop(30);


  sl_Start(NULL, NULL, NULL);
                  
                WiFi._initialized = false;
                WiFi._connecting = false;
                // attempt to connect to Wifi network:
                Serial.print("Attempting to connect to Network named: ");
                delay(1000);
                // print the network name (SSID);
                Serial.println(Rssid);
                //WiFi._initialized = false;
                //WiFi._connecting = false;
                // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
                WiFi.begin(Rssid, Rpsk);
                while ( WiFi.status() != WL_CONNECTED) 
                {
                  // print dots while we wait to connect
                  Serial.print(".");
                  delay(300);
                }


                Serial.println("\nYou're connected to the network");
                Serial.println("Waiting for an ip address");


                while (WiFi.localIP() == INADDR_NONE)
                {
                  // print dots while we wait for an ip addresss
                  Serial.print(".");
                  delay(300);
                }


                Serial.println("\nIP Address obtained");


                // you're connected now, so print out the status
                printWifiStatus();
                mode=STA_MODE;
}
}
void printWifiStatus() 
{
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  IPAddress ip = WiFi.localIP();
  sprintf(b,"%d.%d.%d.%d,",ip[0],ip[1],ip[2],ip[3] );
  Serial.print("IP Address: ");
  Serial.println(ip);
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...