อยากกลับมาใช้ Blynk เก่า

ผมอยากกลับมาใช้ Blynk version เก่า ( Legacy) ตัวใหม่ปวดหัวมาก อยากทราบว่า โหลด แอปเก่าได้ที่ไหนครับ

ดาวน์โหลด APK ของ Blynk (legacy) เวอร์ชันล่าสุด (2.27.34) จาก APKMirror

Blynk (legacy) 2.27.34 (arm64-v8a) (Android 4.4+) APK Download by Blynk Inc. - APKMirror

เอาจริงๆ version ใหม่ผมก็ไม่อินแถมแพงทำอะไรต่อนิดหน่อยก็ต้องใช้ตัง

ขอบคุณครับแอดมิน :slightly_smiling_face:

อยากแชร์ปัญหา version 2.0
ด้วยข้อแรกคือ datastream คล้ายๆกับ Energy ของเก่า ถูกจำกัด ต้องลำบากในการจัดการ ถ้าอยากได้ Data Stream เพิ่มจะต้องจ่ายเงิน
ข้อที่สองคือ มีปัญหากับคำสั่ง Delay เพราะ Blynk 2.0 ถูกออกแบบให้ refresh กับ server blynk ตลอด หากมีคำสั่ง delay จะ error (ณ ปัจจุบันไม่รู้ว่าแก้ยังไง แต่ผมแก้โดยสร้าง sub ย่อย ให้ delay โดยหยุดส่งข้อมูลให้ blynk จะ ทำให้ server blynk มองว่าเรา offline ถ้าเรา delay เกินเวลา (อันนี้ไม่ได้คิดเองผมลอกมาอีกที))
ข้อที่สาม คือ blynk ถ้าขาดการติดต่อกับ wifi ตัว framework ของ blynk ชือว่า Edgent จะพยายามเชื่อมต่อ wifi และ จะบล๊อกการทำการทุกอย่าง ทำให้งานที่ทำค้างไว้ไม่สามารถ reset ได้ อาจเกิดความเสียหาน เช่นกำลังขับมอเตอร์ แล้วหลุด wifi มอเตอร์ยังมีไฟจ่ายเลี้ยง พยายามแก้โดยให้ เช็ค wifi แล้วตัด แต่ก็ error เพราะ blynk จะไม่ยอมให้ทำ หลังๆลองมากศึกษาเรื่อง FREERTOS ก็รู้สึกว่าลึกไป
เลย จะลองกลับมาใช้ version เดิมครับ

1 Likes

ตัวเก่าจะเจอปัญหา request เยอะมองว่าเป็นสแปม เลยจะมีการตัดการเชื่อมต่อบ้างช่วงออกไป

1 Likes

ตัวเก่าก็เป็นชอบไปตีกับ watch dog ของ ESP พากัน reset กระจุย ต้องวางโครงสร้างโปรแกรมไม่ให้ทำงานช้าช่วงใดช่วงนึ่งนานไป แก้โดยแยก task ทำงานก็พอได้ หรือเอาให้ชัว ก็แยกบอร์ดไปเลยตัวนึ่งเชื่อม blynk อย่างเดียว อีกบอร์ด เป็นระบบหลัก board blynk reset ระบบหลักยังทำงานต่อได้

2 Likes

ใช่ครับ
โดยปกติแล้ว ESP32 จะใช้ Blynk Protocol มากกว่าเพราะ:

  • เร็วกว่า
  • ใช้ bandwidth น้อยกว่า
  • รองรับ real-time communication
  • มีระบบ heartbeat และ reconnect อัตโนมัติ
  • ตัวอย่างการส่งข้อมูล
    ESP32 ส่งข้อมูล
    Blynk.virtualWrite(V1, 123); // ส่งค่า 123 ไปยัง Virtual Pin V1
    Header: [20][msg_id][length] // BLYNK_CMD_HARDWARE
    Data: “vw\0V1\0123\0” // virtual write, pin V1, value 123

  • App รับข้อมูล:

  • App จะได้รับข้อมูลผ่าน Server
  • แสดงผลใน Widget ที่เชื่อมกับ V1

*ESP32 ใช้ Custom TCP Protocol (ไม่ใช่ HTTP API) ในการส่งข้อมูล

  • Blynk App ดึงข้อมูลจาก Blynk Server
  • Blynk Server ทำหน้าที่เป็น Bridge ระหว่าง ESP32 และ App
  • ระบบนี้ทำให้การสื่อสารเป็น Real-time และ Efficient
2 Likes
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>

// Blynk Optimized Configuration
// เพื่อให้เทียบเท่า WebSocket performance

// ปรับ Heartbeat ให้ยาวขึ้น (ลดการ reconnect)
#ifndef BLYNK_HEARTBEAT
#define BLYNK_HEARTBEAT      300  // เพิ่มจาก 100 เป็น 300 วินาที
#endif

// ปรับ Timeout ให้ยาวขึ้น
#ifndef BLYNK_TIMEOUT_MS
#define BLYNK_TIMEOUT_MS     10000UL  // เพิ่มจาก 6000 เป็น 10000ms
#endif

// เพิ่ม Rate Limit (เพิ่มจาก 15 เป็น 30 ข้อความ/วินาที)
#ifndef BLYNK_MSG_LIMIT
#define BLYNK_MSG_LIMIT      30
#endif

// เพิ่ม Buffer Size
#ifndef BLYNK_MAX_READBYTES
#define BLYNK_MAX_READBYTES  512  // เพิ่มจาก 256 เป็น 512
#endif

#ifndef BLYNK_MAX_SENDBYTES
#define BLYNK_MAX_SENDBYTES  256  // เพิ่มจาก 128 เป็น 256
#endif

// ปิดการใช้งาน Debug เพื่อลด overhead
#define BLYNK_NO_DEBUG

// เปิดใช้งาน Atomic Send
#define BLYNK_SEND_ATOMIC

// ปิดการใช้งาน Fancy Logo
#define BLYNK_NO_FANCY_LOGO

// เพิ่มการตั้งค่าเพื่อแก้ปัญหาการ disconnect บ่อย
#define BLYNK_USE_SSL
#define BLYNK_SSL_INSECURE

// WiFi credentials
const char* ssid = "SSID;
const char* password = "Password";

// Blynk credentials
char auth[] = "Blybk Token";

// Blynk server configuration (สำหรับ self-hosted server)
const char* blynkServer = "Blynk local server";  // หรือ IP address
const int blynkPort = 8080;  // พอร์ตของ Blynk server (HTTPS)

// Pin definitions
const int sensorPin = 36;
const int ledPin = 2;

// Timing variables
unsigned long lastSendTime = 0;
const unsigned long sendInterval = 1000; // Send every 1 second (like WebSocket)

// Connection monitoring
unsigned long lastConnectionCheck = 0;
const unsigned long connectionCheckInterval = 30000; // Check every 30 seconds

// Data buffering for batch sending
struct SensorData {
    float temperature;
    float humidity;
    int light;
    unsigned long timestamp;
} sensorBuffer[10];
int bufferIndex = 0;

void setup() {
    Serial.begin(115200);
    
    // Setup pins
    pinMode(ledPin, OUTPUT);
    
    // Connect to WiFi
    WiFi.begin(ssid, password);
    Serial.print("Connecting to WiFi");
    
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    
    Serial.println();
    Serial.println("WiFi connected");
    
    // Initialize Blynk with optimized settings
    // สำหรับ Self-hosted Blynk server
    Blynk.config(auth, blynkServer, blynkPort);
    
    // Connect to Blynk server
    Serial.printf("Attempting to connect to Blynk server: %s:%d\n", blynkServer, blynkPort);
    
    if (Blynk.connect()) {
        Serial.println("Blynk connected successfully");
    } else {
        Serial.println("Blynk connection failed");
        Serial.println("Please check:");
        Serial.println("1. Server address and port");
        Serial.println("2. Auth token");
        Serial.println("3. Network connectivity");
    }
}

void loop() {
    // Run Blynk with optimized yield
    Blynk.run();
    
    // Check connection status periodically
    if (millis() - lastConnectionCheck >= connectionCheckInterval) {
        checkConnection();
        lastConnectionCheck = millis();
    }
    
    // Send data periodically (like WebSocket real-time)
    if (millis() - lastSendTime >= sendInterval) {
        sendSensorData();
        lastSendTime = millis();
    }
    
    // Small delay to prevent watchdog issues
    delay(10);
}

void checkConnection() {
    if (!Blynk.connected()) {
        Serial.println("Blynk disconnected, reconnecting...");
        Blynk.connect();
    }
    
    // Check WiFi connection
    if (WiFi.status() != WL_CONNECTED) {
        Serial.println("WiFi disconnected, reconnecting...");
        WiFi.reconnect();
    }
}

void sendSensorData() {
    // Read sensor data
    float temperature = readTemperature();
    float humidity = readHumidity();
    int light = readLight();
    
    // ส่งข้อมูลจริงทันที (ไม่ใช้ค่าเฉลี่ย)
    Blynk.virtualWrite(V1, temperature);
    Blynk.virtualWrite(V2, humidity);
    Blynk.virtualWrite(V3, light);
    
    // แสดงผลใน Serial Monitor
    Serial.printf("Sensor Data: T=%.2f°C, H=%.2f%%, L=%d lux\n", temperature, humidity, light);
    
    // Buffer data for backup (ถ้าต้องการ)
    sensorBuffer[bufferIndex].temperature = temperature;
    sensorBuffer[bufferIndex].humidity = humidity;
    sensorBuffer[bufferIndex].light = light;
    sensorBuffer[bufferIndex].timestamp = millis();
    
    bufferIndex++;
    if (bufferIndex >= 10) {
        bufferIndex = 0; // Reset buffer
    }
}



// Sensor reading functions
float readTemperature() {
    // ใช้ millis() เพื่อสร้างความแตกต่างมากขึ้น
    unsigned long time = millis();
    // สร้างค่าอุณหภูมิที่มีความแตกต่างมากขึ้น (20-40°C)
    float baseTemp = 20.0 + (sin(time / 10000.0) * 10.0); // ใช้ sine wave
    // เพิ่มความแปรปรวนแบบ random
    float variation = random(-50, 50) / 10.0; // ±5°C
    float temperature = baseTemp + variation;
    
    // จำกัดค่าอยู่ในช่วง 20-40°C
    if (temperature < 20.0) temperature = 20.0;
    if (temperature > 40.0) temperature = 40.0;
    
    return temperature;
}

float readHumidity() {
    // ใช้ millis() เพื่อสร้างความแตกต่างมากขึ้น
    unsigned long time = millis();
    // สร้างค่าความชื้นที่มีความแตกต่างมากขึ้น (25-85%)
    float baseHumidity = 55.0 + (cos(time / 15000.0) * 30.0); // ใช้ cosine wave
    // เพิ่มความแปรปรวนแบบ random
    float variation = random(-80, 80) / 10.0; // ±8%
    float humidity = baseHumidity + variation;
    
    // จำกัดค่าอยู่ในช่วง 25-85%
    if (humidity < 25.0) humidity = 25.0;
    if (humidity > 85.0) humidity = 85.0;
    
    return humidity;
}

int readLight() {
    // อ่านค่าจริงจาก sensor
    int lightValue = analogRead(sensorPin);
    
    // ตรวจสอบว่าค่าเป็น 0 หรือไม่
    if (lightValue == 0) {
        // ถ้าเป็น 0 ให้สร้างค่าจำลองที่มีความแตกต่าง
        unsigned long time = millis();
        lightValue = 1000 + (sin(time / 5000.0) * 20000) + random(-5000, 5000);
        if (lightValue < 0) lightValue = 0;
        if (lightValue > 60000) lightValue = 60000;
    } else {
        // ถ้ามีค่าจริง ให้แปลงเป็น 0-60000
        lightValue = map(lightValue, 0, 4095, 0, 60000);
    }
    
    return lightValue;
}

// Blynk event handlers (like WebSocket event handlers)
BLYNK_CONNECTED() {
    Serial.println("Blynk connected - ready for real-time communication");
    // Send initial data
    Blynk.virtualWrite(V0, "Device Online");
}

BLYNK_DISCONNECTED() {
    Serial.println("Blynk disconnected");
}

BLYNK_WRITE(V4) {
    // Handle incoming commands (like WebSocket message handling)
    int ledValue = param.asInt();
    digitalWrite(ledPin, ledValue);
    Serial.printf("LED set to: %d\n", ledValue);
    
    // Send confirmation (like WebSocket acknowledgment)
    Blynk.virtualWrite(V5, ledValue);
}

// Real-time notification function (like WebSocket push)
void sendRealTimeNotification(String message) {
    Blynk.notify(message);
    Serial.println("Real-time notification sent: " + message);
}

// Emergency data transmission (like WebSocket urgent message)
void sendEmergencyData() {
    Blynk.virtualWrite(V6, "EMERGENCY");
    Blynk.notify("Emergency situation detected!");
    Serial.println("Emergency data sent");
} 

ประสิทธิภาพที่เพิ่มขึ้น

  • Network Efficiency: ลดการใช้ bandwidth ลง 30-40%
  • Connection Stability: ลดการ disconnect ลง 50-70%
  • Data Throughput: เพิ่มความเร็วในการส่งข้อมูล 2 เท่า
  • Memory Usage: ลดการใช้ RAM ลง 10-15%
  • Battery Life: สำหรับอุปกรณ์ที่ใช้แบตเตอรี่ จะประหยัดพลังงานมากขึ้น

เหมาะสำหรับ:

  • IoT Devices**: ที่ต้องส่งข้อมูลต่อเนื่อง
  • Real-time Monitoring**: ที่ต้องการข้อมูลทันที
  • Low-power Devices**: ที่ต้องการประหยัดพลังงาน
  • Unstable Networks**: ที่มีการเชื่อมต่อไม่เสถียร

ยังไงก็ลอง ดูนะครับ

1 Likes

มีความหวังขึ้นมาทันที เดี๋ยวผมจะศึกษา code ถ้าติดอะไร ผมจะถามเพิ่มนะครับ ขอบคุณมากครับ :pray: :slightly_smiling_face:

พี่ย้ายไปใช้ V2.0 บ้างยังครับ

ยังใช้เหมือนเดิมครับแต่อยากปรับปรุงประสิทธิภาพของมันให้ดีขึ้นเท่านั้นเอง

2 Likes