(Or: How Not To Get Your Viz Blacklisted After Posting It Publicly)
So, you're pumped up, all fired up - think you've got a 'killer' viz and want to have people flashing it in their L3D Cubes all over the world and give you praise?
- First things first! Are you sure your viz's code is bug-free? Are you sure you have done everything humanly possible to test it in order to ensure other users won't be disappointed when flashing your viz in their Cubes?
The above may sound like commonplace, but it's a fact of life that choosing between disregarding it or making it your top priority will make the difference between being the proud author of a 5-star ranked viz and one that ends up blacklisted shortly after being publicized. The secret is: Testing, debugging, testing, debugging, testing!! And more testing!!
By now you should already have a working knowledge in C/C++ programming. If you are unsure about what C/C++ is (and no, the language used in code you see in any viz's "View Source" tab is not Java - it's C/C++; those are completely different languages, even though Java was loosely based on C++). If you are asking yourself about this "C/C++ thing", then you probably need to brush up a bit. You can read through the many excellent tutorials available through the web - here's a handful of carefully selected ones for you to get started:
Not only those websites are complete tutorials, but they also offer a solid reference to the C/C++ language. So as you walk along your path into programming you will find yourself constantly referring to those (and possibly many others).
If you're proficient in another language (e.g., Java or .NET with C#), you shouldn't find it too difficult to transition to C++. The main thing you need to keep in mind is that C++ is NOT (yes, in both CAPITALS and bold letters) nearly as forgiving as the former two -- keep in mind the famous words by Bjarne Stroustrup:
"C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
This means, C++ will let you write (almost) anything you want and sometimes, even compile! But if you're not programming with both your eyes open (and possibly a third eye on your forehead as well) you will likely get disastrous results.
Which brings us a notch further down in the topic of C/C++ programming. If you're already coding in C/C++ and thinking "if I got it to compile with no error messages in the console, then it's good already" - Wrong!
Re-read everything said up to here; compiling with no errors is merely 1/2 of the way - any C/C++ compiler merely checks for basic mistakes (like type assignment inconsistencies, references to misplaced/orphaned header files/macros/defines, etc) - it can't possibly know what your code is intended for, nor what it's trying to do or why; as an example, you can write code that tries to assign a value that's outside of the scope a variable's type can hold and be "OK" for the compiler -- therefore, there is still the possibility of things going wrong, from a viz not displaying correctly (or not at all) to a viz bringing the photon processor in your L3D cube to a completely undefined state (a.k.a., stall your photon). And that is precisely what programmers need to be aware of and mostly focused on avoiding during development.
With that out of the way, we're moving on to discuss the tools available for programming for the photon. The first thing you as a programmer need to be familiar with (OK, let me rephrase that: the second thing) is your target platform -- in our case, the particle photon. You should become intimate with it; if you've no idea what I'm talking about, have a look at the underside of your L3D cube. See that little rectangular thingy with lots of "paws" stuck to the main PCB? The one with an LED that's (hopefully!!) breathing cyan? That's right. Look at particle's reference website and identify it from the pictures. Got your unsub ID'd right? Great!
So you'll be controlling its functions internally; that means, whatever code you decide to stick into it will govern what it will do; and make no mistake, this means: anything you tell it to do (regardless if instructed correctly or not), it will do. So, coding correctly is key.
Aside from the "doing things right" subject, also runs "fixing things that go wrong for no apparent reason" -- becoming intimate with your target platform means understanding it to a minimum level that'll allow you to restore it to a previously known good state should anything go south during development/testing. If you want to be in command of your photon, you need to be able to tell when it's become sick and how to make it good again. Here are the main telltale signs to look for. You should already be familiarized with the first two; it is the normal state as you power on your photon (provided you've already set up the Wifi credentials and your internet connection is up and running flawlessly).
If your photon is in listening mode, this means that you haven't yet set it up to stay connected to the internet via your home Wifi; So you need to get that out of the way before moving further on.
If your photon is in wifi off mode, it's probably because something in your code (or somebody else's code that you've flashed from the gallery) has turned off the photon's internal Wifi controller chip. This means no matter what you do, while the photon is in this state it no longer is looking for any internet; it's neither connected to your home Wifi, nor will it ever try, until you roll back this scenario by erasing the damaging code from your photon. See next bullet item for how to do that.
Safe mode: The mother of all solutions. The lifesaver. The rescue rope. Behold, for you are now saved. Although it does not erase the programming from the photon (like earlier firmware revisions did) this mode is basically telling your photon to not run whatever programming is stored in its Flash and just to look for and try to connect using whatever Wifi credentials it's got stored. If successful, it will breathe magenta. If not, it will probably be either in wifi not connected / cloud not connected modes; the former means you may have to reset your home Wifi router, because the photon is unsuccessfully trying to log on to it, whereas the latter means the particle cloud is either not recognizing your photon (is it claimed?) or just not reachable at the moment. Point is, when in safe mode, you can either go back to the gallery and flash some other viz or do the same via DFU (more ont that below). Suggested ones follow:
ZPLASMA + FFT JOY;
Note that the last 2 viz'es are private; meaning, they won't show up in the gallery, because they weren't made public. The reason I'm pointing this out now is because this is an interesting feature about the Cubetube Gallery: you can save your work as a private viz and still share it by handing out their unique Twitter share link to selected audiences; so, say during your development you may want to have someone else flash your code into their own L3D Cube to watch your code in action and provide you with some valuable feedback. Hence why making your viz public while still in draft or WIP (Work In Progress) stages is not recommended practice and will possibly become a candidate for blacklisting once people realize it's incomplete work or worse, not working at all.
Red flash (a.k.a., SOS) mode: Things went south. Stop. Ctrl-Z (Windows) / Command-Z (OS-X) is your best friend. And so is Safe mode.
And lastly, there's DFU mode: DFU stands for "Device Firmware Upgrade"; it is the hardcore cousin of Safe mode. While Safe mode only requires you to press a combination of buttons in your photon to summon this mode, DFU, in addition to requiring a combination of button presses in your photon, also requires you to perform a few extra steps: first, you will need to install the CLI tools from particle; second, you will need to install the DFU-Util utility program in your desktop PC; third, your photon will be connected via USB -- as opposed to Safe mode, where the code is OTA-flashed (Over The Air), code will be flashed via a serial connection so you will need some drivers installed too. There are online tutorials available to show you a step-by-step installation procedure for every platform. The DFU method works by means of command-line instructions issued via the CLI tools on a console (or terminal) window (these instructions have already been discussed in this forum); the DFU method is the one employed in Cube Doctor to perform the necessary firmware updates in your photon to restore it to working order. Now the secret's out. Welcome to the black magic society of L3D conjurors.
As such, you'll be handed your own set of DFU magic spells -- the following downloadable executable is a tool created to simplify the work of flashing a binary directly via USB to your photon:
DFU-Me & Flashy Tools (for Windows **); requires .NET Framework installed.
With this tool, you no longer will have to memorize and type the various CLI commands (open a Windows command prompt > identify COM port > put the photon into DFU mode > invoke DFU-UTIL.EXE to flash the compiled binary to the photon via USB serial) in order to program your photon via DFU; instead, you can just select the binary you want to flash into the photon and click the "Download" button; the tool will (most likely) identify the correct COM port and switch the photon to DFU and download the selected compiled binary to it (much like how Cube Doctor does it).
** Mac users: The above download is a Windows executable. You may try to wrap it into an app package to be run on OSX under Wine by following this tutorial (I have neither tested this method and nor do I offer any support).
Coding environment (or, IDE):
When it comes to programming, for the photon there are two avenues you can adhere to: the Web IDE is one, and it comes with some features that you may find useful at times, or just plain annoying over time:
The Web IDE allows you to store your code on the cloud; it also allows you to flash your photon OTA by just clicking a button; you can also select which firmware revision you want your code compiled against. Every action is performed by particle's cloud servers (saving/compiling/flashing). Problem is, most times you are faced with issues that come from these servers or the cloud (due to the fact it relays on the internet infrastructure to carry out actions you request), because when it comes to sending/receiving internet packets via HTTP you are susceptible to various degrees of failure. To illustrate my point, just think of yourself browsing the web and how many times you need to reload a page because it got stuck during mid-loading or the remote server responded with a 404 (a.k.a., "Page Not Found") error. If you think of your L3D cube as a web browser (or, Web Client), that's almost exactly what I mean. And why sometimes it is just not possible to determine if the cause of a photon not running your code right is due to an incomplete flash or even a cached flash (code was not updated to the latest compile) or if it's really your code that's causing the problem.
Local development environment: Developing locally only means you're coding in your favorite text editor (e.g., Notepad++) or IDE (e.g., Netbeans / Visual Studio / Code::Blocks / Eclipse) and using the already discussed CLI tools to compile the code over the air and get back a binary file that you can either flash into your photon locally via DFU or have it OTA-flashed by particle (personally, I prefer the former). There are plenty of discussions here in the forum about how to develop locally and use the CLI tools to compile and flash your code. But these forums are far from being the only resort to information on the subject. Look over to the particle website for a complete language reference and documentation for more complete info on it.
Important tips for those getting started in viz (or any other kind of) programming
Start small! You're threading into an unknown universe, and you don't have a clue where North is at. So instead of using the sky and count stars for orientation, take a compass; by that I mean, you don't need to start with a blank slate staring at you. Whether you're coding in the Web IDE or your favorite text editor/IDE or even in the Gallery's small web code editor, you will certainly find countless examples to get started at understanding other people's code and what it's doing. I cannot possibly emphasize enough how important this is and how making a habit out of it will get you through even bigger programming challenges. Taking a big chunk of the apple pie just because it's there will likely get you choked at the first try. So start with small bites, savouring every bit and making sure everything is properly chewed. You get the point. In other words, don't start with a piece of code that's 10,000 lines long and expect it to work flawlessly straight away with the changes you're making to it (that's redefining insanity).
Breaking it down:
Understand that you've just embarked on a wonderful journey, not a sprint, and mastery will come with time. See this excellent blog post by Peter Norvig: Teach Yourself Programming in Ten Years.
Get comfortable coding. So, write some C++ code, even trivial code, regularly. Practice what you think you've learned. To use a metaphor: Don't just try it on, really wear it. You'll only get comfortable with it if you try to use it regularly. It can be toy code at first, but let your ambition push you further.
Read other people's code. Especially, read code other people consider to be good. You don't have to adopt the style (there's quite a wide range of styles out there), but at least try to understand why the code is structured the way it is. In the end, program architecture will trump low-level coding in determining the successfulness of a programming project in the vast majority of cases.
Beef up your algorithm and data structure knowledge. Interesting programs will require interesting data structures. The difference between elegance and insanity often rests in the data structures. On the algorithm side of things: Once you understand the basic algorithms and data structures (e. g., quicksort, heaps, heapsort, binary search trees, hash tables, etc.), work on developing a more general sense of algorithm development.
If you're in the Web IDE for the first time, simply do this:
Open the "Libraries" panel located at the left side; find the NEOPIXEL library and click its name. Then have a look at its many examples (the *.CPP files -- apart from the one called "Neopixel.cpp"), take one that suits you (please do me a favor and take the shortest example possible, not one that has over 250 lines of code) and click the "USE THIS EXAMPLE" button (illustrated below):
Try to make the example you selected work in your cube. In order to pump up your success rate, I'll even let you in a little secret: most examples you'll find out there will have the following (or very similar) defines:
#define PIXEL_PIN D0
#define PIXEL_COUNT 512
#define PIXEL_TYPE WS2812B
What these defines do is set a few constants that instruct the NEOPIXEL library how to write data out and how many individually addressable voxels are available for it to write data out to; for our L3D Cube, the values need to be set as above or else you're going to be scratching your head as you stare at a blackened cube in dismay, even though the example code will compile fine.
So that's the end of this post. If you're serious about writing code that amazes and mesmerizes the crowd out there, you'll most certainly be in the right track by reading through it and understanding it fully. For other questions and concerns that you will have during your journey, there's always the forums aside from the old GIYF ("Google Is Your Friend") adage -- Good luck!