Arduino Jquery retain sliders last value

Hello,

I am trying to create a html page for basic home automation.

I do not know anything about hmtl and javascript. But I managed to finish the audio control page by modifiying one of the sample skecthes. Now, I have one single problem.

Each time I refresh the page or load it from an other device the sliders goes back to the default value “0”.

Is it possible to retain the last value for the sliders or buttons and load the page with last known value?

  #include "SPI.h"
  #include "Ethernet.h"
  #include "WebServer.h"
  #include <Wire.h>
  #include <TDA7439.h>
  TDA7439 equ;

  static uint8_t mac[6] = { 0x02, 0xAA, 0xBB, 0xCC, 0x00, 0x22 };
  static uint8_t ip[4] = { 192, 168, 0, 100 }; 
  
  #define PREFIX "/rgb"
  WebServer webserver(PREFIX, 80);
  
  int input1v;  
  int input2v; 
  int input3v;
  int input4v;
  int volume;
  int inputt;
  int inputm;
  int inputb;
  int input = 1;
 
  void rgbCmd(WebServer &server, WebServer::ConnectionType type, char *, bool)
  {
    if (type == WebServer::POST)
    {
      bool repeat;
      char name[16], value[16];
      do
      {
        repeat = server.readPOSTparam(name, 16, value, 16);
  
        if (strcmp(name, "input1v") == 0)
        {
          if(input1v > 0){selectInput(1);}
          input1v = strtoul(value, NULL, 10);
          volume = input1v;
        }

        if (strcmp(name, "inputt") == 0)
        {
          inputt = strtoul(value, NULL, 10);
        }
        
        if (strcmp(name, "inputm") == 0)
        {
          inputm = strtoul(value, NULL, 10);
        }
        
        if (strcmp(name, "inputb") == 0)
        {
          inputb = strtoul(value, NULL, 10);
        }
        
        if (strcmp(name, "input2v") == 0)
        {
          if(input2v > 0){selectInput(2);}
          input2v = strtoul(value, NULL, 10);
          volume = input2v;
        }
        
        if (strcmp(name, "input3v") == 0)
        {
          if(input3v > 0){selectInput(3);}
          input3v = strtoul(value, NULL, 10);
          volume = input3v;
        }
        
        if (strcmp(name, "input4v") == 0)
        {
          if(input4v > 0){selectInput(4);}
          input4v = strtoul(value, NULL, 10);
          volume = input4v;
        }

      } while (repeat);
      

      server.httpSeeOther(PREFIX);

  
      return;
    }
  
    server.httpSuccess();

    if (type == WebServer::GET)
    {
      P(message) = 
    "<!DOCTYPE html><html><head>"
    "<meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\">"
    "<title>Home Automation</title>"
    "<link rel=\"stylesheet\" href=\"http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.css\" />"
    "<script src=\"http://code.jquery.com/jquery-2.1.1.min.js\"></script>"
    "<script src=\"http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.js\"></script>"
    
    "<script>"
    "$(document).ready(function(){ $('#input1v, #inputt, #inputm, #inputb, #input2v, #input3v, #input4v').slider;" 
    "$('#input1v, #inputt, #inputm, #inputb, #input2v, #input3v, #input4v').bind( 'change', function(event, ui) { jQuery.ajaxSetup({timeout: 100});"
    "var id = $(this).attr('id'); var strength = $(this).val();" 
    "if (id == 'input1v') $.post('/rgb', { input1v: strength } );"
    "if (id == 'inputt') $.post('/rgb', { inputt: strength } );"
    "if (id == 'inputm') $.post('/rgb', { inputm: strength } );"
    "if (id == 'inputb') $.post('/rgb', { inputb: strength } );"
    "if (id == 'input2v') $.post('/rgb', { input2v: strength } );" 
    "if (id == 'input3v') $.post('/rgb', { input3v: strength } );" 
    "if (id == 'input4v') $.post('/rgb', { input4v: strength } ); });});"
    "</script>"
    
    "</head>"
    "<body>"
    
"<div data-role=\"page\" data-control-title=\"Volume\" id=\"page1\">"
    "<div data-role=\"header\" data-position=\"fixed\">"
        "<div data-controltype=\"textblock\">"
            "<p style=\"text-align: center;\">"
                "Audio Mixer Volume Controller"
            "</p>"
        "</div>"
   "</div>"
   
"<div data-role=\"content\">"

        
        "<div data-role=\"fieldcontain\" data-controltype=\"slider\">"
            "<label for=\"input4v\">"
                "Airplay"
            "</label>"
            "<input id=\"input4v\" type=\"range\" name=\"slider\" value=\"0\" min=\"0\" max=\"48\" data-highlight=\"true\">"
        "</div>"        
        
        
        "<div data-role=\"fieldcontain\" data-controltype=\"slider\">"
            "<label for=\"input3v\">"
                "Channel 2"
            "</label>"
            "<input id=\"input3v\" type=\"range\" name=\"slider\" value=\"0\" min=\"0\" max=\"48\" data-highlight=\"true\">"
        "</div>"        
        
            
        "<div data-role=\"fieldcontain\" data-controltype=\"slider\">"
            "<label for=\"input2v\">"
                "Channel 3"
            "</label>"
            "<input id=\"input2v\" type=\"range\" name=\"slider\" value=\"0\" min=\"0\" max=\"48\" data-highlight=\"true\">"             
        "</div>"


            
            "<div data-role=\"collapsible-set\">"
            "<div data-role=\"collapsible\">"
                "<h3>"
                    "EQ"
                "</h3>"
                "<div data-role=\"fieldcontain\" data-controltype=\"slider\">"
                    "<label for=\"inputt\">"
                        "Treble"
                    "</label>"
                    "<input id=\"inputt\" type=\"range\" name=\"slider\" value=\"7\" min=\"0\" max=\"14\" data-highlight=\"false\">"
                "</div>"
                "<div data-role=\"fieldcontain\" data-controltype=\"slider\">"
                    "<label for=\"inputm\">"
                        "Mid"
                    "</label>"
                    "<input id=\"inputm\" type=\"range\" name=\"slider\" value=\"7\" min=\"0\" max=\"14\" data-highlight=\"false\">"
                "</div>"
                "<div data-role=\"fieldcontain\" data-controltype=\"slider\">"
                    "<label for=\"inputb\">"
                        "Bass"
                    "</label>"
                    "<input id=\"inputb\" type=\"range\" name=\"slider\" value=\"7\" min=\"0\" max=\"14\" data-highlight=\"false\">"
                "</div>"
            "</div>"
            "</div>"
    
    "<div data-role=\"footer\" data-position=\"fixed\">"
    "<div data-role=\"navbar\" data-iconpos=\"top\"  data-position=\"fixed\">"
        "<ul>"
            "<li>"
                "<a href=\"#page1\" data-transition=\"slide\"  data-icon=\"audio\">Audio</a>"
            "</li>"
            "<li>"
                "<a href=\"#page2\" data-transition=\"slide\"  data-icon=\"info\">Lights</a>"
            "</li>"
       "</ul>"
    "</div>"
    "</div>"
    
"</div>" 
"</div>"    
      
 "<div data-role=\"page\" id=\"page2\">"
     "<div data-role=\"header\" data-position=\"fixed\">"
        "<div data-controltype=\"textblock\">"
            "<p style=\"text-align: center;\">"
                "Light Power Socket Remote"
            "</p>"
        "</div>"
   "</div>"
   
  "<div data-role=\"content\"></div>"
  "<div data-role=\"footer\" data-position=\"fixed\">" 
  "<div data-role=\"navbar\" data-iconpos=\"top\" data-position=\"fixed\">"
            "<ul>"
                "<li>"
                    "<a href=\"#page1\" data-transition=\"slide\" data-icon=\"audio\">Audio</a>"
                "</li>"
                "<li>"
                    "<a href=\"#page2\" data-transition=\"slide\" data-icon=\"info\">Lights</a>"
                "</li>"
            "</ul>"
        "</div>"
  "</div>"
"</div> "         
      
      
      
    "</body>"
  "</html>";
  
      server.printP(message);
    }
  }
  
  void setup()
  {
  
    Serial.begin(9600);
    Wire.begin();
  
    // setup the Ehternet library to talk to the Wiznet board
    Ethernet.begin(mac, ip);
    webserver.setDefaultCommand(&rgbCmd);
  

     webserver.begin();
     equ.setInput(input);
     equ.inputGain(0);
     equ.setVolume(0);
     equ.setSnd(0,1);
     equ.setSnd(0,2);
     equ.setSnd(0,3);
     equ.spkAtt(0);
  }
  
  void loop()
   {
    webserver.processConnection();
    equ.setSnd(inputb-7,1); //bass
    equ.setSnd(inputm-7,2); //mid
    equ.setSnd(inputt-7,3);//treble
    equ.setVolume(volume);

  }
  
  void selectInput(int x)
   {
     if ( input == x) {}
     else{input = x; equ.setInput(input);}
   }

Is it possible to retain the last value for the sliders or buttons and load the page with last known value?

Well, you probably would need to make the default slider value a variable that is stored each time a request is received by the server, which is then included in the html when the web page is sent to the client. I've made a slider setup for servo control, but set it up such that the page does not refresh when the slider commands are sent from the web page. This way the slider values sent remain in the slider display.

Thanks for the clue. I think setting up a cookie is also a solution. The problem is I have a very limited knowledge of jquery and html. I really dont know how to embed these into the arduino sketch. I would really appreciate if you could give me code examples. I was looking for a sample to play with but couldnot finy any.

I’m currently working on a Arduino based pre amp that hosts a rest api for remote controlling:



I’m using a modified version of the Webduino library that can be found from here GitHub - lasselukkari/aWOT: Arduino web server library. , but you should be able to use the same idea with standard webduino as well.

Here is the the full scetch. The parts you are interested are on the top. The end result looks like this:

#include <SPI.h>
#include <Ethernet.h>
#include <HTTPServer.h>
#include <ServerInterface.h>
#include <StreamServerAdapter.h>
#include <EthernetServerAdapter.h>
#include <JsonParser.h>
#include <pga23XX.h>
#include <Encoder.h>

#define encoderPin1 2
#define encoderPin2 3
#define channelOnePin 5
#define channelOnePin 5
#define channelTwoPin 6
#define channelThreePin 7
#define encoderSwitchPin 9
#define pgaMutePin 14
#define  pgaSckPin 15
#define  pgaCsPin 16
#define  pgaSdataPin 17

PGA23XX pga2311;

byte volume = 0;
byte input = 0;
byte minVolume  = 0;
byte maxVolume  = 192;

byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetServer server(80);
EthernetServerAdapter ethernetServerAdapter(&server);
HTTPServer httpServer("");
Encoder volumeKnob(encoderPin1, encoderPin2);

bool previousButtonState;
bool buttonPressed = false;
long lastBounceTime = 0;         // the last time the output pin was toggled
byte debounceHoldTime = 50;   // the debounce time, increase if the output flickers

void indexCmd(HTTPServer &server, HTTPServer::MethodType type, char *, bool) {
  server.httpSuccess();
  P(helloMsg) =
    "<!DOCTYPE html>\n"
    "<html lang=\"en\">\n"
    "\n"
    "<head>\n"
    "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n"
    "<title>aPreAmp</title>\n"
    "<link href=\"http://www.cs.helsinki.fi/u/ljlukkar/apreamp/css/main.css\" rel=\"stylesheet\">\n"
    "</head>\n"
    "\n"
    "<body>\n"
    "\n"
    "<div class=\"buttons\">\n"
    "<input type=\"radio\" id=\"input0\" name=\"inputSelect\" value=\"0\">\n"
    "<label for=\"input0\" class=\"button\">input 1</label>\n"
    "<input type=\"radio\" id=\"input1\" name=\"inputSelect\" value=\"1\">\n"
    "<label for=\"input1\" class=\"button\">input 2</label>\n"
    "<input type=\"radio\" id=\"input2\" name=\"inputSelect\" value=\"2\">\n"
    "<label for=\"input2\" class=\"button\">input 3</label>\n"
    "</div>\n"
    "\n"
    "<div id=\"volumeSlider\" class=\"center-block\"></div>\n"
    "\n"
    "<script src=\"http://code.jquery.com/jquery-1.10.2.js\"></script>\n"
    "<script src=\"http://cdnjs.cloudflare.com/ajax/libs/noUiSlider/6.2.0/jquery.nouislider.min.js\"></script>\n"
    "\n"
    "<script>\n"
    "\n"
    "var state = {\n"
    "v: 0,\n"
    "i: 0\n"
    "};\n"
    "\n"
    "var busy = false;\n"
    "\n"
    "var inputSelect = $(\'input[name=\"inputSelect\"]:radio\');\n"
    "var volumeSlider = $(\"#volumeSlider\");\n"
    "\n"
    "volumeSlider.noUiSlider({\n"
    "start: 0,\n"
    "orientation: \'vertical\',\n"
    "direction: \"rtl\",\n"
    "range: {\n"
    "\'min\': 0,\n"
    "\'max\': 192\n"
    "}\n"
    "});\n"
    "\n"
    "volumeSlider.on({\n"
    "slide: function () {\n"
    "busy = true;\n"
    "},\n"
    "set: function (event, value) {\n"
    "state.v = parseInt(value);\n"
    "busy = false;\n"
    "saveState(state);\n"
    "}\n"
    "});\n"
    "\n"
    "\n"
    "inputSelect.change(function () {\n"
    "state.i = Number(this.value);\n"
    "saveState(state);\n"
    "});\n"
    "\n"
    "\n"
    "function fetchState() {\n"
    "\n"
    "if (busy) return;\n"
    "\n"
    "busy = true;\n"
    "\n"
    "$.getJSON(\"/state\", function (serverState) {\n"
    "state.i = serverState.i;\n"
    "state.v = serverState.v;\n"
    "volumeSlider.val(state.v);\n"
    "$(\"input[name=inputSelect][value=\" + state.i + \"]\").prop(\'checked\', true);\n"
    "busy = false;\n"
    "});\n"
    "}\n"
    "\n"
    "function saveState(newState) {\n"
    "$.ajax({\n"
    "type: \"PUT\",\n"
    "url: \'/state\',\n"
    "contentType: \'application/json\',\n"
    "data: JSON.stringify(newState)\n"
    "});\n"
    "}\n"
    "\n"
    "function resizeControls() {\n"
    "\n"
    "var height = $(window).height();\n"
    "var width = $(window).width();\n"
    "\n"
    "var reference = (height / width < 1.30) ? (height * 0.45) : (width * 0.60);\n"
    "\n"
    "$(\"#volumeSlider\").width(reference).height(1.49 * reference);\n"
    "$(\".noUi-handle\").width(0.41 * reference).height(0.41 * reference);\n"
    "$(\".buttons\").width(1.56 * reference);\n"
    "$(\".button\").width(0.51 * reference).height(0.23 * reference);\n"
    "\n"
    "}\n"
    "\n"
    "$(window).resize(function () {\n"
    "\n"
    "resizeControls();\n"
    "\n"
    "});\n"
    "\n"
    "$(function () {\n"
    "\n"
    "resizeControls();\n"
    "setInterval(fetchState, 500);\n"
    "\n"
    "});\n"
    "\n"
    "</script>\n"
    "\n"
    "</body>\n"
    "</html>\n"
    ;
  server.printP(helloMsg);
}

void sendJSONresponse(HTTPServer &server){

  char buffer [4];

  server.httpSuccess("application/json");

  server.write("{\"v\":");
  itoa (volume,buffer,10);
  server.write(buffer);
  server.write(",\"i\":");
  itoa (input,buffer,10);
  server.write(buffer);
  server.write("}");

}

void getState(HTTPServer &server, HTTPServer::MethodType type, char ** routeParams, char *, bool) {

  sendJSONresponse(server);

}

void updateState(HTTPServer &server, HTTPServer::MethodType type, char ** routeParams, char *, bool) {

  char buffer[20];
  byte i = 0;

  while (server.available() && i < 19){
    buffer[i] = (char)server.read();
    i++;
  }

  buffer[i] = '\0';

  JsonParser<5> parser;

  JsonHashTable hashTable = parser.parseHashTable(buffer);

  if (!hashTable.success()){

    server.httpServerError();

  } 
  else {

    volume = hashTable.getLong("v");
    input = hashTable.getLong("i");

    sendJSONresponse(server);
    server.close();

    volumeKnob.write(volume);
    selectInput(input);
    pga2311.setVolume(volume, volume);

  }
}

void setup() {
  Serial.begin(115200);
  Serial.println("starting");
  pga2311.begin(pgaCsPin, pgaSdataPin, pgaSckPin, pgaMutePin);

  pinMode(channelOnePin, OUTPUT);
  pinMode(channelTwoPin, OUTPUT);
  pinMode(channelThreePin, OUTPUT);
  pinMode(encoderSwitchPin, INPUT);
  digitalWrite(encoderSwitchPin, HIGH);

  selectInput(input); 

  if (Ethernet.begin(mac)) {
    Serial.print("My IP address: ");
    for (byte thisByte = 0; thisByte < 4; thisByte++) {

      Serial.print(Ethernet.localIP()[thisByte], DEC);
      Serial.print(".");
    }
    Serial.println();
  }

  httpServer.setDefaultCommand(&indexCmd);
  httpServer.onGET("state", &getState);
  httpServer.onPUT("state", &updateState);

}

void selectInput(byte input) {

  if (input >= 0 && input < 3) {

    digitalWrite(channelOnePin, LOW);
    digitalWrite(channelTwoPin, LOW);
    digitalWrite(channelThreePin, LOW);
    digitalWrite(input + 5, HIGH);

  }

}

void processVolumeKnob() {

  byte reading = volumeKnob.read();

  if (reading != volume && reading >= minVolume && reading <= maxVolume) {

    volume = reading;
    pga2311.setVolume(volume, volume);

  }

  volumeKnob.write(volume);

}

void processInputButton() {

  byte reading = volumeKnob.read();

  reading = digitalRead(encoderSwitchPin);

  if (reading != previousButtonState) {
    lastBounceTime = millis();
  } 

  if (millis() - lastBounceTime > debounceHoldTime) {

    if (reading == LOW && !buttonPressed){

      buttonPressed = true;

      if (input<2) {

        input++;

      }  
      else {

        input = 0;

      }

      selectInput(input);

    } 
    else if (reading == HIGH){

      buttonPressed = false;

    }

  }

  previousButtonState = reading;

}


void loop() {

  httpServer.processConnection(&ethernetServerAdapter);

  pga2311.run(50);

  processInputButton();

  processVolumeKnob();

}

The HTML is kinda annoying to read because of the escaping. Here is the HTML content alone:
http://pastebin.com/w0Yk5sRH