EVIA Paradigma is visual programming: drag blocks from the palette onto the canvas, wire them together and press Run. The same program can be turned into C (C99, C11, C17) or C++ (C++98 to C++20) and compiled with Clang or GCC, or into code for Arduino and ESP32 boards.
The interface itself is in English, Russian or Armenian too: Settings > General > Interface language. Menus, buttons, the palette and the names on the blocks follow; the generated code and the compilers' messages stay in English. The change takes effect when EVIA Paradigma starts again.
Look and language. View > Theme chooses the IntelliJ light theme, the Darcula dark theme or the setting of your system; it changes at once and is remembered. Above the topic list you can read this guide in English, Russian or Armenian.
| Block | Code | What it does |
|---|---|---|
| Start / End | - | Where the main program begins and stops. |
| Set | x = x + 1 | Assigns a variable (or a field: this.count = 0). |
| Input | n | Asks for a value and stores it. |
"x = " + x | Prints the value of an expression. | |
| If / Else | x > 10 | Two outputs: then and else. |
| For | i = 1; i <= 10; i = i + 1 | Output body runs while the condition holds; wire the end of the body back to the For block. done continues after the loop. |
| While | n > 0 | Checks before every pass. |
| Do-While | n > 0 | Runs the body once, then checks. |
| Enter / Exit | exit name | Only inside a class method: where it begins and the ways it can end. |
The Board blocks (Pin Mode, Digital Write, Digital Read, Analog Read, Analog Write, Delay, Millis, UART, SPI, I2C) are for microcontrollers; see Arduino and ESP32 boards.
Values are numbers or text. Operators, from lowest to highest priority:
|| &&== != < <= > >= (texts compare alphabetically)+ - (+ joins text if either side is text)* / %- and !, parenthesesText uses double quotes and \", \\, \n escapes. A condition is true
when it is a non-zero number or a non-empty text.
A class bundles fields (data each object keeps) and methods (block programs that work on it). Create one with Edit > New Class, the palette's + New class, or select blocks and press Ctrl+G to turn them into a class.
this.name.n is read as this.n.init (button + Constructor). When an object is
created its fields get their initial values first, then init runs once.Drag a method from the Classes section of the palette onto the canvas to call it. Right-click the block, or double-click it, to choose the method, the object and the arguments. Blocks with the same object name share one object (and its fields); a block with no object name has an object of its own. Objects are created the first time they are used.
A module (*.eviam) is a file of classes that several programs can use.
File > New Project creates a folder with everything a program needs:
MyProject/ MyProject.eviaproj project settings main.evia the main program modules/ class modules build/ generated code (not committed) README.md .gitignore
Open it again with File > Open Project (choose the folder or the .eviaproj file). In a project,
modules are imported from and exported to modules/, and Generate code also writes
build/<name>.c or .cpp. The project remembers its language.
The Git menu runs the git installed on your computer and uses the login it already has
(Git Credential Manager, an SSH key or gh auth login). EVIA Paradigma never asks for or stores
passwords or tokens.
git init on branch main (new projects do this automatically when git is installed).owner/repo or a clone URL. Create repository on GitHub
opens github.com in your browser with the name filled in; create it empty, then press OK.Install git from git-scm.com if the menu says it is missing.
Generate code (F7) turns the whole program into one source file. Three drop-down lists in the toolbar (and in the code window) choose what you get; Run > Code Language and Mode has the same choices. Changing them in the code window generates the code again.
| List | Choices | What changes |
|---|---|---|
| Language | C99, C11, C17 C++98, C++11, C++14, C++17, C++20 |
C: a struct per class and functions Class_m_method(self, ...), a small runtime with only
the helpers the program uses. C++: a struct per class with member functions; C++98 uses plain pointers,
C++11/14 std::unique_ptr, C++17/20 std::variant and std::to_chars. |
| Flow | Structured Goto |
Structured: if/else, for, while, do/while
and switch (labels only where the wiring is not block-structured). Goto: every block is a label and every
wire a jump, closest to the diagram. |
| Values | Safe Fast |
Safe: numbers and text with exactly the interpreter's checks (undefined variables, division by zero, text that is
not a number, endless recursion). Fast: plain double variables and fields, text only in Print, no
runtime checks. A program that keeps text in a variable can't use Fast values; Generate code says which block. |
Every combination is tested to give the same output as the interpreter (with Fast values: for programs that run without errors). Right-click a block, a method or a class and choose View source code to see the code it became, highlighted, in the language you chose.
The code window can save the file, compile it and run it. For C it uses the matching C compiler (clang, gcc), the
right -std= and -lm. Settings > C, C++ and Python chooses the compiler: Clang (clang++ / clang) or
GCC (g++ / gcc, version 13 or newer). On Windows EVIA Paradigma can install either one for you: llvm-mingw
(Clang) or WinLibs (GCC, MinGW-w64). Visual Studio is not needed.
Three more languages for computers and phones. Like Python, they have no goto: Structured flow writes
nested if/else and while loops, and where the wiring is not block-structured (and
always with Goto flow) the diagram becomes a state machine, one branch per block. Safe and Fast values work as in C++,
with the interpreter's output, error messages and exit code.
| Language | What it makes | Needs |
|---|---|---|
| Java | One file with class Program. Compile & Run compiles it with javac and runs it.
Outside EVIA Paradigma: java Program.java. | A JDK, 17 or newer |
| Kotlin | One .kt file. Compile & Run makes a runnable jar with kotlinc and runs it. |
A JDK and kotlinc |
| Android | An app: the program's Print lines on the screen, Input in a text field with OK, and Run again. Build makes the APK; Install on Phone installs it with adb and starts it. | A JDK, kotlinc and the Android SDK |
Settings > Java and Kotlin: the JDK (found by itself from JAVA_HOME or PATH; Get downloads Eclipse
Temurin) and kotlinc (Get downloads JetBrains' compiler). Settings > Android: the SDK folder (Android
Studio's is found by itself; Get Android SDK... shows Google's licence and, once you accept it, downloads the
platform, build-tools and adb from Google), the application id (for example am.evia.counter), the name under
the icon and the phone. On the phone, turn on USB debugging: Settings > About phone, tap Build number
seven times, then Developer options > USB debugging.
EVIA Paradigma builds the app itself with the SDK's tools in a few seconds, without Gradle. The folder it writes (the
project's build/android, or EVIA Projects/Android/) is also an ordinary Android Studio project:
File > Open and Run.
The phone's sensors. The Phone Sensor block (palette group Phone) stores a reading in a variable:
ax = ACCEL_X. It reads ACCEL_X, ACCEL_Y, ACCEL_Z (m/s²),
GYRO_X, GYRO_Y, GYRO_Z (rad/s), LATITUDE, LONGITUDE,
ALTITUDE, GPS_ACCURACY and GPS_FIX (1 once the position is known). Run simulates a
phone on a table; Language Android reads the real sensors, and an app that reads the position asks for the location
permission. Delay and Millis work in Java, Kotlin and Android too. Examples: File > Open Example >
Android Phones (Hello world, GPS viewer, Motion tester).
Three more languages make code for microcontrollers. Both use fast values (numbers; text only in Print), and Print and Input go over the serial port at 115200 baud.
| Language | Boards | Built with |
|---|---|---|
| Arduino | Arduino Uno, Nano, Mega 2560, Leonardo, Micro, Pro Mini; ESP32, ESP32-S2, -S3, -C3, -C6, -H2 |
One sketch (.ino) with setup() and loop(); arduino-cli with the arduino:avr
and esp32:esp32 cores. |
| AVR C | the six Arduino AVR boards (ATmega328P, ATmega2560, ATmega32U4) | Bare-metal C: no Arduino core. Pins, timers, PWM, the ADC and the UART are driven through the chip's registers. avr-gcc and avr-libc build it, avrdude uploads it. |
| PIC32 C | nine PIC32MX chips: MX1xx/2xx (PIC32MX150F128B, 250F128B, 270F256B), MX3xx/4xx (320F128H, 340F512H, 440F256H, 460F512L), MX5xx/6xx/7xx (695F512L, 795F512L) the PIC32 Ethernet Starter Kit II (LED1 on RD0) and the chipKIT Pro MX7 (LD1 on RG12, Ethernet) | Bare-metal C for Microchip's XC32: clock, pins, PWM, ADC, UART, SPI and I2C are driven through the registers; no Harmony or plib.
xc32-gcc builds it, xc32-bin2hex makes the .hex, and an upload command of your choice (pic32prog by default) loads it. Boards pic32prog cannot program, such as the PIC32MX Ethernet Starter Kit II (its on-board programmer), the PICkit 4/5, ICD 4/5 and Snap, use Microchip's ipecmd: Settings > PIC32 > Get MPLAB IPE installs IPE from the MPLAB X v6.20 installer you download at microchip.com, and Programmer sets the upload command, e.g. ipecmd -TPPKOB -P{chip} -M -F{hex} -OL. |
| STM32 C | Blue Pill (STM32F103C8), Black Pill (STM32F411CE), Nucleo-F401RE, Nucleo-F411RE, STM32F4DISCOVERY (STM32F407VG), 32F429IDISCOVERY (STM32F429ZI, LED LD3 on PG13) | Bare-metal C for arm-none-eabi-gcc: clock, pins (PA0 ... PI15), PWM, the ADC, USART, SPI1 and I2C1 are driven through the registers, with the vector table, start-up code and linker script in the file; no HAL. OpenOCD uploads it through an ST-Link (built into the Nucleo and Discovery boards; a separate ST-Link V2 for the Pills). The same boards also take Arduino sketches with STMicroelectronics' core: Settings > STM32 > Install installs it once. |
Choose the board in the Board list next to the language (also in Settings). Build in the code window compiles for it; Upload builds and sends the program to the board on the serial port set in Settings.
| Block | Code | What it does |
|---|---|---|
| Pin Mode | LED_BUILTIN, OUTPUT | OUTPUT, INPUT or INPUT_PULLUP (a button to ground reads LOW when pressed). |
| Digital Write | LED_BUILTIN, HIGH | HIGH for any non-zero value, LOW for 0. |
| Digital Read | pressed = 4 | Stores 1 (HIGH) or 0 (LOW). |
| Analog Read | level = A0 | 0..1023 on AVR boards, 0..4095 on ESP32. |
| Analog Write | 5, brightness | PWM, 0 (off) .. 255 (always on). |
| Delay | 500 | Waits this many milliseconds. |
| Millis | t | Stores the milliseconds since the program started. |
| UART Open | 9600 | Starts the serial port used by the UART blocks, at this baud rate. |
| UART Write | 65 | Sends one byte (0..255). |
| UART Read | c | Stores the next received byte, or -1 if none has arrived. |
| SPI Open | 1000000 | Starts the SPI bus as master at this clock in Hz (mode 0, most significant bit first). |
| SPI Transfer | reply = 66 | Sends a byte and stores the byte that came back at the same time. |
| I2C Open | 100000 | Starts the I2C bus as master at this clock in Hz. |
| I2C Write | 80, 0, 42 | Writes a value to a register of the device at this 7-bit address: address, register, value. |
| I2C Read | v = 80, 0 | Stores the register's value, or -1 if no device answers at that address. |
| MQTT Connect | "network", "password", "broker.example.com", 1883 | Joins the network and connects to the MQTT broker. |
| MQTT Publish | "evia/temperature", t | Sends a message on that topic: a number or a text. |
| MQTT Subscribe | "evia/command" | Asks the broker for the messages of that topic (up to four topics). |
| MQTT Has Message | waiting = "evia/command" | Stores 1 when a message of that topic is waiting, 0 when none is. |
| MQTT Read | cmd = "evia/command" | Stores the number in the next message, or -1 if none has arrived. |
MQTT. The network name, password, broker and topics are fixed texts, because they are written into the program when it is built. PIC32 C drives an ESP8266 or ESP32 module with AT firmware on UART2 (RB5/RB1 on the 28-pin chips, RF4/RF5 on the others), so Print keeps UART1. Arduino on an ESP32 board uses the board's own WiFi. Run answers from a broker on your computer: publishing to a topic you subscribed to brings the message back. An AVR board refuses the MQTT blocks (one serial port, which Print uses), and so does an FPGA. A message is a number, written as Print writes it; since -1 also means "nothing has arrived", MQTT Has Message tells a real -1 apart. MQTT can also go through the chip's own Ethernet port on the MX695F512L, the MX795F512L and the Ethernet Starter Kit II: set PIC32 MQTT over to Ethernet in Settings and the generated file becomes an application for an MPLAB X Harmony project, which brings the TCP/IP stack. That route is experimental: it compiles against stub headers here, but has never been built against real Harmony or run on a board, so the WiFi module is still the tested one.
MQTT over Ethernet (experimental). For the MX695F512L, the MX795F512L and the PIC32 Ethernet Starter Kit II, Settings > PIC32 > PIC32 MQTT over > Ethernet makes the generated file an application for an MPLAB X Harmony project: Harmony brings the TCP/IP stack, the project keeps its own configuration, clock and main(), and you call app_run() from it. Enable TCP, the DHCP and DNS clients, the Ethernet MAC driver and the board's PHY (LAN8740 on the starter kit). The address comes from DHCP, so the network name and password are not used. This path compiles against stub headers in the checks, but has not been built against real Harmony or run on a board: the WiFi module is the tested one.
Pins can be numbers, expressions or the board's names LED_BUILTIN, A0 ... A15;
HIGH and LOW work in any expression. These names can't be used as variables.
The bus blocks work in Run and in all three board languages. Open a bus before using it; addresses are 7-bit and the numbers are decimal (80 is 0x50). On a PIC32 the pins are fixed per chip family and listed at the top of the generated code (the chip's own UART1, SPI and I2C1). Run simulates the buses: the UART's transmitter is wired to its receiver, so what UART Write sends comes back from UART Read (and also appears as output text), SPI's input is wired to its output, and one I2C device with 256 registers answers at address 80.
Run simulates an Arduino Uno: pin changes appear in the output as board [500 ms] pin 13 HIGH,
time only moves forward in Delay (the main window also really waits, unless the speed slider is at full speed),
a button on every input pin is pressed during the second half of each 2 seconds, and analog pins read a slow wave
0..1023..0. The program runs once, as if from setup(); afterwards the pins keep their state.
File > Open Example > Arduino Boards, ESP32 Boards, PIC32 Boards and STM32 Boards have blink, button, fade, an analog meter, a Led class, and UART, SPI and I2C examples.
Desktop languages (C, C++) can't use the Board blocks; Generate code says which block to change.
The toolchains are packages of the EVIA server (evia.am): arduino-cli, avr-gcc with avrdude, the Arm GNU Toolchain, OpenOCD and the OSS CAD Suite. The first start of an installed copy asks which ones to fetch; Settings > Packages and Updates (or Help > Check for Updates) shows what is installed and what is available, and installs, updates or removes them. The Get buttons in Settings fetch one tool the same way. Every download is checked before it is used, and nothing needs administrator rights: the packages live in your own data folder.
A newer EVIA Paradigma is a package too: it installs next to the one you have and starts the next time (or at once
with Restart Now). Nothing is uninstalled. On the command line: --packages, --install ID
(or --install updates) and --remove ID.
Terminal (toolbar, or Help > Terminal) opens a real terminal on a board's serial port (UART: port, baud rate, what Enter sends, local echo) or on another computer over SSH (password or key). Each session gets a tab; close the tab before Upload, which needs the port.
Three more languages, SystemVerilog, Verilog-2001 and VHDL (VHDL-2008), turn the same diagram into hardware. Every block becomes one state of a state machine and takes one clock cycle. Variables are signed 32-bit registers.
| Board | Chip | Clock | Pins you can use |
|---|---|---|---|
| Digilent Nexys A7-100T | Artix-7 XC7A100T | 100 MHz | LED0-15, SW0-15, BTNC/U/L/R/D, JA-JD, USB-UART |
| Digilent Arty A7-35 / A7-100 | Artix-7 | 100 MHz | 4 LEDs, 4 switches, 4 buttons, JA-JD, USB-UART |
| Digilent Basys 3 | Artix-7 XC7A35T | 100 MHz | 16 LEDs, 16 switches, 5 buttons, JA-JC, USB-UART |
| Olimex GateMateA1-EVB | GateMate CCGM1A1 | 10 MHz | LED0, BTN0, debug UART |
| Cologne Chip GateMate A1 evaluation board | GateMate CCGM1A1 | 10 MHz | LED0 only |
Pins are fixed when the design is built, so a pin must be a number or a name: LED0, SW3, BTNC, BTN0, JA1. A pin the board does not have is an error that lists the pins it has. A pin cannot be both read and written.
Whole numbers. Arithmetic wraps at 32 bits; / and % truncate toward zero, and dividing by 0 gives 0. Run uses double numbers, so 5 / 2 is 2.5 in Run and 2 on the FPGA. Not supported yet: classes, Input, Analog Read, SPI, I2C and text in variables (text works in Print).
Build and Upload. Artix-7: Vivado in batch mode, or the open-source flow (yosys, nextpnr-xilinx, Project X-Ray), chosen in Settings > FPGA. GateMate: yosys, nextpnr-himbaechel, gmpack. Upload uses Vivado or openFPGALoader. The pin constraints are in the first comment of the file, and -o on the command line also writes a .xdc or .ccf file.
Tested: simulation against Run, and synthesis with open-source tools. Not tested: Vivado, openXC7 and real boards.
Examples are in File > Open Example > FPGA Boards.
The Linux menu builds your own Linux for a BeagleBone Black or a Raspberry Pi 5 and writes it to an SD card. Choose a build system:
| Build system | What you get | First build |
|---|---|---|
| Buildroot 2026.02 (LTS) | A small system: kernel, BusyBox, the packages you ask for | about 1 hour, 15 GB |
| Yocto 5.0 Scarthgap (LTS) | A full distribution (core-image-base or core-image-minimal) | hours, about 90 GB |
| OpenWrt 25.12 (Image Builder) | A network OS with a web interface (LuCI), from ready packages | minutes, 3 GB |
| OpenWrt 25.12 (from source) | OpenWrt with any option (menuconfig) | about 2 hours, 30 GB |
Linux > New Linux Image opens the window: the board, a folder (no spaces in its path), the host name, a root password, an SSH server, Python 3, more packages by the build system's names. Build Image downloads the sources the first time, applies the choices and builds; the output scrolls in the window. Menuconfig opens a terminal with the build system's own menu for everything else. Write to SD Card lists only SD cards and USB drives, asks twice, and asks for your password to write.
Everything is in the folder: evia-linux.json (the choices) and build.sh, which runs on its own
too: ./build.sh all. The root password is kept in secrets/, readable only by you; the image gets
only its hash. Without a password, root logs in without one (Buildroot, Yocto) or is asked to set one (OpenWrt).
The builds run on Linux (on Windows: WSL 2; on a Mac: a Linux virtual machine). Check This Computer lists
what is missing and the command that installs it. On the board: a BeagleBone Black boots from the card when S2 is held
at power-on; a Raspberry Pi 5 boots from it by itself. Then Terminal logs in over UART (115200) or SSH. On the
command line: --linux DIR --system yocto --board bbb.
Sources as packages. Buildroot, Yocto (Poky and meta-raspberrypi) and OpenWrt (with the Image Builders for
both boards) are packages of the EVIA server: Get Sources in the window, or Settings > Packages and Updates,
group "Linux images". build.sh takes the sources from the installed package; without it, it downloads the
same pinned files and checks their SHA-256. The build itself still downloads the compilers and packages it needs.
| Ctrl+N | New program |
| Ctrl+Shift+N | New project |
| Ctrl+O | Open program |
| Ctrl+S / Ctrl+Shift+S | Save / Save As |
| Ctrl+A | Select all blocks |
| Delete | Delete the selected blocks |
| Ctrl+G | Group selected blocks into a class |
| F5 / Shift+F5 | Run / Stop |
| F7 | Generate code |
| Mouse wheel | Zoom the diagram in or out toward the pointer (25% to 300%) |
| Shift+wheel / Ctrl+wheel | Scroll sideways / up and down |
| Middle button + drag | Move the canvas (also when you start on a block) |
| Ctrl+= / Ctrl+- | Zoom in / out |
| Ctrl+0 / Ctrl+9 | Actual size (100%) / fit the diagram in the window |
| Ctrl+K | Git commit |
| F1 | This guide |
| Shift+click, drag a rectangle | Select several blocks |
| Right-click a block | Block menu (edit, View source code, delete ...) |
Code fields, the code window and the commit message editor use Vim keys (turn them off in Settings). Text starts in insert mode; Esc switches to normal mode.
h j k l, w b e, 0 ^ $, gg G, %, f ti a I A o O, x, dd, cw, yy, p, u, Ctrl+R, .v, V; search: /text, n N, *:w accept/save, :q close, :wq, :s/a/b/g, :make compile and run (code window), :vim open in real Vim