aboutsummaryrefslogtreecommitdiff
path: root/libraries/Esplora/examples/EsploraTable
diff options
context:
space:
mode:
authorCristian Maglie <c.maglie@bug.st>2012-12-10 15:55:05 +0100
committerCristian Maglie <c.maglie@bug.st>2012-12-10 15:55:05 +0100
commit433090f18b6218319fe0a721c24e1dc69285ea3e (patch)
treee7dc4da5b6ff077f1bc255350506dfc0bf87c6c3 /libraries/Esplora/examples/EsploraTable
parentc453e0a32e7adf5e7bab7bfb7c8f7a21e30ca563 (diff)
parente624b841b3b5d22f6e9cb7ec515beb47f96f46f2 (diff)
Merged 1.0.3
Diffstat (limited to 'libraries/Esplora/examples/EsploraTable')
-rw-r--r--libraries/Esplora/examples/EsploraTable/EsploraTable.ino219
1 files changed, 219 insertions, 0 deletions
diff --git a/libraries/Esplora/examples/EsploraTable/EsploraTable.ino b/libraries/Esplora/examples/EsploraTable/EsploraTable.ino
new file mode 100644
index 0000000..73d5652
--- /dev/null
+++ b/libraries/Esplora/examples/EsploraTable/EsploraTable.ino
@@ -0,0 +1,219 @@
+/*
+ Esplora Table
+
+ Acts like a keyboard that prints some of its sensors'
+ data in a table-like text, row by row.
+ It is a sort of "data-logger".
+
+ At startup, it does nothing. It just waits for you to open a
+ spreadsheet (e.g. Google Drive spreadsheet) so it can put its
+ data. Then, by pressing Switch 1, it starts printing the table
+ headers and the first row of data. It waits a bit, then it
+ will print another row, and so on.
+
+ The amount of time between each row is given by the slider.
+ If put to full left, the sketch will wait 10 seconds; at
+ full right position, it will wait 5 minutes. An intermediate
+ position will make the sketch wait for some time in-between.
+
+ Clicking the Switch 1 at any time will stop the logging.
+
+ The color LED shows what the sketch is doing:
+ blue = idle, waiting for you to press Switch 1 to start logging
+ green = active; will print soon
+ red = printing data to the PC
+
+ Created on 22 november 2012
+ By Enrico Gueli <enrico.gueli@gmail.com>
+ modified 24 Nov 2012
+ by Tom Igoe
+*/
+
+#include <Esplora.h>
+
+/*
+ * this variable tells if the data-logging is currently active.
+ */
+boolean active = false;
+
+/*
+ * this variable holds the time in the future when the sketch
+ * will "sample" the data (sampling is the act of reading some
+ * input at a known time). This variable is checked continuously
+ * against millis() to know when it's time to sample.
+ */
+unsigned long nextSampleAt = 0;
+
+/*
+ * This variable just holds the millis() value at the time the
+ * logging was activated. This is needed to enter the correct
+ * value in the "Time" column in the printed table.
+ */
+unsigned long startedAt = 0;
+
+
+/*
+ * when the "active" variable is set to true, the same is done
+ * with this variable. This is needed because the code that does
+ * the "just-after-activation" stuff is run some time later than
+ * the code that says "be active now".
+ */
+boolean justActivated = false;
+
+
+/*
+ * this variable holds the last sensed status of the switch press
+ * button. If the code sees a difference between the value of
+ * this variable and the current status of the switch, it means
+ * that the button was either pressed or released.
+ */
+boolean lastStartBtn = HIGH;
+
+/*
+ * Initialization code. The virtual USB keyboard must be
+ * initialized; the Serial class is needed just for debugging.
+ */
+void setup() {
+ Keyboard.begin();
+ Serial.begin(9600);
+}
+
+/*
+ * This code is run continuously.
+ */
+void loop() {
+ /*
+ * note: we don't use Arduino's delay() here, because we can't
+ * normally do anything while delaying. Our own version lets us
+ * check for button presses often enough to not miss any event.
+ */
+ activeDelay(50);
+
+ /*
+ * the justActivated variable may be set to true in the
+ * checkSwitchPress() function. Here we check its status to
+ * print the table headers and configure what's needed to.
+ */
+ if (justActivated == true) {
+ justActivated = false; // do this just once
+ printHeaders();
+ // do next sampling ASAP
+ nextSampleAt = startedAt = millis();
+ }
+
+ if (active == true) {
+ if (nextSampleAt < millis()) {
+ // it's time to sample!
+ int slider = Esplora.readSlider();
+ // the row below maps the slider position to a range between
+ // 10 and 290 seconds.
+ int sampleInterval = map(slider, 0, 1023, 10, 290);
+ nextSampleAt = millis() + sampleInterval * 1000;
+
+ logAndPrint();
+ }
+
+ // let the RGB led blink green once per second, for 200ms.
+ unsigned int ms = millis() % 1000;
+ if (ms < 200)
+ Esplora.writeGreen(50);
+ else
+ Esplora.writeGreen(0);
+
+ Esplora.writeBlue(0);
+ }
+ else
+ // while not active, keep a reassuring blue color coming
+ // from the Esplora...
+ Esplora.writeBlue(20);
+
+}
+
+/*
+ * Print the table headers.
+ */
+void printHeaders() {
+ Keyboard.print("Time");
+ Keyboard.write(KEY_TAB);
+ activeDelay(300); // Some spreadsheets are slow, e.g. Google
+ // Drive that wants to save every edit.
+ Keyboard.print("Accel X");
+ Keyboard.write(KEY_TAB);
+ activeDelay(300);
+ Keyboard.print("Accel Y");
+ Keyboard.write(KEY_TAB);
+ activeDelay(300);
+ Keyboard.print("Accel Z");
+ Keyboard.println();
+ activeDelay(300);
+}
+
+void logAndPrint() {
+ // do all the samplings at once, because keystrokes have delays
+ unsigned long timeSecs = (millis() - startedAt) /1000;
+ int xAxis = Esplora.readAccelerometer(X_AXIS);
+ int yAxis = Esplora.readAccelerometer(Y_AXIS);
+ int zAxis = Esplora.readAccelerometer(Z_AXIS);
+
+ Esplora.writeRed(100);
+
+ Keyboard.print(timeSecs);
+ Keyboard.write(KEY_TAB);
+ activeDelay(300);
+ Keyboard.print(xAxis);
+ Keyboard.write(KEY_TAB);
+ activeDelay(300);
+ Keyboard.print(yAxis);
+ Keyboard.write(KEY_TAB);
+ activeDelay(300);
+ Keyboard.print(zAxis);
+ Keyboard.println();
+ activeDelay(300);
+ Keyboard.write(KEY_HOME);
+
+ Esplora.writeRed(0);
+}
+
+/**
+ * Similar to delay(), but allows to do something else
+ * in the meanwhile. In particular, it calls waitLoop().
+ * Note 1: it may wait longer than the specified amount, not less;
+ * Note 2: beware of data synchronization issues, e.g. if the
+ * whileWaiting() function alters some variables used by the
+ * caller of this function.
+ *
+ * I discovered by chance that there's an ongoing discussion about
+ * adding yield() in the Arduino API:
+ * http://comments.gmane.org/gmane.comp.hardware.arduino.devel/1381
+ * The purpose is the same, but for now I'm using this implementation.
+ */
+void activeDelay(unsigned long amount) {
+ unsigned long at = millis() + amount;
+ while (millis() < at) {
+ checkSwitchPress();
+ }
+}
+
+/*
+ * This function reads the status of the switch; if it sees that
+ * it was pressed, toggles the status of the "active" variable.
+ * If it's set to true, also the justActivated variable is set to
+ * true, so the loop() function above can do the right things.
+ * This function should be called as often as possible and do as
+ * little as possible, because it can be called while another
+ * function is running.
+ */
+void checkSwitchPress() {
+ boolean startBtn = Esplora.readButton(SWITCH_DOWN);
+
+ if (startBtn != lastStartBtn) {
+ if (startBtn == HIGH) { // button released
+ active = !active;
+ if (active)
+ justActivated = true;
+ }
+
+ lastStartBtn = startBtn;
+ }
+}
+