Patrick Jackson
Published © CC0

Esquilo Grove Starter Kit Demos

This project includes a web-enabled demo for each module in the Grove Starter Kit for Arduino using the Esquilo Air.

BeginnerProtip1,180
Esquilo Grove Starter Kit Demos

Things used in this project

Hardware components

Esquilo Air
Esquilo Air
×1
Seeed Studio Grove Starter Kit for Arduino
×1

Story

Read more

Schematics

Esquilo Grove Button Demo

This demo controls an LED or a relay remotely from a web application or a physical button or touch sensor.

Esquilo Button Demo

Controls an LED or relay with a button, touch sensor, or remotely from an web app.

Esquilo Buzzer Music Demo

Turns the Esquilo into a web-controlled music player using the Grove buzzer module.

Esquilo LED Demo

Simulates a breathing pulse on an LED. The breathing speed can be controlled from a web app.

Esquilo Rotary Angle Sensor Demo

Control the brightness of an LED with either a knob or from a web app.

Esquilo Temperature Sensor Demo

Updates a web app with room temperature.

Esquilo Sound Sensor Demo

Flashes an LED and updates a web app when a sound is picked up over a specified threshold.

Esquilo Light Sensor Demo

Turns on an LED and updates a web app page when ambient light drops below a specified threshold.

Esquilo Servo Demo

Controls a servo from a web app slider.

Esquilo RGB LCD Demo

Control the text displayed and the backlight color of a 16x2 RGB LCD from a web app.

Code

Button Squirrel

C/C++
Embedded code running on the Esquilo. It changes the LED state based on button presses and RPC calls received from the web app.
// Grove Button Demo
//
// Ported from:
//   https://github.com/Seeed-Studio/Sketchbook_Starter_Kit_V2.0
//
// This work is released under the Creative Commons Zero (CC0) license.
// See http://creativecommons.org/publicdomain/zero/1.0/

// Uses a Grove Button to control a Grove LED.
//  - Connect the Grove Button to socket D7
//  - Connect the Grove LED to socket D3

// Import the GPIO library
require("GPIO");

// Defines the pins to which the button and LED are connected
const PIN_BUTTON = 7;
const PIN_LED    = 3;

// Configure the button pin for input
button <- GPIO(PIN_BUTTON);
button.input();

// Configure the LED pin for output
led <- GPIO(PIN_LED);
led.output();

// Track the state of the web app virtual button
isVirtualButtonOn <- false;

// ERPC method to set the virtual button from the web app
function setIsVirtualButtonOn(value)
{
  isVirtualButtonOn = value;
}

// ERPC method to get the button state
function getIsGroveButtonOn()
{
  return button.ishigh();
}

while (true) {
  // If either of the buttons is pressed turn the LED on
  if ((button.ishigh() && !isVirtualButtonOn) ||
      (button.islow() && isVirtualButtonOn)) {
    led.high();
  } else {
    led.low();
  }

  // Sleep for 50ms to give the idle loop time to process the IDE, etc.  
  delay(50);
}

Button JavaScript

JavaScript
This runs in the web app. It updates the background color to match the LED based on RPC calls to the Esquilo. It also controls the LED by sending RPC calls with the state of the web app virtual button.
// Grove Button Demo
//
// See README.md for more information.
//
// This work is released under the Creative Commons Zero (CC0) license.
// See http://creativecommons.org/publicdomain/zero/1.0/
$(document).ready(function() {
    var isVirtualButtonOn = false;
    var isGroveButtonOn   = false;

    function setBackground() {
        if ((isVirtualButtonOn && !isGroveButtonOn) ||
            (!isVirtualButtonOn && isGroveButtonOn)) {
            // Esquilo blue
            $('body').css('background', '#039deb');
        }
        else {
            $('body').css('background', 'lightslategrey');
        }
    }

    function setIsVirtualButtonOn(value) {
        isVirtualButtonOn = value;
        // Update disco mode on the Esquilo
        erpc("setIsVirtualButtonOn", isVirtualButtonOn);
    }

    $("[name='button-switch']").bootstrapSwitch();
    $('input[name="button-switch"]').on('switchChange.bootstrapSwitch', function(event, state) {
        setIsVirtualButtonOn(state);
        setBackground();
    });

    var GROVE_BUTTON_UPDATE_MS = 100;
    function getIsGroveButtonOn() {
        erpc("getIsGroveButtonOn", null, function(result) {
            console.log('getIsGroveButtonOn', result);
                isGroveButtonOn = result;
                setTimeout(getIsGroveButtonOn, GROVE_BUTTON_UPDATE_MS);
                setBackground();
            },
            function(text) {
                console.log("error: " + text);
                setTimeout(getIsGroveButtonOn, GROVE_BUTTON_UPDATE_MS);
            });
    }
    getIsGroveButtonOn();

    demoInit('button');
});

Button HTML

HTML
Web app page for the Grove Button Demo
<!DOCTYPE html>
<!--
Grove Button Demo

See README.md for more information.

This work is released under the Creative Commons Zero (CC0) license.
See http://creativecommons.org/publicdomain/zero/1.0/
-->
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>Grove Button</title>

  <link rel="stylesheet" href="../../libs/bootstrap/css/bootstrap.min.css">
  <link rel="stylesheet"
        href="../../libs/bootstrap/css/bootstrap-switch.min.css">
  <link rel="stylesheet" href="../../libs/bootstrap/css/jumbotron-narrow.css">
  <link rel="stylesheet" href="../demo.css">
  <link rel="stylesheet" href="button.css">
</head>

<body>
<div class="container">
  <div class="jumbotron">
    <img src="button.png" width="80%">
    <h1>Grove Button</h1>
  </div>

  <div class='well getting-started'>
    <p><a class="btn btn-primary" href="README.html"
          role="button">README &raquo;</a>
      <a id='run-button' class="btn btn-success" role="button">
        <span class="glyphicon glyphicon-play" aria-hidden="true"></span> Run
        <b>button.nut</b>
      </a></p>
  </div>

  <div class='well'>
    <p>
    <h3>Virtual Button</h3>
    <input type="checkbox" name="button-switch">
    </p>
  </div>
</div>

<script type="text/javascript" src="../../libs/jquery/jquery.min.js"></script>
<script type="text/javascript" src="../../libs/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="../../libs/bootstrap/js/bootstrap-switch.min.js"></script>
<script type="text/javascript" src="../../libs/ejs/ejs.js"></script>
<script type="text/javascript" src="/js/util.js"></script>
<script type="text/javascript" src="/js/rpc.js"></script>
<script type="text/javascript" src="/js/erpc.js"></script>
<script type="text/javascript" src="../demo.js"></script>
<script type="text/javascript" src="button.js"></script>

</body>
</html>

Buzzer Squirrel

C/C++
Plays a song based on a list of notes the web app sends it by varying the voltage frequency on the Grove Buzzer.
// Buzzer Demo for Grove Starter Kit for Arduino
//
// Ported from:
//   https://github.com/Seeed-Studio/Sketchbook_Starter_Kit_V2.0
//
// This work is released under the Creative Commons Zero (CC0) license.
// See http://creativecommons.org/publicdomain/zero/1.0/

//
// Adapted from the Arduino project:
//
// Melody
// (cleft) 2005 D. Cuartielles for K3
//
// This example uses a piezo speaker to play melodies.  It sends
// a square wave of the appropriate frequency to the piezo, generating
// the corresponding tone.
//
// The calculation of the tones is made following the mathematical
// operation:
//
//       timeHigh = period / 2 = 1 / (2 * toneFrequency)
//
// where the different tones are described as in the table:
//
// note  frequency  period  timeHigh
//  c     261 Hz     3830    1915
//  d     294 Hz     3400    1700
//  e     329 Hz     3038    1519
//  f     349 Hz     2864    1432
//  g     392 Hz     2550    1275
//  a     440 Hz     2272    1136
//  b     493 Hz     2028    1014
//  C     523 Hz     1912    956
//
// http://www.arduino.cc/en/Tutorial/Melody
//

require("GPIO");

// Grove Buzzer connect to D3
const PIN_BUZZER = 3;

// Configure the buzzer's pin for output
speaker <- GPIO(PIN_BUZZER);
speaker.output();

tones <- { c=1915, d=1700, e=1519, f=1432, g=1275, a=1136, b=1014, C=956 };

twinkleTwinkleLittleStar <- {
    tempo=300,
    notes=[
        {note='c', beats=1},
        {note='c', beats=1},
        {note='g', beats=1},
        {note='g', beats=1},
        {note='a', beats=1},
        {note='a', beats=1},
        {note='g', beats=2},
        {note='f', beats=1},
        {note='f', beats=1},
        {note='e', beats=1},
        {note='e', beats=1},
        {note='d', beats=1},
        {note='d', beats=1},
        {note='c', beats=2},
        {note=' ', beats=1}
    ]
};

function playTone(tone, duration)
{
    for (local i = 0; i < duration * 1000; i += tone * 2) {
        speaker.high();
        udelay(tone);
        speaker.low();
        udelay(tone);
    }
}

function playNote(note, duration)
{
    // play the tone corresponding to the note name
    playTone(tones[note.tochar()], duration);
}

function playSong(song)
{
    for (local i=0; i < song.notes.len(); i++) {
        print("note: " + song.notes[i].note.tochar() + " beats: " + song.notes[i].beats + "\n");
        if (song.notes[i].note == ' ')
            delay(song.notes[i].beats * song.tempo); // rest
        else
            playNote(song.notes[i].note, song.notes[i].beats * song.tempo);

        // pause between notes
        delay(song.tempo / 2);
    }
}

//playSong(twinkleTwinkleLittleStar);

// ERPC
function play(song)
{
    song.tempo = song.tempo.tointeger();
    for (local i=0; i < song.notes.len(); i++)
        song.notes[i].note = song.notes[i].note[0];
    playSong(song);
}

Buzzer JavaScript

JavaScript
Builds a list of notes for the song the user selects and/or customizes in the web app and sends it with RPC to the Esquilo to be played on the Grove Buzzer.
// Grove Buzzer Demo
//
// See README.md for more information.
//
// This work is released under the Creative Commons Zero (CC0) license.
// See http://creativecommons.org/publicdomain/zero/1.0/
$(document).ready(function() {
    var SONG_LENGTH = 18;
    // load the notes template file, then render it with data
    var html = new EJS({url: 'notes.ejs'}).render({length:SONG_LENGTH});
    $('#notes').append(html);

    var songs = {
        twinkleTwinkleLittleStar: {
            tempo: 300,
            notes: [
                {note: 'c', beats: 1},
                {note: 'c', beats: 1},
                {note: 'g', beats: 1},
                {note: 'g', beats: 1},
                {note: 'a', beats: 1},
                {note: 'a', beats: 1},
                {note: 'g', beats: 2},
                {note: 'f', beats: 1},
                {note: 'f', beats: 1},
                {note: 'e', beats: 1},
                {note: 'e', beats: 1},
                {note: 'd', beats: 1},
                {note: 'd', beats: 1},
                {note: 'c', beats: 2},
                {note: ' ', beats: 1},
                {note: ' ', beats: 1},
                {note: ' ', beats: 1},
                {note: ' ', beats: 1}
            ]
        },
        threeBlindMice: {
            tempo: 250,
            notes: [
                {note: 'e', beats: 1},
                {note: 'd', beats: 1},
                {note: 'c', beats: 2},
                {note: ' ', beats: 1},
                {note: 'e', beats: 1},
                {note: 'd', beats: 1},
                {note: 'c', beats: 2},
                {note: ' ', beats: 1},
                {note: 'g', beats: 1},
                {note: 'f', beats: 1},
                {note: 'f', beats: 1},
                {note: 'e', beats: 2},
                {note: ' ', beats: 1},
                {note: 'g', beats: 1},
                {note: 'f', beats: 1},
                {note: 'f', beats: 1},
                {note: 'e', beats: 2},
                {note: ' ', beats: 1}
            ]
        }
    };

    function setSong(value) {
        $('#song').val(value);
        var song = songs[value];
        $('#tempo').val(song.tempo);
        for (var i=0; i < song.notes.length; i++) {
            $('#note-' + i).val(song.notes[i].note);
            $('#beats-' + i).val(song.notes[i].beats);
        }
    }

    $('#song').on('change', function() {
        console.log(this.value, 'selected');
        setSong(this.value);
    });

    setSong('twinkleTwinkleLittleStar');

	$('#play-button').on('click', function(event) {
        var song = {
            tempo:  $('#tempo').val(),
            notes: []
        };
        song.tempo = $('#tempo').val();
        for (var i=0; i < SONG_LENGTH; i++)
            song.notes.push({note: $('#note-'+i).val(), beats: parseInt($('#beats-'+i).val())})
        erpc("play", song);
    });

    demoInit('buzzer');
});

Buzzer HTML

HTML
Web app HTML for the Grove Buzzer demo.
<!DOCTYPE html>
<!--
Grove Buzzer Demo

See README.md for more information.

This work is released under the Creative Commons Zero (CC0) license.
See http://creativecommons.org/publicdomain/zero/1.0/
-->
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>Grove Buzzer</title>

  <link rel="stylesheet" href="../../libs/bootstrap/css/bootstrap.min.css">
  <link rel="stylesheet"
        href="../../libs/bootstrap/css/bootstrap-slider.min.css">
  <link rel="stylesheet" href="../../libs/bootstrap/css/jumbotron-narrow.css">
  <link rel="stylesheet" href="../demo.css">
</head>

<body>
<div class="container">
  <div class="jumbotron">
    <img src="buzzer.png" width="80%"
         style="display: block; margin-left: auto; margin-right: auto; margin-top: 2em; margin-bottom: 2em;">
    <h1>Grove Buzzer</h1>
  </div>

  <div class='well getting-started'>
    <p><a class="btn btn-primary" href="README.html"
          role="button">README &raquo;</a>
      <a id='run-button' class="btn btn-success" role="button">
        <span class="glyphicon glyphicon-play" aria-hidden="true"></span> Run
        <b>buzzer.nut</b>
      </a></p>
  </div>

  <div class='well'>
  	<div class="row">
      <div class="col-xs-12">
        <a id='play-button' class="btn btn-success" role="button">
          <span class="glyphicon glyphicon-play" aria-hidden="true"></span> Play Song
        </a>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-12">
          <h3>Load Song</h3>
          <div class="form-group">
            <select id="song" class="form-control">
              <option value="twinkleTwinkleLittleStar">Twinkle Twinkle Little Star</option>
              <option value="threeBlindMice">Three Blind Mice</option>
            </select>
          </div>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-12">
          <h3>Tempo</h3>
          <div class="form-group">
            <select id="tempo" class="form-control">
              <option>100</option>
              <option>150</option>
              <option>200</option>
              <option>250</option>
              <option>300</option>
              <option>350</option>
              <option>400</option>
            </select>
          </div>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-6">
        <h3>Note</h3>
      </div>
      <div class="col-xs-6">
        <h3>Beats</h3>
      </div>
    </div>
    <div id="notes">
    </div>
  </div>
</div>

<script type="text/javascript" src="../../libs/jquery/jquery.min.js"></script>
<script type="text/javascript" src="../../libs/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="../../libs/bootstrap/js/bootstrap-slider.min.js"></script>
<script type="text/javascript" src="../../libs/ejs/ejs.js"></script>
<script type="text/javascript" src="/js/util.js"></script>
<script type="text/javascript" src="/js/rpc.js"></script>
<script type="text/javascript" src="/js/erpc.js"></script>
<script type="text/javascript" src="../demo.js"></script>
<script type="text/javascript" src="buzzer.js"></script>

</body>
</html>

RGB LCD Squirrel

C/C++
Embedded code running on the Esquilo to set the text and backlight color based on RPC calls received from the web app.
// Grove RGB LCD Demo
//
// Ported from:
//   https://github.com/Seeed-Studio/Sketchbook_Starter_Kit_V2.0
//
// This work is released under the Creative Commons Zero (CC0) license.
// See http://creativecommons.org/publicdomain/zero/1.0/

// Uses a Grove Button to control a Grove LED.
//  - Connect the Grove RGB LCD to an I2C socket
//  - Set Grove Base Shield VCC switch to 5V

// Import the RGB and LCD drivers for the chips the Grove board uses
dofile("sd:/lib/displays/PCA9633/PCA9633.nut");
dofile("sd:/lib/displays/JHD1214/JHD1214.nut");

i2c <- I2C(0);

led <- PCA9633(i2c, 0x62);
led.on()
led.setColor(0x039deb);

lcd <- JHD1214(i2c, 0x3E);
lcd.write("Hello IoT!");

// ERPC method to set display state from the web app
function displayPower(value)
{
    if (value) {
        led.on();
        lcd.on();
    } else {
        led.off();
        lcd.off();
    }
}

// ERPC method to set backlight colors
function setLedColors(params)
{
    led.setColors(params.red, params.green, params.blue);
}

// ERPC method to set display text from the web app
function displayText(value)
{
    lcd.clear();
    lcd.write(value);
}

RGB LCD JavaScript

JavaScript
Sends the text and backlight color settings the user specifies in the web app to the Esquilo over RPC.
// Grove RGB LCD Demo
//
// See README.md for more information.
//
// This work is released under the Creative Commons Zero (CC0) license.
// See http://creativecommons.org/publicdomain/zero/1.0/
$(document).ready(function() {
    $('#power').bootstrapSwitch();
    $('#power').on('switchChange.bootstrapSwitch', function(event, state) {
        erpc("displayPower", state);
    });

    function setRgb(red, green, blue) {
        // Update the RGB LED
        erpc("setLedColors", {red: red, green: green, blue: blue});
        $('body').css('background', 'rgb('+ red + ',' + green + ',' + blue + ')');
    }

    function rgbSliderChange() {
        var red   = redSlider.getValue();
        var green = greenSlider.getValue();
        var blue  = blueSlider.getValue();

        setRgb(red, green, blue);
    }

    var redSlider = $('#R').slider()
        .on('slide', rgbSliderChange)
        .data('slider');
    var greenSlider = $('#G').slider()
        .on('slide', rgbSliderChange)
        .data('slider');
    var blueSlider = $('#B').slider()
        .on('slide', rgbSliderChange)
        .data('slider');

    $('#text').change(function(){
        erpc("displayText", $('#text').val());
    });

    $('#update').click(function() {
        erpc("displayText", $('#text').val());
    });

    demoInit('rgbLcd');
});

RGB LCD HTML

HTML
Web app HTML for the Grove RGB LCD demo.
<!DOCTYPE html>
<!--
Grove RGB LCD Demo

See README.md for more information.

This work is released under the Creative Commons Zero (CC0) license.
See http://creativecommons.org/publicdomain/zero/1.0/
-->
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>Grove RGB LCD</title>

  <link rel="stylesheet" href="../../libs/bootstrap/css/bootstrap.min.css">
  <link rel="stylesheet" href="../../libs/bootstrap/css/bootstrap-switch.min.css">
  <link rel="stylesheet" href="../../libs/bootstrap/css/bootstrap-slider.min.css">
  <link rel="stylesheet" href="../../libs/bootstrap/css/jumbotron-narrow.css">
  <link rel="stylesheet" href="../demo.css">
  <link rel="stylesheet" href="rgbLcd.css">
</head>

<body>
<div class="container">
  <div class="jumbotron">
    <img src="rgbLcd.png" width="80%">
    <h1>Grove RGB LCD</h1>
  </div>

  <div class='well getting-started'>
    <p><a class="btn btn-primary" href="README.html"
          role="button">README &raquo;</a>
      <a id='run-button' class="btn btn-success" role="button">
        <span class="glyphicon glyphicon-play" aria-hidden="true"></span> Run
        <b>rgbLcd.nut</b>
      </a></p>
  </div>

  <div class='well'>
    <h3>Power</h3>
    <p><input type="checkbox" name="button-switch" id="power" checked>
    </p>
    <h3>Backlight</h3>
    <p>
      <b>R </b> <input type="text" class="rgb-slider" value="" data-slider-min="0" data-slider-max="255" data-slider-step="1" data-slider-value="3" data-slider-id="RC" id="R" data-slider-tooltip="hide" data-slider-handle="square" />
    </p>
    <p>
      <b>G </b> <input type="text" class="rgb-slider" value="" data-slider-min="0" data-slider-max="255" data-slider-step="1" data-slider-value="157" data-slider-id="GC" id="G" data-slider-tooltip="hide" data-slider-handle="round" />
    </p>
    <p>
      <b>B </b> <input type="text" class="rgb-slider" value="" data-slider-min="0" data-slider-max="255" data-slider-step="1" data-slider-value="235" data-slider-id="BC" id="B" data-slider-tooltip="hide" data-slider-handle="triangle" />
    </p>
    <h3>Text</h3>
    <input type="email" class="form-control" id="text">
    <br/>
    <button class="btn btn-primary" type="submit" id="update">Update Text</button>
  </div>
</div>

<script type="text/javascript" src="../../libs/jquery/jquery.min.js"></script>
<script type="text/javascript" src="../../libs/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="../../libs/bootstrap/js/bootstrap-switch.min.js"></script>
<script type="text/javascript" src="../../libs/bootstrap/js/bootstrap-slider.min.js"></script>
<script type="text/javascript" src="../../libs/ejs/ejs.js"></script>
<script type="text/javascript" src="/js/util.js"></script>
<script type="text/javascript" src="/js/rpc.js"></script>
<script type="text/javascript" src="/js/erpc.js"></script>
<script type="text/javascript" src="../demo.js"></script>
<script type="text/javascript" src="rgbLcd.js"></script>

</body>
</html>

Esquilo Library Grove Demos

Copy the Esquilo lib repo to your Esquilo's SD and browse to sd:/lib/demos/grove/grove.html. The Grove demo code directory is here: https://github.com/esquiloio/lib/tree/master/demos/grove

Credits

Patrick Jackson

Patrick Jackson

3 projects • 6 followers
Thanks to Seeed Studio.

Comments