first commit

This commit is contained in:
Jérôme Delacotte
2025-03-06 11:15:32 +01:00
commit 7b30d6e298
5276 changed files with 2108927 additions and 0 deletions

View File

@@ -0,0 +1,153 @@
extern "C" {
void app_loop();
void restartMCU();
}
#include "Settings.h"
#include <BlynkSimpleEsp32_SSL.h>
#if defined(BLYNK_USE_LITTLEFS)
#include <LittleFS.h>
#define BLYNK_FS LittleFS
#elif defined(BLYNK_USE_SPIFFS)
#if defined(ESP32)
#include <SPIFFS.h>
#elif defined(ESP8266)
#include <FS.h>
#endif
#define BLYNK_FS SPIFFS
#endif
#ifndef BLYNK_NEW_LIBRARY
#error "Old version of Blynk library is in use. Please replace it with the new one."
#endif
#if !defined(BLYNK_TEMPLATE_NAME) && defined(BLYNK_DEVICE_NAME)
#define BLYNK_TEMPLATE_NAME BLYNK_DEVICE_NAME
#endif
#if !defined(BLYNK_TEMPLATE_ID) || !defined(BLYNK_TEMPLATE_NAME)
#error "Please specify your BLYNK_TEMPLATE_ID and BLYNK_TEMPLATE_NAME"
#endif
#if defined(BLYNK_AUTH_TOKEN)
#error "BLYNK_AUTH_TOKEN is assigned automatically when using Blynk.Edgent, please remove it from the configuration"
#endif
BlynkTimer edgentTimer;
#include "BlynkState.h"
#include "ConfigStore.h"
#include "ResetButton.h"
#include "ConfigMode.h"
#include "Indicator.h"
#include "OTA.h"
#include "Console.h"
inline
void BlynkState::set(State m) {
if (state != m && m < MODE_MAX_VALUE) {
DEBUG_PRINT(String(StateStr[state]) + " => " + StateStr[m]);
state = m;
// You can put your state handling here,
// i.e. implement custom indication
}
}
void printDeviceBanner()
{
#ifdef BLYNK_PRINT
Blynk.printBanner();
BLYNK_PRINT.println("----------------------------------------------------");
BLYNK_PRINT.print(" Device: "); BLYNK_PRINT.println(getWiFiName());
BLYNK_PRINT.print(" Firmware: "); BLYNK_PRINT.println(BLYNK_FIRMWARE_VERSION " (build " __DATE__ " " __TIME__ ")");
if (configStore.getFlag(CONFIG_FLAG_VALID)) {
BLYNK_PRINT.print(" Token: ");
BLYNK_PRINT.println(String(configStore.cloudToken).substring(0,4) +
" - •••• - •••• - ••••");
}
BLYNK_PRINT.print(" Platform: "); BLYNK_PRINT.println(String(BLYNK_INFO_DEVICE) + " @ " + ESP.getCpuFreqMHz() + "MHz");
BLYNK_PRINT.print(" Chip rev: "); BLYNK_PRINT.println(ESP.getChipRevision());
BLYNK_PRINT.print(" SDK: "); BLYNK_PRINT.println(ESP.getSdkVersion());
BLYNK_PRINT.print(" Flash: "); BLYNK_PRINT.println(String(ESP.getFlashChipSize() / 1024) + "K");
BLYNK_PRINT.print(" Free mem: "); BLYNK_PRINT.println(ESP.getFreeHeap());
BLYNK_PRINT.println("----------------------------------------------------");
#endif
}
void runBlynkWithChecks() {
Blynk.run();
if (BlynkState::get() == MODE_RUNNING) {
if (!Blynk.connected()) {
if (WiFi.status() == WL_CONNECTED) {
BlynkState::set(MODE_CONNECTING_CLOUD);
} else {
BlynkState::set(MODE_CONNECTING_NET);
}
}
}
}
class Edgent {
public:
void begin()
{
WiFi.persistent(false);
WiFi.enableSTA(true); // Needed to get MAC
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0))
WiFi.setMinSecurity(WIFI_AUTH_WEP);
#endif
#ifdef BLYNK_FS
BLYNK_FS.begin(true);
#endif
indicator_init();
button_init();
config_init();
printDeviceBanner();
console_init();
if (configStore.getFlag(CONFIG_FLAG_VALID)) {
BlynkState::set(MODE_CONNECTING_NET);
} else if (config_load_blnkopt()) {
DEBUG_PRINT("Firmware is preprovisioned");
BlynkState::set(MODE_CONNECTING_NET);
} else {
BlynkState::set(MODE_WAIT_CONFIG);
}
if (!String(BLYNK_TEMPLATE_ID).startsWith("TMPL") ||
!strlen(BLYNK_TEMPLATE_NAME)
) {
DEBUG_PRINT("Invalid configuration of TEMPLATE_ID / TEMPLATE_NAME");
while (true) { delay(100); }
}
}
void run() {
app_loop();
switch (BlynkState::get()) {
case MODE_WAIT_CONFIG:
case MODE_CONFIGURING: enterConfigMode(); break;
case MODE_CONNECTING_NET: enterConnectNet(); break;
case MODE_CONNECTING_CLOUD: enterConnectCloud(); break;
case MODE_RUNNING: runBlynkWithChecks(); break;
case MODE_OTA_UPGRADE: enterOTA(); break;
case MODE_SWITCH_TO_STA: enterSwitchToSTA(); break;
case MODE_RESET_CONFIG: enterResetConfig(); break;
default: enterError(); break;
}
}
} BlynkEdgent;
void app_loop() {
edgentTimer.run();
edgentConsole.run();
}

View File

@@ -0,0 +1,40 @@
enum State {
MODE_WAIT_CONFIG,
MODE_CONFIGURING,
MODE_CONNECTING_NET,
MODE_CONNECTING_CLOUD,
MODE_RUNNING,
MODE_OTA_UPGRADE,
MODE_SWITCH_TO_STA,
MODE_RESET_CONFIG,
MODE_ERROR,
MODE_MAX_VALUE
};
#if defined(APP_DEBUG)
const char* StateStr[MODE_MAX_VALUE+1] = {
"WAIT_CONFIG",
"CONFIGURING",
"CONNECTING_NET",
"CONNECTING_CLOUD",
"RUNNING",
"OTA_UPGRADE",
"SWITCH_TO_STA",
"RESET_CONFIG",
"ERROR",
"INIT"
};
#endif
namespace BlynkState
{
volatile State state = MODE_MAX_VALUE;
State get() { return state; }
bool is (State m) { return (state == m); }
void set(State m);
};

View File

@@ -0,0 +1,544 @@
#include <WiFiClient.h>
#include <WebServer.h>
#include <DNSServer.h>
#include <Update.h>
#ifndef BLYNK_FS
const char* config_form = R"html(
<!DOCTYPE HTML>
<html>
<head>
<title>WiFi setup</title>
<style>
body {
background-color: #fcfcfc;
box-sizing: border-box;
}
body, input {
font-family: Roboto, sans-serif;
font-weight: 400;
font-size: 16px;
}
.centered {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 20px;
background-color: #ccc;
border-radius: 4px;
}
td { padding:0 0 0 5px; }
label { white-space:nowrap; }
input { width: 20em; }
input[name="port"] { width: 5em; }
input[type="submit"], img { margin: auto; display: block; width: 30%; }
</style>
</head>
<body>
<div class="centered">
<form method="get" action="config">
<table>
<tr><td><label for="ssid">WiFi SSID:</label></td> <td><input type="text" name="ssid" length=64 required="required"></td></tr>
<tr><td><label for="pass">Password:</label></td> <td><input type="text" name="pass" length=64></td></tr>
<tr><td><label for="blynk">Auth token:</label></td><td><input type="text" name="blynk" placeholder="a0b1c2d..." pattern="[-_a-zA-Z0-9]{32}" maxlength="32" required="required"></td></tr>
<tr><td><label for="host">Host:</label></td> <td><input type="text" name="host" value="blynk.cloud" length=64></td></tr>
<tr><td><label for="port_ssl">Port:</label></td> <td><input type="number" name="port_ssl" value="443" min="1" max="65535"></td></tr>
</table><br/>
<input type="submit" value="Apply">
</form>
</div>
</body>
</html>
)html";
#endif
WebServer server(80);
DNSServer dnsServer;
const byte DNS_PORT = 53;
static int connectNetRetries = WIFI_CLOUD_MAX_RETRIES;
static int connectBlynkRetries = WIFI_CLOUD_MAX_RETRIES;
static const char serverUpdateForm[] PROGMEM =
R"(<html><body>
<form method='POST' action='' enctype='multipart/form-data'>
<input type='file' name='update'>
<input type='submit' value='Update'>
</form>
</body></html>)";
void restartMCU() {
ESP.restart();
while(1) {};
}
static
String encodeUniquePart(uint32_t n, unsigned len)
{
static constexpr char alphabet[] = { "0W8N4Y1HP5DF9K6JM3C2UA7R" };
static constexpr int base = sizeof(alphabet)-1;
char buf[16] = { 0, };
char prev = 0;
for (unsigned i = 0; i < len; n /= base) {
char c = alphabet[n % base];
if (c == prev) {
c = alphabet[(n+1) % base];
}
prev = buf[i++] = c;
}
return String(buf);
}
static
String getWiFiName(bool withPrefix = true)
{
const uint64_t chipId = ESP.getEfuseMac();
uint32_t unique = 0;
for (int i=0; i<4; i++) {
unique = BlynkCRC32(&chipId, sizeof(chipId), unique);
}
String devUnique = encodeUniquePart(unique, 4);
String devPrefix = CONFIG_DEVICE_PREFIX;
String devName = String(BLYNK_TEMPLATE_NAME).substring(0, 31-6-devPrefix.length());
if (withPrefix) {
return devPrefix + " " + devName + "-" + devUnique;
} else {
return devName + "-" + devUnique;
}
}
static inline
String macToString(byte mac[6]) {
char buff[20];
snprintf(buff, sizeof(buff), "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(buff);
}
static inline
const char* wifiSecToStr(wifi_auth_mode_t t) {
switch (t) {
case WIFI_AUTH_OPEN: return "OPEN";
case WIFI_AUTH_WEP: return "WEP";
case WIFI_AUTH_WPA_PSK: return "WPA";
case WIFI_AUTH_WPA2_PSK: return "WPA2";
case WIFI_AUTH_WPA_WPA2_PSK: return "WPA+WPA2";
case WIFI_AUTH_WPA2_ENTERPRISE: return "WPA2-EAP";
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0))
case WIFI_AUTH_WPA3_PSK: return "WPA3";
case WIFI_AUTH_WPA2_WPA3_PSK: return "WPA2+WPA3";
case WIFI_AUTH_WAPI_PSK: return "WAPI";
#endif
default: return "unknown";
}
}
static
String getWiFiMacAddress() {
return WiFi.macAddress();
}
static
String getWiFiApBSSID() {
return WiFi.softAPmacAddress();
}
static
String getWiFiNetworkSSID() {
return WiFi.SSID();
}
static
String getWiFiNetworkBSSID() {
return WiFi.BSSIDstr();
}
void enterConfigMode()
{
WiFi.mode(WIFI_OFF);
delay(100);
WiFi.mode(WIFI_AP);
delay(2000);
WiFi.softAPConfig(WIFI_AP_IP, WIFI_AP_IP, WIFI_AP_Subnet);
WiFi.softAP(getWiFiName().c_str());
delay(500);
// Set up DNS Server
dnsServer.setTTL(300); // Time-to-live 300s
dnsServer.setErrorReplyCode(DNSReplyCode::ServerFailure); // Return code for non-accessible domains
#ifdef WIFI_CAPTIVE_PORTAL_ENABLE
dnsServer.start(DNS_PORT, "*", WiFi.softAPIP()); // Point all to our IP
server.onNotFound(handleRoot);
#else
dnsServer.start(DNS_PORT, CONFIG_AP_URL, WiFi.softAPIP());
DEBUG_PRINT(String("AP URL: ") + CONFIG_AP_URL);
#endif
server.on("/update", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", serverUpdateForm);
});
server.on("/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");
if (!Update.hasError()) {
server.send(200, "text/plain", "OK");
} else {
server.send(500, "text/plain", "FAIL");
}
delay(1000);
restartMCU();
}, []() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
DEBUG_PRINT(String("Update: ") + upload.filename);
//WiFiUDP::stop();
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
DEBUG_PRINT(Update.errorString());
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
/* flashing firmware to ESP*/
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
DEBUG_PRINT(Update.errorString());
}
#ifdef BLYNK_PRINT
BLYNK_PRINT.print(".");
#endif
} else if (upload.status == UPLOAD_FILE_END) {
#ifdef BLYNK_PRINT
BLYNK_PRINT.println();
#endif
DEBUG_PRINT("Finishing...");
if (Update.end(true)) { //true to set the size to the current progress
DEBUG_PRINT("Update Success. Rebooting");
} else {
DEBUG_PRINT(Update.errorString());
}
}
});
#ifndef BLYNK_FS
server.on("/", []() {
server.send(200, "text/html", config_form);
});
#endif
server.on("/config", []() {
DEBUG_PRINT("Applying configuration...");
String ssid = server.arg("ssid");
String ssidManual = server.arg("ssidManual");
String pass = server.arg("pass");
if (ssidManual != "") {
ssid = ssidManual;
}
String token = server.arg("blynk");
String host = server.arg("host");
String port = server.arg("port_ssl");
String ip = server.arg("ip");
String mask = server.arg("mask");
String gw = server.arg("gw");
String dns = server.arg("dns");
String dns2 = server.arg("dns2");
bool forceSave = server.arg("save").toInt();
String content;
DEBUG_PRINT(String("WiFi SSID: ") + ssid + " Pass: " + pass);
DEBUG_PRINT(String("Blynk cloud: ") + token + " @ " + host + ":" + port);
if (token.length() == 32 && ssid.length() > 0) {
configStore = configDefault;
CopyString(ssid, configStore.wifiSSID);
CopyString(pass, configStore.wifiPass);
CopyString(token, configStore.cloudToken);
if (host.length()) {
CopyString(host, configStore.cloudHost);
}
if (port.length()) {
configStore.cloudPort = port.toInt();
}
IPAddress addr;
if (ip.length() && addr.fromString(ip)) {
configStore.staticIP = addr;
configStore.setFlag(CONFIG_FLAG_STATIC_IP, true);
} else {
configStore.setFlag(CONFIG_FLAG_STATIC_IP, false);
}
if (mask.length() && addr.fromString(mask)) {
configStore.staticMask = addr;
}
if (gw.length() && addr.fromString(gw)) {
configStore.staticGW = addr;
}
if (dns.length() && addr.fromString(dns)) {
configStore.staticDNS = addr;
}
if (dns2.length() && addr.fromString(dns2)) {
configStore.staticDNS2 = addr;
}
if (forceSave) {
configStore.setFlag(CONFIG_FLAG_VALID, true);
config_save();
content = R"json({"status":"ok","msg":"Configuration saved"})json";
} else {
content = R"json({"status":"ok","msg":"Trying to connect..."})json";
}
server.send(200, "application/json", content);
connectNetRetries = connectBlynkRetries = 1;
BlynkState::set(MODE_SWITCH_TO_STA);
} else {
DEBUG_PRINT("Configuration invalid");
content = R"json({"status":"error","msg":"Configuration invalid"})json";
server.send(500, "application/json", content);
}
});
server.on("/board_info.json", []() {
// Configuring starts with board info request (may impact indication)
BlynkState::set(MODE_CONFIGURING);
DEBUG_PRINT("Sending board info...");
const char* tmpl = BLYNK_TEMPLATE_ID;
char buff[512];
snprintf(buff, sizeof(buff),
R"json({"board":"%s","tmpl_id":"%s","fw_type":"%s","fw_ver":"%s","ssid":"%s","bssid":"%s","mac":"%s","last_error":%d,"wifi_scan":true,"static_ip":true})json",
BLYNK_TEMPLATE_NAME,
tmpl ? tmpl : "Unknown",
BLYNK_FIRMWARE_TYPE,
BLYNK_FIRMWARE_VERSION,
getWiFiName().c_str(),
getWiFiApBSSID().c_str(),
getWiFiMacAddress().c_str(),
configStore.last_error
);
server.send(200, "application/json", buff);
});
server.on("/wifi_scan.json", []() {
DEBUG_PRINT("Scanning networks...");
int wifi_nets = WiFi.scanNetworks(true, true);
const uint32_t t = millis();
while (wifi_nets < 0 &&
millis() - t < 20000)
{
delay(20);
wifi_nets = WiFi.scanComplete();
}
DEBUG_PRINT(String("Found networks: ") + wifi_nets);
if (wifi_nets > 0) {
// Sort networks
int indices[wifi_nets];
for (int i = 0; i < wifi_nets; i++) {
indices[i] = i;
}
for (int i = 0; i < wifi_nets; i++) {
for (int j = i + 1; j < wifi_nets; j++) {
if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i])) {
std::swap(indices[i], indices[j]);
}
}
}
wifi_nets = BlynkMin(15, wifi_nets); // Show top 15 networks
// TODO: skip empty names
String result = "[\n";
char buff[256];
for (int i = 0; i < wifi_nets; i++){
int id = indices[i];
snprintf(buff, sizeof(buff),
R"json( {"ssid":"%s","bssid":"%s","rssi":%i,"sec":"%s","ch":%i})json",
WiFi.SSID(id).c_str(),
WiFi.BSSIDstr(id).c_str(),
WiFi.RSSI(id),
wifiSecToStr(WiFi.encryptionType(id)),
WiFi.channel(id)
);
result += buff;
if (i != wifi_nets-1) result += ",\n";
}
WiFi.scanDelete();
server.send(200, "application/json", result + "\n]");
} else {
server.send(200, "application/json", "[]");
}
});
server.on("/reset", []() {
BlynkState::set(MODE_RESET_CONFIG);
server.send(200, "application/json", R"json({"status":"ok","msg":"Configuration reset"})json");
});
server.on("/reboot", []() {
restartMCU();
});
#ifdef BLYNK_FS
server.serveStatic("/img/favicon.png", BLYNK_FS, "/img/favicon.png");
server.serveStatic("/img/logo.png", BLYNK_FS, "/img/logo.png");
server.serveStatic("/", BLYNK_FS, "/index.html");
#endif
server.begin();
while (BlynkState::is(MODE_WAIT_CONFIG) || BlynkState::is(MODE_CONFIGURING)) {
delay(10);
dnsServer.processNextRequest();
server.handleClient();
app_loop();
if (BlynkState::is(MODE_CONFIGURING) && WiFi.softAPgetStationNum() == 0) {
BlynkState::set(MODE_WAIT_CONFIG);
}
}
server.stop();
}
void enterConnectNet() {
BlynkState::set(MODE_CONNECTING_NET);
DEBUG_PRINT(String("Connecting to WiFi: ") + configStore.wifiSSID);
// Needed for setHostname to work
WiFi.enableSTA(false);
String hostname = getWiFiName();
hostname.replace(" ", "-");
WiFi.setHostname(hostname.c_str());
if (configStore.getFlag(CONFIG_FLAG_STATIC_IP)) {
if (!WiFi.config(configStore.staticIP,
configStore.staticGW,
configStore.staticMask,
configStore.staticDNS,
configStore.staticDNS2)
) {
DEBUG_PRINT("Failed to configure Static IP");
config_set_last_error(BLYNK_PROV_ERR_CONFIG);
BlynkState::set(MODE_ERROR);
return;
}
}
WiFi.begin(configStore.wifiSSID, configStore.wifiPass);
unsigned long timeoutMs = millis() + WIFI_NET_CONNECT_TIMEOUT;
while ((timeoutMs > millis()) && (WiFi.status() != WL_CONNECTED))
{
delay(10);
app_loop();
if (!BlynkState::is(MODE_CONNECTING_NET)) {
WiFi.disconnect();
return;
}
}
if (WiFi.status() == WL_CONNECTED) {
IPAddress localip = WiFi.localIP();
if (configStore.getFlag(CONFIG_FLAG_STATIC_IP)) {
BLYNK_LOG_IP("Using Static IP: ", localip);
} else {
BLYNK_LOG_IP("Using Dynamic IP: ", localip);
}
connectNetRetries = WIFI_CLOUD_MAX_RETRIES;
BlynkState::set(MODE_CONNECTING_CLOUD);
} else if (--connectNetRetries <= 0) {
config_set_last_error(BLYNK_PROV_ERR_NETWORK);
BlynkState::set(MODE_ERROR);
}
}
void enterConnectCloud() {
BlynkState::set(MODE_CONNECTING_CLOUD);
Blynk.config(configStore.cloudToken, configStore.cloudHost, configStore.cloudPort);
Blynk.connect(0);
unsigned long timeoutMs = millis() + WIFI_CLOUD_CONNECT_TIMEOUT;
while ((timeoutMs > millis()) &&
(WiFi.status() == WL_CONNECTED) &&
(!Blynk.isTokenInvalid()) &&
(Blynk.connected() == false))
{
delay(10);
Blynk.run();
app_loop();
if (!BlynkState::is(MODE_CONNECTING_CLOUD)) {
Blynk.disconnect();
return;
}
}
if (millis() > timeoutMs) {
DEBUG_PRINT("Timeout");
}
if (Blynk.isTokenInvalid()) {
config_set_last_error(BLYNK_PROV_ERR_TOKEN);
BlynkState::set(MODE_WAIT_CONFIG); // TODO: retry after timeout
} else if (WiFi.status() != WL_CONNECTED) {
BlynkState::set(MODE_CONNECTING_NET);
} else if (Blynk.connected()) {
BlynkState::set(MODE_RUNNING);
connectBlynkRetries = WIFI_CLOUD_MAX_RETRIES;
if (!configStore.getFlag(CONFIG_FLAG_VALID)) {
configStore.last_error = BLYNK_PROV_ERR_NONE;
configStore.setFlag(CONFIG_FLAG_VALID, true);
config_save();
Blynk.sendInternal("meta", "set", "Hotspot Name", getWiFiName());
}
} else if (--connectBlynkRetries <= 0) {
config_set_last_error(BLYNK_PROV_ERR_CLOUD);
BlynkState::set(MODE_ERROR);
}
}
void enterSwitchToSTA() {
BlynkState::set(MODE_SWITCH_TO_STA);
DEBUG_PRINT("Switching to STA...");
delay(1000);
WiFi.mode(WIFI_OFF);
delay(100);
WiFi.mode(WIFI_STA);
BlynkState::set(MODE_CONNECTING_NET);
}
void enterError() {
BlynkState::set(MODE_ERROR);
unsigned long timeoutMs = millis() + 10000;
while (timeoutMs > millis() || g_buttonPressed)
{
delay(10);
app_loop();
if (!BlynkState::is(MODE_ERROR)) {
return;
}
}
DEBUG_PRINT("Restarting after error.");
delay(10);
restartMCU();
}

View File

@@ -0,0 +1,154 @@
#define CONFIG_FLAG_VALID 0x01
#define CONFIG_FLAG_STATIC_IP 0x02
#define BLYNK_PROV_ERR_NONE 0 // All good
#define BLYNK_PROV_ERR_CONFIG 700 // Invalid config from app (malformed token,etc)
#define BLYNK_PROV_ERR_NETWORK 701 // Could not connect to the router
#define BLYNK_PROV_ERR_CLOUD 702 // Could not connect to the cloud
#define BLYNK_PROV_ERR_TOKEN 703 // Invalid token error (after connection)
#define BLYNK_PROV_ERR_INTERNAL 704 // Other issues (i.e. hardware failure)
struct ConfigStore {
uint32_t magic;
char version[15];
uint8_t flags;
char wifiSSID[34];
char wifiPass[64];
char cloudToken[34];
char cloudHost[34];
uint16_t cloudPort;
uint32_t staticIP;
uint32_t staticMask;
uint32_t staticGW;
uint32_t staticDNS;
uint32_t staticDNS2;
int last_error;
void setFlag(uint8_t mask, bool value) {
if (value) {
flags |= mask;
} else {
flags &= ~mask;
}
}
bool getFlag(uint8_t mask) {
return (flags & mask) == mask;
}
} __attribute__((packed));
ConfigStore configStore;
const ConfigStore configDefault = {
0x626C6E6B,
BLYNK_FIRMWARE_VERSION,
0x00,
"",
"",
"invalid token",
CONFIG_DEFAULT_SERVER,
CONFIG_DEFAULT_PORT,
0,
BLYNK_PROV_ERR_NONE
};
template<typename T, int size>
void CopyString(const String& s, T(&arr)[size]) {
s.toCharArray(arr, size);
}
static bool config_load_blnkopt()
{
static const char blnkopt[] = "blnkopt\0"
BLYNK_PARAM_KV("ssid" , BLYNK_PARAM_PLACEHOLDER_64
BLYNK_PARAM_PLACEHOLDER_64
BLYNK_PARAM_PLACEHOLDER_64
BLYNK_PARAM_PLACEHOLDER_64)
BLYNK_PARAM_KV("host" , CONFIG_DEFAULT_SERVER)
BLYNK_PARAM_KV("port" , BLYNK_TOSTRING(CONFIG_DEFAULT_PORT))
"\0";
BlynkParam prov(blnkopt+8, sizeof(blnkopt)-8-2);
BlynkParam::iterator ssid = prov["ssid"];
BlynkParam::iterator pass = prov["pass"];
BlynkParam::iterator auth = prov["auth"];
BlynkParam::iterator host = prov["host"];
BlynkParam::iterator port = prov["port"];
if (!(ssid.isValid() && auth.isValid())) {
return false;
}
// reset to defaut before loading values from blnkopt
configStore = configDefault;
if (ssid.isValid()) { CopyString(ssid.asStr(), configStore.wifiSSID); }
if (pass.isValid()) { CopyString(pass.asStr(), configStore.wifiPass); }
if (auth.isValid()) { CopyString(auth.asStr(), configStore.cloudToken); }
if (host.isValid()) { CopyString(host.asStr(), configStore.cloudHost); }
if (port.isValid()) { configStore.cloudPort = port.asInt(); }
return true;
}
#include <Preferences.h>
void config_load()
{
Preferences prefs;
if (prefs.begin("blynk", true)) { // read-only
memset(&configStore, 0, sizeof(configStore));
prefs.getBytes("config", &configStore, sizeof(configStore));
if (configStore.magic != configDefault.magic) {
DEBUG_PRINT("Using default config.");
configStore = configDefault;
}
} else {
DEBUG_PRINT("Config read failed");
}
}
bool config_save()
{
Preferences prefs;
if (prefs.begin("blynk", false)) { // writeable
prefs.putBytes("config", &configStore, sizeof(configStore));
DEBUG_PRINT("Configuration stored to flash");
return true;
} else {
DEBUG_PRINT("Config write failed");
return false;
}
}
bool config_init()
{
config_load();
return true;
}
void enterResetConfig()
{
DEBUG_PRINT("Resetting configuration!");
configStore = configDefault;
config_save();
BlynkState::set(MODE_WAIT_CONFIG);
}
void config_set_last_error(int error) {
// Only set error if not provisioned
if (!configStore.getFlag(CONFIG_FLAG_VALID)) {
configStore = configDefault;
configStore.last_error = error;
BLYNK_LOG2("Last error code: ", error);
config_save();
}
}

View File

@@ -0,0 +1,225 @@
#include <Blynk/BlynkConsole.h>
extern "C" {
#include "esp_partition.h"
#include "esp_ota_ops.h"
}
BlynkConsole edgentConsole;
void console_init()
{
#ifdef BLYNK_PRINT
edgentConsole.begin(BLYNK_PRINT);
#endif
edgentConsole.print("\n>");
edgentConsole.addCommand("reboot", []() {
edgentConsole.print(R"json({"status":"OK","msg":"rebooting wifi module"})json" "\n");
delay(100);
restartMCU();
});
edgentConsole.addCommand("config", [](int argc, const char** argv) {
if (argc < 1 || 0 == strcmp(argv[0], "start")) {
BlynkState::set(MODE_WAIT_CONFIG);
} else if (0 == strcmp(argv[0], "erase")) {
BlynkState::set(MODE_RESET_CONFIG);
}
});
edgentConsole.addCommand("devinfo", []() {
edgentConsole.printf(
R"json({"name":"%s","board":"%s","tmpl_id":"%s","fw_type":"%s","fw_ver":"%s"})json" "\n",
getWiFiName().c_str(),
BLYNK_TEMPLATE_NAME,
BLYNK_TEMPLATE_ID,
BLYNK_FIRMWARE_TYPE,
BLYNK_FIRMWARE_VERSION
);
});
edgentConsole.addCommand("connect", [](int argc, const char** argv) {
if (argc < 2) {
edgentConsole.print(R"json({"status":"error","msg":"invalid arguments. expected: <auth> <ssid> <pass>"})json" "\n");
return;
}
String auth = argv[0];
String ssid = argv[1];
String pass = (argc >= 3) ? argv[2] : "";
if (auth.length() != 32) {
edgentConsole.print(R"json({"status":"error","msg":"invalid token size"})json" "\n");
return;
}
edgentConsole.print(R"json({"status":"OK","msg":"trying to connect..."})json" "\n");
configStore = configDefault;
CopyString(ssid, configStore.wifiSSID);
CopyString(pass, configStore.wifiPass);
CopyString(auth, configStore.cloudToken);
BlynkState::set(MODE_SWITCH_TO_STA);
});
edgentConsole.addCommand("wifi", [](int argc, const char* argv[]) {
if (argc < 1 || 0 == strcmp(argv[0], "show")) {
edgentConsole.printf(
"mac:%s ip:%s (%s [%s] %ddBm)\n",
getWiFiMacAddress().c_str(),
WiFi.localIP().toString().c_str(),
getWiFiNetworkSSID().c_str(),
getWiFiNetworkBSSID().c_str(),
WiFi.RSSI()
);
} else if (0 == strcmp(argv[0], "scan")) {
int found = WiFi.scanNetworks();
for (int i = 0; i < found; i++) {
bool current = (WiFi.SSID(i) == WiFi.SSID());
edgentConsole.printf(
"%s %s [%s] %s ch:%d rssi:%d\n",
(current ? "*" : " "), WiFi.SSID(i).c_str(),
macToString(WiFi.BSSID(i)).c_str(),
wifiSecToStr(WiFi.encryptionType(i)),
WiFi.channel(i), WiFi.RSSI(i)
);
}
WiFi.scanDelete();
}
});
edgentConsole.addCommand("firmware", [](int argc, const char** argv) {
if (argc < 1 || 0 == strcmp(argv[0], "info")) {
unsigned sketchSize = ESP.getSketchSize();
edgentConsole.printf(" Version: %s (build %s)\n", BLYNK_FIRMWARE_VERSION, __DATE__ " " __TIME__);
edgentConsole.printf(" Type: %s\n", BLYNK_FIRMWARE_TYPE);
edgentConsole.printf(" Platform: %s\n", BLYNK_INFO_DEVICE);
edgentConsole.printf(" SDK: %s\n", ESP.getSdkVersion());
if (const esp_partition_t* running = esp_ota_get_running_partition()) {
edgentConsole.printf(" Partition: %s (%dK)\n", running->label, running->size / 1024);
edgentConsole.printf(" App size: %dK (%d%%)\n", sketchSize/1024, (sketchSize*100)/(running->size));
edgentConsole.printf(" App MD5: %s\n", ESP.getSketchMD5().c_str());
}
} else if (0 == strcmp(argv[0], "rollback")) {
if (Update.rollBack()) {
edgentConsole.print(R"json({"status":"ok"})json" "\n");
edgentTimer.setTimeout(50, restartMCU);
} else {
edgentConsole.print(R"json({"status":"error"})json" "\n");
}
}
});
edgentConsole.addCommand("status", [](int argc, const char** argv) {
const int64_t t = esp_timer_get_time() / 1000000;
unsigned secs = t % BLYNK_SECS_PER_MIN;
unsigned mins = (t / BLYNK_SECS_PER_MIN) % BLYNK_SECS_PER_MIN;
unsigned hrs = (t % BLYNK_SECS_PER_DAY) / BLYNK_SECS_PER_HOUR;
unsigned days = t / BLYNK_SECS_PER_DAY;
edgentConsole.printf(" Uptime: %dd %dh %dm %ds\n", days, hrs, mins, secs);
edgentConsole.printf(" Chip: %s rev %d\n", ESP.getChipModel(), ESP.getChipRevision());
edgentConsole.printf(" Flash: %dK\n", ESP.getFlashChipSize() / 1024);
edgentConsole.printf(" Stack unused: %d\n", uxTaskGetStackHighWaterMark(NULL));
edgentConsole.printf(" Heap free: %d / %d\n", ESP.getFreeHeap(), ESP.getHeapSize());
edgentConsole.printf(" max alloc: %d\n", ESP.getMaxAllocHeap());
edgentConsole.printf(" min free: %d\n", ESP.getMinFreeHeap());
if (ESP.getPsramSize()) {
edgentConsole.printf(" PSRAM free: %d / %d\n", ESP.getFreePsram(), ESP.getPsramSize());
}
#ifdef BLYNK_FS
uint32_t fs_total = BLYNK_FS.totalBytes();
edgentConsole.printf(" FS free: %d / %d\n", (fs_total-BLYNK_FS.usedBytes()), fs_total);
#endif
});
#ifdef BLYNK_FS
edgentConsole.addCommand("ls", [](int argc, const char** argv) {
const char* path = (argc < 1) ? "/" : argv[0];
File rootDir = BLYNK_FS.open(path);
while (File f = rootDir.openNextFile()) {
#if defined(BLYNK_USE_SPIFFS) && (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 0, 0))
String fn = f.name();
#else
String fn = f.path();
#endif
MD5Builder md5;
md5.begin();
md5.addStream(f, f.size());
md5.calculate();
String md5str = md5.toString();
edgentConsole.printf("%8d %-24s %s\n",
f.size(), fn.c_str(),
md5str.substring(0,8).c_str());
}
});
edgentConsole.addCommand("rm", [](int argc, const char** argv) {
if (argc < 1) return;
for (int i=0; i<argc; i++) {
const char* fn = argv[i];
if (BLYNK_FS.remove(fn)) {
edgentConsole.printf("Removed %s\n", fn);
} else {
edgentConsole.printf("Removing %s failed\n", fn);
}
}
});
edgentConsole.addCommand("mv", [](int argc, const char** argv) {
if (argc != 2) return;
if (!BLYNK_FS.rename(argv[0], argv[1])) {
edgentConsole.print("Rename failed\n");
}
});
edgentConsole.addCommand("cat", [](int argc, const char** argv) {
if (argc != 1) return;
if (!BLYNK_FS.exists(argv[0])) {
edgentConsole.print("File not found\n");
return;
}
if (File f = BLYNK_FS.open(argv[0], FILE_READ)) {
while (f.available()) {
edgentConsole.print((char)f.read());
}
edgentConsole.print("\n");
} else {
edgentConsole.print("Cannot open file\n");
}
});
edgentConsole.addCommand("echo", [](int argc, const char** argv) {
if (argc != 2) return;
if (File f = BLYNK_FS.open(argv[1], FILE_WRITE)) {
if (!f.print(argv[0])) {
edgentConsole.print("Cannot write file\n");
}
} else {
edgentConsole.print("Cannot open file\n");
}
});
#endif
}
BLYNK_WRITE(InternalPinDBG) {
String cmd = String(param.asStr()) + "\n";
edgentConsole.runCommand((char*)cmd.c_str());
}

View File

@@ -0,0 +1,55 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
*************************************************************
Blynk.Edgent implements:
- Blynk.Inject - Dynamic WiFi credentials provisioning
- Blynk.Air - Over The Air firmware updates
- Device state indication using a physical LED
- Credentials reset using a physical Button
*************************************************************/
/* Fill in information from your Blynk Template here */
/* Read more: https://bit.ly/BlynkInject */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
#define BLYNK_FIRMWARE_VERSION "0.1.0"
#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG
#define APP_DEBUG
// Uncomment your board, or configure a custom board in Settings.h
//#define USE_ESP32_DEV_MODULE
//#define USE_ESP32C3_DEV_MODULE
//#define USE_ESP32S2_DEV_KIT
//#define USE_WROVER_BOARD
//#define USE_TTGO_T7
//#define USE_TTGO_T_OI
#include "BlynkEdgent.h"
void setup()
{
Serial.begin(115200);
delay(100);
BlynkEdgent.begin();
}
void loop() {
BlynkEdgent.run();
}

View File

@@ -0,0 +1,311 @@
#if defined(BOARD_LED_PIN_WS2812)
#include <Adafruit_NeoPixel.h> // Library: https://github.com/adafruit/Adafruit_NeoPixel
Adafruit_NeoPixel rgb = Adafruit_NeoPixel(1, BOARD_LED_PIN_WS2812, NEO_GRB + NEO_KHZ800);
#endif
void indicator_run();
#if !defined(BOARD_LED_BRIGHTNESS)
#define BOARD_LED_BRIGHTNESS 255
#endif
#if defined(BOARD_LED_PIN_WS2812) || defined(BOARD_LED_PIN_R)
#define BOARD_LED_IS_RGB
#endif
#define DIMM(x) ((uint32_t)(x)*(BOARD_LED_BRIGHTNESS)/255)
#define RGB(r,g,b) (DIMM(r) << 16 | DIMM(g) << 8 | DIMM(b) << 0)
#define TO_PWM(x) ((uint32_t)(x)*(BOARD_PWM_MAX)/255)
class Indicator {
public:
enum Colors {
COLOR_BLACK = RGB(0x00, 0x00, 0x00),
COLOR_WHITE = RGB(0xFF, 0xFF, 0xE7),
COLOR_BLUE = RGB(0x0D, 0x36, 0xFF),
COLOR_BLYNK = RGB(0x2E, 0xFF, 0xB9),
COLOR_RED = RGB(0xFF, 0x10, 0x08),
COLOR_MAGENTA = RGB(0xA7, 0x00, 0xFF),
};
Indicator() {
}
void init() {
m_Counter = 0;
initLED();
}
uint32_t run() {
State currState = BlynkState::get();
// Reset counter if indicator state changes
if (m_PrevState != currState) {
m_PrevState = currState;
m_Counter = 0;
}
const long t = millis();
if (g_buttonPressed) {
if (t - g_buttonPressTime > BUTTON_HOLD_TIME_ACTION) { return beatLED(COLOR_WHITE, (int[]){ 100, 100 }); }
if (t - g_buttonPressTime > BUTTON_HOLD_TIME_INDICATION) { return waveLED(COLOR_WHITE, 1000); }
}
switch (currState) {
case MODE_RESET_CONFIG:
case MODE_WAIT_CONFIG: return beatLED(COLOR_BLUE, (int[]){ 50, 500 });
case MODE_CONFIGURING: return beatLED(COLOR_BLUE, (int[]){ 200, 200 });
case MODE_CONNECTING_NET: return beatLED(COLOR_BLYNK, (int[]){ 50, 500 });
case MODE_CONNECTING_CLOUD: return beatLED(COLOR_BLYNK, (int[]){ 100, 100 });
case MODE_RUNNING: return waveLED(COLOR_BLYNK, 5000);
case MODE_OTA_UPGRADE: return beatLED(COLOR_MAGENTA, (int[]){ 50, 50 });
default: return beatLED(COLOR_RED, (int[]){ 80, 100, 80, 1000 } );
}
}
protected:
/*
* LED drivers
*/
#if defined(BOARD_LED_PIN_WS2812) // Addressable, NeoPixel RGB LED
void initLED() {
rgb.begin();
setRGB(COLOR_BLACK);
}
void setRGB(uint32_t color) {
rgb.setPixelColor(0, color);
rgb.show();
}
#elif defined(BOARD_LED_PIN_R) // Normal RGB LED (common anode or common cathode)
void initLED() {
ledcAttachPin(BOARD_LED_PIN_R, BOARD_LEDC_CHANNEL_1);
ledcAttachPin(BOARD_LED_PIN_G, BOARD_LEDC_CHANNEL_2);
ledcAttachPin(BOARD_LED_PIN_B, BOARD_LEDC_CHANNEL_3);
ledcSetup(BOARD_LEDC_CHANNEL_1, BOARD_LEDC_BASE_FREQ, BOARD_LEDC_TIMER_BITS);
ledcSetup(BOARD_LEDC_CHANNEL_2, BOARD_LEDC_BASE_FREQ, BOARD_LEDC_TIMER_BITS);
ledcSetup(BOARD_LEDC_CHANNEL_3, BOARD_LEDC_BASE_FREQ, BOARD_LEDC_TIMER_BITS);
}
void setRGB(uint32_t color) {
uint8_t r = (color & 0xFF0000) >> 16;
uint8_t g = (color & 0x00FF00) >> 8;
uint8_t b = (color & 0x0000FF);
#if BOARD_LED_INVERSE
ledcWrite(BOARD_LEDC_CHANNEL_1, TO_PWM(255 - r));
ledcWrite(BOARD_LEDC_CHANNEL_2, TO_PWM(255 - g));
ledcWrite(BOARD_LEDC_CHANNEL_3, TO_PWM(255 - b));
#else
ledcWrite(BOARD_LEDC_CHANNEL_1, TO_PWM(r));
ledcWrite(BOARD_LEDC_CHANNEL_2, TO_PWM(g));
ledcWrite(BOARD_LEDC_CHANNEL_3, TO_PWM(b));
#endif
}
#elif defined(BOARD_LED_PIN) // Single color LED
void initLED() {
ledcSetup(BOARD_LEDC_CHANNEL_1, BOARD_LEDC_BASE_FREQ, BOARD_LEDC_TIMER_BITS);
ledcAttachPin(BOARD_LED_PIN, BOARD_LEDC_CHANNEL_1);
}
void setLED(uint32_t color) {
#if BOARD_LED_INVERSE
ledcWrite(BOARD_LEDC_CHANNEL_1, TO_PWM(255 - color));
#else
ledcWrite(BOARD_LEDC_CHANNEL_1, TO_PWM(color));
#endif
}
#else
#warning Invalid LED configuration.
void initLED() {
}
void setLED(uint32_t color) {
}
#endif
/*
* Animations
*/
uint32_t skipLED() {
return 20;
}
#if defined(BOARD_LED_IS_RGB)
template<typename T>
uint32_t beatLED(uint32_t onColor, const T& beat) {
const uint8_t cnt = sizeof(beat)/sizeof(beat[0]);
setRGB((m_Counter % 2 == 0) ? onColor : (uint32_t)COLOR_BLACK);
uint32_t next = beat[m_Counter % cnt];
m_Counter = (m_Counter+1) % cnt;
return next;
}
uint32_t waveLED(uint32_t colorMax, unsigned breathePeriod) {
uint8_t redMax = (colorMax & 0xFF0000) >> 16;
uint8_t greenMax = (colorMax & 0x00FF00) >> 8;
uint8_t blueMax = (colorMax & 0x0000FF);
// Brightness will rise from 0 to 128, then fall back to 0
uint8_t brightness = (m_Counter < 128) ? m_Counter : 255 - m_Counter;
// Multiply our three colors by the brightness:
redMax *= ((float)brightness / 128.0);
greenMax *= ((float)brightness / 128.0);
blueMax *= ((float)brightness / 128.0);
// And turn the LED to that color:
setRGB((redMax << 16) | (greenMax << 8) | blueMax);
// This function relies on the 8-bit, unsigned m_Counter rolling over.
m_Counter = (m_Counter+1) % 256;
return breathePeriod / 256;
}
#else
template<typename T>
uint32_t beatLED(uint32_t, const T& beat) {
const uint8_t cnt = sizeof(beat)/sizeof(beat[0]);
setLED((m_Counter % 2 == 0) ? BOARD_LED_BRIGHTNESS : 0);
uint32_t next = beat[m_Counter % cnt];
m_Counter = (m_Counter+1) % cnt;
return next;
}
uint32_t waveLED(uint32_t, unsigned breathePeriod) {
uint32_t brightness = (m_Counter < 128) ? m_Counter : 255 - m_Counter;
setLED(DIMM(brightness*2));
// This function relies on the 8-bit, unsigned m_Counter rolling over.
m_Counter = (m_Counter+1) % 256;
return breathePeriod / 256;
}
#endif
private:
uint8_t m_Counter;
State m_PrevState;
};
Indicator indicator;
/*
* Animation timers
*/
#if defined(USE_TICKER)
#include <Ticker.h>
Ticker blinker;
void indicator_run() {
uint32_t returnTime = indicator.run();
if (returnTime) {
blinker.attach_ms(returnTime, indicator_run);
}
}
void indicator_init() {
indicator.init();
blinker.attach_ms(100, indicator_run);
}
#elif defined(USE_PTHREAD)
#include <pthread.h>
pthread_t blinker;
void* indicator_thread(void*) {
while (true) {
uint32_t returnTime = indicator.run();
returnTime = BlynkMathClamp(returnTime, 1, 10000);
vTaskDelay(returnTime);
}
}
void indicator_init() {
indicator.init();
pthread_create(&blinker, NULL, indicator_thread, NULL);
}
#elif defined(USE_TIMER_ONE)
#include <TimerOne.h>
void indicator_run() {
uint32_t returnTime = indicator.run();
if (returnTime) {
Timer1.initialize(returnTime*1000);
}
}
void indicator_init() {
indicator.init();
Timer1.initialize(100*1000);
Timer1.attachInterrupt(indicator_run);
}
#elif defined(USE_TIMER_THREE)
#include <TimerThree.h>
void indicator_run() {
uint32_t returnTime = indicator.run();
if (returnTime) {
Timer3.initialize(returnTime*1000);
}
}
void indicator_init() {
indicator.init();
Timer3.initialize(100*1000);
Timer3.attachInterrupt(indicator_run);
}
#elif defined(USE_TIMER_FIVE)
#include <Timer5.h> // Library: https://github.com/michael71/Timer5
int indicator_counter = -1;
void indicator_run() {
indicator_counter -= 10;
if (indicator_counter < 0) {
indicator_counter = indicator.run();
}
}
void indicator_init() {
indicator.init();
MyTimer5.begin(1000/10);
MyTimer5.attachInterrupt(indicator_run);
MyTimer5.start();
}
#else
#warning LED indicator needs a functional timer!
void indicator_run() {}
void indicator_init() {}
#endif

View File

@@ -0,0 +1,91 @@
#include <WiFi.h>
#include <Update.h>
#include <HTTPClient.h>
String overTheAirURL;
extern BlynkTimer edgentTimer;
BLYNK_WRITE(InternalPinOTA) {
overTheAirURL = param.asString();
edgentTimer.setTimeout(2000L, [](){
// Start OTA
Blynk.logEvent("sys_ota", "OTA started");
// Disconnect, not to interfere with OTA process
Blynk.disconnect();
BlynkState::set(MODE_OTA_UPGRADE);
});
}
void enterOTA() {
BlynkState::set(MODE_OTA_UPGRADE);
DEBUG_PRINT(String("Firmware update URL: ") + overTheAirURL);
HTTPClient http;
http.begin(overTheAirURL);
const char* headerkeys[] = { "x-MD5" };
http.collectHeaders(headerkeys, sizeof(headerkeys)/sizeof(char*));
int httpCode = http.GET();
if (httpCode != HTTP_CODE_OK) {
DEBUG_PRINT("HTTP response should be 200");
BlynkState::set(MODE_ERROR);
return;
}
int contentLength = http.getSize();
if (contentLength <= 0) {
DEBUG_PRINT("Content-Length not defined");
BlynkState::set(MODE_ERROR);
return;
}
bool canBegin = Update.begin(contentLength);
if (!canBegin) {
DEBUG_PRINT("Not enough space to begin OTA");
BlynkState::set(MODE_ERROR);
return;
}
if (http.hasHeader("x-MD5")) {
String md5 = http.header("x-MD5");
if (md5.length() == 32) {
md5.toLowerCase();
DEBUG_PRINT("Expected MD5: " + md5);
Update.setMD5(md5.c_str());
}
}
#ifdef BLYNK_FS
BLYNK_FS.end();
#endif
Client& client = http.getStream();
int written = Update.writeStream(client);
if (written != contentLength) {
DEBUG_PRINT(String("OTA written ") + written + " / " + contentLength + " bytes");
BlynkState::set(MODE_ERROR);
return;
}
if (!Update.end()) {
DEBUG_PRINT("Error #" + String(Update.getError()));
BlynkState::set(MODE_ERROR);
return;
}
if (!Update.isFinished()) {
DEBUG_PRINT("Update failed.");
BlynkState::set(MODE_ERROR);
return;
}
DEBUG_PRINT("=== Update successfully completed. Rebooting.");
restartMCU();
}

View File

@@ -0,0 +1,53 @@
#ifdef BOARD_BUTTON_PIN
volatile bool g_buttonPressed = false;
volatile uint32_t g_buttonPressTime = -1;
void button_action(void)
{
BlynkState::set(MODE_RESET_CONFIG);
}
void button_change(void)
{
#if BOARD_BUTTON_ACTIVE_LOW
bool buttonState = !digitalRead(BOARD_BUTTON_PIN);
#else
bool buttonState = digitalRead(BOARD_BUTTON_PIN);
#endif
if (buttonState && !g_buttonPressed) {
g_buttonPressTime = millis();
g_buttonPressed = true;
DEBUG_PRINT("Hold the button for 10 seconds to reset configuration...");
} else if (!buttonState && g_buttonPressed) {
g_buttonPressed = false;
uint32_t buttonHoldTime = millis() - g_buttonPressTime;
if (buttonHoldTime >= BUTTON_HOLD_TIME_ACTION) {
button_action();
} else if (buttonHoldTime >= BUTTON_PRESS_TIME_ACTION) {
// User action
}
g_buttonPressTime = -1;
}
}
void button_init()
{
#if BOARD_BUTTON_ACTIVE_LOW
pinMode(BOARD_BUTTON_PIN, INPUT_PULLUP);
#else
pinMode(BOARD_BUTTON_PIN, INPUT_PULLDOWN);
#endif
attachInterrupt(BOARD_BUTTON_PIN, button_change, CHANGE);
}
#else
#define g_buttonPressed false
#define g_buttonPressTime 0
void button_init() {}
#endif

View File

@@ -0,0 +1,133 @@
/*
* Board configuration (see examples below).
*/
#if defined(USE_WROVER_BOARD)
#define BOARD_BUTTON_PIN 15
#define BOARD_BUTTON_ACTIVE_LOW true
#define BOARD_LED_PIN_R 0
#define BOARD_LED_PIN_G 2
#define BOARD_LED_PIN_B 4
#define BOARD_LED_INVERSE false
#define BOARD_LED_BRIGHTNESS 128
#elif defined(USE_TTGO_T7)
#warning "This board does not have a button. Connect a button to gpio0 <> GND"
#define BOARD_BUTTON_PIN 0
#define BOARD_BUTTON_ACTIVE_LOW true
#define BOARD_LED_PIN 19
#define BOARD_LED_INVERSE false
#define BOARD_LED_BRIGHTNESS 64
#elif defined(USE_TTGO_T_OI)
#warning "This board does not have a button. Connect a button to gpio0 <> GND"
#define BOARD_BUTTON_PIN 0
#define BOARD_BUTTON_ACTIVE_LOW true
#define BOARD_LED_PIN 3
#define BOARD_LED_INVERSE false
#define BOARD_LED_BRIGHTNESS 64
#elif defined(USE_ESP32_DEV_MODULE)
#warning "The LED of this board is not configured"
#define BOARD_BUTTON_PIN 0
#define BOARD_BUTTON_ACTIVE_LOW true
#elif defined(USE_ESP32C3_DEV_MODULE)
#define BOARD_BUTTON_PIN 9
#define BOARD_BUTTON_ACTIVE_LOW true
#define BOARD_LED_PIN_WS2812 8
#define BOARD_LED_INVERSE false
#define BOARD_LED_BRIGHTNESS 32
#elif defined(USE_ESP32S2_DEV_KIT)
#define BOARD_BUTTON_PIN 0
#define BOARD_BUTTON_ACTIVE_LOW true
#define BOARD_LED_PIN 19
#define BOARD_LED_INVERSE false
#define BOARD_LED_BRIGHTNESS 128
#else
#warning "Custom board configuration is used"
#define BOARD_BUTTON_PIN 0 // Pin where user button is attached
#define BOARD_BUTTON_ACTIVE_LOW true // true if button is "active-low"
//#define BOARD_LED_PIN 4 // Set LED pin - if you have a single-color LED attached
//#define BOARD_LED_PIN_R 15 // Set R,G,B pins - if your LED is PWM RGB
//#define BOARD_LED_PIN_G 12
//#define BOARD_LED_PIN_B 13
//#define BOARD_LED_PIN_WS2812 4 // Set if your LED is WS2812 RGB
#define BOARD_LED_INVERSE false // true if LED is common anode, false if common cathode
#define BOARD_LED_BRIGHTNESS 64 // 0..255 brightness control
#endif
/*
* Advanced options
*/
#define BUTTON_HOLD_TIME_INDICATION 3000
#define BUTTON_HOLD_TIME_ACTION 10000
#define BUTTON_PRESS_TIME_ACTION 50
#define BOARD_PWM_MAX 1023
#define BOARD_LEDC_CHANNEL_1 1
#define BOARD_LEDC_CHANNEL_2 2
#define BOARD_LEDC_CHANNEL_3 3
#define BOARD_LEDC_TIMER_BITS 10
#define BOARD_LEDC_BASE_FREQ 12000
#if !defined(CONFIG_DEVICE_PREFIX)
#define CONFIG_DEVICE_PREFIX "Blynk"
#endif
#if !defined(CONFIG_AP_URL)
#define CONFIG_AP_URL "blynk.setup"
#endif
#if !defined(CONFIG_DEFAULT_SERVER)
#define CONFIG_DEFAULT_SERVER "blynk.cloud"
#endif
#if !defined(CONFIG_DEFAULT_PORT)
#define CONFIG_DEFAULT_PORT 443
#endif
#define WIFI_CLOUD_MAX_RETRIES 500
#define WIFI_NET_CONNECT_TIMEOUT 50000
#define WIFI_CLOUD_CONNECT_TIMEOUT 50000
#define WIFI_AP_IP IPAddress(192, 168, 4, 1)
#define WIFI_AP_Subnet IPAddress(255, 255, 255, 0)
//#define WIFI_CAPTIVE_PORTAL_ENABLE
//#define USE_TICKER
//#define USE_TIMER_ONE
//#define USE_TIMER_THREE
//#define USE_TIMER_FIVE
#define USE_PTHREAD
#define BLYNK_NO_DEFAULT_BANNER
#if defined(APP_DEBUG)
#define DEBUG_PRINT(...) BLYNK_LOG1(__VA_ARGS__)
#define DEBUG_PRINTF(...) BLYNK_LOG(__VA_ARGS__)
#else
#define DEBUG_PRINT(...)
#define DEBUG_PRINTF(...)
#endif

View File

@@ -0,0 +1,155 @@
extern "C" {
#include "user_interface.h"
void app_loop();
void restartMCU();
}
#include "Settings.h"
#include <BlynkSimpleEsp8266_SSL.h>
#if defined(BLYNK_USE_LITTLEFS)
#include <LittleFS.h>
#define BLYNK_FS LittleFS
#elif defined(BLYNK_USE_SPIFFS)
#if defined(ESP32)
#include <SPIFFS.h>
#elif defined(ESP8266)
#include <FS.h>
#endif
#define BLYNK_FS SPIFFS
#endif
#if defined(BLYNK_FS) && defined(ESP8266)
#define BLYNK_FILE_READ "r"
#define BLYNK_FILE_WRITE "w"
#endif
#ifndef BLYNK_NEW_LIBRARY
#error "Old version of Blynk library is in use. Please replace it with the new one."
#endif
#if !defined(BLYNK_TEMPLATE_NAME) && defined(BLYNK_DEVICE_NAME)
#define BLYNK_TEMPLATE_NAME BLYNK_DEVICE_NAME
#endif
#if !defined(BLYNK_TEMPLATE_ID) || !defined(BLYNK_TEMPLATE_NAME)
#error "Please specify your BLYNK_TEMPLATE_ID and BLYNK_TEMPLATE_NAME"
#endif
#if defined(BLYNK_AUTH_TOKEN)
#error "BLYNK_AUTH_TOKEN is assigned automatically when using Blynk.Edgent, please remove it from the configuration"
#endif
BlynkTimer edgentTimer;
#include "BlynkState.h"
#include "ConfigStore.h"
#include "ResetButton.h"
#include "ConfigMode.h"
#include "Indicator.h"
#include "OTA.h"
#include "Console.h"
inline
void BlynkState::set(State m) {
if (state != m && m < MODE_MAX_VALUE) {
DEBUG_PRINT(String(StateStr[state]) + " => " + StateStr[m]);
state = m;
// You can put your state handling here,
// i.e. implement custom indication
}
}
void printDeviceBanner()
{
#ifdef BLYNK_PRINT
Blynk.printBanner();
BLYNK_PRINT.println("----------------------------------------------------");
BLYNK_PRINT.print(" Device: "); BLYNK_PRINT.println(getWiFiName());
BLYNK_PRINT.print(" Firmware: "); BLYNK_PRINT.println(BLYNK_FIRMWARE_VERSION " (build " __DATE__ " " __TIME__ ")");
if (configStore.getFlag(CONFIG_FLAG_VALID)) {
BLYNK_PRINT.print(" Token: ");
BLYNK_PRINT.println(String(configStore.cloudToken).substring(0,4) +
" - •••• - •••• - ••••");
}
BLYNK_PRINT.print(" Platform: "); BLYNK_PRINT.println(String(BLYNK_INFO_DEVICE) + " @ " + ESP.getCpuFreqMHz() + "MHz");
BLYNK_PRINT.print(" Boot ver: "); BLYNK_PRINT.println(ESP.getBootVersion());
BLYNK_PRINT.print(" SDK: "); BLYNK_PRINT.println(ESP.getSdkVersion());
BLYNK_PRINT.print(" ESP Core: "); BLYNK_PRINT.println(ESP.getCoreVersion());
BLYNK_PRINT.print(" Flash: "); BLYNK_PRINT.println(String(ESP.getFlashChipSize() / 1024) + "K");
BLYNK_PRINT.print(" Free mem: "); BLYNK_PRINT.println(ESP.getFreeHeap());
BLYNK_PRINT.println("----------------------------------------------------");
#endif
}
void runBlynkWithChecks() {
Blynk.run();
if (BlynkState::get() == MODE_RUNNING) {
if (!Blynk.connected()) {
if (WiFi.status() == WL_CONNECTED) {
BlynkState::set(MODE_CONNECTING_CLOUD);
} else {
BlynkState::set(MODE_CONNECTING_NET);
}
}
}
}
class Edgent {
public:
void begin()
{
#ifdef BLYNK_FS
BLYNK_FS.begin();
#endif
indicator_init();
button_init();
config_init();
printDeviceBanner();
console_init();
if (configStore.getFlag(CONFIG_FLAG_VALID)) {
BlynkState::set(MODE_CONNECTING_NET);
} else if (config_load_blnkopt()) {
DEBUG_PRINT("Firmware is preprovisioned");
BlynkState::set(MODE_CONNECTING_NET);
} else {
BlynkState::set(MODE_WAIT_CONFIG);
}
if (!String(BLYNK_TEMPLATE_ID).startsWith("TMPL") ||
!strlen(BLYNK_TEMPLATE_NAME)
) {
DEBUG_PRINT("Invalid configuration of TEMPLATE_ID / TEMPLATE_NAME");
while (true) { delay(100); }
}
}
void run() {
app_loop();
switch (BlynkState::get()) {
case MODE_WAIT_CONFIG:
case MODE_CONFIGURING: enterConfigMode(); break;
case MODE_CONNECTING_NET: enterConnectNet(); break;
case MODE_CONNECTING_CLOUD: enterConnectCloud(); break;
case MODE_RUNNING: runBlynkWithChecks(); break;
case MODE_OTA_UPGRADE: enterOTA(); break;
case MODE_SWITCH_TO_STA: enterSwitchToSTA(); break;
case MODE_RESET_CONFIG: enterResetConfig(); break;
default: enterError(); break;
}
}
} BlynkEdgent;
void app_loop() {
edgentTimer.run();
edgentConsole.run();
}

View File

@@ -0,0 +1,40 @@
enum State {
MODE_WAIT_CONFIG,
MODE_CONFIGURING,
MODE_CONNECTING_NET,
MODE_CONNECTING_CLOUD,
MODE_RUNNING,
MODE_OTA_UPGRADE,
MODE_SWITCH_TO_STA,
MODE_RESET_CONFIG,
MODE_ERROR,
MODE_MAX_VALUE
};
#if defined(APP_DEBUG)
const char* StateStr[MODE_MAX_VALUE+1] = {
"WAIT_CONFIG",
"CONFIGURING",
"CONNECTING_NET",
"CONNECTING_CLOUD",
"RUNNING",
"OTA_UPGRADE",
"SWITCH_TO_STA",
"RESET_CONFIG",
"ERROR",
"INIT"
};
#endif
namespace BlynkState
{
volatile State state = MODE_MAX_VALUE;
State get() { return state; }
bool is (State m) { return (state == m); }
void set(State m);
};

View File

@@ -0,0 +1,504 @@
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
#include <DNSServer.h>
#ifndef BLYNK_FS
const char* config_form = R"html(
<!DOCTYPE HTML>
<html>
<head>
<title>WiFi setup</title>
<style>
body {
background-color: #fcfcfc;
box-sizing: border-box;
}
body, input {
font-family: Roboto, sans-serif;
font-weight: 400;
font-size: 16px;
}
.centered {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 20px;
background-color: #ccc;
border-radius: 4px;
}
td { padding:0 0 0 5px; }
label { white-space:nowrap; }
input { width: 20em; }
input[name="port"] { width: 5em; }
input[type="submit"], img { margin: auto; display: block; width: 30%; }
</style>
</head>
<body>
<div class="centered">
<form method="get" action="config">
<table>
<tr><td><label for="ssid">WiFi SSID:</label></td> <td><input type="text" name="ssid" length=64 required="required"></td></tr>
<tr><td><label for="pass">Password:</label></td> <td><input type="text" name="pass" length=64></td></tr>
<tr><td><label for="blynk">Auth token:</label></td><td><input type="text" name="blynk" placeholder="a0b1c2d..." pattern="[-_a-zA-Z0-9]{32}" maxlength="32" required="required"></td></tr>
<tr><td><label for="host">Host:</label></td> <td><input type="text" name="host" value="blynk.cloud" length=64></td></tr>
<tr><td><label for="port_ssl">Port:</label></td> <td><input type="number" name="port_ssl" value="443" min="1" max="65535"></td></tr>
</table><br/>
<input type="submit" value="Apply">
</form>
</div>
</body>
</html>
)html";
#endif
ESP8266WebServer server(80);
ESP8266HTTPUpdateServer httpUpdater;
DNSServer dnsServer;
const byte DNS_PORT = 53;
static int connectNetRetries = WIFI_CLOUD_MAX_RETRIES;
static int connectBlynkRetries = WIFI_CLOUD_MAX_RETRIES;
void restartMCU() {
ESP.restart();
ESP.reset();
while(1) {};
}
static
String encodeUniquePart(uint32_t n, unsigned len)
{
static constexpr char alphabet[] = { "0W8N4Y1HP5DF9K6JM3C2UA7R" };
static constexpr int base = sizeof(alphabet)-1;
char buf[16] = { 0, };
char prev = 0;
for (unsigned i = 0; i < len; n /= base) {
char c = alphabet[n % base];
if (c == prev) {
c = alphabet[(n+1) % base];
}
prev = buf[i++] = c;
}
return String(buf);
}
static
String getWiFiName(bool withPrefix = true)
{
byte mac[6] = { 0, };
WiFi.macAddress(mac);
uint32_t unique = 0;
for (int i=0; i<4; i++) {
unique = BlynkCRC32(&mac, sizeof(mac), unique);
}
String devUnique = encodeUniquePart(unique, 4);
String devPrefix = CONFIG_DEVICE_PREFIX;
String devName = String(BLYNK_TEMPLATE_NAME).substring(0, 31-6-devPrefix.length());
if (withPrefix) {
return devPrefix + " " + devName + "-" + devUnique;
} else {
return devName + "-" + devUnique;
}
}
static inline
String macToString(byte mac[6]) {
char buff[20];
snprintf(buff, sizeof(buff), "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(buff);
}
static inline
const char* wifiSecToStr(uint8_t t) {
switch (t) {
case ENC_TYPE_NONE: return "OPEN";
case ENC_TYPE_WEP: return "WEP";
case ENC_TYPE_TKIP: return "WPA";
case ENC_TYPE_CCMP: return "WPA2";
case ENC_TYPE_AUTO: return "WPA+WPA2";
default: return "unknown";
}
}
static
String getWiFiMacAddress() {
return WiFi.macAddress();
}
static
String getWiFiApBSSID() {
return WiFi.softAPmacAddress();
}
static
String getWiFiNetworkSSID() {
return WiFi.SSID();
}
static
String getWiFiNetworkBSSID() {
return WiFi.BSSIDstr();
}
void enterConfigMode()
{
WiFi.mode(WIFI_OFF);
delay(100);
WiFi.mode(WIFI_AP_STA);
WiFi.softAPConfig(WIFI_AP_IP, WIFI_AP_IP, WIFI_AP_Subnet);
WiFi.softAP(getWiFiName().c_str());
delay(500);
IPAddress myIP = WiFi.softAPIP();
if (myIP == (uint32_t)0)
{
config_set_last_error(BLYNK_PROV_ERR_INTERNAL);
BlynkState::set(MODE_ERROR);
return;
}
// Set up DNS Server
dnsServer.setTTL(300); // Time-to-live 300s
dnsServer.setErrorReplyCode(DNSReplyCode::ServerFailure); // Return code for non-accessible domains
#ifdef WIFI_CAPTIVE_PORTAL_ENABLE
dnsServer.start(DNS_PORT, "*", WiFi.softAPIP()); // Point all to our IP
server.onNotFound(handleRoot);
#else
dnsServer.start(DNS_PORT, CONFIG_AP_URL, WiFi.softAPIP());
DEBUG_PRINT(String("AP URL: ") + CONFIG_AP_URL);
#endif
httpUpdater.setup(&server, "/update");
#ifndef BLYNK_FS
server.on("/", []() {
server.send(200, "text/html", config_form);
});
#endif
server.on("/config", []() {
DEBUG_PRINT("Applying configuration...");
String ssid = server.arg("ssid");
String ssidManual = server.arg("ssidManual");
String pass = server.arg("pass");
if (ssidManual != "") {
ssid = ssidManual;
}
String token = server.arg("blynk");
String host = server.arg("host");
String port = server.arg("port_ssl");
String ip = server.arg("ip");
String mask = server.arg("mask");
String gw = server.arg("gw");
String dns = server.arg("dns");
String dns2 = server.arg("dns2");
bool forceSave = server.arg("save").toInt();
String content;
DEBUG_PRINT(String("WiFi SSID: ") + ssid + " Pass: " + pass);
DEBUG_PRINT(String("Blynk cloud: ") + token + " @ " + host + ":" + port);
if (token.length() == 32 && ssid.length() > 0) {
configStore = configDefault;
CopyString(ssid, configStore.wifiSSID);
CopyString(pass, configStore.wifiPass);
CopyString(token, configStore.cloudToken);
if (host.length()) {
CopyString(host, configStore.cloudHost);
}
if (port.length()) {
configStore.cloudPort = port.toInt();
}
IPAddress addr;
if (ip.length() && addr.fromString(ip)) {
configStore.staticIP = addr;
configStore.setFlag(CONFIG_FLAG_STATIC_IP, true);
} else {
configStore.setFlag(CONFIG_FLAG_STATIC_IP, false);
}
if (mask.length() && addr.fromString(mask)) {
configStore.staticMask = addr;
}
if (gw.length() && addr.fromString(gw)) {
configStore.staticGW = addr;
}
if (dns.length() && addr.fromString(dns)) {
configStore.staticDNS = addr;
}
if (dns2.length() && addr.fromString(dns2)) {
configStore.staticDNS2 = addr;
}
if (forceSave) {
configStore.setFlag(CONFIG_FLAG_VALID, true);
config_save();
content = R"json({"status":"ok","msg":"Configuration saved"})json";
} else {
content = R"json({"status":"ok","msg":"Trying to connect..."})json";
}
server.send(200, "application/json", content);
connectNetRetries = connectBlynkRetries = 1;
BlynkState::set(MODE_SWITCH_TO_STA);
} else {
DEBUG_PRINT("Configuration invalid");
content = R"json({"status":"error","msg":"Configuration invalid"})json";
server.send(500, "application/json", content);
}
});
server.on("/board_info.json", []() {
// Configuring starts with board info request (may impact indication)
BlynkState::set(MODE_CONFIGURING);
DEBUG_PRINT("Sending board info...");
const char* tmpl = BLYNK_TEMPLATE_ID;
char buff[512];
snprintf(buff, sizeof(buff),
R"json({"board":"%s","tmpl_id":"%s","fw_type":"%s","fw_ver":"%s","ssid":"%s","bssid":"%s","mac":"%s","last_error":%d,"wifi_scan":true,"static_ip":true})json",
BLYNK_TEMPLATE_NAME,
tmpl ? tmpl : "Unknown",
BLYNK_FIRMWARE_TYPE,
BLYNK_FIRMWARE_VERSION,
getWiFiName().c_str(),
getWiFiApBSSID().c_str(),
getWiFiMacAddress().c_str(),
configStore.last_error
);
server.send(200, "application/json", buff);
});
server.on("/wifi_scan.json", []() {
DEBUG_PRINT("Scanning networks...");
int wifi_nets = WiFi.scanNetworks(true, true);
const uint32_t t = millis();
while (wifi_nets < 0 &&
millis() - t < 20000)
{
delay(20);
wifi_nets = WiFi.scanComplete();
}
DEBUG_PRINT(String("Found networks: ") + wifi_nets);
if (wifi_nets > 0) {
// Sort networks
int indices[wifi_nets];
for (int i = 0; i < wifi_nets; i++) {
indices[i] = i;
}
for (int i = 0; i < wifi_nets; i++) {
for (int j = i + 1; j < wifi_nets; j++) {
if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i])) {
std::swap(indices[i], indices[j]);
}
}
}
wifi_nets = BlynkMin(15, wifi_nets); // Show top 15 networks
// TODO: skip empty names
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
server.send(200, "application/json", "[\n");
char buff[256];
for (int i = 0; i < wifi_nets; i++){
int id = indices[i];
snprintf(buff, sizeof(buff),
R"json( {"ssid":"%s","bssid":"%s","rssi":%i,"sec":"%s","ch":%i,"hidden":%d})json",
WiFi.SSID(id).c_str(),
WiFi.BSSIDstr(id).c_str(),
WiFi.RSSI(id),
wifiSecToStr(WiFi.encryptionType(id)),
WiFi.channel(id),
WiFi.isHidden(id)
);
server.sendContent(buff);
if (i != wifi_nets-1) server.sendContent(",\n");
}
WiFi.scanDelete();
server.sendContent("\n]");
} else {
server.send(200, "application/json", "[]");
}
});
server.on("/reset", []() {
BlynkState::set(MODE_RESET_CONFIG);
server.send(200, "application/json", R"json({"status":"ok","msg":"Configuration reset"})json");
});
server.on("/reboot", []() {
restartMCU();
});
#ifdef BLYNK_FS
server.serveStatic("/img", BLYNK_FS, "/img");
server.serveStatic("/", BLYNK_FS, "/index.html");
#endif
server.begin();
while (BlynkState::is(MODE_WAIT_CONFIG) || BlynkState::is(MODE_CONFIGURING)) {
delay(10);
dnsServer.processNextRequest();
server.handleClient();
app_loop();
if (BlynkState::is(MODE_CONFIGURING) && WiFi.softAPgetStationNum() == 0) {
BlynkState::set(MODE_WAIT_CONFIG);
}
}
server.stop();
}
void enterConnectNet() {
BlynkState::set(MODE_CONNECTING_NET);
DEBUG_PRINT(String("Connecting to WiFi: ") + configStore.wifiSSID);
WiFi.mode(WIFI_STA);
String hostname = getWiFiName();
hostname.replace(" ", "-");
WiFi.hostname(hostname.c_str());
if (configStore.getFlag(CONFIG_FLAG_STATIC_IP)) {
if (!WiFi.config(configStore.staticIP,
configStore.staticGW,
configStore.staticMask,
configStore.staticDNS,
configStore.staticDNS2)
) {
DEBUG_PRINT("Failed to configure Static IP");
config_set_last_error(BLYNK_PROV_ERR_CONFIG);
BlynkState::set(MODE_ERROR);
return;
}
}
if (!WiFi.begin(configStore.wifiSSID, configStore.wifiPass)) {
config_set_last_error(BLYNK_PROV_ERR_CONFIG);
BlynkState::set(MODE_ERROR);
return;
}
unsigned long timeoutMs = millis() + WIFI_NET_CONNECT_TIMEOUT;
while ((timeoutMs > millis()) && (WiFi.status() != WL_CONNECTED))
{
delay(10);
app_loop();
if (!BlynkState::is(MODE_CONNECTING_NET)) {
WiFi.disconnect();
return;
}
}
if (WiFi.status() == WL_CONNECTED) {
IPAddress localip = WiFi.localIP();
if (configStore.getFlag(CONFIG_FLAG_STATIC_IP)) {
BLYNK_LOG_IP("Using Static IP: ", localip);
} else {
BLYNK_LOG_IP("Using Dynamic IP: ", localip);
}
connectNetRetries = WIFI_CLOUD_MAX_RETRIES;
BlynkState::set(MODE_CONNECTING_CLOUD);
} else if (--connectNetRetries <= 0) {
config_set_last_error(BLYNK_PROV_ERR_NETWORK);
BlynkState::set(MODE_ERROR);
}
}
void enterConnectCloud() {
BlynkState::set(MODE_CONNECTING_CLOUD);
Blynk.config(configStore.cloudToken, configStore.cloudHost, configStore.cloudPort);
Blynk.connect(0);
unsigned long timeoutMs = millis() + WIFI_CLOUD_CONNECT_TIMEOUT;
while ((timeoutMs > millis()) &&
(WiFi.status() == WL_CONNECTED) &&
(!Blynk.isTokenInvalid()) &&
(Blynk.connected() == false))
{
delay(10);
Blynk.run();
app_loop();
if (!BlynkState::is(MODE_CONNECTING_CLOUD)) {
Blynk.disconnect();
return;
}
}
if (millis() > timeoutMs) {
DEBUG_PRINT("Timeout");
}
if (Blynk.isTokenInvalid()) {
config_set_last_error(BLYNK_PROV_ERR_TOKEN);
BlynkState::set(MODE_WAIT_CONFIG); // TODO: retry after timeout
} else if (WiFi.status() != WL_CONNECTED) {
BlynkState::set(MODE_CONNECTING_NET);
} else if (Blynk.connected()) {
BlynkState::set(MODE_RUNNING);
connectBlynkRetries = WIFI_CLOUD_MAX_RETRIES;
if (!configStore.getFlag(CONFIG_FLAG_VALID)) {
configStore.last_error = BLYNK_PROV_ERR_NONE;
configStore.setFlag(CONFIG_FLAG_VALID, true);
config_save();
Blynk.sendInternal("meta", "set", "Hotspot Name", getWiFiName());
}
} else if (--connectBlynkRetries <= 0) {
config_set_last_error(BLYNK_PROV_ERR_CLOUD);
BlynkState::set(MODE_ERROR);
}
}
void enterSwitchToSTA() {
BlynkState::set(MODE_SWITCH_TO_STA);
DEBUG_PRINT("Switching to STA...");
delay(1000);
WiFi.mode(WIFI_OFF);
delay(100);
WiFi.mode(WIFI_STA);
BlynkState::set(MODE_CONNECTING_NET);
}
void enterError() {
BlynkState::set(MODE_ERROR);
unsigned long timeoutMs = millis() + 10000;
while (timeoutMs > millis() || g_buttonPressed)
{
delay(10);
app_loop();
if (!BlynkState::is(MODE_ERROR)) {
return;
}
}
DEBUG_PRINT("Restarting after error.");
delay(10);
restartMCU();
}

View File

@@ -0,0 +1,147 @@
#define CONFIG_FLAG_VALID 0x01
#define CONFIG_FLAG_STATIC_IP 0x02
#define BLYNK_PROV_ERR_NONE 0 // All good
#define BLYNK_PROV_ERR_CONFIG 700 // Invalid config from app (malformed token,etc)
#define BLYNK_PROV_ERR_NETWORK 701 // Could not connect to the router
#define BLYNK_PROV_ERR_CLOUD 702 // Could not connect to the cloud
#define BLYNK_PROV_ERR_TOKEN 703 // Invalid token error (after connection)
#define BLYNK_PROV_ERR_INTERNAL 704 // Other issues (i.e. hardware failure)
struct ConfigStore {
uint32_t magic;
char version[15];
uint8_t flags;
char wifiSSID[34];
char wifiPass[64];
char cloudToken[34];
char cloudHost[34];
uint16_t cloudPort;
uint32_t staticIP;
uint32_t staticMask;
uint32_t staticGW;
uint32_t staticDNS;
uint32_t staticDNS2;
int last_error;
void setFlag(uint8_t mask, bool value) {
if (value) {
flags |= mask;
} else {
flags &= ~mask;
}
}
bool getFlag(uint8_t mask) {
return (flags & mask) == mask;
}
} __attribute__((packed));
ConfigStore configStore;
const ConfigStore configDefault = {
0x626C6E6B,
BLYNK_FIRMWARE_VERSION,
0x00,
"",
"",
"invalid token",
CONFIG_DEFAULT_SERVER,
CONFIG_DEFAULT_PORT,
0,
BLYNK_PROV_ERR_NONE
};
template<typename T, int size>
void CopyString(const String& s, T(&arr)[size]) {
s.toCharArray(arr, size);
}
static bool config_load_blnkopt()
{
static const char blnkopt[] = "blnkopt\0"
BLYNK_PARAM_KV("ssid" , BLYNK_PARAM_PLACEHOLDER_64
BLYNK_PARAM_PLACEHOLDER_64
BLYNK_PARAM_PLACEHOLDER_64
BLYNK_PARAM_PLACEHOLDER_64)
BLYNK_PARAM_KV("host" , CONFIG_DEFAULT_SERVER)
BLYNK_PARAM_KV("port" , BLYNK_TOSTRING(CONFIG_DEFAULT_PORT))
"\0";
BlynkParam prov(blnkopt+8, sizeof(blnkopt)-8-2);
BlynkParam::iterator ssid = prov["ssid"];
BlynkParam::iterator pass = prov["pass"];
BlynkParam::iterator auth = prov["auth"];
BlynkParam::iterator host = prov["host"];
BlynkParam::iterator port = prov["port"];
if (!(ssid.isValid() && auth.isValid())) {
return false;
}
// reset to defaut before loading values from blnkopt
configStore = configDefault;
if (ssid.isValid()) { CopyString(ssid.asStr(), configStore.wifiSSID); }
if (pass.isValid()) { CopyString(pass.asStr(), configStore.wifiPass); }
if (auth.isValid()) { CopyString(auth.asStr(), configStore.cloudToken); }
if (host.isValid()) { CopyString(host.asStr(), configStore.cloudHost); }
if (port.isValid()) { configStore.cloudPort = port.asInt(); }
return true;
}
#include <EEPROM.h>
#define EEPROM_CONFIG_START 0
void config_load()
{
memset(&configStore, 0, sizeof(configStore));
EEPROM.get(EEPROM_CONFIG_START, configStore);
if (configStore.magic != configDefault.magic) {
DEBUG_PRINT("Using default config.");
configStore = configDefault;
return;
}
}
bool config_save()
{
EEPROM.put(EEPROM_CONFIG_START, configStore);
EEPROM.commit();
DEBUG_PRINT("Configuration stored to flash");
return true;
}
bool config_init()
{
EEPROM.begin(sizeof(ConfigStore));
config_load();
return true;
}
void enterResetConfig()
{
DEBUG_PRINT("Resetting configuration!");
configStore = configDefault;
config_save();
BlynkState::set(MODE_WAIT_CONFIG);
}
void config_set_last_error(int error) {
// Only set error if not provisioned
if (!configStore.getFlag(CONFIG_FLAG_VALID)) {
configStore = configDefault;
configStore.last_error = error;
BLYNK_LOG2("Last error code: ", error);
config_save();
}
}

View File

@@ -0,0 +1,209 @@
#include <Blynk/BlynkConsole.h>
BlynkConsole edgentConsole;
void console_init()
{
#ifdef BLYNK_PRINT
edgentConsole.begin(BLYNK_PRINT);
#endif
edgentConsole.print("\n>");
edgentConsole.addCommand("reboot", []() {
edgentConsole.print(R"json({"status":"OK","msg":"rebooting wifi module"})json" "\n");
delay(100);
restartMCU();
});
edgentConsole.addCommand("config", [](int argc, const char** argv) {
if (argc < 1 || 0 == strcmp(argv[0], "start")) {
BlynkState::set(MODE_WAIT_CONFIG);
} else if (0 == strcmp(argv[0], "erase")) {
BlynkState::set(MODE_RESET_CONFIG);
}
});
edgentConsole.addCommand("devinfo", []() {
edgentConsole.printf(
R"json({"name":"%s","board":"%s","tmpl_id":"%s","fw_type":"%s","fw_ver":"%s"})json" "\n",
getWiFiName().c_str(),
BLYNK_TEMPLATE_NAME,
BLYNK_TEMPLATE_ID,
BLYNK_FIRMWARE_TYPE,
BLYNK_FIRMWARE_VERSION
);
});
edgentConsole.addCommand("connect", [](int argc, const char** argv) {
if (argc < 2) {
edgentConsole.print(R"json({"status":"error","msg":"invalid arguments. expected: <auth> <ssid> <pass>"})json" "\n");
return;
}
String auth = argv[0];
String ssid = argv[1];
String pass = (argc >= 3) ? argv[2] : "";
if (auth.length() != 32) {
edgentConsole.print(R"json({"status":"error","msg":"invalid token size"})json" "\n");
return;
}
edgentConsole.print(R"json({"status":"OK","msg":"trying to connect..."})json" "\n");
configStore = configDefault;
CopyString(ssid, configStore.wifiSSID);
CopyString(pass, configStore.wifiPass);
CopyString(auth, configStore.cloudToken);
BlynkState::set(MODE_SWITCH_TO_STA);
});
edgentConsole.addCommand("wifi", [](int argc, const char* argv[]) {
if (argc < 1 || 0 == strcmp(argv[0], "show")) {
edgentConsole.printf(
"mac:%s ip:%s (%s [%s] %ddBm)\n",
getWiFiMacAddress().c_str(),
WiFi.localIP().toString().c_str(),
getWiFiNetworkSSID().c_str(),
getWiFiNetworkBSSID().c_str(),
WiFi.RSSI()
);
} else if (0 == strcmp(argv[0], "scan")) {
int found = WiFi.scanNetworks();
for (int i = 0; i < found; i++) {
bool current = (WiFi.SSID(i) == WiFi.SSID());
edgentConsole.printf(
"%s %s [%s] %s ch:%d rssi:%d\n",
(current ? "*" : " "), WiFi.SSID(i).c_str(),
macToString(WiFi.BSSID(i)).c_str(),
wifiSecToStr(WiFi.encryptionType(i)),
WiFi.channel(i), WiFi.RSSI(i)
);
}
WiFi.scanDelete();
}
});
edgentConsole.addCommand("firmware", [](int argc, const char** argv) {
if (argc < 1 || 0 == strcmp(argv[0], "info")) {
unsigned sketchSize = ESP.getSketchSize();
unsigned partSize = sketchSize + ESP.getFreeSketchSpace();
edgentConsole.printf(" Version: %s (build %s)\n", BLYNK_FIRMWARE_VERSION, __DATE__ " " __TIME__);
edgentConsole.printf(" Type: %s\n", BLYNK_FIRMWARE_TYPE);
edgentConsole.printf(" Platform: %s\n", BLYNK_INFO_DEVICE);
edgentConsole.printf(" SDK: %s\n", ESP.getSdkVersion());
edgentConsole.printf(" ESP Core: %s\n", ESP.getCoreVersion().c_str());
edgentConsole.printf(" App size: %dK (%d%%)\n", sketchSize/1024, (sketchSize*100)/partSize);
edgentConsole.printf(" App MD5: %s\n", ESP.getSketchMD5().c_str());
}
});
edgentConsole.addCommand("status", [](int argc, const char** argv) {
const uint64_t t = micros64() / 1000000;
unsigned secs = t % BLYNK_SECS_PER_MIN;
unsigned mins = (t / BLYNK_SECS_PER_MIN) % BLYNK_SECS_PER_MIN;
unsigned hrs = (t % BLYNK_SECS_PER_DAY) / BLYNK_SECS_PER_HOUR;
unsigned days = t / BLYNK_SECS_PER_DAY;
uint32_t heap_free; uint16_t heap_max;
uint8_t heap_frag;
ESP.getHeapStats(&heap_free, &heap_max, &heap_frag);
edgentConsole.printf(" Uptime: %dd %dh %dm %ds\n", days, hrs, mins, secs);
edgentConsole.printf(" Reset reason: %s\n", ESP.getResetReason().c_str());
edgentConsole.printf(" Flash: %dK\n", ESP.getFlashChipSize() / 1024);
edgentConsole.printf(" Stack unused: %d\n", ESP.getFreeContStack());
edgentConsole.printf(" Heap free: %d / %d\n", heap_free, heap_max);
edgentConsole.printf(" fragment: %d\n", heap_frag);
edgentConsole.printf(" max alloc: %d\n", ESP.getMaxFreeBlockSize());
#ifdef BLYNK_FS
FSInfo fs_info;
BLYNK_FS.info(fs_info);
edgentConsole.printf(" FS free: %d / %d\n", (fs_info.totalBytes-fs_info.usedBytes), fs_info.totalBytes);
#endif
});
#ifdef BLYNK_FS
edgentConsole.addCommand("ls", [](int argc, const char** argv) {
const char* path = (argc < 1) ? "/" : argv[0];
Dir dir = BLYNK_FS.openDir(path);
while (dir.next()) {
File f = dir.openFile(BLYNK_FILE_READ);
MD5Builder md5;
md5.begin();
md5.addStream(f, f.size());
md5.calculate();
String md5str = md5.toString();
edgentConsole.printf("%8d %-24s %s\n",
f.size(), dir.fileName().c_str(),
md5str.substring(0,8).c_str());
}
});
edgentConsole.addCommand("rm", [](int argc, const char** argv) {
if (argc < 1) return;
for (int i=0; i<argc; i++) {
const char* fn = argv[i];
if (BLYNK_FS.remove(fn)) {
edgentConsole.printf("Removed %s\n", fn);
} else {
edgentConsole.printf("Removing %s failed\n", fn);
}
}
});
edgentConsole.addCommand("mv", [](int argc, const char** argv) {
if (argc != 2) return;
if (!BLYNK_FS.rename(argv[0], argv[1])) {
edgentConsole.print("Rename failed\n");
}
});
edgentConsole.addCommand("cat", [](int argc, const char** argv) {
if (argc != 1) return;
if (!BLYNK_FS.exists(argv[0])) {
edgentConsole.print("File not found\n");
return;
}
if (File f = BLYNK_FS.open(argv[0], BLYNK_FILE_READ)) {
while (f.available()) {
edgentConsole.print((char)f.read());
}
edgentConsole.print("\n");
} else {
edgentConsole.print("Cannot open file\n");
}
});
edgentConsole.addCommand("echo", [](int argc, const char** argv) {
if (argc != 2) return;
if (File f = BLYNK_FS.open(argv[1], BLYNK_FILE_WRITE)) {
if (!f.print(argv[0])) {
edgentConsole.print("Cannot write file\n");
}
} else {
edgentConsole.print("Cannot open file\n");
}
});
#endif
}
BLYNK_WRITE(InternalPinDBG) {
String cmd = String(param.asStr()) + "\n";
edgentConsole.runCommand((char*)cmd.c_str());
}

View File

@@ -0,0 +1,53 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
*************************************************************
Blynk.Edgent implements:
- Blynk.Inject - Dynamic WiFi credentials provisioning
- Blynk.Air - Over The Air firmware updates
- Device state indication using a physical LED
- Credentials reset using a physical Button
*************************************************************/
/* Fill in information from your Blynk Template here */
/* Read more: https://bit.ly/BlynkInject */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
#define BLYNK_FIRMWARE_VERSION "0.1.0"
#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG
#define APP_DEBUG
// Uncomment your board, or configure a custom board in Settings.h
//#define USE_SPARKFUN_BLYNK_BOARD
//#define USE_NODE_MCU_BOARD
//#define USE_WITTY_CLOUD_BOARD
//#define USE_WEMOS_D1_MINI
#include "BlynkEdgent.h"
void setup()
{
Serial.begin(115200);
delay(100);
BlynkEdgent.begin();
}
void loop() {
BlynkEdgent.run();
}

View File

@@ -0,0 +1,306 @@
#if defined(BOARD_LED_PIN_WS2812)
#include <Adafruit_NeoPixel.h> // Library: https://github.com/adafruit/Adafruit_NeoPixel
Adafruit_NeoPixel rgb = Adafruit_NeoPixel(1, BOARD_LED_PIN_WS2812, NEO_GRB + NEO_KHZ800);
#endif
void indicator_run();
#if !defined(BOARD_LED_BRIGHTNESS)
#define BOARD_LED_BRIGHTNESS 255
#endif
#if defined(BOARD_LED_PIN_WS2812) || defined(BOARD_LED_PIN_R)
#define BOARD_LED_IS_RGB
#endif
#define DIMM(x) ((uint32_t)(x)*(BOARD_LED_BRIGHTNESS)/255)
#define RGB(r,g,b) (DIMM(r) << 16 | DIMM(g) << 8 | DIMM(b) << 0)
#define TO_PWM(x) ((uint32_t)(x)*(BOARD_PWM_MAX)/255)
class Indicator {
public:
enum Colors {
COLOR_BLACK = RGB(0x00, 0x00, 0x00),
COLOR_WHITE = RGB(0xFF, 0xFF, 0xE7),
COLOR_BLUE = RGB(0x0D, 0x36, 0xFF),
COLOR_BLYNK = RGB(0x2E, 0xFF, 0xB9),
COLOR_RED = RGB(0xFF, 0x10, 0x08),
COLOR_MAGENTA = RGB(0xA7, 0x00, 0xFF),
};
Indicator() {
}
void init() {
m_Counter = 0;
initLED();
}
uint32_t run() {
State currState = BlynkState::get();
// Reset counter if indicator state changes
if (m_PrevState != currState) {
m_PrevState = currState;
m_Counter = 0;
}
const long t = millis();
if (g_buttonPressed) {
if (t - g_buttonPressTime > BUTTON_HOLD_TIME_ACTION) { return beatLED(COLOR_WHITE, (int[]){ 100, 100 }); }
if (t - g_buttonPressTime > BUTTON_HOLD_TIME_INDICATION) { return waveLED(COLOR_WHITE, 1000); }
}
switch (currState) {
case MODE_RESET_CONFIG:
case MODE_WAIT_CONFIG: return beatLED(COLOR_BLUE, (int[]){ 50, 500 });
case MODE_CONFIGURING: return beatLED(COLOR_BLUE, (int[]){ 200, 200 });
case MODE_CONNECTING_NET: return beatLED(COLOR_BLYNK, (int[]){ 50, 500 });
case MODE_CONNECTING_CLOUD: return beatLED(COLOR_BLYNK, (int[]){ 100, 100 });
case MODE_RUNNING: return waveLED(COLOR_BLYNK, 5000);
case MODE_OTA_UPGRADE: return beatLED(COLOR_MAGENTA, (int[]){ 50, 50 });
default: return beatLED(COLOR_RED, (int[]){ 80, 100, 80, 1000 } );
}
}
protected:
/*
* LED drivers
*/
#if defined(BOARD_LED_PIN_WS2812) // Addressable, NeoPixel RGB LED
void initLED() {
rgb.begin();
setRGB(COLOR_BLACK);
}
void setRGB(uint32_t color) {
rgb.setPixelColor(0, color);
rgb.show();
}
#elif defined(BOARD_LED_PIN_R) // Normal RGB LED (common anode or common cathode)
void initLED() {
pinMode(BOARD_LED_PIN_R, OUTPUT);
pinMode(BOARD_LED_PIN_G, OUTPUT);
pinMode(BOARD_LED_PIN_B, OUTPUT);
}
void setRGB(uint32_t color) {
uint8_t r = (color & 0xFF0000) >> 16;
uint8_t g = (color & 0x00FF00) >> 8;
uint8_t b = (color & 0x0000FF);
#if BOARD_LED_INVERSE
analogWrite(BOARD_LED_PIN_R, TO_PWM(255 - r));
analogWrite(BOARD_LED_PIN_G, TO_PWM(255 - g));
analogWrite(BOARD_LED_PIN_B, TO_PWM(255 - b));
#else
analogWrite(BOARD_LED_PIN_R, TO_PWM(r));
analogWrite(BOARD_LED_PIN_G, TO_PWM(g));
analogWrite(BOARD_LED_PIN_B, TO_PWM(b));
#endif
}
#elif defined(BOARD_LED_PIN) // Single color LED
void initLED() {
pinMode(BOARD_LED_PIN, OUTPUT);
}
void setLED(uint32_t color) {
#if BOARD_LED_INVERSE
analogWrite(BOARD_LED_PIN, TO_PWM(255 - color));
#else
analogWrite(BOARD_LED_PIN, TO_PWM(color));
#endif
}
#else
#warning Invalid LED configuration.
void initLED() {
}
void setLED(uint32_t color) {
}
#endif
/*
* Animations
*/
uint32_t skipLED() {
return 20;
}
#if defined(BOARD_LED_IS_RGB)
template<typename T>
uint32_t beatLED(uint32_t onColor, const T& beat) {
const uint8_t cnt = sizeof(beat)/sizeof(beat[0]);
setRGB((m_Counter % 2 == 0) ? onColor : (uint32_t)COLOR_BLACK);
uint32_t next = beat[m_Counter % cnt];
m_Counter = (m_Counter+1) % cnt;
return next;
}
uint32_t waveLED(uint32_t colorMax, unsigned breathePeriod) {
uint8_t redMax = (colorMax & 0xFF0000) >> 16;
uint8_t greenMax = (colorMax & 0x00FF00) >> 8;
uint8_t blueMax = (colorMax & 0x0000FF);
// Brightness will rise from 0 to 128, then fall back to 0
uint8_t brightness = (m_Counter < 128) ? m_Counter : 255 - m_Counter;
// Multiply our three colors by the brightness:
redMax *= ((float)brightness / 128.0);
greenMax *= ((float)brightness / 128.0);
blueMax *= ((float)brightness / 128.0);
// And turn the LED to that color:
setRGB((redMax << 16) | (greenMax << 8) | blueMax);
// This function relies on the 8-bit, unsigned m_Counter rolling over.
m_Counter = (m_Counter+1) % 256;
return breathePeriod / 256;
}
#else
template<typename T>
uint32_t beatLED(uint32_t, const T& beat) {
const uint8_t cnt = sizeof(beat)/sizeof(beat[0]);
setLED((m_Counter % 2 == 0) ? BOARD_LED_BRIGHTNESS : 0);
uint32_t next = beat[m_Counter % cnt];
m_Counter = (m_Counter+1) % cnt;
return next;
}
uint32_t waveLED(uint32_t, unsigned breathePeriod) {
uint32_t brightness = (m_Counter < 128) ? m_Counter : 255 - m_Counter;
setLED(DIMM(brightness*2));
// This function relies on the 8-bit, unsigned m_Counter rolling over.
m_Counter = (m_Counter+1) % 256;
return breathePeriod / 256;
}
#endif
private:
uint8_t m_Counter;
State m_PrevState;
};
Indicator indicator;
/*
* Animation timers
*/
#if defined(USE_TICKER)
#include <Ticker.h>
Ticker blinker;
void indicator_run() {
uint32_t returnTime = indicator.run();
if (returnTime) {
blinker.attach_ms(returnTime, indicator_run);
}
}
void indicator_init() {
indicator.init();
blinker.attach_ms(100, indicator_run);
}
#elif defined(USE_PTHREAD)
#include <pthread.h>
pthread_t blinker;
void* indicator_thread(void*) {
while (true) {
uint32_t returnTime = indicator.run();
returnTime = BlynkMathClamp(returnTime, 1, 10000);
vTaskDelay(returnTime);
}
}
void indicator_init() {
indicator.init();
pthread_create(&blinker, NULL, indicator_thread, NULL);
}
#elif defined(USE_TIMER_ONE)
#include <TimerOne.h>
void indicator_run() {
uint32_t returnTime = indicator.run();
if (returnTime) {
Timer1.initialize(returnTime*1000);
}
}
void indicator_init() {
indicator.init();
Timer1.initialize(100*1000);
Timer1.attachInterrupt(indicator_run);
}
#elif defined(USE_TIMER_THREE)
#include <TimerThree.h>
void indicator_run() {
uint32_t returnTime = indicator.run();
if (returnTime) {
Timer3.initialize(returnTime*1000);
}
}
void indicator_init() {
indicator.init();
Timer3.initialize(100*1000);
Timer3.attachInterrupt(indicator_run);
}
#elif defined(USE_TIMER_FIVE)
#include <Timer5.h> // Library: https://github.com/michael71/Timer5
int indicator_counter = -1;
void indicator_run() {
indicator_counter -= 10;
if (indicator_counter < 0) {
indicator_counter = indicator.run();
}
}
void indicator_init() {
indicator.init();
MyTimer5.begin(1000/10);
MyTimer5.attachInterrupt(indicator_run);
MyTimer5.start();
}
#else
#warning LED indicator needs a functional timer!
void indicator_run() {}
void indicator_init() {}
#endif

View File

@@ -0,0 +1,266 @@
#define OTA_FATAL(...) { BLYNK_LOG1(__VA_ARGS__); delay(1000); restartMCU(); }
#define USE_SSL
String overTheAirURL;
extern BlynkTimer edgentTimer;
BLYNK_WRITE(InternalPinOTA) {
overTheAirURL = param.asString();
edgentTimer.setTimeout(2000L, [](){
// Start OTA
Blynk.logEvent("sys_ota", "OTA started");
// Disconnect, not to interfere with OTA process
Blynk.disconnect();
BlynkState::set(MODE_OTA_UPGRADE);
});
}
#if defined(ESP32)
#include <Update.h>
#include <WiFiClientSecure.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <time.h>
#endif
#if defined(USE_SSL) && defined(ESP8266)
WiFiClient* connectSSL(const String& host, const int port)
{
WiFiUDP::stopAll();
WiFiClient::stopAll();
time_t now = time(nullptr);
if (time(nullptr) < 100000) {
// Synchronize time useing SNTP. This is necessary to verify that
// the TLS certificates offered by the server are currently valid
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
while (now < 100000) {
delay(100);
now = time(nullptr);
}
}
// Reuse Secure WIFI Client on ESP8266
//WiFiClientSecure* clientSSL = &_blynkWifiClient;
WiFiClientSecure* clientSSL = new WiFiClientSecure();
clientSSL->setTrustAnchors(&BlynkCert);
if (!clientSSL->connect(host.c_str(), port)) {
OTA_FATAL(F("Connection failed"));
}
return clientSSL;
}
#elif defined(USE_SSL) && defined(ESP32)
WiFiClient* connectSSL(const String& host, const int port)
{
WiFiUDP::stopAll();
WiFiClient::stopAll();
WiFiClientSecure* clientSSL = new WiFiClientSecure();
clientSSL->setCACert(BLYNK_DEFAULT_ROOT_CA);
if (clientSSL->connect(host.c_str(), port)) {
DEBUG_PRINT(F("Certificate OK"));
} else {
OTA_FATAL(F("Secure connection failed"));
}
return clientSSL;
}
#endif
WiFiClient* connectTCP(const String& host, const int port)
{
WiFiUDP::stopAll();
WiFiClient::stopAll();
WiFiClient* clientTCP = new WiFiClient();
if (!clientTCP->connect(host.c_str(), port)) {
OTA_FATAL(F("Client not connected"));
}
return clientTCP;
}
bool parseURL(String url, String& protocol, String& host, int& port, String& uri)
{
int index = url.indexOf(':');
if(index < 0) {
return false;
}
protocol = url.substring(0, index);
url.remove(0, (index + 3)); // remove protocol part
index = url.indexOf('/');
String server = url.substring(0, index);
url.remove(0, index); // remove server part
index = server.indexOf(':');
if(index >= 0) {
host = server.substring(0, index); // hostname
port = server.substring(index + 1).toInt(); // port
} else {
host = server;
if (protocol == "http") {
port = 80;
} else if (protocol == "https") {
port = 443;
}
}
if (url.length()) {
uri = url;
} else {
uri = "/";
}
return true;
}
void enterOTA() {
BlynkState::set(MODE_OTA_UPGRADE);
// Disconnect, not to interfere with OTA process
Blynk.disconnect();
String protocol, host, url;
int port;
DEBUG_PRINT(String("OTA: ") + overTheAirURL);
if (!parseURL(overTheAirURL, protocol, host, port, url)) {
OTA_FATAL(F("Cannot parse URL"));
}
DEBUG_PRINT(String("Connecting to ") + host + ":" + port);
Client* client = NULL;
if (protocol == "http") {
client = connectTCP(host, port);
#ifdef USE_SSL
} else if (protocol == "https") {
client = connectSSL(host, port);
#endif
} else {
OTA_FATAL(String("Unsupported protocol: ") + protocol);
}
client->print(String("GET ") + url + " HTTP/1.0\r\n"
+ "Host: " + host + "\r\n"
+ "Connection: keep-alive\r\n"
+ "\r\n");
uint32_t timeout = millis();
while (client->connected() && !client->available()) {
if (millis() - timeout > 10000L) {
OTA_FATAL("Response timeout");
}
delay(10);
}
// Collect headers
String md5;
int contentLength = 0;
while (client->available()) {
String line = client->readStringUntil('\n');
line.trim();
//DEBUG_PRINT(line); // Uncomment this to show response headers
line.toLowerCase();
if (line.startsWith("content-length:")) {
contentLength = line.substring(line.lastIndexOf(':') + 1).toInt();
} else if (line.startsWith("x-md5:")) {
md5 = line.substring(line.lastIndexOf(':') + 1);
} else if (line.length() == 0) {
break;
}
delay(10);
}
if (contentLength <= 0) {
OTA_FATAL("Content-Length not defined");
}
bool canBegin = Update.begin(contentLength);
if (!canBegin) {
#ifdef BLYNK_PRINT
Update.printError(BLYNK_PRINT);
#endif
OTA_FATAL("OTA begin failed");
}
if (md5.length()) {
md5.trim();
md5.toLowerCase();
DEBUG_PRINT(String("Expected MD5: ") + md5);
if(!Update.setMD5(md5.c_str())) {
OTA_FATAL("Cannot set MD5");
}
}
DEBUG_PRINT("Flashing...");
// The next loop does approx. the same thing as Update.writeStream(http) or Update.write(http)
int written = 0;
int prevProgress = 0;
uint8_t buff[256];
while (client->connected() && written < contentLength) {
delay(10);
timeout = millis();
while (client->connected() && !client->available()) {
delay(1);
if (millis() - timeout > 10000L) {
OTA_FATAL("Timeout");
}
}
int len = client->read(buff, sizeof(buff));
if (len <= 0) continue;
Update.write(buff, len);
written += len;
const int progress = (written*100)/contentLength;
if (progress - prevProgress >= 10 || progress == 100) {
#ifdef BLYNK_PRINT
BLYNK_PRINT.print(String("\r ") + progress + "%");
#endif
prevProgress = progress;
}
}
#ifdef BLYNK_PRINT
BLYNK_PRINT.println();
#endif
client->stop();
if (written != contentLength) {
#ifdef BLYNK_PRINT
Update.printError(BLYNK_PRINT);
#endif
OTA_FATAL(String("Write failed. Written ") + written + " / " + contentLength + " bytes");
}
if (!Update.end()) {
#ifdef BLYNK_PRINT
Update.printError(BLYNK_PRINT);
#endif
OTA_FATAL(F("Update not ended"));
}
if (!Update.isFinished()) {
OTA_FATAL(F("Update not finished"));
}
DEBUG_PRINT("=== Update successfully completed. Rebooting.");
restartMCU();
}

View File

@@ -0,0 +1,54 @@
#ifdef BOARD_BUTTON_PIN
volatile bool g_buttonPressed = false;
volatile uint32_t g_buttonPressTime = -1;
void button_action(void)
{
BlynkState::set(MODE_RESET_CONFIG);
}
IRAM_ATTR
void button_change(void)
{
#if BOARD_BUTTON_ACTIVE_LOW
bool buttonState = !digitalRead(BOARD_BUTTON_PIN);
#else
bool buttonState = digitalRead(BOARD_BUTTON_PIN);
#endif
if (buttonState && !g_buttonPressed) {
g_buttonPressTime = millis();
g_buttonPressed = true;
DEBUG_PRINT("Hold the button for 10 seconds to reset configuration...");
} else if (!buttonState && g_buttonPressed) {
g_buttonPressed = false;
uint32_t buttonHoldTime = millis() - g_buttonPressTime;
if (buttonHoldTime >= BUTTON_HOLD_TIME_ACTION) {
button_action();
} else if (buttonHoldTime >= BUTTON_PRESS_TIME_ACTION) {
// User action
}
g_buttonPressTime = -1;
}
}
void button_init()
{
#if BOARD_BUTTON_ACTIVE_LOW
pinMode(BOARD_BUTTON_PIN, INPUT_PULLUP);
#else
pinMode(BOARD_BUTTON_PIN, INPUT);
#endif
attachInterrupt(BOARD_BUTTON_PIN, button_change, CHANGE);
}
#else
#define g_buttonPressed false
#define g_buttonPressTime 0
void button_init() {}
#endif

View File

@@ -0,0 +1,101 @@
/*
* Board configuration (see examples below).
*/
#if defined(USE_NODE_MCU_BOARD) || defined(USE_WEMOS_D1_MINI)
#if defined(USE_WEMOS_D1_MINI)
#warning "This board does not have a button. Connect a button to gpio0 <> GND"
#endif
#define BOARD_BUTTON_PIN 0
#define BOARD_BUTTON_ACTIVE_LOW true
#define BOARD_LED_PIN 2
#define BOARD_LED_INVERSE true
#define BOARD_LED_BRIGHTNESS 255
#elif defined(USE_SPARKFUN_BLYNK_BOARD)
#define BOARD_BUTTON_PIN 0
#define BOARD_BUTTON_ACTIVE_LOW true
#define BOARD_LED_PIN_WS2812 4
#define BOARD_LED_BRIGHTNESS 64
#elif defined(USE_WITTY_CLOUD_BOARD)
#define BOARD_BUTTON_PIN 4
#define BOARD_BUTTON_ACTIVE_LOW true
#define BOARD_LED_PIN_R 15
#define BOARD_LED_PIN_G 12
#define BOARD_LED_PIN_B 13
#define BOARD_LED_INVERSE false
#define BOARD_LED_BRIGHTNESS 64
#else
#warning "Custom board configuration is used"
#define BOARD_BUTTON_PIN 0 // Pin where user button is attached
#define BOARD_BUTTON_ACTIVE_LOW true // true if button is "active-low"
//#define BOARD_LED_PIN 4 // Set LED pin - if you have a single-color LED attached
//#define BOARD_LED_PIN_R 15 // Set R,G,B pins - if your LED is PWM RGB
//#define BOARD_LED_PIN_G 12
//#define BOARD_LED_PIN_B 13
//#define BOARD_LED_PIN_WS2812 4 // Set if your LED is WS2812 RGB
#define BOARD_LED_INVERSE false // true if LED is common anode, false if common cathode
#define BOARD_LED_BRIGHTNESS 64 // 0..255 brightness control
#endif
/*
* Advanced options
*/
#define BUTTON_HOLD_TIME_INDICATION 3000
#define BUTTON_HOLD_TIME_ACTION 10000
#define BUTTON_PRESS_TIME_ACTION 50
#define BOARD_PWM_MAX 1023
#if !defined(CONFIG_DEVICE_PREFIX)
#define CONFIG_DEVICE_PREFIX "Blynk"
#endif
#if !defined(CONFIG_AP_URL)
#define CONFIG_AP_URL "blynk.setup"
#endif
#if !defined(CONFIG_DEFAULT_SERVER)
#define CONFIG_DEFAULT_SERVER "blynk.cloud"
#endif
#if !defined(CONFIG_DEFAULT_PORT)
#define CONFIG_DEFAULT_PORT 443
#endif
#define WIFI_CLOUD_MAX_RETRIES 500
#define WIFI_NET_CONNECT_TIMEOUT 50000
#define WIFI_CLOUD_CONNECT_TIMEOUT 50000
#define WIFI_AP_IP IPAddress(192, 168, 4, 1)
#define WIFI_AP_Subnet IPAddress(255, 255, 255, 0)
//#define WIFI_CAPTIVE_PORTAL_ENABLE
#define USE_TICKER
//#define USE_TIMER_ONE
//#define USE_TIMER_THREE
//#define USE_TIMER_FIVE
//#define USE_PTHREAD
#define BLYNK_NO_DEFAULT_BANNER
#if defined(APP_DEBUG)
#define DEBUG_PRINT(...) BLYNK_LOG1(__VA_ARGS__)
#define DEBUG_PRINTF(...) BLYNK_LOG(__VA_ARGS__)
#else
#define DEBUG_PRINT(...)
#define DEBUG_PRINTF(...)
#endif

View File

@@ -0,0 +1,6 @@
/*
* Arduino 33 IoT and Arduino MKR1010 are no longer supported by Blynk.Edgent.
* Blynk now offers a better solution for Dual-MCU boards. Please use Blynk.NCP:
* https://github.com/blynkkk/BlynkNcpExample
*
*/

View File

@@ -0,0 +1,97 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
*************************************************************
NOTE: This example requires the connectivity module on your board to be
flashed using Blynk.NCP firmware.
The easiest way to install the NCP firmware is using this PlatformIO project:
https://github.com/blynkkk/BlynkNcpExample
*************************************************************/
/* Fill in information from your Blynk Template here */
/* Read more: https://bit.ly/BlynkInject */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
/* The firmware version of the Primary MCU (used for OTA updates) */
#define BLYNK_FIRMWARE_VERSION "0.1.0"
// Debug output
#define BLYNK_PRINT Serial
// Redefine NCP connection port settings, if needed
//#define BLYNK_NCP_SERIAL Serial1
//#define BLYNK_NCP_BAUD 2000000
#include <BlynkEdgentNCP.h>
BlynkTimer timer;
BLYNK_CONNECTED() {
BLYNK_LOG("Connected to Blynk 🙌");
}
BLYNK_DISCONNECTED() {
BLYNK_LOG("Blynk disconnected");
}
void setup() {
Serial.begin(115200);
Serial.println();
// Give Serial Monitor some time to connect
delay(3000);
BLYNK_LOG("Main firmware: %s", BLYNK_FIRMWARE_VERSION);
BLYNK_LOG("Build: %s", __DATE__ " " __TIME__);
// Initialize the Blynk.NCP hardware
if (Blynk.initNCP()) {
String ver = Blynk.getNcpVersion();
BLYNK_LOG("Blynk.NCP firmware: %s", ver.c_str());
} else {
BLYNK_LOG("Cannot communicate to Blynk.NCP");
BLYNK_LOG(" Please ensure you have flashed your board with the Blynk.NCP firmware, before running this example.");
BLYNK_LOG(" See: https://github.com/blynkkk/BlynkNcpExample");
return;
}
// Print state changes
Blynk.onStateChange([]() {
BLYNK_LOG("State: %s", Blynk.getStateString());
});
// Set config mode timeout to 30 minutes, for testing purposes
Blynk.setConfigTimeout(30*60);
// White labeling (use this ONLY if you have a branded Blynk App)
//Blynk.setVendorPrefix("MyCompany");
//Blynk.setVendorServer("dashboard.mycompany.com");
// Product setup
Blynk.begin(BLYNK_TEMPLATE_ID, BLYNK_TEMPLATE_NAME);
// Publish some data periodically
timer.setInterval(1000, []() {
Blynk.virtualWrite(V0, millis() / 1000);
});
}
void loop() {
timer.run();
Blynk.run();
delay(1);
}

View File

@@ -0,0 +1,128 @@
extern "C" {
void app_loop();
void restartMCU();
}
#include "Settings.h"
#include <BlynkSimpleWioTerminal_SSL.h>
#ifndef BLYNK_NEW_LIBRARY
#error "Old version of Blynk library is in use. Please replace it with the new one."
#endif
#if !defined(BLYNK_TEMPLATE_NAME) && defined(BLYNK_DEVICE_NAME)
#define BLYNK_TEMPLATE_NAME BLYNK_DEVICE_NAME
#endif
#if !defined(BLYNK_TEMPLATE_ID) || !defined(BLYNK_TEMPLATE_NAME)
#error "Please specify your BLYNK_TEMPLATE_ID and BLYNK_TEMPLATE_NAME"
#endif
#if defined(BLYNK_AUTH_TOKEN)
#error "BLYNK_AUTH_TOKEN is assigned automatically when using Blynk.Edgent, please remove it from the configuration"
#endif
BlynkTimer edgentTimer;
#include "BlynkState.h"
#include "ConfigStore.h"
#include "ResetButton.h"
#include "ConfigMode.h"
#include "Indicator.h"
#include "OTA.h"
#include "Console.h"
inline
void BlynkState::set(State m) {
if (state != m && m < MODE_MAX_VALUE) {
DEBUG_PRINT(String(StateStr[state]) + " => " + StateStr[m]);
state = m;
// You can put your state handling here,
// i.e. implement custom indication
}
}
void printDeviceBanner()
{
#ifdef BLYNK_PRINT
Blynk.printBanner();
BLYNK_PRINT.println("----------------------------------------------------");
BLYNK_PRINT.print(" Device: "); BLYNK_PRINT.println(getWiFiName());
BLYNK_PRINT.print(" Firmware: "); BLYNK_PRINT.println(BLYNK_FIRMWARE_VERSION " (build " __DATE__ " " __TIME__ ")");
if (configStore.getFlag(CONFIG_FLAG_VALID)) {
BLYNK_PRINT.print(" Token: ");
BLYNK_PRINT.println(String(configStore.cloudToken).substring(0,4) +
" - •••• - •••• - ••••");
}
BLYNK_PRINT.print(" Platform: "); BLYNK_PRINT.println(String(BLYNK_INFO_DEVICE) + " @ " + (F_CPU/1000000) + "MHz");
BLYNK_PRINT.print(" WiFi FW: "); BLYNK_PRINT.println(rpc_system_version());
BLYNK_PRINT.println("----------------------------------------------------");
#endif
}
void runBlynkWithChecks() {
Blynk.run();
if (BlynkState::get() == MODE_RUNNING) {
if (!Blynk.connected()) {
if (WiFi.status() == WL_CONNECTED) {
BlynkState::set(MODE_CONNECTING_CLOUD);
} else {
BlynkState::set(MODE_CONNECTING_NET);
}
}
}
}
class Edgent {
public:
void begin()
{
//indicator_init();
button_init();
config_init();
printDeviceBanner();
console_init();
if (configStore.getFlag(CONFIG_FLAG_VALID)) {
BlynkState::set(MODE_CONNECTING_NET);
} else if (config_load_blnkopt()) {
DEBUG_PRINT("Firmware is preprovisioned");
BlynkState::set(MODE_CONNECTING_NET);
} else {
BlynkState::set(MODE_WAIT_CONFIG);
}
if (!String(BLYNK_TEMPLATE_ID).startsWith("TMPL") ||
!strlen(BLYNK_TEMPLATE_NAME)
) {
DEBUG_PRINT("Invalid configuration of TEMPLATE_ID / TEMPLATE_NAME");
while (true) { delay(100); }
}
}
void run() {
app_loop();
switch (BlynkState::get()) {
case MODE_WAIT_CONFIG:
case MODE_CONFIGURING: enterConfigMode(); break;
case MODE_CONNECTING_NET: enterConnectNet(); break;
case MODE_CONNECTING_CLOUD: enterConnectCloud(); break;
case MODE_RUNNING: runBlynkWithChecks(); break;
case MODE_OTA_UPGRADE: enterOTA(); break;
case MODE_SWITCH_TO_STA: enterSwitchToSTA(); break;
case MODE_RESET_CONFIG: enterResetConfig(); break;
default: enterError(); break;
}
}
} BlynkEdgent;
void app_loop() {
edgentTimer.run();
edgentConsole.run();
}

View File

@@ -0,0 +1,40 @@
enum State {
MODE_WAIT_CONFIG,
MODE_CONFIGURING,
MODE_CONNECTING_NET,
MODE_CONNECTING_CLOUD,
MODE_RUNNING,
MODE_OTA_UPGRADE,
MODE_SWITCH_TO_STA,
MODE_RESET_CONFIG,
MODE_ERROR,
MODE_MAX_VALUE
};
#if defined(APP_DEBUG)
const char* StateStr[MODE_MAX_VALUE+1] = {
"WAIT_CONFIG",
"CONFIGURING",
"CONNECTING_NET",
"CONNECTING_CLOUD",
"RUNNING",
"OTA_UPGRADE",
"SWITCH_TO_STA",
"RESET_CONFIG",
"ERROR",
"INIT"
};
#endif
namespace BlynkState
{
volatile State state = MODE_MAX_VALUE;
State get() { return state; }
bool is (State m) { return (state == m); }
void set(State m);
};

View File

@@ -0,0 +1,480 @@
#include <WiFiClient.h>
#include <WebServer.h>
#include <DNSServer.h>
const char* config_form = R"html(
<!DOCTYPE HTML>
<html>
<head>
<title>WiFi setup</title>
<style>
body {
background-color: #fcfcfc;
box-sizing: border-box;
}
body, input {
font-family: Roboto, sans-serif;
font-weight: 400;
font-size: 16px;
}
.centered {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 20px;
background-color: #ccc;
border-radius: 4px;
}
td { padding:0 0 0 5px; }
label { white-space:nowrap; }
input { width: 20em; }
input[name="port"] { width: 5em; }
input[type="submit"], img { margin: auto; display: block; width: 30%; }
</style>
</head>
<body>
<div class="centered">
<form method="get" action="config">
<table>
<tr><td><label for="ssid">WiFi SSID:</label></td> <td><input type="text" name="ssid" length=64 required="required"></td></tr>
<tr><td><label for="pass">Password:</label></td> <td><input type="text" name="pass" length=64></td></tr>
<tr><td><label for="blynk">Auth token:</label></td><td><input type="text" name="blynk" placeholder="a0b1c2d..." pattern="[-_a-zA-Z0-9]{32}" maxlength="32" required="required"></td></tr>
<tr><td><label for="host">Host:</label></td> <td><input type="text" name="host" value="blynk.cloud" length=64></td></tr>
<tr><td><label for="port_ssl">Port:</label></td> <td><input type="number" name="port_ssl" value="443" min="1" max="65535"></td></tr>
</table><br/>
<input type="submit" value="Apply">
</form>
</div>
</body>
</html>
)html";
WebServer server(80);
DNSServer dnsServer;
const byte DNS_PORT = 53;
static int connectNetRetries = WIFI_CLOUD_MAX_RETRIES;
static int connectBlynkRetries = WIFI_CLOUD_MAX_RETRIES;
void restartMCU() {
NVIC_SystemReset();
while(1) {};
}
static
String encodeUniquePart(uint32_t n, unsigned len)
{
static constexpr char alphabet[] = { "0W8N4Y1HP5DF9K6JM3C2UA7R" };
static constexpr int base = sizeof(alphabet)-1;
char buf[16] = { 0, };
char prev = 0;
for (unsigned i = 0; i < len; n /= base) {
char c = alphabet[n % base];
if (c == prev) {
c = alphabet[(n+1) % base];
}
prev = buf[i++] = c;
}
return String(buf);
}
static
String getWiFiName(bool withPrefix = true)
{
static byte mac[6] = { 0, };
static bool needMac = true;
if (needMac) {
WiFi.macAddress(mac);
needMac = false;
}
uint32_t unique = 0;
for (int i=0; i<4; i++) {
unique = BlynkCRC32(&mac, sizeof(mac), unique);
}
String devUnique = encodeUniquePart(unique, 4);
String devPrefix = CONFIG_DEVICE_PREFIX;
String devName = String(BLYNK_TEMPLATE_NAME).substring(0, 31-6-devPrefix.length());
if (withPrefix) {
return devPrefix + " " + devName + "-" + devUnique;
} else {
return devName + "-" + devUnique;
}
}
static
String getWiFiMacAddress() {
return WiFi.macAddress();
}
static
String getWiFiApBSSID() {
return WiFi.softAPmacAddress();
}
static
String getWiFiNetworkSSID() {
return WiFi.SSID();
}
static
String getWiFiNetworkBSSID() {
return WiFi.BSSIDstr();
}
String scanNetworks()
{
DEBUG_PRINT("Scanning networks...");
int wifi_nets = WiFi.scanNetworks(true, true);
const uint32_t t = millis();
while (wifi_nets < 0 &&
millis() - t < 20000)
{
delay(20);
wifi_nets = WiFi.scanComplete();
}
DEBUG_PRINT(String("Found networks: ") + wifi_nets);
if (wifi_nets > 0) {
// Sort networks
int indices[wifi_nets];
for (int i = 0; i < wifi_nets; i++) {
indices[i] = i;
}
for (int i = 0; i < wifi_nets; i++) {
for (int j = i + 1; j < wifi_nets; j++) {
if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i])) {
std::swap(indices[i], indices[j]);
}
}
}
wifi_nets = BlynkMin(15, wifi_nets); // Show top 15 networks
// TODO: skip empty names
String result = "[\n";
char buff[256];
for (int i = 0; i < wifi_nets; i++){
int id = indices[i];
const char* sec;
switch (WiFi.encryptionType(id)) {
case WIFI_AUTH_WEP: sec = "WEP"; break;
case WIFI_AUTH_WPA_PSK: sec = "WPA/PSK"; break;
case WIFI_AUTH_WPA2_PSK: sec = "WPA2/PSK"; break;
case WIFI_AUTH_WPA_WPA2_PSK: sec = "WPA/WPA2/PSK"; break;
case WIFI_AUTH_OPEN: sec = "OPEN"; break;
default: sec = "unknown"; break;
}
snprintf(buff, sizeof(buff),
R"json( {"ssid":"%s","bssid":"%s","rssi":%i,"sec":"%s","ch":%i})json",
WiFi.SSID(id).c_str(),
WiFi.BSSIDstr(id).c_str(),
WiFi.RSSI(id),
sec,
WiFi.channel(id)
);
result += buff;
if (i != wifi_nets-1) result += ",\n";
}
return result + "\n]";
} else {
return "[]";
}
}
void handleRoot() {
server.send(200, "text/html", config_form);
}
String networks = "[]";
void enterConfigMode()
{
networks = scanNetworks();
WiFi.mode(WIFI_OFF);
delay(100);
WiFi.mode(WIFI_AP);
delay(2000);
WiFi.softAPConfig(WIFI_AP_IP, WIFI_AP_IP, WIFI_AP_Subnet);
WiFi.softAP(getWiFiName().c_str());
delay(500);
// Set up DNS Server
dnsServer.setTTL(300); // Time-to-live 300s
dnsServer.setErrorReplyCode(DNSReplyCode::ServerFailure); // Return code for non-accessible domains
#ifdef WIFI_CAPTIVE_PORTAL_ENABLE
dnsServer.start(DNS_PORT, "*", WiFi.softAPIP()); // Point all to our IP
server.onNotFound(handleRoot);
#else
dnsServer.start(DNS_PORT, CONFIG_AP_URL, WiFi.softAPIP());
DEBUG_PRINT(String("AP URL: ") + CONFIG_AP_URL);
#endif
server.on("/config", []() {
DEBUG_PRINT("Applying configuration...");
String ssid = server.arg("ssid");
String ssidManual = server.arg("ssidManual");
String pass = server.arg("pass");
if (ssidManual != "") {
ssid = ssidManual;
}
String token = server.arg("blynk");
String host = server.arg("host");
String port = server.arg("port_ssl");
String ip = server.arg("ip");
String mask = server.arg("mask");
String gw = server.arg("gw");
String dns = server.arg("dns");
String dns2 = server.arg("dns2");
bool forceSave = server.arg("save").toInt();
String content;
DEBUG_PRINT(String("WiFi SSID: ") + ssid + " Pass: " + pass);
DEBUG_PRINT(String("Blynk cloud: ") + token + " @ " + host + ":" + port);
if (token.length() == 32 && ssid.length() > 0) {
configStore = configDefault;
CopyString(ssid, configStore.wifiSSID);
CopyString(pass, configStore.wifiPass);
CopyString(token, configStore.cloudToken);
if (host.length()) {
CopyString(host, configStore.cloudHost);
}
if (port.length()) {
configStore.cloudPort = port.toInt();
}
IPAddress addr;
if (ip.length() && addr.fromString(ip)) {
configStore.staticIP = addr;
configStore.setFlag(CONFIG_FLAG_STATIC_IP, true);
} else {
configStore.setFlag(CONFIG_FLAG_STATIC_IP, false);
}
if (mask.length() && addr.fromString(mask)) {
configStore.staticMask = addr;
}
if (gw.length() && addr.fromString(gw)) {
configStore.staticGW = addr;
}
if (dns.length() && addr.fromString(dns)) {
configStore.staticDNS = addr;
}
if (dns2.length() && addr.fromString(dns2)) {
configStore.staticDNS2 = addr;
}
if (forceSave) {
configStore.setFlag(CONFIG_FLAG_VALID, true);
config_save();
content = R"json({"status":"ok","msg":"Configuration saved"})json";
} else {
content = R"json({"status":"ok","msg":"Trying to connect..."})json";
}
server.send(200, "application/json", content);
connectNetRetries = connectBlynkRetries = 1;
BlynkState::set(MODE_SWITCH_TO_STA);
} else {
DEBUG_PRINT("Configuration invalid");
content = R"json({"status":"error","msg":"Configuration invalid"})json";
server.send(500, "application/json", content);
}
});
server.on("/board_info.json", []() {
// Configuring starts with board info request (may impact indication)
BlynkState::set(MODE_CONFIGURING);
DEBUG_PRINT("Sending board info...");
const char* tmpl = BLYNK_TEMPLATE_ID;
char buff[512];
snprintf(buff, sizeof(buff),
R"json({"board":"%s","tmpl_id":"%s","fw_type":"%s","fw_ver":"%s","ssid":"%s","bssid":"%s","mac":"%s","last_error":%d,"wifi_scan":true,"static_ip":true,"5ghz":true})json",
BLYNK_TEMPLATE_NAME,
tmpl ? tmpl : "Unknown",
BLYNK_FIRMWARE_TYPE,
BLYNK_FIRMWARE_VERSION,
getWiFiName().c_str(),
getWiFiApBSSID().c_str(),
getWiFiMacAddress().c_str(),
configStore.last_error
);
server.send(200, "application/json", buff);
});
server.on("/wifi_scan.json", []() {
server.send(200, "application/json", networks);
});
server.on("/reset", []() {
BlynkState::set(MODE_RESET_CONFIG);
server.send(200, "application/json", R"json({"status":"ok","msg":"Configuration reset"})json");
});
server.on("/reboot", []() {
restartMCU();
});
server.begin();
while (BlynkState::is(MODE_WAIT_CONFIG) || BlynkState::is(MODE_CONFIGURING)) {
delay(10);
dnsServer.processNextRequest();
server.handleClient();
app_loop();
if (BlynkState::is(MODE_CONFIGURING) && WiFi.softAPgetStationNum() == 0) {
BlynkState::set(MODE_WAIT_CONFIG);
}
}
server.stop();
}
void enterConnectNet() {
BlynkState::set(MODE_CONNECTING_NET);
DEBUG_PRINT(String("Connecting to WiFi: ") + configStore.wifiSSID);
String hostname = getWiFiName();
hostname.replace(" ", "-");
WiFi.setHostname(hostname.c_str());
if (configStore.getFlag(CONFIG_FLAG_STATIC_IP)) {
if (!WiFi.config(configStore.staticIP,
configStore.staticGW,
configStore.staticMask,
configStore.staticDNS,
configStore.staticDNS2)
) {
DEBUG_PRINT("Failed to configure Static IP");
config_set_last_error(BLYNK_PROV_ERR_CONFIG);
BlynkState::set(MODE_ERROR);
return;
}
}
if (strlen(configStore.wifiPass)) {
WiFi.begin(configStore.wifiSSID, configStore.wifiPass);
} else {
WiFi.begin(configStore.wifiSSID);
}
unsigned long timeoutMs = millis() + WIFI_NET_CONNECT_TIMEOUT;
while ((timeoutMs > millis()) && (WiFi.status() != WL_CONNECTED))
{
delay(10);
app_loop();
if (!BlynkState::is(MODE_CONNECTING_NET)) {
WiFi.disconnect();
return;
}
}
if (WiFi.status() == WL_CONNECTED) {
IPAddress localip = WiFi.localIP();
if (configStore.getFlag(CONFIG_FLAG_STATIC_IP)) {
BLYNK_LOG_IP("Using Static IP: ", localip);
} else {
BLYNK_LOG_IP("Using Dynamic IP: ", localip);
}
connectNetRetries = WIFI_CLOUD_MAX_RETRIES;
BlynkState::set(MODE_CONNECTING_CLOUD);
} else if (--connectNetRetries <= 0) {
config_set_last_error(BLYNK_PROV_ERR_NETWORK);
BlynkState::set(MODE_ERROR);
}
}
void enterConnectCloud() {
BlynkState::set(MODE_CONNECTING_CLOUD);
Blynk.config(configStore.cloudToken, configStore.cloudHost, configStore.cloudPort);
Blynk.connect(0);
unsigned long timeoutMs = millis() + WIFI_CLOUD_CONNECT_TIMEOUT;
while ((timeoutMs > millis()) &&
(WiFi.status() == WL_CONNECTED) &&
(!Blynk.isTokenInvalid()) &&
(Blynk.connected() == false))
{
delay(10);
Blynk.run();
app_loop();
if (!BlynkState::is(MODE_CONNECTING_CLOUD)) {
Blynk.disconnect();
return;
}
}
if (millis() > timeoutMs) {
DEBUG_PRINT("Timeout");
}
if (Blynk.isTokenInvalid()) {
config_set_last_error(BLYNK_PROV_ERR_TOKEN);
BlynkState::set(MODE_WAIT_CONFIG); // TODO: retry after timeout
} else if (WiFi.status() != WL_CONNECTED) {
BlynkState::set(MODE_CONNECTING_NET);
} else if (Blynk.connected()) {
BlynkState::set(MODE_RUNNING);
connectBlynkRetries = WIFI_CLOUD_MAX_RETRIES;
if (!configStore.getFlag(CONFIG_FLAG_VALID)) {
configStore.last_error = BLYNK_PROV_ERR_NONE;
configStore.setFlag(CONFIG_FLAG_VALID, true);
config_save();
Blynk.sendInternal("meta", "set", "Hotspot Name", getWiFiName());
}
} else if (--connectBlynkRetries <= 0) {
config_set_last_error(BLYNK_PROV_ERR_CLOUD);
BlynkState::set(MODE_ERROR);
}
}
void enterSwitchToSTA() {
BlynkState::set(MODE_SWITCH_TO_STA);
DEBUG_PRINT("Switching to STA...");
delay(1000);
WiFi.mode(WIFI_OFF);
delay(100);
WiFi.mode(WIFI_STA);
BlynkState::set(MODE_CONNECTING_NET);
}
void enterError() {
BlynkState::set(MODE_ERROR);
unsigned long timeoutMs = millis() + 10000;
while (timeoutMs > millis() || g_buttonPressed)
{
delay(10);
app_loop();
if (!BlynkState::is(MODE_ERROR)) {
return;
}
}
DEBUG_PRINT("Restarting after error.");
delay(10);
restartMCU();
}

View File

@@ -0,0 +1,162 @@
#define CONFIG_FLAG_VALID 0x01
#define CONFIG_FLAG_STATIC_IP 0x02
#define BLYNK_PROV_ERR_NONE 0 // All good
#define BLYNK_PROV_ERR_CONFIG 700 // Invalid config from app (malformed token,etc)
#define BLYNK_PROV_ERR_NETWORK 701 // Could not connect to the router
#define BLYNK_PROV_ERR_CLOUD 702 // Could not connect to the cloud
#define BLYNK_PROV_ERR_TOKEN 703 // Invalid token error (after connection)
#define BLYNK_PROV_ERR_INTERNAL 704 // Other issues (i.e. hardware failure)
struct ConfigStore {
uint32_t magic;
char version[15];
uint8_t flags;
char wifiSSID[34];
char wifiPass[64];
char cloudToken[34];
char cloudHost[34];
uint16_t cloudPort;
uint32_t staticIP;
uint32_t staticMask;
uint32_t staticGW;
uint32_t staticDNS;
uint32_t staticDNS2;
int last_error;
void setFlag(uint8_t mask, bool value) {
if (value) {
flags |= mask;
} else {
flags &= ~mask;
}
}
bool getFlag(uint8_t mask) {
return (flags & mask) == mask;
}
} __attribute__((packed));
ConfigStore configStore;
const ConfigStore configDefault = {
0x626C6E6B,
BLYNK_FIRMWARE_VERSION,
0x00,
"",
"",
"invalid token",
CONFIG_DEFAULT_SERVER,
CONFIG_DEFAULT_PORT,
0,
BLYNK_PROV_ERR_NONE
};
template<typename T, int size>
void CopyString(const String& s, T(&arr)[size]) {
s.toCharArray(arr, size);
}
static bool config_load_blnkopt()
{
static const char blnkopt[] = "blnkopt\0"
BLYNK_PARAM_KV("ssid" , BLYNK_PARAM_PLACEHOLDER_64
BLYNK_PARAM_PLACEHOLDER_64
BLYNK_PARAM_PLACEHOLDER_64
BLYNK_PARAM_PLACEHOLDER_64)
BLYNK_PARAM_KV("host" , CONFIG_DEFAULT_SERVER)
BLYNK_PARAM_KV("port" , BLYNK_TOSTRING(CONFIG_DEFAULT_PORT))
"\0";
BlynkParam prov(blnkopt+8, sizeof(blnkopt)-8-2);
BlynkParam::iterator ssid = prov["ssid"];
BlynkParam::iterator pass = prov["pass"];
BlynkParam::iterator auth = prov["auth"];
BlynkParam::iterator host = prov["host"];
BlynkParam::iterator port = prov["port"];
if (!(ssid.isValid() && auth.isValid())) {
return false;
}
// reset to defaut before loading values from blnkopt
configStore = configDefault;
if (ssid.isValid()) { CopyString(ssid.asStr(), configStore.wifiSSID); }
if (pass.isValid()) { CopyString(pass.asStr(), configStore.wifiPass); }
if (auth.isValid()) { CopyString(auth.asStr(), configStore.cloudToken); }
if (host.isValid()) { CopyString(host.asStr(), configStore.cloudHost); }
if (port.isValid()) { configStore.cloudPort = port.asInt(); }
return true;
}
#include <sfud.h>
const sfud_flash *_flash = sfud_get_device_table() + 0;
void config_load()
{
memset(&configStore, 0, sizeof(configStore));
sfud_err result = sfud_read(_flash, 0, sizeof(configStore), (uint8_t*)&configStore);
if (result != SFUD_SUCCESS || configStore.magic != 0x626C6E6B)
{
DEBUG_PRINT("Using default config.");
configStore = configDefault;
return;
}
}
bool config_save()
{
sfud_err result = sfud_erase(_flash, 0, sizeof(configStore));
delay(100);
if (!result == SFUD_SUCCESS) { DEBUG_PRINT("Erase flash data failed"); return false; }
result = sfud_write(_flash, 0, sizeof(configStore), (uint8_t*)&configStore);
delay(50);
if (!result == SFUD_SUCCESS) { DEBUG_PRINT("Write the flash data failed"); return false; }
DEBUG_PRINT("Configuration stored to flash");
return true;
}
bool config_init()
{
if (sfud_init() != SFUD_SUCCESS) { DEBUG_PRINT("SFUD init failed"); return false; }
sfud_qspi_fast_read_enable(sfud_get_device(SFUD_W25Q32_DEVICE_INDEX), 2);
config_load();
return true;
}
void enterResetConfig()
{
DEBUG_PRINT("Resetting configuration!");
configStore = configDefault;
config_save();
BlynkState::set(MODE_WAIT_CONFIG);
}
void config_set_last_error(int error) {
// Only set error if not provisioned
if (!configStore.getFlag(CONFIG_FLAG_VALID)) {
configStore = configDefault;
sfud_err result = sfud_erase(_flash, 0, 1);
configStore.last_error = error;
BLYNK_LOG2("Last error code: ", error);
config_save();
}
}

View File

@@ -0,0 +1,69 @@
#include <Blynk/BlynkConsole.h>
BlynkConsole edgentConsole;
void console_init()
{
#ifdef BLYNK_PRINT
edgentConsole.begin(BLYNK_PRINT);
#endif
edgentConsole.print("\n>");
edgentConsole.addCommand("reboot", []() {
edgentConsole.print(R"json({"status":"OK","msg":"rebooting wifi module"})json" "\n");
delay(100);
restartMCU();
});
edgentConsole.addCommand("config", [](int argc, const char** argv) {
if (argc < 1 || 0 == strcmp(argv[0], "start")) {
BlynkState::set(MODE_WAIT_CONFIG);
} else if (0 == strcmp(argv[0], "erase")) {
BlynkState::set(MODE_RESET_CONFIG);
}
});
edgentConsole.addCommand("devinfo", []() {
edgentConsole.printf(
R"json({"name":"%s","board":"%s","tmpl_id":"%s","fw_type":"%s","fw_ver":"%s"})json" "\n",
getWiFiName().c_str(),
BLYNK_TEMPLATE_NAME,
BLYNK_TEMPLATE_ID,
BLYNK_FIRMWARE_TYPE,
BLYNK_FIRMWARE_VERSION
);
});
edgentConsole.addCommand("connect", [](int argc, const char** argv) {
if (argc < 2) {
edgentConsole.print(R"json({"status":"error","msg":"invalid arguments. expected: <auth> <ssid> <pass>"})json" "\n");
return;
}
String auth = argv[0];
String ssid = argv[1];
String pass = (argc >= 3) ? argv[2] : "";
if (auth.length() != 32) {
edgentConsole.print(R"json({"status":"error","msg":"invalid token size"})json" "\n");
return;
}
edgentConsole.print(R"json({"status":"OK","msg":"trying to connect..."})json" "\n");
configStore = configDefault;
CopyString(ssid, configStore.wifiSSID);
CopyString(pass, configStore.wifiPass);
CopyString(auth, configStore.cloudToken);
BlynkState::set(MODE_SWITCH_TO_STA);
});
}
BLYNK_WRITE(InternalPinDBG) {
String cmd = String(param.asStr()) + "\n";
edgentConsole.runCommand((char*)cmd.c_str());
}

View File

@@ -0,0 +1,59 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
*************************************************************
Blynk.Edgent implements:
- Blynk.Inject - Dynamic WiFi credentials provisioning
- Blynk.Air - Over The Air firmware updates
- Device state indication using a physical LED
- Credentials reset using a physical Button
Required libraries:
- Seeed Arduino rpcUnified
- Seeed Arduino rpcWiFi
- Seeed Arduino SFUD
- Seeed Arduino FS
- Seeed Arduino mbedtls
- Seeed Arduino FreeRTOS
- ArduinoOTA
- ArduinoHttpClient
NOTE: Please also update the WiFi module firmware:
https://wiki.seeedstudio.com/Wio-Terminal-Network-Overview
*************************************************************/
/* Fill in information from your Blynk Template here */
/* Read more: https://bit.ly/BlynkInject */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
#define BLYNK_FIRMWARE_VERSION "0.1.0"
#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG
#define APP_DEBUG
#include "BlynkEdgent.h"
void setup()
{
Serial.begin(115200);
delay(100);
BlynkEdgent.begin();
}
void loop() {
BlynkEdgent.run();
}

View File

@@ -0,0 +1,250 @@
#if defined(BOARD_LED_PIN_WS2812)
#include <Adafruit_NeoPixel.h> // Library: https://github.com/adafruit/Adafruit_NeoPixel
Adafruit_NeoPixel rgb = Adafruit_NeoPixel(1, BOARD_LED_PIN_WS2812, NEO_GRB + NEO_KHZ800);
#endif
void indicator_run();
#if !defined(BOARD_LED_BRIGHTNESS)
#define BOARD_LED_BRIGHTNESS 255
#endif
#if defined(BOARD_LED_PIN_WS2812) || defined(BOARD_LED_PIN_R)
#define BOARD_LED_IS_RGB
#endif
#define DIMM(x) ((uint32_t)(x)*(BOARD_LED_BRIGHTNESS)/255)
#define RGB(r,g,b) (DIMM(r) << 16 | DIMM(g) << 8 | DIMM(b) << 0)
#define TO_PWM(x) ((uint32_t)(x)*(BOARD_PWM_MAX)/255)
class Indicator {
public:
enum Colors {
COLOR_BLACK = RGB(0x00, 0x00, 0x00),
COLOR_WHITE = RGB(0xFF, 0xFF, 0xE7),
COLOR_BLUE = RGB(0x0D, 0x36, 0xFF),
COLOR_BLYNK = RGB(0x2E, 0xFF, 0xB9),
COLOR_RED = RGB(0xFF, 0x10, 0x08),
COLOR_MAGENTA = RGB(0xA7, 0x00, 0xFF),
};
Indicator() {
}
void init() {
m_Counter = 0;
initLED();
}
uint32_t run() {
State currState = BlynkState::get();
// Reset counter if indicator state changes
if (m_PrevState != currState) {
m_PrevState = currState;
m_Counter = 0;
}
const long t = millis();
if (g_buttonPressed) {
if (t - g_buttonPressTime > BUTTON_HOLD_TIME_ACTION) { return beatLED(COLOR_WHITE, (int[]){ 100, 100 }); }
if (t - g_buttonPressTime > BUTTON_HOLD_TIME_INDICATION) { return waveLED(COLOR_WHITE, 1000); }
}
switch (currState) {
case MODE_RESET_CONFIG:
case MODE_WAIT_CONFIG: return beatLED(COLOR_BLUE, (int[]){ 50, 500 });
case MODE_CONFIGURING: return beatLED(COLOR_BLUE, (int[]){ 200, 200 });
case MODE_CONNECTING_NET: return beatLED(COLOR_BLYNK, (int[]){ 50, 500 });
case MODE_CONNECTING_CLOUD: return beatLED(COLOR_BLYNK, (int[]){ 100, 100 });
case MODE_RUNNING: return waveLED(COLOR_BLYNK, 5000);
case MODE_OTA_UPGRADE: return beatLED(COLOR_MAGENTA, (int[]){ 50, 50 });
default: return beatLED(COLOR_RED, (int[]){ 80, 100, 80, 1000 } );
}
}
protected:
/*
* LED drivers
*/
#if defined(BOARD_LED_PIN_WS2812) // Addressable, NeoPixel RGB LED
void initLED() {
rgb.begin();
setRGB(COLOR_BLACK);
}
void setRGB(uint32_t color) {
rgb.setPixelColor(0, color);
rgb.show();
}
#elif defined(BOARD_LED_PIN_R) // Normal RGB LED (common anode or common cathode)
void initLED() {
pinMode(BOARD_LED_PIN_R, OUTPUT);
pinMode(BOARD_LED_PIN_G, OUTPUT);
pinMode(BOARD_LED_PIN_B, OUTPUT);
}
void setRGB(uint32_t color) {
uint8_t r = (color & 0xFF0000) >> 16;
uint8_t g = (color & 0x00FF00) >> 8;
uint8_t b = (color & 0x0000FF);
#if BOARD_LED_INVERSE
analogWrite(BOARD_LED_PIN_R, TO_PWM(255 - r));
analogWrite(BOARD_LED_PIN_G, TO_PWM(255 - g));
analogWrite(BOARD_LED_PIN_B, TO_PWM(255 - b));
#else
analogWrite(BOARD_LED_PIN_R, TO_PWM(r));
analogWrite(BOARD_LED_PIN_G, TO_PWM(g));
analogWrite(BOARD_LED_PIN_B, TO_PWM(b));
#endif
}
#elif defined(BOARD_LED_PIN) // Single color LED
void initLED() {
pinMode(BOARD_LED_PIN, OUTPUT);
}
void setLED(uint32_t color) {
#if BOARD_LED_INVERSE
analogWrite(BOARD_LED_PIN, TO_PWM(255 - color));
#else
analogWrite(BOARD_LED_PIN, TO_PWM(color));
#endif
}
#else
#warning Invalid LED configuration.
void initLED() {
}
void setLED(uint32_t color) {
}
#endif
/*
* Animations
*/
uint32_t skipLED() {
return 20;
}
#if defined(BOARD_LED_IS_RGB)
template<typename T>
uint32_t beatLED(uint32_t onColor, const T& beat) {
const uint8_t cnt = sizeof(beat)/sizeof(beat[0]);
setRGB((m_Counter % 2 == 0) ? onColor : (uint32_t)COLOR_BLACK);
uint32_t next = beat[m_Counter % cnt];
m_Counter = (m_Counter+1) % cnt;
return next;
}
uint32_t waveLED(uint32_t colorMax, unsigned breathePeriod) {
uint8_t redMax = (colorMax & 0xFF0000) >> 16;
uint8_t greenMax = (colorMax & 0x00FF00) >> 8;
uint8_t blueMax = (colorMax & 0x0000FF);
// Brightness will rise from 0 to 128, then fall back to 0
uint8_t brightness = (m_Counter < 128) ? m_Counter : 255 - m_Counter;
// Multiply our three colors by the brightness:
redMax *= ((float)brightness / 128.0);
greenMax *= ((float)brightness / 128.0);
blueMax *= ((float)brightness / 128.0);
// And turn the LED to that color:
setRGB((redMax << 16) | (greenMax << 8) | blueMax);
// This function relies on the 8-bit, unsigned m_Counter rolling over.
m_Counter = (m_Counter+1) % 256;
return breathePeriod / 256;
}
#else
template<typename T>
uint32_t beatLED(uint32_t, const T& beat) {
const uint8_t cnt = sizeof(beat)/sizeof(beat[0]);
setLED((m_Counter % 2 == 0) ? BOARD_LED_BRIGHTNESS : 0);
uint32_t next = beat[m_Counter % cnt];
m_Counter = (m_Counter+1) % cnt;
return next;
}
uint32_t waveLED(uint32_t, unsigned breathePeriod) {
uint32_t brightness = (m_Counter < 128) ? m_Counter : 255 - m_Counter;
setLED(DIMM(brightness*2));
// This function relies on the 8-bit, unsigned m_Counter rolling over.
m_Counter = (m_Counter+1) % 256;
return breathePeriod / 256;
}
#endif
private:
uint8_t m_Counter;
State m_PrevState;
};
Indicator indicator;
/*
* Animation timers
*/
#if defined(USE_TC3)
#include <TimerTC3.h>
void indicator_run() {
uint32_t returnTime = indicator.run();
if (returnTime) {
TimerTc3.initialize(returnTime*1000);
}
}
void indicator_init() {
indicator.init();
TimerTc3.initialize(100*1000);
TimerTc3.attachInterrupt(indicator_run);
}
#elif defined(USE_TCC0)
#include <TimerThree.h>
void indicator_run() {
uint32_t returnTime = indicator.run();
if (returnTime) {
Timer3.initialize(returnTime*1000);
}
}
void indicator_init() {
indicator.init();
Timer3.initialize(100*1000);
Timer3.attachInterrupt(indicator_run);
}
#else
#warning LED indicator needs a functional timer!
void indicator_run() {}
void indicator_init() {}
#endif

View File

@@ -0,0 +1,151 @@
#include <ArduinoOTA.h> // only for InternalStorage
#include <ArduinoHttpClient.h>
#define OTA_FATAL(...) { BLYNK_LOG1(__VA_ARGS__); delay(1000); restartMCU(); }
#define USE_SSL
String overTheAirURL;
extern BlynkTimer edgentTimer;
BLYNK_WRITE(InternalPinOTA) {
overTheAirURL = param.asString();
// Force HTTP update
overTheAirURL.replace("https://", "http://");
edgentTimer.setTimeout(2000L, [](){
// Start OTA
Blynk.logEvent("sys_ota", "OTA started");
// Disconnect, not to interfere with OTA process
Blynk.disconnect();
BlynkState::set(MODE_OTA_UPGRADE);
});
}
bool parseURL(String url, String& protocol, String& host, int& port, String& uri)
{
int index = url.indexOf(':');
if(index < 0) {
return false;
}
protocol = url.substring(0, index);
url.remove(0, (index + 3)); // remove protocol part
index = url.indexOf('/');
String server = url.substring(0, index);
url.remove(0, index); // remove server part
index = server.indexOf(':');
if(index >= 0) {
host = server.substring(0, index); // hostname
port = server.substring(index + 1).toInt(); // port
} else {
host = server;
if (protocol == "http") {
port = 80;
} else if (protocol == "https") {
port = 443;
}
}
if (url.length()) {
uri = url;
} else {
uri = "/";
}
return true;
}
void enterOTA() {
BlynkState::set(MODE_OTA_UPGRADE);
// Disconnect, not to interfere with OTA process
Blynk.disconnect();
String protocol, host, url;
int port;
DEBUG_PRINT(String("OTA: ") + overTheAirURL);
if (!parseURL(overTheAirURL, protocol, host, port, url)) {
OTA_FATAL(F("Cannot parse URL"));
}
DEBUG_PRINT(String("Connecting to ") + host + ":" + port);
Client* client = NULL;
if (protocol == "http") {
client = new WiFiClient();
#ifdef USE_SSL
} else if (protocol == "https") {
client = &_blynkWifiClient;
//client = new WiFiClientSecure();
#endif
} else {
OTA_FATAL(String("Unsupported protocol: ") + protocol);
}
HttpClient http(*client, host, port);
http.get(url);
int statusCode = http.responseStatusCode();
if (statusCode != 200) {
http.stop();
OTA_FATAL(String("HTTP status code: ") + statusCode);
}
int contentLength = http.contentLength();
if (contentLength == HttpClient::kNoContentLengthHeader) {
http.stop();
OTA_FATAL("Content-Length not defined");
}
if (!InternalStorage.open(contentLength)) {
http.stop();
OTA_FATAL("Not enough space to store the update");
}
//InternalStorage.debugPrint();
DEBUG_PRINT("Flashing...");
int written = 0;
int prevProgress = 0;
uint8_t buff[256];
while (client->connected() && written < contentLength) {
int len = http.readBytes(buff, sizeof(buff));
if (len <= 0) continue;
for (int i = 0; i<len; i++) {
InternalStorage.write(buff[i]);
}
written += len;
const int progress = (written*100)/contentLength;
if (progress - prevProgress >= 10 || progress == 100) {
#ifdef BLYNK_PRINT
BLYNK_PRINT.print(String("\r ") + progress + "%");
#endif
prevProgress = progress;
}
}
#ifdef BLYNK_PRINT
BLYNK_PRINT.println();
#endif
InternalStorage.close();
http.stop();
if (written != contentLength) {
OTA_FATAL(String("Interrupted at ") + written + " / " + contentLength + " bytes");
}
DEBUG_PRINT("=== Update successfully completed. Rebooting.");
InternalStorage.apply();
}

View File

@@ -0,0 +1,53 @@
#ifdef BOARD_BUTTON_PIN
volatile bool g_buttonPressed = false;
volatile uint32_t g_buttonPressTime = -1;
void button_action(void)
{
BlynkState::set(MODE_RESET_CONFIG);
}
void button_change(void)
{
#if BOARD_BUTTON_ACTIVE_LOW
bool buttonState = !digitalRead(BOARD_BUTTON_PIN);
#else
bool buttonState = digitalRead(BOARD_BUTTON_PIN);
#endif
if (buttonState && !g_buttonPressed) {
g_buttonPressTime = millis();
g_buttonPressed = true;
DEBUG_PRINT("Hold the button for 10 seconds to reset configuration...");
} else if (!buttonState && g_buttonPressed) {
g_buttonPressed = false;
uint32_t buttonHoldTime = millis() - g_buttonPressTime;
if (buttonHoldTime >= BUTTON_HOLD_TIME_ACTION) {
button_action();
} else if (buttonHoldTime >= BUTTON_PRESS_TIME_ACTION) {
// User action
}
g_buttonPressTime = -1;
}
}
void button_init()
{
#if BOARD_BUTTON_ACTIVE_LOW
pinMode(BOARD_BUTTON_PIN, INPUT_PULLUP);
#else
pinMode(BOARD_BUTTON_PIN, INPUT_PULLDOWN);
#endif
attachInterrupt(BOARD_BUTTON_PIN, button_change, CHANGE);
}
#else
#define g_buttonPressed false
#define g_buttonPressTime 0
void button_init() {}
#endif

View File

@@ -0,0 +1,61 @@
/*
* Board configuration (see examples below).
*/
// Example configuration for Wio Terminal Board
#define BOARD_BUTTON_PIN WIO_KEY_A // Pin where user button is attached
#define BOARD_BUTTON_ACTIVE_LOW true // true if button is "active-low"
#define BOARD_LED_PIN LED_BUILTIN // Set LED pin - if you have a single-color LED attached
//#define BOARD_LED_PIN_R 27 // Set R,G,B pins - if your LED is PWM RGB
//#define BOARD_LED_PIN_G 26
//#define BOARD_LED_PIN_B 25
//#define BOARD_LED_PIN_WS2812 33 // Set if your LED is WS2812 RGB
#define BOARD_LED_INVERSE false // true if LED is common anode, false if common cathode
#define BOARD_LED_BRIGHTNESS 255 // 0..255 brightness control
/*
* Advanced options
*/
#define BUTTON_HOLD_TIME_INDICATION 3000
#define BUTTON_HOLD_TIME_ACTION 10000
#define BUTTON_PRESS_TIME_ACTION 50
#define BOARD_PWM_MAX 1023
#if !defined(CONFIG_DEVICE_PREFIX)
#define CONFIG_DEVICE_PREFIX "Blynk"
#endif
#if !defined(CONFIG_AP_URL)
#define CONFIG_AP_URL "blynk.setup"
#endif
#if !defined(CONFIG_DEFAULT_SERVER)
#define CONFIG_DEFAULT_SERVER "blynk.cloud"
#endif
#if !defined(CONFIG_DEFAULT_PORT)
#define CONFIG_DEFAULT_PORT 443
#endif
#define WIFI_CLOUD_MAX_RETRIES 500
#define WIFI_NET_CONNECT_TIMEOUT 50000
#define WIFI_CLOUD_CONNECT_TIMEOUT 50000
#define WIFI_AP_IP IPAddress(192, 168, 4, 1)
#define WIFI_AP_Subnet IPAddress(255, 255, 255, 0)
//#define WIFI_CAPTIVE_PORTAL_ENABLE 1
//#define USE_TC3
//#define USE_TCC0
#define BLYNK_NO_DEFAULT_BANNER
#if defined(APP_DEBUG)
#define DEBUG_PRINT(...) BLYNK_LOG1(__VA_ARGS__)
#define DEBUG_PRINTF(...) BLYNK_LOG(__VA_ARGS__)
#else
#define DEBUG_PRINT(...)
#define DEBUG_PRINTF(...)
#endif

View File

@@ -0,0 +1,104 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This sketch shows how to use an Arduino Client directly in Blynk.
Using a standard Client interface is a convenient way to integrate
any connectivity shield, even if it's not directly supported by Blynk.
NOTE: Pins 10, 11, 12 and 13 are reserved for Ethernet module.
DON'T use them in your sketch directly!
WARNING: If you have an SD card, you may need to disable it
by setting pin 4 to HIGH. Read more here:
https://www.arduino.cc/en/Main/ArduinoEthernetShield
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Uncomment this to see the verbose Blynk protocol log */
//#define BLYNK_DEBUG
/* Fill in information from Blynk Device Info here */
/* Read more: https://bit.ly/BlynkSimpleAuth */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
/* BlynkMultiClient allows attaching Blynk to the standard Arduino Client,
and also allows multiple (up to 4) connections to be registered.
NOTE: don't replace it with any of the BlynkSimple*.h variants */
#include <BlynkMultiClient.h>
/*
* Ethernet
*/
// You can specify your board mac adress
byte ETH_MAC[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
#include <SPI.h>
#include <Ethernet.h> // For ENC28J60, replace this with <EthernetENC.h> library
// Ethernet shield and SDcard pins
#define W5100_CS 10
#define SDCARD_CS 4
static EthernetClient blynkEthernetClient;
/*
* Main
*/
void connectEthernet()
{
if (Ethernet.begin(ETH_MAC, 5000L, 500L)) {
Serial.print("Ethernet IP: ");
Serial.println(Ethernet.localIP());
} else if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found.");
} else if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
} else {
Serial.println("Ethernet: DHCP configuration failed.");
}
}
void setup()
{
// Debug console
Serial.begin(115200);
// Deselect the SD card
pinMode(SDCARD_CS, OUTPUT);
digitalWrite(SDCARD_CS, HIGH);
// Initialize Ethernet shield
Ethernet.init(W5100_CS);
delay(1000); // Give the Ethernet shield a second to initialize
connectEthernet();
// Setup Blynk
Blynk.addClient("ETH", blynkEthernetClient, 80);
Blynk.config(BLYNK_AUTH_TOKEN);
}
void loop()
{
Blynk.run();
Ethernet.maintain();
}

View File

@@ -0,0 +1,149 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This sketch shows how to use multiple connectivity options
at the same time:
- Arduino MKR1400 GSM module provides GPRS
- Arduino MKR ETH shield provides Ethernet
Using a standard Client interface is a convenient way to integrate
any connectivity shield, even if it's not directly supported by Blynk.
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Uncomment this to see the verbose Blynk protocol log */
//#define BLYNK_DEBUG
/* Fill in information from Blynk Device Info here */
/* Read more: https://bit.ly/BlynkSimpleAuth */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
/* BlynkMultiClient allows attaching Blynk to the standard Arduino Client,
and also allows multiple (up to 4) connections to be registered.
NOTE: don't replace it with any of the BlynkSimple*.h variants */
#include <BlynkMultiClient.h>
/*
* Ethernet
*/
// You can specify your board mac adress
byte ETH_MAC[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
#include <SPI.h>
#include <Ethernet.h>
// Ethernet shield and SDcard pins
#define MKRETH_CS 5
#define SDCARD_CS 4
static EthernetClient blynkEthernetClient;
/*
* GSM modem
*/
// Please specify your GPRS credentials
const char SIM_PIN[] = "";
const char GPRS_APN[] = "internet";
const char GPRS_USER[] = "";
const char GPRS_PASS[] = "";
#include <MKRGSM.h>
static GSMModem modem;
static GPRS gprs;
static GSM gsmAccess;
static GSMClient blynkGsmClient;
/*
* Main
*/
void connectEthernet()
{
if (Ethernet.begin(ETH_MAC, 5000L, 500L)) {
Serial.print("Ethernet IP: ");
Serial.println(Ethernet.localIP());
} else if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found.");
} else if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
} else {
Serial.println("Ethernet: DHCP configuration failed.");
}
}
void connectGPRS()
{
bool gsmConnected = false;
bool gprsConnected = false;
const uint32_t tstart = millis();
while (millis() - tstart < 20000) {
if (gsmAccess.begin(SIM_PIN) == GSM_READY) {
gsmConnected = true;
break;
}
delay(1000);
}
while (gsmConnected && millis() - tstart < 20000) {
if (gprs.attachGPRS(GPRS_APN, GPRS_USER, GPRS_PASS) == GPRS_READY) {
gprsConnected = true;
break;
}
delay(1000);
}
if (!gsmConnected) {
Serial.println("GSM not connected.");
} else if (!gprsConnected) {
Serial.println("GPRS not connected.");
} else {
Serial.print("GPRS IP: ");
Serial.println(gprs.getIPAddress());
}
}
void setup()
{
// Debug console
Serial.begin(115200);
// Deselect the SD card
pinMode(SDCARD_CS, OUTPUT);
digitalWrite(SDCARD_CS, HIGH);
// Initialize Ethernet shield
Ethernet.init(MKRETH_CS);
connectEthernet();
connectGPRS();
// Setup Blynk
Blynk.addClient("ETH", blynkEthernetClient, 80);
Blynk.addClient("GSM", blynkGsmClient, 80);
Blynk.config(BLYNK_AUTH_TOKEN);
}
void loop()
{
Blynk.run();
Ethernet.maintain();
}

View File

@@ -0,0 +1,224 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This sketch shows how to use multiple connectivity options
at the same time:
- Arduino MKR1400 GSM module provides GPRS
- Arduino MKR ETH shield provides Ethernet
Using a standard Client interface is a convenient way to integrate
any connectivity shield, even if it's not directly supported by Blynk.
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Uncomment this to see the verbose Blynk protocol log */
//#define BLYNK_DEBUG
/* Fill in information from Blynk Device Info here */
/* Read more: https://bit.ly/BlynkSimpleAuth */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
/* BlynkMultiClient allows attaching Blynk to the standard Arduino Client,
and also allows multiple (up to 4) connections to be registered.
NOTE: don't replace it with any of the BlynkSimple*.h variants */
#include <BlynkMultiClient.h>
/*
* Ethernet
*/
// You can specify your board mac adress
byte ETH_MAC[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoECCX08.h>
#include <ArduinoBearSSL.h>
// Ethernet shield and SDcard pins
#define MKRETH_CS 5
#define SDCARD_CS 4
static EthernetClient blynkEthernetClient;
static BearSSLClient blynkEthernetClientSSL(blynkEthernetClient);
/*
* GSM modem
*/
// Please specify your GPRS credentials
const char SIM_PIN[] = "";
const char GPRS_APN[] = "internet";
const char GPRS_USER[] = "";
const char GPRS_PASS[] = "";
#include <MKRGSM.h>
static GSMModem modem;
static GPRS gprs;
static GSM gsmAccess;
static GSMSSLClient blynkGsmClientSSL;
/*
* Main
*/
void connectEthernet()
{
if (Ethernet.begin(ETH_MAC, 5000L, 500L)) {
Serial.print("Ethernet IP: ");
Serial.println(Ethernet.localIP());
} else if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found.");
} else if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
} else {
Serial.println("Ethernet: DHCP configuration failed.");
}
}
void connectGPRS()
{
bool gsmConnected = false;
bool gprsConnected = false;
const uint32_t tstart = millis();
while (millis() - tstart < 20000) {
if (gsmAccess.begin(SIM_PIN) == GSM_READY) {
gsmConnected = true;
break;
}
delay(1000);
}
while (gsmConnected && millis() - tstart < 20000) {
if (gprs.attachGPRS(GPRS_APN, GPRS_USER, GPRS_PASS) == GPRS_READY) {
gprsConnected = true;
break;
}
delay(1000);
}
if (!gsmConnected) {
Serial.println("GSM not connected.");
} else if (!gprsConnected) {
Serial.println("GPRS not connected.");
} else {
Serial.print("GPRS IP: ");
Serial.println(gprs.getIPAddress());
}
}
unsigned long ntpGetTime()
{
static const char timeServer[] = "time.nist.gov";
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE];
EthernetUDP Udp;
Udp.begin(8888);
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
for (int i = 0; i < 10; i++)
{
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(timeServer, 123); // NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
millis_time_t started = BlynkMillis();
while (BlynkMillis() - started < 1000)
{
delay(100);
if (Udp.parsePacket()) {
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
// the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
//Serial.print("Seconds since Jan 1 1900 = ");
//Serial.println(secsSince1900);
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears;
// print Unix time:
Serial.print("Unix time = ");
Serial.println(epoch);
return epoch;
}
}
Serial.println("Retry NTP");
}
Serial.println("NTP failed");
return 0;
}
void setup()
{
// Debug console
Serial.begin(115200);
// Deselect the SD card
pinMode(SDCARD_CS, OUTPUT);
digitalWrite(SDCARD_CS, HIGH);
// Initialize Ethernet shield
Ethernet.init(MKRETH_CS);
// Enable NTP time helper (needed for SSL authentiction)
ArduinoBearSSL.onGetTime(ntpGetTime);
connectEthernet();
connectGPRS();
// Setup Blynk
Blynk.addClient("ETH", blynkEthernetClientSSL, 443);
Blynk.addClient("GSM", blynkGsmClientSSL, 443);
Blynk.config(BLYNK_AUTH_TOKEN);
}
void loop()
{
Blynk.run();
Ethernet.maintain();
}

View File

@@ -0,0 +1,101 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This sketch shows how to use an Arduino Client directly in Blynk.
Using a standard Client interface is a convenient way to integrate
any connectivity shield, even if it's not directly supported by Blynk.
Please be sure to select a correct ESP8266 or ESP32 module
in the Tools -> Board menu!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Uncomment this to see the verbose Blynk protocol log */
//#define BLYNK_DEBUG
/* Fill in information from Blynk Device Info here */
/* Read more: https://bit.ly/BlynkSimpleAuth */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
/* BlynkMultiClient allows attaching Blynk to the standard Arduino Client,
and also allows multiple (up to 4) connections to be registered.
NOTE: don't replace it with any of the BlynkSimple*.h variants */
#include <BlynkMultiClient.h>
/*
* WiFi
*/
// Your WiFi credentials.
// Set password to "" for open networks.
const char* ssid = "YourNetworkName";
const char* pass = "YourPassword";
#ifdef ESP32
# include <WiFi.h>
#else
# include <ESP8266WiFi.h>
#endif
static WiFiClient blynkWiFiClient;
/*
* Main
*/
void connectWiFi()
{
Serial.print("Connecting to ");
Serial.println(ssid);
if (pass && strlen(pass)) {
WiFi.begin((char*)ssid, (char*)pass);
} else {
WiFi.begin((char*)ssid);
}
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
}
void setup()
{
// Debug console
Serial.begin(115200);
connectWiFi();
// Setup Blynk
Blynk.addClient("WiFi", blynkWiFiClient, 80);
Blynk.config(BLYNK_AUTH_TOKEN);
}
void loop()
{
// Reconnect WiFi
if (WiFi.status() != WL_CONNECTED) {
connectWiFi();
return;
}
Blynk.run();
}

View File

@@ -0,0 +1,65 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Arduino Ethernet shield (W5100)
to connect your project to Blynk.
NOTE: Pins 10, 11, 12 and 13 are reserved for Ethernet module.
DON'T use them in your sketch directly!
WARNING: If you have an SD card, you may need to disable it
by setting pin 4 to HIGH. Read more here:
https://www.arduino.cc/en/Main/ArduinoEthernetShield
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#define W5100_CS 10
#define SDCARD_CS 4
void setup()
{
// Debug console
Serial.begin(9600);
pinMode(SDCARD_CS, OUTPUT);
digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
Blynk.begin(BLYNK_AUTH_TOKEN);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, IPAddress(192,168,1,100), 8080);
// For more options, see Boards_Ethernet/Arduino_Ethernet_Manual example
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,72 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to configure static IP with Ethernet.
Be sure to check ordinary Ethernet example first!!!
NOTE: Pins 10, 11, 12 and 13 are reserved for Ethernet module.
DON'T use them in your sketch directly!
WARNING: If you have an SD card, you may need to disable it
by setting pin 4 to HIGH. Read more here:
https://www.arduino.cc/en/Main/ArduinoEthernetShield
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
IPAddress server_ip (10, 0, 0, 10);
// Mac address should be different for each device in your LAN
byte arduino_mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress arduino_ip ( 10, 0, 0, 20);
IPAddress dns_ip ( 8, 8, 8, 8);
IPAddress gateway_ip ( 10, 0, 0, 1);
IPAddress subnet_mask(255, 255, 255, 0);
#define W5100_CS 10
#define SDCARD_CS 4
void setup()
{
// Debug console
Serial.begin(9600);
pinMode(SDCARD_CS, OUTPUT);
digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
Blynk.begin(BLYNK_AUTH_TOKEN, server_ip, 8080, arduino_ip, dns_ip, gateway_ip, subnet_mask, arduino_mac);
// Or like this:
//Blynk.begin(BLYNK_AUTH_TOKEN, "blynk.cloud", 80, arduino_ip, dns_ip, gateway_ip, subnet_mask, arduino_mac);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,66 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Arduino MKR ETH shield
to connect your project to Blynk.
NOTE: This requires the latest Ethernet library (2.0.0+)
WARNING: If you have an SD card, you may need to disable it
by setting pin 4 to HIGH. Read more here:
https://www.arduino.cc/en/Main/ArduinoEthernetShield
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#define MKRETH_CS 5
#define SDCARD_CS 4
void setup()
{
// Debug console
Serial.begin(9600);
pinMode(SDCARD_CS, OUTPUT);
digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
Ethernet.init(MKRETH_CS); // Init MKR ETH shield
Blynk.begin(BLYNK_AUTH_TOKEN);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, IPAddress(192,168,1,100), 8080);
// For more options, see Boards_Ethernet/Arduino_Ethernet_Manual example
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,71 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Arduino MKR ETH shield
to connect your project to Blynk.
NOTE: This requires the latest Ethernet library (2.0.0+)
WARNING: If you have an SD card, you may need to disable it
by setting pin 4 to HIGH. Read more here:
https://www.arduino.cc/en/Main/ArduinoEthernetShield
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoECCX08.h>
#include <ArduinoBearSSL.h>
#include <BlynkSimpleEthernetSSL.h>
#define MKRETH_CS 5
#define SDCARD_CS 4
void setup()
{
// Debug console
Serial.begin(9600);
pinMode(SDCARD_CS, OUTPUT);
digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
Ethernet.init(MKRETH_CS); // Init MKR ETH shield
// Enable NTP time helper (needed for SSL authentiction)
ArduinoBearSSL.onGetTime(ntpGetTime);
Blynk.begin(BLYNK_AUTH_TOKEN);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, IPAddress(192,168,1,100), 8080);
// For more options, see Boards_Ethernet/Arduino_Ethernet_Manual example
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,60 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
For this example you need EthernetENC library:
https://github.com/jandrassy/EthernetENC
Typical wiring would be (this is for Arduino UNO,
search for correct wiring for your board):
VCC -- 5V
GND -- GND
CS -- D10
SI -- D11
SCK -- D13
SO -- D12
INT -- D2
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <EthernetENC.h>
#include <BlynkSimpleEthernetENC.h>
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, IPAddress(192,168,1,100), 8080);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,61 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Arduino MKRGSM 1400
to connect your project to Blynk.
NOTE: This requires MKRGSM library
from https://www.arduino.cc/en/Reference/MKRGSM
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <MKRGSM.h>
#include <BlynkSimpleMKRGSM.h>
// Your SIM and GPRS credentials
// Leave empty, if missing pin, user or pass
char pin[] = "";
char apn[] = "YourAPN";
char user[] = "";
char pass[] = "";
GSMClient client;
GPRS gprs;
GSM gsmAccess;
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, gsmAccess, gprs, client, pin, apn, user, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,52 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Arduino MKRNB 1500
to connect your project to Blynk.
NOTE: This requires MKRGSM library
from https://www.arduino.cc/en/Reference/MKRNB
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <MKRNB.h>
#include <BlynkSimpleMKRNB.h>
NBClient client;
GPRS gprs;
NB nbAccess;
// Your SIM credential
// Leave empty, if missing pin
char pin[] = "";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, nbAccess, gprs, client, pin);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,89 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
Attention! Please check out TinyGSM guide:
https://tiny.cc/tinygsm-readme
Change GPRS apm, user, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
// Arduino MKR GSM 1400 uses U-blox modem
#define TINY_GSM_MODEM_UBLOX
// Default heartbeat interval for GSM is 60
// If you want override this value, uncomment and set this option:
//#define BLYNK_HEARTBEAT 30
#include <TinyGsmClient.h>
#include <BlynkSimpleTinyGSM.h>
// Your GPRS credentials
// Leave empty, if missing user or pass
char apn[] = "YourAPN";
char user[] = "";
char pass[] = "";
TinyGsm modem(SerialGSM);
void setup()
{
// Debug console
Serial.begin(9600);
delay(10);
// Set GSM module baud rate
SerialGSM.begin(115200);
pinMode(GSM_DTR, OUTPUT);
digitalWrite(GSM_DTR, LOW);
delay(5);
// Turn on the GSM module by triggering GSM_RESETN pin
pinMode(GSM_RESETN, OUTPUT);
digitalWrite(GSM_RESETN, HIGH);
delay(100);
digitalWrite(GSM_RESETN, LOW);
delay(1000);
// Restart takes quite some time
// To skip it, call init() instead of restart()
Serial.println("Initializing modem...");
modem.restart();
// Unlock your SIM card with a PIN
//modem.simUnlock("1234");
Blynk.begin(BLYNK_AUTH_TOKEN, modem, apn, user, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,91 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
Attention! Please check out TinyGSM guide:
https://tiny.cc/tinygsm-readme
Change GPRS apm, user, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
// Select your modem:
#define TINY_GSM_MODEM_SIM800
//#define TINY_GSM_MODEM_SIM900
//#define TINY_GSM_MODEM_M590
//#define TINY_GSM_MODEM_A6
//#define TINY_GSM_MODEM_A7
//#define TINY_GSM_MODEM_BG96
//#define TINY_GSM_MODEM_XBEE
// Default heartbeat interval for GSM is 60
// If you want override this value, uncomment and set this option:
//#define BLYNK_HEARTBEAT 30
#include <TinyGsmClient.h>
#include <BlynkSimpleTinyGSM.h>
// Your GPRS credentials
// Leave empty, if missing user or pass
char apn[] = "YourAPN";
char user[] = "";
char pass[] = "";
// Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial1
// or Software Serial on Uno, Nano
//#include <SoftwareSerial.h>
//SoftwareSerial SerialAT(2, 3); // RX, TX
TinyGsm modem(SerialAT);
void setup()
{
// Debug console
Serial.begin(9600);
delay(10);
// Set GSM module baud rate
SerialAT.begin(115200);
delay(3000);
// Restart takes quite some time
// To skip it, call init() instead of restart()
Serial.println("Initializing modem...");
modem.restart();
// Unlock your SIM card with a PIN
//modem.simUnlock("1234");
Blynk.begin(BLYNK_AUTH_TOKEN, modem, apn, user, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,59 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Adafruit Feather M0 WiFi
to connect your project to Blynk.
NOTE: This requires WiFi101 library
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <WiFi101.h>
#include <BlynkSimpleWiFiShield101.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
WiFi.setPins(8, 7, 4, 2);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, IPAddress(192,168,1,100), 8080);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,58 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Arduino MKR1000
to connect your project to Blynk.
NOTE: This requires WiFi101 library
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <WiFi101.h>
#include <BlynkSimpleMKR1000.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, IPAddress(192,168,1,100), 8080);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,57 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Arduino MKR 1010
to connect your project to Blynk.
NOTE: This requires WiFiNINA library
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, IPAddress(192,168,1,100), 8080);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,59 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Arduino WiFi shield
to connect your project to Blynk.
Please update your shield firmware:
https://www.arduino.cc/en/Hacking/WiFiShieldFirmwareUpgrading
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <WiFi.h>
#include <BlynkSimpleWifi.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, IPAddress(192,168,1,100), 8080);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,58 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Arduino WiFi 101 shield
to connect your project to Blynk.
NOTE: This requires WiFi101 library
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <WiFi101.h>
#include <BlynkSimpleWiFiShield101.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, IPAddress(192,168,1,100), 8080);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,50 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Arduino Yun Bridge
to connect your project to Blynk.
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <Bridge.h>
#include <BlynkSimpleYun.h>
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, IPAddress(192,168,1,100), 8080);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,59 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Arduino.org UNO WiFi
to connect your project to Blynk.
NOTE: This requires WiFi Link library
Please update your UNO WiFi firmware to WiFiLink 1.0.0 (at least).
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <WiFiLink.h>
#include <BlynkSimpleWiFiLink.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, IPAddress(192,168,1,100), 8080);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,59 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example runs directly on ESP32 chip.
NOTE: This requires ESP32 support package:
https://github.com/espressif/arduino-esp32
Please be sure to select the right ESP32 module
in the Tools -> Board menu!
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,59 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example runs directly on ESP32 chip.
NOTE: This requires ESP32 support package:
https://github.com/espressif/arduino-esp32
Please be sure to select the right ESP32 module
in the Tools -> Board menu!
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <BlynkSimpleEsp32_SSL.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,76 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use ESP8266 Shield (with AT commands)
to connect your project to Blynk.
WARNING!
It's very tricky to get it working. Please read this article:
http://help.blynk.cc/hardware-and-libraries/arduino/esp8266-with-at-firmware
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
// Hardware Serial on Mega, Leonardo, Micro...
#define EspSerial Serial1
// or Software Serial on Uno, Nano...
//#include <SoftwareSerial.h>
//SoftwareSerial EspSerial(2, 3); // RX, TX
// Your ESP8266 baud rate:
#define ESP8266_BAUD 115200
ESP8266 wifi(&EspSerial);
void setup()
{
// Debug console
Serial.begin(9600);
delay(10);
// Set ESP8266 baud rate
EspSerial.begin(ESP8266_BAUD);
delay(10);
Blynk.begin(BLYNK_AUTH_TOKEN, wifi, ssid, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,58 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example runs directly on ESP8266 chip.
NOTE: This requires ESP8266 support package:
https://github.com/esp8266/Arduino
Please be sure to select the right ESP8266 module
in the Tools -> Board menu!
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,72 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example runs directly on ESP8266 chip.
NOTE: This requires ESP8266 support package:
https://github.com/esp8266/Arduino
Please be sure to select the right ESP8266 module
in the Tools -> Board menu!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
// Mac address should be different for each device in your LAN
byte arduino_mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress device_ip (192, 168, 0, 80);
IPAddress dns_ip ( 8, 8, 8, 8);
IPAddress gateway_ip (192, 168, 0, 1);
IPAddress subnet_mask(255, 255, 255, 0);
void setup()
{
// Debug console
Serial.begin(9600);
// Setup WiFi network
WiFi.config(device_ip, gateway_ip, subnet_mask);
WiFi.begin(ssid, pass);
// Setup Blynk
Blynk.config(BLYNK_AUTH_TOKEN);
while (Blynk.connect() == false) {
}
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,58 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example runs directly on ESP8266 chip.
NOTE: This requires ESP8266 support package:
https://github.com/esp8266/Arduino
Please be sure to select the right ESP8266 module
in the Tools -> Board menu!
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266_SSL.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,57 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use Fishino to connect your project to Blynk.
NOTE: This requires Fishino Software libraries:
http://fishino.it/en/download/
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Fishino.h>
#include <BlynkSimpleFishino.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,52 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use LinkItONE to connect your project to Blynk.
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <LWiFi.h>
#include <LWiFiClient.h>
#include <BlynkSimpleLinkItONE.h>
// Your WiFi credentials.
// Choose wifi_sec from LWIFI_OPEN, LWIFI_WPA, or LWIFI_WEP
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
int wifi_sec = LWIFI_WPA;
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, wifi_sec);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,81 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use WiFly RN-XV
to connect your project to Blynk.
For this example you need WiFlyHQ library:
https://github.com/harlequin-tech/WiFlyHQ
NOTE: Ensure a stable serial connection!
Hardware serial is preferred.
Firmware version 4.41 or later is preferred.
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <WiFlyHQ.h>
#include <BlynkSimpleWiFly.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
#define WiFlySerial Serial1
// This can be a SoftwareSerial object:
//#include <SoftwareSerial.h>
//SoftwareSerial WiFlySerial(2, 3); // RX, TX
WiFly wifly;
void setup()
{
// Debug console
Serial.begin(9600);
delay(10);
WiFlySerial.begin(9600); // Set your RN-XV baud rate
delay(10);
// Bind WiFly driver to the serial
if (!wifly.begin(&WiFlySerial)) {
BLYNK_FATAL("Failed to start wifly");
}
// You can try increasing baud rate:
//wifly.setBaud(115200);
//WiFlySerial.begin(115200);
Blynk.begin(BLYNK_AUTH_TOKEN, wifly, ssid, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,64 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use RedBear Duo
to connect your project to Blynk.
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <BlynkSimpleRedBear_Duo.h>
// Your WiFi credentials.
// Choose wifi_sec from WPA2, WPA, or WEP
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
int wifi_sec = WPA2;
//SYSTEM_MODE(AUTOMATIC);
SYSTEM_MODE(MANUAL);
void setup()
{
// Debug console
Serial.begin(9600);
delay(5000);
WiFi.on();
WiFi.setCredentials(ssid, pass, wifi_sec);
WiFi.connect();
Blynk.begin(BLYNK_AUTH_TOKEN);
// Or specify server using one of those commands:
//Blynk.begin(BLYNK_AUTH_TOKEN, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, server_ip, port);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,61 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example runs on Sparkfun Blynk Board.
NOTE: This requires ESP8266 support package:
https://github.com/esp8266/Arduino
You can select NodeMCU 1.0 (compatible board)
in the Tools -> Board menu
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, IPAddress(192,168,1,100), 8080);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,79 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use AirBoard + RN-XV WiFly module
to connect your project to Blynk.
For this example you need WiFlyHQ library:
https://github.com/harlequin-tech/WiFlyHQ
NOTE: Be sure to read this: http://www.theairboard.cc/quick-start/
WiFly firmware version 4.41 or later is preferred.
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
#include <SoftwareSerial.h>
SoftwareSerial DebugSerial(10, 11); // RX, TX
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT DebugSerial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <TheAirBoard.h>
#include <WiFlyHQ.h>
#include <BlynkSimpleWiFly.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
#define WiFlySerial Serial
WiFly wifly;
void setup()
{
// Debug console
DebugSerial.begin(9600);
delay(10);
WiFlySerial.begin(9600); // Set your RN-XV baud rate
delay(10);
// Bind WiFly driver to the serial
if (!wifly.begin(&WiFlySerial)) {
BLYNK_FATAL("Failed to start wifly");
}
// You can try increasing baud rate:
//wifly.setBaud(115200);
//WiFlySerial.begin(115200);
Blynk.begin(BLYNK_AUTH_TOKEN, wifly, ssid, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,59 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use TinyCircuits CC3000 shield
to connect your project to Blynk.
NOTE: Firmware version 1.14 or later is preferred.
Tools->Board should be "Arduino Pro or Pro Mini"
Tools->Processor should be "ATmega 328 (3.3V, 8MHz)"
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Adafruit_CC3000.h>
#include <BlynkSimpleTinyDuino.h>
// Your WiFi credentials.
// Choose wifi_sec from WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
int wifi_sec = WLAN_SEC_WPA2;
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, wifi_sec);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,64 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use CC3000 on WildFire board
to connect your project to Blynk.
NOTE: You need to install Arduino IDE WildFire support:
http://shop.wickeddevice.com/resources/wildfire/
NOTE: Firmware version 1.14 or later is preferred.
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <WildFire.h>
#include <WildFire_CC3000.h>
#include <BlynkSimpleWildFire.h>
WildFire wildfire;
// Your WiFi credentials.
// Choose wifi_sec from WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
int wifi_sec = WLAN_SEC_WPA2;
void setup()
{
// Debug console
Serial.begin(9600);
wildfire.begin();
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, wifi_sec);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,73 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use WildFire V4
to connect your project to Blynk.
NOTE: You need to install Arduino IDE WildFire support:
http://shop.wickeddevice.com/resources/wildfire/
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
// Digital the pin that is used to reset/enable the ESP8266 module
const int EspSwitch = 23;
ESP8266 wifi(&Serial1);
void setup()
{
// Debug console
Serial.begin(9600);
delay(10);
// Set ESP8266 baud rate
Serial1.begin(115200);
delay(10);
// Reset ESP
pinMode(EspSwitch, OUTPUT);
digitalWrite(EspSwitch, LOW);
delay(50);
digitalWrite(EspSwitch, HIGH);
// Configure Blynk connection
Blynk.begin(BLYNK_AUTH_TOKEN, wifi, ssid, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,58 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example runs directly on Wio Terminal.
NOTE: This requires Wio Terminal Wi-Fi support package:
https://wiki.seeedstudio.com/Wio-Terminal-Network-Overview/
Please be sure to select the right Wio Terminal module
in the Tools -> Board menu!
Change WiFi ssid, pass, and Blynk auth token to run :)
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <rpcWiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleWioTerminal.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,55 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use WizFi250
to connect your project to Blynk.
NOTE: This requires WizFi250 library
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <WizFi250.h>
#include <BlynkSimpleWizFi250.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
WiFi.init();
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, IPAddress(192,168,1,100), 8080);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,57 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to use WizFi310
to connect your project to Blynk.
NOTE: This requires WizFi310 library
Feel free to apply it to any other example. It's simple!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <WizFi310.h>
#include <BlynkSimpleWizFi310.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// You can also specify server:
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, "blynk.cloud", 80);
//Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, IPAddress(192,168,1,100), 8080);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,188 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
This example code is in public domain.
*************************************************************
App dashboard setup:
Value Display widget on V2
NOTE: Pins 10, 11, 12 and 13 are reserved for Ethernet module.
DON'T use them in your sketch directly!
WARNING: If you have an SD card, you may need to disable it
by setting pin 4 to HIGH. Read more here:
https://www.arduino.cc/en/Main/ArduinoEthernetShield
*************************************************************/
#include <SPI.h>
#include <Ethernet.h>
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
// Blynk cloud server
const char* host = "blynk.cloud";
unsigned int port = 80;
// Network settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetClient client;
#define W5100_CS 10
#define SDCARD_CS 4
// Start the Ethernet connection
void connectNetwork()
{
Serial.println("Connecting to Ethernet...");
pinMode(SDCARD_CS, OUTPUT);
digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
while (true);
}
// Give the Ethernet shield a second to initialize
delay(1000);
Serial.println("Ethernet connected");
}
bool httpRequest(const String& method,
const String& url,
const String& request,
String& response)
{
Serial.print(F("Connecting to "));
Serial.print(host);
Serial.print(":");
Serial.print(port);
Serial.print("... ");
if (client.connect(host, port)) {
Serial.println("OK");
} else {
Serial.println("failed");
return false;
}
Serial.print(method); Serial.print(" "); Serial.println(url);
client.print(method); client.print(" ");
client.print(url); client.println(F(" HTTP/1.1"));
client.print(F("Host: ")); client.println(host);
client.println(F("Connection: close"));
if (request.length()) {
client.println(F("Content-Type: application/json"));
client.print(F("Content-Length: ")); client.println(request.length());
client.println();
client.print(request);
} else {
client.println();
}
//Serial.println("Waiting response");
int timeout = millis() + 5000;
while (client.available() == 0) {
if (timeout - millis() < 0) {
Serial.println(">>> Client Timeout !");
client.stop();
return false;
}
}
//Serial.println("Reading response");
int contentLength = -1;
while (client.available()) {
String line = client.readStringUntil('\n');
line.trim();
line.toLowerCase();
if (line.startsWith("content-length:")) {
contentLength = line.substring(line.lastIndexOf(':') + 1).toInt();
} else if (line.length() == 0) {
break;
}
}
//Serial.println("Reading response body");
response = "";
response.reserve(contentLength + 1);
while (response.length() < contentLength) {
if (client.available()) {
char c = client.read();
response += c;
} else if (!client.connected()) {
break;
}
}
client.stop();
return true;
}
void setup()
{
Serial.begin(9600);
delay(10);
Serial.println();
Serial.println();
connectNetwork();
}
void loop() {
String response;
unsigned long value = millis();
// Send value to the cloud
// similar to Blynk.virtualWrite()
Serial.print("Sending value: ");
Serial.println(value);
if (httpRequest("GET", String("/external/api/update?token=") + BLYNK_AUTH_TOKEN + "&pin=V2&value=" + value, "", response)) {
if (response.length() != 0) {
Serial.print("WARNING: ");
Serial.println(response);
}
}
// Read the value back
// similar to Blynk.syncVirtual()
Serial.println("Reading value");
if (httpRequest("GET", String("/external/api/get?token=") + BLYNK_AUTH_TOKEN + "&pin=V2", "", response)) {
Serial.print("Value from server: ");
Serial.println(response);
}
// Set Property
Serial.println("Setting property");
if (httpRequest("GET", String("/external/api/update/property?token=") + BLYNK_AUTH_TOKEN + "&pin=V2&label=" + value, "", response)) {
if (response.length() != 0) {
Serial.print("WARNING: ");
Serial.println(response);
}
}
// For more HTTP API, see https://docs.blynk.io/en/blynk.cloud/https-api-overview
// Wait
delay(30000L);
}

View File

@@ -0,0 +1,189 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
This example code is in public domain.
*************************************************************
App dashboard setup:
Value Display widget on V2
*************************************************************/
#include <GSM.h>
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
// Blynk cloud server
const char* host = "blynk.cloud";
unsigned int port = 80;
// Network settings
#define PINNUMBER ""
// APN data
#define GPRS_APN "GPRS_APN" // replace your GPRS APN
#define GPRS_LOGIN "login" // replace with your GPRS login
#define GPRS_PASSWORD "password" // replace with your GPRS password
GSMClient client;
GPRS gprs;
GSM gsmAccess;
// Start the GSM connection
void connectNetwork()
{
Serial.println("Connecting to GSM...");
bool status = false;
// After starting the modem with GSM.begin()
// attach the shield to the GPRS network with the APN, login and password
while (status == false) {
if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &
(gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
status = true;
} else {
Serial.print(".");
delay(1000);
}
}
Serial.println();
Serial.println("GSM connected");
}
bool httpRequest(const String& method,
const String& url,
const String& request,
String& response)
{
Serial.print(F("Connecting to "));
Serial.print(host);
Serial.print(":");
Serial.print(port);
Serial.print("... ");
if (client.connect(host, port)) {
Serial.println("OK");
} else {
Serial.println("failed");
return false;
}
Serial.print(method); Serial.print(" "); Serial.println(url);
client.print(method); client.print(" ");
client.print(url); client.println(F(" HTTP/1.1"));
client.print(F("Host: ")); client.println(host);
client.println(F("Connection: close"));
if (request.length()) {
client.println(F("Content-Type: application/json"));
client.print(F("Content-Length: ")); client.println(request.length());
client.println();
client.print(request);
} else {
client.println();
}
//Serial.println("Waiting response");
int timeout = millis() + 5000;
while (client.available() == 0) {
if (timeout - millis() < 0) {
Serial.println(">>> Client Timeout !");
client.stop();
return false;
}
}
//Serial.println("Reading response");
int contentLength = -1;
while (client.available()) {
String line = client.readStringUntil('\n');
line.trim();
line.toLowerCase();
if (line.startsWith("content-length:")) {
contentLength = line.substring(line.lastIndexOf(':') + 1).toInt();
} else if (line.length() == 0) {
break;
}
}
//Serial.println("Reading response body");
response = "";
response.reserve(contentLength + 1);
while (response.length() < contentLength) {
if (client.available()) {
char c = client.read();
response += c;
} else if (!client.connected()) {
break;
}
}
client.stop();
return true;
}
void setup()
{
Serial.begin(9600);
delay(10);
Serial.println();
Serial.println();
connectNetwork();
}
void loop() {
String response;
unsigned long value = millis();
// Send value to the cloud
// similar to Blynk.virtualWrite()
Serial.print("Sending value: ");
Serial.println(value);
if (httpRequest("GET", String("/external/api/update?token=") + BLYNK_AUTH_TOKEN + "&pin=V2&value=" + value, "", response)) {
if (response.length() != 0) {
Serial.print("WARNING: ");
Serial.println(response);
}
}
// Read the value back
// similar to Blynk.syncVirtual()
Serial.println("Reading value");
if (httpRequest("GET", String("/external/api/get?token=") + BLYNK_AUTH_TOKEN + "&pin=V2", "", response)) {
Serial.print("Value from server: ");
Serial.println(response);
}
// Set Property
Serial.println("Setting property");
if (httpRequest("GET", String("/external/api/update/property?token=") + BLYNK_AUTH_TOKEN + "&pin=V2&label=" + value, "", response)) {
if (response.length() != 0) {
Serial.print("WARNING: ");
Serial.println(response);
}
}
// For more HTTP API, see https://docs.blynk.io/en/blynk.cloud/https-api-overview
// Wait
delay(30000L);
}

View File

@@ -0,0 +1,181 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
This example code is in public domain.
*************************************************************
App dashboard setup:
Value Display widget on V2
*************************************************************/
#ifdef ESP32
# include <WiFi.h>
#else
# include <ESP8266WiFi.h>
#endif
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
// Network settings
const char ssid[] = "structure8";
const char pass[] = "lebowski8";
// Blynk cloud server
const char* host = "blynk.cloud";
unsigned int port = 80;
WiFiClient client;
// Start the WiFi connection
void connectNetwork()
{
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
}
bool httpRequest(const String& method,
const String& url,
const String& request,
String& response)
{
Serial.print(F("Connecting to "));
Serial.print(host);
Serial.print(":");
Serial.print(port);
Serial.print("... ");
if (client.connect(host, port)) {
Serial.println("OK");
} else {
Serial.println("failed");
return false;
}
Serial.print(method); Serial.print(" "); Serial.println(url);
client.print(method); client.print(" ");
client.print(url); client.println(F(" HTTP/1.1"));
client.print(F("Host: ")); client.println(host);
client.println(F("Connection: close"));
if (request.length()) {
client.println(F("Content-Type: application/json"));
client.print(F("Content-Length: ")); client.println(request.length());
client.println();
client.print(request);
} else {
client.println();
}
//Serial.println("Waiting response");
int timeout = millis() + 5000;
while (client.available() == 0) {
if (timeout - millis() < 0) {
Serial.println(">>> Client Timeout !");
client.stop();
return false;
}
}
//Serial.println("Reading response");
int contentLength = -1;
while (client.available()) {
String line = client.readStringUntil('\n');
line.trim();
line.toLowerCase();
if (line.startsWith("content-length:")) {
contentLength = line.substring(line.lastIndexOf(':') + 1).toInt();
} else if (line.length() == 0) {
break;
}
}
//Serial.println("Reading response body");
response = "";
response.reserve(contentLength + 1);
while (response.length() < contentLength) {
if (client.available()) {
char c = client.read();
response += c;
} else if (!client.connected()) {
break;
}
}
client.stop();
return true;
}
void setup()
{
Serial.begin(9600);
delay(10);
Serial.println();
Serial.println();
connectNetwork();
}
void loop() {
String response;
unsigned long value = millis();
// Send value to the cloud
// similar to Blynk.virtualWrite()
Serial.print("Sending value: ");
Serial.println(value);
if (httpRequest("GET", String("/external/api/update?token=") + BLYNK_AUTH_TOKEN + "&pin=V2&value=" + value, "", response)) {
if (response.length() != 0) {
Serial.print("WARNING: ");
Serial.println(response);
}
}
// Read the value back
// similar to Blynk.syncVirtual()
Serial.println("Reading value");
if (httpRequest("GET", String("/external/api/get?token=") + BLYNK_AUTH_TOKEN + "&pin=V2", "", response)) {
Serial.print("Value from server: ");
Serial.println(response);
}
// Set Property
Serial.println("Setting property");
if (httpRequest("GET", String("/external/api/update/property?token=") + BLYNK_AUTH_TOKEN + "&pin=V2&label=" + value, "", response)) {
if (response.length() != 0) {
Serial.print("WARNING: ");
Serial.println(response);
}
}
// For more HTTP API, see https://docs.blynk.io/en/blynk.cloud/https-api-overview
// Wait
delay(30000L);
}

View File

@@ -0,0 +1,317 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
This example code is in public domain.
*************************************************************
App dashboard setup:
Value Display widget on V2
Attention!
1. Using your phone:
Disable PIN code on the SIM card
Check your ballance
Check that APN,User,Pass are correct and you have internet
2. Ensure the sim card is correctly inserted into the module
3. Provide a good, stable power supply (up to 2A)
(4.0-4.2V or 5V according to your module documentation)
4. Provide good serial connection
(Hardware Serial is recommended)
5. Check if GSM antenna is attached
*************************************************************/
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
// APN data
#define GPRS_APN "YourAPN" // Replace your GPRS APN
#define GPRS_USER "" // Replace with your GPRS user
#define GPRS_PASSWORD "" // Replace with your GPRS password
// Uncomment this to use HTTPS
//#define USE_HTTPS
// Set Serial to which GSM module is connected
Stream* stream = &Serial1;
// Blynk cloud server
const char* host = "blynk.cloud";
bool gprsInit();
bool gprsConnect();
bool gprsDisconnect();
void setup()
{
Serial.begin(9600);
delay(10);
Serial.println();
Serial.println();
// Setup GPRS module baud rate
Serial1.begin(115200);
delay(3000);
gprsInit();
}
void loop() {
gprsConnect();
String response;
unsigned long value = millis();
// Send value to the cloud
// similar to Blynk.virtualWrite()
Serial.print("Sending value: ");
Serial.println(value);
if (httpRequest("GET", String("/external/api/update?token=") + BLYNK_AUTH_TOKEN + "&pin=V2&value=" + value, "", response)) {
if (response.length() != 0) {
Serial.print("WARNING: ");
Serial.println(response);
}
}
// Read the value back
// similar to Blynk.syncVirtual()
Serial.println("Reading value");
if (httpRequest("GET", String("/external/api/get?token=") + BLYNK_AUTH_TOKEN + "&pin=V2", "", response)) {
Serial.print("Value from server: ");
Serial.println(response);
}
// Set Property
Serial.println("Setting property");
if (httpRequest("GET", String("/external/api/update/property?token=") + BLYNK_AUTH_TOKEN + "&pin=V2&label=" + value, "", response)) {
if (response.length() != 0) {
Serial.print("WARNING: ");
Serial.println(response);
}
}
// For more HTTP API, see https://docs.blynk.io/en/blynk.cloud/https-api-overview
// Disconnect and wait
gprsDisconnect();
Serial.println("Waiting 1 minute...");
Serial.println();
Serial.println();
delay(60000L);
}
/**************************************************************
* AT commands stuff
**************************************************************/
typedef const __FlashStringHelper* GsmConstStr;
void sendAT(const String& cmd) {
stream->print("AT");
stream->println(cmd);
}
uint8_t waitResponse(uint32_t timeout, GsmConstStr r1,
GsmConstStr r2 = NULL, GsmConstStr r3 = NULL)
{
String data;
data.reserve(64);
int index = 0;
for (unsigned long start = millis(); millis() - start < timeout; ) {
while (stream->available() > 0) {
int c = stream->read();
if (c < 0) continue;
data += (char)c;
if (data.indexOf(r1) >= 0) {
index = 1;
goto finish;
} else if (r2 && data.indexOf(r2) >= 0) {
index = 2;
goto finish;
} else if (r3 && data.indexOf(r3) >= 0) {
index = 3;
goto finish;
}
}
}
finish:
return index;
}
uint8_t waitResponse(GsmConstStr r1,
GsmConstStr r2 = NULL, GsmConstStr r3 = NULL)
{
return waitResponse(1000, r1, r2, r3);
}
uint8_t waitOK_ERROR(uint32_t timeout = 1000) {
return waitResponse(timeout, F("OK\r\n"), F("ERROR\r\n"));
}
bool gprsInit()
{
sendAT(F("E0"));
waitOK_ERROR();
sendAT(F("+SAPBR=3,1,\"Contype\",\"GPRS\""));
waitOK_ERROR();
sendAT(F("+SAPBR=3,1,\"APN\",\"" GPRS_APN "\""));
waitOK_ERROR();
#ifdef GPRS_USER
sendAT(F("+SAPBR=3,1,\"USER\",\"" GPRS_USER "\""));
waitOK_ERROR();
#endif
#ifdef GPRS_PASSWORD
sendAT(F("+SAPBR=3,1,\"PWD\",\"" GPRS_PASSWORD "\""));
waitOK_ERROR();
#endif
sendAT(F("+CGDCONT=1,\"IP\",\"" GPRS_APN "\""));
waitOK_ERROR();
return true;
}
// Start the GSM connection
bool gprsConnect()
{
Serial.println("Connecting to GSM...");
sendAT(F("+CGACT=1,1"));
waitOK_ERROR(60000L);
// Open a GPRS context
sendAT(F("+SAPBR=1,1"));
waitOK_ERROR(85000L);
// Query the GPRS context
sendAT(F("+SAPBR=2,1"));
if (waitOK_ERROR(30000L) != 1)
return false;
Serial.println("GSM connected");
return true;
}
bool gprsDisconnect() {
sendAT(F("+SAPBR=0,1"));
if (waitOK_ERROR(30000L) != 1)
return;
sendAT(F("+CGACT=0"));
waitOK_ERROR(60000L);
Serial.println("GSM disconnected");
return true;
}
int httpRequest(const String& method,
const String& url,
const String& request,
String& response)
{
Serial.print(F(" Request: "));
Serial.print(host);
Serial.println(url);
sendAT(F("+HTTPTERM"));
waitOK_ERROR();
sendAT(F("+HTTPINIT"));
waitOK_ERROR();
sendAT(F("+HTTPPARA=\"CID\",1"));
waitOK_ERROR();
#ifdef USE_HTTPS
sendAT(F("+HTTPSSL=1"));
waitOK_ERROR();
sendAT(String(F("+HTTPPARA=\"URL\",\"https://")) + host + url + "\"");
waitOK_ERROR();
#else
sendAT(String(F("+HTTPPARA=\"URL\",\"")) + host + url + "\"");
waitOK_ERROR();
#endif
if (request.length()) {
sendAT(F("+HTTPPARA=\"CONTENT\",\"application/json\""));
waitOK_ERROR();
sendAT(String(F("+HTTPDATA=")) + request.length() + "," + 10000);
waitResponse(F("DOWNLOAD\r\n"));
stream->print(request);
waitOK_ERROR();
}
if (method == "GET") {
sendAT(F("+HTTPACTION=0"));
} else if (method == "POST") {
sendAT(F("+HTTPACTION=1"));
} else if (method == "HEAD") {
sendAT(F("+HTTPACTION=2"));
} else if (method == "DELETE") {
sendAT(F("+HTTPACTION=3"));
}
waitOK_ERROR();
if (waitResponse(30000L, F("+HTTPACTION:")) != 1) {
Serial.println("HTTPACTION Timeout");
return false;
}
stream->readStringUntil(',');
int code = stream->readStringUntil(',').toInt();
size_t len = stream->readStringUntil('\n').toInt();
if (code != 200) {
Serial.print("Error code:");
Serial.println(code);
sendAT(F("+HTTPTERM"));
waitOK_ERROR();
return false;
}
response = "";
if (len > 0) {
response.reserve(len);
sendAT(F("+HTTPREAD"));
if (waitResponse(10000L, F("+HTTPREAD: ")) != 1) {
Serial.println("HTTPREAD Timeout");
return false;
}
len = stream->readStringUntil('\n').toInt();
while (len--) {
while (!stream->available()) {
delay(1);
}
response += (char)(stream->read());
}
waitOK_ERROR();
}
sendAT(F("+HTTPTERM"));
waitOK_ERROR();
return true;
}

View File

@@ -0,0 +1,82 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
Youll need:
- Blynk App (download from AppStore or Google Play)
- Arduino UNO or similar microcontroller board
- Decide how to connect to Blynk
(USB, Ethernet, Wi-Fi, Bluetooth, ...)
There is a bunch of great example sketches included to show you how to get
started. Think of them as LEGO bricks and combine them as you wish.
For example, take the Ethernet Shield sketch and combine it with the
Servo example, or choose a USB sketch and add a code from SendData
example.
*************************************************************
Lets turn ON your LED with Blynk!
In this example we'll use Arduino UNO + Ethernet Shield
5 Steps guide:
1. Connect LED to Pin 9
( http://arduino.cc/en/uploads/Tutorial/simplefade_bb.png )
In the Blynk App:
2. Create New Project
3. Email yourself Auth Token. You can do it later at any time
4. Add a Button Widget. Select Pin D9 in Widget's Settings
5. Press Play icon. Enjoy Blynking!
You can find a QR code for easy setup of this project here:
https://github.com/blynkkk/blynk-library/tree/master/examples/GettingStarted/BlynkBlink
*************************************************************/
#define BLYNK_PRINT Serial // Enables Serial Monitor
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
// Following includes are for Arduino Ethernet Shield (W5100)
// If you're using another shield, see Boards_* examples
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
void setup()
{
// See the connection status in Serial Monitor
Serial.begin(9600);
// Here your Arduino connects to the Blynk Cloud.
Blynk.begin(BLYNK_AUTH_TOKEN);
}
void loop()
{
// All the Blynk Magic happens here...
Blynk.run();
// You can inject your own code or combine it with other sketches.
// Check other examples on how to communicate with Blynk. Remember
// to avoid delay() function!
}

View File

@@ -0,0 +1,62 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
You can use this sketch as a debug tool that prints all incoming values
sent by a widget connected to a Virtual Pin 1 in the Blynk App.
App dashboard setup:
Slider widget (0...100) on V1
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
// This function will be called every time Slider Widget
// in Blynk app writes values to the Virtual Pin 1
BLYNK_WRITE(V1)
{
int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
// You can also use:
// String i = param.asStr();
// double d = param.asDouble();
Serial.print("V1 Slider value is: ");
Serial.println(pinValue);
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,68 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how value can be pushed from Arduino to
the Blynk App.
NOTE:
BlynkTimer provides SimpleTimer functionality:
http://playground.arduino.cc/Code/SimpleTimer
App dashboard setup:
Value Display widget attached to Virtual Pin V5
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
BlynkTimer timer;
// This function sends Arduino's up time every second to Virtual Pin (5).
void myTimerEvent()
{
// You can send any value at any time.
// Please don't send more that 10 values per second.
Blynk.virtualWrite(V5, millis() / 1000);
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
// Setup a function to be called every second
timer.setInterval(1000L, myTimerEvent);
}
void loop()
{
Blynk.run();
timer.run(); // Initiates BlynkTimer
}

View File

@@ -0,0 +1,59 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
Rotate a servo using a slider!
App dashboard setup:
Slider widget (0...180) on V3
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <Servo.h>
Servo servo;
BLYNK_WRITE(V3)
{
servo.write(param.asInt());
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
servo.attach(9);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,58 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This sketch shows how to read values from Virtual Pins
App dashboard setup:
Slider widget (0...100) on Virtual Pin V1
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
// This function will be called every time Slider Widget
// in Blynk app writes values to the Virtual Pin V1
BLYNK_WRITE(V1)
{
int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
// process received value
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,67 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This sketch shows how to write values to Virtual Pins
NOTE:
BlynkTimer provides SimpleTimer functionality:
http://playground.arduino.cc/Code/SimpleTimer
App dashboard setup:
Value Display widget attached to Virtual Pin V5
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
BlynkTimer timer;
// This function sends Arduino's up time every second to Virtual Pin (5)
void myTimerEvent()
{
// You can send any value at any time.
// Please don't send more that 10 values per second.
Blynk.virtualWrite(V5, millis() / 1000);
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
// Setup a function to be called every second
timer.setInterval(1000L, myTimerEvent);
}
void loop()
{
Blynk.run();
timer.run(); // Initiates BlynkTimer
}

View File

@@ -0,0 +1,89 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how value can be pushed from Arduino to
the Blynk App.
WARNING:
For this example you'll need Adafruit DHT sensor libraries:
https://github.com/adafruit/Adafruit_Sensor
https://github.com/adafruit/DHT-sensor-library
App dashboard setup:
Value Display widget attached to V5
Value Display widget attached to V6
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <DHT.h>
#define DHTPIN 2 // What digital pin we're connected to
// Uncomment whatever type you're using!
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22, AM2302, AM2321
//#define DHTTYPE DHT21 // DHT 21, AM2301
DHT dht(DHTPIN, DHTTYPE);
BlynkTimer timer;
// This function sends Arduino's up time every second to Virtual Pin (5)
void sendSensor()
{
float h = dht.readHumidity();
float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// You can send any value at any time.
// Please don't send more that 10 values per second.
Blynk.virtualWrite(V5, h);
Blynk.virtualWrite(V6, t);
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
dht.begin();
// Setup a function to be called every second
timer.setInterval(1000L, sendSensor);
}
void loop()
{
Blynk.run();
timer.run();
}

View File

@@ -0,0 +1,68 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
You can construct and display any strings on a Value Display.
App dashboard setup:
Value Display widget attached to V5
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
BlynkTimer timer;
// This function sends Arduino's up time every second to Virtual Pin (5)
void sendTemperature()
{
// Generate random temperature value 10.0 to 30.0 (for example)
float t = float(random(100, 300)) / 10;
// Format: 1 decimal place, add ℃
String str = String(t, 1) + "";
// Send it to the server
Blynk.virtualWrite(V5, str);
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
// Setup a function to be called every second
timer.setInterval(1000L, sendTemperature);
}
void loop()
{
Blynk.run();
timer.run();
}

View File

@@ -0,0 +1,78 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to keep WiFi connection on ESP8266.
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
int lastConnectionAttempt = millis();
int connectionDelay = 5000; // try to reconnect every 5 seconds
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
}
void loop()
{
// check WiFi connection:
if (WiFi.status() != WL_CONNECTED)
{
// (optional) "offline" part of code
// check delay:
if (millis() - lastConnectionAttempt >= connectionDelay)
{
lastConnectionAttempt = millis();
// attempt to connect to Wifi network:
if (pass && strlen(pass))
{
WiFi.begin((char*)ssid, (char*)pass);
}
else
{
WiFi.begin((char*)ssid);
}
}
}
else
{
Blynk.run();
}
}

View File

@@ -0,0 +1,85 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
Control a color gradient on NeoPixel strip using a slider!
For this example you need NeoPixel library:
https://github.com/adafruit/Adafruit_NeoPixel
App dashboard setup:
Slider widget (0...500) on V1
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <Adafruit_NeoPixel.h>
#define PIN 8
Adafruit_NeoPixel strip = Adafruit_NeoPixel(30, PIN, NEO_GRB + NEO_KHZ800);
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
if (WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
BLYNK_WRITE(V1)
{
int shift = param.asInt();
for (int i = 0; i < strip.numPixels(); i++)
{
strip.setPixelColor(i, Wheel(shift & 255));
// OR: strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + shift) & 255));
}
strip.show();
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
strip.begin();
strip.show();
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,60 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example uses BLYNK_WRITE_DEFAULT to capture arbitrary
virtual pin changes. This may be useful if you have lots
of DataStreams with controls.
It also shows how to iterate over all parameter values.
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
// This is called for all virtual pins, that don't have BLYNK_WRITE handler
BLYNK_WRITE_DEFAULT() {
Serial.print("input V");
Serial.print(request.pin);
Serial.println(":");
// Print all parameter values
for (auto i = param.begin(); i < param.end(); ++i) {
Serial.print("* ");
Serial.println(i.asString());
}
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,105 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
Blynk can provide your device with time data, like an RTC.
Please note that the accuracy of this method is up to several seconds.
Datastream setup:
Virtual Pin V1, type: String
Virtual Pin V2, type: String
App dashboard setup:
Value Display widget on V1
Value Display widget on V2
NOTE: On Web dashboard, use Label widgets
WARNING:
For this example you'll need Time keeping library:
https://github.com/PaulStoffregen/Time
This code is based on an example from the Time library:
https://github.com/PaulStoffregen/Time/blob/master/examples/TimeSerial/TimeSerial.ino
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
BlynkTimer timer;
WidgetRTC rtc;
// Digital clock display of the time
void clockDisplay()
{
// You can call hour(), minute(), ... at any time
// Please see Time library examples for details
String currentTime = String(hour()) + ":" + minute() + ":" + second();
String currentDate = String(day()) + " " + month() + " " + year();
Serial.print("Current time: ");
Serial.print(currentTime);
Serial.print(" ");
Serial.print(currentDate);
Serial.println();
// Send time to the App
Blynk.virtualWrite(V1, currentTime);
// Send date to the App
Blynk.virtualWrite(V2, currentDate);
}
BLYNK_CONNECTED() {
// Synchronize time on connection
rtc.begin();
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
// Other Time library functions can be used, like:
// timeStatus(), setSyncInterval(interval)...
// Read more: http://www.pjrc.com/teensy/td_libs_Time.html
setSyncInterval(10 * 60); // Sync interval in seconds (10 minutes)
// Display digital clock every 10 seconds
timer.setInterval(10000L, clockDisplay);
}
void loop()
{
Blynk.run();
timer.run();
}

View File

@@ -0,0 +1,67 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
Blynk can provide your device with time data, like an RTC.
Please note that the accuracy of this method is up to several seconds.
NOTE: there's a better way to get a detailed time and timezone info.
See TimeAndLocation example for details!
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
BlynkTimer timer;
void requestTime() {
Blynk.sendInternal("rtc", "sync");
}
BLYNK_WRITE(InternalPinRTC) {
long t = param.asLong();
Serial.print("Unix time: ");
Serial.print(t);
Serial.println();
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
timer.setInterval(10000L, requestTime);
}
void loop()
{
Blynk.run();
timer.run();
}

View File

@@ -0,0 +1,82 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows you how you can use server as storage for
your data like EEPROM
App dashboard setup (optional):
Value display on V1
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
BlynkTimer timer;
int uptimeCounter;
String someStaticData = "SomeStaticData";
// This function will run every time Blynk connection is established
BLYNK_CONNECTED() {
//get data stored in virtual pin V0 from server
Blynk.syncVirtual(V0);
}
// restoring counter from server
BLYNK_WRITE(V0)
{
//restoring int value
uptimeCounter = param[0].asInt();
//restoring string value
someStaticData = param[1].asString();
}
void increment() {
uptimeCounter++;
//storing int and string in V0 pin on server
Blynk.virtualWrite(V0, uptimeCounter, someStaticData);
//updating value display with uptimeCounter
Blynk.virtualWrite(V1, uptimeCounter);
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
timer.setInterval(1000L, increment);
}
void loop()
{
Blynk.run();
timer.run();
}

View File

@@ -0,0 +1,76 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows you how you can use server as storage for
your data like EEPROM
App dashboard setup (optional):
Value display on V0
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
BlynkTimer timer;
int uptimeCounter;
// This function will run every time Blynk connection is established
BLYNK_CONNECTED() {
//get data stored in virtual pin V0 from server
Blynk.syncVirtual(V0);
}
// restoring counter from server
BLYNK_WRITE(V0)
{
//restoring int value
uptimeCounter = param.asInt();
}
void increment() {
uptimeCounter++;
//storing int in V0 pin on server
Blynk.virtualWrite(V0, uptimeCounter);
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
timer.setInterval(1000L, increment);
}
void loop()
{
Blynk.run();
timer.run();
}

View File

@@ -0,0 +1,73 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
You can set predefined properties (color, label, ...) of any widget.
Read more: https://docs.blynk.io/en/blynk.edgent-firmware-api/widget-properties
Datastream setup:
Virtual Pin V1, type: Integer, min: 1, max: 3
App dashboard setup:
Menu Widget on V1 with 2 items: "Item 1", "Add items"
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
BLYNK_WRITE(V1) {
int value = param.asInt();
if (value == 1) {
Serial.println("Item 1 selected");
} else if (value == 2) {
// If item 2 is selected, change menu items...
BlynkParamAllocated items(128); // list length, in bytes
items.add("New item 1");
items.add("New item 2");
items.add("New item 3");
Blynk.setProperty(V1, "labels", items);
// You can also use it like this:
//Blynk.setProperty(V1, "labels", "item 1", "item 2", "item 3");
} else {
Serial.println("Unknown item selected");
}
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,80 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
You can set predefined properties (color, label, ...) of any widget.
Read more: https://docs.blynk.io/en/blynk.edgent-firmware-api/widget-properties
App dashboard setup:
Gauge widget (0...100) on V0
Slider widget (0...100) on V1
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#define BLYNK_GREEN "#23C48E"
#define BLYNK_BLUE "#04C0F8"
#define BLYNK_YELLOW "#ED9D00"
#define BLYNK_RED "#D3435C"
#define BLYNK_DARK_BLUE "#5F7CD8"
String gaugeColor;
BLYNK_WRITE(V1) {
int gaugeValue = param.asInt();
String newColor;
if (gaugeValue > 80) {
newColor = BLYNK_RED;
} else if (gaugeValue > 50) {
newColor = BLYNK_YELLOW;
} else {
newColor = BLYNK_GREEN;
}
// Send only if changed
if (newColor != gaugeColor) {
gaugeColor = newColor;
Blynk.setProperty(V0, "color", gaugeColor);
}
Blynk.virtualWrite(V0, gaugeValue);
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,87 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This is a simple stroboscope.
You can turn it on and of using a button,
and control frequency with a slider.
App dashboard setup:
Button widget (Switch) on V1
Slider widget (100...1000) on V2
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#define LED_PIN 4
BlynkTimer timer;
BlynkTimer::Handle t1;
// Toggle LED
void ledBlynk()
{
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
}
// Enable/disable blinking using virtual pin 1
BLYNK_WRITE(V1)
{
if (param.asInt()) {
t1.enable();
} else {
t1.disable();
digitalWrite(LED_PIN, LOW);
}
}
// Change blink interval using virtual pin 2
BLYNK_WRITE(V2)
{
long interval = param.asLong();
t1.changeInterval(interval);
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
// Configure LED and timer
pinMode(LED_PIN, OUTPUT);
t1 = timer.setInterval(500L, ledBlynk);
t1.disable();
}
void loop()
{
Blynk.run();
timer.run();
}

View File

@@ -0,0 +1,85 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to monitor a button state
using interrupts mechanism.
App dashboard setup:
LED widget on V1
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
WidgetLED led1(V1);
// We make these values volatile, as they are used in interrupt context
volatile bool pinChanged = false;
volatile int pinValue = 0;
// Most boards won't send data to WiFi out of interrupt handler.
// We just store the value and process it in the main loop.
void checkPin()
{
// Invert state, since button is "Active LOW"
pinValue = !digitalRead(2);
// Mark pin value changed
pinChanged = true;
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
// Make pin 2 HIGH by default
pinMode(2, INPUT_PULLUP);
// Attach INT to our handler
attachInterrupt(digitalPinToInterrupt(2), checkPin, CHANGE);
}
void loop()
{
Blynk.run();
if (pinChanged) {
// Process the value
if (pinValue) {
led1.on();
} else {
led1.off();
}
// Clear the mark, as we have processed the value
pinChanged = false;
}
}

View File

@@ -0,0 +1,77 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to monitor a button state
using polling mechanism.
App dashboard setup:
LED widget on V1
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
int prevState = -1;
int currState = -1;
long lastChangeTime = 0;
void checkPin()
{
// Invert state, since button is "Active LOW"
int state = !digitalRead(2);
// Debounce mechanism
long t = millis();
if (state != prevState) {
lastChangeTime = t;
}
if (t - lastChangeTime > 50) {
if (state != currState) {
currState = state;
Blynk.virtualWrite(V1, state);
}
}
prevState = state;
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
// Make pin 2 default HIGH, and attach INT to our handler
pinMode(2, INPUT_PULLUP);
}
void loop()
{
Blynk.run();
checkPin();
}

View File

@@ -0,0 +1,78 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
You can synchronize the state of widgets with hardware states,
even if hardware resets or looses connection temporarily
App dashboard setup:
Slider widget (0...1024) on V0
Value display (0...1024) on V2
Button widget on digital pin (connected to an LED)
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
// This function will run every time Blynk connection is established
BLYNK_CONNECTED() {
// Request Blynk server to re-send latest values for all pins
Blynk.syncAll();
// You can also update individual virtual pins like this:
//Blynk.syncVirtual(V0, V2);
// Let's write your hardware uptime to Virtual Pin 2
int value = millis() / 1000;
Blynk.virtualWrite(V2, value);
}
BLYNK_WRITE(V0)
{
// Use of syncAll() will cause this function to be called
// Parameter holds last slider value
int sliderValue0 = param.asInt();
}
BLYNK_WRITE(V2)
{
// You'll get uptime value here as result of syncAll()
int uptime = param.asInt();
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,102 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how to synchronize Button widget
and physical button state.
App dashboard setup:
Button widget attached to V2 (Switch mode)
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
// Set your LED and physical button pins here
const int ledPin = 13;
const int btnPin = 12;
BlynkTimer timer;
void checkPhysicalButton();
int ledState = LOW;
int btnState = HIGH;
// Every time we connect to the cloud...
BLYNK_CONNECTED() {
// Request the latest state from the server
Blynk.syncVirtual(V2);
// Alternatively, you could override server state using:
//Blynk.virtualWrite(V2, ledState);
}
// When App button is pushed - switch the state
BLYNK_WRITE(V2) {
ledState = param.asInt();
digitalWrite(ledPin, ledState);
}
void checkPhysicalButton()
{
if (digitalRead(btnPin) == LOW) {
// btnState is used to avoid sequential toggles
if (btnState != LOW) {
// Toggle LED state
ledState = !ledState;
digitalWrite(ledPin, ledState);
// Update Button Widget
Blynk.virtualWrite(V2, ledState);
}
btnState = LOW;
} else {
btnState = HIGH;
}
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
pinMode(ledPin, OUTPUT);
pinMode(btnPin, INPUT_PULLUP);
digitalWrite(ledPin, ledState);
// Setup a function to be called every 100 ms
timer.setInterval(100L, checkPhysicalButton);
}
void loop()
{
Blynk.run();
timer.run();
}

View File

@@ -0,0 +1,97 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
Blynk can provide your device with time and location data.
NOTE: the accuracy of this method is up to several seconds.
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
BLYNK_CONNECTED() {
// Send requests for different internal data
// Request what is actually needed for your use-case
Blynk.sendInternal("utc", "tz_name"); // Name of timezone
Blynk.sendInternal("utc", "iso"); // ISO-8601 formatted time
Blynk.sendInternal("utc", "time"); // Unix timestamp (with msecs)
Blynk.sendInternal("utc", "tz"); // Timezone and DST offsets
Blynk.sendInternal("utc", "tz_rule"); // POSIX TZ rule
Blynk.sendInternal("utc", "dst_next"); // Up to 2 next time offset changes (due to DST)
}
// Receive UTC data
BLYNK_WRITE(InternalPinUTC) {
String cmd = param[0].asStr();
if (cmd == "time") {
uint64_t utc_time = param[1].asLongLong();
Serial.print("Unix time (UTC): "); Serial.println((uint32_t)(utc_time/1000));
} else if (cmd == "iso") {
String iso_time = param[1].asStr();
Serial.print("ISO-8601 time: "); Serial.println(iso_time);
} else if (cmd == "tz") {
long tz_offset = param[1].asInt();
long dst_offset = param[2].asInt();
Serial.print("TZ offset: "); Serial.print(tz_offset); Serial.println(" minutes");
Serial.print("DST offset: "); Serial.print(dst_offset); Serial.println(" minutes");
} else if (cmd == "tz_name") {
String tz_name = param[1].asStr();
Serial.print("Timezone: "); Serial.println(tz_name);
} else if (cmd == "tz_rule") {
String tz_rule = param[1].asStr();
Serial.print("POSIX TZ rule: "); Serial.println(tz_rule);
} else if (cmd == "dst_next") {
uint32_t next1_ts = param[1].asLong();
int next1_off = param[2].asInt();
uint32_t next2_ts = param[3].asLong();
int next2_off = param[4].asInt();
Serial.print("Next offset changes: ");
Serial.print(next1_off); Serial.print("min. on "); Serial.print(next1_ts);
Serial.print(", ");
Serial.print(next2_off); Serial.print("min. on "); Serial.print(next2_ts);
Serial.println();
}
}
void setup()
{
// Debug console
Serial.begin(115200);
Blynk.begin(BLYNK_AUTH_TOKEN);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,65 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
You can receive x and y coords for joystick movement within App.
Datastream setup:
Virtual Pin V0, type: String
App dashboard setup:
Add Joystick widget, select mode: Advanced, attach it V0
NOTE: Advanced mode means device will receive both x and y on a single Datastream
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
BLYNK_WRITE(V0) {
int x = param[0].asInt();
int y = param[1].asInt();
// Do something with x and y
Serial.print("X = ");
Serial.print(x);
Serial.print("; Y = ");
Serial.println(y);
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,60 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
Output any data on LCD widget!
Datastream setup:
Virtual Pin V9, type: String
App dashboard setup:
LCD widget, switch to ADVANCED mode, attach it to V9
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
WidgetLCD lcd(V9);
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
lcd.clear(); //Use it to clear the LCD Widget
lcd.print(4, 0, "Hello"); // use: (position X: 0-15, position Y: 0-1, "Message you want to print")
lcd.print(4, 1, "World");
// Please use timed events when LCD printintg in void loop to avoid sending too many commands
// It will cause a FLOOD Error, and connection will be dropped
}
void loop()
{
Blynk.run();
}

View File

@@ -0,0 +1,74 @@
/*************************************************************
Blynk is a platform with iOS and Android apps to control
ESP32, Arduino, Raspberry Pi and the likes over the Internet.
You can easily build mobile and web interfaces for any
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: https://www.blynk.io
Sketch generator: https://examples.blynk.cc
Blynk community: https://community.blynk.cc
Follow us: https://www.fb.com/blynkapp
https://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
Output any data on LCD widget!
Datastream setup:
Virtual Pin V8, type: Integer, min: 0, max: 10000
Virtual Pin V9, type: Integer, min: 0, max: 10000000
App dashboard setup:
LCD widget, SIMPLE mode. In Settings tab:
- Attach V8 to first line
- Attach V9 to second line
Switch to Design tab:
- Set first line message to: "/value1/ seconds"
- Set second line message to: "/value2/ ms"
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
//#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME "Device"
//#define BLYNK_AUTH_TOKEN "YourAuthToken"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
BlynkTimer timer;
void sendSeconds() {
Blynk.virtualWrite(V8, millis() / 1000);
}
void sendMillis() {
Blynk.virtualWrite(V9, millis());
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(BLYNK_AUTH_TOKEN);
// Setup a function to be called every second
timer.setInterval(1000L, sendSeconds);
// Setup a function to be called every second
timer.setInterval(1000L, sendMillis);
}
void loop()
{
Blynk.run();
timer.run();
}

Some files were not shown because too many files have changed in this diff Show More