The use of the ESP8266 in the world of IoT

User avatar
By mybluox
#77847 Hi all, I'm new here; so if I posted this in the wrong forum, I'm sorry.

I'm trying to setup my ModeMCU to get it's updates from a web server. I set up a PHP file to make sure it doesn't keep downloading the update file. My web site is being hosted by Ipower.com It's not local so I'm have a hard time getting verbose error logs. I do know that I can access the php file by the NodeMCU. I'm currently getting this error: HTTP_UPDATE_FAILD Error (-103): Forbidden (403. It makes me think that I'm not using the right MAC address. When I flash the NodeMCU with the NodeMCU flasher I get 2 MAC address's, AP and STA.

When I use a script to get the MAC address I get a different MAC address. I've tried all 3 mac address's in my script and still get an error.

Here is my sketch. Edited for security..,:
Code: Select all
#define BLYNK_PRINT Serial
#include <Arduino.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266httpUpdate.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
// #include <Wire.h>
#define N_DIMMERS 3
#define led_pin D0
#define USE_SERIAL Serial
#define led_blink D1

ESP8266WiFiMulti WiFiMulti;

int dimmer_pin[] = {14, 5, 15};

// Voltage Sensor Data
float vout = 0.0;
float vin = 0.0;
float R1 = 29980.0; //
float R2 = 7520.0; //
int value = 0;

char auth[] = "adaefce52c2a4ac09f98800fbe76a87b";

char ssid[] = "**";
char pass[] = "**";
char host[] = "ESP-OTA";


// Select your pin with physical button
const int btnPin = D5;
const int Stop = D6;
const int Prime = D6;


WidgetLED led3(V3);
WidgetLED led4(V4);

BlynkTimer timer;

BLYNK_CONNECTED() {
  Blynk.syncAll();
}


void LedWidget() {
  if  (digitalRead(btnPin) == HIGH) {  // Sets LED widget ON or OFF depending on state of btnpin

    led3.on();

  } else {

    led3.off ();


  }
  if  (digitalRead(Stop) == HIGH) {  // Sets LED widget ON or OFF depending on state of btnpin

    led4.on();

  } else {

    led4.off ();

  }
}

void ButtonWidget() {
  if  (digitalRead(btnPin) == HIGH) {  // Sets LED widget ON or OFF depending on state of btnpin

    Blynk.virtualWrite(V20, HIGH);
  } else {

    Blynk.virtualWrite(V20, LOW);
  }
  if  (digitalRead(Stop) == HIGH) {  // Sets LED widget ON or OFF depending on state of btnpin

    Blynk.virtualWrite(V21, HIGH);
  } else {

    Blynk.virtualWrite(V21, LOW);
  }
  if  (digitalRead(Prime) == HIGH) {  // Sets LED widget ON or OFF depending on state of btnpin

    Blynk.virtualWrite(V22, HIGH);

  } else {

    Blynk.virtualWrite(V22, LOW);
  }

}
void myTimerEvent(){
 
  value = analogRead(A0);
  vout = (value * 3.253 / 1024); // see text
  vin = vout / (R2 / (R1 + R2));
  Blynk.virtualWrite(V1, vin);
 

}
void myBlinkEvent(){
  digitalWrite(led_blink, HIGH);   
  delay(1000);             
  digitalWrite(led_blink, LOW);   
  delay(1000);

}
void myUpdateEvent(){

    // wait for WiFi connection
  if ((WiFiMulti.run() == WL_CONNECTED))
  {

   t_httpUpdate_return ret = ESPhttpUpdate.update("**", 80, "/bin/nodemcu.php");
    //t_httpUpdate_return  ret = ESPhttpUpdate.update("https://server/file.bin", "", "fingerprint");

    switch (ret) {
      case HTTP_UPDATE_FAILED:
        USE_SERIAL.printf("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
        break;

      case HTTP_UPDATE_NO_UPDATES:
        USE_SERIAL.println("HTTP_UPDATE_NO_UPDATES");
        break;

      case HTTP_UPDATE_OK:
        USE_SERIAL.println("HTTP_UPDATE_OK");
        break;
    }
  } 
}
void setup()
{
  Serial.begin(115200);
  // USE_SERIAL.setDebugOutput(true);
  Blynk.begin(auth, ssid, pass);
  pinMode(led_pin, OUTPUT);
  digitalWrite(led_pin, LOW);
  pinMode(btnPin, OUTPUT);
  pinMode(Stop, OUTPUT);
  pinMode(led_blink, OUTPUT);
  digitalWrite(btnPin, LOW);
  digitalWrite(Stop, LOW);
  timer.setInterval(100L, LedWidget);
  timer.setInterval(100L, ButtonWidget);
  timer.setInterval(1000L, myTimerEvent);
  timer.setInterval(2000L, myBlinkEvent);
  timer.setInterval(60000L, myUpdateEvent);

  Serial.println("Booting");

  for (uint8_t t = 4; t > 0; t--) {
   USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
   USE_SERIAL.flush();
   delay(1000);
  }
  WiFi.mode(WIFI_STA);



  Blynk.begin(auth, ssid, pass);



  while (WiFi.waitForConnectResult() != WL_CONNECTED) {

    Blynk.begin(auth, ssid, pass);

    Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
    Serial.println("Retrying connection...");

  }

  /* switch off led */

  digitalWrite(led_pin, HIGH);



  /* configure dimmers, and OTA server events */

  analogWriteRange(1000);

  analogWrite(led_pin, 990);



  for (int i = 0; i < N_DIMMERS; i++) {

    pinMode(dimmer_pin[i], OUTPUT);

    analogWrite(dimmer_pin[i], 50);

  }



  ArduinoOTA.setHostname(host);

  ArduinoOTA.onStart([]() { // switch off all the PWMs during upgrade

    for (int i = 0; i < N_DIMMERS; i++) {

      analogWrite(dimmer_pin[i], 0);

    }

    analogWrite(led_pin, 0);

  });



  ArduinoOTA.onEnd([]() { // do a fancy thing with our board led at end

    for (int i = 0; i < 30; i++) {

      analogWrite(led_pin, (i * 100) % 1001);

      delay(50);

    }

  });



  ArduinoOTA.onError([](ota_error_t error) {

    (void)error;

    ESP.restart();

  });



  /* setup the OTA server */

  ArduinoOTA.begin();

  Serial.println("Ready");


}

BLYNK_WRITE(V20) {
  digitalWrite(btnPin, param.asInt());  // Sets btnPin HIGH or LOW depending on state of Button Widget.
  int value = param.asInt();
  if (value == 1) {
    Serial.println("Start x on");
    digitalWrite(btnPin, HIGH);
    timer.setTimeout(10000L, []() { // 10 seconds
      digitalWrite(btnPin, LOW);

    });  // END Timer Function

    Blynk.virtualWrite(V20, LOW);
    //stop running
  }
}
BLYNK_WRITE(V21) {
  digitalWrite(Stop, param.asInt());  // Sets btnPin HIGH or LOW depending on state of Button Widget.
  int kill = param.asInt();
  if (kill == 1) {
    Serial.println("Shutdown x on");
    digitalWrite(Stop, HIGH);
    timer.setTimeout(1000L, []() { // 1 seconds
      digitalWrite(Stop, LOW);

    });  // END Timer Function

    Blynk.virtualWrite(V20, LOW);
    //stop running
  }
}
BLYNK_WRITE(V22) {
  digitalWrite(btnPin, param.asInt());  // Sets btnPin HIGH or LOW depending on state of Button Widget.
  int prime = param.asInt();
  if (prime == 1) {
    Serial.println("Prime x on");
    digitalWrite(Stop, HIGH);
    timer.setTimeout(15000L, []() { // 15 seconds
      digitalWrite(Stop, LOW);

    });  // END Timer Function

    Blynk.virtualWrite(V22, LOW);
    //stop running
  }
}

BLYNK_WRITE(V23) {
  digitalWrite(btnPin, param.asInt());  // Sets btnPin HIGH or LOW depending on state of Button Widget.
}

BLYNK_WRITE(V24) {
  digitalWrite(btnPin, param.asInt());  // Sets btnPin HIGH or LOW depending on state of Button Widget.
}

void loop()
{
  Blynk.run();
  ArduinoOTA.handle();
  timer.run();
}


Here is my PHP file:
Code: Select all<?php

header('Content-type: text/plain; charset=utf8', true);

function check_header($name, $value = false) {
    if(!isset($_SERVER[$name])) {
        return false;
    }
    if($value && $_SERVER[$name] != $value) {
        return false;
    }
    return true;
}

function sendFile($path) {
    header($_SERVER["SERVER_PROTOCOL"].' 200 OK', true, 200);
    header('Content-Type: application/octet-stream', true);
    header('Content-Disposition: attachment; filename='.basename($path));
    header('Content-Length: '.filesize($path), true);
    header('x-MD5: '.md5_file($path), true);
    readfile($path);
}

if(!check_header('HTTP_USER_AGENT', 'ESP8266-http-Update')) {
    header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
    echo "only for ESP8266 updater!\n";
    exit();
}

if(
    !check_header('HTTP_X_ESP8266_STA_MAC') ||
    !check_header('HTTP_X_ESP8266_AP_MAC') ||
    !check_header('HTTP_X_ESP8266_FREE_SPACE') ||
    !check_header('HTTP_X_ESP8266_SKETCH_SIZE') ||
    !check_header('HTTP_X_ESP8266_CHIP_SIZE') ||
    !check_header('HTTP_X_ESP8266_SDK_VERSION') ||
    !check_header('HTTP_X_ESP8266_VERSION')
) {
    header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
    echo "only for ESP8266 updater! (header)\n";
    exit();
}

$db = array(
    "38:2B:78:03:84:A3" => "update.bin"  # <-- I have added the ESP MAC address and file name
);

if(isset($db[$_SERVER['HTTP_X_ESP8266_STA_MAC']])) {
    if($db[$_SERVER['HTTP_X_ESP8266_STA_MAC']] != $_SERVER['HTTP_X_ESP8266_VERSION'])  {
        sendFile("./bin/".$db[$_SERVER['HTTP_X_ESP8266_STA_MAC']]."bin");
    } else {
        header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304);
    }
    exit();
}

header($_SERVER["SERVER_PROTOCOL"].' 500 no version for ESP MAC', true, 500);
?>


Any help will be appreciated.

Thank you