mirror of
https://github.com/xodio/xod.git
synced 2026-03-09 18:26:54 +01:00
doc(docs): proofread the docs
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||
<div class="ui segment">
|
||||
<p>
|
||||
<span class="ui ribbon label">XOD T0D0</span>
|
||||
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.
|
||||
</p>
|
||||
@@ -65,90 +71,100 @@ A2 is 16, etc.
|
||||
<p>This inconvenience will be fixed in future versions of XOD.</p>
|
||||
</div>
|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||
<div class="ui segment">
|
||||
<span class="ui ribbon label">Note</span>
|
||||
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.
|
||||
</div>
|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
<Feedback>
|
||||
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>
|
||||
<div class="ui segment">
|
||||
<span class="ui ribbon label">Feedback</span>
|
||||
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.
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
@@ -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:
|
||||
|
||||

|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
@@ -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`.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||
<div class="ui segment">
|
||||
<span class="ui ribbon label">Note</span>
|
||||
<p>Although it could look excessive and strange at first, but <em>any</em> 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.</p>
|
||||
<p>Although it might seem excessive and strange at first, <em>any</em> 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.</p>
|
||||
|
||||
<p>Splitting actual values and pulses helps to understand what and when could
|
||||
ever happen. That makes programs more explicit and reliable.</p>
|
||||
<p>Keeping actual values and pulses separate makes it easier to understand what
|
||||
may happen and when. It makes programs more explicit and reliable.</p>
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
<div class="ui segment">
|
||||
<span class="ui ribbon label">Hint</span>
|
||||
<p>If pulses are heartbeats, then the clock is a heart. And the boot is a
|
||||
<p>If pulses are heartbeats, then the clock is a heart. And the boot node is a
|
||||
defibrillator that starts the clock-heart.</p>
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
@@ -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:
|
||||
|
||||

|
||||
|
||||
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 (+).
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
@@ -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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||

|
||||
|
||||
Now make a following patch to control the device:
|
||||
Now make the following patch to control the device:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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`:
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||
<div class="ui segment">
|
||||
<p><span class="ui ribbon label">XOD T0D0</span>
|
||||
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
|
||||
<a href="//forum.xod.io">share your opinion on our forum</a>.</p>
|
||||
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 <a href="//forum.xod.io">share your opinion on our
|
||||
forum</a>.</p>
|
||||
</div>
|
||||
|
||||
Here is final `main` patch:
|
||||
Here is the final `main` patch:
|
||||
|
||||

|
||||
|
||||
@@ -119,12 +124,12 @@ Wire up the circuit:
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user