I need to set a static IP on a Photon

I have an application that is going to be used with a special server that does not support DHCP and is just looking for a TCP client to connect to it at on a specific port. The server has a fixed IP address associated with it. But I don’t see a firmware function which will allow me to set a static IP on the Photon or any IP that is within the 255.255.255.0 mask for this particular server.

This is the idea behind this application. I think the sequence is reasonable.

This application will be preprogrammed with the SSID, Password, and Security Type of this special server (it acts as an access point and server). The Photon app will start off operating in Manual Mode since there is no cloud connection initially (that special server is not connected to the Internet). It is just making a TCP client connection to this special server to gather data. Upon capturing the data required it will clear the credentials, set it to another preprogrammed SSID for a router which will enable it to connect to the Internet. The application will call Spark.connect() when it is ready to connect to the Particle cloud and make its own calls to Spark.process() since it will be set to operate in Manual Mode [SYSTEM_MODE(MANUAL);]. It can then publish the data it collected from the special server, up to the Particle cloud.

But the first part is managing to insure the Photon is in the same IP range as this access point/server so it can make a client connection to the server at the servers fixed IP address and port number.

This can be seen as a bump to this thread (where I added a link to this one here)
Static IP (not static dynamic) [RESOLVED]

Maybe @mdma can comment.

I have coded this but it’s not slated for integration until 0.4.5, until it’s had more testing. If you’d like to help test, please see https://github.com/spark/firmware/pull/451

Hi mdma,

Yes I would be interested in Beta testing the ability to bypass DNS requests and to set a static IP in the Photon. But since I have not built a firmware project I would like to ask if you can prepare an image that I can flash onto my Photon? I am not sure if your code can be integrated with firmware v0.4.3 or would just be a Beta of the v0.4.5 which was planning to have this capability added.

I noted in the code that there is a wan_set_ip_source() that is set to STATIC_IP or DYMANIC_IP to determine if a DNS will be used or a static IP set. Have any high level calls been established from Photon application code to call. For example a WiFi.set_ip_source() or WiFi.set_ip_address()?

One last question. The last time I updated to v0.4.3 I was unable to find a DFU driver for Windows 7 to reflash using DFU-Util. I ended up using CLI to flash v.0.4.3. Can you tell me where I can find the ,inf file associated with the DFU driver for the USB on Win 7?

I believe this feature was completely implemented but I can't get my Photon to use a static IP. I'm running in SEMI_AUTOMATIC mode, and have tried running....

WiFi.setStaticIP(myAddress, netmask, gateway, dns);
WiFi.useStaticIP();

before and after WIFI is turned on, but WIFI is constantly grabbing a DHCP address. I am clearing credentials at every boot, setting new credentials and then calling...

WiFi.connect(WIFI_CONNECT_SKIP_LISTEN);

Is this related to not getting a static IP? I'm clearing credentials because I want to use credentials stored on microSD.

@mdma Can you confirm this feature should be active? If so, when should setStaticIP and useStaticIP be called in conjunction with setCredentials?

Yes, the feature is active, has been available since 0.4.5. What version of system firmware are you using?

@mdma I am on system firmware 0.4.7.

I’ve stripped down my sketch to the bare essentials. Could you please try running this after replacing the WIFI credentials & desired Static IP near the top of the networkConnect() function? Connect to console when you see the blue D7 LED light up and it should report everything there. Does it use your Static IP?

SYSTEM_MODE(SEMI_AUTOMATIC);

#define STATUS_LED D7

//Global variables
boolean useStaticIP = true;

void setup(void) {
  // debug LED setup
  pinMode(STATUS_LED, OUTPUT);
  digitalWrite(STATUS_LED, HIGH);

  Time.zone(-8);
  delay(5000);
  Serial.begin(57600);
  delay(2000);
  Serial.println("Hello there!");

  // read wifi .INI and connect to network
  networkConnect();
}

void loop() {

}

void networkConnect()
{
  char networkSSID[33] = "mySSID";
  char networkPass[65] = "myPass";

  // WLAN_SEC_UNSEC = 0
  // WLAN_SEC_WEP = 1
  // WLAN_SEC_WPA = 2
  // WLAN_SEC_WPA2 = 3
  int authValue = 3;

  // WLAN_CIPHER_NOT_SET = 0
  // WLAN_CIPHER_AES = 1
  // WLAN_CIPHER_TKIP = 2
  // WLAN_CIPHER_AES_TKIP = 3
  int cipherValue = 1;

  uint8_t serverIP[] = {192, 168, 1, 150};
  IPAddress myAddress = serverIP;
  uint8_t serverNM[] = {255, 255, 255, 0};
  IPAddress netmask = serverNM;
  uint8_t serverGW[] = {192, 168, 1, 1};
  IPAddress gateway = serverGW;
  uint8_t serverDNS[] = {192, 168, 1, 1};
  IPAddress dns = serverDNS;

  // Static IP or DHCP?
  if (useStaticIP)
  {
    Serial.print("Using Static IP Address: ");
    Serial.print(serverIP[0]);
    Serial.print(".");
    Serial.print(serverIP[1]);
    Serial.print(".");
    Serial.print(serverIP[2]);
    Serial.print(".");
    Serial.println(serverIP[3]);
    WiFi.setStaticIP(myAddress, netmask, gateway, dns);
    WiFi.useStaticIP();
  }
  else Serial.println("Using DHCP");

  if (Spark.connected() == false) {
    Serial.println("WiFi On...");
    WiFi.on();
    Serial.println("Clearing Credentials...");
    WiFi.clearCredentials();

    Serial.println("Setting Credentials...");
    // set Credentials
    if (authValue > -1 && cipherValue > -1)
    {
      WiFi.setCredentials(networkSSID, networkPass, authValue, cipherValue);
    }
    else if (authValue > -1)
    {
      WiFi.setCredentials(networkSSID, networkPass, authValue);
    }
    else WiFi.setCredentials(networkSSID, networkPass);
    WiFi.connect(WIFI_CONNECT_SKIP_LISTEN);
    if (WiFi.hasCredentials())
    {
      Serial.println("We have Credentials! Connecting to Cloud...");
      Spark.connect();
      while(!Spark.connected())
      {
        Particle.process();
      }
      Serial.println("Connected to:");
      Serial.println(WiFi.localIP());
      Serial.println(WiFi.subnetMask());
      Serial.println(WiFi.gatewayIP());
      Serial.println(WiFi.SSID());
    }
    else Serial.println("We have NO Credentials.");
  }
  Serial.println("---");
  Serial.print("deviceID: ");
  String myID = System.deviceID();
  Serial.println(myID);
  Serial.printlnf("System version: %s", System.version().c_str());
  uint32_t freemem = System.freeMemory();
  Serial.print("free memory: ");
  Serial.println(freemem);
}
1 Like

Have you ever tried, not to perform

WiFi.setCredentials();
WiFi.setStaticIP();
WiFi.useStaticIP();

Since these settings are persisted in flash, you’d not need to do it each time and maybe not doing it once, might be a good check if it made a difference.

1 Like

@ScruffR I’m clearing & setting credentials on boot to ensure that ones stored on SD are always used.

I’ve read that part, but just for testing give it try.

It might not be an issue really, but flash wear might be something to consider too.
We had a case where a user did run into some condition where his code kept doing such a thing inadvertently in a loop causing his device to wear out being unable to reprogram it.

1 Like

@ScruffR I disabled

WiFi.clearCredentials();
WiFi.setCredentials();
WiFi.setStaticIP();
WiFi.useStaticIP();

And, sure enough, it worked. It used the last Static IP that I had assigned in a previous flash. This is obviously not ideal for my purposes though. I need the end user to be able to assign a Static IP and have it work on boot.

You can do that, just rethink the way how you do it.

e.g. if your user has inserted an SD card with a settings file, just do your stuff, remove/rename the setup file and reboot.
Since the file is gone, you won’t do the same thing again but start your normal work.

Does my implementation sketch above not work by design, or is this a bug? If it’s a bug, I’d rather see it fixed and not ask my end users to work around it.

There might be a misunderstanding.
Elite users are no Particle employees, so I’m just helping another use to get the problem solved.
You are not my customer :wink:

But if you want Particle’s official view if this is a bug, we can ping @mdma

No misunderstanding. I appreciate the workaround idea and didn’t mean to sound demanding. Thank you for suggesting a reboot to force the new settings to take. Hopefully that will shed some light for @MDMA to weigh in on the issue.

Thanks for your patience in waiting for a resolution here. The test app was very helpful - that helped resolve the issue within a few minutes. A fix will be part of the 0.4.9 release.

I’d like to re-iterate that calling clearCredentials()/setCredentials() on each boot will cause considerable flash wear. The application should take steps to determine when the credentials have in fact changed, and only then clear and change the credentials.

3 Likes

I’m amending my code to avoid flash wear. Do calls to either…

WiFi.useStaticIP();
WiFi.useDynamicIP();

…cause wear if one is called repeatedly, or is it safe to call every boot cycle? I know the setting is stored in flash, but I’m not sure whether it’s re-written or only updated when necessary.

It’s safe to use on each boot.

1 Like