# Photon operation w/o cloud connection

**URL:** <https://community.particle.io/t/photon-operation-w-o-cloud-connection/39852>\
**Category:** Troubleshooting\
**Created:** [February 23, 2018, 6:11pm UTC](https://community.particle.io/t/photon-operation-w-o-cloud-connection/39852 "2018-02-23T18:11:01Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![WoobaGooba](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/woobagooba/32/16369_2.png) [@WoobaGooba](https://community.particle.io/u/WoobaGooba)\
**Post date:** [February 23, 2018, 6:11pm UTC](https://community.particle.io/t/photon-operation-w-o-cloud-connection/39852/1 "2018-02-23T18:11:01Z")

</div>

Folks. Can someone point me at a best practice example for a non cloud connected Photon joining my local WiFi network and obtaining an IP address? I’m finding the forum and documentation to be lacking clarity. Thanks

---

<div class="post-metadata">

**Author:** ![rickkas7](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/rickkas7/32/8681_2.png) [@rickkas7](https://community.particle.io/u/rickkas7)\
**Post date:** [February 23, 2018, 6:53pm UTC](https://community.particle.io/t/photon-operation-w-o-cloud-connection/39852/2 "2018-02-23T18:53:11Z")

</div>

# Using a Photon without Wi-Fi

In its default configuration (system mode AUTOMATIC without system threading), the Photon requires a Wi-Fi connection to operate, and won’t even run your user firmware.

This is just the default configuration, however, and there are numerous ways to use the Photon without Wi-Fi or the cloud.

## Running with or without cloud

The easiest way to make your code run whether you have Wi-Fi or a cloud connection is to use [SYSTEM\_THREAD](https://docs.particle.io/reference/firmware/#system-thread) mode.

```auto
SYSTEM_THREAD(ENABLED);

```

You insert this at the top of your source file. What it does is run the cloud processing in a separate system thread and your code will run regardless of whether you have a connection or not.

The only thing to be careful is that when you do this, your loop code will run before connected to the cloud. Because of this, it’s useful to check for a connection before publishing events:

You might also do something like this in loop() when using [Particle.publish](https://docs.particle.io/reference/firmware/photon/#particle-publish-):

```auto
if (Particle.connected()) {
	Particle.publish("myEvent", PRIVATE);
}

```

The same should be done for [Particle.subscribe](https://docs.particle.io/reference/firmware/photon/#particle-subscribe-).

It’s not necessary to check before [Particle.variable](https://docs.particle.io/reference/firmware/photon/#particle-variable-) or [Particle.function](https://docs.particle.io/reference/firmware/photon/#particle-function-). These should always be made early in setup() and should not wait for a cloud connection.

## Running with Wi-Fi off

If you don’t intend to use Wi-Fi at all, you can turn it off using the [MANUAL system mode](https://docs.particle.io/reference/firmware/photon/#manual-mode).

```auto
SYSTEM_MODE(MANUAL);

```

When you do this, the Photon will breathe white instead of cyan (light blue) and will not attempt to connect to the cloud.

If you want to over-the-air (OTA) flash your Photon with new code, you can use [Safe Mode](https://docs.particle.io/guide/getting-started/modes/photon/#safe-mode).

Press RESET and SETUP at the same time. Release RESET and continue to hold down SETUP until the status LED blinks magenta (red and blue at the same time). Release SETUP.

Safe mode connects to the cloud but does not run your user firmware, so Wi-Fi and the cloud connection will stay on so you can do an OTA flash.

## Running with Wi-Fi but no cloud

It’s also possible to run the Photon with Wi-Fi enabled but no cloud connection. You might do this if you are using the Photon on an isolated network, not connected to the Internet, but you still have a Wi-Fi access point to connect to.

This mode allows communication between devices on the local Wi-Fi network using [TCP](https://docs.particle.io/reference/firmware/photon/#tcpclient) or [UDP](https://docs.particle.io/reference/firmware/photon/#udp). You can’t use things like [Particle.publish](https://docs.particle.io/reference/firmware/photon/#particle-publish-) without cloud access.

To do this you’ll probably use [SEMI\_AUTOMATIC system mode](https://docs.particle.io/reference/firmware/photon/#semi-automatic-mode), though sometimes you may prefer MANUAL.

```auto
SYSTEM_MODE(SEMI_AUTOMATIC);

```

In your setup() function, you’ll probably use [WiFi.connect](https://docs.particle.io/reference/firmware/photon/#connect-).

```auto
WiFi.on();
WiFi.connect();

```

This will connect Wi-Fi only, not the cloud, and you’ll get breathing green instead of breathing cyan (light blue).

## Running with SoftAP

In SoftAP mode, the Photon itself acts as a Wi-Fi access point. In this mode, another computer or phone can connect to the Photon Wi-Fi (“Photon-XXXX”) and communicate data directly by using [TCP](https://docs.particle.io/reference/firmware/photon/#tcpclient) or [UDP](https://docs.particle.io/reference/firmware/photon/#udp). You can’t use things like [Particle.publish](https://docs.particle.io/reference/firmware/photon/#particle-publish-) without cloud access.

To do this, you’ll need to use [SYSTEM\_THREAD](https://docs.particle.io/reference/firmware/#system-thread) mode.

```auto
SYSTEM_THREAD(ENABLED);

```

You’ll also need to probably use [SEMI\_AUTOMATIC system mode](https://docs.particle.io/reference/firmware/photon/#semi-automatic-mode), though sometimes you may prefer MANUAL.

```auto
SYSTEM_MODE(SEMI_AUTOMATIC);

```

In your setup() function, you’ll probably use [WiFi.listen](https://docs.particle.io/reference/firmware/photon/#listen-).

```auto
WiFi.on();
WiFi.listen();

```

In listening mode, the Photon will blink dark blue.

---

<div class="post-metadata">

**Author:** ![WoobaGooba](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/woobagooba/32/16369_2.png) [@WoobaGooba](https://community.particle.io/u/WoobaGooba)\
**Post date:** [February 23, 2018, 7:55pm UTC](https://community.particle.io/t/photon-operation-w-o-cloud-connection/39852/3 "2018-02-23T19:55:06Z")

</div>

> [@rickkas7](#):
>
> Running with Wi-Fi but no cloud  
> It’s also possible to run the Photon with Wi-Fi enabled but no cloud connection. You might do this if you are using the Photon on an isolated network, not connected to the Internet, but you still have a Wi-Fi access point to connect to.
> 
> This mode allows communication between devices on the local Wi-Fi network using TCP or UDP. You can’t use things like Particle.publish without cloud access.
> 
> To do this you’ll probably use SEMI\_AUTOMATIC system mode, though sometimes you may prefer MANUAL.
> 
> SYSTEM\_MODE(SEMI\_AUTOMATIC);
> 
> In your setup() function, you’ll probably use WiFi.connect.
> 
> WiFi.on();  
> WiFi.connect();
> 
> This will connect Wi-Fi only, not the cloud, and you’ll get breathing green instead of breathing cyan (light blue).

No joy. I've got a Photon breathing green and reporting IP address of 0.0.0.0. Same result for both system MANUAL and SEMI\_AUTOMATIC modes.

```
SYSTEM_MODE(SEMI_AUTOMATIC);

void setup() {
    
    // Serial debug
    //
    Serial.begin(9600);
    
    // Connect to WiFi
    //
    WiFi.on();
    WiFi.connect();
    while (!WiFi.ready())
    {
        Serial.println("WiFi not yet ready");
        delay(1000);
    }

```

---

<div class="post-metadata">

**Author:** ![rickkas7](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/rickkas7/32/8681_2.png) [@rickkas7](https://community.particle.io/u/rickkas7)\
**Post date:** [February 23, 2018, 7:57pm UTC](https://community.particle.io/t/photon-operation-w-o-cloud-connection/39852/4 "2018-02-23T19:57:01Z")

</div>

Where did you check the WiFi.localIP()? I’ve found that you need to wait about 500 milliseconds after WiFi.ready() before it becomes valid.

---

<div class="post-metadata">

**Author:** ![WoobaGooba](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/woobagooba/32/16369_2.png) [@WoobaGooba](https://community.particle.io/u/WoobaGooba)\
**Post date:** [February 23, 2018, 8:04pm UTC](https://community.particle.io/t/photon-operation-w-o-cloud-connection/39852/5 "2018-02-23T20:04:11Z")

</div>

Immediately after the code snippet I posted. Per the reference documentation …

```
ready()

This function will return true once the device is connected to the network and has been assigned an IP address, which means that it's ready to open TCP sockets and send UDP datagrams. Otherwise it will return false.
```

---

<div class="post-metadata">

**Author:** ![WoobaGooba](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/woobagooba/32/16369_2.png) [@WoobaGooba](https://community.particle.io/u/WoobaGooba)\
**Post date:** [February 23, 2018, 8:53pm UTC](https://community.particle.io/t/photon-operation-w-o-cloud-connection/39852/6 "2018-02-23T20:53:42Z")

</div>

Joy ... but either WiFi.ready() or its documentation needs correction.

> SYSTEM\_MODE(SEMI\_AUTOMATIC);
> 
> void setup() {
> 
> ```
> // Serial debug
> //
> Serial.begin(9600);
> 
> // Connect to WiFi
> //
> WiFi.on();
> WiFi.connect();
> while (!WiFi.ready())
> {
> Serial.println("WiFi not yet ready");
> delay(1000);
> }
> 
> while(true)
> {
> localIP = WiFi.localIP();        
> if (localIP[0] != 0) break;
> Serial.println("IP not yet ready");        
> delay(1000);
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![bko](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/bko/32/20704_2.png) [@bko](https://community.particle.io/u/bko)\
**Post date:** [February 23, 2018, 9:02pm UTC](https://community.particle.io/t/photon-operation-w-o-cloud-connection/39852/7 "2018-02-23T21:02:41Z")

</div>

Hi @WoobaGooba

I agree that the doc is not clear, but under the hood, both things can be true. localIP is just a cache of what is in the WiFi chip and the cache may not be correct for some time after you connect. So the system is really ready for connections when WiFi.ready() is true but the cache for the IP address does not get updated for some time.
