Hardware components | ||||||
| × | 1 | ||||
| × | 1 |
The Grove system makes building an electronics project easy by taking a building block approach. Whether you are just getting started or want to quickly prototype an IoT gadget, the Esquilo Air and Grove are a perfect combination. So turn off the soldering iron and skip the breadboards and start making connected devices right away.
This project includes a web-enabled demo for each of the components included in the Grove Starter Kit for Arduino. And because the Esquilo has a built-in web IDE, hacking the demos up to combine components or add functionality is simple.
There's a demo for each Grove module in the kit:
- LCD with RGB Backlight
- Button
- Socket LED
- Smart Relay
- Sound Sensor
- Touch Sensor
- Rotary Angle Sensor
- Temperature Sensor
- Light Sensor
- Mini Servo
Here are a few screenshots of the demo web apps:
Using the demos is easy. All you need is an Esquilo Air and a Grove Starter Kit for Arduino (see the hardware list).
First, copy the Esquilo Library code from the Github repo to the lib directory of your Esquilo's SD card:
https://github.com/esquiloio/lib
You can do this manually from a computer with an SD slot or sync it down from the cloud using the SD Card Library Synchonize feature from the web IDE system menu item Squirrel.
Once the library code is updated, open the Grove demo landing page from the SD card in the Web IDE by double-clicking it in the file list view. Each demo has a readme with specific instructions and a link to the live demo web app.
That's it!
Button Squirrel
C/C++// 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// 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');
});
<!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 »</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++// 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// 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');
});
<!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 »</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++// 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// 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');
});
<!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 »</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>
Comments