diff --git a/docs/guide/data-types/README.md b/docs/guide/data-types/README.md index f4430aab..f3c77be0 100644 --- a/docs/guide/data-types/README.md +++ b/docs/guide/data-types/README.md @@ -5,63 +5,64 @@ title: Data Types Data Types ========== -In XOD any pin have a data type. Data values are transfered along links -between nodes allowing them to work together on a whole job. +In XOD, every pin has a data type. Data values are transfered along links +between nodes, allowing them to work together to a perform a job. -This is very much like signals of ICs in electronics. Although signals in -hardware are quite limited in the sense what data they could carry. They are -simply voltage with a value somewhere between zero volts and few volts. To -express meaningful values like numbers various tricks are used. For example, -one could map voltage to a value with a logarithmic scale, or consider the -voltage a series of 0’s and 1’s arriving at predefined rate, then group them by -eight and convert into bytes. +This is very much like integrated circuits’ signals in electronics, though +hardware signals are quite limited as to what data they can carry. They are +simply voltages with a value somewhere between zero volts and few volts. +Various tricks are used to express meaningful values like numbers. For example, +you could map voltage to a value on a logarithmic scale, or you could interpet +the voltage as a series of 0’s and 1’s arriving at a predefined rate, and +then convert them into bytes by grouping them into sets of eight. -In XOD various data types are supported natively. There is no need to use the +XOD has native support for various data types — no need to use any tricks. For example, there are data types that hold arbitrary numbers or -textual strings. +text strings.
Pro Tip -

Perhaps you know, there are languages with static typing (C, C++, Java, -Haskell) and languages with dynamic typing (JS, Python, Ruby). What’s better -is a long flamewar.

+

You may know there are languages with static typing (C, C++, Java, +Haskell) and languages with dynamic typing (JS, Python, Ruby). A long flamewar +has been waged as to which is better.

-

XOD is in static typing camp. I.e. a pin can’t have a number value now, and a -textual string value two seconds latter. This gives necessary knowledge to IDE -so that it can protect you from silly mistakes.

+

XOD is in the static-typing camp, e.g. a pin can’t have a number value +now, and a text string value two seconds later. This lets the IDE protect you +from silly mistakes.

-As said above, the data type is a characteristic of a pin. You can say “Node -FOO has output pin BAR of number type”. That means that the BAR pin -carries a number value at any particular node. You can also say “Node FOO has +As mentioned above, a data type is a characteristic of a pin. You can say +“Node FOO has output pin BAR of number type”. That means that the BAR pin +carries a number value in every FOO node. You can also say “Node FOO has input pin QUX of boolean type”. That means the FOO node always expects 0 or 1 value connected to its QUX pin. -One important division of types in XOD is between a *pulse type* and any other -type that are together called *value types*. All them described below. +Importantly, XOD types are divided between *pulse types* and all other types, +which are collectively known as *value types*. Each type is described below. Pulse type ---------- -Pulse type is a very special type because it actually don’t carry any data on -its own. It is only used to tell about something happened just now or something -is required to happen right now. +The pulse type is very special, because it doesn't actually carry any data on +its own. It is only used to indicate that something has just happened or that +something should happen right now. Pulses are similar to clock or interrupt signals in digital electronics. -All we’re interested in is *moments* when the signal rises to Vcc or falls to -ground. They don’t carry any additional useful information in them. +All we’re interested in is the *moments* when the signal rises to Vcc or +falls to ground. They don’t carry any additional useful information. -A pulse signal can tell us that we’ve got a new TCP packet from network, that -a button was pressed, that some timeout has been past. We would use a pulse -signal to trigger SMS send or to adjust motor speed. +A pulse signal can tell us that we’ve got a new TCP packet from the network, +a button was pressed, or some time interval has passed. We would use a pulse +signal to trigger an SMS send command or adjust motor speed. -Very often pulse signals are accompanied with other value types on neighbour -pins. The values describe “what” whereas the pulse describes “when”. +Pulse signals are quite often accompanied by other value types on neighboring +pins. The values describe the “what”, while the pulse describes the +“when”. -Pulses make your programs live. Without them your device would stay intact. +Pulses give life to your programs. Without them, your device won't do anything. Read [Execution Model](../execution-model/) to understand this logic in detail. -Here are short list of nodes you’ll use a lot working with pulses: +Here is a short list of nodes you’ll use a lot in conjunction with pulses: * [`boot`](/libs/xod/core/boot/) * [`clock`](/libs/xod/core/clock/) @@ -71,13 +72,14 @@ Here are short list of nodes you’ll use a lot working with pulses: Boolean type ------------ -Boolean value can be either *true* or *false*. You can also think of it as a -choice between of one/zero, yes/no, on/off, high/low, enabled/disabled. +Boolean values can be either *true* or *false*. Alternatively, you can think of +them as a choice between of one/zero, yes/no, on/off, high/low, or +enabled/disabled. -Logical values are ubiquitous. They are enough to express values of simple +Logical values are ubiquitous. They are adequate to implement simple digital sensors (is a button pressed or not?), control simple actuators (should -a relay close?), and carry results of logical operations (is temperature -greater than 25°?). +a relay close?), and carry the results of logical operations (is the +temperature greater than 25°?). Here are short list of nodes you’ll use a lot working with logical values: @@ -89,20 +91,20 @@ Here are short list of nodes you’ll use a lot working with logical values: Number type ----------- -Numbers are widespread. The numeric data type is used to transfer sensors’ -measured values, set speed of motors, perform arithmetical computations, -comparisons and so on. +Numbers are everywhere. The number data type is used to transfer sensor +readings, set motor speeds, perform arithmetic computations and +comparisons, and so on. -Number type values in XOD can represent fractional numbers, positive and +Number values in XOD can be fractional numbers and positive and negative infinity. -Precision and most extremal representable values depend on capabilities of a -target platform. In any case it would be enough to operate on numbers with -six significant digits in range ±1038. +Precision and the range of representable values depend on the capabilities of +the target platform. In any event, the number type is enough to operate on +numbers with six significant digits in range ±1038.
Pro Tip -The underlying type for numerical values is IEEE 754 floating point with +The underlying format for number values is IEEE 754 floating point with single or double precision. It depends on a target platform.
@@ -120,54 +122,56 @@ Here are some nodes you’ll use to work with numbers: ### Unit ranges -Many nodes use numbers in range from 0 to 1. It is handy if the value denote -some kind of percentage. For example, a potentiometer node -uses 0.0 to denote leftmost washer position, 0.5 to denote middle position, -and 1.0 to express rightmost position. +Many nodes use numbers in the range from 0 to 1. This is convenient if the +value denotes some kind of percentage. For example, a potentiometer node +uses 0.0 to denote the leftmost washer position, 0.5 to denote the middle +position, and 1.0 to denote the rightmost position. Another example is an LED node. 0.0 is used to turn it off, 0.33 -to emit 33% brightness and 1.0 to turn on at maximum brightness. +to emit 33% brightness and 1.0 to turn on it at maximum brightness. -Some nodes use ranges from -1 to 1. E.g. motor node use -1 for -full backward, -0.2 for 20% backward, 0 to stop and 1 to run full forward. +Some nodes use ranges from -1 to 1. For example, a motor node use -1 for +full backward, -0.2 for 20% backward, 0 to stop, and 1 to run full forward. -Unit ranges are easy to operate with although they’re purely conventional. -It’s up to a node implementation to decide what to do if an input value falls -out of the range. Usually they’ll clamp the input to a desired range. +Unit ranges are convenient to use, but entirely unnecessary. +It’s up to a node's implementation to decide what to do if an input value +falls out of the range. A common behavior is to clamp the input to the desired +range. String type ----------- Strings represent pieces of text like “Hello World!”. -Unlike some languages where strings are threated specially in XOD it’s just a -list of bytes. Thus it’s up to you to control text encoding. You can choose -ASCII, UTF-8 or old-school CP-1252 for storage. What would work best depends -on capabilities of hardware modules and data transfer formats you work with. +Unlike some languages that give strings special treatment, XOD considers them +to be just a list of bytes. Thus it’s up to you to manage text encoding. You +can choose ASCII, UTF-8, or old-school CP-1252 for storage. The best choice +depends on the hardware modules and data transfer formats you work with. -Computers don’t like text actually, but humans are. You’ll use text to parse a -high-level input like SMS or tweet and to present values back to human on -display or via some web-service. +Computers don’t actually like text, but humans do. You’ll use text to parse +high-level input like an SMS or tweet, and display values to humans, or send +them via some web-service.
XOD T0D0 -All types described below are not yet implemented in XOD. For now, it’s just -a description of how things could look like in future. We’re welcome you -to the discussion on our forum. Here you can -affect the design decisions. +The types described below are not yet implemented in XOD. For now, we'll just +describe how things could look in future. We invite you +to join the discussion on our forum. You could +affect our design decisions.
Integer type ------------ -Although in many cases number type is enough to process numerical values, -sometimes it’s more preferrable to work on integer type. +Although the number type is often enough to process numeric values, +sometimes it’s preferrable to work with an integer type. -It have no problems with precission loss, operated faster by processors and -have much more sense for some functions such as as getting a substring from +Integers have no problems with precision loss, are processed faster, and +make much more sense for some purposes, such as as getting a substring from a string at a particular index and of a particular length. -Integer values can represent integral values from rougly ±2 milliards range. +The integer type can represent integral values in the range of rougly ±2 +billion.
Pro Tip @@ -177,79 +181,79 @@ The underlying type for integer values is a signed 32-bit integer. Byte type --------- -Bytes are fundamental building blocks of low-level computing. Many hardware -peripherals send or consume series of bytes to interact with a controller. +Bytes are the fundamental building blocks of low-level computing. Many hardware +peripherals send or consume a sequence of bytes to interact with a controller. -In XOD byte is a distinct data type that is used to perform low-level -operations. It can’t be interchanged with other types directly. You’ll -use some conversion nodes to convert byte values to more useful types and -back. They are: +In XOD, a byte is a distinct data type that is used to perform low-level +operations. It can’t be directly interchanged with other types. You’ll +use some conversion nodes to convert byte values to and from more useful types +such as: Tuples ------ Tuples are simply groups of other values with a predefined order and size. -Say, `Tuple3 Number Number Number` could be used to denote a point in 3D-space. -In that case it would contain X at first position, Y at second, and Z at -third. +For example, `Tuple3 Number Number Number` could be used to denote a point in +3D-space. In that case, it would contain X in the first position, Y in second, +and Z in the third. -Or `Tuple2 Byte Integer` could be used to describe a message for a particular -I²C chip. +Or `Tuple2 Byte Integer` could be used to encode a message for a particular IC +chip.
Pro Tip -If you’re familar with C or Arduino think of tuples as of structs in which +If you’re familar with C or Arduino, think of tuples as structs whose members are accessed by their index rather than by their name.
-You can easily pack and unpack single values to or from tuples using following -nodes: +You can easily pack and unpack single values to and from tuples using the +following nodes: Lists ----- -Lists are sequences of values of a particular type. Unlike tuples their length -is not predefined: they could grow or shrink as program goes. And they can only -contain values of a single type. +Lists are sequences of values of a particular type. Unlike tuples, their length +is not predefined: they can grow or shrink as the program runs. And they can +only contain values of a single type. For example: - `List Number` can represent a history of temperature readings -- `List Byte` can be a packet to send or receive from the network -- `List (Tuple Number Number Number)` can represent a trajectory for a robotic - hand as a sequence of points in 3D-space. -- `List (List Number)` represents a 2D-table of numbers with dynamic size. +- `List Byte` might be a packet to send or receive from the network +- `List (Tuple Number Number Number)` could represent the trajectory of a + robotic hand as a sequence of points in 3D-space. +- `List (List Number)` represents a dynamically-sized 2D-table of numbers. Common operations on lists include: Errors ------ -Error is not an independent type per se. It rather augments other types with -special values to denote errors in computations. +Error is not an independent type per se. Instead, it augments other types with +special values to denote computational errors. -For example, a division of an integer on zero would result in error value -rather than integer value. The same way an attempt to get an element from +For example, dividing an integer by zero would result in error value +rather than integer value.Similarly, an attempt to get an element from an empty list would result in another error value. Error values are viral. Once a functional node gets an error value on one of its inputs all it outputs get error values too. -There are few nodes that you would use to generate your own errors and -to handle potentially error’ish values. +There are few nodes that you would use to generate your own errors and handle +potential errors. Casting rules ------------- What should happen if a pin of one type is connected to a pin of another -type? Some combinations are forbidden and you’ll get an error if try to link -two pins of these types. Other combinations are valid and *casting* between two -is done behind the scenes. +type? Some combinations are forbidden and you’ll get an error if you try to +link such pins. Other combinations are valid, and values are *cast* from one +type to another. -In many cases you would like to convert a signal value from one type to -another. I.e. to link a pin with one type to a pin of another type. +It is often desirable to convert a signal value from one type to +another, i.e. to link a pin with one type to a pin of another type. -For some type pairs this is possible without any intermediate conversion +For some type pairs, this is possible without any intermediate conversion nodes: @@ -278,7 +282,7 @@ nodes: - + @@ -307,7 +311,7 @@ nodes:
use nodes use nodes3.14159 →
"3.14"
(two digits
after dot)
3.14159 →
"3.14"
(two digits
after decimal)
Integer →
-Other convertions can’t always be done unambigously thus are not allowed. +Other convertions can’t always be done unambigously and thus are not allowed. Use additional nodes to make casting explicit in such cases: * [`format-number`](/libs/xod/core/format-number/) @@ -316,25 +320,25 @@ Use additional nodes to make casting explicit in such cases: ### List lifting There are times when we have an output of a particular type `T` and an -input of corresponding list type `List T`. Or vice versa. Conceptually +input of the corresponding list type `List T`. Or vice versa. Conceptually, these are two very different types. However, XOD can make an implicit cast to link them properly. This transformation is known as “lifting”. If a value of type `T` is connected to an input of type `List T`, the -value is considered to be a single element list with that value on -first position. E.g. `42` becomes `[42]`. +value is considered to be a single element list with that value in +the first position, i.e. `42` becomes `[42]`. -Vice versa, if a value of type `List T` is connected to an input of type `T` in -of a functional node that node *maps* each element of the list and its result -value gets list type. E.g. a node [absolute](/libs/xod/core/absolute/) that is -usually operate on single numbers given a list `[-1, 2, 3, -4, -5]` would have -`[1, 2, 3, 4, 5]` as a result. +Conversely, if a value of type `List T` is connected to an input of type `T` in +a functional node, the node *maps* each element of the list and the resulting +value is a list type. For example, if `[-1, 2, 3, -4, -5]` were passed to an +[absolute](/libs/xod/core/absolute/) node, which usually operates on single +numbers, the result would be `[1, 2, 3, 4, 5]`. -If two lists given as values of two inputs of a functional node the computation -is done element-wise. E.g. a node [add](/libs/xod/core/add/) given `[1, 2, 3]` -for `X` and `[40, 50, 60]` -for `Y` would output `[41, 52, 63]`. +If two lists are given as the two inputs of a functional node, the node +operates element-wise on the lists, i.e. given `[1, 2, 3]` for `X` and `[40, +50, 60]` for `Y`, the [add](/libs/xod/core/add/) node would output `[41, 52, +63]`. -When lists’ length differ lifting operation takes a shortest one and acts as -all lists have the same shortest length. E.g. “add” node given `[1, 2, 3, 4]` -and `[40, 50]` would output `[41, 52]`. +If the lists differ in length, the lifting operation treats each of the lists +as if it was as short as the shortest list, i.e. given `[1, 2, 3, 4]` and `[40, +50]`, the “add” node would output `[41, 52]`. diff --git a/docs/guide/execution-model/README.md b/docs/guide/execution-model/README.md index f8b869f9..5ab5c16d 100644 --- a/docs/guide/execution-model/README.md +++ b/docs/guide/execution-model/README.md @@ -1,61 +1,60 @@ --- -title: Execution Model in Details +title: Execution Model in Detail --- -Execution Model in Details -=========================== +Execution Model in Detail +========================= In contrast to conventional programming, XOD is a data flow language rather -than control flow one. That means there is no such thing as an instruction -pointer that determines what command will be executed next moment. Instead, -updates are done in semi-instant *transactions* where all data is evaluated -simultaneously. +than a control flow language. That means there is no such thing as an +instruction pointer that determines what command will be executed at the next +moment. Instead, updates are done in semi-instantaneous *transactions* in which +all data is evaluated simultaneously. Functional and effect nodes --------------------------- -There is such thing as a *function* in mathematics. Sure, you know many of them: +There is such thing as a *function* in mathematics. You know many of them: -- `f(x) = sin x` is a function of single argument that returns its sine; -- `f(r) = π × r²` is a function of single argument that returns square of a +- `f(x) = sin x` is a unary (i.e. it takes a single argument) function that + returns the sine of its argument; +- `f(r) = π × r²` is a unary function that returns the area of a circle with given radius; -- `f(x, y) = √(x² + y²)` is a function of two arguments that returns a distance - from origin to a point with given coordinates; -- `f(v₀, a, t) = v₀ × t + (a × t²) / 2` is a function of - three arguments that returns velocity of an object at a particular moment in - time. +- `f(x, y) = √(x² + y²)` is a binary function (i.e. it takes two arguments) + that returns the distance from the origin to the point (x, y); +- `f(v₀, a, t) = v₀ × t + (a × t²) / 2` is a ternary (i.e. it takes + three arguments) function that returns the velocity of an object at a + particular moment in time. -Functions are great because they have very predictable behavior. E.g. if you’re -computing circle square it will be always the same for the same radius. It is a -nonsense if the result of computation today would differ from the result of -yesterday, or if the result would change depending on other factors like -weather outside. Furthermore computing circle square of radius 2 can’t affect -a result of another computation, e.g. `sin 2` now or in the future. +Functions are great, because they behave very predictably, i.e. if you’re +computing the area of a circle, it will always be the same for the same radius. +It would be nonsense if the computation today differed from that of yesterday, +or if the result changed based on other factors like the weather outside. +Furthermore, computing the area of a circle with radius 2 can’t affect the +result of another computation, e.g. `sin 2`, now or in the future. -Functions are intuitive and understandable pieces that don’t involve side -effects in computation. +Functions are intuitive and understandable pieces that don’t have +computational side effects.

Note Experienced programmers say that such functions are referrentially transparent, -easy to reason about, stateless, idempotent and pure. They mean the same things -and they love’em. +easy to reason about, stateless, idempotent, and pure.

-The characteristics of functions make them ideal building blocks to compose -complex computations. Input arguments of one function could be results of -other functions. They in turn can get arguments from yet other functions, etc. +The characteristics of functions make them ideal building blocks for creating +complex computations. The results of one function can be the input arguments of +another function, which could feed its results into yet another function, etc. -However, if you’re going to build a program solely from functions it would be a -program that always do the same thing and lead to absolutely same result. It -would not depend on user input, events in real world, or time. It would not -affect outside world and furthermore would have no chance to present -computation results. All because functions can’t have side effects. Thus -another kind of building block is required. +However, a program consisting solely from functions would always do the same +thing and produce exactly the same result. It would not depend on user input, +real world events, or time. It would not affect the external world or have the +ability to display computational results. All because functions can’t have +side effects. Thus another kind of building block is required. -In XOD there are two kinds of nodes available. *Functional nodes* represent -functions. And *effect nodes* serve as interfaces to the outside world, time, -and memory of past values. +In XOD, there are two kinds of nodes available. *Functional nodes* represent +functions. *Effect nodes* serve as interfaces to the external world, time, and +memory of past values. ### Functional nodes @@ -63,9 +62,9 @@ Functional nodes always have inputs and output pins. All pins have [value types](../data-types/#value). In other words functional nodes *never* have pins of [pulse type](../data-types/#pulse). -Output values depend only on values of input pins. They can’t depend on time -(only if given as an explicit input value), on parameters of outside world, or -on results of their past computations. Given the same set of input values they +Output values only depend on the values at input pins. They can’t depend on +time (unless given as an explicit input value), parameters of the external +outside world, or past computations. Given the same set of input values, they always result in the same set of output values. Some examples of functional nodes are: @@ -76,27 +75,27 @@ Some examples of functional nodes are: * [`or`](/libs/xod/core/or/) * [`format-number`](/libs/xod/core/format-number/) -Functional nodes affect nothing but their output values. They can’t change -brightness of a LED or speed of a motor on their own. +Functional nodes affect nothing but their output values. On their own, they +can’t change the brightness of an LED or the speed of a motor.

Note -If you’re an advanced Excel user think about functional nodes as of cell +If you’re an advanced Excel user, think about functional nodes as cell formulas.

### Effect nodes -Effect nodes could have just inputs, just outputs or both at once. They -*always* have pins of pulse type. Input pulses is what drives them to perform -effects and their output pulses is what tell us about effects that took place. +Effect nodes can have just inputs, just outputs, or both. Their pins +are *always* the pulse type. Input pulses drive them to perform +effects, and output pulses tell us about effects that have taken place. -A result of hitting an effect node can be arbitrary. It could turn on a lamp, -send an SMS, launch a nuke, or memoize a value for future use. +The result of activating an effect node can be arbitrary, e.g. turn on a lamp, +send an SMS, launch a nuke, or store a value for future use. -When such node would emit an output pulse is up to node implementation as well. -It could pulse on an update from sensor, on SMS received or on timeout event, -for example. +The node's implementation also decides when to emit an output pulse. +For example, a node could pulse when a sensor reading updates, an SMS is +received, or a timeout event occurs. Some examples of effect nodes are: @@ -106,109 +105,110 @@ Some examples of effect nodes are: * [`analog-input`](/libs/xod/core/analog-input/) * [`pwm-output`](/libs/xod/core/pwm-output/) -Effect nodes is a thing that complements functional land so that your program -could interact with a user, the world, and the time. +Effect nodes complement functional nodes so your program can interact with +users, the world, and time. Program life cycle ------------------ -In any particular moment a XOD program is either in a transaction or in an idle -state. +At any particular moment, a XOD program is either in a transaction or in an +idle state. -While being idle the system stays stable, nothing changes. A board can even -choose to go sleep to keep battery charge longer. What makes the program go out -of idle state is getting a new pulse from an effect node. It could be a pulse -from system clock or a sensor, for example. +While idle, the system remains stable, nothing changes. A board can even +choose to go to sleep to preserve the battery. Receiving a new pulse from an +effect node, e.g. a system clock or sensor, is what makes the program leave the +idle state. -A pulse cause the program to enter a new *transaction*. The pulse flows along -links downstream and cause nodes it hits to update. Node update process is -called *evaluation* in XOD. +A pulse causes the program to enter a new *transaction*. The pulse flows +downstream along links and causes the nodes it hits to update. The process of +updating a node is called *evaluation* in XOD. -At the moment of pulse emission a node can (and in most cases it would) set new -values on its other ouput pins that have value types such as number or boolean. +At the moment a pulse is emitted, a node can (and in most cases does) set new +values on its other ouput pins with value types such as number or boolean. -Evaluation of a node hit by a pulse in most cases would require computing -actual values on other node’s input pins. That values could depend on values of -upstream nodes’ outputs, which in turn depend on values of their upstream -nodes, and so on. All these dependencies are resolved by the XOD runtime -engine. Final and intermediate values required to evaluate a node are computed -atomically in the transaction. +Evaluation of a node hit by a pulse usually requires computing +actual values on another node’s input pins. The values on these pins could +depend on the values of upstream nodes’ outputs, which in turn depend on the +values of their upstream nodes, and so on. All these dependencies are resolved +by the XOD runtime engine. The final and intermediate values required to +evaluate a node are computed atomically in the transaction. -After all nodes affected by a pulse are evaluated the transaction completes and -the system returns to the idle state. +After all nodes affected by a pulse are evaluated the transaction is complete +and the system returns to the idle state. Transaction rules ----------------- ### No external pulses while a transaction is in progress -Any transaction has a guard that will not allow any external pulse to come half -way along the current transaction is in progress. Such pulse will be postponed -and would trigger a new transaction after the current one completes. +All transaction prevent any external pulses from occuring while the current +transaction is in progress. Such a pulse would be postponed and trigger a new +transaction after the current transaction is complete. -To be more precise, external pulses are pushed into a FIFO queue. And once the -system is in the idle state a pulse is popped from the queue and a new -transaction is initiated. The transaction completes, the system goes idle, -takes next pulse from the queue, launches new transaction, and so on until the -queue is empty. +To be more precise, external pulses are pushed into a FIFO queue. Once the +system is idle, a pulse is popped from the queue and a new transaction is +initiated. The transaction completes, the system goes idle, takes the next +pulse from the queue, launches a new transaction, etc. until the queue is +empty. ### Evaluation order -During a transaction any particular node will be evaluated only after all nodes -it depends on via links would be evaluated in their turn. +During a transaction, a node is evaluated only after all nodes +it depends on via links have been evaluated. -Consider following example. +Consider the following example. ![Diamond graph](./abc.patch.png) -The result node will be only evaluated after both branches are evaluated despite -they have node chains of different length. You can’t know the order the branches -will be evaluated. It could be M1-M2-M3, M3-M1-M2, M1-M3-M2, or even M1-M2 and -M3 in parallel. Furthermore, result node evaluation could be postponed until -its values would be actually required (so called “lazy evaluation”). It’s up to -target platform to decide. +The result node will only be evaluated after both branches are evaluated, +despite the fact that they have node chains of different length. You can’t +know the order in which the branches will be evaluated. It could be M1-M2-M3, +M3-M1-M2, M1-M3-M2, or even M1-M2 and M3 in parallel. Furthermore, evaluation +of the result node might be postponed until its values are actually required +(so-called “lazy evaluation”). The target platform decides. -The only thing that does matter is a node will be never evaluated with incomplete -data. +The only thing that does matter is that a node will be never evaluated with +incomplete data. -That is the reason why inputs can’t have more than one incoming link. In other -case the ambiguity will take place when two or more links would try to deliver +That is the reason why inputs can’t have more than one incoming link. +Otherwise, there would be ambiguity if two or more links tried to deliver different values. ### Buffering -Effect nodes’ outputs are *buffered* when changed. In other words the outputs -keep most recent value they got. The data is persistent between transactions. So -a node will “see” the buffered value from an old transaction via link if it is -required to evaluate again due to other input value change. +Effect nodes’ outputs are *buffered* when changed. In other words, the +outputs keep their most recent value. The data is persistent between +transactions. So a node will “see” the buffered value from an old +transaction via a link if the node must be evaluated again due to a change in +another input's value.
Pro Tip -If you’re familiar with conventional programming think of pins and their -buffered values as variables. They hold the program state and evolve over the -time. +If you’re familiar with conventional programming, think of pins and their +buffered values as variables. They hold the program state and evolve +over time.
-Whether values on of functional nodes’ pins would be buffered is up to target -platform to decide. Since outputs of a functional node depend only on its -inputs the decision is just a matter of execution speed vs RAM consumption. It +The target platform decides whether the values on functional nodes’ pins will +be buffered. Since a functional node's outputs depend only on its +inputs, the decision is just a matter of execution speed vs RAM consumption. It has no effect on actual program behavior. ### Feedback loops handling -In XOD link cycles that contain only functional nodes are not allowed. They -would lead to dead locks and program hangs. +In XOD, link cycles that contain only functional nodes are not allowed. They +would lead to deadlocks and hangs. -However it is OK to have a cycle broken by an effect node. In that case -new value will be delivered via feedback link but the node will “see” it -only once it would receive new incoming pulse. +However, cycles broken by effect nodes are OK. In this case, a new value will +be delivered via the feedback link, but the node will “see” it only once it has +received a new incoming pulse. Summary ------- -Program life cycle can be looked at as a infinite series of transactions that -run whenever an external impact occurs. Pulses drive the program. No pulses, no -changes. +The program's life cycle can be looked at as a infinite series of transactions +that run whenever an external impact occurs. Pulses drive the program. No +pulses, no changes. -Transactions are protected from sudden pulses that could change or make it -ambiguous the order of nodes’ evaluation. +Transactions are protected from sudden pulses that could change or make +ambiguous the order of node evaluation. diff --git a/docs/guide/linking-rules/README.md b/docs/guide/linking-rules/README.md index dce81090..e22ef2b1 100644 --- a/docs/guide/linking-rules/README.md +++ b/docs/guide/linking-rules/README.md @@ -5,34 +5,34 @@ title: Linking Rules Linking Rules ============= -To make behavior of XOD programs predictable there are some rules on how pins -can be linked. +To make XOD programs behave predictably, there are some rules on how pins can +be linked. Outputs and inputs ------------------ -You’re are not allowed to link two input pins, neither you’re allowed to link +You’re are not allowed to link two input pins, nor are you allowed to link two output pins. It doesn’t makes much sense. -A link should always connect an output and an input. +A link must always connect an output and an input. If you want to mirror values, just create multiple links from an output pin. ![Link fan out](./fan-out.patch.png) -An output can have an arbitrary number of links and an input can have -no more than one incoming link. +An output can have an arbitrary number of links, but an input can have no more +than one incoming link. Type matching ------------- -If an input and an output has same [data type](../data-types/) they -may be linked as is. +If an input and an output have the same [data type](../data-types/), they may +be linked as is. -However if they have different types they are only allowed to be linked if -[casting](../data-types/#casting-rules) between their type is possible. +However, if they have different types, they can only be linked if the output +type can be [cast](../data-types/#casting-rules) into the input type. -Once you start linking pins that are suitable for other end of the link +Once you start linking, pins that are suitable for the other end of the link are highlighted. Color code diff --git a/docs/guide/program-structure/README.md b/docs/guide/program-structure/README.md index 46f0d8fc..abf2ba06 100644 --- a/docs/guide/program-structure/README.md +++ b/docs/guide/program-structure/README.md @@ -5,20 +5,20 @@ title: Program Structure Program Structure ================= -Programs in XOD are quite similar to electronic circuits. Whereas to build an -electronic circuit you use various electronic components and connect them -with wires, in a XOD program you use *nodes* and connect them with *links*. +XOD programs are quite similar to electronic circuits. To build an +electronic circuit, you use various electronic components and connect them +with wires. In a XOD program, you use *nodes* and connect them with *links*. ![Example patch](./example.patch.png) Nodes ----- -What a node does depends on its type. Like in reality there are ICs to control -motors, amplify audio signals, store data, in XOD there are many types of -nodes available. It is easy to create your own as well. +What a node does depends on its type. Just as there are ICs in the physical +world to control motors, amplify audio signals, and store data, in XOD there +are many types of nodes available. You can also easily create your own. -Some nodes represent physical devices like LED or digital thermometer, other +Some nodes represent physical devices like LEDs or digital thermometers. Others are used to transform and filter data. Here are few examples: * [`thermometer-tmp36`](/libs/xod/common-hardware/thermometer-tmp36/) @@ -26,80 +26,81 @@ are used to transform and filter data. Here are few examples: * [`add`](/libs/xod/core/add/) * [`to-percent`](/libs/xod/core/to-percent/) -You place nodes you’ve chosen for your program into slots to be later connected -with links. +You place the nodes you’ve chosen for your program into slots to be later +connected with links. Pins, inputs, and outputs ------------------------- -Nodes alone are black boxes. To interact with them they expose *pins*. Think of -pins as of sockets, ports, IC legs, jack-connectors. +Nodes alone are black boxes. They expose *pins* to support interaction. Think +of pins as of sockets, ports, IC legs, and jacks. -A pin can be either *input* or *output*. Once you feed an input with a new value -the node is evaluated. As a reaction it can update values of its output pins or -perform some interaction with real world, e.g. change a motor speed. +A pin can be either an *input* or an *output*. Once you feed a new value to an +input, the node is evaluated. In response, it may update the values on its +output pins or interact with the real world in some way, e.g. change a motor's +speed. -Some nodes send an output on their own as a reaction to some external event. For -example the [clock](/libs/xod/core/clock/) node sends output with regular time -intervals. +Some nodes send an output on their own as a reaction to some external event. +For example, the [clock](/libs/xod/core/clock/) node sends outputs at regular +time intervals. Pins are depicted as holes with short labels. Inputs are placed on a darker -background and outputs are placed on a lighter background. +background, and outputs are placed on a lighter background. ![Nodes inputs and outputs](./nodes-inputs-outputs.png) Links and values ---------------- -Nodes talk to each other by transmitting values over *links*. A link is a -kind of wire that you use to connect one node output to another node input. +Nodes talk to each other by transmitting values over *links*. A link is a kind +of wire that you use to connect one node's output to another node's input. Values in XOD are quite similar to electric signals. However unlike their -electric counterparts they could carry not only a primitive voltage value, but +electric counterparts, they can carry not only raw voltage values, but also more sensible data like arbitrary numbers and text strings. Learn more about -values in [Data Types](../data-types/) article. +values in the [Data Types](../data-types/) article. -In digital electronics voltage values are switched discretely and their change -usually accompanied by some kind of clock signal. The clock signal is seen as -a sequence of “moments” which are defined by observing falling or rising signal -edges on the clock line. Interactions and changes actually happen at that -moments. I.e. a digital circuit is static until a new clock signal would -appear. +In digital electronics, voltage values are switched discretely, usually +accompanied by some kind of clock signal. The clock signal is seen as a +sequence of “moments” defined by the falling or rising signal edges on the +clock line. Interactions and changes actually happen at these moments, i.e. a +digital circuit is static until a new clock signal appears. -Behavior of values in XOD is very much similar. Values change and propogate -instantly. These cascade updates of values are called *transactions*. And things -that play a role of clock signals are called *pulses* in XOD. [Execution -Model](../execution-model/) article describes all principles in detail. +Values behave very similarly in XOD. They change and propogate +instantly. These cascading value updates are called *transactions*. In XOD, the +role of clock signals is played by *pulses*. The [Execution +Model](../execution-model/) article describes how they work in detail. -There are few rules that define which pins are allowed to be linked and which -are not. They are intuitive enough, although for a formal description you can -see [Linking Rules](../linking-rules/). +There are a few rules that define which pins are allowed to be linked and which +are not. They are intuitive enough, but for a formal description see [Linking +Rules](../linking-rules/). Patches ------- -Nodes linked together form a *patch*. Patches are like modules, documents, files -in other systems. +Nodes linked together form a *patch*. Patches are like modules, documents, or +files in other programming systems. -You would have a single patch in a simple project and for complex projects you’d -likely to have many. +You would have a single patch in a simple project, while you’d likely have +many for complex projects. -What makes a patch pretty interesting is that once you’ve created it you can -use it as a new type of node on other patches! That’s the main idea behind XOD +What makes a patch interesting is that once you’ve created one you can use it +as a new type of node in other patches! That’s the main idea behind XOD extensibility. -You use special *terminal nodes* to denote input and output pins when the patch +You use special *terminal nodes* to denote input and output pins when a patch is used as a node.
- Photo by cutwithflourish. + Photo by + cutwithflourish.

Note - If you’ve heard of modular synthesizers they are very similar to XOD programs. - The nodes are modules, the links are CV cables with banana connectors, - the patches are rack chassis for modules. + Perhaps you’ve heard of modular synthesizers - they are very similar to XOD + programs. Nodes are modules, links are CV cables with banana connectors, + and patches are a rack chassis for modules.

Modular synth diff --git a/docs/tutorial/complex-projects/README.md b/docs/tutorial/complex-projects/README.md index e87de663..47cf9c30 100644 --- a/docs/tutorial/complex-projects/README.md +++ b/docs/tutorial/complex-projects/README.md @@ -5,47 +5,46 @@ title: Complex Projects Complex Projects ================ -In past chapters of the tutorial series you’ve used bare minimum of nodes to -build simple projects. But what if you need to create something more complex? +In the tutorial's past chapters, you’ve used a bare minimum of nodes to build +simple projects. But what if you need to create something more complex? -The principle of programming will stay the same although you would create -more patches and use more nodes. +The programming principles stay the same even if you create more patches and +use more nodes. Search for nodes ---------------- -Before implementing your own nodes check if there is a ready to use node -that will solve your problem. Visit [library index](/libs/) to browse for -existing nodes. +Before implementing your own nodes, check if there is a ready to use node that +will solve your problem. Visit [library index](/libs/) to browse for existing +nodes. Interfacing with hardware ------------------------- -If you want to use a sensor or an electronic module that you haven’t find -support for it’s quite possible that all you need for it is few standard -nodes like `analog-input` or `digital-output`. +If you want to use a sensor or an electronic module that you haven’t found +support for, it’s quite possible that all you need is a few standard nodes +like `analog-input` or `digital-output`. -Refer to the item documentation to understand how you can talk with the +Refer to the item's documentation to understand how you can talk with the hardware. Write a native wrapper ---------------------- -You can implement a new node not only with XOD, but with C++ as well. -In this case you can even wrap an existing native library to make it -available in XOD. +You can implement new nodes not only in XOD, but also with C++. +You can even wrap an existing native library to make it available in XOD. -See implementation of `analog-input`, `digital-output`, `text-lcd-16x2` -as an example of how to do this. +See the implementation of `analog-input`, `digital-output`, and `text-lcd-16x2` +for examples of how to do this. Tell us what you need --------------------- -XOD ecosystem is poor since the project is very-very young. If you need -a node for something, [ask for it on our forum](//forum.xod.io). That -would help us to better prioritize our work. +The XOD ecosystem is barebones since the project is very-very young. If you +need a node for something, [ask for it on our forum](//forum.xod.io). That will +help us better prioritize our work. Dive into details ----------------- -Read [User’s guide](/docs/#users-guide) to understand XOD better. +Read the [User’s guide](/docs/#users-guide) to understand XOD better. diff --git a/docs/tutorial/data-types-and-conversions/README.md b/docs/tutorial/data-types-and-conversions/README.md index d72d71ef..0f78d65f 100644 --- a/docs/tutorial/data-types-and-conversions/README.md +++ b/docs/tutorial/data-types-and-conversions/README.md @@ -1,20 +1,23 @@ --- -title: Data Types and Conversions Between Them +title: Data Types and Conversions --- -Data Types and Conversions Between Them +Data Types and Conversions ======================================= -In previous tutorial chapters you’ve had a deal with pulses and logical values. +In previous tutorial chapters, you’ve had to deal with pulses and logical +values. A pulse just denotes the fact something happened and logical values carry either 0 or 1 value. -The later is called *boolean* data type and its values are called boolean values. -It’s just a matter of terminology, but boolean value which corresponds to -1/high/on/enable is called *true*, and 0/low/off/disable value is called *false*. +The latter is called a *boolean* data type, and its values are called boolean +values. +It’s just a matter of terminology, but the boolean value that corresponds to +1/high/on/enable is called *true*, and the boolean value corresponding to +0/low/off/disable value is called *false*. -There are more types in XOD to express more than simple flow of boolean values. -Lets get familiar with them. +XOD has other types to express more than a simple flow of boolean values. +Let's get familiar with them. Number type ----------- @@ -22,42 +25,45 @@ Number type 42, 3.14159, -2.7… All these are numbers. They can be used to describe values like temperature, distance, angle, acceleration along an axis, and many more. -Let’s use few nodes that employ numbers. We are going to build a simple dimmer -with a potentiometer which would set LED brightness. First of all, we need a +Let’s use few nodes that operate on numbers. We are going to build a simple +dimmer with a potentiometer that sets LED brightness. First of all, we need a circuit: ![Pot and LED circuit](./pot-led.fz.png) -We would like to control LED brightness, so make sure to connect the LED to a -port with PWM feature available. They are marked with tilda (~). And since the -potentiometer provides analog values its port should be capable of reading -analog signals. Ports marked A0 through A5 are good choise for that. +We would like to control LED brightness, so be sure to connect the LED to a +port that supports PWM. They are marked with a tilda (~). Because the +potentiometer provides analog values, its port must be capable of reading +analog signals. Ports marked A0 through A5 are a good choice for that. -Then create new project with main menu: File → New Project. Name it -`pot-led-dimmer` or something like that. Add nodes and links to get a program -that looks like one below: +Then create a new project from the main menu: File → New Project. Name it +`pot-led-dimmer` or something like that. Add nodes and links to create a +program that looks like the one below: ![Pot and LED patch](./pot-led.patch.png) -We use `pwm-output` from `xod/core` to provide PWM signal to our LED. -The `DUTY` input defines duty cycle. Value 0.0 denotes always-low signal -(LED is off), 0.33 is for 33% cycle (third of full brightness), 0.5 is for -50% brightness, etc up to 1.0 for always-high signal when LED is 100% on. +We use `pwm-output` from `xod/core` to provide a PWM signal to our LED. The +`DUTY` input defines the duty cycle. The value 0.0 denotes the always-low +signal (LED is off), 0.33 is for a 33% cycle (one-third of full brightness), +0.5 is for +50% brightness, etc. up to 1.0 for the always-high signal when the LED is 100% +on. -Make sure to set `PORT` input value to 3 with Inspector. +Be sure to set the `PORT` input value to 3 with Inspector. -Next, we use `analog-input` from `xod/core` to read values from potentiometer. -Read values are available on its output `SIG` and take value 0.0 for one edge -point of potentiometer, 1.0 for another, and fractional values for anything +Next we use `analog-input` from `xod/core` to read values from the +potentiometer. Read values are available on its output `SIG` and take the value +0.0 for one of the potentiometer's limits, 1.0 for the other, and fractional +values for anything between them. -For `PORT` value of `analog-input` use value 14 which corresponds to pin A0 -on the board. +For the `PORT` value on the `analog-input`, use value 14 which corresponds to +pin A0 on the board.

XOD T0D0 -Currently ports are represented as simple numbers. So you can’t enter value +Ports are currently represented as simple numbers. So you can’t enter a value like `A0` directly. Just remember that A0 is 14 behind the scenes, A1 is 15, A2 is 16, etc.

@@ -65,90 +71,100 @@ A2 is 16, etc.

This inconvenience will be fixed in future versions of XOD.

-We need some source of pulses that would kick `analog-input` to update readings. -Again, `clock` would help. Set its `IVAL` to 0.02 seconds. That would give us -50 Hertz refresh rate. +We need some source of pulses that will kick `analog-input` to update its +readings. +The `clock` node will help here. Set its `IVAL` to 0.02 seconds. That would +give us a 50 Hertz refresh rate. -Now note that we have `SIG` output of our potentiometer linked to `DUTY` input -of our LED. They both operate on *number type* in range from 0.0 to 1.0, so no +Now note that we have the `SIG` output of our potentiometer linked to the +`DUTY` input of our LED. They both operate on a *number type* in the range from +0.0 to 1.0, so no conversions are necessary and we link them directly. -Finally, our program reads like this: +Our program now runs like this: -- On boot the clock is set up; -- Every 20 ms the clock kicks the analog input with potentiometer causing it - to read value again; -- The value is feed to PWM output with LED causing it to update its brightness. +- On boot, the clock is set up; +- Every 20 ms the clock kicks the analog input with the potentiometer, causing +it to read the value again; +- The value is fed to the PWM output with the LED, causing it to update its +brightness. -Upload the program to your board and checkout the result. +Upload the program to your board and check out the result. Compare to convert between numbers and booleans ----------------------------------------------- -Let’s modify our device a bit so that it would work as a smart light. It should -turn on when it’s too dark and turn off when it’s bright enough. For this we’re -going to replace the potentiometer with simple LDR-based voltage divider: +Let’s slightly modify our device to make a smart light. It should turn on +when it’s too dark and turn off when it’s bright enough. To do this, +we’re going to replace the potentiometer with a simple LDR-based voltage +divider: ![LDR and LED circuit](./ldr-led.fz.png) -Now our A0 port provides number values which correspond to ambient light -brightness. We should define a threshold value and if the value is under it, the -LED should be on, otherwise it should be off. So we should map a number value to -a boolean value somehow. +Now our A0 port provides number values that correspond to the brightness of the +ambient light. We should define a threshold value: if the value is under the +threshold, the +LED should be on; otherwise it should be off. So we need to somehow map a +number value to a boolean value. -A common way to do this is using comparison nodes `less`, `greater`, `equal` from -`xod/core`. Let’s do it: +This is commonly done using the comparison nodes `less`, `greater`, `equal` +from `xod/core`. Let’s do it: ![LDR and LED patch](./ldr-led.patch.png) -The `less` node compares two numbers on left hand side (`LHS`) and right hand side -(`RHS`) and outputs true iff `LHS` < `RHS`. Set `RHS` to a constant value using -Inspector. An exact value depends on characteristics of the resistors and desired -darkness threshold. You could experiment a bit with it. 0.5 could work fine as a -start value. +The `less` node compares the two numbers on the left hand side (`LHS`) and the +right hand side (`RHS`) and outputs true iff `LHS` < `RHS`. Set `RHS` to a +constant value using +Inspector. The exact value depends on characteristics of the resistors and +desired darkness threshold. You could experiment a bit with it. 0.5 should work +fine as a +starting value. -Upload the program. Make sure the LED is off when device starts. If not, adjust the -threshold value. Then cover the LDR with your hand to simulate darkness, the LED +Upload the program. Make sure the LED is off when the device starts. If not, +adjust the threshold value. Then cover the LDR with your hand to simulate +darkness. The LED should turn on. Look at the program again. Notice that we don’t tell our LED to turn off if -some condition met, then turn off if another computation gave us some value. -Instead we hard-wire pins of our nodes making the behavior explicit and easy -to reason about. That’s what differentiates functional/reactive paradigm of XOD +some condition met and then turn off against based on another computation. +Instead, we hard-wire our node's pins, making the behavior explicit and easy +to understand. That’s what differentiates XOD's functional/reactive paradigm from conventional programming like C. String type ----------- -Now you are familiar with pulses, booleans, and numbers. XOD also provides string -type. Strings are used to represent pieces of textual data. They could represent -single or multiple lines, or they could even be empty. +Now you are familiar with pulses, booleans, and numbers. XOD also provides a +string type. Strings are used to represent pieces of textual data. They may +represent single or multiple lines, and can even be empty. -`"Hello world!"` is a string, `""` is an empty string, `"0.42"` is a string too, -although it contains only numeric characters and looks like a number at a first sight. +`"Hello world!"` is a string. `""` is an empty string. `"0.42"` is a string +too, though it contains only numeric characters and looks like a number at a +first sight. -Let’s improve our device to show the lightness level on LCD screen. Use any -widespread text LCD to build circuit like one below: +Let’s improve our device to show the lightness level on an LCD screen. Use +any popular text LCD to build a circuit like one below: ![LDR, LED, and LCD circuit](./ldr-led-lcd.fz.png) -Add `text-lcd-16x2` node from `xod/common-hardware`. And give it the value of -`analog-input` as an input for the first line (`L1`). Link output of the `less` node +Add the `text-lcd-16x2` node from `xod/common-hardware` and give it the value +of `analog-input` as an input for the first line (`L1`). Link the output of the +`less` node to the `L2` input. ![LDR, LED, and LCD patch](./ldr-led-lcd.patch.png) -Now upload the program to the board. See how the data is displayed and updated as -you cover the sensor. +Now upload the program to the board. See how the data is displayed and updated +as you cover the sensor. -Note that `L1` and `L2` inputs of the LCD expect string type values. And we linked -number and boolean values to them. This is possible because automatic conversion -from any type to string is possible. Although the inverse isn’t true. +Note that the LCD's `L1` and `L2` inputs expect string values, but we linked +number and boolean values to them. This is possible because any type can be +automatically converted to a string. The reverse isn’t true. What’s next ----------- -If you’re going to build a project that is more complex than trivial, the program -created on a single pane would be too complicated. There is a mechanism in XOD that -allows you to easily create your own nodes from existing. Learn how to do it -in [Patch Nodes](../patch-nodes/) chapter. +If you’re going to build a project that is more complex than trivial, a +program created on a single patch would be too complicated. XOD has a mechanism +that lets you easily create your own nodes from existing nodes. Learn how to do +it in the [Patch Nodes](../patch-nodes/) chapter. diff --git a/docs/tutorial/install/README.md b/docs/tutorial/install/README.md index b965436f..2fda6253 100644 --- a/docs/tutorial/install/README.md +++ b/docs/tutorial/install/README.md @@ -5,82 +5,85 @@ title: Installing and Running XOD Installing and Running XOD ========================== -To work with XOD you would use XOD integrated development environment -(IDE for short). It comes in two flavors: browser-based version and -desktop version. +To work with XOD, you use the XOD integrated development environment (IDE for +short), which comes in two flavors: browser-based and desktop version. Browser-based IDE ----------------- -You can start [browser-based XOD IDE](/ide/) just by visiting the link. -However, since browser has few access permissions to computer’s file system and +You can start the [browser-based XOD IDE](/ide/) simply by visiting the link. +However, because the browser has relatively few permissions to access the +computer’s file system and USB-ports, its capabilities are quite limited. -Notably you can’t upload your program directly to the board from within browser -and you wouldn’t get convenient save/load functionality. +Notably, you can’t upload your program directly to the board from within your +browser and you won't get the convenient save/load functionality. -Although, you can import/export your programs as a single file (so called xodball) -and generate source code that you could copy and paste into Arduino IDE and then -upload it to the board via Arduino IDE. +However, you can import/export your programs as a single file (known as a +xodball), generate source code that you could copy and paste into an Arduino +IDE, and then upload it to the board via the Arduino IDE. Desktop IDE ----------- -XOD IDE for desktop requires installing but provides all features. It works on -Windows, macOS, and Linux. Find a distributive for your system on +XOD IDE for desktop requires installing, but provides all features. It works on +Windows, macOS, and Linux. Find a distribution package for your system on [downloads page](/downloads/). Upload your first program ------------------------- -Once you start XOD IDE you’ll see `welcome-to-xod` project open. It’s a primitive -demo project that—yes, you guess it—blinks a LED on the board. +Once you start XOD IDE, you’ll see the `welcome-to-xod` project open. It’s +a primitive demo project that—yes, you guessed it—blinks a LED on the board. ![XOD main window](./main-window.png) -Lets try to upload the program to your Arduino. +Let's try to upload the program to your Arduino IDE. -In main menu go to Deploy → Show Code for Arduino. You’ll see much of C++ source code -that once compiled and uploaded to the board would blink built-in LED. If you have -Arduino IDE installed, try it, copy-paste the code to Arduino IDE and click Upload. +In the main menu, go to Deploy → Show Code for Arduino. You’ll see much of +C++ source code that once compiled and uploaded to the board will blink the +built-in LED. If you have the Arduino IDE installed, try it. Copy and paste the +code to the Arduino IDE and click Upload.
Note -If you’ve previously seen what code to blink a LED looks like for Arduino, you could -be astonished looking at the amount of code given by XOD. Don’t worry, most of it is -a code of XOD runtime environment which actually give little overhead after compilation. -And you haven’t to understand how it actually works. For now think about it as -of black box. +If you’ve previously seen what code to blink an LED looks like for Arduino, +you might be astonished looking at the amount of code produced by XOD. Don’t +worry - most of it is code for the XOD runtime environment, which actually +creates little overhead after compilation. +You don't need to understand how it actually works. For now, think of it as a +black box.
-Upload directly from within XOD IDE +Upload directly from within the XOD IDE ----------------------------------- -The feature is only available in desktop version. Go to Deploy → Upload to Arduino. -Select your board model and serial port it is connected to: +This feature is only available in the desktop version. Go to Deploy → Upload +to Arduino. Select your board model and the serial port it is connected to: ![XOD model/port dialog](./board-selection.png) -Click Upload. Hold on. +Click Upload and wait. -Behind the scenes XOD uses Arduino IDE to compile and upload programs. So if -you have no Arduino IDE installed yet, you’ll be asked to download and install -it. Arduino IDE itself has package system to support various boards. If a package -to support your board is not installed yet, it would be automatically installed -as well. +Behind the scenes, XOD uses the Arduino IDE to compile and upload programs. So +if you have no Arduino IDE installed yet, you’ll be asked to download and +install it. The Arduino IDE itself has a package system to support various +boards. If a package supporting your board is not installed yet, it will also +be automatically installed. -If upload succeeds you’ll see 100% progress and a message from compiler: +If the upload succeeds, you’ll see 100% progress and a compiler message: ![XOD upload window](./upload.png) - -If you have a problem with upload, please report about it on our -[forum](//forum.xod.io). Describe what you do, what you expect to get, and -what you actually get. We will help. - +
+Feedback +If you have a problem with uploading, please report it on our +[forum](//forum.xod.io). Describe what you're doing, what you expect to get, +and what you actually get. We will help. +
What’s next ----------- -Now, when you can run IDE and upload programs, lets try to understand how and -why they work. Follow to [Nodes and Links](../nodes-and-links/) chapter. +Now that you can run the IDE and upload programs, let's try to understand how +and why they work. Go to the [Nodes and Links](../nodes-and-links/) chapter. diff --git a/docs/tutorial/nodes-and-links/README.md b/docs/tutorial/nodes-and-links/README.md index e7c234c1..7f9fd7d8 100644 --- a/docs/tutorial/nodes-and-links/README.md +++ b/docs/tutorial/nodes-and-links/README.md @@ -5,9 +5,9 @@ title: Nodes and Links Nodes and Links =============== -Now let’s look closely on the demo project which opened up on IDE start. It -blinks the LED connected to pin 13 of your board. Although many boards have -a built-in LED on that pin, let’s make it more visible by building a simple +Now let’s look closely at the demo project that opened up when you started +the IDE. It blinks the LED connected to pin 13 of your board. Many boards have +a built-in LED on that pin, but let’s make it more clear by building a simple circuit: ![LED on pin 13](./led-on-pin-13.fz.png) @@ -20,9 +20,9 @@ Why does it blink? The nodes --------- -You see four *nodes* linked together in a chain to make this possible. -Nodes are basic building blocks in XOD. Each of them make a tiny portion -of work and communicate to others. +You see four *nodes* linked together in a chain to implement the blinking. +Nodes are basic building blocks in XOD. Each of them handles a tiny portion of +work and communicates with other nodes. ![Blink patch](./blink.patch.png) @@ -30,83 +30,84 @@ Let’s talk about each node one by one from bottom to top. ### digital-output -This node represents a single physical pin on the board that is used -as an output, and can be either in high (enabled) or low (disabled) -state. We use it to switch our LED on and off. +This node represents a single physical output pin on the board. It can be +either in a high (enabled) or low (disabled) state. We use it to switch our LED +on and off. The node has three *inputs*. They are `PORT`, `SIG`, and `UPD`. -The `PORT` defines what physical pin corresponds to the node. Select -the node by clicking on it. You’ll see *Inspector* sidebar with -properties related to the selected node, i.e. our `digital-output`. +The `PORT` defines what physical pin corresponds to the node. Select the node +by clicking on it. You’ll see the *Inspector* sidebar with the properties of +the selected node, i.e. our `digital-output`. ![Inspector](./inspector.png) -Note that `PORT` value is set to 13’th pin. +Note that the `PORT` value is set to 13th pin. -Value on `SIG` input defines wether the digital output port should -go high or low state. In Inspector you see its value disabled with -placeholder “linked”. That’s fine because the value is defined by -an upstream node it is linked to. More on that later. +The value on the `SIG` input defines whether the digital output port should go +into a high or low state. In the Inspector, you see its value is disabled and +has the placeholder “linked”. That’s fine, because the value is defined +by a linked upstream node. More on that later. -Input `UPD` listens for *pulses* and used to actually update the signal and -physically update the physical pin according to `SIG` value. In other -words updating `SIG` value alone is not enough and wouldn’t lead to any +The `UPD` input listens for *pulses*, uses them to actually update the signal, +and physically updates the physical pin according to the `SIG` value. In other +words, updating the `SIG` value alone is not enough and wouldn’t lead to any visible results.
Note -

Although it could look excessive and strange at first, but any update in -the XOD program is accompanied by pulses. They’re like heartbeat which delivers -all updates to their destinations. No pulses, no observable effects.

+

Although it might seem excessive and strange at first, any update +in a XOD program is accompanied by pulses. They’re like a heartbeat that +delivers all updates to their destinations. No pulses, no observable +effects.

-

Splitting actual values and pulses helps to understand what and when could -ever happen. That makes programs more explicit and reliable.

+

Keeping actual values and pulses separate makes it easier to understand what +may happen and when. It makes programs more explicit and reliable.

-Finally, the `digital-output` node listens for pulses on its `UPD` pin and -once it get a pulse, it sets physical port 13 (`PORT`) to a state defined -by a value on the pin `SIG` at the moment when the pulse was recieved. +Finally, the `digital-output` node listens for pulses on its `UPD` pin. Once it +get a pulse, it sets physical port 13 (`PORT`) to a state defined by the value +on the `SIG` pin at the moment when the pulse was received. ### flip-flop -This node is like a virtual light switch that could be turned on (`SET`), -turned off (`RST`) or inverted to an opposite state (`TGL`). +This node is like a virtual light switch that can be turned on (`SET`), turned +off (`RST`) or toggled (`TGL`). -In addition to its inputs the `flip-flop` has two *outputs*. They are -`MEM` which provides current state (high or low) and `CHNG` which sends a -pulse right when value of `MEM` changes. +In addition to its inputs, the `flip-flop` node has two *outputs*. They are +`MEM`, which provides the current state (high or low), and `CHNG`, which sends +a pulse when the value of `MEM` changes. ### clock -The `clock` node emits a pulse on `TICK` output over equal periods of time. -The period is defined by the value of `IVAL` input. +The `clock` node emits a pulse on its `TICK` output at equal time intervals. +The interval is defined by the value of the `IVAL` input. Select the `clock` node and note the value set for `IVAL` in Inspector. -The interval is set up in seconds. +The interval is expressed in seconds. -The second input `RST` accepts pulses. On pulse the clock accept new interval -value and start counting from scratch. +The second input, `RST`, accepts pulses. On each pulse, the clock accept a new +interval value and starts counting from zero. -Clock is a very usual source of pulses. You’d use it quite often to drive -updates in your programs. +The clock node is a very common source of pulses. You’ll use it quite often +to drive updates in your programs. ### boot -The `boot` node is very simple. It sends a single pulse when program starts, -i.e. when the board gets powered on, resetted or reflashed. +The `boot` node is very simple. It sends a single pulse when the program +starts, i.e. when the board gets powered on, reset, or flashed.
Hint -

If pulses are heartbeats, then the clock is a heart. And the boot is a +

If pulses are heartbeats, then the clock is a heart. And the boot node is a defibrillator that starts the clock-heart.

The links --------- -You see that inputs and outputs of the nodes are connected together with lines. -These lines are called *links* in XOD. +You see that nodes' inputs and outputs are connected together with lines. These +lines are called *links* in XOD. ![Blink patch](./blink.patch.png) @@ -115,13 +116,13 @@ values and downstream nodes consume that values. What happens in our blink program? Take a look: -1. The `boot` node emits a pulse on program start +1. The `boot` node emits a pulse when the program starts. 2. The pulse goes to the `clock` node which start to tick at regular intervals 3. Each tick pulse goes to the `flip-flop` and toggles its state -4. The `flip-flop` provides its state value to the `digital-output` and asks - it to actually update by sending a pulse on each state update. +4. The `flip-flop` provides its state value to the `digital-output` and asks it +to update by sending a pulse each time the `flip-flop` changes state. -As a final result we see the LED blinking. +As a result, we see the LED blinking. Tweaking the program @@ -129,35 +130,37 @@ Tweaking the program Try to change something. -Select the `clock` node and set another `IVAL` value. Say, set it to 1.0 seconds, +Select the `clock` node and set a different `IVAL` value, e.g. 1.0 second, upload the updated program and observe the result. That’s not too interesting. Let’s add another LED. Improve your circuit: ![LED on pin 13 and 12](./led-on-pin-13-and-12.fz.png) -Place new node of type `digital-output`. To do this use Project Browser sidebar. -The `digital-output` is available in `xod/core` library. Hover the cursor over -the item and click on (+). +Place a new `digital-output` node. To do this, use the Project Browser sidebar. +The `digital-output` node is available in the `xod/core` library. Hover the +cursor over the item and click the (+). ![Project Browser](./project-browser.png) -You’ll see new node appeared in the main work area. Drag it to a slot you want. -The one next to existing `digital-output` would be fine. In Inspector set `PORT` -for the new node to 12 since it should control our new LED. +You’ll see a new node appear in the main workspace. Drag it to the slot you +want. The one next to the existing `digital-output` would be fine. In +Inspector, set the `PORT` for the new node to 12, since it will control our new +LED. Now we need to provide the new node with data. Link its `SIG` and `UPD` pins to -`flip-flop` outputs: +the `flip-flop` outputs: ![Blink two LEDs](./blink-two-leds.patch.png) Upload the updated program to the board. Whoa! Both LED’s are blinking. -Now let’s improve our program another bit and make the lights opposite. To do -this we should cut signal inversion into either of `digital-output` `SIG` links. -Node `not` under `xod/core` does exactly that. Delete existing link, place `not` -node and add new links so that signal from our `flip-flop` to `digital-output` -goes through it: +Now let’s improve our program some more and make the lights blink +alternately. To do this, we need to add a signal inversion into either the +`digital-output` or `SIG` links. +The `not` node under `xod/core` does exactly that. Delete the existing link, +place a `not` node, and add new links so that the signal from our `flip-flop` +to the `digital-output` goes through it: ![Blink two LEDs with inversion](./blink-two-leds-inv.patch.png) @@ -166,21 +169,22 @@ Upload the new version to the board. See the result? Disjoint graphs and independent tasks ------------------------------------- -In XOD nodes are not required to be connected in a single network. You can build +In XOD, nodes do not have to be connected in a single circuit. You can build two or more disjoint clusters of nodes to perform several tasks simultaneously. -Try to add yet another LED with absolutely independent blink interval and state: +Try adding yet another LED with an absolutely independent blink interval and +state: ![Blink with disjoint clusters](./blink-disjoint.patch.png) -Now we have three `digital-output`’s. It could be hard to understand which one -corresponds to what LED so it would be better to give them clear labels. To set -a custom label for a node select it and provide the label via Inspector: +Now we have three `digital-output` nodes. It can be hard to understand which +node corresponds to each LED, so it would be better to give them clear labels. +To set +a custom label for a node, select it and provide the label via Inspector: ![Edit label with Inspector](./inspector-label.png) -You can provide a custom label for any node. Now the program could look more -clear: +You can provide a custom label for any node. Now the program looks clearer: ![Labeled nodes](./blink-disjoint-labeled.patch.png) @@ -189,5 +193,6 @@ What’s next You’ve seen pins and links that carry values of different types. Some provide logical values and some transmit pulses. They are differentiated by colors. -There are more data types in XOD. Follow to [Types and -Conversions](../data-types-and-conversions/) chapter to learn more on this topic. +XOD has even more data types. Go to the [Types and +Conversions](../data-types-and-conversions/) chapter to learn more on this +topic. diff --git a/docs/tutorial/patch-nodes/README.md b/docs/tutorial/patch-nodes/README.md index dda5c4a6..24119fac 100644 --- a/docs/tutorial/patch-nodes/README.md +++ b/docs/tutorial/patch-nodes/README.md @@ -5,109 +5,114 @@ title: Patch Nodes Patch Nodes =========== -What you see in a tab of main work area is called a *patch*. In other -programming languages a XOD patch corresponds to a single source file or -module. +What you see on the tab in the main workspace is called a *patch*. A XOD patch +corresponds to a single source file or module in other programming languages. -Until now you’ve created single-patch programs and the patch was given name -`main` automatically for you. Creating a whole project on a single patch would -become messy once number of nodes and links will pass some limit. In many cases -it is a good idea to split complex patches into several that are easier to -understand and change. +Until now, you’ve created single-patch programs and the patch was +automatically named `main`. Creating a whole project in a single patch would +become messy once the number of nodes and links passed some limit. It is often +a good idea to split complex patches into several simpler patches that are +easier to understand and edit. -Furthermore, you can reuse a patch several times in your project with slightly -different parameters and in such way avoid nodes duplication. +Furthermore, you can reuse patches several times in your project with slightly +different parameters, thus avoiding node duplication. -The mechanism which lets you use one patches as nodes on other patches is -called *patch nodes*. +When you use one patch as a node in other patches it is called a *patch node*. -In this chapter we’re going to build simple watering station for two plants. -The idea is to water a plat if it’s soil became too dry and constantly show current -soil measurements on text LCD screen. +In this chapter, we’re going to build a simple watering station for two +plants. The idea is to water a plant if its soil became too dry and constantly +show the current +soil measurements on an LCD screen. Single plant station on a single patch -------------------------------------- -To start lets build a device that will work with a single plant. We’ll use single -patch `main` as in previous chapters. +To start, let's build a device that will work with a single plant. We’ll use +a single patch called `main`, as in previous chapters. -Create new project `water-station` and wire up your circuit: +Create a new project called `water-station` and wire up your circuit: ![Single plant circuit](./single-plant.fz.png) -Now make a following patch to control the device: +Now make the following patch to control the device: ![Single plant patch](./single-plant.patch.png) -Make sure to properly set port values for all hardware nodes. +Be sure to set port values properly for all hardware nodes. -You may noticed it is very similar to previously implemented smart light project. -All things we’ve changed is the sensor and the actuator. Moisture sensor replaced -the light sensor and the pump replaced the LED. +You may have noticed it is very similar to the previously implemented smart +light project. We've only changed the sensor and the actuator. The moisture +sensor replaced the light sensor, and the pump replaced the LED. -Upload the program to your board and test the device. Put the sensor into a glass -of water and take it out. See how the relay reacts. Observe the text shown on LCD. +Upload the program to your board and test the device. Put the sensor into a +glass of water and take it out. See how the relay reacts. Observe the text +shown on the LCD. -Let’s improve the program a bit and add pretty formatting to the messages. So that -instead of `"0.42"` the LCD would show something like `"Cactus: 42%"`. We achieve -this by adding two nodes. First one `to-percent` would convert number from sensor -to a string like `"42%"`. Second one `concat` would concatenate a constant prefix -`"Cactus: "` with the percent string: +Let’s improve the program a bit by adding pretty formatting to the messages +so that instead of `"0.42"`, the LCD would show something like `"Cactus: 42%"`. +We achieve this by adding two nodes. First, a `to-percent` node will convert a +number from the sensor to a string like `"42%"`. Second, the `concat` node will +concatenate the constant prefix `"Cactus: "` with the percent string: ![Single plant patch with percents](./single-plant-percent.patch.png) Extracting plant logic to a separate patch ------------------------------------------ -So far, so good. Now consider we want to extend the device to handle two plants -at once. We have another sensor, yet another relay, and pump. What we want to -share is LCD. Each plant’s message should be shown on its own line. +So far, so good. Now consider that we want to extend the device to handle two +plants at once. We have another sensor, yet another relay, and a pump. What we +want to +share is the LCD. Each plant’s message should be shown on its own line. -The very staightforward way to do it would be duplicate most of nodes related to -reading data, comparing it and formatting the result. But it would quickly became -unmanagable and error prone. Changes in one place would always require mirroring -the changes in other places by hand. +The very staightforward way to do it would be to duplicate most of nodes +related to reading and comparing data, and formatting the result. But it would +quickly become unmanagable and error prone. Changes in one place would always +require manually mirroring those changes in other places. -Patch nodes to the rescue. What do we have in common between different plants and -what differs? The logic is common, but the name of the plant, its watering threshold -value differs. Ports used to connect the sensor and the relay differs too. So -these things should be provided as parameters to our patch. +Patch nodes to the rescue. What do the different plants have in common? And +what is different? The logic is common, but the name of the plant and its +watering threshold value differ. The ports used to connect the sensor and the +relay are also different. So these things need to be provided as parameters to +our patch. -What the patch could output to the outside world? It could be a status message -string and a pulse that denotes that update is completed. +What might the patch output to the outside world? It could be a status message +string and a pulse that denotes that an update is complete. -Create new patch with File → New Patch and name it `plant`. Look at Project Browser -you’ll see that `plant` patch has appeared next to our `main`. +Create a new patch with File → New Patch, and name it `plant`. Look at +Project Browser. You’ll see that a `plant` patch has appeared next to our +`main`. -First of all we’re going to define its inputs and outputs. Expand +First of all, we’re going to define its inputs and outputs. Expand `xod/patch-nodes` in Project Browser and notice nodes with names like -`input-xxx` and `output-xxx`. They are called *terminals* and define patch -input and output pins. Place few inputs and outputs according to what we’ve +`input-xxx` and `output-xxx`. They are called *terminals*, and define the +patch's +input and output pins. Place a few inputs and outputs according to what we’ve planned to parametrize: ![Plant patch terminals](./plant-terminals.patch.png) -Now give the terminal nodes informative labels so that we can remember which one means -what: +Now give the terminal nodes informative labels so we can remember which one +means what: ![Plant patch terminals with labels](./plant-terminals-labeled.patch.png) -Switch back to the `main` patch. And try to add two nodes of our newly created type -`plant`: +Switch back to the `main` patch and try to add two nodes of our newly created +type `plant`: ![Patch nodes](./single-plant-with-patch-nodes.patch.png) -We’re going to use these two nodes to manage plants and move existing logic to the -shared `plant` patch. Let’s do it. +We’re going to use these two nodes to manage plants and move the existing +logic to the shared `plant` patch. Let’s do it.

XOD T0D0 -Currently there is no cut/copy/paste in XOD. Yes, that’s a pain. We’ll implement it -in future versions. If you would like to give the feature more priority we welcome you to -share your opinion on our forum.

+Currently there is no cut/copy/paste in XOD. Yes, that’s a pain. We’ll +implement it in future versions. If you would like to give the feature more +priority, we welcome you to share your opinion on our +forum.

-Here is final `main` patch: +Here is the final `main` patch: ![Main patch for two plants](./two-plants-main.patch.png) @@ -119,12 +124,12 @@ Wire up the circuit: ![Single plant circuit](./two-plants.fz.png) -Set parameters for your plants with Inspector. Then upload the program and see how -both plants are served simultaneously with a single patch. +Set parameters for your plants with Inspector. Then upload the program and see +how both plants are served simultaneously with a single patch. What’s next ----------- -Our quick tutorial is almost completed. The last thing to learn is what you can do -to build arbitrary projects with arbitrary hardware. -See [Complex Projects](../complex-projects/) chapter to know more. +Our quick tutorial is almost complete. The last thing to learn is what you can +do to build arbitrary projects with arbitrary hardware. See the [Complex +Projects](../complex-projects/) chapter to learn more.