Repository: blynkkk/blynkkk.github.io
Branch: master
Commit: f914dc98a161
Files: 497
Total size: 2.4 MB
Directory structure:
gitextract_308jsc33/
├── Amendments.md
├── AppExport.md
├── BlynkFirmware.md
├── BlynkMainOperations.md
├── BlynkProtocol.md
├── BlynkServer.md
├── CNAME
├── FAQ.md
├── GettingStarted.md
├── HardwareSetUps.md
├── Implementing.md
├── IntroAndDownloads.md
├── License.md
├── Links.md
├── OTA.md
├── README.md
├── Roadmap.md
├── SUMMARY.md
├── Security.md
├── Sharing.md
├── SupportedHardware.md
├── Troubleshooting.md
├── Widgets-RU.md
├── Widgets.md
├── amendments.md
├── api/
│ ├── README.md
│ ├── api_getlastweekdata.md
│ ├── events-api.md
│ └── external_api.md
├── appexport.md
├── blynkfirmware.md
├── blynkmainoperations.md
├── blynkprotocol.md
├── blynkserver.md
├── css/
│ └── style.css
├── en/
│ ├── README.md
│ ├── api/
│ │ └── README.md
│ ├── infra/
│ │ └── backup_policy_FAQ.md
│ └── product/
│ ├── README.md
│ └── product-template-settings/
│ ├── README.md
│ ├── dashboard.md
│ ├── datastreams/
│ │ ├── README.md
│ │ ├── datastream_alias.md
│ │ ├── datastream_automation.md
│ │ ├── datastream_datatype.md
│ │ ├── datastream_default_value.md
│ │ ├── datastream_deicmals.md
│ │ ├── datastream_feedback.md
│ │ ├── datastream_invalidate.md
│ │ ├── datastream_min_max.md
│ │ ├── datastream_name.md
│ │ ├── datastream_save_raw.md
│ │ ├── datastream_sync.md
│ │ └── datastream_virtual_pin.md
│ ├── events/
│ │ ├── README.md
│ │ ├── event_code.md
│ │ ├── event_name.md
│ │ ├── event_notification.md
│ │ ├── event_notification_period.md
│ │ └── event_online_offline.md
│ ├── general-settings/
│ │ ├── README.md
│ │ ├── product_manufacturer.md
│ │ └── product_offline_ignore_period.md
│ └── metadata.md
├── en-product/
│ ├── create-new-product.md
│ ├── dashboard/
│ │ └── chart.md
│ ├── datastreams/
│ │ ├── README.md
│ │ ├── datastream-alias.md
│ │ ├── datastream-data-type.md
│ │ ├── datastream-invalidate-value.md
│ │ ├── datastream-min-max-values.md
│ │ ├── datastream-name.md
│ │ ├── datastream-save-raw-data.md
│ │ ├── datastream-virtual-pin.md
│ │ ├── decimals-formatting.md
│ │ ├── default-value.md
│ │ ├── expose-to-automation.md
│ │ ├── sync-with-the-latest-server-value.md
│ │ └── wait-for-confirmation-from-the-device.md
│ ├── events/
│ │ ├── README.md
│ │ ├── events-code.md
│ │ ├── events-name.md
│ │ ├── events-notification-period.md
│ │ ├── events-notification.md
│ │ └── events-online-offline.md
│ ├── general-settings/
│ │ ├── README.md
│ │ ├── manufacturer.md
│ │ └── offline-ignore-period.md
│ ├── metadata.md
│ ├── mobile-app-ui.md
│ └── web-dashboard.md
├── faq.md
├── firmware-api/
│ ├── README.md
│ └── disable-widgets-in-the-app.md
├── firmware-api-1/
│ └── disable-widgets-in-the-app.md
├── gettingstarted.md
├── google-code-prettify/
│ ├── CHANGES.html
│ ├── COPYING
│ ├── Makefile
│ ├── README.html
│ ├── examples/
│ │ └── quine.html
│ ├── js-modules/
│ │ ├── combinePrefixPatterns.js
│ │ ├── externs.js
│ │ ├── extractSourceSpans.js
│ │ ├── extractSourceSpans_test.html
│ │ ├── js_include.pl
│ │ ├── numberLines.js
│ │ ├── numberLines_test.html
│ │ ├── prettify.js
│ │ ├── recombineTagsAndDecorations.js
│ │ ├── recombineTagsAndDecorations_test.html
│ │ ├── regexpPrecederPatterns.pl
│ │ └── run_prettify.js
│ ├── src/
│ │ ├── lang-apollo.js
│ │ ├── lang-basic.js
│ │ ├── lang-clj.js
│ │ ├── lang-css.js
│ │ ├── lang-dart.js
│ │ ├── lang-erlang.js
│ │ ├── lang-go.js
│ │ ├── lang-hs.js
│ │ ├── lang-lisp.js
│ │ ├── lang-llvm.js
│ │ ├── lang-lua.js
│ │ ├── lang-matlab.js
│ │ ├── lang-ml.js
│ │ ├── lang-mumps.js
│ │ ├── lang-n.js
│ │ ├── lang-pascal.js
│ │ ├── lang-proto.js
│ │ ├── lang-r.js
│ │ ├── lang-rd.js
│ │ ├── lang-scala.js
│ │ ├── lang-sql.js
│ │ ├── lang-tcl.js
│ │ ├── lang-tex.js
│ │ ├── lang-vb.js
│ │ ├── lang-vhdl.js
│ │ ├── lang-wiki.js
│ │ ├── lang-xq.js
│ │ ├── lang-yaml.js
│ │ ├── prettify.css
│ │ ├── prettify.js
│ │ └── run_prettify.js
│ ├── styles/
│ │ ├── demo.html
│ │ ├── desert.css
│ │ ├── doxy.css
│ │ ├── index.html
│ │ ├── sons-of-obsidian.css
│ │ └── sunburst.css
│ ├── tests/
│ │ ├── debug-ie-compat-matrix.html
│ │ ├── ie-newline-copy-paste.html
│ │ ├── large_input_test.html
│ │ ├── prettify_test.html
│ │ ├── prettify_test_2.html
│ │ ├── run_prettify_test.html
│ │ ├── test_base.js
│ │ └── test_styles.css
│ └── tools/
│ ├── closure-compiler/
│ │ ├── COPYING
│ │ ├── README
│ │ ├── amd-externs.js
│ │ ├── compiler.jar
│ │ └── console-externs.js
│ ├── cut-release.sh
│ ├── googlecode_upload.py
│ ├── lang-handler-aliases.sh
│ └── yui-compressor/
│ ├── LICENSE.TXT
│ ├── README
│ └── yuicompressor-2.4.4.jar
├── hardwaresetups.md
├── http.md
├── https-api/
│ ├── api_getlastweekdata.md
│ ├── events-api.md
│ └── external_api.md
├── implementing.md
├── index.html
├── introanddownloads.md
├── license.md
├── links.md
├── mobile/
│ ├── README.md
│ ├── accelerometer.md
│ ├── barometer.md
│ ├── ble.md
│ ├── bluetooth.md
│ ├── bridge.md
│ ├── button.md
│ ├── datastreams.md
│ ├── device_selector.md
│ ├── device_tiles.md
│ ├── email.md
│ ├── eventor.md
│ ├── gauge.md
│ ├── gps_streaming.md
│ ├── gps_trigger.md
│ ├── graph.md
│ ├── gravity.md
│ ├── humidity.md
│ ├── image.md
│ ├── joystick.md
│ ├── labeled_value.md
│ ├── labeled_value_display.md
│ ├── lcd.md
│ ├── led.md
│ ├── level_display.md
│ ├── light.md
│ ├── map.md
│ ├── menu.md
│ ├── music_player.md
│ ├── notification.md
│ ├── numberInput.md
│ ├── number_input.md
│ ├── proximity.md
│ ├── report.md
│ ├── rgb.md
│ ├── rtc.md
│ ├── ru/
│ │ ├── accelerometer.md
│ │ ├── barometer.md
│ │ ├── ble.md
│ │ ├── bluetooth.md
│ │ ├── bridge.md
│ │ ├── button.md
│ │ ├── device_selector.md
│ │ ├── device_tiles.md
│ │ ├── email.md
│ │ ├── eventor.md
│ │ ├── gauge.md
│ │ ├── gps_streaming.md
│ │ ├── gps_trigger.md
│ │ ├── graph.md
│ │ ├── gravity.md
│ │ ├── humidity.md
│ │ ├── image.md
│ │ ├── joystick.md
│ │ ├── labeled_value.md
│ │ ├── labeled_value_display.md
│ │ ├── lcd.md
│ │ ├── led.md
│ │ ├── level_display.md
│ │ ├── light.md
│ │ ├── map.md
│ │ ├── menu.md
│ │ ├── music_player.md
│ │ ├── notification.md
│ │ ├── numberInput.md
│ │ ├── number_input.md
│ │ ├── proximity.md
│ │ ├── report.md
│ │ ├── rgb.md
│ │ ├── rtc.md
│ │ ├── segmentedSwitch.md
│ │ ├── segmented_control.md
│ │ ├── slider.md
│ │ ├── step.md
│ │ ├── styled_button.md
│ │ ├── super_chart.md
│ │ ├── table.md
│ │ ├── tabs.md
│ │ ├── temperature.md
│ │ ├── terminal.md
│ │ ├── textInput.md
│ │ ├── text_input.md
│ │ ├── time_input.md
│ │ ├── timeinput.md
│ │ ├── timer.md
│ │ ├── twitter.md
│ │ ├── value_display.md
│ │ ├── video.md
│ │ └── webhook.md
│ ├── segmentedSwitch.md
│ ├── segmented_control.md
│ ├── slider.md
│ ├── step.md
│ ├── styled_button.md
│ ├── super_chart.md
│ ├── table.md
│ ├── tabs.md
│ ├── temperature.md
│ ├── terminal.md
│ ├── textInput.md
│ ├── text_input.md
│ ├── time_input/
│ │ ├── README.md
│ │ └── untitled-1.md
│ ├── time_input.md
│ ├── timeinput.md
│ ├── timer.md
│ ├── twitter.md
│ ├── value_display.md
│ ├── video.md
│ └── webhook.md
├── mobile-app/
│ └── untitled.md
├── new/
│ └── en/
│ ├── product_categories.md
│ ├── product_hotspot_prefix.md
│ └── product_template_ids.md
├── ota.md
├── roadmap.md
├── ru/
│ ├── Amendments.md
│ ├── AppExport.md
│ ├── BlynkFirmware.md
│ ├── BlynkMainOperations.md
│ ├── BlynkProtocol.md
│ ├── BlynkServer.md
│ ├── FAQ.md
│ ├── GettingStarted.md
│ ├── HardwareSetUps.md
│ ├── Implementing.md
│ ├── IntroAndDownloads.md
│ ├── License.md
│ ├── Links.md
│ ├── OTA.md
│ ├── README.md
│ ├── Roadmap.md
│ ├── Security.md
│ ├── Sharing.md
│ ├── SupportedHardware.md
│ ├── Troubleshooting.md
│ ├── Widgets.md
│ ├── amendments.md
│ ├── appexport.md
│ ├── blynkfirmware.md
│ ├── blynkmainoperations.md
│ ├── blynkprotocol.md
│ ├── blynkserver.md
│ ├── faq.md
│ ├── gettingstarted.md
│ ├── hardwaresetups.md
│ ├── http.md
│ ├── implementing.md
│ ├── introanddownloads.md
│ ├── license.md
│ ├── links.md
│ ├── ota.md
│ ├── readme.md
│ ├── roadmap.md
│ ├── ru.md
│ ├── security.md
│ ├── sharing.md
│ ├── supportedhardware.md
│ ├── troubleshooting.md
│ └── widgets.md
├── scripts/
│ ├── flatdoc.js
│ ├── legacy.js
│ └── script.js
├── security.md
├── sharing.md
├── supportedhardware.md
├── table.css
├── themes/
│ ├── blynk.css
│ └── prism.css
├── troubleshooting.md
├── untitled/
│ ├── README.md
│ ├── accelerometer.md
│ ├── archive/
│ │ ├── README.md
│ │ ├── bad-request-github.md
│ │ ├── joystick.md
│ │ └── super_chart.md
│ ├── barometer.md
│ ├── ble.md
│ ├── blob/
│ │ ├── README.md
│ │ ├── master.md
│ │ ├── menu/
│ │ │ ├── README.md
│ │ │ └── blynkkk-blynkkk.github.io-1.md
│ │ ├── proximity.md
│ │ ├── styled_button/
│ │ │ ├── README.md
│ │ │ └── blynkkk-blynkkk.github.io.md
│ │ ├── textinput.md
│ │ └── timeinput/
│ │ ├── README.md
│ │ └── blynkkk-blynkkk.github.io-2.md
│ ├── bluetooth.md
│ ├── blynkkk-blynkkk.github.io/
│ │ ├── README.md
│ │ └── gps_trigger.md
│ ├── blynkkk-blynkkk.github.io-1/
│ │ ├── README.md
│ │ └── rtc.md
│ ├── blynkkk-blynkkk.github.io-2/
│ │ ├── README.md
│ │ └── eventor.md
│ ├── blynkkk-blynkkk.github.io-3/
│ │ ├── README.md
│ │ └── email.md
│ ├── blynkkk-blynkkk.github.io-4/
│ │ ├── README.md
│ │ └── tabs.md
│ ├── blynkkk-blynkkk.github.io-5/
│ │ ├── README.md
│ │ └── map.md
│ ├── blynkkk-blynkkk.github.io-6/
│ │ ├── README.md
│ │ └── ble.md
│ ├── blynkkk-blynkkk.github.io-7/
│ │ ├── README.md
│ │ └── device_tiles.md
│ ├── blynkkk-blynkkk.github.io-8/
│ │ ├── README.md
│ │ └── temperature.md
│ ├── blynkkk-blynkkk.github.io-9/
│ │ ├── README.md
│ │ └── value_display.md
│ ├── bridge.md
│ ├── build-software-better-together/
│ │ ├── README.md
│ │ └── video.md
│ ├── button.md
│ ├── commit/
│ │ ├── README.md
│ │ ├── change-float-to-double-41-b1f1a43.md
│ │ ├── gauge.md
│ │ └── music_player.md
│ ├── commits/
│ │ ├── README.md
│ │ ├── blynkkk-blynkkk.github.io.md
│ │ ├── light.md
│ │ └── time_input.md
│ ├── device_selector.md
│ ├── device_tiles.md
│ ├── email.md
│ ├── eventor.md
│ ├── find/
│ │ ├── README.md
│ │ ├── blynkkk-blynkkk.github.io.md
│ │ ├── image.md
│ │ └── terminal.md
│ ├── gauge.md
│ ├── gps_streaming.md
│ ├── gps_trigger.md
│ ├── graph.md
│ ├── gravity.md
│ ├── humidity.md
│ ├── image.md
│ ├── joystick.md
│ ├── labeled_value.md
│ ├── labeled_value_display.md
│ ├── lcd.md
│ ├── led.md
│ ├── level_display.md
│ ├── light.md
│ ├── map.md
│ ├── menu.md
│ ├── music_player.md
│ ├── network/
│ │ ├── README.md
│ │ ├── blynkkk-blynkkk.github.io.md
│ │ ├── numberinput.md
│ │ └── slider.md
│ ├── notification.md
│ ├── number_input.md
│ ├── numberinput.md
│ ├── proximity.md
│ ├── pull/
│ │ ├── README.md
│ │ ├── change-float-to-double-by-earlold-pull-request-41.md
│ │ ├── text_input.md
│ │ └── webhook.md
│ ├── report.md
│ ├── rgb.md
│ ├── rtc.md
│ ├── ru.md
│ ├── segmented_control.md
│ ├── segmentedswitch.md
│ ├── slider.md
│ ├── step.md
│ ├── styled_button.md
│ ├── super_chart.md
│ ├── table.md
│ ├── tabs.md
│ ├── temperature.md
│ ├── terminal.md
│ ├── textinput.md
│ ├── timeinput.md
│ ├── timer.md
│ ├── tree/
│ │ ├── README.md
│ │ ├── accelerometer/
│ │ │ ├── README.md
│ │ │ └── new.md
│ │ ├── barometer.md
│ │ ├── bluetooth/
│ │ │ ├── README.md
│ │ │ └── blynkkk-blynkkk.github.io-4.md
│ │ ├── blynkkk-blynkkk.github.io.md
│ │ ├── bridge.md
│ │ ├── button/
│ │ │ ├── README.md
│ │ │ └── blynkkk-blynkkk.github.io-3.md
│ │ ├── device_selector.md
│ │ ├── gps_streaming.md
│ │ ├── graph/
│ │ │ ├── README.md
│ │ │ └── blynkkk-blynkkk.github.io-6.md
│ │ ├── gravity/
│ │ │ ├── README.md
│ │ │ └── blynkkk-blynkkk.github.io-5.md
│ │ ├── humidity/
│ │ │ ├── README.md
│ │ │ └── blynkkk-blynkkk.github.io-1.md
│ │ ├── labeled_value.md
│ │ ├── labeled_value_display.md
│ │ ├── lcd.md
│ │ ├── led.md
│ │ ├── level_display.md
│ │ ├── master.md
│ │ ├── notification.md
│ │ ├── number_input/
│ │ │ ├── README.md
│ │ │ └── blynkkk-blynkkk.github.io.md
│ │ ├── report.md
│ │ ├── rgb.md
│ │ ├── segmented_control/
│ │ │ ├── README.md
│ │ │ └── blynkkk-blynkkk.github.io-2.md
│ │ ├── segmentedswitch.md
│ │ ├── step.md
│ │ ├── table/
│ │ │ ├── README.md
│ │ │ └── blynkkk-blynkkk.github.io.md
│ │ ├── timer.md
│ │ └── twitter.md
│ ├── twitter.md
│ ├── value_display.md
│ ├── video.md
│ └── webhook.md
├── widgets-ru.md
└── widgets.md
================================================
FILE CONTENTS
================================================
================================================
FILE: Amendments.md
================================================
#Blynk Amendments
###Tell every maker about Blynk
No pressure. Just do it. Now.
###Make your idea work without Blynk
Blynk can be easily integrated in almost any project. But before that - make it work **without** it. After you are sure that you can get all the sensor data or can control things from the code – integrate Blynk and make it even more awesome.
###Use search
We are always happy to chat and help, but remember - every time you ask the question that was answered many many times before that, Blynk Team is not building a new widget or new cool feature. So:
- google before asking
- use search on our forum, it works really well
- check Instructables
###Always wrap your code
Though shalt not post code without ```wrapping it```
================================================
FILE: AppExport.md
================================================
# App Export
## Firmware for ESP8266, NodeMCU, BlynkBoard, etc.
#### Prepare development environment
1. Install [Arduino IDE](https://www.arduino.cc/en/Main/Software)
2. Install [Blynk Library](https://github.com/blynkkk/blynk-library/releases/latest) and restart Arduino IDE
3. Install [ESP8266 core for Arduino](https://github.com/esp8266/Arduino#installing-with-boards-manager)
4. For Windows / OS X, you may need to install USB-Serial drivers according to your converter:
- СP2102: https://www.silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx
- FTDI (FT232, etc): http://www.ftdichip.com/Drivers/VCP.htm
- *TODO: Link to drivers for CH340 and PL2303.*
5. If your board has a NeoPixel RGB LED, install [Adafruit NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel) library from Library Manager
#### Build your Firmware
1. Open our example in Arduino IDE: ```File -> Examples -> Blynk -> Provisioning -> Blynk_ESP8266```
2. Open ```Settings.h``` tab.
3. Configure your firmware:
* ```BOARD_NAME``` - ...
* ```BOARD_VENDOR``` - ...
* ```PRODUCT_WIFI_SSID``` - ...
#### Upload firmare
1. Select your board type: ```Tools -> Board -> [Your Board]```
2. Select your port: ```Tools -> Port -> [...]```
3. Verify and Upload!
Note that for Blynk Board, you can select board type ```NodeMCU 1.0```.
================================================
FILE: BlynkFirmware.md
================================================
#Blynk Firmware
## Configuration
### Blynk.begin()
The easiest way to configure Blynk is to use ```Blynk.begin()```:
```cpp
Blynk.begin(auth, ...);
```
It has multiple parameters for different hardware models and it also depends on the type of connection. Follow the example sketches for your specific hardware model.
What happens inside of ```Blynk.begin()``` function:
1. Connection to the network (WiFi, Ethernet, ...)
2. Call of ```Blynk.config(...)``` to set Auth Token, Server Address, etc.
3. Attempts to connect to the server once (can block for more than 30s)
If your shield/connection type is not supported yet - you can implement it by yourself. [Here are some examples](https://github.com/blynkkk/blynk-library/tree/master/examples/More/ArduinoClient).
### Blynk.config()
```config()``` allows you to manage network connection. You can set up your connection type (WiFi, Ethernet, ...) by yourself, and then call:
```cpp
Blynk.config(auth, server, port);
```
or just
```cpp
Blynk.config(auth);
```
**NOTE: After ``` Blynk.config(...) ``` is called, your hardware is not yet connected to the server.**
It will try to connect while until it hits first instance of ``` Blynk.run() ``` or ``` Blynk.connect() ```routine.
To skip connecting to the server or to disconnect manually, call ``` Blynk.disconnect() ``` after configuration.
Use ```connectWiFi``` to conveniently set up WiFi connection:
```cpp
Blynk.connectWiFi(ssid, pass);
```
To connect to open WiFi networks, set pass to an empty string (```""```).
## Connection management
There are several functions to help with connection management:
### Blynk.connect()
This functions will continue trying to connect to Blynk server.
Returns `true` when connected, `false` if timeout have been reached.
Default timeout is 30 seconds.
```cpp
bool result = Blynk.connect();
bool result = Blynk.connect(timeout);
```
### Blynk.disconnect()
Disconnects hardware from Blynk server:
```cpp
Blynk.disconnect();
```
### Blynk.connected()
Returns `true` when hardware is connected to Blynk Server, `false` if there is no active connection to Blynk server.
```cpp
bool result = Blynk.connected();
```
### Blynk.run()
This function should be called frequently to process incoming commands and perform housekeeping of Blynk connection.
It is usually called in ``` void loop() {} ```.
This command can be initiated it in other places of your code unless you run out of heap memory (in the cascaded functions with local memory).
For example, it is not recommended to call ``` Blynk.run() ``` inside of the ```BLYNK_READ ``` and ``` BLYNK_WRITE ``` functions on low-RAM devices.
## Digital & Analog pins control
Blynk library can perform basic pin IO (input-output) operations out-of-the-box:
digitalRead
digitalWrite
analogRead
analogWrite (PWM or Analog signal depending on the platform)
No need to write code for simple things like LED, Relay control and analog sensors. Just choose a corresponding Pin in Blynk app and control it directly with no additional code
## Virtual pins control
Virtual Pins is a way to exchange any data between your hardware and Blynk app.
Think about Virtual Pins as channels for sending any data. Make sure you differentiate Virtual Pins from physical GPIO
pins on your hardware. Virtual Pins have no physical representation.
Virtual Pins are commonly used to interface with other libraries (Servo, LCD and others) and implement custom logic.
The device can send data to the App using ```Blynk.virtualWrite(pin, value)``` and receive data from the App using ```BLYNK_WRITE(vPIN)```. Read below
#### Virtual Pin data types
All Virtual Pin values are always sent as Strings and there are no practical limits on the data that can be sent.
However, there are certian limitations on the hardware side when dealing with numbers. For example, the integer on Arduino
is 16-bit, allowing range -32768 to 32767.
To interpret incoming data as Integers, Floats, Doubles and Strings use:
```cpp
param.asInt();
param.asFloat();
param.asDouble();
param.asStr();
```
You can also get the RAW data from the param buffer:
```cpp
param.getBuffer()
param.getLength()
```
### Blynk.virtualWrite(vPin, value)
**NOTE: Use BlynkTimer when you use this command to send data. Otherwise your hardware will be disconnected from the server**
Send data in various formats to Virtual Pins.
```cpp
// Send string
Blynk.virtualWrite(pin, "abc");
// Send integer
Blynk.virtualWrite(pin, 123);
// Send float
Blynk.virtualWrite(pin, 12.34);
// Send multiple values as an array
Blynk.virtualWrite(pin, "hello", 123, 12.34);
// Send RAW data
Blynk.virtualWriteBinary(pin, buffer, length);
```
Calling ```virtualWrite``` attempts to send the value to the network immediately.
**Note:** For virtual pins with numbers > 127, the `V128` syntax is not available.
Please use plain virtual pin number, for example:
```cpp
Blynk.virtualWrite(128, "abc");
```
## BlynkTimer
It's important to send data in intervals and keep the void loop() as clean as possible.
`BlynkTimer` allows you to send data periodically with given intervals not interfering with Blynk library routines
`Blynk Timer` inherits [SimpleTimer Library](http://playground.arduino.cc/Code/SimpleTimer), a well known and widely used library to time multiple events on hardware.
`BlynkTimer` is included in Blynk library by default and there is no need to install SimpleTimer separately or include `SimpleTimer.h`
- A single `BlynkTimer` object allows to schedule up to 16 timers
- Improved compatibility with boards like `Arduino 101`, `Intel Galileo`, etc.
- When a timer struggles to run multiple times (due to a blocked `loop`), it just skips all the missed intervals, and calls your function only once. This differs from `SimpleTimer`, which could call your function multiple times in this scenario.
For more information on timer usage, please see: http://playground.arduino.cc/Code/SimpleTimer
And here is a BlynkTimer [example sketch](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/PushData/PushData.ino#L30).
Please also remember that a single ```BlynkTimer``` can schedule many timers, so most probably you need only one instance of BlynkTimer in your sketch.
### BLYNK_WRITE(vPIN)
```BLYNK_WRITE``` is a function called every time device gets an update of Virtual Pin value from the server (or app):
To read the received data use:
```cpp
BLYNK_WRITE(V0)
{
int value = param.asInt(); // Get value as integer
// The param can contain multiple values, in such case:
int x = param[0].asInt();
int y = param[1].asInt();
}
```
**`BLYNK_WRITE` can't be used inside of any loop or function. It's a standalone function.**
**Note:** For virtual pins with numbers > 127, please use `BLYNK_WRITE_DEFAULT()` API
### BLYNK_READ(vPIN)
```BLYNK_READ``` is function called when device is requested to send it's current value of Virtual Pin to the server. Normally, this function should contain ```Blynk.virtualWrite``` call(s).
```cpp
BLYNK_READ(V0)
{
Blynk.virtualWrite(V0, newValue);
}
```
**Note:** For virtual pins with numbers > 127, please use `BLYNK_READ_DEFAULT()` API
### BLYNK_WRITE_DEFAULT()
Redefines the handler for all pins that are not covered by custom ```BLYNK_WRITE``` functions.
```cpp
BLYNK_WRITE_DEFAULT()
{
int pin = request.pin; // Which exactly pin is handled?
int value = param.asInt(); // Use param as usual.
}
```
### BLYNK_READ_DEFAULT()
Redefines the handler for all pins that are not covered by custom ```BLYNK_READ``` functions.
```cpp
BLYNK_READ_DEFAULT()
{
int pin = request.pin; // Which exactly pin is handled?
Blynk.virtualWrite(pin, newValue);
}
```
### BLYNK_CONNECTED()
Use this function when you need to run certain routine when hardware connects to Blynk Cloud or private server. It's common to call sync functions inside of this function.
```cpp
BLYNK_CONNECTED() {
// Your code here
}
```
### BLYNK_APP_CONNECTED()
This function is called every time Blynk app client connects to Blynk server.
```cpp
BLYNK_APP_CONNECTED() {
// Your code goes here
}
```
**Note: Ennable this feature in Project Settings first:**
Caveats: please properly escape less-thans. x<y
instead of x<y, and use " instead of
" for string delimiters. Put code snippets in
<pre class="prettyprint">...</pre>
or <code class="prettyprint">...</code>
and it will automatically be pretty printed.
The comments in prettify.js are authoritative but the lexer
should work on a number of languages including C and friends,
Java, Python, Bash, SQL, HTML, XML, CSS, Javascript, Makefiles,
and Rust.
It works passably on Ruby, PHP, VB, and Awk and a decent subset of Perl
and Ruby, but, because of commenting conventions, but doesn't work on
Smalltalk. Other languages are supported via extensions:
If you'd like to add an extension for your favorite language, please
look at src/lang-lisp.js and file an
issue including your language extension, and a testcase. You don't need to specify the language since You may also use the
HTML 5 convention of embedding a code element inside the
Yes. Prettifying obfuscated code is like putting lipstick on a pig
— i.e. outside the scope of this tool. It's been tested with IE 6, Firefox 1.5 & 2, and Safari 2.0.4.
Look at the test page to see if it
works in your browser. See the change log Apparently wordpress does "smart quoting" which changes close quotes.
This causes end quotes to not match up with open quotes.
This breaks prettifying as well as copying and pasting of code samples.
See
WordPress's help center for info on how to stop smart quoting of code
snippets. You can use the For example
You can use the For a more complete example see the issue22
testcase. If you are calling
Prettify adds
Instead of
Below is the content of this page prettified. The
The line numbers to the left appear because the preceding comment
* The HTML DOM structure:
* corresponds to the HTML
* {@code print 'Hello '
[Example](https://github.com/blynkkk/blynk-library/blob/master/examples/More/AppConnectedEvents/AppConnectedEvents.ino)
### BLYNK_APP_DISCONNECTED()
This function is called every time the Blynk app disconnects from Blynk Cloud or private server.
```cpp
BLYNK_APP_DISCONNECTED() {
// Your code here
}
```
**Note: Enable this feature in Project Settings first:**
[Example](https://github.com/blynkkk/blynk-library/blob/master/examples/More/AppConnectedEvents/AppConnectedEvents.ino)
### Blynk.syncAll()
Requests all stored on the server latest values for all widgets. All analog/digital/virtual pin values and states will be set to the latest stored value. Every virtual pin will generate BLYNK_WRITE() event.
```cpp
BLYNK_CONNECTED() {
Blynk.syncAll();
}
```
### Blynk.syncVirtual(vPin)
This command updates individual Virtual Pin to the latest stored value on the server. When it's used, a corresponding ```BLYNK_WRITE``` handler is called.
```cpp
Blynk.syncVirtual(V0);
```
To update multiple pins, use:
```
Blynk.syncVirtual(V0, V1, V6, V9, V16);
```
### Blynk.setProperty(vPin, "property", value)
This command allows [changing widget properties](#blynk-main-operations-change-widget-properties)
## Debugging
### #define BLYNK_PRINT
### #define BLYNK_DEBUG
To enable debug prints on the default Serial port add on the top of your sketch
**IMPORTANT: This should be the first line in your code**:
```cpp
#define BLYNK_PRINT Serial // Defines the object that is used for printing
#define BLYNK_DEBUG // Optional, this enables more detailed prints
```
Then enable Serial Output in setup():
```cpp
Serial.begin(9600);
```
Open Serial Monitor and you'll see the debug prints.
You can also use spare Hardware serial ports or SoftwareSerial for debug output (you will need an adapter to connect to it with your PC).
**WARNING:** Enabling ```BLYNK_DEBUG``` will slowdown your hardware processing speed up to 10 times!
### BLYNK_LOG()
When ```BLYNK_PRINT``` is defined, you can use ```BLYNK_LOG``` to print your logs. The usage is similar to ```printf```:
```cpp
BLYNK_LOG("This is my value: %d", 10);
```
On some platforms (like Arduino 101) the ```BLYNK_LOG``` may be unavailable, or may just use too much resources.
In this case you can use a set of simpler log functions:
```cpp
BLYNK_LOG1("Hello World"); // Print a string
BLYNK_LOG1(10); // Print a number
BLYNK_LOG2("This is my value: ", 10); // Print 2 values
BLYNK_LOG4("Temperature: ", 24, " Humidity: ", 55); // Print 4 values
...
```
## Minimizing footprint
To minimize the program Flash/RAM, you can disable some of the built-in functionality:
1. Comment-out ```#define BLYNK_PRINT``` to remove prints
2. Put on the top of your sketch:
```
#define BLYNK_NO_BUILTIN // Disable built-in analog & digital pin operations
#define BLYNK_NO_FLOAT // Disable float operations
```
## Porting, hacking
If you want to dive into crafting/hacking/porting Blynk library implementation, please also check [this documentation](https://github.com/blynkkk/blynk-library/tree/master/extras/docs).
================================================
FILE: BlynkMainOperations.md
================================================
# Blynk main operations
## Virtual Pins
Blynk can control Digital and Analog I/O Pins on you hardware directly. You don't even need to write code for it.
It's great for blinking LEDs, but often it's just not enough...
We designed Virtual Pins to send **any** data from your microcontroller to the Blynk App and back.
Anything you connect to your hardware will be able to talk to Blynk.
With Virtual Pins you can send something from the App, process it on microcontroller and then send it back to the smartphone. You can trigger functions, read I2C devices, convert values, control servo and DC motors etc.
Virtual Pins can be used to interface with external libraries (Servo, LCD and others) and implement custom functionality.
Hardware may send data to the Widgets over the Virtual Pin like this:
```cpp
Blynk.virtualWrite(pin, "abc");
Blynk.virtualWrite(pin, 123);
Blynk.virtualWrite(pin, 12.34);
Blynk.virtualWrite(pin, "hello", 123, 12.34);
```
For more information about virtual pins, [read this](/#blynk-firmware-virtual-pins-control)
## Send data from app to hardware
You can send any data from Widgets in the app to your hardware.
All [Controller Widgets](/#widgets-controllers) can send data to Virtual Pins on your hardware.
For example, code below shows how to get values from the Button Widget in the App
```cpp
BLYNK_WRITE(V1) //Button Widget is writing to pin V1
{
int pinData = param.asInt();
}
```
When you press a Button, Blynk App sends ```1``` On the second click - it sends ```0```
This is how Button Widget is set up:
Full example sketch: [Get Data](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/GetData/GetData.ino#L24)
### Sending array from Widget
Some Widgets (e.g Joystick, zeRGBa) have more than one output.
This output can be written to Virtual Pin as an array of values.
On the hardware side - you can get any element of the array [0,1,2...] by using:
```cpp
BLYNK_WRITE(V1) // Widget WRITEs to Virtual Pin V1
{
int x = param[0].asInt(); // getting first value
int y = param[1].asInt(); // getting second value
int z = param[N].asInt(); // getting N value
}
```
**Sketch:** [JoystickTwoAxis](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/JoystickTwoAxis/JoystickTwoAxis.ino#L24)
## Get data from hardware
There are two ways of pushing data from your hardware to the Widgets in the app over Virtual Pins.
### Perform requests by Widget
- Using Blynk built-in reading frequency while App is active by setting 'Reading Frequency' parameter to some interval:
```cpp
BLYNK_READ(V5) // Widget in the app READs Virtal Pin V5 with the certain frequency
{
// This command writes Arduino's uptime in seconds to Virtual Pin V5
Blynk.virtualWrite(5, millis() / 1000);
}
```
**Sketch:** [PushDataOnRequest](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/PushDataOnRequest/PushDataOnRequest.ino#L26)
### Pushing data from hardware
If you need to PUSH sensor or other data from your hardware to Widget, you can write any logic you want.
Just set the frequency to PUSH mode. Any command that hardware sends to Blynk Cloud is automatically stored on server
and you get this info either with [History Graph](/#widgets-displays-superchart) widget
or with [HTTP API](http://docs.blynkapi.apiary.io/#reference/0/pin-history-data/get-all-history-data-for-specific-pin).
We recommend sending data in intervals and avoiding [Flood Error](https://docs.blynk.cc/#troubleshooting-flood-error).
You can use timers like [BlynkTimer](/#blynk-firmware-blynktimer).
Please read instructions inside this [example sketch](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/PushData/PushData.ino) for more details.
Here is how it can work:
```cpp
#include
You'll see list of devices :
So you can add new device :
After above steps, every widget will have one more field "Target" :
Now you need to assign widget to device and after that widget will control only this specific device.
That's it! Now you need to upload sketches with correct Auth Tokens to your hardware.
### Tags
Tags feature allows you to group multiple devices. Tags are very useful in case you want to control few devices with
1 widget. For example, imagine a case when you have 3 smart bulbs and you want to turn on all those bulbs with one
single click. You need to assign 3 devices to 1 tag and assign tag to button. That's it.
Tag widgets also support state syncing. So you can get state of widget from your hardware. However you can't update
state of such widgets from hardware.
## Devices online status
Blynk app has support for online statuses for multiple devices.
In ideal world when device closes tcp connection with some ```connection.close()``` - connected server will get notification
regarding closed connection. So you can get instant status update on UI. However in real world this mostly exceptional situation.
In majority of cases there is no easy and instant way to find out that connection is not active anymore.
That's why Blynk uses ```HEARTBEAT``` mechanism. With this approach hardware periodically sends ```ping``` command with predefined
interval (10 seconds by default, ```BLYNK_HEARTBEAT``` [property](https://github.com/blynkkk/blynk-library/blob/master/src/Blynk/BlynkConfig.h)).
In case hardware don't send anything within 10 seconds server waits additional 5 seconds and after that connection
assumed to be broken and closed by server. So on UI you'll see connection status update only after 15 seconds when it is
actually happened.
You can also change ```HEARTBEAT``` interval from hardware side via ```Blynk.config```. In that case ```newHeartbeatInterval * 2.3``` formula will be applied. So in case you you decided to set ```HEARTBEAT``` interval to
5 seconds. You'll get notification regarding connection with 11 sec delay in worst case.
## Project Settings
Every project has it's own settings:
- **Theme** - switch between the Light and Black Blynk Theme (Business accounts have wider choice);
- **Keep screen always on** - allows you to use the Blynk app without going to the sleep mode (usually all mobile devices do that);
- **Send app connected command** - with this option enabled the server will send "App Connected" and "App Disconnected" commands
to your hardware when your Blynk app goes online/offline. [Usage example](https://github.com/blynkkk/blynk-library/blob/master/examples/More/AppConnectedEvents/AppConnectedEvents.ino);
- **Do not show offline notifications** - right now, for debugging purposes, every time your hardware goes offline - the Blynk
Server will notify you with popup in the app about that. However, when debugging is not needed or the Blynk app is used only
via HTTP/S this notifications are meaningless. So this switch allows you to turn off this popups. Also this switch turns off
the Push notification "Notify when offline" option.
## Change Widget properties
Changing some of the widget properties from hardware side is also supported.
For example, you can change the color of LED widget based on a condition:
```
//change LED color
Blynk.setProperty(V0, "color", "#D3435C");
//change LED label
Blynk.setProperty(V0, "label", "My New Widget Label");
//change MENU labels
Blynk.setProperty(V0, "labels", "Menu Item 1", "Menu Item 2", "Menu Item 3");
```
[Set Property for single value field](https://github.com/blynkkk/blynk-library/blob/master/examples/More/SetProperty/SetProperty_SingleValue/SetProperty_SingleValue.ino)
[Set Property for multi value field](https://github.com/blynkkk/blynk-library/blob/master/examples/More/SetProperty/SetProperty_MultiValue/SetProperty_MultiValue.ino)
**NOTE : ** Changing these parameters work **only** for widgets attached to Virtual pins (analog/digital pins won't work).
Four widget properties are supported - ```color```, ```label```, ```min```, ```max``` for all widgets :
```label``` is string for label of all widgets.
```color``` is string in [HEX](http://www.w3schools.com/html/html_colors.asp) format (in the form: #RRGGBB,
where RR (red), GG (green) and BB (blue) are hexadecimal values between 00 and FF). For example :
```
#define BLYNK_GREEN "#23C48E"
#define BLYNK_BLUE "#04C0F8"
#define BLYNK_YELLOW "#ED9D00"
#define BLYNK_RED "#D3435C"
#define BLYNK_DARK_BLUE "#5F7CD8"
```
```min```, ```max``` - minimum and maximum values for the widget (for example range for the Slider).
This numbers may be float.
On firmware side, widget objects also support ```setLabel()``` and ```setColor()``` functions.
Widget specific properties:
**Button**
```onLabel``` / ```offLabel``` is string for ON/OFF label of button;
**Styled Button**
```onLabel``` / ```offLabel``` is string for ON/OFF label of button;
```onColor``` / ```offColor``` is string in HEX format for ON/OFF colors of the button;
```onBackColor``` / ```offBackColor``` is string in HEX format for ON/OFF colors of the button background.
**Music Player**
```isOnPlay``` is boolean accepts true/false.
```
Blynk.setProperty(V0, "isOnPlay", "true");
```
**Menu**
```labels``` is list of strings for Menu widget selections;
```
Blynk.setProperty(V0, "labels", "label 1", "label 2", "label 3");
```
**Video Streaming**
```cpp
Blynk.setProperty(V1, "url", "http://my_new_video_url");
```
**Step**
```cpp
Blynk.setProperty(V1, "step", 10);
```
**Image**
```cpp
Blynk.setProperty(V1, "opacity", 50); // 0-100%
```
```cpp
Blynk.setProperty(V1, "scale", 30); // 0-100%
```
```cpp
Blynk.setProperty(V1, "rotation", 10); //0-360 degrees
```
also, you can fully replace the list of images from the hardware:
```cpp
Blynk.setProperty(V1, "urls", "https://image1.jpg", "https://image2.jpg");
```
or you can change individual image by it index:
```cpp
Blynk.setProperty(V1, "url", 1, "https://image1.jpg");
```
You can also change widget properties via [HTTP API](http://docs.blynkapi.apiary.io/#).
## Limitations and Recommendations
- Don't put ```Blynk.virtualWrite``` and any other ```Blynk.*``` command inside ```void loop()```- it will cause
lot's of outgoing messages to our server and your connection will be terminated;
- We recommend calling functions with intervals. For example, use [BlynkTimer](/#blynk-firmware-blynktimer)
- Avoid using long delays with ```delay()``` – it may cause connection breaks;
- If you send more than 100 values per second - you may cause
[Flood Error](/#troubleshooting-flood-error) and your hardware will be automatically disconnected from the server;
- Be careful sending a lot of ```Blynk.virtualWrite``` commands as most hardware is not very powerful (like ESP8266)
so it may not handle many requests.
================================================
FILE: BlynkProtocol.md
================================================
# Blynk protocol
Blynk transfers binary messages with the following structure:
| Command | Message Id | Length/Status | Body |
|:-------------:|:-------------:|:---------------:|:--------:|
| 1 byte | 2 bytes | 2 bytes | Variable |
Message Id and Length are [big endian](http://en.wikipedia.org/wiki/Endianness#Big-endian).
Body has a command-specific format.
Command and Status definitions: [BlynkProtocolDefs.h](https://github.com/blynkkk/blynk-library/blob/master/Blynk/BlynkProtocolDefs.h)
Another protocol description can be found [here](https://github.com/blynkkk/blynk-server/blob/master/README_FOR_APP_DEVS.md#protocol-messages).
Typical Blynk library knows how to send(S)/process(P):
S BLYNK_CMD_LOGIN + auth token
SP BLYNK_CMD_PING
SP BLYNK_CMD_RESPONSE
SP BLYNK_CMD_BRIDGE
SP BLYNK_CMD_HARDWARE
S BLYNK_CMD_TWEET
S BLYNK_CMD_EMAIL
S BLYNK_CMD_PUSH_NOTIFICATION
## HARDWARE/BRIDGE command body
The body of these commands are encoded as a sequence of strings, separated by ```'\0'``` ([Null character](http://en.wikipedia.org/wiki/Null_character)).
Please note that the last value may be not Null-terminated.
In the following command examples ```\0``` chars are replaced with spaces.
### Pin mode
PinMode command is received by library after connection, or when a mobile application starts.
pm
##Getting Started With The Blynk App
###1. Create a Blynk Account
After you download the Blynk App, you'll need to create a New Blynk account. This account is separate from the accounts used for the Blynk Forums, in case you already have one.
We recommend using a **real** email address because it will simplify things later.
####Why do I need to create an account?
An account is needed to save your projects and have access to them from multiple devices from anywhere. It's also a security measure.
You can always set up your own [Private Blynk Server](/#blynk-server) and have full control.
###2. Create a New Project
After you've successfully logged into your account, start by creating a new project.
###3. Choose Your Hardware
Select the hardware model you will use. Check out the [list of supported hardware](/#supported-hardware)!
###4. Auth Token
**Auth Token** is a unique identifier which is needed to connect your hardware to your smartphone.
Every new project you create will have its own Auth Token. You'll get Auth Token automatically on your email after
project creation. You can also copy it manually. Click on devices section and selected required device :
And you'll see token :
**NOTE:** Don't share your Auth Token with anyone, unless you want someone to have access to your hardware.
It's very convenient to send it over e-mail. Press the e-mail button and the token will be sent to the e-mail address you used for registration.
You can also tap on the Token line and it will be copied to the clipboard.
Now press the **"Create"** button.
###5. Add a Widget
Your project canvas is empty, let's add a button to control our LED.
Tap anywhere on the canvas to open the widget box. All the available widgets are located here. Now pick a button.
**Widget Box**
**Drag-n-Drop** - Tap and hold the Widget to drag it to the new position.
**Widget Settings** - Each Widget has it's own settings. Tap on the widget to get to them.
The most important parameter to set is **PIN** . The list of pins reflects physical pins defined by your hardware. If your LED is connected to Digital Pin 8 - then select **D8** (**D** - stands for **D**igital).
###6. Run The Project
When you are done with the Settings - press the **PLAY** button. This will switch you from EDIT mode to PLAY mode where you can interact with the hardware. While in PLAY mode, you won't be able to drag or set up new widgets, press **STOP** and get back to EDIT mode.
You will get a message saying "Arduino UNO is offline". We'll deal with that in the next section.
##Getting Started With Hardware
###How To Use an Example Sketch
You should by now have the Blynk Library installed on your computer. If not - [click here](/#downloads-blynk-library).
Example sketches will help you get your hardware online quickly and major Blynk features.
Open the example sketch according to the hardware model or shield you are using.
Let's take a look at the example sketch for an [Arduino UNO + Ethernet shield](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/BlynkBlink/BlynkBlink.ino)
```cpp
#define BLYNK_PRINT Serial
#include
Check out [other example sketches](https://github.com/blynkkk/blynk-library/tree/master/examples).
Feel free to experiment and combine different examples together to create your own amazing projects.
For example, to attach an LED to a [PWM](http://www.arduino.cc/en/Tutorial/Fading)-enabled Pin on your Arduino, set the slider widget to control the brightness of an LED. Just use the same steps described above.
================================================
FILE: HardwareSetUps.md
================================================
# Hardware set-ups
## Arduino over USB (no shield)
If you don't have any shield and your hardware doesn't have any connectivity, you can still use Blynk – directly over USB :
1. Open [Arduino Serial USB example](https://github.com/blynkkk/blynk-library/blob/master/examples/Boards_USB_Serial/Arduino_Serial_USB/Arduino_Serial_USB.ino)
and change [Auth Token](/#getting-started-getting-started-with-application-4-auth-token)
```cpp
// You could use a spare Hardware Serial on boards that have it (like Mega)
#include
Additional materials:
- [Particle core + DHT22](https://www.hackster.io/gusgonnet/temperature-humidity-monitor-with-blynk-7faa51)
================================================
FILE: Implementing.md
================================================
# Implementing a Blynk HW client (library)
Currently we provide Arduino/C++ implementation of the library.
It is very extensible and modular, look at [the list of supported hardware](/#supported-hardware).
Adding new connection types and Arduino-compatible boards is easy.
TODO: Porting guide.
But some devices are programmed in other languages, like:
* Espruino, JavaScript, Node.JS
* MicroPython, Python
* NodeMCU, eLua
This document hints how to write a custom library.
## Blynk library main functions
* Provide easy-to use API
* Virtual pin handlers registration
* Provide comfortable wrappers for some widgets
* Manage connection
* Should support different connection type/hardware, if applicable
* Serialize/deserialize Blynk protocol
* Handle direct pin operations
* Should be portable across similar devices (or same technology/programming language), if possible
* Should detect and notify the user about [troubles](/#troubleshooting) where possible (especially Flood)
### Adding new HW board
Different boards can be added by creating JSON board description file.
```json
{
"name": "Arduino UNO",
"map": {
"digital": {
"pins": {
"D0": 0, "D1": 1, "D2": 2, "D3": 3, "D4": 4,
"D5": 5, "D6": 6, "D7": 7, "D8": 8, "D9": 9,
"D10": 10, "D11": 11, "D12": 12, "D13": 13
},
"ops": [ "dr", "dw" ]
},
"analog": {
"pins": {
"A0": 14, "A1": 15, "A2": 16, "A3": 17, "A4": 18, "A5": 19
},
"ops": [ "dr", "dw", "ar" ],
"arRange":[0, 1023]
},
"pwm": {
"pins": [
"D3", "D5", "D6", "D9", "D10", "D11"
],
"ops": [ "aw" ],
"awRange":[0, 255]
},
"virtual": {
"pinsRange": [ 0, 31 ],
"ops": [ "vr", "vw" ]
}
}
}
```
Look at the [full boards list](https://github.com/blynkkk/blynk-library/tree/master/boards_json).
You can send us your own board description file for review and App integration.
There may be a problem that you want to start testing your implementation, but your board is not listed int the Blynk App.
On Android, we now have a "Generic Board" specially for such purposes.
Unfortunately iOS does not have it yet.
Basically you can select UNO board and check how it works using just virtual pins.
Most digital pins will also work.
Analog IO/PWM will not work in general, until we add your board to the App.
================================================
FILE: IntroAndDownloads.md
================================================
# Intro
🚨🚨🚨 IMPORTANT:
If you want to continue with using unsupported verion of Blynk, check out Getting Started.
[Getting Started >](/#getting-started)
##How Blynk Works
Blynk was designed for the Internet of Things. It can control hardware remotely, it can display sensor data,
it can store data, vizualize it and do many other cool things.
There are three major components in the platform:
- **Blynk App** - allows to you create amazing interfaces for your projects using various widgets we provide.
- **Blynk Server** - responsible for all the communications between the smartphone and hardware.
You can use our Blynk Cloud or run your [private Blynk server](/#blynk-server) locally.
It's open-source, could easily handle thousands of devices and can even be launched on a Raspberry Pi.
- **Blynk Libraries** - for all the popular hardware platforms - enable communication with the server and
process all the incoming and outcoming commands.
Now imagine: every time you press a Button in the Blynk app, the message travels to ~~space~~ the Blynk Cloud,
where it magically finds its way to your hardware. It works the same in the opposite direction and
everything happens in a blynk of an eye.
##Features
* Similar API & UI for all supported hardware & devices
* Connection to the cloud using:
* WiFi
* Bluetooth and BLE
* Ethernet
* USB (Serial)
* GSM
* ...
* Set of easy-to-use Widgets
* Direct pin manipulation with no code writing
* Easy to integrate and add new functionality using virtual pins
* History data monitoring via SuperChart widget
* Device-to-Device communication using Bridge Widget
* Sending emails, tweets, push notifications, etc.
* ... new features are constantly added!
You can find [example sketches](https://github.com/blynkkk/blynk-library/tree/master/examples) covering basic Blynk Features.
They are included in the library. All the sketches are designed to be easily combined with each other.
##What do I need to Blynk?
At this point you might be thinking: **"Ok, I want it. What do I need to get started?"** – Just a couple of things, really:
####**1. Hardware**.
An Arduino, Raspberry Pi, or a similar development kit.
**Blynk works over the Internet.**
This means that the hardware you choose should be able to connect to the internet. Some of the boards, like Arduino Uno
will need an Ethernet or Wi-Fi Shield to communicate, others are already Internet-enabled: like the ESP8266, Raspberri Pi with WiFi dongle, Particle Photon or SparkFun Blynk Board. But even if you don't have a shield, you can connect it over USB to your
laptop or desktop (it's a bit more complicated for newbies, but we got you covered).
What's cool, is that the [list of hardware](/#supported-hardware) that works with Blynk is huge and will keep on growing.
####**2. A Smartphone**.
The Blynk App is a well designed interface builder. It works on both iOS and Android, so no holywars here, ok?
#Downloads
##**Blynk Apps for iOS or Android**
[](https://itunes.apple.com/us/app/blynk-control-arduino-raspberry/id808760481?ls=1&mt=8) [
](https://play.google.com/store/apps/details?id=cc.blynk)
##**Blynk Library**
[Download The Blynk Library >](https://github.com/blynkkk/blynk-library/releases/latest)
In case you forgot, or don't know how to install Arduino libraries [click here](http://www.arduino.cc/en/guide/libraries).
================================================
FILE: License.md
================================================
# License
This project is released under The MIT License (MIT)
================================================
FILE: Links.md
================================================
#Links
* [Blynk site](https://www.blynk.cc)
* [Blynk community](https://community.blynk.cc)
* [Facebook](https://www.fb.com/blynkapp)
* [Twitter](https://twitter.com/blynk_app)
* [Blynk Library](https://github.com/blynkkk/blynk-library)
* [Blynk Examples](https://github.com/blynkkk/blynk-library/tree/master/examples)
* [Blynk Server](https://github.com/blynkkk/blynk-server)
* [Kickstarter campaign](https://www.kickstarter.com/projects/167134865/blynk-build-an-app-for-your-arduino-project-in-5-m/description)
================================================
FILE: OTA.md
================================================
#OTA
Blynk also supports over the air updates for - ESP8266, NodeMCU and SparkFun Blynk boards. OTA supported only
for the private servers and for the paid customers for now.
## How does it work?
- You need to use [regular sketch for exported apps](https://github.com/blynkkk/blynk-library/tree/master/examples/Blynk.Inject/Template_ESP8266);
- After you launched your hardware you are ready for OTA;
- You can trigger the firmware update for the specific hardware via it's token or for all hardware.
### Flow
1. User triggers OTA with one of below HTTPS request;
2. User provides within HTTPS request admin credentials and firmware binary file to update hardware with;
3. When hardware connects to server - server checks it firmware. In case, hardware firmware build date differs from
uploaded firmware, than server sends special command to hardware with url for the new firmware;
4. Hardware processes url with below [handler](https://github.com/blynkkk/blynk-library/blob/master/examples/Blynk.Inject/Template_ESP8266/OTA.h#L31):
```
BLYNK_WRITE(InternalPinOTA) {
//url to get firmware from. This is HTTP url
//http://localhost:8080/static/ota/FUp_2441873656843727242_upload.bin
overTheAirURL = param.asString();
...
}
```
5. Hardware downloads new firmware and starts flashing firmware;
## Trigger update for the specific hardware
```
curl -v -F file=@Template_ESP8266.ino.nodemcu.bin --insecure -u admin@blynk.cc:admin https://localhost:9443/admin/ota/start?token=123
```
- ```Template_ESP8266.ino.nodemcu.bin``` - is relative (or full) path to your firmware;
- ```--insecure``` flag for servers with self-generated certificates. You don't need this flag if you used Let's Encrypt or other trusted certificates;
- ```admin@blynk.cc:admin``` admin credentials to your server. This is default ones. Format is ```username:password```. You can change it in ```server.properties``` file;
- ```token``` is token of your hardware you want apply the firmware update to. The firmware update will be initiated only in case device is online;
## Trigger OTA for all devices
Update for all devices will be triggered only when they are connected to the cloud. You need to remove the token part for that.
```
curl -v -F file=@Template_ESP8266.ino.nodemcu.bin --insecure -u admin@blynk.cc:admin https://localhost:9443/admin/ota/start
```
In that case, OTA will be triggered right after device connected to the server. In case device is online firmware update
will be initiated only when device will be connected again.
## Trigger OTA for the specific user
In that case firmware update will be triggered for all devices of specified user.
```
curl -v -F file=@Template_ESP8266.ino.nodemcu.bin --insecure -u admin@blynk.cc:admin https://localhost:9443/admin/ota/start?user=pupkin@gmail.com
```
## Trigger OTA for specific user and project
In that case firmware update will be triggered for all devices of specified user within specified project.
```
curl -v -F file=@Template_ESP8266.ino.nodemcu.bin --insecure -u admin@blynk.cc:admin https://localhost:9443/admin/ota/start?user=pupkin@gmail.com&project=123
```
## Stop OTA
```
curl -v --insecure -u admin@blynk.cc:admin https://localhost:9443/admin/ota/stop
```
## How to make firmware
In order to make firmware in Arduino IDE - go to menu: Sketch -> Export compiled Binary.
*NOTE:* ESP8266 right now takes firmware only via HTTP. And not HTTPS.
================================================
FILE: README.md
================================================
# This documentation is no longer maintained and supported. Latest documentation is available here: https://docs.blynk.io
Blynk IoT Platform is a white-label, multi-tenant software solution that allows you to build personal and commercial IoT projects connected products.
With Blynk you can start with building a prototype or personal project and then scale it up to millions of commercial connected devices.
Blynk platform allows you to connect almost any electronics hardware to the Internet, start collectind data from devices, monitor and control them remotely from anywhere in the world
Data from devices can be stored, aggregated, and visualized in easy-to-build mobile and web applications.
Blynk is a real-time system where you can create outstanding experience for your end-customers and perform complex analytics
The four major components of the Blynk IoT Platform are:
* **Blynk.Cloud**
* **Blynk.Edgent**
* **Blynk.app**
* **Blynk.Console**
================================================
FILE: Roadmap.md
================================================
#Roadmap
We build Blynk based on Blynkers feedback but with limited resources we have to prioritize our features. At the moment list look like that:
- App Sharing (project sharing when other people can control your hardware, but can't modify your project); Free Beta
- App Sharing (project sharing when other people can control your hardware, but can't modify your project); Subscription based
- Bluetooth Low Energy support;
- Hardware state handling (changing physical button state changes Blynk application state);
- Hardware online/offlane state improvements (better indication for "is hardware online?", "is hardware offline?");
- Project space increase
- Direct Connect support (for WiFi);
- RTC widget;
- Design options for widgets (size, button with icons, etc);
- Phone sensors widgets (GPS, accelerometer);
- IP camera support;
- Customizable look and feel of the project
Under consideration:
- Home screen widget (to avoid opening App when you need only 1 button click);
- Haptic feedback (vibration) when touching widgets
================================================
FILE: SUMMARY.md
================================================
# Table of contents
* [What is Blynk](README.md)
## overview
* [Blynk Components](overview/blynk-components.md)
## Product
* [What is a Product](en-product/create-new-product.md)
* [General Settings](en-product/general-settings/README.md)
* [Manufacturer](en-product/general-settings/manufacturer.md)
* [Offline Ignore Period](en-product/general-settings/offline-ignore-period.md)
* [Metadata](en-product/metadata.md)
* [Datastreams](en-product/datastreams/README.md)
* [Datastream Name](en-product/datastreams/datastream-name.md)
* [Decimals Formatting](en-product/datastreams/decimals-formatting.md)
* [Wait for confirmation from the device](en-product/datastreams/wait-for-confirmation-from-the-device.md)
* [Default Value](en-product/datastreams/default-value.md)
* [Expose to Automation](en-product/datastreams/expose-to-automation.md)
* [Sync with the latest server value](en-product/datastreams/sync-with-the-latest-server-value.md)
* [Datastream: Alias](en-product/datastreams/datastream-alias.md)
* [Datastream: Invalidate Value](en-product/datastreams/datastream-invalidate-value.md)
* [Datastream: Min/Max values](en-product/datastreams/datastream-min-max-values.md)
* [Datastream: Data Type](en-product/datastreams/datastream-data-type.md)
* [Datastream: Virtual Pin](en-product/datastreams/datastream-virtual-pin.md)
* [Datastream: Save Raw Data](en-product/datastreams/datastream-save-raw-data.md)
* [Events](en-product/events/README.md)
* [Events: Notification](en-product/events/events-notification.md)
* [Events: Code](en-product/events/events-code.md)
* [Events: Name](en-product/events/events-name.md)
* [System Events](en-product/events/events-online-offline.md)
* [Events: Notifications Limit](en-product/events/events-notification-period.md)
* [Web Dashboard](en-product/web-dashboard.md)
* [Mobile app UI](en-product/mobile-app-ui.md)
## Firmware API
* [Disable Widgets in the App](firmware-api-1/disable-widgets-in-the-app.md)
## REST API
* [Devices](https-api/external_api.md)
* [Events](https-api/events-api.md)
## Mobile App
* [Untitled](mobile-app/untitled.md)
================================================
FILE: Security.md
================================================
#Security
Blynk server has 5 ports open for different security levels.
* **80** - plain TCP connection for the hardware (no security)
* **8080** - plain TCP connection for hardware (no security)
* **443** - SSL/TLS connection for the Mobile Apps and hardware with SSL
* **9443** - SSL/TLS connection for the Mobile Apps and hardware with SSL
Hardware may select to connect to 443 (9443) or 80 (8080), depending on it's capabilities.
Connection between the app and the server is always is done through SSL/TLS, so it is always secured.
Connection between the hardware and server depends on your hardware capabilities.
## Use Local Blynk Server
Local Blynk Server is no longer supported.
## Use SSL gateway
Most platforms are not capable to handle SSL, so they connect to 80.
However, our [gateway script](https://github.com/blynkkk/blynk-library/blob/master/scripts/blynk-ser.sh) can be used to add SSL security layer to communication.
```bash
./blynk-ser.sh -f SSL
```
This will forward all hardware connections from 9443 port to the server via SSL gateway.
You can run this script on your Raspberry Pi, desktop computer, or even directly on your router!
**Note:** when using your own server, you should overwrite the bundled server.crt certificate, or specify it to the script using ```--cert``` switch:
```bash
./blynk-ser.sh -f SSL -s
Click on "Generate Link" button :
It will generate QR code you can share with others:
That's it! Now **Exit the settings and press PLAY button.**
Another person would need to install Blynk app and scan QR code from the login screen (scanning from existing profile is not yet supported) ;
**NOTE:** Your Project should be active, don't forget to press Play button.
**WARNING:** Sharing costs 1000 energy and this energy is not recoverable even you didn't use sharing at all.
## Share your Project configuration
In case you want to share your Project's set up without giving access to your hardware (for example to make a tutorial or instructable)- follow the steps:
In Project's Settings go to **Clone** button.
It will generate QR code you can share with anyone.
Another person **should Log In to Blynk app** and press QR button in Projects gallery
After the scan, a new Project will be created, all the widgets, settings, layout will be cloned. Another person would need enough Energy Balance to clone your Project.
**Auth Token will be different!**. Nobody will get access to your hardware. They just get a copy of the layout and settings.
================================================
FILE: SupportedHardware.md
================================================
# Supported Hardware
**Attention!** This documentation is for the LEGACY version of Blynk platform which is no longer supported.
Please check out the [**new documentation**](https://docs.blynk.io)
Blynk supports more than 400 boards already, including support for Arduino, Particle, ARM mbed, TI Energia, MicroPython, Node.js, OpenWRT and many Single Board Computers. You can add your own connection types easily (see [these](https://github.com/blynkkk/blynk-library/tree/master/examples/More/ArduinoClient) examples for Arduino)!
## Platforms
- **Arduino** (https://github.com/blynkkk/blynk-library)
- Arduino MKR WiFi 1010
- Arduino MKR GSM 1400
- Arduino MKR NB 1500
- Arduino Uno, Duemilanove
- Arduino Nano, Mini, Pro Mini, Pro Micro, Due, Mega
- Arduino 101 (Intel Curie, with BLE)
- Arduino MKR1000
- Arduino Zero
- Arduino Yún (onboard WiFi and Ethernet, via Bridge)
- Arduino.org UNO WiFi
- Arduino MKR VIDOR 4000 (use the example for MKR WiFi 1010)
- Arduino UNO WiFi Rev.2 (use the example for MKR WiFi 1010)
- **Arduino-like**
- Blynk Board
- ESP8266 (Generic, NodeMCU, Witty Cloud, Huzzah, WeMos D1, Seeed Wio Link, etc.)
- ESP32 (WiFi, BLE)
- Nordic nRF51/nRF52 - based boards
- Teensy 3.2/3.1
- Blue Pill (STM32F103C)
- Realtek RTL8710 / Ameba via [RTLduino](https://github.com/pvvx/RtlDuino)
- BBC micro:bit
- LightBlue Bean *, soon*
- DFRobot Bluno
- RedBear Duo (WiFi, BLE)
- RedBearLab Blend Micro
- RedBearLab BLE Nano (v1 and v2)
- Seeed Tiny BLE
- Simblee BLE
- RFduino BLE
- The AirBoard (BLE-Link, RN-XV)
- Feather M0 WiFi
- Feather 32u4 BLE
- Intel Edison
- Intel Galileo
- Fishino Guppy, Uno, Mega
- TinyCircuits TinyDuino (CC3000)
- Microduino/mCookie Core, Core+, CoreUSB
- Wicked WildFire V2, V3, V4
- Digistump Oak
- chipKIT Uno32
- Alorium XLR8 (FPGA)
- LinkIt ONE (WiFi only)
- **Energia**
- Texas Instruments
- CC3220SF-LaunchXL
- CC3200-LaunchXL
- Tiva C Connected LaunchPad
- Stellaris LM4F120 LaunchPad
- MSP430F5529 + CC3100
- LaunchPad MSP432
- RedBearLab (CC3200, WiFi Mini)
- **Particle** https://github.com/vshymanskyy/blynk-library-spark)
- Core
- Photon
- Electron
- RPi
- SparkFun RedBoard
- RedBear Duo (WiFi & BLE)
- **ARM mbed** (https://developer.mbed.org/users/vshymanskyy/code/Blynk/)
- Seeed Tiny BLE
- RedBearLab BLE Nano
- BBC micro:bit
- STM32 Nucleo + Wiznet 5100 *, soon*
- **JavaScript** (Node.js, Espruino, Browsers) (https://www.npmjs.com/package/blynk-library)
- Regular PC with Linux / Windows / OS X
- Raspberry Pi (Banana Pi, Orange Pi, ...)
- BeagleBone Black
- Onion Omega
- Onion Omega 2
- Intel Galileo
- Intel Edison
- Intel Joule
- LeMaker Guitar
- LeMaker Banana Pro
- Samsung ARTIK 5
- PandaBoard, CubieBoard, pcDuino, Tessel 2
- VoCore, VoCore2 (OpenWRT + [Espruino package](https://github.com/vshymanskyy/OpenWRT-Espruino-packages))
- Espruino Pico
- ...
- **Python** (https://github.com/vshymanskyy/blynk-library-python)
- MicroPython
- Python 2
- Python 3
- **Lua** (https://github.com/blezek/blynk-esp)
- NodeMCU
## Arduino connection types
- USB (Serial), connected to your laptop or desktop
- **Ethernet**
- Arduino MKR ETH
- Arduino Ethernet Shield (W5100)
- Arduino Ethernet Shield 2 (W5500)
- SeeedStudio Ethernet Shield V2.0 (W5200)
- ENC28J60-based modules
- **WiFi**
- ESP8266 as WiFi modem (running original firmware)
- Arduino WiFi 101 Shield
- Arduino WiFi Shield
- WIZnet WizFi310
- Adafruit CC3000 WiFi Breakout / Shield
- RN-XV WiFly
- **Bluetooth Smart (BLE 4.0)**
- HM-10, HC-08
- DFRobot BLE-Link module
- Microduino/mCookie BLE
- RedBearLab BLE Mini
- nRF8001-based boards (Adafruit Bluefruit LE, etc.)
- **Bluetooth 2.0 Serial Port Profile (SPP)**
- HC-05, HC-06, ...
- **Cellular (GSM/3G/LTE)**
- SIMCom SIM800 series (SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868)
- SIMCom SIM900 series (SIM900A, SIM900D, SIM908, SIM968)
- A6/A7
- M590
- BG96
- GPRSbee
- Microduino GSM
- Adafruit FONA (Mini Cellular GSM Breakout)
- Adafruit FONA 800/808 Shield
## Made by Community
- [Marvell® EZ-Connect™ MW300/MW302](https://github.com/vshymanskyy/blynk-library-ez-connect)
- [WIZnet-W5500-EVB](http://instructables.com/id/WIZnet-W5500-EVB-and-Blynk-App-communication)
- [LabVIEW](https://github.com/juncaofish/NI-LabVIEWInterfaceforBlynk)
- [Node-RED](https://github.com/gablau/node-red-contrib-blynk-ws) (can be used as bridge to HTTP, TCP, UDP, MQTT, XMPP, IRC, OSC...)
## Problematic Boards
These boards are not supported and do not work out of the box:
- [Arduino Tian](http://www.arduino.org/products/boards/arduino-tian)
Here is a list of [**known library issues**](https://github.com/blynkkk/blynk-library/issues?q=is%3Aissue+label%3A"for+reference"+)
================================================
FILE: Troubleshooting.md
================================================
# Troubleshooting
## Connection
If you experience connection problems, follow these steps:
1. Check that your hardware, wires, cables and power supply are good quality, not harmed or damaged, etc.
Use high power USB cables and USB ports.
2. Check your wiring using the examples (TCP/HTTP Client or similar) **provided with your shield and hardware**.
* Once you understand how to manage connection, it's much easier to use Blynk.
3. Try running command ```telnet blynk-cloud.com 80``` from your PC, connected to the same network as your hardware.
You should see something like: ```Connected to blynk-cloud.com.```.
4. Try running Blynk default examples for your platform **without modifications** to see if it is working.
* Double-check that you have selected **the right example** for your connection type and hardware model.
* Our examples come with **comments and explanations**. **Read them carefully.**
* Check that your Auth Token is valid (copied from the App and **doesn't contain spaces, etc.**)
* If it doesn't work, try looking into [serial debug prints](/#enable-debug).
5. Done! Add your modifications and functionality. Enjoy Blynk!
***Note:*** when you have multiple devices connected to your network, they should all have different MAC and IP addresses. For example, when using 2 Arduino UNO with Ethernet shields, flashing default example to both of them will cause connection problems. You should use [manual ethernet configuration](https://github.com/blynkkk/blynk-library/blob/master/examples/Boards_Ethernet/Arduino_Ethernet_Manual/Arduino_Ethernet_Manual.ino) example.
## WiFi network connection
If you encounter WiFi connection problems, please check these pitfalls:
* You're trying to connect to "WPA & WPA2 Enterprise" network (often used in offices), and your shield does not support this security method
* Your WiFi network has a login page that requests entering an access token (often used in restaurants)
* Your WiFi network security disallows connecting alien devices completely (MAC filtering, etc)
* There is a firewall running. Default port for hardware connections is 80 (8080 on the Local Server).
Make sure it's open.
## Delay
If you use long ```delay()``` or send your hardware to sleep inside of the ```loop()``` expect connection drops and downgraded performance.
***DON'T DO THAT:***
```cpp
void loop()
{
...
delay(1000); // this is long delay, that should be avoided
other_long_operation();
...
Blynk.run();
}
```
***Note:*** This also applies to the BLYNK_READ & BLYNK_WRITE handlers!
***SOLUTION:***
If you need to perform actions in time intervals - use timers, for example [BlynkTimer](/#blynk-firmware-blynktimer).
## Flood Error
If your code frequently sends a lot of requests to our server, your hardware will be disconnected. Blynk App may show "Your hardware is offline"
When ```Blynk.virtualWrite``` is in the ```void loop```, it generates hundreds of "writes" per second
Here is an example of what may cause flood. ***DON'T DO THAT:***
```cpp
void loop()
{
Blynk.virtualWrite(1, value); // This line sends hundreds of messages to Blynk server
Blynk.run();
}
```
***SOLUTION:***
If you need to perform actions in time intervals - use timers, for example [BlynkTimer](/#blynk-firmware-blynktimer).
Using ```delay()``` will not solve the problem either. It may cause [another issue](/#delay). Use timers!
If sending hundreds of requests is what you need for your product you may increase flood limit on local server
and within Blynk library.
For local server you need to change ```user.message.quota.limit``` property within ```server.properties``` file :
#100 Req/sec rate limit per user.
user.message.quota.limit=100
For library you need to change ```BLYNK_MSG_LIMIT``` property within ```BlynkConfig.h``` file :
//Limit the amount of outgoing commands.
#define BLYNK_MSG_LIMIT 20
## Enable debug
To enable debug prints on the default Serial, add this on the top of your sketch **(it should be the first line
in your sketch)**:
```cpp
#define BLYNK_DEBUG // Optional, this enables lots of prints
#define BLYNK_PRINT Serial
```
And enable serial in ```void setup()```:
```cpp
Serial.begin(9600);
```
You can also use spare Hardware serial ports or SoftwareSerial for debug output (you will need an adapter to connect to it with your PC).
***Note:*** enabling debug mode will slow down your hardware processing speed up to 10 times.
## Geo DNS problem
Geo DNS issue is no longer a problem. It was solved in 2017.
## Reset password
On login screen click on "Forgot password?" label and than type your email and ```Send``` button.
You'll get instruction on your email.
### Android reset password flow
1. Open instruction email **from your smartphone or tablet**;
2. Click on "Reset now" button in your email;
3. Click on Blynk icon in below popup and reset the pass:
================================================
FILE: Widgets-RU.md
================================================
🚨🚨🚨 ВАЖНО:
#Widgets
Widgets are interface modules. Each of them performs a specific input/ output function when communicating with the hardware.
There are 4 types of Widgets:
- **Controllers** - used to send commands that control your hardware
- **Displays** - used for data visualization from sensors and other sources;
- **Notifications** - send messages and notifications;
- **Interface** - widgets to perform certain GUI functions;
- **Other** - widgets that don't belong to any category;
Each Widget has it's own settings. Some of the Widgets (e.g. Bridge) just enable functionality and they don't have any settings.
## Common Widget Settings
### Pin Selector
This is one of the main parameters you need to set. It defines which pin to control or to read from.
**Digital Pins** - represent physical Digital IO pins on your hardware. PWM-enabled pins are marked with the ```~``` symbol
**Analog Pins** - represent physical Analog IO pins on your hardware
**Virtual Pins** - have no physical representation. They are used to transfer any data between Blynk App and your hardware.
Read more about Virtual Pins [here](/#blynk-main-operations-virtual-pins).
### Data Mapping
In case you want to map incoming values to specific range you may use mapping button:
Let's say your sensor sends values from 0 to 1023. But you want to display values in a range 0 to 100 in the app.
When Data Mapping enabled, incoming value 1023 will be mapped to 100.
### SPLIT/MERGE
Some of the Widgets can send more than one value. And with this switch you can control how to send them.
- **SPLIT**:
Each of the parameters is sent directly to the Pin on your hardware (e.g D7). You don't need to write any code.
**NOTE:** In this mode you send multiple commands from one widget, which can reduce performance of your hardware.
Example: If you have a Joystick Widget and it's set to D3 and D4, it will send 2 commands over the Internet:
```cpp
digitalWrite(3, value);
digitalWrite(4, value);
```
- **MERGE:**
When MERGE mode is selected, you are sending just 1 message, consisting of array of values. But you'll need to parse it on the hardware.
This mode can be used with Virtual Pins only.
Example: Add a zeRGBa Widget and set it to MERGE mode. Choose Virtual Pin V1
```cpp
BLYNK_WRITE(V1) // There is a Widget that WRITEs data to V1
{
int r = param[0].asInt(); // get a RED channel value
int g = param[1].asInt(); // get a GREEN channel value
int b = param[2].asInt(); // get a BLUE channel value
}
```
### Decimals
Defines how many decimals you would like to see when moving a Slider.
When "No Fraction" is chosen, slider will only send integer values with no decimals.
"1 digit" means that values will look like 1.1, 1.2, ..., 2.0, etc.
### Send On Release
This option allows you to optimize data traffic on your hardware.
For example, when you move joystick widget, commands are streamed to the hardware, during a single joystick move
you can send dozens of commands. There are use-cases where it's needed, however creating such a load may lead to hardware overload and reset.
**Send On Release** is a recommended setting for majority of applications. This is also a default setting.
### Write interval
Similar to "Send on Release" option. However, it allows you to stream values to your hardware within certain interval. For example, setting **write interval** to 100 ms means that while you move the slider, only 1 value will be sent to hardware within 100 ms period.
This option is also used to optimize data traffic flow to your hardware.
### Color gradient
When you choose gradient, it affects the color of widget elements based on invoming values.
For example: You set Gauge Widget with Min and Max parameters of 0-100, and choose green-yellow-red gradient. When hardware sends:
- `10`, Gauge will change it's color to green color
- `50` will change Gauge to yellow color
- `80` will change Gauge to red color
There are 2 types of gradients you can choose from:
- Warm: Green - Orange - Red;
- Cold: Green - Blue - Violet;
##Controllers
### Кнопка (Button)
Кнопка может работать в двух режимах - в режиме переключателя (нажатие и отжатие посылает 1 сообщение) и в пуш режиме
(нажатие посылает команду и отжатие посылает команду). Кнопка позволяет послать любое число. По умолчанию кнопка шлет
0/1 (LOW/HIGH). В пуш режиме кнопка шлет 1 (HIGH) на нажатие и 0 (LOW) при отжатии.
Вы так же можете менять состояние кнопки с микроконтроллера. Например, включить кнопку на пине V1 можно так :
```cpp
Blynk.virtualWrite(V1, HIGH);
```
Так же можно поменять тексты в кнопке :
```cpp
Blynk.setProperty(V1, "onLabel", "Вкл");
```
```cpp
Blynk.setProperty(V1, "offLabel", "Выкл");
```
Название самой кнопки :
```cpp
Blynk.setProperty(V1, "label", "Моя кнопочка");
```
Или изменить ее цвет :
```cpp
//#D3435C - Blynk RED
Blynk.setProperty(V1, "color", "#D3435C");
```
В случае если микроконтроллер был перегружен, Вы всегда можете получить последнее состояние кнопки с сервера с помощью
фичи синхронизации состояния:
```cpp
//как только подключились
BLYNK_CONNECTED() {
//запросить информацию у сервера о состоянии пина V1
Blynk.syncVirtual(V1);
}
//этот метод будет вызыван после ответа сервера
BLYNK_WRITE(V1) {
int buttonState = param.asInt();
}
```
#### Кнопка на рабочем столе
Если Вы используете Android, то Вы можете добавить Blynk кнопку на рабочий стол. В этом случае кнопка будет работать по
протоколу HTTPS. Такого рода кнопки имеют определенные ограничения по функционалу в связи с ограничениями платформы Android.
Например, Вы не можете получить мгновенную синхронизацию состояния кнопки на рабочем столе с состоянием на микроконтроллере. Так как состояние кнопки на рабочем столе обновляется раз в 15 мин.
**Замечание:** Добавление виджета кнопки на рабочий стол стоит 100 энергии. Эта энергия не возвращается после удаления виджета.
Также такая кнопка будет работать на локальном сервере только если открыть порт 8080.
**Пример кода:** [Базовый пример](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/BlynkBlink/BlynkBlink.ino)
**Пример кода:** [Синхронизация состояния с физической кнопкой через прерывания](https://github.com/blynkkk/blynk-library/blob/master/examples/More/Sync/ButtonInterrupt/ButtonInterrupt.ino)
**Пример кода:** [Синхронизация состояния с физической кнопкой через поллинг](https://github.com/blynkkk/blynk-library/blob/master/examples/More/Sync/ButtonPoll/ButtonPoll.ino)
**Пример кода:** [Синхронизация состояния с физической кнопкой](https://github.com/blynkkk/blynk-library/blob/master/examples/More/Sync/SyncPhysicalButton/SyncPhysicalButton.ino)
### Слайдер (Slider)
Слайдер очень похож на потенциометр. Он позволяет посылать значения в диапазоне от минимального значения к максимальному.
Диапазон допустимых максимального и минимального значений определяется в приложении.
Вы так же можете менять состояние слайдера с микроконтроллера. Например, Вы можете изменить положение ползунка в слайдере :
```cpp
Blynk.virtualWrite(V1, 55);
```
Так же можно поменять текст в слайдере :
```cpp
Blynk.setProperty(V1, "label", "Мой слайдерок");
```
или изменить цвет :
```cpp
//#D3435C - Карсный цвет в кодирвке RGB
Blynk.setProperty(V1, "color", "#D3435C");
```
### Таймер (Timer)
Таймер запускает действия в определенное время. Даже если смартфон не в сети. По умолчанию время начала отправляет 1 (HIGH), время остановки отправляет 0 (LOW). Вы можете изменить это поведение на любые другие значения.
Вы можете изменить настройки Таймера в режиме «Запуска».
В последней версии Android также есть улучшенный таймер в виджете [Обработчик событий](https://github.com/blynkkk/blynkkk.github.io/blob/master/mobile/ru/eventor.md).
C [Обработчиком](https://github.com/blynkkk/blynkkk.github.io/blob/master/mobile/ru/eventor.md) событий вы можете назначить несколько таймеров на один и тот же пин, отправить любую строку/число, выбирать дни и часовой пояс.
Рекомендуется использовать виджет [Обработчик событий](https://github.com/blynkkk/blynkkk.github.io/blob/master/mobile/ru/eventor.md) поверх виджета Таймер.
Однако виджет Таймер по-прежнему подходит и для простых событий таймера.
**ПРИМЕЧАНИЕ:** Виджет таймера зависит от времени сервера, а не вашего телефона. Иногда время телефона может не соответствовать времени сервера.
**Пример кода:** [Таймер](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Timer/Timer.ino)
### Джойстик (Joystick)
Управление сервоприводом в 4 направлениях.
#### Параметры:
- **Раздельный** (SPLIT):
Каждый из параметров отправляется непосредственно на пин вашего оборудования (например, D7 и D8). Вам не нужно писать код.
**ПРИМЕЧАНИЕ:** В этом режиме вы отправляете несколько команд из одного виджета, что может снизить производительность вашего оборудования.
**Пример:** Если у вас есть виджет Джойстика и он настроен на D3 и D4, он отправит две команды через Интернет:
```cpp
digitalWrite(3, x);
digitalWrite(4, y);
```
- **Совмещенный** (MERGE):
Когда выбран режим MERGE, вы отправляете только 1 сообщение, состоящее из массива значений. Но вам нужно разобрать его на оборудовании устройства.
Этот режим можно использовать только с виртуальными пин-ами.
**Пример:** добавьте виджет Джойстика и установите его в режим "MERGE". Выберите виртуальный пин V1
```cpp
BLYNK_WRITE(V1) // Joystick assigned to V1
{
// получить x
int x = param[0].asInt();
// получить y
int y = param[1].asInt();
}
```
- **Поворт/Наклон** (Rotate on Tilt)
Когда это параметр включен, Джойстик будет автоматически вращаться, если вы будете использовать смартфон в горизонтальной положении.
- **Автовозврат** (Auto-Return)
Когда это парамтер выключен, ручка джойстика не вернется в центральное положение. Она останется там, где вы ее оставили.
### Отправка при Отжатии (Send On Release)
**Send On Release** доступно для большинства виджетов контроллеров и позволяет уменьшить трафик данных на ваше оборудование. Например, когда вы перемещаете виджет джойстика, команды непрерывно передаются на аппаратное устройство, во время одного движения джойстика вы можете отправлять десятки команд. Есть случаи, когда это необходимо, однако создание такой нагрузки может привести к зависанию или сбросу оборудования. Мы рекомендуем включить функцию **Send On Release** для большинства случаев, если вам не требуется мгновенная обратная связь. Эта опция включена по умолчанию.
### Интервал записи (Write interval)
Похоже на вышеуказанный вариант. Однако, позволяет вам передавать значения на ваше оборудование в через определенные интервалы времени. Например, установка интервала записи на 100 мс означает, что при перемещении ползунка на аппаратное обеспечение будет отправлено только 1 значение в течение 100 мс. Эта опция также используется для уменьшения трафика данных на ваше оборудовании.
**Пример кода:** [Джойстик две оси](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/JoystickTwoAxis/JoystickTwoAxis.ino)
### Шаговое управление (Step Control)
Шаговое управление похоже на две кнопки, назначенные одному пин-у. Одна кнопка увеличивает ваше значение на установленный шаг, а другая уменьшает его. Это очень полезно для случаев использования, когда вам нужно точно изменять ваши значения, но вы не можете достичь такой точности с помощью виджета [Cлайдера](https://github.com/blynkkk/blynkkk.github.io/tree/master/mobile/ru/slider.md).
**Отправить шаг (Send Step)** опция позволяет вам отправлять на оборудование каждый шаг нвместо фактического значения виджета.
**Зациклить значения (Loop value)** опция позволяет сбросить Шаговый виджет на начальное значение при достижении максимального.
Вы можете изменить значение Шагового виджета со стороны оборудования. Например:
```cpp
Blynk.virtualWrite(V1, val);
```
Вы можете изменить описание виджета со стороны оборудования с помощью кода:
```cpp
Blynk.setProperty(V1, "label", "Мой счетчик.");
```
Вы можете изменить шаг виджета со стороны оборудования:
```cpp
Blynk.setProperty(V1, "step", 10);
```
или изменить цвет:
```cpp
//#D3435C - Красный цвет в RGB кодировке
Blynk.setProperty(V1, "color", "#D3435C");
```
Вы также можете получить состояние виджета Шагового управления с сервера в случае, если ваше оборудование отключилось, с помощью функции Blynk.Sync:
```cpp
BLYNK_CONNECTED() {
Blynk.syncVirtual(V1);
}
BLYNK_WRITE(V1) {
int stepperValue = param.asInt();
}
```
##Displays
### Отображение значений (Value Display)
Отображает входящие данные с ваших датчиков или виртуальных пин-ов.
Может работать в двух режимах:
- режим PUSH (выберается в списке выбора частоты считывания);
- режим частоты считываний;
В режиме PUSH вы обновляете значения виджета со стороны оборудования с помощью кода:
```cpp
Blynk.virtualWrite(V1, val);
```
В этом режиме каждое сообщение, которое отправляет аппаратное устройство автоматически сохраняется на сервере. Режим PUSH не требует, чтобы приложение было онлайн или открыто.
В режиме частоты считывния вам необходимо выбрать интервал обновления данных, и приложение будет запускать события считывния с требуемой периодичностью.
Ваше приложение должно быть открыто и запущено для отправки запросов на оборудование. Вам не нужен код для аналоговых и цифровых выводов в даном случае. Однако для виртуальных выводов вам необходимо использовать следующий код:
```cpp
//вызывать из приложения
BLYNK_READ(V1)
{
//отправить в приложение
Blynk.virtualWrite(V1, val);
}
```
#### Отображение значений на рабочем столе
Вы также можете добавить виджет отображение значения на рабочий стол Android. В этом случае отображение значений работает по протоколу HTTPS.
Имейте в виду, что в режиме «Рабочий стол» отображение значений имеет несколько ограничений. Виджет будет обновлять свое состояние только один раз в 15 минут. Вы можете изменить это органичение через настройки виджета. Однако интервал обновления менее 15 минут не гарантируется.
Вы также можете изменить размер отображаемого значения на рабочем столе - просто сделайте длинный тап на виджете и измените его размер на необходимый.
**Примечание:** Добавление виджета на главный экран стоит 100 энергии. Эта энергия не возвращяется при удалении виджета.
**Примечание:** Виджеты рабочего стола для локальных серверов Blynk требуют открытия порта 8080.
**Пример кода:** [Базовый пример](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/BlynkBlink/BlynkBlink.ino)
### Интервал записи (Write interval)
Опция позволяет вам передавать значения на ваше оборудование в через определенные интервалы времени. Например, установка интервала записи на 100 мс означает, что при перемещении ползунка на аппаратное обеспечение будет отправлено только 1 значение в течение 100 мс. Эта опция также используется для уменьшения трафика данных на ваше оборудовании.
**Пример кода:** [Базовый пример](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/BlynkBlink/BlynkBlink.ino)
### Светодиод (LED)
Простой светодиод для индикации. Вам нужно отправить 0, чтобы выключить светодиод. И 255 для того, чтобы включить светодиод.
Или просто используйте Blynk API, как описано ниже:
```cpp
//регистрируемся на виртуальном пине 1
WidgetLED led1(V1);
led1.off();
led1.on();
```
Все значения от 0 до 255 изменяют яркость светодиода:
```cpp
WidgetLED led2(V2);
//установить яркость светодиода на 50%.
led2.setValue(127);
```
Вы также можете изменить цвет светодиода с помощью кода:
```cpp
//#D3435C - Красный в RGB формате
Blynk.setProperty(V1, "color", "#D3435C");
```
#### Светодиод на рабочем столе
Вы можете добавить виджет светодиод на рабочий стол Android. В этом случае светодиод работает через протокол HTTPS. Имейте в виду, что в режиме «Рабочий стол» виджет светодиода имеет некоторые ограничения. Светодиод будет обновлять свое состояние только один раз в 15 минут. Вы можете изменить этот интервал через настройки виджета. Однако интервал обновления менее 15 минут не гарантируется.
**Примечание:** Добавление виджета на рабочий стол стоит 100 энергии. Эта энергия не возвращается при удалении виджета.
**Примечание:** Виджеты рабочего стола для локальных серверов Blynk требуют открыть порт 8080.
**Пример кода:** [Базовый пример](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/LED/LED_Blink/LED_Blink.ino)
### Указатель (Gauge)
Отличный визуальный способ отображения входящих числовых значений.
Может работать в 2 режимах:
- режим PUSH (выберается в списке выбора частоты считывания);
- режим частоты считываний;
В режиме PUSH вы обновляете значения указателя со стороны оборудования с помощью кода:
```cpp
Blynk.virtualWrite(V1, val);
```
В этом режиме каждое сообщение, которое отправляет аппаратное устройство автоматически сохраняется на сервере. Режим PUSH не требует, чтобы приложение было онлайн или открыто.
В режиме частоты считывния вам необходимо выбрать интервал обновления данных, и приложение будет запускать события считывния с требуемым периодичностью.
Ваше приложение должно быть открыто и запущено для отправки запросов на оборудование. Вам не нужен код для аналоговых и цифровых выводов в даном случае. Однако для виртуальных выводов вам необходимо использовать следующий код:
```cpp
//вызывать из приложения
BLYNK_READ(V1)
{
//отправить в приложение
Blynk.virtualWrite(V1, val);
}
```
#### Параметры форматирования
Указатель также имеет поле «Label» (Метка), которое позволяет использовать форматирование.
Предположим, ваш датчик отправляет число 12.6789 в приложение Blynk.
Поддерживаются следующие параметры форматирования:
```/pin/``` - отображает значение без форматирования (12.6789)
```/pin./``` - отображает значение без десятичной части (13)
```/pin.#/``` - отображает значение с одним десятичным знаком (12.7)
```/pin.##/``` - отображает значение с двумя десятичными знаками (12.68)
#### Другие опции
Вы также можете изменить метку прибора с помощью:
```cpp
Blynk.setProperty(V1, "label", "Мое значение метки");
```
или изменить цвет (кодировка RGB):
```cpp
//#D3435C - Красный цвет
Blynk.setProperty(V1, "color", "#D3435C");
```
**Пример кода:** [Светодиод](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/BlynkBlink/BlynkBlink.ino)
### ЖК дисплей (LCD)
Это обычный ЖК-дисплей 16x2, "сделанный" на нашем секретном предприятии в Китае.
Виджет может работать в двух режимах:
- Простой (Simple)
- Расширенный (Advanced)
#### Простой режим (Simple)
В простом режиме ваш ЖК-виджет работает как обычный виджет с частотой чтения.
В режиме частоты считывания вам нужно выбрать интервал обновления данных, и приложение будет запускать события с требуемым интервалом. Ваше приложение должно быть открыто и запущено для отправки запросов на оборудование. В данном случае вам не нужен код для аналоговых и цифровых пин-ов. Однако для виртуальных пин-ов вам необходимо использовать следующий код:
```cpp
//вызываем из приложения
BLYNK_READ(V1)
{
//отправляем в приложение
Blynk.virtualWrite(V1, val);
}
```
В простом режиме ЖК-дисплей также поддерживает параметры форматирования.
#### Параметры форматирования
Предположим, ваш датчик отправляет число 12.6789 в приложение Blynk.
Поддерживаются следующие параметры форматирования:
```/pin/``` - отображает значение без форматирования (12.6789)
```/pin./``` - отображает значение без десятичной части (13)
```/pin.#/``` - отображает значение с одним десятичным знаком (12.7)
```/pin.##/``` - отображает значение с двумя десятичными знаками (12.68)
**Пример кода:** [ЖК дисплей простой режим - PUSH](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/LCD/LCD_SimpleModePushing/LCD_SimpleModePushing.ino)
**Пример кода:** [ЖК дисплей простой режим - 1 сек](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/LCD/LCD_SimpleModeReading/LCD_SimpleModeReading.ino)
#### Расширенный режим (Advanced)
Расширенный режим предназначен для опытных пользователей. Позволяет использовать специальные команды для управления ЖК-дисплеем.
#### Команды
Инициируем переменную ЖК-дисплея:
```cpp
WidgetLCD lcd(V1);
```
Отправим сообщение:
```cpp
lcd.print(x, y, "Ваше сообщение");
```
Где ```x``` - позиция символа (0-15), ``` y``` - номер строки (0 или 1),
Очистка ЖК-дисплея:
```cpp
lcd.clear();
```
**Пример кода:** [ЖК-дисплей расширенный режим](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/LCD/LCD_AdvancedMode/LCD_AdvancedMode.ino)
### Диаграмма (SuperChart)
Диаграмма используется для живой визуализации и хранения данных. Вы можете использовать виджет для логирования данных датчиков, бинарных событий и многого другого.
Чтобы использовать виджет Диаграмма, вам нужно будет передать данные с оборудования с желаемым интервалом, используя таймеры.
[Здесь приведен](https://examples.blynk.cc/?board=ESP8266&shield=ESP8266%20WiFi&example=GettingStarted%2FPushData) базовый пример передачи данных.
#### Взаимодействие:
- **Переключение между режимами текущий и временной** Нажмите диапазоны времени в нижней части виджета, чтобы изменить масштаб Диаграммы по времени.
- **Тап по легенде графиков** показать или скрыть поток данных.
- **Долги тап на графике** покажет метку времени и соответствующие значения.
- **Быстро проведите пальцем влево или вправо, чтобы увидеть предыдущие данные** впоследствии вы можете прокручивать данные назад и вперед в пределах заданного временного диапазона.
- **Полноэкранный режим** нажмите эту кнопку, чтобы открыть полноэкранный режим в альбомной ориентации.
Чтобы выйти из режима полного экрана, просто поверните телефон обратно в портретный режим. График должен вращаться автоматически. В полноэкранном режиме вы увидите X (время) и несколько шкал Y.
Полноэкранный режим можно отключить в настройках виджета.
- **Кнопка меню**
Кнопка меню откроет дополнительные функции:
- Экспорт в CSV
- Стереть данные на сервере
#### Настройки диаграммы:
- **Заголовок диаграммы (Chart Title)** общее наименование диаграммы.
- **Размер шрифта заголовка (Title Font Size)** выберите из 3 размеров шрифта.
- **Выравнивание заголовка (Title Alignment)** выберите выравнивание заголовка диаграммы. Этот параметр влияет на положение заголовка и легенды в виджете.
- **Показать ось X (время) (Show x-axis (time))** выберите настройку, если хотите показать шкалу времени внизу графика.
- **Автоматическое масштабирование для всех потоков данных (Override Auto Scaling for All Datastreams)** отключение этой опции позволит выполнить ручную настройку для оси Y (см. ниже).
- **Выбор масштаба времени (Time ranges picker)** Позволяет выбрать необходимые периоды (`15m`,` 30m`, `1h`,` 3h`, ...) и разрешение для вашего графика. Разрешение определяет, насколько подробные ваши данные. Прямо сейчас график поддерживает два типа разрешения: `standard` и `high`. Разрешение также зависит от выбранного периода. Например, `standard` разрешение для `1d` означает, что вы будете получать 24 значения в день (одно в час), а при `high` разрешении вы будете получать за` 1d` 1440 значений в день (одно в минуту).
- **Потоки данных (Datastreams)** добавить потоки данных (см. ниже, как настроить потоки данных).
#### Настройки потоков данных
Виджет поддерживает до 4 потоков данных.
Нажмите значок настроек потоков данных, чтобы открыть настройки.
**Дизайн (Design)** выберите доступные типы диаграмм:
- Линейная (Line)
- С областями (Area)
- Гистограмма (Bar)
- Бинарная (Binary) (приведение данных к двоичному виду)
**Цвет (Color)** выберите сплошные цвета или градиенты.
**Источник и ввод (Source and input)** - Вы можете использовать три типа источника данных:
**1. Виртуальный пин (Virtual Pin)** - выберите желаемое устройство и виртуальный пин для получения данных.
**2. Теги (Tags)** - диаграмма может агрегировать данные с нескольких устройств, используя встроенные функции агрегирования.
Например, если у вас есть 10 датчиков температуры, посылающих температуру с заданным интервалом, Вы можете отобразить среднее значение от 10 датчиков в виджете.
Использование тегов:
- **[Добавить Тэг](http://docs.blynk.cc/#blynk-main-operations-control-of-multiple-devices-tags)** на каждое устройство, с которого вы хотите агрегировать данные. Это можно сделать в настройках проекта Blynk.
- **Отправить данные в виртуальный пин (Push data to the same Virtual Pin)** на каждое устройство. (т.е. ```Blynk.virtualWrite (V0, temperature);```)
- **Выберите тег в качестве источника (Choose Tag as a source)** в виджете Диаграмма и используйте пин, куда поступают данные (т.е. V0)
**Добступные функции:**
- `SUM` будет суммировать все входящие значения в указанный виртуальный пин со всех устройств, помеченные выбранным тегом
- `AVG` будет вычислять среднее значение
- `MED` найдет среднее значение
- `MIN` будет вычислять минимальное значение
- `MAX` будет вычислять максимальное значение
**ВАЖНО: Теги не работают в режиме реального времени.**
**3. [Выбор устройства (Device Selector)](https://github.com/blynkkk/blynkkk.github.io/tree/master/mobile/ru/ device_selector.md)**
Если вы добавите виджет Выбор устройства в свой проект, вы можете использовать его в качестве источника данных для Диаграммы.
В том случае, когда вы меняете устройство, диаграмма будет автоматически обновляться.
#### Настройки оси Y (Y-Axis Settings)
Cуществует 4 режима масштабирования данных вдоль оси Y, активируется после отключения общей настройки виджета "Автоматическое масштабирование для всех потоков данных (Override Auto Scaling for All Datastreams)".
**1. Авто (Auto)**
Данные будут автоматически масштабироваться на основе минимальных и максимальных значений заданного периода времени. Это лучший вариант для начинающих.
**2. Минимальный/Максимальный (Min/Max)**
Когда выбран этот режим, шкала Y будет установлена на выбранные вами границы значений.
Например, если ваше оборудование отправляет данные со значениями от -100 до 100, вы можете установить эти границы и данные графика будут отображены полностью.
Вы также можете визуализировать данные в другом диапазоне. Допустим, входящие данные имеют значения в диапазоне 0-55, но вы хотели бы видеть только значения в диапазоне 30-50. Вы можете настроить диапазон, но если значения не соответствуют заданному масштабу оси Y, диаграмма будет обрезана.
**3. Процент от высоты (% of Height)**
Эта опция позволяет автоматически масштабировать входящие данные на виджете и размещать их так, как вы хотите.
В этом режиме вы устанавливаете процент высоты виджета на экране от 0% до 100%.
Если вы установите диапазон 0-100%, это будет полная автоматическая шкала. Независимо от того, в каком диапазоне поступают данные, он всегда будет масштабирован по всей высоте виджета.
Если вы установите его на 0-25%, то график будет отображаться только на 1/4 высоты виджета.
Этот параметр очень полезен для **Бинарной диаграммы** или для визуализации нескольких потоков данных на одной и той же диаграмме разными способами.
**4. Дельта (Delta)**
Пока данные остаются в пределах заданного значения дельты, график будет автоматически масштабироваться в этом диапазоне.
Если дельта превышает диапазон, график автоматически масштабируется до минимальных/максимальных значений указанного периода.
**Суффикс (Suffix)**
Здесь вы можете указать суффикс, который будет отображаться со значениями во время длительного тап на графике.
**Разрядность (Decimals)**
Определяет формат числовых значений, когда вы нажимаете и удерживаете палец на графике. Возможные варианты: #, #.#, #.##, и т.д.
**Соединиить отсуствующие точки графика (Connect Missing Data Points)**
Если этот переключатель включен, то Диаграмма соединит все точки, даже если данные частично отсуствуют.
Если для него установлено значение «ВЫКЛ», то вы увидите пропуски в случае отсутствия данных.
**Настройки Бинарной диаграммы (Binary Chart Settings)**
Этот тип диаграммы полезен для построения двоичных данных, например, когда устройство было включено или выключено, или когда было обнаружено движение или когда был достигнут определенный порог значений.
Вам необходимо указать точку **Перехода (FLIP)**, которая будет точкой, в которой входящие данные будут принимать состояние `ИСТИНА (TRUE)` или `ЛОЖЬ (FALSE)`.
Например, вы отправляете данные в диапазоне от 0 до 1023. Если вы установите `512` в качестве точки **Перехода (FLIP)**, то все, что выше `512` (исключая 512), будет записано как `ИСТИНА (TRUE)`, любое значение ниже `512` (включая 512) будет `ЛОЖЬ (FALSE)`.
Другой пример: если вы отправляете `0 и 1` и устанавливаете `0` в качестве точки **Перехода FLIP**, то `1` будет `ИСТИНА`, а `0` будет `ЛОЖЬ`.
**Маркеры состояния (State Labels):**
Здесь вы можете указать, как `ИСТИНА/ЛОЖЬ` должны отображаться на графике когда вы нажимаете и удерживаете палец.
Например, вы можете установить значение `ИСТИНА` как `Оборудование ВКЛ`, `ЛОЖЬ` как `Оборудование ВЫКЛ`.
### Видео трансляция (Video Streaming)
Простой виджет, который позволяет отображать прямой эфир и потокове видео. Виджет поддерживает протоколы RTSP (RP, SDP), HTTP/S прогрессивной потоковой передачи, HTTP/S прямого эфира. Для получения дополнительной информации, пожалуйста ознакомтесь с [официальной документацией Android](https://developer.android.com/guide/appendix/media-formats.html).
На данный момент команда Blynk не предоставляет потоковые серверы. Таким образом, вы можете осуществлять потоковую передачу непосредственно с ваше камеры или использовать сторонние сервисы, а также запустить собственны потоковый сервер (например, на оборудовании Raspberry).
Вы можете остановить/запустить видео поток, нажав на сам виджет.
Вы можете изменить URL-адрес видео потока с аппаратного устройства при помощи кода:
```cpp
Blynk.setProperty(V1, "url", "http://my_new_video_url");
```
### Индикатор уровня (Level Display)
Отображает входящие данные с ваших датчиков или виртуальных пин-ов. Отображение уровня очень похоже на индикатор выполнения процесса, это очень красивый и причудливый вид для индикации «выполненных» событий, например «уровня заряда батареи».
Вы можете обновить отображение значения с аппаратной стороны с помощью кода:
```cpp
Blynk.virtualWrite(V1, val);
```
Каждое сообщение, которое аппаратное устройство отправляет на сервер, автоматически сохраняется на сервере.
Режим PUSH не требует, чтобы приложение было онлайн или запущено.
**Пример кода:** [Пример PUSH](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/PushData/PushData.ino)
## Interface
### Вкладки (Tabs)
Единственная цель виджета Вкладки - расширить пространство вашего проекта.
Чтобы редактировать виджет Вкладок - просто нажмите на выбранную вкладку.
Вы можете перетаскивать виджеты между вкладками.
Из списка можно удалить только последнюю вкладку: чтобы удалить ее, проведите пальцем влево по ее названию в экране настроек виджета.
Максимальное количество вкладок на iOS составляет 4.
Максимальное количество вкладок на Android - 10.
Оставайтесь с нами для предстоящего редизайна виджета вкладок!
### Меню (Menu)
Виджет Меню позволяет отправлять команды на ваше оборудование на основе выборного списка, сделанного вами в пользовательском интерфейсе. Меню отправляет индекс выбранного элемента спика, а не саму строку. Отправляемый индекс начинается с 1. Он работает так же, как типовой элемент "Комбинированный список" ([ComboBox](https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA)).
Пример кода:
```cpp
BLYNK_WRITE {
switch (param.asInt()) {
case 1: { // Пункт 1
Serial.println("Выбран Пункт 1");
break;
}
case 2: { // Пункт 2
Serial.println("Выбран Пункт 2");
break;
}
}
}
```
Вы также можете назначить пункты меню со стороны оборудования с помощью кода:
```cpp
Blynk.setProperty(V1, "labels", "label 1", "label 2", "label 3");
```
**Пример кода:** [Меню](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Menu/Menu.ino)
### Ввод времени (Time Input)
Виджет Ввода времени позволяет вам выбрать время начала/окончания, день недели, часовой пояс, значения в формате до полудня/после полудня и отправить их на ваше оборудование. В настоящее время поддерживаются следующие форматы: ```ЧЧ:ММ``` и ```ЧЧ:ММ AM/PM```.
Аппаратное устройстов будет отсчитывать время пользовательского интерфейса в виде секунд дня (```3600 * часов + 60 * минут```) для запуска/остановки времения. Время, которое виджет отправляет оборудованию, является локальным временем пользователя.
Индексы по выбранных дней:
```
Понедельник - 1
Вторник - 2
...
Суббота - 6
Воскресенье - 7
```
Вы также можете изменить состояние виджета в интерфейсе пользователя. Смотрите ниже примеры кода.
**Пример кода:** [Простой Ввод времени для времени начала](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/TimeInput/SimpleTimeInput/SimpleTimeInput.ino)
**Пример кода:** [Расширенный Ввод времени](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/TimeInput/AdvancedTimeInput/AdvancedTimeInput.ino)
**Пример кода:** [Обновление Ввода времени в пользовательском интерфейсе](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/TimeInput/UpdateTimeInputState/UpdateTimeInputState.ino)
### Карта (Map)
Виджет Карты позволяет устанавливать точки/флажки на карте со стороны оборудования. Это очень полезный виджет, если у вас есть несколько устройств, и вы хотите отслеживать их позиции на карте.
Вы можете отправить точку на карту с помощью обычной команды виртуальной записи:
```cpp
Blynk.virtualWrite(V1, pointIndex, lat, lon, "Название");
```
Мы также создали оболочку, чтобы вы могли упростить использование виджета Карты.
Вы можете изменить метки флажков на оборудовании с помощью кода:
```cpp
WidgetMap myMap(V1);
...
int index = 1;
float lat = 51.5074;
float lon = 0.1278;
myMap.location(index, lat, lon, "Название");
```
Использование уникальных ```index``` позволяет вам переопределить существующее значение точки.
**Пример кода:** [Базовый пример Карты](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Map/Map.ino)
### Таблица (Table)
Табличный виджет удобен, когда вам нужно структурировать аналогичные данные в пределах одного графического элемента. Работает как обычная таблица.
Вы можете добавить строку в таблицу с помощью кода:
```
Blynk.virtualWrite(V1, "add", id, "Имя", "Значение");
```
Вы можете обновить строку в таблице с помощью кода:
```
Blynk.virtualWrite(V1, "update", id, "Новое имя", "Новое значение");
```
Чтобы выделить любой элемент в таблице, используйте его идентификатор:
```
Blynk.virtualWrite(V1, "pick", 0);
```
Чтобы выбрать/отменить выбор (сделать значок зеленым/серым) элемент в таблице, используйте его идентификатор:
```
Blynk.virtualWrite(V1, "select", 0);
Blynk.virtualWrite(V1, "deselect", 0);
```
Чтобы очистить таблицу используйте код:
```
Blynk.virtualWrite(V1, "clr");
```
Вы также можете обрабатывать другие действия из таблицы. Например, использовать строку таблицы в качестве кнопки переключения.
```
BLYNK_WRITE(V1) {
String cmd = param[0].asStr();
if (cmd == "select") {
// строка в таблице была выбрана.
int rowId = param[1].asInt();
}
if (cmd == "deselect") {
// строка в таблице была отменена.
int rowId = param[1].asInt();
}
if (cmd == "order") {
// когда строки в таблице переупорядочиваются
int oldRowIndex = param[1].asInt();
int newRowIndex = param[2].asInt();
}
}
```
**Примечание:** Максимальное количество строк в таблице равно 100. Когда вы достигнете предела, таблица будет работать как список FIFO (Первый пришел - первый ушел).
Это ограничение можно изменить, настроив свойство ```table.rows.pool.size``` в параметрах локального сервера.
**Пример кода:** [Простое использование таблицы](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Table/Table_Simple/Table_Simple.ino)
**Пример кода:** [Расширенное использование таблицы](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Table/Table_Advanced/Table_Advanced.ino)
### Селектор устройств (Device Selector)
Селектор устройств - это мощный виджет, который позволяет обновлять виджеты на основе одного активного устройства.
Этот виджет особенно полезен, когда у вас есть несколько устройств с аналогичной функциональностью.
Представьте, что у вас есть 4 устройства, и к каждому устройству подключен датчик температуры и влажности. Для отображения данных по всем 4 устройствам вам необходимо добавить 8 виджетов.
С помощью Селектора устройств вы можете использовать только 2 виджета, которые будут отображать температуру и влажность в зависимости от активного устройства, выбранного в Селекторе.
Все, что вам нужно сделать, это:
1. Добавить виджет Селектора устройств в проект
2. Добавить 2 виджета (например виджет отображения значений (Value Display Widget)), чтобы отобразить температуру и влажность
3. В настройках виджетов вы сможете назначить их на Селектор устройств (в разделе источника или цели)
4. Выйти из настроек, запустить проект
Теперь вы можете изменить активное устройство в Селекторе устройств и увидите, что значения температуры и влажности отражают обновленные данные для только что выбранного вами устройства.
**ПРИМЕЧАНИЕ:** Виджет вебхук ([Webhook](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/WebHook/WebHook_GET/WebHook_GET.ino)) пока не работает с Селектором устройств.
### Плитка устройств (Device Tiles)
Плитка устройств - это мощный виджет, очень похожий на виджет Селектора устройств (Device Selector), но с пользовательским интерфейсом. Позволяет отображать один пин с устройства на одну плитку.
Этот виджет особенно полезен, когда у вас есть несколько устройств с аналогичной функциональностью. Теперь вы можете группировать похожие устройства на одном макете (шаблоне).
## Sensors
### Акселерометр (Accelerometer)
Акселерометр один из [сенсоров движения](https://developer.android.com/guide/topics/sensors/sensors_motion.html),
который позволяет определить движение Вашего телефона в пространстве.
Он может пригодится для отслеживания таких событий как тряска, удар, поворот или наклон телефона. Концептуально, акселерометр определяет силу ускорения приложенную к вашему телефону.
Единица измерения - м/c^2 приложенная к каждой из осей ```x```, ```y```, ```z```.
Чтобы получить данные с сенсора нужно использовать следующий код :
```cpp
BLYNK_WRITE(V1) {
//сила ускорения, приложенная к оси x
int x = param[0].asFloat();
//сила ускорения, приложенная к оси y
int y = param[1].asFloat();
//сила ускорения, приложенная к оси z
int z = param[2].asFloat();
}
```
Акселерометр не работает при свернутом приложении.
### Барометр/Давление (Barometer/pressure)
Барометр один из сенсоров [окружающей среды](https://developer.android.com/guide/topics/sensors/sensors_environment.html)
и позволяет измерять атмосферное давление.
Измеряется в ```hPa``` (гПа) или ```mbar``` (мБар).
Чтобы получить данные с сенсора нужно использовать следующий код :
```cpp
BLYNK_WRITE(V1) {
//Давление в мБар
int pressure = param[0].asInt();
}
```
Барометр не работает при свернутом приложении.
### Гравитация (Gravity)
Гравитация - это своего рода [датчики движения](https://developer.android.com/guide/topics/sensors/sensors_motion.html), который позволяет обнаруживать движение вашего смартфона.
Полезно для мониторинга движения устройства, таких как наклон, встряхивание, вращение или качание.
Датчик силы притяжения выдает трехмерный вектор, указывающий направление и величину силы притяжения.
Измеряется в ```m/s^2``` силы притяжения, приложенной к оси ```x```, ```y```, ```z```.
Для того, чтобы принять данные от него, вам необходимо:
```cpp
BLYNK_WRITE(V1) {
//сила притяжения, приложенная к оси x
int x = param[0].asFloat();
//сила притяжения, приложенная к оси y
int y = param[1].asFloat();
//сила притяжения, приложенная к оси y
int z = param[2].asFloat();
}
```
**ВНИМАНИЕ:** Виджет гравитации не работает в фоновом режиме.
### Влажность (Humidity)
Влажность является своего рода [датчиком среды](https://developer.android.com/guide/topics/sensors/sensors_environment.html),
который позволяет измерять относительную влажность окружающей среды.
Измеряется в ```%``` - фактически это относительная влажность в процентах.
Для того, чтобы принять данные от датчика, вам необходимо:
```cpp
BLYNK_WRITE(V1) {
//Влажность в %
int humidity = param.asInt();
}
```
**ВНИМАНИЕ:** Влажность не работает в фоновом режиме.
### Свет (Light)
Свет - это своего рода [датчики окружающей среды](https://developer.android.com/guide/topics/sensors/sensors_environment.html), который позволяет измерять уровень освещенности (уровень внешней освещенности измеряется в люксах). В телефонах чаще всего используется для управления яркостью экрана.
Для того, чтобы принять данные этого виджета, вам необходимо:
```cpp
BLYNK_WRITE(V1) {
//уровень освещенности
int lx = param.asInt();
}
```
Виджет Свет не работает в фоновом режиме.
### Близость (Proximity)
Близость - это своего рода [датчики положения](https://developer.android.com/guide/topics/sensors/sensors_position.html)
это позволяет определить, насколько близко смартфон к лицу. Измеряется в ```cm``` (см) - расстояние от телефона до лица. Однако большинство этих датчиков возвращает только информацию FAR / NEAR.
Поэтому, возвращаемое значение будет ```0 / 1```. Где 0 / LOW = ```FAR``` (далеко), а 1 / HIGH = ``` NEAR``` (рядом).
Для того, чтобы принять данные из виджета, вам необходимо:
```cpp
BLYNK_WRITE(V1) {
// расстояние до объекта
int proximity = param.asInt();
if (proximity) {
// РЯДОМ
} else {
// ДАЛЕКО
}
}
```
Виджет близость не работает в фоновом режиме.
### Температура (Temperature)
Температура является своего рода [датчиком окружающей среды](https://developer.android.com/guide/topics/sensors/sensors_environment.html) который позволяет измерять температуру окружающего воздуха. Измеряется в ```°C``` - градусах Цельсия.
Для приема данных из виджета, необходимо использовать код:
```cpp
BLYNK_WRITE(V1) {
// температура в градусах цельсия
int celcius = param.asInt();
}
```
Виджет Температуры не работает в фоновом режиме.
### Триггер GPS (GPS Trigger)
Виджет Триггер GPS позволяет легко инициировать события, когда вы входите или выходите из географической зоны. Этот виджет будет работать в фоновом режиме и периодически будет проверять ваши координаты. Если ваше местоположение находится в пределах или вне указанной зоны (географическая зона выбирается на карте виджета), виджет отправит команду ```HIGH```/``` LOW``` на аппаратное устройство. Например, Триггер GPS назначен для пина ```V1```, и включена опция ```Trigger When Enter```. В этом случае, когда вы окажитесь в указанной географической зоне виджет вызовет событие ```HIGH```.
```cpp
BLYNK_WRITE(V1) {
int state = param.asInt();
if (state) {
//Вы вошли в зону
} else {
//Вы вышли из зоны
}
}
```
Подробнее о том, как работает GPS-виджет, вы можете прочитать [здесь](https://developer.android.com/guide/topics/location/strategies.html).
**ВНИМАНИЕ:** Виджет Триггер GPS работает в фоновом режиме.
### Поток GPS (GPS Streaming)
Полезно для мониторинга местонахождения смартфона получать данные о широте, долготе, высоте и скорости (скорость часто может быть 0, если смартфон не поддерживает ее измерение).
Чтобы принимать данные из этого виджета, вам необходимо:
```cpp
BLYNK_WRITE(V1) {
float latitude = param[0].asFloat();
float longitude = param[1].asFloat();
float altitude = param[2].asFloat();
float speed = param[3].asFloat();
}
```
или вы можете использовать подготовленную оболочку ```GpsParam``` :
```cpp
BLYNK_WRITE(V1) {
GpsParam gps(param);
//Печать лат/лон с 6 десятичными знаками
Serial.println(gps.getLat(), 7);
Serial.println(gps.getLon(), 7);
Serial.println(gps.getAltitude(), 2);
Serial.println(gps.getSpeed(), 2);
}
```
Поток GPS работает в фоновом режиме.
**Пример кода:** [Поток GPS](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/GPS_Stream/GPS_Stream.ino)
## Other
### Мост (Bridge)
Мост может быть использован для связи между устройствами (без участия приложения). Вы можете отправлять цифровые / аналоговые / виртуальные команды записи с одного устройства на другое, зная только токен авторизации. На данный момент виджет Мост не обязательно использовать в приложении (здесь он используется для указания того, что у нас есть такая функция).
**Вы можете использовать несколько мостов для управления несколькими устройствами.**
Виджет Мост использует виртуальный пин и превращает его в канал для управления другим устройством. Это означает, что вы можете контролировать любые виртуальные, цифровые или аналоговые пины целевого устройства. Будьте осторожны, не используйте пины типа ```A0, A1, A2 ...``` при обмене данными между различными типами устройств, так как в таких случаях Arduino Core может ссылаться на неверные пины.
Пример кода для устройства A, которое будет отправлять значения на устройство B:
```cpp
//Инициирует виджет Моста на V1 устройства A
WidgetBridge bridge1(V1);
...
void setup() {
Blynk.begin(...);
while (Blynk.connect() == false) {
// Ждем пока Blynk подключится
}
bridge1.digitalWrite(9, HIGH); // выставим триггер HIGH на D9 устройства B. Код на устройстве B не требуется
bridge1.analogWrite(10, 123);
bridge1.virtualWrite(V1, "hello"); // вам нужно написать код на устройстве B, чтобы получить это значение. См. ниже
bridge1.virtualWrite(V2, "value1", "value2", "value3");
}
BLYNK_CONNECTED() {
bridge1.setAuthToken("OtherAuthToken"); // токен с устройства B
}
```
**ВАЖНО:** при выполнении ```virtualWrite()``` с виджета Мост, устройство B должно обрабатывать входящие данные с устройства A.
Например, если вы отправляете значение с устройства A на устройство B, используя ```bridge.virtualWrite (V5)```, вам необходимо использовать свой обработчик на устройстве B:
```cpp
BLYNK_WRITE(V5){
int pinData = param.asInt(); //pinData variable will store value that came via Bridge
}
```
Имейте в виду, что ```bridge.virtualWrite``` не отправляет никаких значений в мобильное приложение. Для этого вам нужно вызвать ```Blynk.virtualWrite```.
**Пример кода:** [Мост](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Bridge/Bridge.ino)
### Обработчик событий (Eventor)
Виджет Обработчик событий позволяет создавать простые правила поведения или **события**.
Давайте рассмотрим типичный вариант использования: считывание температуры с датчика DHT и отправка push-уведомления, когда температура превышает определенный предел:
```cpp
float t = dht.readTemperature();
if (isnan(t)) {
return;
}
if (t > 40) {
Blynk.notify(String("Температура слишком высокая: ") + t);
}
```
С Обработчиком событий вам не нужно писать этот код. Все, что вам нужно, это отправить значение с датчика на сервер Blynk:
```cpp
float t = dht.readTemperature();
Blynk.virtualWrite(V0, t);
```
Не забывайте, что команды ```virtualWrite``` должны быть заключены в таймер и не должны использоваться в основном цикле ```loop```.
**ПРИМЕЧАНИЕ:** Не забудьте добавить виджет уведомлений в приложении.
Обработчик событий пригодится вам, когда нужно изменить условия на лету без повторной загрузки нового скетча на аппаратное обеспечение. Вы можете создать столько **событий**, сколько вам нужно. Обработчик событий также может быть запущен со стороны приложения. Вам просто нужно назначить виджет на тот же контакт, что и ваше событие в Обработчике событий.
Обработчик событий не постоянно отправляет события. Давайте рассмотрим простой пример, как показано выше ```if (temperature > 40) send notification```. Когда температура превышает 40 пороговых значений - отправляется уведомление. Если температура продолжает оставаться выше 40 никакие повторные действия не будут инициированы. Но если ```temperature``` опускается ниже порогового значения, а затем проходит его снова уведомление будет отправлено повторно (для уведомлений Обработчика событий нет ограничения отправки в течение 5 секунд).
Обработчик событий также поддерживает события таймера (Timer). Например, вы можете установить пин ```V1``` ON/HIGH в 21:00:00 каждую пятницу.
В Обработчике событий вы можете назначить несколько таймеров на один и тот же пин, отправить любую строку/число, выбрать день и часовой пояс.
Чтобы удалить созданное **событие**, пожалуйста, используйте сдвиг пальцем по экрану. Вы также можете перенести последний элемент самого события.
**Пример кода:** [Обработчик событий](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Eventor/Eventor.ino)
**ПРИМЕЧАНИЕ:** Виджет таймера зависит от времени сервера, а не вашего телефона. Иногда время телефона может не соответствовать времени сервера.
**ПРИМЕЧАНИЕ:** события запускаются только один раз при выполнении условия. Это означитает что [цепочка событий] (https://community.blynk.cc/t/eventor-behavior-bug-feature/20962) невозможна (однако она может быть включена в коммерческой версии).
### Часы реального времени (RTC)
Часы реального времени позволяют получать время с сервера. Вы можете предварительно выбрать любой часовой пояс в пользовательском интерфейсе, чтобы получить время на оборудование из нужной локали.
**Пример кода:** [Часы реального времени](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/RTC/RTC.ino)
### Bluetooth с низким энергопотреблением
Этот виджет позволяет включить блутзуз с низким энергопотреблением на вашем телефоне. На текущий момент виджет также
требует наличия интернет соединения (постараемся пофиксить в ближайшем будущем). Некоторые типы виджетов нельзя
использовать вместе с блутузом, например исторический граф, так как он требует чтобы данные отправлялись на сервер, чего
блутуз виджет не делает.
**Список поддерживаемых чипов и контроллеров:** [BLE](https://github.com/blynkkk/blynk-library/tree/master/examples/Boards_Bluetooth)
### Блютуз (Bluetooth)
Этот виджет позволяет включить блютуз на вашем телефоне. На текущий момент виджет также требует наличия интернет соединения (постараемся пофиксить в ближайшем будущем) и поддерживается только на Android.
Некоторые типы виджетов нельзя использовать вместе с блютузом, например исторический граф, так как он требует чтобы
данные отправлялись на сервер, чего блютуз виджет не делает.
**Список поддерживаемых чипов и контроллеров:** [BLE](https://github.com/blynkkk/blynk-library/tree/master/examples/Boards_Bluetooth)
### Музыкальный проигрыватель (Music Player)
Простой элемент интерфейса с 3 кнопками - имитирует интерфейс музыкального проигрывателя. Каждая кнопка отправляет свою команду на аппаратное устройство: ```play``` (воспроизвести), ```stop``` (стоп), ```prev``` (предыдущий), ```next``` (следующий).
Вы можете изменить состояние виджета в приложении с аппаратной стороны с помощью следующих команд:
```
Blynk.virtualWrite(Vx, "play");
Blynk.virtualWrite(Vx, "stop");
```
Вы также можете изменить состояние воспроизведение/остановка виджета с помощью следующего кода (эквивалент вышеупомянутых команд):
```Blynk.setProperty(V1, "isOnPlay", "false");```
**Пример кода:** [Музыкальный проигрыватель](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Player/Player.ino)
### Вебхук (Webhook)
Вебхук очень мощный виджет, который позволяет Вам легко интегрироватся с любыми сторонними сервисами. С его помощью
Вы можете слать любые HTTP/S запросы на любой сервер или устройство, которое имеет HTTP/S API (например, лампы Philips Hue).
Вебхук вешается на вирутальный пин и любая команда, которая приходит на этот пин будет вызывать срабатывание HTTP/S
запроса. Команды на такой виртуальный пин могут приходить как со стороны железа, так и со стороны приложения. То есть,
Вы можете слать любой HTTP запрос при нажатии кнопки в приложении, если эта кнопка на том же пине что и вебхук.
Вот простой пример, представьте, что Вы хотите слать данные с микроконтроллера не только в Blynk, но и в какой-то другой сервис,
например - Google Docs или в thingspeak.com. Раньше Вам для этого пришлось бы писать что-то вроде :
```cpp
WiFiClient client;
if (client.connect("api.thingspeak.com", 80)) {
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: " + apiKeyThingspeak1 + "\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);
}
```
С вебхуком этого больше делать не нужно. Достаточно лишь заполнить поля виджета в приложении и выполнить привычное:
```cpp
Blynk.virtualWrite(V0, value);
```
Где V0 - пин вебхук виджета.
В дополнение, Вы можете подставлять значение пина в URL:
```cpp
https://api.thingspeak.com/update?api_key=xxxxxx&field1=/pin/
```
или тело запроса :
```cpp
["/pin/"]
```
Так же можно отправлять несколько значений внутри одного пина (до 5) :
```/pin[0]/```,```/pin[1]/```, ```/pin[2]/```
Еще одна крутая штука - это возможность делать HTTP GET запросы на сервере и слать их результат на микроконтроллер.
Прелесть тут в том, что Вам не нужно для этого писать сложный код на микроконтроллере. Представьте, что Вам нужно
получить информацию о погоде от какого-то метио сервиса. Например, по такому запросу :
```http://api.sunrise-sunset.org/json?lat=33.3823&lng=35.1856&date=2016-10-01```
Вы можете вставить этот запрос в вебхук виджет, выбрать пин ```V0``` и написать :
```cpp
BLYNK_WRITE(V0){
String webhookdata = param.asStr();
Serial.println(webhookdata);
}
```
Теперь, каждый раз когда вы дергаете ```V0``` с помощью ```Blynk.virtualWrite(V0, 1)``` будет вызвана функция ```BLYNK_WRITE(V0)```.
**Замечание:** обычно HTTP запросы довольно большие, поэтому Вам, вероятно, нужно будет увеличить лимит на максимальную
длину сообщения на микроконтроллере ```#define BLYNK_MAX_READBYTES 1024```.
**Замечание:** наше облако так же имеет определенные лимиты для вебхука. Мы разрешаем слать только 1 запрос в секунду.
Это поведение можно изменить на локальном сервер через свойство ```webhooks.frequency.user.quota.limit```. Пожалуйста,
используйте вебхуки с умом. Многие веб ресурсы не способны обрабатывать даже 1 запрос в секунду.
**Замечание :** в случае если Ваш вебхук не выполнился 10 раз подряд - вебхук виджет будет остановлен. Чтобы восстановить
его работу - нужно открыть и закрыть виджет в режиме редактирования. Не выполненными считаются запросы у которых код ответа
не равен 200 или 302.
### Отчеты (Reports)
Функция виджета Отчеты заключается в настройке и разметке отчетов данных в формате CSV. Вы можете выбрать разовые или переодически запланированные отчеты.
Кроме того, в отчетах вы можете очистить все пользовательсике данные, собранные с ваших устройств.
Вам необходимо настроить начальные параметры в режиме редактирования, а затем уже в режиме воспроизведения вы сможете настроить сами отчеты.
#### Режим редактирования. Конфигурация ввода данных
В режиме редактирования (когда ваш проект остановлен) вы определяете потоки данных, которые вы хотели бы позже включить в отчет.
Виджет Отчеты предназначен для работы с виджетом [Плитка устройств (Device Tiles)](https://github.com/blynkkk/blynkkk.github.io/blob/master/mobile/ru/device_tiles.md). Если вы не используете плитки устройств, вы все равно можете выбрать одно устройство или группу устройств в качестве источника данных для отчетов.
Вы должны выбрать либо [Плитку устройств](https://github.com/blynkkk/blynkkk.github.io/blob/master/mobile/ru/device_tiles.md), либо одино устройство, либо группу устройств для отчета. Вы не можете объединить эти оба варианта.
#### Режим воспроизведения
После добавления исходных устройств и их потоков данных нажмите кнопку «Воспроизвести» и нажмите кнопку «Отчеты».
### Настройка отчетов
Каждый параметр отчета предполагает свои собственные настройки:
```Report name``` (Имя отчета) - дайте вашему отчету осмысленное имя.
```Data source``` (Источники данных) - выберите потоки данных, которые вы хотели бы включить в отчеты.
```Report Frequency``` (периодичность отчетов) - Определяет, как часто будут отправляться отчеты. Они могут быть разовыми и запланированными.
```one-time``` (Сейчас) - мгновенно сформирует отчет и отправит его на указанные адреса электронной почты. Нажмите на значок справа, чтобы отправить отчет.
Запланированные отчеты могут быть отправлены ```daily```/```weekly```/```monthly``` (ежедневно/еженедельно/ежемесячно).
```At Time``` (Время) установите время дня, когда отчет будет отправлен.
```Start```/```End``` (Качало/Конец) указывает дату начала и окончания оправки отчетов.
Для еженедельного отчета вы можете выбрать день недели, когда отчет должен быть отправлен.
Для ежемесячного отчета вы можете выбрать, отправку отчета в первый или последний день месяца.
```Recipients``` (Получатели) - укажите до 5 адресов электронной почты..
```Data resolution``` (Разрешение данных) определяет детализацию ваших отчетов. Поддерживаемые детализации: ```minute``` (ежеминутно), ```hourly``` (ежечасно) и ```daily``` (ежедневно).
Например, когда вы генерируете ежедневный отчет с детализацией в 1 минуту, вы получаете ```24 * 60 * 60``` единиц данных в вашем ежедневном отчете за каждый выбранный поток.
```Group data in reports by``` (Группировка данных в отчетах) - укажите выходной формат файла-(ов) CSV:
```Datastream``` (Поток) - вы получите один CSV файл для каждого потока данных.
```Device``` (Устройство) - вы получите один CSV-файл на каждое устройство. Каждый файл будет содержать все включенные потоки данных.
```Report``` (Отчет) - вы получите один CSV-файл для всех ваших устройств и всех ваших потоков данных.
```Timezone correction``` (Времненная зона) - укажите корректировку часового пояса, если вам нужно настроить дату и время отчета на определенный часовой пояс.
```Date and time format``` (Формат даты и времени) - определяет формат поля временной метки ваших данных.
Вы можете выбрать ```2018-06-21 20:16:48```, ```2018-06-21T20:16:48+03:00``` или другой поддерживаемый формат.
Существует особый формат ```Timestamp``` (Временная метка), которая отражает разницу между текущим временем и полуночью 1 января 1970 года UTC, измеряемую в миллисекундах.
После настройки отчета нажмите кнопку «ОК» в правом верхнем углу. Ваш отчет готов.
После настройки отчета вы увидите, когда запланирован следущий отчет ```Next```, а также увидите расписание для этого отчета.
После отправки отчета хотя бы один раз, вы можете увидеть дату его последней отправки ```Last```.
```Last``` (Последний) метка также содержит статус отправки отчета:
- ```OK``` (Успешно): отчет был сгенерирован и успешно отправлен Получателям;
- ```No Data``` (Нет данных): отчет не содержит данных за указанный период;
- ```Error``` (Ошибка): что-то пошло не так. Пожалуйста, свяжитесь со службой поддержки Blynk.
Отчеты будут генерироваться, даже если ваш проект не находится в активном (Play) режиме. Однако помните, неактивные проекты небудут генерировать данные.
**ПРИМЕЧАНИЕ:** все отчеты формируются в кодировке UTF-16. Пожалуйста, убедитесь, что при открытии файла отчета вы выбрали кодировку UTF-16 в вашем CSV-редакторе.
### Отчеты (Reports)
Функция виджета Отчеты заключается в настройке и разметке отчетов данных в формате CSV. Вы можете выбрать разовые или переодически запланированные отчеты.
Кроме того, в отчетах вы можете очистить все пользовательсике данные, собранные с ваших устройств.
Вам необходимо настроить начальные параметры в режиме редактирования, а затем уже в режиме воспроизведения вы сможете настроить сами отчеты.
#### Режим редактирования. Конфигурация ввода данных
В режиме редактирования (когда ваш проект остановлен) вы определяете потоки данных, которые вы хотели бы позже включить в отчет.
Виджет Отчеты предназначен для работы с виджетом [Плитка устройств (Device Tiles)](https://github.com/blynkkk/blynkkk.github.io/blob/master/mobile/ru/device_tiles.md). Если вы не используете плитки устройств, вы все равно можете выбрать одно устройство или группу устройств в качестве источника данных для отчетов.
Вы должны выбрать либо [Плитку устройств](https://github.com/blynkkk/blynkkk.github.io/blob/master/mobile/ru/device_tiles.md), либо одино устройство, либо группу устройств для отчета. Вы не можете объединить эти оба варианта.
#### Режим воспроизведения
После добавления исходных устройств и их потоков данных нажмите кнопку «Воспроизвести» и нажмите кнопку «Отчеты».
### Настройка отчетов
Каждый параметр отчета предполагает свои собственные настройки:
```Report name``` (Имя отчета) - дайте вашему отчету осмысленное имя.
```Data source``` (Источники данных) - выберите потоки данных, которые вы хотели бы включить в отчеты.
```Report Frequency``` (периодичность отчетов) - Определяет, как часто будут отправляться отчеты. Они могут быть разовыми и запланированными.
```one-time``` (Сейчас) - мгновенно сформирует отчет и отправит его на указанные адреса электронной почты. Нажмите на значок справа, чтобы отправить отчет.
Запланированные отчеты могут быть отправлены ```daily```/```weekly```/```monthly``` (ежедневно/еженедельно/ежемесячно).
```At Time``` (Время) установите время дня, когда отчет будет отправлен.
```Start```/```End``` (Качало/Конец) указывает дату начала и окончания оправки отчетов.
Для еженедельного отчета вы можете выбрать день недели, когда отчет должен быть отправлен.
Для ежемесячного отчета вы можете выбрать, отправку отчета в первый или последний день месяца.
```Recipients``` (Получатели) - укажите до 5 адресов электронной почты..
```Data resolution``` (Разрешение данных) определяет детализацию ваших отчетов. Поддерживаемые детализации: ```minute``` (ежеминутно), ```hourly``` (ежечасно) и ```daily``` (ежедневно).
Например, когда вы генерируете ежедневный отчет с детализацией в 1 минуту, вы получаете ```24 * 60 * 60``` единиц данных в вашем ежедневном отчете за каждый выбранный поток.
```Group data in reports by``` (Группировка данных в отчетах) - укажите выходной формат файла-(ов) CSV:
```Datastream``` (Поток) - вы получите один CSV файл для каждого потока данных.
```Device``` (Устройство) - вы получите один CSV-файл на каждое устройство. Каждый файл будет содержать все включенные потоки данных.
```Report``` (Отчет) - вы получите один CSV-файл для всех ваших устройств и всех ваших потоков данных.
```Timezone correction``` (Времненная зона) - укажите корректировку часового пояса, если вам нужно настроить дату и время отчета на определенный часовой пояс.
```Date and time format``` (Формат даты и времени) - определяет формат поля временной метки ваших данных.
Вы можете выбрать ```2018-06-21 20:16:48```, ```2018-06-21T20:16:48+03:00``` или другой поддерживаемый формат.
Существует особый формат ```Timestamp``` (Временная метка), которая отражает разницу между текущим временем и полуночью 1 января 1970 года UTC, измеряемую в миллисекундах.
После настройки отчета нажмите кнопку «ОК» в правом верхнем углу. Ваш отчет готов.
После настройки отчета вы увидите, когда запланирован следущий отчет ```Next```, а также увидите расписание для этого отчета.
После отправки отчета хотя бы один раз, вы можете увидеть дату его последней отправки ```Last```.
```Last``` (Последний) метка также содержит статус отправки отчета:
- ```OK``` (Успешно): отчет был сгенерирован и успешно отправлен Получателям;
- ```No Data``` (Нет данных): отчет не содержит данных за указанный период;
- ```Error``` (Ошибка): что-то пошло не так. Пожалуйста, свяжитесь со службой поддержки Blynk.
Отчеты будут генерироваться, даже если ваш проект не находится в активном (Play) режиме. Однако помните, неактивные проекты небудут генерировать данные.
**ПРИМЕЧАНИЕ:** все отчеты формируются в кодировке UTF-16. Пожалуйста, убедитесь, что при открытии файла отчета вы выбрали кодировку UTF-16 в вашем CSV-редакторе.
================================================
FILE: Widgets.md
================================================
#Widgets
Widgets are interface modules. Each of them performs a specific input/ output function when communicating with the hardware.
There are 4 types of Widgets:
- **Controllers** - used to send commands that control your hardware
- **Displays** - used for data visualization from sensors and other sources;
- **Notifications** - send messages and notifications;
- **Interface** - widgets to perform certain GUI functions;
- **Other** - widgets that don't belong to any category;
Each Widget has it's own settings. Some of the Widgets (e.g. Bridge) just enable functionality and they don't have any settings.
## Common Widget Settings
### Pin Selector
This is one of the main parameters you need to set. It defines which pin to control or to read from.
**Digital Pins** - represent physical Digital IO pins on your hardware. PWM-enabled pins are marked with the ```~``` symbol
**Analog Pins** - represent physical Analog IO pins on your hardware
**Virtual Pins** - have no physical representation. They are used to transfer any data between Blynk App and your hardware.
Read more about Virtual Pins [here](/#blynk-main-operations-virtual-pins).
### Data Mapping
In case you want to map incoming values to specific range you may use mapping button:
Let's say your sensor sends values from 0 to 1023. But you want to display values in a range 0 to 100 in the app.
When Data Mapping enabled, incoming value 1023 will be mapped to 100.
### SPLIT/MERGE
Some of the Widgets can send more than one value. And with this switch you can control how to send them.
- **SPLIT**:
Each of the parameters is sent directly to the Pin on your hardware (e.g D7). You don't need to write any code.
**NOTE:** In this mode you send multiple commands from one widget, which can reduce performance of your hardware.
Example: If you have a Joystick Widget and it's set to D3 and D4, it will send 2 commands over the Internet:
```cpp
digitalWrite(3, value);
digitalWrite(4, value);
```
- **MERGE:**
When MERGE mode is selected, you are sending just 1 message, consisting of array of values. But you'll need to parse it on the hardware.
This mode can be used with Virtual Pins only.
Example: Add a zeRGBa Widget and set it to MERGE mode. Choose Virtual Pin V1
```cpp
BLYNK_WRITE(V1) // There is a Widget that WRITEs data to V1
{
int r = param[0].asInt(); // get a RED channel value
int g = param[1].asInt(); // get a GREEN channel value
int b = param[2].asInt(); // get a BLUE channel value
}
```
### Decimals
Defines how many decimals you would like to see when moving a Slider.
When "No Fraction" is chosen, slider will only send integer values with no decimals.
"1 digit" means that values will look like 1.1, 1.2, ..., 2.0, etc.
### Send On Release
This option allows you to optimize data traffic on your hardware.
For example, when you move joystick widget, commands are streamed to the hardware, during a single joystick move
you can send dozens of commands. There are use-cases where it's needed, however creating such a load may lead to hardware overload and reset.
**Send On Release** is a recommended setting for majority of applications. This is also a default setting.
### Write interval
Similar to "Send on Release" option. However, it allows you to stream values to your hardware within certain interval. For example, setting **write interval** to 100 ms means that while you move the slider, only 1 value will be sent to hardware within 100 ms period.
This option is also used to optimize data traffic flow to your hardware.
### Color gradient
When you choose gradient, it affects the color of widget elements based on invoming values.
For example: You set Gauge Widget with Min and Max parameters of 0-100, and choose green-yellow-red gradient. When hardware sends:
- `10`, Gauge will change it's color to green color
- `50` will change Gauge to yellow color
- `80` will change Gauge to red color
There are 2 types of gradients you can choose from:
- Warm: Green - Orange - Red;
- Cold: Green - Blue - Violet;
##Controllers
### Button
Works in push or switch modes. Allows to send ON and OFF (LOW/HIGH) values. Button sends 1 (HIGH) on press and sends 0 (LOW) on release.
**Sketch:** [BlynkBlink](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/BlynkBlink/BlynkBlink.ino)
### Slider
Similar to potentiometer. Allows to send values between in a given MIN/MAX range.
**Sketch:** [BlynkBlink](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/BlynkBlink/BlynkBlink.ino)
### Timer
Timer triggers actions at a specified time. Even if smartphone and app is offline. Start time sends 1 (HIGH). Stop time sends 0 (LOW).
Recent Android version also has improved Timer within Eventor widget.
With Eventor Time Event you can assign multiple timers on same pin, send any string/value, select days and timezone.
It is recommended to use Eventor over Timer widget.
However Timer widget is still suitable for simple timer events.
**NOTE:** The timer widget rely on the server time and not your phone time. Sometimes the phone time may not match the server time.
**Sketch:** [Timer](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Timer/Timer.ino)
### Joystick
Control servo movements in 4 directions
####Settings:
- SPLIT/MERGE modes - read [here](/#widgets-common-widget-settings-splitmerge)
- **Rotate on Tilt**
When it's ON, Joystck will automatically rotate if you use your smartphone in landscape orientation
- **Auto-Return**
-
When it's OFF, Joystick handle will not return back to center position. It will stay where you left it.
**Sketch:** [JoystickTwoAxis](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/JoystickTwoAxis/JoystickTwoAxis.ino)
### zeRGBa
zeRGBa is a usual RGB color picker + brightness picker
#### Settings:
- **SPLIT**:
Each of the parameters is sent directly to the Pin on your hardware (e.g D7). You don't need to write any code.
**NOTE:** In this mode you send multiple commands from one widget, which can reduce performance of your hardware.
Example: If you have a zeRGBa Widget and it's set to D1, D2, D3 it will send 3 commands over the Internet:
```cpp
digitalWrite(1, r);
digitalWrite(2, g);
digitalWrite(3, b);
```
- **MERGE**:
When MERGE mode is selected, you send 1 message with an array of values inside. You would need to parse the message on the hardware.
This mode can be used with Virtual Pins only.
Example: Add a zeRGBa Widget and set it to MERGE mode. Choose Virtual Pin V1.
```cpp
BLYNK_WRITE(V1) // zeRGBa assigned to V1
{
// get a RED channel value
int r = param[0].asInt();
// get a GREEN channel value
int g = param[1].asInt();
// get a BLUE channel value
int b = param[2].asInt();
}
```
### Step Control
Step Control is used to set granular values with a given step
2 buttons are assigned to 1 pin. One button increments the value, another one decrements it.
**Send Step** option allows you to send step value to hardware instead of actual value of step widget.
**Loop value** option allows you to reset step widget to start value when maximum value is reached.
**Sketch:** [Basic Sketch](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/BlynkBlink/BlynkBlink.ino)
##Displays
### Value Display
Displays incoming data.
**Sketch:** [BlynkBlink](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/BlynkBlink/BlynkBlink.ino)
### Labeled Value
Displays incoming data in a formatted wayt. It is a better version of 'Value Display' where you can add suffixes and prefixes on the app side, with no coding on the hardware.
**Sketch:** [BlynkBlink](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/BlynkBlink/BlynkBlink.ino)
#### Formatting options
For example: your sensor sends vaule of 12.6789 to Blynk application.
Next formatting options are supported:
```/pin/``` - displays the value without formatting (12.6789)
```/pin./``` - displays the rounded value without decimal part (13)
```/pin.#/``` - displays the value with 1 decimal digit (12.7)
```/pin.##/``` - displays the value with two decimal places (12.68)
### LED
A simple LED for indication. You need to send 0 in order to turn LED off. And 255 in order to turn LED on. Or just use
Blynk API as described below:
```cpp
WidgetLED led1(V1); //register to virtual pin 1
led1.off();
led1.on();
```
All values between 0 and 255 will change LED brightness:
```cpp
WidgetLED led2(V2);
led2.setValue(127); //set brightness of LED to 50%.
```
**Sketch:** [LED](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/LED/LED_Blink/LED_Blink.ino)
### Gauge
Visual display of numeric values.
**Sketch:** [BlynkBlink](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/BlynkBlink/BlynkBlink.ino)
#### Formatting options
For example: your sensor sends vaule of 12.6789 to Blynk application.
Next formatting options are supported:
```/pin/``` - displays the value without formatting (12.6789)
```/pin./``` - displays the rounded value without decimal part (13)
```/pin.#/``` - displays the value with 1 decimal digit (12.7)
```/pin.##/``` - displays the value with two decimal places (12.68)
### LCD
This is a regular 16x2 LCD display made in our secret facility in China.
#### SIMPLE / ADVANCED MODE
#### Commands
You need to use special commands with this widget:
```
lcd.print(x, y, "Your Message");
```
Where x is a symbol position (0-15), y is a line id (0 or 1),
```
lcd.clear();
```
**Sketch:** [LCD Advanced Mode](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/LCD/LCD_AdvancedMode/LCD_AdvancedMode.ino)
**Sketch:** [LCD Simple Mode Pushing](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/LCD/LCD_SimpleModePushing/LCD_SimpleModePushing.ino)
**Sketch:** [LCD Simple Mode Reading](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/LCD/LCD_SimpleModeReading/LCD_SimpleModeReading.ino)
#### Formatting options
For example: your sensor sends vaule of 12.6789 to Blynk application.
Next formatting options are supported:
```/pin/``` - displays the value without formatting (12.6789)
```/pin./``` - displays the rounded value without decimal part (13)
```/pin.#/``` - displays the value with 1 decimal digit (12.7)
```/pin.##/``` - displays the value with two decimal places (12.68)
### SuperChart
SuperChart is used to visualise live and historical data. You can use it for sensor data, for binary event logging and more.
To use SuperChart widget you would need to push the data from the hardware with the desired interval by using timers.
[Here is](https://examples.blynk.cc/?board=ESP8266&shield=ESP8266%20WiFi&example=GettingStarted%2FPushData) a basic example for data pushing.
#### Interactions:
- **Switch between time ranges and Live mode**
Tap time ranges at the bottom of the widget to change time ranges
- **Tap Legend Elements** to show or hide datastreams
- **Tap'n'hold to view timestamp and corresponding values**
- **Quick swipe from left to right to reveal previous data**
Then you can then scroll data back and forward within the given time range.
- **Full Screen Mode**
Press this button to open Full Screen view in landscape orientation:
Simply rotate the phone back to portrait mode. Chart should rotate automagically.
In full screen view you will see X (time) and multiple Y scales.
Full Screen Mode can be disabled from widget Settings.
- **Menu Button**
Menu button will open additional functions:
- Export to CSV
- Erase Data on the server
#### SuperChart Settings:
- Chart Title
- Title Font Size
You have a choice of 3 font sizes
- Title Alignment
Choose chart title alignment. This setting also affects Title and Legend position on the Widget.
- Show x-axis (time)
Select it if you want to show the time label at the bottom of your chart.
- Time ranges picker
Allows you to select required periods (`15m`, `30m`, `1h`, `3h`, ...) and resolution for your chart. Resolution
defines how precise your data is. Right now chart supports 2 types of resolution `standard` and `high`. Resolution also
depends on the selected period. For example, `standard` resolution for `1d` means you'll get 24 points per day (1 per hour),
with `high` resolution you'll get for `1d` 1440 points per day (1 per minute).
- Datastreams - add datastreams (read below how to configure datastreams)
#### Datastream Settings
Widget supports up to 4 Datastreams.
Press Datastream Settings Icon to open Datastream Settings.
**Design:**
Choose available types of Chart:
- Line
- Area
- Bar
- Binary (anchor LINK to binary)
**Color:**
Choose solid colors or gradients
**Source and input:**
You can use 3 types of Data source:
**1. Virtual Pin**
Choose the desired Device and Virtual Pin to read the data from.
**2. Tags**
SuperChart can aggregate data from multiple devices using built-in aggregation functions.
For example, if you have 10 Temperature sensors sending temperature with the given period,
you can plot average value from 10 sensors on the widget.
To use Tags:
- **[Add Tag](/#blynk-main-operations-control-of-multiple-devices-tags)** to every device you want to aggregate data from.
- **Push data to the same Virtual Pin** on every device. (e.g. ```Blynk.virtualWrite (V0, temperature);```)
- **Choose Tag as a source** in SuperChart Widget and use the pin where the data is coming to (e.g V0)
**Functions available:**
- **SUM**, will summarize all incoming values to the specified Virtual Pin across all devices tagged with the chosen tag
- **AVG**, will plot average value
- **MED**, will find a median value
- **MIN**, will plot minimum value
- **MAX** will plot maximum value
**☝️ IMPORTANT: Tags are not working in Live Mode.**
3. **[Device Selector](/#widgets-time-input-device-selector)**
If you add Device Selector Widget to your project, you can use it as a source for SuperChart.
In this case, when you change the device in Device Selector, chart will be updated accordingly
**Y-Axis Settings**
There are 4 modes of how to scale data along the Y axis
1. *Auto*
Data will be auto-scaled based on min and max values of the given time period. This is nice option to start with.
2. **Values**
When this mode is selected, Y scale will be set to the values you choose.
For example, if your hardware sends data with values varying from -100 to 100, you can set the chart
to this values and data will be rendered correctly.
You may also want to visualize the data within some specific range.
Let's say incoming data has values in the range of 0-55, but you would like to see only values in the range 30-50.
You can set it up and if values are out of Y scale you configured, chart will be cropped
3. **% of Height**
This option allows you to auto-scale incoming data on the widget and position it the way you want.
In this mode, you set up the percentage of widget height on the screen, from 0% to 100%.
If you set 0-100%, in fact it's a full auto-scale. No matter in which range the data is coming,
it will be always scaled to the whole height of the widget.
If you set it to 0-25%, then this chart will only be rendered on 1/4 of the widget height:
This setting is very valuable for **Binary Chart** or for visualizing a few datastreams on the same chart in a different way.
4. *Delta*
While data stays within the given Delta value, chart will be auto-scaled within this range.
If delta exceeds the range, chart will be auto-scaled to min/max values of the given period.
**Suffix:**
Here you can specify a suffix that will be shown during the Tap'n'hold
**Decimals**
Defines the formatting of the graph value when you Tap'n'hold the graph. Possible options are: #, #.#, #.##, etc.
**Connect Missing Data Points**
If this switch is ON, then SuperChart will connect all the dots even if there was no data
If it's set to OFF, then you will see gaps in case there was no data.
**Binary Chart Settings**
This type of chart is useful to plot binary data, for example when unit was ON or OFF, or when motion was detected or when certain threshold was reached.
You need to specify a **FLIP** point, which is the point where incoming data will be turned into TRUE or FALSE state.
For example, you send the data in the range of `0 to 1023`. If you set `512` as a **FLIP** point, then everything above `512` (excluding 512) will be recorded as `TRUE`, any value below `512` (including 512) will be `FALSE`.
Another example, if you send `0 and 1` and set `0` as a **FLIP** point, then `1` will be `TRUE`, `0` will be `FALSE`
**State Labels:**
Here you can specify how `TRUE/FALSE` should be shown in Tap'n'Hold mode.
For example, you can set to `TRUE` to "Equipment ON" label, `FALSE` to "Equipment OFF".
Superchart supports currently 2 types of granularity:
- Minute granularity - ```1h```, ```6h```, ```1d```;
- Hour granularity - ```1w```, ```1m```, ```3m```;
This means that minimum chart update interval is 1 minute for ```1h```, ```6h```, ```1d``` periods.
1 hour for ```1w```, ```1m``` and ```3m``` periods.
As Blynk Cloud is free to use we have a limit on how many data you can store. At the moment Blynk Cloud accepts
1 message per minute per pin. In case you send your data more frequently your values will be averaged. For example,
in case you send value ```10``` at 12:12:05 and than again ```12``` at 12:12:45 as result in chart you'll see
value ```11``` for 12:12.
In order to see data in chart you need to use either widgets with "Frequency reading" interval (in
that case your app should be open and running) or you can use ```Blynk.virtualWrite``` on hardware side. Every
```Blynk.virtualWrite``` command is stored on server automatically. In that case you don't need application to be up and running.
### Terminal
Displays data from your hardware. Allows to send any string to your hardware. Terminal always stores last 25 messages
your hardware had send to Blynk Cloud. This limit may be increased on Local Server with ```terminal.strings.pool.size```
property.
You need to use special commands with this widget:
```cpp
terminal.print(); // Print values, like Serial.print
terminal.println(); // Print values, like Serial.println()
terminal.write(); // Write a raw data buffer
terminal.flush(); // Ensure that data was sent out of device
terminal.clear(); // Erase all values in the terminal
```
**Sketch:** [Terminal](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Terminal/Terminal.ino)
### Video Streaming
Simple widget that allows you to display any live stream. Widget supports RTSP (RP, SDP), HTTP/S progressive streaming,
HTTP/S live streaming. For more info please follow [official Android documentation](https://developer.android.com/guide/appendix/media-formats.html).
At the moment Blynk doesn't provide streaming servers. So you can either stream directly from camera, use 3-d party
services or host streaming server on own server (on raspberry for example).
You can also change video url from hardware with:
```cpp
Blynk.setProperty(V1, "url", "http://my_new_video_url");
```
### Level Display
Level Display is very similar to progress bar, when you need to visualize a level betwen min/max value
To update Level Display from hardware side with code:
```cpp
Blynk.virtualWrite(V1, val);
```
Every message that hardware sends to server is stored automatically on server. PUSH mode doesn't require
application to be online or opened.
**Sketch:** [Push Example](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/PushData/PushData.ino)
##Notifications
###Twitter
Twitter widget connects your Twitter account to Blynk and allows you to send Tweets from your hardware.
Example code:
```cpp
Blynk.tweet("Hey, Blynkers! My Arduino can tweet now!");
```
Limitations:
- you cant' send 2 tweets with same message (it's Twitter policy)
- only 1 tweet per 5 seconds is allowed
**Sketch:** [Twitter](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Twitter/Twitter.ino)
###Email
Email widget allows you to send email from your hardware to any address.
Example code:
```cpp
Blynk.email("my_email@example.com", "Subject", "Your message goes here");
```
It also contains ```to``` field. With this field you may define receiver of email in the app.
You may skip ```to``` field when you want to send email to your Blynk app login email:
```cpp
Blynk.email("Subject", "Your message goes here");
```
You can send either ```text/html``` or ```text/plain``` (some clients don't support ```text/html```) email.
You can change this content type of email in the Mail widget settings.
Additionally you may use ```{DEVICE_NAME}```, ```{DEVICE_OWNER_EMAIL}``` and ```{VENDOR_EMAIL}``` (for the local server)
placeholders in the mail for the ```to```, ```subject``` and ```body``` fields:
```cpp
Blynk.email("{DEVICE_OWNER_EMAIL}", "{DEVICE_NAME} : Alarm", "Your {DEVICE_NAME} has critical error!");
```
Limitations:
- Maximum allowed email + subject + message length is 120 symbols. However you can increase this limit if necessary
by adding ```#define BLYNK_MAX_SENDBYTES XXX``` to you sketch. Where ```XXX``` is desired max length of your email.
For example for ESP you can set this to 1200 max length ```#define BLYNK_MAX_SENDBYTES 1200```. The
```#define BLYNK_MAX_SENDBYTES 1200``` must be included before any of the Blynk includes.
- Only 1 email per 5 seconds is allowed
- In case you are using gmail on the Local Server you are limited with 500 mails per day (by google). Other providers may have similar
limitations, so please be careful.
- User is limited with 100 messages per day in the Blynk Cloud;
**Sketch:** [Email](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Email/Email.ino)
###Push Notifications
Push Notification widget allows you to send push notification from your hardware to your device. Currently it also
contains 2 additional options:
- **Notify when hardware offline** - you will get push notification in case your hardware went offline.
- **Offline Ignore Period** - defines how long hardware could be offline (after it went offline) before sending notification.
In case period is exceeded - "hardware offline" notification will be send. You will get no notification in case hardware
was reconnected within specified period.
- **Priority** high priority gives more chances that your message will be delivered without any delays.
See detailed explanation [here](https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a-message).
**WARNING**: high priority contributes more to battery drain compared to normal priority messages.
Example code:
```cpp
Blynk.notify("Hey, Blynkers! My hardware can push now!");
```
You can also use placeholder for device name, that will be replaced on the server with your device name:
```cpp
Blynk.notify("Hey, Blynkers! My {DEVICE_NAME} can push now!");
```
Limitations:
- Maximum allowed body length is 120 symbols;
- Every device can send only 1 notification every 5 seconds;
**Sketch:** [PushNotification](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/PushNotification/PushNotification_Button/PushNotification_Button.ino)
###Unicode in notify, email, push, ...
The library handles all strings as UTF8 Unicode. If you're facing problems, try to print your message to the Serial and see if it works (the terminal should be set to UTF-8 encoding). If it doesn't work, probably you should read about unicode support of your compiler.
If it works, but your message is truncated - you need to increase message length limit (all Unicode symbols consume at least twice the size of Latin symbols).
###Increasing message length limit
You can increase maximum message length by putting on the top of your sketch (before Blynk includes):
```cpp
#define BLYNK_MAX_SENDBYTES 256 // Default is 128
```
## Interface
### Tabs
The only purpose of Tabs widget is to extend your project space. You can have up to 4 tabs.
Also you can drag widgets between tabs. Just drag widget on the label of required tab of tabs widget.
### Menu
Menu widget allows you to send command to your hardware based on selection you made on UI. Menu
sends index of element you selected and not label string. Sending index is starts from 1.
It works same way as usual ComboBox element. You can also set Menu items
[from hardware side](/#blynk-main-operations-change-widget-properties).
Example code:
```
switch (param.asInt())
{
case 1: { // Item 1
Serial.println("Item 1 selected");
break;
}
case 2: { // Item 2
Serial.println("Item 2 selected");
break;
}
}
```
**Sketch:** [Menu](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Menu/Menu.ino)
### Time Input
Time input widget allows you to select start/stop time, day of week, timezone, sunrise/sunset formatted values
and send them to your hardware. Supported formats for time now are ```HH:MM``` and ```HH:MM AM/PM```.
Hardware will get selected on UI time as seconds of day (```3600 * hours + 60 * minutes```) for start/stop time.
Time that widget sends to hardware is user local time.
Selected days indexes:
```
Monday - 1
Tuesday - 2
...
Saturday - 6
Sundays - 7
```
You can also change state of widget on UI. See below sketches.
**Sketch:** [Simple Time Input for start time](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/TimeInput/SimpleTimeInput/SimpleTimeInput.ino)
**Sketch:** [Advanced Time Input](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/TimeInput/AdvancedTimeInput/AdvancedTimeInput.ino)
**Sketch:** [Update Time Input State on UI](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/TimeInput/UpdateTimeInputState/UpdateTimeInputState.ino)
### Map
Map widget allows you set points/pins on map from hardware side. This is very useful widget in case you have
multiple devices and you want track their values on map.
You can send a point to map with regular virtual wrtei command:
```cpp
Blynk.virtualWrite(V1, pointIndex, lat, lon, "value");
```
We also created wrapper for you to make suage of map simpler:
You can change button labels from hardware with:
```cpp
WidgetMap myMap(V1);
...
int index = 1;
float lat = 51.5074;
float lon = 0.1278;
myMap.location(index, lat, lon, "value");
```
Using save ```index``` allows you to override existing point value.
**Sketch:** [Basic Sketch](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Map/Map.ino)
### Table
Table widget comes handy when you need to structure similar data within 1 graphical element. It works as a usual table.
You can add a row to the table with:
```
Blynk.virtualWrite(V1, "add", id, "Name", "Value");
```
You can update a row in the table with:
```
Blynk.virtualWrite(V1, "update", id, "UpdatedName", "UpdatedValue");
```
To highlight any item in a table by using it's id in a table:
```
Blynk.virtualWrite(V1, "pick", 0);
```
To select/deselect (make icon green/grey) item in a table by using it's row id in a table:
```
Blynk.virtualWrite(V1, "select", 0);
Blynk.virtualWrite(V1, "deselect", 0);
```
To clear the table at any time with:
```
Blynk.virtualWrite(V1, "clr");
```
You can also handle other actions coming from table. For example, use row as a switch button.
```
BLYNK_WRITE(V1) {
String cmd = param[0].asStr();
if (cmd == "select") {
//row in table was selected.
int rowId = param[1].asInt();
}
if (cmd == "deselect") {
//row in table was deselected.
int rowId = param[1].asInt();
}
if (cmd == "order") {
//rows in table where reodered
int oldRowIndex = param[1].asInt();
int newRowIndex = param[2].asInt();
}
}
```
**Note:** Max number of rows in the table is 100. When you reach the limit, table will work as FIFO (First In First Out) list.
This limit can be changed by configuring ```table.rows.pool.size``` property for Local Server.
**Sketch:** [Simple Table usage](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Table/Table_Simple/Table_Simple.ino)
**Sketch:** [Advanced Table usage](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Table/Table_Advanced/Table_Advanced.ino)
### Device Selector
Device selector is a powerful widget which allows you to update widgets based on one active device. This widget is particlularly helpful when you have a fleet of devices with similar functionality.
Imagine you have 4 devices and every device has a Temperature & Humidity sensor connected to it. To display the data for all 4 devices you would need to add 8 widgets.
With Device Selector, you can use only 2 Widgets which will display Temperature and Humidity based on the active device chosen in Device Selector.
All you have to do is:
1. Add Device Selector Widget to the project
2. Add 2 widgets (for example Value Display Widget) to show Temperature and Humidity
3. In Widgets Settings you will be able assign them to Device Selector (Source or Target section)
4. Exit settings, Run the project.
Now you can change the active device in Device Selector and you will see that Temperature and Humidity values are reflecting the data updates for the device you just picked.
**NOTE:** Webhook Widget will not work with Device Selector (yet).
### Device Tiles
Device tiles is a powerful widget and very similar to the device selector widget, but with UI.
It allows you to display 1 pin per device per tile.
This widget is particularly helpful when you have a fleet of devices with similar functionality. So you can
group similar devices within one layout (template).
## Sensors
### Accelerometer
Accelerometer is kind of [motion sensors](https://developer.android.com/guide/topics/sensors/sensors_motion.html)
that allows you to detect motion of your smartphone.
Useful for monitoring device movement, such as tilt, shake, rotation, or swing.
Conceptually, an acceleration sensor determines the acceleration that is applied to a device by measuring the forces
that are applied to the sensor. Measured in ```m/s^2``` applied to ```x```, ```y```, ```z``` axis.
In order to accept data from it you need to:
```cpp
BLYNK_WRITE(V1) {
//acceleration force applied to axis x
int x = param[0].asFloat();
//acceleration force applied to axis y
int y = param[1].asFloat();
//acceleration force applied to axis y
int z = param[2].asFloat();
}
```
Accelerometer doesn't work in background.
### Barometer/pressure
Barometer/pressure is kind of [environment sensors](https://developer.android.com/guide/topics/sensors/sensors_environment.html)
that allows you to measure the ambient air pressure.
Measured in in ```hPa``` or ```mbar```.
In oder to accept data from it you need to:
```cpp
BLYNK_WRITE(V1) {
//pressure in mbar
int pressure = param[0].asInt();
}
```
Barometer doesn't work in background.
### Gravity
Gravity is kind of [motion sensors](https://developer.android.com/guide/topics/sensors/sensors_motion.html)
that allows you to detect motion of your smartphone.
Useful for monitoring device movement, such as tilt, shake, rotation, or swing.
The gravity sensor provides a three dimensional vector indicating the direction and magnitude of gravity.
Measured in ```m/s^2``` of gravity force applied to ```x```, ```y```, ```z``` axis.
In oder to accept data from it you need to:
```cpp
BLYNK_WRITE(V1) {
//force of gravity applied to axis x
int x = param[0].asFloat();
//force of gravity applied to axis y
int y = param[1].asFloat();
//force of gravity applied to axis y
int z = param[2].asFloat();
}
```
Gravity doesn't work in background.
### Humidity
Humidity is kind of [environment sensors](https://developer.android.com/guide/topics/sensors/sensors_environment.html)
that allows you to measure ambient relative humidity.
Measured in ```%``` - actual relative humidity in percent.
In oder to accept data from it you need to:
```cpp
BLYNK_WRITE(V1) {
// humidity in %
int humidity = param.asInt();
}
```
Humidity doesn't work in background.
### Light
Light is kind of [environment sensors](https://developer.android.com/guide/topics/sensors/sensors_environment.html)
that allows you to measure level of light (measures the ambient light level (illumination) in lx).
In phones it is used to control screen brightness.
In order to accept data from it you need to:
```cpp
BLYNK_WRITE(V1) {
//light value
int lx = param.asInt();
}
```
Light doesn't work in background.
### Proximity
Proximity is kind of [position sensors](https://developer.android.com/guide/topics/sensors/sensors_position.html)
that allows you to determine how close the face of a smartphone is to an object.
Measured in ```cm``` - distance from phone face to object. However most of this sensors returns only FAR / NEAR information.
So return value will be ```0/1```. Where 0/LOW is ```FAR``` and 1/HIGH is ```NEAR```.
In order to accept data from it you need to:
```cpp
BLYNK_WRITE(V1) {
// distance to object
int proximity = param.asInt();
if (proximity) {
//NEAR
} else {
//FAR
}
}
```
Proximity doesn't work in background.
### Temperature
Temperature is kind of [environment sensors](https://developer.android.com/guide/topics/sensors/sensors_environment.html)
that allows you to measure ambient air temperature.
Measured in ```°C``` - celcius.
In order to accept data from it you need to:
```cpp
BLYNK_WRITE(V1) {
// temperature in celcius
int celcius = param.asInt();
}
```
Temperature doesn't work in background.
### GPS Trigger
GPS trigger widget allows easily trigger events when you arrive to or leave from some destination. This widget
will work in background and periodically will check your coordinates. In case your location is within/out required
radius (selected on widget map) widget will send ```HIGH```/```LOW``` command to hardware. For example, let's assume you have
GPS Trigger widget assigned to pin ```V1``` and option ```Trigger When Enter```. In that case when you'll arrive to destination
point widget will trigger ```HIGH``` event.
```cpp
BLYNK_WRITE(V1) {
int state = param.asInt();
if (state) {
//You enter destination
} else {
//You leave destination
}
}
```
More details on how GPS widget works you can read [here](https://developer.android.com/guide/topics/location/strategies.html).
GPS trigger widget works in background.
### GPS Streaming
Useful for monitoring smartphone location data such as latitude, longitude, altitude and speed (speed could be often 0
in case smartphone doesn't support it).
In order to accept data from this widget you need to:
```cpp
BLYNK_WRITE(V1) {
float latitude = param[0].asFloat();
float longitude = param[1].asFloat();
float altitude = param[2].asFloat();
float speed = param[3].asFloat();
}
```
or you can use prepared wrapper ```GpsParam```:
```cpp
BLYNK_WRITE(V1) {
GpsParam gps(param);
// Print 6 decimal places for Lat
Serial.println(gps.getLat(), 7);
Serial.println(gps.getLon(), 7);
Serial.println(gps.getAltitude(), 2);
Serial.println(gps.getSpeed(), 2);
}
```
GPS Streaming works in background.
**Sketch:** [GPS Stream](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/GPS_Stream/GPS_Stream.ino)
## Other
### Bridge
Bridge can be used for Device-to-Device communication (no app. involved). You can send digital/analog/virtual write commands from one device to another, knowing it's auth token.
At the moment Bridge widget is not required on application side (it is mostly used for indication that we have such feature).
**You can use multiple bridges to control multiple devices.**
Bridge widget takes a virtual pin, and turns it into a channel to control another device. It means you can control any virtual, digital or analog pins of the target device.
Be careful not to use pins like ```A0, A1, A2 ...``` when communicating between different device types, as Arduino Core may refer to wrong pins in such cases.
Example code for device A which will send values to device B:
```cpp
WidgetBridge bridge1(V1); //Initiating Bridge Widget on V1 of Device A
...
void setup() {
Blynk.begin(...);
while (Blynk.connect() == false) {
// Wait until Blynk is connected
}
bridge1.digitalWrite(9, HIGH); // will trigger D9 HIGH on Device B. No code on Device B required
bridge1.analogWrite(10, 123);
bridge1.virtualWrite(V1, "hello"); // you need to write code on Device B in order to receive this value. See below
bridge1.virtualWrite(V2, "value1", "value2", "value3");
}
BLYNK_CONNECTED() {
bridge1.setAuthToken("OtherAuthToken"); // Token of the hardware B
}
```
**IMPORTANT:** when performing ```virtualWrite()``` with Bridge Widget, Device B would need to process the incoming data from Device A.
For example, if you are sending value from Device A to Device B using ```bridge.virtualWrite(V5)``` you would need to use this handler on Device B:
```cpp
BLYNK_WRITE(V5){
int pinData = param.asInt(); //pinData variable will store value that came via Bridge
}
```
Keep in mind that ```bridge.virtualWrite``` doesn't send any value to mobile app. You need to call ```Blynk.virtualWrite``` for that.
**Sketch:** [Bridge](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Bridge/Bridge.ino)
### Eventor
Eventor widget allows you to create simple behaviour rules or **events**.
Let's look at a typical use case: read temperature from DHT sensor and send push notification when the temperature is over a certain limit:
```cpp
float t = dht.readTemperature();
if (isnan(t)) {
return;
}
if (t > 40) {
Blynk.notify(String("Temperature is too high: ") + t);
}
```
With Eventor you don't need to write this code. All you need is to send the value from the sensor to the server:
```cpp
float t = dht.readTemperature();
Blynk.virtualWrite(V0, t);
```
Don't forget that ```virtualWrite``` commands should be wrapped in the timer and can't be used in the main loop.
Now configure new **Event** in Eventor widget:
**NOTE** Don't forget to add notification widget.
Eventor comes handy when you need to change conditions on the fly without re-uploading new sketch on
the hardware. You can create as many **events** as you need.
Eventor also could be triggered from the application side.
You just need to assign the widget to the same pin as your Event within Eventor.
Eventor doesn't constantly sends events. Let's consider simple event as above ```if (temperature > 40) send notification ```.
When temperature goes beyond 40 threshold - notification action is triggered. If temperature continues to stay above the
40 threshold no actions will be triggered. But if ```temperature``` goes below threshold and then passes it again -
notification will be sent again (there is no 5 sec limit on Eventor notifications).
Eventor also supports Timer events. For example, you can set a pin ```V1``` ON/HIGH at 21:00:00 every Friday.
With Eventor Time Event you can assign multiple timers on same pin, send any string/number, select days and timezone.
In order to remove created **event** please use swipe. You can also swipe out last element in the Event itself.
**NOTE:** The timer widget rely on the server time and not your phone time. Sometimes the phone time may not match the server time.
**NOTE:** Events are triggered only once when the condition is met. That's mean
[chaining of events](https://community.blynk.cc/t/eventor-behavior-bug-feature/20962) is not possible (however, could be enabled for commercials).
**Sketch:** [Eventor](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Eventor/Eventor.ino)
**NOTE:**: Events are triggered only once when the condition is met.
Exception:
Let's consider simple event as above ```if (temperature > 40) send notification ```.
When temperature goes beyond 40 threshold - notification action is triggered. If temperature continues to stay above the 40 threshold no actions will be triggered. But if ```temperature``` goes below threshold and then passes it again -
notification will be sent again (there is no 5 sec limit on Eventor notifications).
### RTC
Real-time clock allows you to get time from server. You can preselect any timezone on UI to get time on hardware in required locale.
No pin required for RTC widget.
**Sketch:** [RTC](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/RTC/RTC.ino)
### BLE
Widget to enable Bluetooth Low Energy support. At the moment BLE widget requires
internet connection in order to login and load your profile. However this will be fixed soon. Also some Blynk
widgets are not supported within the BLE connection.
Blynk currently supports a handful of different BLE modules. Please check sketches below.
**Sketches:** [BLE](https://github.com/blynkkk/blynk-library/tree/master/examples/Boards_Bluetooth)
### Bluetooth
Widget to enable Bluetooth support. At the moment Bluetooth widget is supported only on Android and requires
internet connection to login and to load your profile. This will be fixed soon. Alsom some Blynk
widgets do not work within the Bluetooth connection.
Blynk currently supports bunch of different modules. Please check sketches below.
**Sketches:** [Bluetooth](https://github.com/blynkkk/blynk-library/tree/master/examples/Boards_Bluetooth)
### Music Player
Simple UI element with 3 buttons with common music player controls. Every button sends it's own command to hardware:
```play```, ```stop```, ```prev```, ```next```.
You can change widget state within the app from hardware side with next commands:
```
Blynk.virtualWrite(Vx, “play”);
Blynk.virtualWrite(Vx, “stop”);
```
You can also change widget play/stop state with next code (equivalent to above commands):
```Blynk.setProperty(V1, "isOnPlay", "false");```
**Sketch:** [Music Player](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/Player/Player.ino)
### Webhook
Webhook is a widget designed to communicate with 3rd party services. With Webhook widget you can send HTTP(S) requests to any 3rd party service or device that has HTTP(S) API (e.g. Philips Hue bulb). You can trigger 3-d party service with a single click of a button.
Any `write` operation from hardware side will trigger Webhook Widget. You can also trigger webhook from Blynk app when a app widget is assigned to the same pin as Webhook.
For example, when you need to send data from your hardware not only to Blynk, but also to Thingspeak, you would need to write a long http request code like this (this is just an example, not a full sketch):
```
WiFiClient client;
if (client.connect("api.thingspeak.com", 80)) {
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: " + apiKeyThingspeak1 + "\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);
}
```
Instead, with Webhook widget you would only need to fill in these fields:
And add this code on hardware side:
```
Blynk.virtualWrite(V0, value);
```
where `V0` is pin assigned to the Webhook widget.
Use standard Blynk placeholders for Pin Value in the body or URL, for example:
```
https://api.thingspeak.com/update?api_key=xxxxxx&field1=/pin/
```
or for the body
```
["/pin/"]
```
When you need to send an array of values, you can refer to a specific index of the array value. Blynk Pin can hold an array of max 10 values:
```/pin[0]/```,```/pin[1]/```, ```/pin[2]/```
You can also make GET requests from Blynk Server and get responses directly to your hardware.
For example, to get current weather from a 3rd party Weather service that uses an URL similar to this:
```http://api.sunrise-sunset.org/json?lat=33.3823&lng=35.1856&date=2016-10-01```, you would need to put this URL in Webhook widget and assign it to ```V0``` pin.
To parse the response on the hardware side:
```
BLYNK_WRITE(V0){
String webhookdata = param.asStr();
Serial.println(webhookdata);
}
```
Now, every time there is a "write" command to ```V0``` pin (e.g. with ```Blynk.virtualWrite(V0, 1)``` from hardware or from app widget assigned to ```V0```), ```BLYNK_WRITE(V0)``` construction will be triggered and processed.
**NOTE:** Usually, 3rd party servers return long responses. You have to increase the maximum allowed message size your hardware can process. Modify this line in your firmware code:
```#define BLYNK_MAX_READBYTES 1024```. Where ```1024``` - is maximum allowed message size.
**NOTE:** Blynk Cloud has limitation for Webhook Widget - you can only send 1 request per second. This can be
changed on a Local Server by changing ```webhooks.frequency.user.quota.limit```. Be careful with Webhooks,
as many 3rd party services can't handle 1 req/sec, and you can be banned on some of them.
For example, Thingspeak allows only 1 request per 15 seconds.
**NOTE:** To avoid spamming, Blynk Webhook feature has another limitation - if your Webhook requests fail 10 times in a row, Webhook Widget will be stopped. To resume it, you would need to open Widget Settings and re-save it. Failed request is a request that doesn't return `200` or `302`.
**NOTE:** Webhook widget may affect ```Blynk.syncAll()``` function when a returned response is large.
### Reports Widget
Function of Reports is to configure and customize data reports in CSV format. You can choose between one-time or continuous scheduled reports.
Also, within the Reports you can clear all the data collected by your devices.
You need to configure initial inputs in Edit mode, and then, in Play mode you will be able to customize reports.
#### Edit mode. Data inputs configuration
In edit mode (when your project is stopped) you define the Datastreams you would like to later be included in reports.
Reports widget is designed to work with the Device Tiles widget. If you don't use Device Tiles you can still select a single device or a group of devices as a source of data for reports.
You have to choose either Device Tiles or single / group of the devices for the report. You can't combine these 2 options.
#### Play mode.
After you added source devices and their Datastreams click Play button and click on the Reports button.
### Customizing Reports.
Every Report option supposes it's own settings:
```Report name``` - give your report a meaningful name.
```Data source``` - select the Datastreams you would like to be included in reports.
```Report Frequency``` - Defines how often reports will be sent. They can be one-time and scheduled.
```one-time``` - will instantly generate report and send it to the email addresses specified. Click on the right icon to send it.
Scheduled reports can be sent ```daily```/```weekly```/```monthly```.
```At Time``` will set up a time of the day the report will be sent.
```Start```/```End``` specifies start and end date the reports will continue to be sent.
For Weekly Report you can select a day of the week when report should be sent.
For Monthly report you can choose whether to send report on the first or last day of the month.
```Recipients``` - specify up to 5 email addresses.
```Data resolution``` defines granularity of your reports. Supported granularities are: ```minute```, ```hourly``` and ```daily```.
For example, when you generate daily report with 1 minute granularity you'll get ```24 * 60 * 60```
points in your daily report for every selected Datastream.
```Group data in reports by``` - specify the output format of the CSV file(s).
```Datastream``` you will get 1 CSV file for each Datastream.
```Device``` you will get 1 CSV file per each device. Each file will contain all of the included Datastreams.
```Report``` you will get 1 CSV file for all your devices and all your Datastreams.
```Timezone correction``` - specify the time zone adjustment if you need to get report date and time adjusted to a specific time zone
```Date and time format``` - defines the format of the timestamp field of your data. You can select ```2018-06-21 20:16:48```,
```2018-06-21T20:16:48+03:00``` or other supported formats.
There is one specific ```Timestamp``` format - which reflects the difference between the current time and midnight, January 1, 1970 UTC measured in milliseconds.
After the report is set up - click on "OK" button at the right upper corner. Your report is ready.
Once you configured the report you will see when is the ```Next``` report scheduled and also a schedule for this report.
After the report was sent at least once, you can see when the ```Last``` report was sent.
```Last``` label also contains the status regarding the report:
- ```OK```: the report was generated and sent to the Recipients successfully;
- ```No Data```: the report doesn't contain any data for the configured period;
- ```Error```: something went wrong. Please contact the Blynk Team support;
Reports will be generated even if your project is not in active (Play) mode. However, inactive projects don't generate any data.
**NOTE:** all reports are encoded in UTF-16. Please, make sure you selected UTF-16 as required "Character set" for your csv reader.
================================================
FILE: amendments.md
================================================
# Blynk Amendments
## Tell every maker about Blynk
No pressure. Just do it. Now.
## Make your idea work without Blynk
Blynk can be easily integrated in almost any project. But before that - make it work **without** it. After you are sure that you can get all the sensor data or can control things from the code – integrate Blynk and make it even more awesome.
## Use search
We are always happy to chat and help, but remember - every time you ask the question that was answered many many times before that, Blynk Team is not building a new widget or new cool feature. So:
* google before asking
* use search on our forum, it works really well
* check Instructables
**Always wrap your code**
Though shalt not post code without `wrapping it`
================================================
FILE: api/README.md
================================================
# HTTPs API
================================================
FILE: api/api_getlastweekdata.md
================================================
# Download Datastream Data
To get the device data for last week, use this API call:
**API call:**
```text
api/external/getRawData?token=123&days=7, (from: now - 7 days, to: now)
```
**Response example:**
```text
response example
```
================================================
FILE: api/events-api.md
================================================
# Events API
To trigger [Events](../product/events/) creation from hardware \(or other sources\) and render them on Timeline in Device profile pages on the web and in the mobile apps, use this API call:
```text
/external/api/logEvent?token={token}&code={event_name}
```
`event_name` should be taken from [Product Template Settings](../product/product-template-settings.md) > [Events](../product/events/)
\*\*\*\*
**Options:**
To render custom description of the event on the Timeline, use `event_description` parameter
`/external/api/logEvent?token={token}&code={event_name}&description={event_desciption}`
>>IMAGE OF TIMELINE WITH EVENT DESCRIPTION \(MOBILE AND WEB\)
================================================
FILE: api/external_api.md
================================================
# Datastreams API
## Hardware
Get datastream value \(via HTTP GET\):
* `/external/api/get?token={token}&pin={pin}`
* `/external/api/get?token={token}&dataStreamId={id}`
Update datastream value \(via HTTP GET\):
* `/external/api/update?token={token}&pin={pin}&value={value}`
* `/external/api/update?token={token}&dataStreamId={id}&value={value}`
* `/external/api/update/property?token={token}&pin={pin}&{property}={value}`
## Log event
* `/external/api/logEvent?token={token}&code={event_name}`
* `/external/api/logEvent?token={token}&code={event_name}&description={event_desciption}`
================================================
FILE: appexport.md
================================================
# App Export
## Firmware for ESP8266, NodeMCU, BlynkBoard, etc.
### Prepare development environment
1. Install [Arduino IDE](https://www.arduino.cc/en/Main/Software)
2. Install [Blynk Library](https://github.com/blynkkk/blynk-library/releases/latest) and restart Arduino IDE
3. Install [ESP8266 core for Arduino](https://github.com/esp8266/Arduino#installing-with-boards-manager)
4. For Windows / OS X, you may need to install USB-Serial drivers according to your converter:
* СP2102: [https://www.silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx](https://www.silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx)
* FTDI \(FT232, etc\): [http://www.ftdichip.com/Drivers/VCP.htm](http://www.ftdichip.com/Drivers/VCP.htm)
* _TODO: Link to drivers for CH340 and PL2303._
5. If your board has a NeoPixel RGB LED, install [Adafruit NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel) library from Library Manager
### Build your Firmware
1. Open our example in Arduino IDE: `File -> Examples -> Blynk -> Provisioning -> Blynk_ESP8266`
2. Open `Settings.h` tab.
3. Configure your firmware:
* `BOARD_NAME` - ...
* `BOARD_VENDOR` - ...
* `PRODUCT_WIFI_SSID` - ...
### Upload firmare
1. Select your board type: `Tools -> Board -> [Your Board]`
2. Select your port: `Tools -> Port -> [...]`
3. Verify and Upload!
Note that for Blynk Board, you can select board type `NodeMCU 1.0`.
================================================
FILE: blynkfirmware.md
================================================
# Blynk Firmware
## Configuration
### Blynk.begin\(\)
The easiest way to configure Blynk is to use `Blynk.begin()`:
```cpp
Blynk.begin(auth, ...);
```
It has multiple parameters for different hardware models and it also depends on the type of connection. Follow the example sketches for your specific hardware model.
What happens inside of `Blynk.begin()` function:
1. Connection to the network \(WiFi, Ethernet, ...\)
2. Call of `Blynk.config(...)` to set Auth Token, Server Address, etc.
3. Attempts to connect to the server once \(can block for more than 30s\)
If your shield/connection type is not supported yet - you can implement it by yourself. [Here are some examples](https://github.com/blynkkk/blynk-library/tree/master/examples/More/ArduinoClient).
### Blynk.config\(\)
`config()` allows you to manage network connection. You can set up your connection type \(WiFi, Ethernet, ...\) by yourself, and then call:
```cpp
Blynk.config(auth, server, port);
```
or just
```cpp
Blynk.config(auth);
```
**NOTE: After `Blynk.config(...)` is called, your hardware is not yet connected to the server.** It will try to connect while until it hits first instance of `Blynk.run()` or `Blynk.connect()`routine.
To skip connecting to the server or to disconnect manually, call `Blynk.disconnect()` after configuration.
Use `connectWiFi` to conveniently set up WiFi connection:
```cpp
Blynk.connectWiFi(ssid, pass);
```
To connect to open WiFi networks, set pass to an empty string \(`""`\).
## Connection management
There are several functions to help with connection management:
### Blynk.connect\(\)
This functions will continue trying to connect to Blynk server. Returns `true` when connected, `false` if timeout have been reached. Default timeout is 30 seconds.
```cpp
bool result = Blynk.connect();
bool result = Blynk.connect(timeout);
```
### Blynk.disconnect\(\)
Disconnects hardware from Blynk server:
```cpp
Blynk.disconnect();
```
### Blynk.connected\(\)
Returns `true` when hardware is connected to Blynk Server, `false` if there is no active connection to Blynk server.
```cpp
bool result = Blynk.connected();
```
### Blynk.run\(\)
This function should be called frequently to process incoming commands and perform housekeeping of Blynk connection. It is usually called in `void loop() {}`.
This command can be initiated it in other places of your code unless you run out of heap memory \(in the cascaded functions with local memory\).
For example, it is not recommended to call `Blynk.run()` inside of the `BLYNK_READ` and `BLYNK_WRITE` functions on low-RAM devices.
## Digital & Analog pins control
Blynk library can perform basic pin IO \(input-output\) operations out-of-the-box:
```text
digitalRead
digitalWrite
analogRead
analogWrite (PWM or Analog signal depending on the platform)
```
No need to write code for simple things like LED, Relay control and analog sensors. Just choose a corresponding Pin in Blynk app and control it directly with no additional code
## Virtual pins control
Virtual Pins is a way to exchange any data between your hardware and Blynk app. Think about Virtual Pins as channels for sending any data. Make sure you differentiate Virtual Pins from physical GPIO pins on your hardware. Virtual Pins have no physical representation.
Virtual Pins are commonly used to interface with other libraries \(Servo, LCD and others\) and implement custom logic. The device can send data to the App using `Blynk.virtualWrite(pin, value)` and receive data from the App using `BLYNK_WRITE(vPIN)`. Read below
#### Virtual Pin data types
All Virtual Pin values are always sent as Strings and there are no practical limits on the data that can be sent.
However, there are certian limitations on the hardware side when dealing with numbers. For example, the integer on Arduino is 16-bit, allowing range -32768 to 32767.
To interpret incoming data as Integers, Floats, Doubles and Strings use:
```cpp
param.asInt();
param.asFloat();
param.asDouble();
param.asStr();
```
You can also get the RAW data from the param buffer:
```cpp
param.getBuffer()
param.getLength()
```
### Blynk.virtualWrite\(vPin, value\)
**NOTE: Use BlynkTimer when you use this command to send data. Otherwise your hardware will be disconnected from the server**
Send data in various formats to Virtual Pins.
```cpp
// Send string
Blynk.virtualWrite(pin, "abc");
// Send integer
Blynk.virtualWrite(pin, 123);
// Send float
Blynk.virtualWrite(pin, 12.34);
// Send multiple values as an array
Blynk.virtualWrite(pin, "hello", 123, 12.34);
// Send RAW data
Blynk.virtualWriteBinary(pin, buffer, length);
```
Calling `virtualWrite` attempts to send the value to the network immediately.
**Note:** For virtual pins with numbers > 127, the `V128` syntax is not available.
Please use plain virtual pin number, for example:
```cpp
Blynk.virtualWrite(128, "abc");
```
## BlynkTimer
It's important to send data in intervals and keep the void loop\(\) as clean as possible.
`BlynkTimer` allows you to send data periodically with given intervals not interfering with Blynk library routines `Blynk Timer` inherits [SimpleTimer Library](http://playground.arduino.cc/Code/SimpleTimer), a well known and widely used library to time multiple events on hardware. `BlynkTimer` is included in Blynk library by default and there is no need to install SimpleTimer separately or include `SimpleTimer.h`
* A single `BlynkTimer` object allows to schedule up to 16 timers
* Improved compatibility with boards like `Arduino 101`, `Intel Galileo`, etc.
* When a timer struggles to run multiple times \(due to a blocked `loop`\), it just skips all the missed intervals, and calls your function only once. This differs from `SimpleTimer`, which could call your function multiple times in this scenario.
For more information on timer usage, please see: [http://playground.arduino.cc/Code/SimpleTimer](http://playground.arduino.cc/Code/SimpleTimer)
And here is a BlynkTimer [example sketch](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/PushData/PushData.ino#L30).
Please also remember that a single `BlynkTimer` can schedule many timers, so most probably you need only one instance of BlynkTimer in your sketch.
### BLYNK\_WRITE\(vPIN\)
`BLYNK_WRITE` is a function called every time device gets an update of Virtual Pin value from the server \(or app\):
To read the received data use:
```cpp
BLYNK_WRITE(V0)
{
int value = param.asInt(); // Get value as integer
// The param can contain multiple values, in such case:
int x = param[0].asInt();
int y = param[1].asInt();
}
```
**`BLYNK_WRITE` can't be used inside of any loop or function. It's a standalone function.**
**Note:** For virtual pins with numbers > 127, please use `BLYNK_WRITE_DEFAULT()` API
### BLYNK\_READ\(vPIN\)
`BLYNK_READ` is function called when device is requested to send it's current value of Virtual Pin to the server. Normally, this function should contain `Blynk.virtualWrite` call\(s\).
```cpp
BLYNK_READ(V0)
{
Blynk.virtualWrite(V0, newValue);
}
```
**Note:** For virtual pins with numbers > 127, please use `BLYNK_READ_DEFAULT()` API
### BLYNK\_WRITE\_DEFAULT\(\)
Redefines the handler for all pins that are not covered by custom `BLYNK_WRITE` functions.
```cpp
BLYNK_WRITE_DEFAULT()
{
int pin = request.pin; // Which exactly pin is handled?
int value = param.asInt(); // Use param as usual.
}
```
### BLYNK\_READ\_DEFAULT\(\)
Redefines the handler for all pins that are not covered by custom `BLYNK_READ` functions.
```cpp
BLYNK_READ_DEFAULT()
{
int pin = request.pin; // Which exactly pin is handled?
Blynk.virtualWrite(pin, newValue);
}
```
### BLYNK\_CONNECTED\(\)
Use this function when you need to run certain routine when hardware connects to Blynk Cloud or private server. It's common to call sync functions inside of this function.
```cpp
BLYNK_CONNECTED() {
// Your code here
}
```
### BLYNK\_APP\_CONNECTED\(\)
This function is called every time Blynk app client connects to Blynk server.
```cpp
BLYNK_APP_CONNECTED() {
// Your code goes here
}
```
**Note: Ennable this feature in Project Settings first:**

[Example](https://github.com/blynkkk/blynk-library/blob/master/examples/More/AppConnectedEvents/AppConnectedEvents.ino)
### BLYNK\_APP\_DISCONNECTED\(\)
This function is called every time the Blynk app disconnects from Blynk Cloud or private server.
```cpp
BLYNK_APP_DISCONNECTED() {
// Your code here
}
```
**Note: Enable this feature in Project Settings first:**

[Example](https://github.com/blynkkk/blynk-library/blob/master/examples/More/AppConnectedEvents/AppConnectedEvents.ino)
### Blynk.syncAll\(\)
Requests all stored on the server latest values for all widgets. All analog/digital/virtual pin values and states will be set to the latest stored value. Every virtual pin will generate BLYNK\_WRITE\(\) event.
```cpp
BLYNK_CONNECTED() {
Blynk.syncAll();
}
```
### Blynk.syncVirtual\(vPin\)
This command updates individual Virtual Pin to the latest stored value on the server. When it's used, a corresponding `BLYNK_WRITE` handler is called.
```cpp
Blynk.syncVirtual(V0);
```
To update multiple pins, use:
```text
Blynk.syncVirtual(V0, V1, V6, V9, V16);
```
### Blynk.setProperty\(vPin, "property", value\)
This command allows [changing widget properties](blynkfirmware.md#blynk-main-operations-change-widget-properties)
## Debugging
### \#define BLYNK\_PRINT
### \#define BLYNK\_DEBUG
To enable debug prints on the default Serial port add on the top of your sketch **IMPORTANT: This should be the first line in your code**:
```cpp
#define BLYNK_PRINT Serial // Defines the object that is used for printing
#define BLYNK_DEBUG // Optional, this enables more detailed prints
```
Then enable Serial Output in setup\(\):
```cpp
Serial.begin(9600);
```
Open Serial Monitor and you'll see the debug prints.
You can also use spare Hardware serial ports or SoftwareSerial for debug output \(you will need an adapter to connect to it with your PC\).
**WARNING:** Enabling `BLYNK_DEBUG` will slowdown your hardware processing speed up to 10 times!
### BLYNK\_LOG\(\)
When `BLYNK_PRINT` is defined, you can use `BLYNK_LOG` to print your logs. The usage is similar to `printf`:
```cpp
BLYNK_LOG("This is my value: %d", 10);
```
On some platforms \(like Arduino 101\) the `BLYNK_LOG` may be unavailable, or may just use too much resources.
In this case you can use a set of simpler log functions:
```cpp
BLYNK_LOG1("Hello World"); // Print a string
BLYNK_LOG1(10); // Print a number
BLYNK_LOG2("This is my value: ", 10); // Print 2 values
BLYNK_LOG4("Temperature: ", 24, " Humidity: ", 55); // Print 4 values
...
```
## Minimizing footprint
To minimize the program Flash/RAM, you can disable some of the built-in functionality:
1. Comment-out `#define BLYNK_PRINT` to remove prints
2. Put on the top of your sketch:
```text
#define BLYNK_NO_BUILTIN // Disable built-in analog & digital pin operations
#define BLYNK_NO_FLOAT // Disable float operations
```
## Porting, hacking
If you want to dive into crafting/hacking/porting Blynk library implementation, please also check [this documentation](https://github.com/blynkkk/blynk-library/tree/master/extras/docs).
================================================
FILE: blynkmainoperations.md
================================================
# Blynk main operations
## Virtual Pins
Blynk can control Digital and Analog I/O Pins on you hardware directly. You don't even need to write code for it. It's great for blinking LEDs, but often it's just not enough...
We designed Virtual Pins to send **any** data from your microcontroller to the Blynk App and back.
Anything you connect to your hardware will be able to talk to Blynk. With Virtual Pins you can send something from the App, process it on microcontroller and then send it back to the smartphone. You can trigger functions, read I2C devices, convert values, control servo and DC motors etc.
Virtual Pins can be used to interface with external libraries \(Servo, LCD and others\) and implement custom functionality.
Hardware may send data to the Widgets over the Virtual Pin like this:
```cpp
Blynk.virtualWrite(pin, "abc");
Blynk.virtualWrite(pin, 123);
Blynk.virtualWrite(pin, 12.34);
Blynk.virtualWrite(pin, "hello", 123, 12.34);
```
For more information about virtual pins, [read this](./#blynk-firmware-virtual-pins-control)
## Send data from app to hardware
You can send any data from Widgets in the app to your hardware.
All [Controller Widgets](./#widgets-controllers) can send data to Virtual Pins on your hardware. For example, code below shows how to get values from the Button Widget in the App
```cpp
BLYNK_WRITE(V1) //Button Widget is writing to pin V1
{
int pinData = param.asInt();
}
```
When you press a Button, Blynk App sends `1` On the second click - it sends `0`
This is how Button Widget is set up:

Full example sketch: [Get Data](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/GetData/GetData.ino#L24)
### Sending array from Widget
Some Widgets \(e.g Joystick, zeRGBa\) have more than one output.

This output can be written to Virtual Pin as an array of values. On the hardware side - you can get any element of the array \[0,1,2...\] by using:
```cpp
BLYNK_WRITE(V1) // Widget WRITEs to Virtual Pin V1
{
int x = param[0].asInt(); // getting first value
int y = param[1].asInt(); // getting second value
int z = param[N].asInt(); // getting N value
}
```
**Sketch:** [JoystickTwoAxis](https://github.com/blynkkk/blynk-library/blob/master/examples/Widgets/JoystickTwoAxis/JoystickTwoAxis.ino#L24)
## Get data from hardware
There are two ways of pushing data from your hardware to the Widgets in the app over Virtual Pins.
### Perform requests by Widget
* Using Blynk built-in reading frequency while App is active by setting 'Reading Frequency' parameter to some interval:

```cpp
BLYNK_READ(V5) // Widget in the app READs Virtal Pin V5 with the certain frequency
{
// This command writes Arduino's uptime in seconds to Virtual Pin V5
Blynk.virtualWrite(5, millis() / 1000);
}
```
**Sketch:** [PushDataOnRequest](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/PushDataOnRequest/PushDataOnRequest.ino#L26)
### Pushing data from hardware
If you need to PUSH sensor or other data from your hardware to Widget, you can write any logic you want. Just set the frequency to PUSH mode. Any command that hardware sends to Blynk Cloud is automatically stored on server and you get this info either with [History Graph](./#widgets-displays-superchart) widget or with [HTTP API](http://docs.blynkapi.apiary.io/#reference/0/pin-history-data/get-all-history-data-for-specific-pin).

We recommend sending data in intervals and avoiding [Flood Error](https://docs.blynk.cc/#troubleshooting-flood-error). You can use timers like [BlynkTimer](./#blynk-firmware-blynktimer). Please read instructions inside this [example sketch](https://github.com/blynkkk/blynk-library/blob/master/examples/GettingStarted/PushData/PushData.ino) for more details.
Here is how it can work:
```cpp
#include Known Issues
<code> elements with newlines in the text
which use CSS to specify white-space:pre will have the newlines
improperly stripped if the element is not attached to the document at the time
the stripping is done. Also, on IE 6, all newlines will be stripped from
<code> elements because of the way IE6 produces
innerHTML. Workaround: use <pre> for code with
newlines.
Change Log
29 March 2007
prettyPrintOne was not halting. This was not
reachable through the normal entry point.
is no longer applicable.
4 Jul 2008
lang-<language-file-extension>'''string'''
/ in regex [charsets] should not end regex
5 Jul 2008
14 Jul 2008
nocode spans to allow embedding of line
numbers and code annotations which should not be styled or otherwise
affect the tokenization of prettified code.
See the issue 22
testcase.
6 Jan 2009
21 May 2009
14 August 2009
<code> blocks with embedded newlines.
3 October 2009
19 July 2010
  instead of
so that the output works when embedded in XML.
Bug
108.7 September 2010
4 March 2011
29 March 2011
prettyPrintOne injects the HTML
passed to it into a <pre> element.
If the HTML comes from a trusted source, this may allow XSS.
Do not do this. This should not be a problem for existing apps
since the standard usage is to rewrite the HTML and then inject
it, so anyone doing that with untrusted HTML already has an XSS
vulnerability. If you sanitize and prettify HTML from an
untrusted source, sanitize first.
4 February 2013
24 February 2013
4 March 2013
================================================
FILE: google-code-prettify/COPYING
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2011 Mike Samuel et al
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: google-code-prettify/Makefile
================================================
SHELL := /bin/bash
CLOSURE_COMPILER=java -jar tools/closure-compiler/compiler.jar \
--warning_level VERBOSE \
--language_in ECMASCRIPT5 \
--compilation_level ADVANCED_OPTIMIZATIONS \
--charset US-ASCII
# Don't specify --charset=UTF-8. If we do, then non-ascii codepoints
# that do not correspond to line terminators are converted
# to UTF-8 sequences instead of being emitted as ASCII.
# This makes the resulting JavaScript less portable.
YUI_COMPRESSOR=java -jar tools/yui-compressor/yuicompressor-2.4.4.jar \
--charset UTF-8
TAR_ROOT=distrib/google-code-prettify
all: distrib
clean:
rm -rf distrib.tstamp distrib src/prettify.js src/run_prettify.js
src/prettify.js: js-modules/*.js js-modules/*.pl
@if [ -e "$@" ]; then chmod +w "$@"; fi
@perl js-modules/js_include.pl "$$(basename $@)" > "$@"
@if [ -e "$@" ]; then chmod -w "$@"; fi
src/run_prettify.js: js-modules/*.js js-modules/*.pl
@if [ -e "$@" ]; then chmod +w "$@"; fi
@perl js-modules/js_include.pl "$$(basename $@)" > "$@"
@if [ -e "$@" ]; then chmod -w "$@"; fi
distrib: distrib.tstamp distrib/prettify-small.tgz distrib/prettify-small.zip distrib/prettify-small.tar.bz2
@wc -c distrib/prettify-small.{tar.bz2,tgz,zip} \
| grep -v total
distrib.tstamp: src/prettify.js src/run_prettify.js src/*.js src/*.css
@echo Compiling
@mkdir -p $(TAR_ROOT)
@for f in src/*.css; do \
$(YUI_COMPRESSOR) --type css $$f \
> $(TAR_ROOT)/$$(basename $$f); \
wc -c $$f $(TAR_ROOT)/$$(basename $$f) \
| grep -v total; \
done
@$(CLOSURE_COMPILER) --js src/prettify.js \
--externs tools/closure-compiler/console-externs.js \
--externs tools/closure-compiler/amd-externs.js \
--define IN_GLOBAL_SCOPE=true \
--output_wrapper='!function(){%output%}()' \
> $(TAR_ROOT)/prettify.js
@wc -c src/prettify.js $(TAR_ROOT)/prettify.js \
| grep -v total
@$(CLOSURE_COMPILER) --js src/run_prettify.js \
--externs tools/closure-compiler/console-externs.js \
--externs tools/closure-compiler/amd-externs.js \
--define IN_GLOBAL_SCOPE=false \
--output_wrapper='!function(){%output%}()' \
> $(TAR_ROOT)/run_prettify.js
@wc -c src/run_prettify.js $(TAR_ROOT)/run_prettify.js \
| grep -v total
@for f in src/lang*.js; do \
if [ $$f -nt $(TAR_ROOT)/$$(basename $$f) ]; then \
$(CLOSURE_COMPILER) --js $$f --externs js-modules/externs.js \
| perl -pe 's/\bPR\.PR_ATTRIB_NAME\b/"atn"/g; \
s/\bPR\.PR_ATTRIB_VALUE\b/"atv"/g; \
s/\bPR\.PR_COMMENT\b/"com"/g; \
s/\bPR\.PR_DECLARATION\b/"dec"/g; \
s/\bPR\.PR_KEYWORD\b/"kwd"/g; \
s/\bPR\.PR_LITERAL\b/"lit"/g; \
s/\bPR\.PR_PLAIN\b/"pln"/g; \
s/\bPR\.PR_PUNCTUATION\b/"pun"/g; \
s/\bPR\.PR_STRING\b/"str"/g; \
s/\bPR\.PR_TAG\b/"tag"/g; \
s/\bPR\.PR_TYPE\b/"typ"/g;' \
> $(TAR_ROOT)/$$(basename $$f); \
wc -c $$f $(TAR_ROOT)/$$(basename $$f) \
| grep -v total; \
fi \
done
@touch distrib.tstamp
lang-aliases : lang-aliases.tstamp
lang-aliases.tstamp : distrib.tstamp
@tools/lang-handler-aliases.sh \
distrib/sources/google-code-prettify/src \
| perl -ne 'system("cp $$1 $$2") if m/^(\S+) (\S+)$$/ && ! -e $$2' \
&& touch lang-aliases.tstamp
%.tgz: %.tar
@gzip -c -9 $^ > $@
%.tar.bz2: %.tar
@bzip2 -k -9f $^
distrib/prettify-small.tar: distrib.tstamp
tar cf $@ -C distrib google-code-prettify
distrib/prettify-small.zip: distrib.tstamp
@pushd distrib >& /dev/null; \
rm -f ../$@; \
zip -q -9 -r ../$@ google-code-prettify; \
popd >& /dev/null
distrib/prettify.tar: distrib.tstamp
mkdir -p distrib/sources/google-code-prettify
cp -fr CHANGES.html COPYING README.html Makefile \
examples js-modules src styles tests tools \
distrib/sources/google-code-prettify
tar cf distrib/prettify.tar -C distrib/sources google-code-prettify
================================================
FILE: google-code-prettify/README.html
================================================
Javascript code prettifier
Setup
>script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js></script>
Usage
The original
Prettier
class Voila {
public:
// Voila
static const string VOILA = "Voila";
// will not interfere with embedded tags.
}
class Voila {
public:
// Voila
static const string VOILA = "Voila";
// will not interfere with embedded tags.
}
FAQ
For which languages does it work?
How do I specify the language of my code?
prettyprint()
will guess. You can specify a language by specifying the language extension
along with the prettyprint class like so:<pre class="prettyprint lang-html">
The lang-* class specifies the language file extensions.
File extensions supported by default include
"bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html",
"java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh",
"xhtml", "xml", "xsl".
</pre>
PRE and using language-java style classes.
E.g. ...It doesn't work on <obfuscated code sample>?
Which browsers does it work with?
What's changed?
Why doesn't Prettyprinting of strings work on WordPress?
How do I put line numbers in my code?
linenums class to turn on line
numbering. If your code doesn't start at line number 1, you can
add a colon and a line number to the end of that class as in
linenums:52.
<pre class="prettyprint linenums:4"
>// This is line 4.
foo();
bar();
baz();
boo();
far();
faz();
<pre>
produces
// This is line 4.
foo();
bar();
baz();
boo();
far();
faz();
How do I prevent a portion of markup from being marked as code?
nocode class to identify a span of markup
that is not code.
<pre class=prettyprint>
int x = foo(); /* This is a comment <span class="nocode">This is not code</span>
Continuation of comment */
int y = bar();
</pre>
produces
int x = foo(); /* This is a comment This is not code
Continuation of comment */
int y = bar();
I get an error message "a is not a function" or "opt_whenDone is not a function"
prettyPrint via an event handler, wrap it in a function.
Instead of doing
wrap it in a closure like
addEventListener('load', prettyPrint, false);
so that the browser does not pass an event object to addEventListener('load', function (event) { prettyPrint() }, false);
prettyPrint which
will confuse it.
How can I customize the colors and styles of my code?
<span> with classes describing
the kind of code. You can create CSS styles to matches these
classes.
See the
theme gallery for examples.
I can't add classes to my code (because it comes from Markdown, etc.)
<pre class="prettyprint ..."> you can use a
comment or processing instructions that survives processing instructions :
<?prettify ...?> works as explained in
Getting Started
================================================
FILE: google-code-prettify/examples/quine.html
================================================
Making Quines Prettier
<pre>
element is prettified because it has class="prettyprint" and
because the sourced script loads a JavaScript library that styles source
code.
<?prettify lang=html linenums=true?> turns on
line-numbering and the
stylesheet
(see skin=sunburst in the <script src>)
specifies that every fifth line should be numbered.
* (Element "p"
* (Element "b"
* (Text "print ")) ; #1
* (Text "'Hello '") ; #2
* (Element "br") ; #3
* (Text " + 'World';")) ; #4
*
*
+ 'World';
* It will produce the output:
*
* {
* sourceCode: "print 'Hello '\n + 'World';",
* // 1 2
* // 012345678901234 5678901234567
* spans: [0, #1, 6, #2, 14, #3, 15, #4]
* }
*
* * where #1 is a reference to the {@code "print "} text node above, and so * on for the other text nodes. *
* ** The {@code} spans array is an array of pairs. Even elements are the start * indices of substrings, and odd elements are the text nodes (or BR elements) * that contain the text for those substrings. * Substrings continue until the next index or the end of the source. *
* * @param {Node} node an HTML DOM subtree containing source-code. * @param {boolean} isPreformatted true if white-space in text nodes should * be considered significant. * @return {Object} source code and the text nodes in which they occur. */ function extractSourceSpans(node, isPreformatted) { var nocode = /(?:^|\s)nocode(?:\s|$)/; var chunks = []; var length = 0; var spans = []; var k = 0; function walk(node) { var type = node.nodeType; if (type == 1) { // Element if (nocode.test(node.className)) { return; } for (var child = node.firstChild; child; child = child.nextSibling) { walk(child); } var nodeName = node.nodeName.toLowerCase(); if ('br' === nodeName || 'li' === nodeName) { chunks[k] = '\n'; spans[k << 1] = length++; spans[(k++ << 1) | 1] = node; } } else if (type == 3 || type == 4) { // Text var text = node.nodeValue; if (text.length) { if (!isPreformatted) { text = text.replace(/[ \t\r\n]+/g, ' '); } else { text = text.replace(/\r\n?/g, '\n'); // Normalize newlines. } // TODO: handle tabs here? chunks[k] = text; spans[k << 1] = length; length += text.length; spans[(k++ << 1) | 1] = node; } } } walk(node); return { sourceCode: chunks.join('').replace(/\n$/, ''), spans: spans }; } ================================================ FILE: google-code-prettify/js-modules/extractSourceSpans_test.html ================================================| Test space preserved in PRE | ||
|---|---|---|
print 'Hello ' |
^print ^'Hello '^\n^ + '<World>';^ |
|
| Test class="nocode" | ||
1. print 'Hello ' |
^print ^'Hello '^\n^ + '<World>';^ |
|
| Test whitespace normalized in code | ||
print 'Hello '
+ '<World>'; |
^print ^'Hello ' + '<World>';^ |
|
| Test XMP | ||
^print 'Hello '\n + '<World>';^ |
||
| Test tabs | ||
print 'Hello ' + '<World>'; |
^print 'Hello '\n\t+ '<World>';^ |
|
| Test number lines output | ||
|
^print ^'Hello '^\n^ + '<World>';^^ |
|
| Test Nothing to Split | ||
|---|---|---|
Hello, World! |
|
|
| Test Normalized Spaces | ||
Hello,
World! |
|
|
| Test BR | ||
Hello, |
|
|
| Test line breaks | ||
Hello, there World! |
|
|
| Test line breaks with followers | ||
Hello, there World! |
|
|
| Test nocode | ||
Hello,
there
World! |
|
|
| Test link | ||
Hello, there World! |
||
| Test blank lines | ||
One Three |
|
|
* For a fairly comprehensive set of languages see the * README * file that came with this source. At a minimum, the lexer should work on a * number of languages including C and friends, Java, Python, Bash, SQL, HTML, * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk * and a subset of Perl, but, because of commenting conventions, doesn't work on * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. *
* Usage:
} and {@code } tags in your source with
* {@code class=prettyprint.}
* You can also use the (html deprecated) {@code } tag, but the pretty
* printer needs to do more substantial DOM manipulations to support that, so
* some css styles may not be preserved.
* } or {@code } element to specify the
* language, as in {@code }. Any class that
* starts with "lang-" followed by a file extension, specifies the file type.
* See the "lang-*.js" files in this directory for code that implements
* per-language file handlers.
*
* Change log:
* cbeust, 2006/08/22
*
* Java annotations (start with "@") are now captured as literals ("lit")
*
* @requires console
*/
// JSLint declarations
/*global console, document, navigator, setTimeout, window, define */
/** @define {boolean} */
var IN_GLOBAL_SCOPE = true;
/**
* Split {@code prettyPrint} into multiple timeouts so as not to interfere with
* UI events.
* If set to {@code false}, {@code prettyPrint()} is synchronous.
*/
window['PR_SHOULD_USE_CONTINUATION'] = true;
/**
* Pretty print a chunk of code.
* @param {string} sourceCodeHtml The HTML to pretty print.
* @param {string} opt_langExtension The language name to use.
* Typically, a filename extension like 'cpp' or 'java'.
* @param {number|boolean} opt_numberLines True to number lines,
* or the 1-indexed number of the first line in sourceCodeHtml.
* @return {string} code as html, but prettier
*/
var prettyPrintOne;
/**
* Find all the {@code } and {@code } tags in the DOM with
* {@code class=prettyprint} and prettify them.
*
* @param {Function} opt_whenDone called when prettifying is done.
* @param {HTMLElement|HTMLDocument} opt_root an element or document
* containing all the elements to pretty print.
* Defaults to {@code document.body}.
*/
var prettyPrint;
(function () {
var win = window;
// Keyword lists for various languages.
// We use things that coerce to strings to make them compact when minified
// and to defeat aggressive optimizers that fold large string constants.
var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
"double,enum,extern,float,goto,inline,int,long,register,short,signed," +
"sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
"new,operator,private,protected,public,this,throw,true,try,typeof"];
var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
"concept,concept_map,const_cast,constexpr,decltype,delegate," +
"dynamic_cast,explicit,export,friend,generic,late_check," +
"mutable,namespace,nullptr,property,reinterpret_cast,static_assert," +
"static_cast,template,typeid,typename,using,virtual,where"];
var JAVA_KEYWORDS = [COMMON_KEYWORDS,
"abstract,assert,boolean,byte,extends,final,finally,implements,import," +
"instanceof,interface,null,native,package,strictfp,super,synchronized," +
"throws,transient"];
var CSHARP_KEYWORDS = [JAVA_KEYWORDS,
"as,base,by,checked,decimal,delegate,descending,dynamic,event," +
"fixed,foreach,from,group,implicit,in,internal,into,is,let," +
"lock,object,out,override,orderby,params,partial,readonly,ref,sbyte," +
"sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort," +
"var,virtual,where"];
var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
"for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
"throw,true,try,unless,until,when,while,yes";
var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
"debugger,eval,export,function,get,null,set,undefined,var,with," +
"Infinity,NaN"];
var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
"goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
"sub,undef,unless,until,use,wantarray,while,BEGIN,END";
var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
"elif,except,exec,finally,from,global,import,in,is,lambda," +
"nonlocal,not,or,pass,print,raise,try,with,yield," +
"False,True,None"];
var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
"def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
"rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
"BEGIN,END"];
var RUST_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "as,assert,const,copy,drop," +
"enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv," +
"pub,pure,ref,self,static,struct,true,trait,type,unsafe,use"];
var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
"function,in,local,set,then,until"];
var ALL_KEYWORDS = [
CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS,
PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
// token style names. correspond to css classes
/**
* token style for a string literal
* @const
*/
var PR_STRING = 'str';
/**
* token style for a keyword
* @const
*/
var PR_KEYWORD = 'kwd';
/**
* token style for a comment
* @const
*/
var PR_COMMENT = 'com';
/**
* token style for a type
* @const
*/
var PR_TYPE = 'typ';
/**
* token style for a literal value. e.g. 1, null, true.
* @const
*/
var PR_LITERAL = 'lit';
/**
* token style for a punctuation string.
* @const
*/
var PR_PUNCTUATION = 'pun';
/**
* token style for plain text.
* @const
*/
var PR_PLAIN = 'pln';
/**
* token style for an sgml tag.
* @const
*/
var PR_TAG = 'tag';
/**
* token style for a markup declaration such as a DOCTYPE.
* @const
*/
var PR_DECLARATION = 'dec';
/**
* token style for embedded source.
* @const
*/
var PR_SOURCE = 'src';
/**
* token style for an sgml attribute name.
* @const
*/
var PR_ATTRIB_NAME = 'atn';
/**
* token style for an sgml attribute value.
* @const
*/
var PR_ATTRIB_VALUE = 'atv';
/**
* A class that indicates a section of markup that is not code, e.g. to allow
* embedding of line numbers within code listings.
* @const
*/
var PR_NOCODE = 'nocode';
include("regexpPrecederPatterns.pl");
include("combinePrefixPatterns.js");
include("extractSourceSpans.js");
/**
* Apply the given language handler to sourceCode and add the resulting
* decorations to out.
* @param {number} basePos the index of sourceCode within the chunk of source
* whose decorations are already present on out.
*/
function appendDecorations(basePos, sourceCode, langHandler, out) {
if (!sourceCode) { return; }
var job = {
sourceCode: sourceCode,
basePos: basePos
};
langHandler(job);
out.push.apply(out, job.decorations);
}
var notWs = /\S/;
/**
* Given an element, if it contains only one child element and any text nodes
* it contains contain only space characters, return the sole child element.
* Otherwise returns undefined.
*
* This is meant to return the CODE element in {@code
} when
* there is a single child element that contains all the non-space textual
* content, but not to return anything where there are multiple child elements
* as in {@code ......
} or when there
* is textual content.
*/
function childContentWrapper(element) {
var wrapper = undefined;
for (var c = element.firstChild; c; c = c.nextSibling) {
var type = c.nodeType;
wrapper = (type === 1) // Element Node
? (wrapper ? element : c)
: (type === 3) // Text Node
? (notWs.test(c.nodeValue) ? element : wrapper)
: wrapper;
}
return wrapper === element ? undefined : wrapper;
}
/** Given triples of [style, pattern, context] returns a lexing function,
* The lexing function interprets the patterns to find token boundaries and
* returns a decoration list of the form
* [index_0, style_0, index_1, style_1, ..., index_n, style_n]
* where index_n is an index into the sourceCode, and style_n is a style
* constant like PR_PLAIN. index_n-1 <= index_n, and style_n-1 applies to
* all characters in sourceCode[index_n-1:index_n].
*
* The stylePatterns is a list whose elements have the form
* [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
*
* Style is a style constant like PR_PLAIN, or can be a string of the
* form 'lang-FOO', where FOO is a language extension describing the
* language of the portion of the token in $1 after pattern executes.
* E.g., if style is 'lang-lisp', and group 1 contains the text
* '(hello (world))', then that portion of the token will be passed to the
* registered lisp handler for formatting.
* The text before and after group 1 will be restyled using this decorator
* so decorators should take care that this doesn't result in infinite
* recursion. For example, the HTML lexer rule for SCRIPT elements looks
* something like ['lang-js', /<[s]cript>(.+?)<\/script>/]. This may match
* '
Recombine Tags And Decorations
Test Single Decoration
"Hello, World!"
[0, 'str']
"Hello, World!"
Test Single Span
print "Hello, <World>!";
[0, 'kwd', 5, 'pln', 6, 'str', 14, 'tag', 21, 'str', 23, 'pun']
print "Hello, <World>!";
Test Interleaved
print "Hello, <World>!";
[0, 'kwd', 5, 'pln', 6, 'str', 14, 'tag', 21, 'str', 23, 'pun']
print "Hello, <World>!";
Last modified: Tue Mar 29 10:41:34 PDT 2011