diff --git a/content/hacking/01.software/ArduinoStyleGuide/ArduinoStyleGuide.md b/content/learn/08.contributions/00.arduino-writing-style-guide/arduino-writing-style-guide.md similarity index 94% rename from content/hacking/01.software/ArduinoStyleGuide/ArduinoStyleGuide.md rename to content/learn/08.contributions/00.arduino-writing-style-guide/arduino-writing-style-guide.md index 1b058ab936..37eeef6871 100644 --- a/content/hacking/01.software/ArduinoStyleGuide/ArduinoStyleGuide.md +++ b/content/learn/08.contributions/00.arduino-writing-style-guide/arduino-writing-style-guide.md @@ -1,13 +1,15 @@ --- -title: 'Arduino Style Guide' +title: 'Arduino Style Guide for Writing Content' description: 'Learn how to write clear Arduino examples that can be read by beginners and advanced users alike.' tags: - - Style Guide + - Styleguide - Guidelines --- -This is a guide for writing clear Arduino examples that can be read by beginners and advanced users alike. You don't have to code this way, but it helps if you want your code to be clear to all levels of users. This is not a set of hard and fast rules, it's a set of guidelines. Some of these guidelines might even conflict with each other. Use your judgment on when they're best followed, and if you're not sure, ask someone who'll be learning from what you write what makes the most sense. You might also be interested in the API Style Guide for Arduino. +This is a guide for writing clear Arduino examples that can be read by beginners and advanced users alike. You don't have to code this way, but it helps if you want your code to be clear to all levels of users. This is not a set of hard and fast rules, it's a set of guidelines. Some of these guidelines might even conflict with each other. Use your judgment on when they're best followed, and if you're not sure, ask someone who'll be learning from what you write what makes the most sense. You might also be interested in the [Arduino Style Guide for Creating Libraries](/learn/contributions/arduino-library-style-guide). + +If you want to contribute with content for the Arduino Documentation website, please find instructions in the contribution-templates folder in the [Arduino Documentation repository](https://github.com/arduino/docs-content). ## Writing a tutorial diff --git a/content/learn/08.contributions/01.arduino-library-style-guide/arduino-library-style-guide.md b/content/learn/08.contributions/01.arduino-library-style-guide/arduino-library-style-guide.md new file mode 100644 index 0000000000..4232971cea --- /dev/null +++ b/content/learn/08.contributions/01.arduino-library-style-guide/arduino-library-style-guide.md @@ -0,0 +1,74 @@ +--- +title: 'Arduino Style Guide for Creating Libraries' +description: 'Learn how to write library APIs in an Arduino style.' +tags: + - Styleguide + - Guidelines +--- + +This is a style guide to writing library APIs in an Arduino style. Some of these run counter to professional programming practice. We’re aware of that, but it’s what’s made it possible for so many beginners to get started with Arduino easily. So please code with these principles in mind. If you have suggestions on how to make Arduino libraries clearer for that core audience, please jump in the discussion. + +**Be kind to the end user.** Assume you are writing an API for an intelligent person who has not programmed before. Come up with a clear mental model of the concept you’re working with, and the terms and functions you will use. + +**Match your API to the underlying capabilities.** You don’t want to expose implementation details to the user but you also don’t want an API that suggests an inaccurate mental model of the possibilities. For example, if there are only a few possible options for a particular setting, don’t use a function that takes an int, as it implies you can use any value you want. + +**Organize your public functions around the data and functionality that the user wants.** Quite often, the command set for a particular electronic module is overly complicated for the most common uses, or can be re-organized around higher level functionality. Think about what the average person thinks the thing does, and try to organise your API functions around that. Adafruit's [BMP085 library](https://github.com/adafruit/Adafruit-BMP085-Library) is a good example. The `readPressure()` function performs all the necessary steps to get the final pressure. The library wraps this commonly executed series of functions into a high-level single command which returns the value the user's looking for in a format she expects. It abstracts away not only the low-level I2C commands, but also the mid-level temperature and pressure calculations, while still offering those mid-level functions as public functions for those who want them. + +**Use full, everyday words.** Don’t be terse with your function names or variables. Use everyday terms instead of technical ones. Pick terms that correspond to popular perception of the concept at hand. Don’t assume specialized knowledge. For example, this is why we used `analogWrite()` rather than `pwm()`. Abbreviations are acceptable, though, if they’re in common use or are the primary name for something. For example, “HTML” is relatively common and “SPI” is effectively the name of that protocol (“serial-peripheral interface” is probably too long). (“Wire” was probably a mistake, as the protocol it uses is typically called “TWI” or “I2C”.) + +**Avoid words that have different meanings to the general public.** For example, to programmers, an error is a notification that something happened. To the general public, errors are bad things. + +**When you have to use a domain-specific term, write a sentence or two describing it to the general public FIRST.** You’ll likely come across a better term, and if not, you’ll have started the documentation on your library. + +**Document and comment as you go.** When writing examples and documentation, follow the [Writing Style Guide](/learn/contributions/arduino-writing-style-guide) + +**Use the established core libraries and styles.** + +* Use `read()` to read inputs, and `write()` to write to outputs, e.g. `digitalRead()`, `analogWrite()`, etc. +* Use the `Stream` and `Print` classes when dealing with byte streams. If it’s not appropriate, at least try to use its API as a model. For more on this, see below +* For network applications, use the `Client` and `Server` classes as the basis. +* Use `begin()` to initialize a library instance, usually with some settings. Use `end()` to stop it. +* Use camel case function names, not underscore. For example, **analogRead**, not **analog_read**. Or **myNewFunction**, not **my_new_function**. We've adopted this from Processing.org for readability's sake. + +**LONG_CONSTANT_NAMES_FULL_OF_CAPS are hard to read.** Try to simplify when possible, without being terse. + +**Try to avoid boolean arguments.** Instead, consider providing two different functions with names the describe the differences between them. + +**Don’t assume knowledge of pointers.** Beginning users of C find this the biggest roadblock, and get very confused by `&` and `*`, so whenever you can avoid having them hanging out in the API, do so. One way is to pass by reference using array notation rather than `*` notation, for example. + +```arduino +void printArray(char* array); +``` + +can be replaced by + +```arduino +void printArray(char[] array); +``` + +Though there are some libraries where we pass pointers by using structures like const chars, avoid anything that requires the user to pass them. For example,rather than: + +```arduino + foo.readAccel(&x, &y, &z); +``` + +use something like this: + +```arduino + xAxis = adxl.readX(); + yAxis = adxl.readY(); + zAxis = adxl.readZ(); +``` + +When using serial communication, allow the user to specify any `Stream` object, rather than hard-coding `Serial`. This will make your library compatible with all serial ports on boards with multiple (e.g., Mega), and can also use alternate interfaces like SoftwareSerial. The Stream object can be passed to your library's constructor or to a `begin()` function (as a reference, not a pointer). See [Firmata 2.3](http://www.firmata.org/wiki/Main_Page) or [XBee 0.4](https://github.com/andrewrapp/xbee-arduino) for examples of each approach. + +When writing a library that provides byte-stream communication, inherit Arduino's `Stream` class, so your library can be used with all other libraries that accept `Stream` objects. If possible, buffer incoming data, so that `read()` immediately accesses the buffer but does not wait for more data to arrive. If possible, your `write()` method should store data to a transmit buffer, but `write()` must wait if the buffer does not have enough space to immediately store all outgoing data. The `yield()` function should be called while waiting. + +Here are a few libraries that are exemplary from Adafruit. She breaks the functions of the devices down into their high-level activities really well. + +* https://github.com/adafruit/Adafruit-BMP085-Library +* https://github.com/adafruit/DHT-sensor-library + +This does a nice job of abstracting from the Wire (I2C) library: https://github.com/adafruit/RTClib + +The text of the Arduino reference is licensed under a [Creative Commons Attribution-ShareAlike 3.0 License](http://creativecommons.org/licenses/by-sa/3.0/). Code samples in the reference are released into the public domain. \ No newline at end of file diff --git a/content/hacking/01.software/LibraryTutorial/LibraryTutorial.md b/content/learn/08.contributions/03.arduino-creating-library-guide/arduino-creating-library-guide.md similarity index 78% rename from content/hacking/01.software/LibraryTutorial/LibraryTutorial.md rename to content/learn/08.contributions/03.arduino-creating-library-guide/arduino-creating-library-guide.md index 9e8c659827..35e2f97505 100644 --- a/content/hacking/01.software/LibraryTutorial/LibraryTutorial.md +++ b/content/learn/08.contributions/03.arduino-creating-library-guide/arduino-creating-library-guide.md @@ -2,14 +2,18 @@ title: 'Writing a Library for Arduino' description: 'Creating libraries to extend the functionality of Arduino. Goes step-by-step through the process of making a library from a sketch.' tags: + - Styleguide + - Guidelines - Libraries --- + This document explains how to create a library for Arduino. It starts with a sketch for flashing Morse code and explains how to convert its functions into a library. This allows other people to easily use the code that you've written and to easily update it as you improve the library. For more information, see the [API Style Guide](https://www.arduino.cc/en/Reference/APIStyleGuide) for information on making a good Arduino-style API for your library. We start with a sketch that does simple Morse code: -``` + +```arduino int pin = 13; void setup() @@ -41,16 +45,18 @@ void dash() delay(250); } ``` + If you run this sketch, it will flash out the code for SOS (a distress call) on pin 13. -The sketch has a few different parts that we'll need to bring into our library. First, of course, we have the **dot()** and **dash()** functions that do the actual blinking. Second, there's the **ledPin** variable which the functions use to determine which pin to use. Finally, there's the call to **pinMode()** that initializes the pin as an output. +The sketch has a few different parts that we'll need to bring into our library. First, of course, we have the `dot()` and `dash()` functions that do the actual blinking. Second, there's the **ledPin** variable which the functions use to determine which pin to use. Finally, there's the call to `pinMode()` that initializes the pin as an output. Let's start turning the sketch into a library! -You need at least two files for a library: a header file (w/ the extension .h) and the source file (w/ extension .cpp). The header file has definitions for the library: basically a listing of everything that's inside; while the source file has the actual code. We'll call our library "Morse", so our header file will be Morse.h. Let's take a look at what goes in it. It might seem a bit strange at first, but it will make more sense once you see the source file that goes with it. +You need at least two files for a library: a header file (w/ the extension .h) and the source file (w/ extension .cpp). The header file has definitions for the library: basically a listing of everything that's inside; while the source file has the actual code. We'll call our library "Morse", so our header file will be `Morse.h`. Let's take a look at what goes in it. It might seem a bit strange at first, but it will make more sense once you see the source file that goes with it. The core of the header file consists of a line for each function in the library, wrapped up in a class along with any variables you need: -``` + +```arduino class Morse { public: @@ -64,11 +70,14 @@ class Morse A class is simply a collection of functions and variables that are all kept together in one place. These functions and variables can be public, meaning that they can be accessed by people using your library, or private, meaning they can only be accessed from within the class itself. Each class has a special function known as a constructor, which is used to create an instance of the class. The constructor has the same name as the class, and no return type. You need a couple of other things in the header file. One is an #include statement that gives you access to the standard types and constants of the Arduino language (this is automatically added to normal sketches, but not to libraries). It looks like this (and goes above the class definition given previously): -``` + +```arduino #include "Arduino.h" ``` + Finally, it's common to wrap the whole header file up in a weird looking construct: -``` + +```arduino #ifndef Morse_h #define Morse_h @@ -76,12 +85,14 @@ Finally, it's common to wrap the whole header file up in a weird looking constru #endif ``` -Basically, this prevents problems if someone accidentally #include's your library twice. + +Basically, this prevents problems if someone accidentally `#include`'s your library twice. Finally, you usually put a comment at the top of the library with its name, a short description of what it does, who wrote it, the date, and the license. Let's take a look at the complete header file: -``` + +```arduino /* Morse.h - Library for flashing Morse code. Created by David A. Mellis, November 2, 2007. @@ -104,25 +115,31 @@ class Morse #endif ``` + Now let's go through the various parts of the source file, Morse.cpp. First comes a couple of #include statements. These give the rest of the code access to the standard Arduino functions, and to the definitions in your header file: -``` + +```arduino #include "Arduino.h" #include "Morse.h" ``` + Then comes the constructor. Again, this explains what should happen when someone creates an instance of your class. In this case, the user specifies which pin they would like to use. We configure the pin as an output save it into a private variable for use in the other functions: -``` + +```arduino Morse::Morse(int pin) { pinMode(pin, OUTPUT); _pin = pin; } ``` -There are a couple of strange things in this code. First is the **Morse::** before the name of the function. This says that the function is part of the **Morse** class. You'll see this again in the other functions in the class. The second unusual thing is the underscore in the name of our private variable, **_pin**. This variable can actually have any name you want, as long as it matches the definition in the header file. Adding an underscore to the start of the name is a common convention to make it clear which variables are private, and also to distinguish the name from that of the argument to the function (**pin** in this case). -Next comes the actual code from the sketch that you're turning into a library (finally!). It looks pretty much the same, except with **Morse::** in front of the names of the functions, and **_pin** instead of **pin**: -``` +There are a couple of strange things in this code. First is the **Morse::** before the name of the function. This says that the function is part of the **Morse** class. You'll see this again in the other functions in the class. The second unusual thing is the underscore in the name of our private variable, `_pin`. This variable can actually have any name you want, as long as it matches the definition in the header file. Adding an underscore to the start of the name is a common convention to make it clear which variables are private, and also to distinguish the name from that of the argument to the function (**pin** in this case). + +Next comes the actual code from the sketch that you're turning into a library (finally!). It looks pretty much the same, except with **Morse::** in front of the names of the functions, and `_pin` instead of **pin**: + +```arduino void Morse::dot() { digitalWrite(_pin, HIGH); @@ -139,8 +156,10 @@ void Morse::dash() delay(250); } ``` + Finally, it's typical to include the comment header at the top of the source file as well. Let's see the whole thing: -``` + +```arduino /* Morse.cpp - Library for flashing Morse code. Created by David A. Mellis, November 2, 2007. @@ -172,12 +191,14 @@ void Morse::dash() delay(250); } ``` + And that's all you need (there's some other nice optional stuff, but we'll talk about that later). Let's see how you use the library. First, make a **Morse** directory inside of the **libraries** sub-directory of your sketchbook directory. Copy or move the Morse.h and Morse.cpp files into that directory. Now launch the Arduino environment. If you open the **Sketch > Import Library** menu, you should see Morse inside. The library will be compiled with sketches that use it. If the library doesn't seem to build, make sure that the files really end in .cpp and .h (with no extra .pde or .txt extension, for example). Let's see how we can replicate our old SOS sketch using the new library: -``` + +```arduino #include Morse morse(13); @@ -194,37 +215,44 @@ void loop() delay(3000); } ``` + There are a few differences from the old sketch (besides the fact that some of the code has moved to a library). First, we've added an #include statement to the top of the sketch. This makes the Morse library available to the sketch and includes it in the code sent to the board. That means if you no longer need a library in a sketch, you should delete the #include statement to save space. Second, we now create an instance of the Morse class called **morse**: -``` + +```arduino Morse morse(13); ``` -When this line gets executed (which actually happens even before the **setup()** function), the constructor for the Morse class will be called, and passed the argument you've given here (in this case, just 13). -Notice that our **setup()** is now empty; that's because the call to **pinMode()** happens inside the library (when the instance is constructed). +When this line gets executed (which actually happens even before the `setup()` function), the constructor for the `Morse` class will be called, and passed the argument you've given here (in this case, just 13). -Finally, to call the **dot()** and **dash()** functions, we need to prefix them with **morse**. - the name of the instance we want to use. We could have multiple instances of the Morse class, each on their own pin stored in the _pin private variable of that instance. By calling a function on a particular instance, we specify which instance's variables should be used during that call to a function. That is, if we had both: -``` +Notice that our `setup()` is now empty; that's because the call to `pinMode()` happens inside the library (when the instance is constructed). + +Finally, to call the `dot()` and `dash()` functions, we need to prefix them with **morse**. - the name of the instance we want to use. We could have multiple instances of the `Morse` class, each on their own pin stored in the _pin private variable of that instance. By calling a function on a particular instance, we specify which instance's variables should be used during that call to a function. That is, if we had both: + +```arduino Morse morse(13); Morse morse2(12); ``` -then inside a call to **morse2.dot()**, **_pin** would be 12. + +then inside a call to `morse2.dot()`, `_pin` would be 12. If you tried the new sketch, you probably noticed that nothing from our library was recognized by the environment and highlighted in color. Unfortunately, the Arduino software can't automatically figure out what you've define in your library (though it would be a nice feature to have), so you have to give it a little help. To do this, create a file called **keywords.txt** in the Morse directory. It should look like this: + +```arduino +Morse KEYWORD1 +dash KEYWORD2 +dot KEYWORD2 ``` -Morse KEYWORD1 -dash KEYWORD2 -dot KEYWORD2 -``` + Each line has the name of the keyword, followed by a tab (not spaces), followed by the kind of keyword. Classes should be KEYWORD1 and are colored orange; functions should be KEYWORD2 and will be brown. You'll have to restart the Arduino environment to get it to recognize the new keywords. It's also nice to provide people with an example sketch that uses your library. To do this, create an **examples** directory inside the **Morse** directory. Then, move or copy the directory containing the sketch (let's call it **SOS**) we wrote above into the examples directory. (You can find the sketch using the **Sketch > Show Sketch Folder** command.) If you restart the Arduino environment (this is the last time, I promise) - you'll see a **Library-Morse** item inside the **File > Sketchbook > Examples** menu containing your example. You might want to add some comments that better explain how to use your library. If you'd like to check out the complete library (with keywords and example), you can download it: [Morse.zip](https://www.arduino.cc/en/uploads/Hacking/Morse.zip). -That's all for now but I'll probably write an advanced library tutorial soon. In the meantime, if you have any problems or suggestions, please post them to the [Software Development forum](https://forum.arduino.cc/c/development/libraries/39). +If you have any problems or suggestions, please post them to the [Software Development forum](https://forum.arduino.cc/c/development/libraries/39). -For more information, see the [API Style Guide](https://www.arduino.cc/en/Reference/APIStyleGuide) for information on making a good Arduino-style API for your library. +For more information, see the [API Style Guide](/learn/contributions/arduino-library-style-guide) for information on making a good Arduino-style API for your library. diff --git a/content/learn/08.contributions/04.arduino-creating-content-guide/arduino-creating-content-guide.md b/content/learn/08.contributions/04.arduino-creating-content-guide/arduino-creating-content-guide.md new file mode 100644 index 0000000000..a860f69af8 --- /dev/null +++ b/content/learn/08.contributions/04.arduino-creating-content-guide/arduino-creating-content-guide.md @@ -0,0 +1,37 @@ +--- +title: 'Writing Content for Arduino' +description: 'How to write content for the Arduino Documentation Website' +tags: + - Styleguide + - Guidelines +--- + +## Adding your own content + +You are welcome to add your own content to the Arduino Documentation repository. You can contribute with the following content: + +|Content|Description|Example| +|-------|-----------|-------| +|Tutorial|Learn how to do something.|[Control Built-in RGB LED over Wi-Fi with Nano RP2040 Connect](/tutorials/nano-rp2040-connect/rp2040-web-server-rgb)| +|Article|Learn about a specific topic.|[Multimeter Basics](/learn/electronics/multimeter-basics)| +|Nugget|Smaller tutorial with less information and more straight to the example.|[Analog Read Serial](/built-in-examples/basics/AnalogReadSerial)| +|Project|Learn how to build something.|[DIY Photoshop Editing Console using Arduino Nano RP2040 Connect](https://create.arduino.cc/projecthub/jithinsanal1610/diy-photoshop-editing-console-using-arduino-nano-rp-2040-a43e97)| + +\*Note that the contributed Projects should be added to **Project Hub** instead of on the Arduino Documentation website. + +***You can also contribute to our content by creating your own libraries. Read more about that [here](/learn/contributions/arduino-library-style-guide).*** + + +For us to be able to approve your contribution, you should [follow the guidelines](/learn/contributions/arduino-writing-style-guide) on how to structure and write your content. + + +## Styleguides + +If you want to write your own content, please read the following guides on how to write in a user friendly way. + +* [Arduino Style Guide for Writing Content](/learn/contributions/arduino-writing-style-guide) + + +If you want to contribute with your own content to the Arduino Documentation website, please read the following documentation on how to do just that. + +* [Contribution Content](https://github.com/arduino/docs-content/tree/main/contribution-templates) \ No newline at end of file diff --git a/content/learn/08.contributions/contributions.md b/content/learn/08.contributions/contributions.md new file mode 100644 index 0000000000..136bd02a06 --- /dev/null +++ b/content/learn/08.contributions/contributions.md @@ -0,0 +1,3 @@ +--- +title: Contributions +--- \ No newline at end of file