Using the Cloud9 IDE for Particle Development

I’ve been using the Particle web IDE for 99.9% of my development ever since I received my first Core. However, it seems that development in the web IDE is so passé these days. All the cool kids are using the Particle CLI. The primary reason that I’ve been using the web IDE for so long is because it keeps everything in the cloud, so I don’t have to worry about synchronizing dropboxes or whatever across multiple computers. The Cloud9 IDE allows me to do both! It has a well-featured development environment with a command line as well! I’ve been using Cloud9 for the past several days and thoroughly enjoy it. It even takes less than 5 minutes to set up a workspace and flash code to your Particle cloud-enabled device!

Here’s a little sample of what it looks like:

Neat, isn’t it! But how? Here’s how!

  1. Sign up or log in to c9.io .

  2. Once logged in, create a new workspace (or use an existing one if you’d like).

  3. A dialog box will pop up. Name your workspace anything you’d like, select the desired privacy level, make sure Node.js is selected, and then click Create.

  4. Once the workspace has been created, select the workspace, and then click Start Editing.

  5. You should now be looking at the Cloud9 IDE in its full glory. If you’re like me, you may want to go ahead and close the opened README.md tab and delete everything under the root directory (named “particle” in my case). This will allow you to create your own clutter.

  6. At the bottom of the IDE, you should see a command line already opened. Go ahead and click in there to set focus so we can install and log in with the Particle CLI.

  7. In the command line, type: npm install -g particle-cli

  8. Wait a few seconds while all the requisites are installed. Once that finishes, type: particle login and provide your cloud login credentials.

  9. Now that you’ve gotten that out of the way, it’s time to flash some code! Look back towards the upper-left corner for your root directory, right-click on it, and select “New Folder”. Name the new folder anything you like. In this tutorial, I’ve named it “sample-project”.

  10. Now it’s time to create a file for your code. Right-click on the folder you created in the step above and select “New File”. Once again, name it anything you like. In this tutorial, I’ve named it “sample-project”.

  11. Double-click on the new file to open it for editing. You can write your own code or use the simple sketch at the bottom of this tutorial.

  12. (Optional) Syntax highlighting for *.ino files may not be enabled by default. You can fix this by opening the View menu in the IDE, hover over Syntax, and then select “C and C++”.

  13. Ready to compile and/or flash? I thought so. But first let’s go back to that command line. First, you’ll want to change to the correct directory. By default, you are in the “~/workspace” directory. To change to your project directory, type: cd sample-project. Be sure to change “sample-project” with whatever you named your folder from the step above.

  14. The moment of truth! Still in the command line, type: particle compile. This will send your file up to the Particle cloud, compile it, and download the binary output of the compile operation. If you use the sketch provided in this tutorial, you should see Compiled firmware downloaded. as the last line of output in the command line.

  15. Assuming all went well in the step above, you can flash the code to a device using particle flash YOUR_TARGET_DEVICE_ID .. After some flashing magenta on the device, you should see the D7 LED blinking at you. Congrats!

This just scratches the surface of what can be done with the Cloud9 IDE. There are “runners” that can help automate the compile and flash process, but I haven’t had the chance to really dig into it yet. I plan on providing some simple shell scripts that I have written to help alleviate the monotony of particle flash yadda yadda yadda in the future. (The scripts are already written, but I have to leave in a minute.)

If you aren’t familiar with the Particle CLI, check it out in the docs. I’d love to see any other tips or tricks other folks come up with!

Sample Sketch

void setup() {
    pinMode(D7, OUTPUT);
    digitalWrite(D7, LOW);
}


void loop() {
    digitalWrite(D7, HIGH);
    delay(500);

    digitalWrite(D7, LOW);
    delay(500);
}
13 Likes

Hi wgBartley

Thank you for all your sharing and effort. All the best

I still haven’t figured out the custom runners yet, but I have written some simple shell scripts to help save time typing. Some of these depend on a file named device_id (no extension) in your project directory. The contents of device_id should simply be the device ID of the target Core or Photon that you wish to flash. Save each of these in the root of your project’s directory. I have all of my projects in sub-directories of my workspace, so each project directory has a copy of these scripts.


compile.sh: Compiles current directory and saves it to an “output” sub-directory.

#!/bin/bash

if [ ! -d "$(pwd)/output)" ]; then
    mkdir "$(pwd)/output"
fi

particle compile `find . -type f -iname *.ino -or -iname *.h -or -iname *.c* -not -ipath */examples/*` --saveTo output/firmware_$(date +"%Y%m%d%H%M%S").bin

__verify.sh__: Compiles the current directory but does not save the output. This is handy when you just want to make sure your code compiles but don't want to save the output to disk. Technically it does save the compiled `.bin` file, but it deletes it immediately after compilation. ``` #!/bin/bash

if [ ! -d “$(pwd)/output)” ]; then
mkdir "$(pwd)/output"
fi

particle compile photon find . -type f -iname *.ino -or -iname *.h -or -iname *.c* -not -ipath */examples/* --saveTo output/firmware_$(date +"%Y%m%d%H%M%S").bin

<br>
__deploy.sh__: Flashes your project to the target device.  You could name this file something like `flash.sh` if you wanted, but I have used `deploy.sh` for tons of other projects, so this is just easier on me.  ;-)

#!/bin/bash

DEVICE_ID=$(cat device_id)

particle flash $DEVICE_ID find . -type f -iname *.ino -or -iname *.h -or -iname *.c* -not -ipath */examples/*

1 Like

Great work. I really appreciate this. Before reading this I tried loading the CLI directly on cloud9 from the github site at startup and it sort-of worked. Will try your tutorial today and see what I can do.,

@wgbartley, @MORA

I got your cloud9 particle site working and it is excellent to be able to setup the Particle CLI online very quickly. However it is not the way that I am used to using cloud9. I am used to installing from a github repository and then running

npm install  

and

npm start

and then you can run any of the particle CLI commands such as

particle help

particle list

particle webhook create myhook3.json

particle webhook list

So I threw together a github site that works but I am not sure if it is correct. Could you have a look at the package.json file @kennethlimcp ? (or show it to someone familiar with cloud9 and node.js)

The github site is at

and here is an image of the setup

1 Like

I don’t understand the need to do extra work.

Does npm install -g particle-cli not work?

1 Like

Good point. More like different ways to do the same thing. I try to simplify everything. The previous method sets up a working Nodejs chat program that you then have to delete, make a directory, make files. etc, but Cloud9 is actually a bit confusing for beginners to just make files as the directory structure is not very easy to spot where to put your files.

In the following image the files look like they are in the “node_modules” folder but they are actually in the “great-name” folder

My way just takes everything from the github repository and pre-sets up the entire directory structure.

npm install

Is a very normal command that many people using Nodejs will be familiar with. It activates a script in the package.json file. Here it simply runs

npm install -g particle-cli

Using cloud9 and “npm install” you can get hundreds of Nodejs programs installed automatically from github sites and operating in the few minutes to download all the supporting files. Compared to what I used to do where I would spend hours setting up a ubuntu server just to test out a new program, this method is amazing.


An example is a nodejs github site I made a while ago that lets you make Android and iOS live Apps that allow testing your phone accelerometer etc without paying the Apple $100/year developer fee by using the Adobe Phonegap Developer App.
My site is at

using the same steps as above you are up and running with an entire nodejs Javascript tutorial in a few minutes.

1 Like

does this still work for you? I’ve tried both @rocksetta and @wgbartley’s methods, but it doesnt work. I also upgraded npm + node.js versions, but still i just get compilation errors about missing definition for D7.

I added an include for application.h which obviously wasnt there, so I then cloned https://github.com/spark/firmware to a parent directory, and created a particle.include file:

*.cpp
*.h
*.ino
../../firmware/*/inc/*.h
../../firmware/*/inc/*.cpp
../../firmware/*/src/*.h
../../firmware/*/src/*.cpp

but i get this output which is entirely unhelpful…

mnbf9rca:~/workspace/owncode/sample (dev) $ particle compile o .

Compiling code for o

Including:
/home/ubuntu/workspace/owncode/sample/sample.ino
/home/ubuntu/workspace/firmware/dynalib/inc/dynalib.h
/home/ubuntu/workspace/firmware/dynalib/inc/module_info.h
/home/ubuntu/workspace/firmware/hal/inc/adc_hal.h
/home/ubuntu/workspace/firmware/hal/inc/cellular_hal.h
/home/ubuntu/workspace/firmware/hal/inc/concurrent_hal.h
/home/ubuntu/workspace/firmware/hal/inc/core_hal.h
/home/ubuntu/workspace/firmware/hal/inc/core_subsys_hal.h
/home/ubuntu/workspace/firmware/hal/inc/dac_hal.h
/home/ubuntu/workspace/firmware/hal/inc/delay_hal.h
/home/ubuntu/workspace/firmware/hal/inc/deviceid_hal.h
/home/ubuntu/workspace/firmware/hal/inc/dfu_hal.h
/home/ubuntu/workspace/firmware/hal/inc/eeprom_hal.h
/home/ubuntu/workspace/firmware/hal/inc/gpio_hal.h
/home/ubuntu/workspace/firmware/hal/inc/hal_dynalib_cellular.h
/home/ubuntu/workspace/firmware/hal/inc/hal_dynalib_concurrent.h
/home/ubuntu/workspace/firmware/hal/inc/hal_dynalib_core.h
/home/ubuntu/workspace/firmware/hal/inc/hal_dynalib_gpio.h
/home/ubuntu/workspace/firmware/hal/inc/hal_dynalib_i2c.h
/home/ubuntu/workspace/firmware/hal/inc/hal_dynalib_ota.h
/home/ubuntu/workspace/firmware/hal/inc/hal_dynalib_peripherals.h
/home/ubuntu/workspace/firmware/hal/inc/hal_dynalib_socket.h
/home/ubuntu/workspace/firmware/hal/inc/hal_dynalib_spi.h
/home/ubuntu/workspace/firmware/hal/inc/hal_dynalib_usart.h
/home/ubuntu/workspace/firmware/hal/inc/hal_dynalib_wlan.h
/home/ubuntu/workspace/firmware/hal/inc/hal_dynalib.h
/home/ubuntu/workspace/firmware/hal/inc/i2c_hal.h
/home/ubuntu/workspace/firmware/hal/inc/inet_hal.h
/home/ubuntu/workspace/firmware/hal/inc/interrupts_hal.h
/home/ubuntu/workspace/firmware/hal/inc/interrupts_irq.h
/home/ubuntu/workspace/firmware/hal/inc/memory_hal.h
/home/ubuntu/workspace/firmware/hal/inc/ota_flash_hal.h
/home/ubuntu/workspace/firmware/hal/inc/pinmap_hal.h
/home/ubuntu/workspace/firmware/hal/inc/product_store_hal.h
/home/ubuntu/workspace/firmware/hal/inc/pwm_hal.h
/home/ubuntu/workspace/firmware/hal/inc/rgbled_hal.h
/home/ubuntu/workspace/firmware/hal/inc/rng_hal.h
/home/ubuntu/workspace/firmware/hal/inc/rtc_hal.h
/home/ubuntu/workspace/firmware/hal/inc/servo_hal.h
/home/ubuntu/workspace/firmware/hal/inc/socket_hal.h
/home/ubuntu/workspace/firmware/hal/inc/spi_hal.h
/home/ubuntu/workspace/firmware/hal/inc/syshealth_hal.h
/home/ubuntu/workspace/firmware/hal/inc/timer_hal.h
/home/ubuntu/workspace/firmware/hal/inc/tone_hal.h
/home/ubuntu/workspace/firmware/hal/inc/usart_hal.h
/home/ubuntu/workspace/firmware/hal/inc/usb_config_hal.h
/home/ubuntu/workspace/firmware/hal/inc/usb_hal.h
/home/ubuntu/workspace/firmware/hal/inc/watchdog_hal.h
/home/ubuntu/workspace/firmware/hal/inc/wlan_hal.h
/home/ubuntu/workspace/firmware/rt-dynalib/inc/rt_dynalib.h
/home/ubuntu/workspace/firmware/services/inc/appender.h
/home/ubuntu/workspace/firmware/services/inc/config.h
/home/ubuntu/workspace/firmware/services/inc/dcd.h
/home/ubuntu/workspace/firmware/services/inc/debug.h
/home/ubuntu/workspace/firmware/services/inc/flash_storage.h
/home/ubuntu/workspace/firmware/services/inc/jsmn.h
/home/ubuntu/workspace/firmware/services/inc/panic_codes.h
/home/ubuntu/workspace/firmware/services/inc/panic.h
/home/ubuntu/workspace/firmware/services/inc/rgbled.h
/home/ubuntu/workspace/firmware/services/inc/service_debug.h
/home/ubuntu/workspace/firmware/services/inc/services_dynalib.h
/home/ubuntu/workspace/firmware/services/inc/spark_macros.h
/home/ubuntu/workspace/firmware/services/inc/static_assert.h
/home/ubuntu/workspace/firmware/system/inc/active_object.h
/home/ubuntu/workspace/firmware/system/inc/append_list.h
/home/ubuntu/workspace/firmware/system/inc/channel.h
/home/ubuntu/workspace/firmware/system/inc/system_cloud.h
/home/ubuntu/workspace/firmware/system/inc/system_dynalib_cloud.h
/home/ubuntu/workspace/firmware/system/inc/system_dynalib_net.h
/home/ubuntu/workspace/firmware/system/inc/system_dynalib.h
/home/ubuntu/workspace/firmware/system/inc/system_event.h
/home/ubuntu/workspace/firmware/system/inc/system_mode.h
/home/ubuntu/workspace/firmware/system/inc/system_network_internal.h
/home/ubuntu/workspace/firmware/system/inc/system_network.h
/home/ubuntu/workspace/firmware/system/inc/system_setup.h
/home/ubuntu/workspace/firmware/system/inc/system_sleep.h
/home/ubuntu/workspace/firmware/system/inc/system_task.h
/home/ubuntu/workspace/firmware/system/inc/system_threading.h
/home/ubuntu/workspace/firmware/system/inc/system_update.h
/home/ubuntu/workspace/firmware/system/inc/system_user.h
/home/ubuntu/workspace/firmware/system/inc/system_version.h
/home/ubuntu/workspace/firmware/system/inc/system_ymodem.h
/home/ubuntu/workspace/firmware/system/inc/wifitester.h
/home/ubuntu/workspace/firmware/user/inc/application.h
/home/ubuntu/workspace/firmware/user/inc/Particle.h
/home/ubuntu/workspace/firmware/wiring/inc/debug_output_handler.h
/home/ubuntu/workspace/firmware/wiring/inc/fast_pin.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_disable_cloud.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_disable_wlan.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_arduino.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_cellular.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_character.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_client.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_cloud.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_constants.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_eeprom.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_i2c.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_interrupts.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_ipaddress.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_network.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_platform.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_print.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_printable.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_random.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_rgb.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_servo.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_spi.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_startup.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_stream.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_string.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_system.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_tcpclient.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_tcpserver.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_thread.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_ticks.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_time.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_tone.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_udp.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_usartserial.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_usbkeyboard.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_usbmouse.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_usbserial.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_version.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring_wifi.h
/home/ubuntu/workspace/firmware/wiring/inc/spark_wiring.h
/home/ubuntu/workspace/firmware/wiring/inc/string_convert.h
/home/ubuntu/workspace/firmware/communication/src/coap.h
/home/ubuntu/workspace/firmware/communication/src/communication_dynalib.h
/home/ubuntu/workspace/firmware/communication/src/device_keys.h
/home/ubuntu/workspace/firmware/communication/src/dsakeygen.h
/home/ubuntu/workspace/firmware/communication/src/events.h
/home/ubuntu/workspace/firmware/communication/src/file_transfer.h
/home/ubuntu/workspace/firmware/communication/src/handshake.h
/home/ubuntu/workspace/firmware/communication/src/spark_descriptor.h
/home/ubuntu/workspace/firmware/communication/src/spark_protocol_functions.h
/home/ubuntu/workspace/firmware/communication/src/spark_protocol.h
/home/ubuntu/workspace/firmware/system/src/system_cloud_internal.h
/home/ubuntu/workspace/firmware/system/src/system_network_cellular.h
/home/ubuntu/workspace/firmware/system/src/system_network_internal.h
/home/ubuntu/workspace/firmware/system/src/system_network_wifi.h
/home/ubuntu/workspace/firmware/communication/src/coap.cpp
/home/ubuntu/workspace/firmware/communication/src/communication_dynalib.cpp
/home/ubuntu/workspace/firmware/communication/src/dsakeygen.cpp
/home/ubuntu/workspace/firmware/communication/src/events.cpp
/home/ubuntu/workspace/firmware/communication/src/handshake.cpp
/home/ubuntu/workspace/firmware/communication/src/spark_protocol_functions.cpp
/home/ubuntu/workspace/firmware/communication/src/spark_protocol.cpp
/home/ubuntu/workspace/firmware/system/src/active_object.cpp
/home/ubuntu/workspace/firmware/system/src/main.cpp
/home/ubuntu/workspace/firmware/system/src/system_cloud_internal.cpp
/home/ubuntu/workspace/firmware/system/src/system_cloud.cpp
/home/ubuntu/workspace/firmware/system/src/system_event.cpp
/home/ubuntu/workspace/firmware/system/src/system_mode.cpp
/home/ubuntu/workspace/firmware/system/src/system_network.cpp
/home/ubuntu/workspace/firmware/system/src/system_setup.cpp
/home/ubuntu/workspace/firmware/system/src/system_sleep.cpp
/home/ubuntu/workspace/firmware/system/src/system_task.cpp
/home/ubuntu/workspace/firmware/system/src/system_threading.cpp
/home/ubuntu/workspace/firmware/system/src/system_update.cpp
/home/ubuntu/workspace/firmware/system/src/system_utilities.cpp
/home/ubuntu/workspace/firmware/system/src/system_ymodem.cpp
/home/ubuntu/workspace/firmware/system/src/wifitester.cpp
/home/ubuntu/workspace/firmware/user/src/application.cpp
/home/ubuntu/workspace/firmware/wiring_globals/src/spark_wiring_gpio.cpp
/home/ubuntu/workspace/firmware/wiring_globals/src/wiring_globals_cloud.cpp
/home/ubuntu/workspace/firmware/wiring_globals/src/wiring_globals_eeprom.cpp
/home/ubuntu/workspace/firmware/wiring_globals/src/wiring_globals_i2c.cpp
/home/ubuntu/workspace/firmware/wiring_globals/src/wiring_globals_ipaddress.cpp
/home/ubuntu/workspace/firmware/wiring_globals/src/wiring_globals_spi.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_cloud.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_eeprom.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_i2c.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_interrupts.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_ipaddress.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_print.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_random.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_rgb.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_servo.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_spi.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_stream.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_string.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_system.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_tcpclient.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_tcpserver.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_time.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_tone.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_udp.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_usartserial.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_usbkeyboard.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_usbmouse.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_usbserial.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring_wifi.cpp
/home/ubuntu/workspace/firmware/wiring/src/spark_wiring.cpp
/home/ubuntu/workspace/firmware/wiring/src/string_convert.cpp
/home/ubuntu/workspace/firmware/wiring/src/user.cpp
attempting to compile firmware
Compile failed. Exiting.

You shouldn’t need to clone the full firmware repo.
Just build your own project, the Particle framework will be present at the buildfarm.

1 Like

Thanks - I created a new workspace and it works fine, except for compiling for Oaks, which i see is a known issue here: Nothing compiles (Oak) - so i have no idea what i was doing wrong last night…

1 Like