Blinkled - Help

I would also like an example of multiple LEDs

I searched the code of tinywebserver blinkled example, but I don't know where to start,
Any help or an example would be appreciated

After testing and debugging today I managed to get a second LED working,

just some problems,
the page shows 2 Lamps, but the status of lamp1 and lamp2 remains the same.
Lamp 2 goes on when I click it on the page, but it wont turn off.

anyone that can help me out ?

here is my code (also next post):

Arduino:

// -*- c++ -*-
//
// Copyright 2010 Ovidiu Predescu <ovidiu@gmail.com>
// Date: December 2010
//

#include <SPI.h>
#include <Ethernet.h>
#include <Flash.h>
#include <SdFat.h>
#include <SdFatUtil.h>
#include <TinyWebServer.h>

// The LED attached in PIN 13 on an Arduino board.
const int ledPin = 7;
const int ledPin2 = 8;

// The initial state of the LED
int ledState = LOW;
int ledState2 = LOW;

void setLedEnabled(boolean state) {
  ledState = state;
  digitalWrite(ledPin, ledState);
}

void setLed2Enabled(boolean state2) {
  ledState2 = state2;
  digitalWrite(ledPin2, ledState2);
}


inline boolean getLedState() { return ledState; }
inline boolean getLedState2() { return ledState2; }

boolean file_handler(TinyWebServer& web_server);
boolean blink_led_handler(TinyWebServer& web_server);
boolean blink_led2_handler(TinyWebServer& web_server);
boolean led_status_handler(TinyWebServer& web_server);
boolean led2_status_handler(TinyWebServer& web_server);
boolean index_handler(TinyWebServer& web_server);

TinyWebServer::PathHandler handlers[] = {
  // Work around Arduino's IDE preprocessor bug in handling /* inside
  // strings.
  //
  // `put_handler' is defined in TinyWebServer
  {"/", TinyWebServer::GET, &index_handler },
  {"/upload/" "*", TinyWebServer::PUT, &TinyWebPutHandler::put_handler },
  {"/blinkled", TinyWebServer::POST, &blink_led_handler },
  {"/blinkled2", TinyWebServer::POST, &blink_led2_handler },
  {"/ledstatus" "*", TinyWebServer::GET, &led_status_handler },
  {"/ledstatus2" "*", TinyWebServer::GET, &led2_status_handler },
  {"/" "*", TinyWebServer::GET, &file_handler },
  {NULL},
};

const char* headers[] = {
  "Content-Length",
  NULL
};

TinyWebServer web = TinyWebServer(handlers, headers);

boolean has_filesystem = true;
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

static uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// Don't forget to modify the IP to an available one on your home network
byte ip[] = { 192, 168, 1, 25 };

void send_file_name(TinyWebServer& web_server, const char* filename) {
  if (!filename) {
    web_server.send_error_code(404);
    web_server << F("Could not parse URL");
  } else {
    TinyWebServer::MimeType mime_type
      = TinyWebServer::get_mime_type_from_filename(filename);
    web_server.send_error_code(200);
    web_server.send_content_type(mime_type);
    web_server.end_headers();
    if (file.open(&root, filename, O_READ)) {
      Serial << F("Read file "); Serial.println(filename);
      web_server.send_file(file);
      file.close();
    } else {
      web_server << F("Could not find file: ") << filename << "\n";
    }
  }
}

boolean file_handler(TinyWebServer& web_server) {
  char* filename = TinyWebServer::get_file_from_path(web_server.get_path());
  send_file_name(web_server, filename);
  free(filename);
  return true;
}

boolean blink_led_handler(TinyWebServer& web_server) {
  web_server.send_error_code(200);
  web_server.send_content_type("text/plain");
  web_server.end_headers();
  // Reverse the state of the LED.
  setLedEnabled(!getLedState());
  Client& client = web_server.get_client();
  if (client.available()) {
    char ch = (char)client.read();
    if (ch == '0') {
      setLedEnabled(false);
    } else if (ch == '1') {
      setLedEnabled(true);
    }
  }
}

boolean blink_led2_handler(TinyWebServer& web_server) {
  web_server.send_error_code(200);
  web_server.send_content_type("text/plain");
  web_server.end_headers();
  // Reverse the state of the LED.
  setLed2Enabled(!getLedState2());
  Client& client = web_server.get_client();
  if (client.available()) {
    char ch = (char)client.read();
    if (ch == '0') {
      setLed2Enabled(false);
    } else if (ch == '1') {
      setLed2Enabled(true);
    }
  }
}

boolean led_status_handler(TinyWebServer& web_server) {
  web_server.send_error_code(200);
  web_server.send_content_type("text/plain");
  web_server.end_headers();
  Client& client = web_server.get_client();
  client.println(getLedState(), DEC);
}

boolean led2_status_handler(TinyWebServer& web_server) {
  web_server.send_error_code(200);
  web_server.send_content_type("text/plain");
  web_server.end_headers();
  Client& client = web_server.get_client();
  client.println(getLedState2(), DEC);
}

boolean index_handler(TinyWebServer& web_server) {
  send_file_name(web_server, "INDEX.HTM");
  return true;
}

void file_uploader_handler(TinyWebServer& web_server,
			   TinyWebPutHandler::PutAction action,
			   char* buffer, int size) {
  static uint32_t start_time;
  static uint32_t total_size;

  switch (action) {
  case TinyWebPutHandler::START:
    start_time = millis();
    total_size = 0;
    if (!file.isOpen()) {
      // File is not opened, create it. First obtain the desired name
      // from the request path.
      char* fname = web_server.get_file_from_path(web_server.get_path());
      if (fname) {
	Serial << F("Creating ") << fname << "\n";
	file.open(&root, fname, O_CREAT | O_WRITE | O_TRUNC);
	free(fname);
      }
    }
    break;

  case TinyWebPutHandler::WRITE:
    if (file.isOpen()) {
      file.write(buffer, size);
      total_size += size;
    }
    break;

  case TinyWebPutHandler::END:
    file.sync();
    Serial << F("Wrote ") << file.fileSize() << F(" bytes in ")
	   << millis() - start_time << F(" millis (received ")
           << total_size << F(" bytes)\n");
    file.close();
  }
}

void setup() {
  Serial.begin(115200);
  Serial << F("Free RAM: ") << FreeRam() << "\n";

  pinMode(ledPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  setLedEnabled(false);
  setLed2Enabled(false);

  // initialize the SD card
  Serial << F("Setting up SD card...\n");
  pinMode(10, OUTPUT); // set the SS pin as an output (necessary!)
  digitalWrite(10, HIGH); // but turn off the W5100 chip!
  if (!card.init(SPI_FULL_SPEED, 4)) {
    Serial << F("card failed\n");
    has_filesystem = false;
  }
  // initialize a FAT volume
  if (!volume.init(&card)) {
    Serial << F("vol.init failed!\n");
    has_filesystem = false;
  }
  if (!root.openRoot(&volume)) {
    Serial << F("openRoot failed");
    has_filesystem = false;
  }

  if (has_filesystem) {
    // Assign our function to `upload_handler_fn'.
    TinyWebPutHandler::put_handler_fn = file_uploader_handler;
  }

  Serial << F("Setting up the Ethernet card...\n");
  Ethernet.begin(mac, ip);

  // Start the web server.
  Serial << F("Web server starting...\n");
  web.begin();

  Serial << F("Ready to accept HTTP requests.\n");
}

void loop() {
  if (has_filesystem) {
    web.process();
  }
}

main.js:

/*

  • Copyright 2010 Ovidiu Predescu ovidiu@gmail.com
  • Date: December 2010
    /
    String.prototype.trim = function () {
    return this.replace(/^\s
    /, "").replace(/\s*$/, "");
    };

function Button(elem) {
var btn = this;
this.elem = elem;
this.setEnabled(false);
this.elem.click(function(e) {
e.preventDefault();
btn.clickHandler(btn, e);
});
};

Button.prototype.setEnabled = function(yesno) {
this.enabled = yesno;
this.elem.attr('class', function(idx, val) {
var newClass = yesno ? "on" : "off";
return newClass;
});
};

Button.prototype.isEnabled = function() { return this.enabled; };

Button.prototype.clickHandler = function(btn, e) {
var url = btn.elem.attr('href');
$.ajax({type: "POST",
data: (!btn.isEnabled() + 0).toString(10),
dataType: "text",
cache: false,
url: url,
success: function(r) {
},
error: function(s, xhr, status, e) {
console.log("POST failed: " + s.responseText);
}
});
};

function ledStatus(btn, url) {
$.ajax({type: "GET",
cache: false,
url: url,
success: function(status) {
status = parseInt(status.trim());
btn.setEnabled(status);
window.setTimeout(ledStatus, 400, btn, url);
},
error: function(s, xhr, status, e) {
console.log("Getting status failed: "

  • s.responseText);
    }
    });
    };

function ledStatus2(btn, url) {
$.ajax({type: "GET",
cache: false,
url: url,
success: function(status2) {
status2 = parseInt(status2.trim());
btn.setEnabled(status2);
window.setTimeout(ledStatus2, 400, btn, url);
},
error: function(s, xhr, status2, e) {
console.log("Getting status2 failed: "

  • s.responseText);
    }
    });
    };

$(document).ready(
function() {
var lightBulb = new Button($("#lightbulb"));
var lightBulb2 = new Button($("#lightbulb2"));
ledStatus(lightBulb, "/ledstatus");
ledStatus2(lightBulb2, "/ledstatus2");
});

index.html:

TinyWebServer LED control

{"/blinkled", TinyWebServer::POST, &blink_led_handler },
{"/blinkled2", TinyWebServer::POST, &blink_led2_handler },
{"/ledstatus" "", TinyWebServer::GET, &led_status_handler },
{"/ledstatus2" "
", TinyWebServer::GET, &led2_status_handler },

You've registered two handlers for the same event. It is unlikely that the TinyWebServer class manages this.

You should have one handler for each event (POST, GET, PUT, etc.) and, in that handler, deal with all the data passed in.

For instance, the GET request should include information about which LED you want the status of, and the led_status_handler method should get the status of that LED (not a hard-coded number).

Try rearranging the order of the handlers, like this:

{"/blinkled2", TinyWebServer::POST, &blink_led2_handler },
{"/blinkled", TinyWebServer::POST, &blink_led_handler },
{"/ledstatus2" "", TinyWebServer::GET, &led2_status_handler },
{"/ledstatus" "
", TinyWebServer::GET, &led_status_handler },

The code matches the handlers by doing string comparisons.

TinyWebServer can definitely handle multiple request handlers for the same method type.

I have managed to work on 5 led with more mobile friendly toggle switch

Thank you, Ovidiu. :slight_smile:

The goal of my project are accomplished.

  1. Self sufficient, no external web server or PC is required.
  2. Low Power consumption.
  3. min. 5 output controlled.
  4. Operational from any device be it android, blackberry, pc or ipad so webbased app is only waytogo
  5. Password protected access.

big thanks to you for tinywebserver.

capper:
I have managed to work on 5 led with more mobile friendly toggle switch

Impressive piece of work. Any chance for letting us have a glance at the code???

I am stuck at password protection. The pc works fine but android and blackberry fail even if password is right using Javascript in the section after other js load.

Solved :slight_smile:

"BLINKLED5"

Password Page

"BLINKLED5"

Note that password field is masked,COOL! 8) isn't it ?

"BLINKLED5"

TADA :slight_smile:


FIND THE ATTACHED ZIP FILE FOR THE SOURCE CODE AND IMAGES

THANKS EVERYBODY.

BlinkLed5.zip (57 KB)

hello,
I am testing 'BlinkLed5.pde' code with Arduino 1.0 but I have these errors :

/Applications/Arduino 1.app/Contents/Resources/Java/libraries/TinyWebServer/TinyWebServer.cpp:36:16: error: SD.h: No such file or directory
/Applications/Arduino 1.app/Contents/Resources/Java/libraries/TinyWebServer/TinyWebServer.cpp: In member function 'void TinyWebServer::send_file(SdFile&)':
/Applications/Arduino 1.app/Contents/Resources/Java/libraries/TinyWebServer/TinyWebServer.cpp:489: error: invalid use of incomplete type 'struct SdFile'
/Applications/Arduino 1.app/Contents/Resources/Java/libraries/TinyWebServer/TinyWebServer.h:15: error: forward declaration of 'struct SdFile'

can you help me?...
thank you.

perchè questo chè è pubblicato qui non funziona sulla 1.0 va modificato

......non sai come và modificato, cosa bisogna cambiare?.... ma sulla 0023 funziona?

BlinkLED5 for Arduino IDF 1.01 attached Below

You need to login to see the file attached Below

BlinkLed5_new.zip (64.3 KB)

capper:
BlinkLED5 for Arduino IDF 1.01 attached Below

You need to login to see the file attached Below

chi ha modificato lo sketch e il file js originali per 5 porte non ha capito nulla di questa libreria :fearful:
Non serve quintuplicare il programma per farlo funzionare, basta inviare un numero corrispondente alla porta da commutare

the original program is good for 5 port or 5000, need only modify string to send server.
this not need

boolean file_handler(TinyWebServer& web_server);
boolean blink_led_handler(TinyWebServer& web_server);
boolean blink_led2_handler(TinyWebServer& web_server);
boolean blink_led3_handler(TinyWebServer& web_server);
boolean blink_led4_handler(TinyWebServer& web_server);
boolean blink_led5_handler(TinyWebServer& web_server);
boolean led_status_handler(TinyWebServer& web_server);
boolean led2_status_handler(TinyWebServer& web_server);
boolean led3_status_handler(TinyWebServer& web_server);
boolean led4_status_handler(TinyWebServer& web_server);
boolean led5_status_handler(TinyWebServer& web_server);
boolean index_handler(TinyWebServer& web_server);

TinyWebServer::PathHandler handlers[] = {
  // Work around Arduino's IDE preprocessor bug in handling /* inside
  // strings.
  //
  // `put_handler' is defined in TinyWebServer
  {"/", TinyWebServer::GET, &index_handler },
  {"/upload/" "*", TinyWebServer::PUT, &TinyWebPutHandler::put_handler },
  {"/blinkled5", TinyWebServer::POST, &blink_led5_handler },  
  {"/blinkled4", TinyWebServer::POST, &blink_led4_handler },
  {"/blinkled3", TinyWebServer::POST, &blink_led3_handler },
  {"/blinkled2", TinyWebServer::POST, &blink_led2_handler },
  {"/blinkled", TinyWebServer::POST, &blink_led_handler },
  {"/ledstatus5" "*", TinyWebServer::GET, &led5_status_handler },
  {"/ledstatus4" "*", TinyWebServer::GET, &led4_status_handler },
  {"/ledstatus3" "*", TinyWebServer::GET, &led3_status_handler },
  {"/ledstatus2" "*", TinyWebServer::GET, &led2_status_handler },
  {"/ledstatus" "*", TinyWebServer::GET, &led_status_handler },
  {"/" "*", TinyWebServer::GET, &file_handler },
  {NULL},

and this not need

function ledStatus2(btn, url) { .........
...
function ledStatus3(btn, url){ .........
...
function ledStatus4(btn, url){ .........
...
function ledStatus5(btn, url) { .........
...
{

this not need

var lightBulb2 = new Button($("#lightbulb2"));
   var lightBulb3 = new Button($("#lightbulb3"));
   var lightBulb4 = new Button($("#lightbulb4"));
   var lightBulb5 = new Button($("#lightbulb5"));
  
   ledStatus2(lightBulb2, "/ledstatus2");
   ledStatus3(lightBulb3, "/ledstatus3");
   ledStatus4(lightBulb4, "/ledstatus4");
   ledStatus5(lightBulb5, "/ledstatus5");

thanks Pablos for pointing out. My objective was accomplished by adding five times the code. but i am a SUPERBAD coder :slight_smile:

Can you upload /attache the corrected code for me to study?

Thanks again for you comment, I am learning arduino and Italiano everyday because of good people like you

Hey,
Thanks for these amazing work.

Im not really be a good programer.
Could you tell me wich part of code i need to change to write my own pasword?
I can see just the password site but i can not see anymore...
Thanks

Thanks for these
very help full for me
but i have problem with parse for this script on index.htm
if(passcode==8488480)
{window.location=password+".htm"}
i can,t redirect to 8488480.htm, and on my scr url like=http://192.168.11.10/?password2=8488480
how to parses this(pasword2)