diff options
Diffstat (limited to 'libraries/Esplora')
-rw-r--r-- | libraries/Esplora/Esplora.cpp | 175 | ||||
-rw-r--r-- | libraries/Esplora/Esplora.h | 163 | ||||
-rw-r--r-- | libraries/Esplora/examples/EsploraKart/EsploraKart.ino | 125 | ||||
-rw-r--r-- | libraries/Esplora/examples/EsploraLedShow/EsploraLedShow.ino | 42 | ||||
-rw-r--r-- | libraries/Esplora/examples/EsploraLedShow2/EsploraLedShow2.ino | 55 | ||||
-rw-r--r-- | libraries/Esplora/examples/EsploraMusic/EsploraMusic.ino | 52 | ||||
-rw-r--r-- | libraries/Esplora/examples/EsploraRemote/EsploraRemote.ino | 94 | ||||
-rw-r--r-- | libraries/Esplora/examples/EsploraTable/EsploraTable.ino | 213 | ||||
-rw-r--r-- | libraries/Esplora/keywords.txt | 68 |
9 files changed, 987 insertions, 0 deletions
diff --git a/libraries/Esplora/Esplora.cpp b/libraries/Esplora/Esplora.cpp new file mode 100644 index 0000000..83df0d7 --- /dev/null +++ b/libraries/Esplora/Esplora.cpp @@ -0,0 +1,175 @@ +/* + Esplora.cpp - Arduino Esplora board library + Written by Enrico Gueli + Copyright (c) 2012 Arduino(TM) All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + + +#include "Esplora.h" + +_Esplora Esplora; + +/* + * The following constants tell, for each accelerometer + * axis, which values are returned when the axis measures + * zero acceleration. + */ +const int ACCEL_ZERO_X = 320; +const int ACCEL_ZERO_Y = 330; +const int ACCEL_ZERO_Z = 310; + +const byte MUX_ADDR_PINS[] = { A0, A1, A2, A3 }; +const byte MUX_COM_PIN = A4; + +const int JOYSTICK_DEAD_ZONE = 100; + +const byte RED_PIN = 5; +const byte BLUE_PIN = 9; +const byte GREEN_PIN = 10; + +const byte BUZZER_PIN = 6; + +// non-multiplexer Esplora pins: +// Accelerometer: x-A5, y-A7, z-A6 +// External outputs: D3, D11 +// Buzzer: A8 +// RGB Led: red-D5, green-D10/A11, blue-D9/A10 +// Led 13: D13 + +const byte ACCEL_X_PIN = A5; +const byte ACCEL_Y_PIN = A11; +const byte ACCEL_Z_PIN = A6; + +const byte LED_PIN = 13; + +_Esplora::_Esplora() { + for (byte p=0; p<4; p++) { + pinMode(MUX_ADDR_PINS[p], OUTPUT); + } + pinMode(RED_PIN, OUTPUT); + pinMode(GREEN_PIN, OUTPUT); + pinMode(BLUE_PIN, OUTPUT); +} + +unsigned int _Esplora::readChannel(byte channel) { + digitalWrite(MUX_ADDR_PINS[0], (channel & 1) ? HIGH : LOW); + digitalWrite(MUX_ADDR_PINS[1], (channel & 2) ? HIGH : LOW); + digitalWrite(MUX_ADDR_PINS[2], (channel & 4) ? HIGH : LOW); + digitalWrite(MUX_ADDR_PINS[3], (channel & 8) ? HIGH : LOW); + // workaround to cope with lack of pullup resistor on joystick switch + if (channel == CH_JOYSTICK_SW) { + pinMode(MUX_COM_PIN, INPUT_PULLUP); + unsigned int joystickSwitchState = (digitalRead(MUX_COM_PIN) == HIGH) ? 1023 : 0; + digitalWrite(MUX_COM_PIN, LOW); + return joystickSwitchState; + } + else + return analogRead(MUX_COM_PIN); +} + +boolean _Esplora::joyLowHalf(byte joyCh) { + return (readChannel(joyCh) < 512 - JOYSTICK_DEAD_ZONE) + ? LOW : HIGH; +} + +boolean _Esplora::joyHighHalf(byte joyCh) { + return (readChannel(joyCh) > 512 + JOYSTICK_DEAD_ZONE) + ? LOW : HIGH; +} + +boolean _Esplora::readButton(byte ch) { + if (ch >= SWITCH_1 && ch <= SWITCH_4) { + ch--; + } + + switch(ch) { + case JOYSTICK_RIGHT: + return joyLowHalf(CH_JOYSTICK_X); + case JOYSTICK_LEFT: + return joyHighHalf(CH_JOYSTICK_X); + case JOYSTICK_UP: + return joyLowHalf(CH_JOYSTICK_Y); + case JOYSTICK_DOWN: + return joyHighHalf(CH_JOYSTICK_Y); + } + + unsigned int val = readChannel(ch); + return (val > 512) ? HIGH : LOW; +} + +void _Esplora::writeRGB(byte r, byte g, byte b) { + writeRed(r); + writeGreen(g); + writeBlue(b); +} + +#define RGB_FUNC(name, pin, lastVar) \ +void _Esplora::write##name(byte val) { \ + if (val == lastVar) \ + return; \ + analogWrite(pin, val); \ + lastVar = val; \ + delay(5); \ +} \ +\ +byte _Esplora::read##name() { \ + return lastVar; \ +} + +RGB_FUNC(Red, RED_PIN, lastRed) +RGB_FUNC(Green, GREEN_PIN, lastGreen) +RGB_FUNC(Blue, BLUE_PIN, lastBlue) + +void _Esplora::tone(unsigned int freq) { + if (freq > 0) + ::tone(BUZZER_PIN, freq); + else + ::noTone(BUZZER_PIN); +} + +void _Esplora::tone(unsigned int freq, unsigned long duration) { + if (freq > 0) + ::tone(BUZZER_PIN, freq, duration); + else + ::noTone(BUZZER_PIN); +} + +void _Esplora::noTone() { + ::noTone(BUZZER_PIN); +} + +int _Esplora::readTemperature(const byte scale) { + long rawT = readChannel(CH_TEMPERATURE); + if (scale == DEGREES_C) { + return (int)((rawT * 500 / 1024) - 50); + } + else if (scale == DEGREES_F) { + return (int)((rawT * 450 / 512 ) - 58); + } + else { + return readTemperature(DEGREES_C); + } +} + +int _Esplora::readAccelerometer(const byte axis) { + switch (axis) { + case X_AXIS: return analogRead(ACCEL_X_PIN) - ACCEL_ZERO_X; + case Y_AXIS: return analogRead(ACCEL_Y_PIN) - ACCEL_ZERO_Y; + case Z_AXIS: return analogRead(ACCEL_Z_PIN) - ACCEL_ZERO_Z; + default: return 0; + } +} diff --git a/libraries/Esplora/Esplora.h b/libraries/Esplora/Esplora.h new file mode 100644 index 0000000..74fa88b --- /dev/null +++ b/libraries/Esplora/Esplora.h @@ -0,0 +1,163 @@ +/* + Esplora.h - Arduino Esplora board library + Written by Enrico Gueli + Copyright (c) 2012 Arduino(TM) All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef ESPLORA_H_ +#define ESPLORA_H_ + +#include "Arduino.h" + +/* + * The following constants are used internally by the Esplora + * library code. + */ + +const byte JOYSTICK_BASE = 16; // it's a "virtual" channel: its ID won't conflict with real ones + +const byte MAX_CHANNELS = 13; + +const byte CH_SWITCH_1 = 0; +const byte CH_SWITCH_2 = 1; +const byte CH_SWITCH_3 = 2; +const byte CH_SWITCH_4 = 3; +const byte CH_SLIDER = 4; +const byte CH_LIGHT = 5; +const byte CH_TEMPERATURE = 6; +const byte CH_MIC = 7; +const byte CH_JOYSTICK_SW = 10; +const byte CH_JOYSTICK_X = 11; +const byte CH_JOYSTICK_Y = 12; + +/* + * The following constants can be used with the readButton() + * method. + */ + +const byte SWITCH_1 = 1; +const byte SWITCH_2 = 2; +const byte SWITCH_3 = 3; +const byte SWITCH_4 = 4; + +const byte SWITCH_DOWN = SWITCH_1; +const byte SWITCH_LEFT = SWITCH_2; +const byte SWITCH_UP = SWITCH_3; +const byte SWITCH_RIGHT = SWITCH_4; + +const byte JOYSTICK_DOWN = JOYSTICK_BASE; +const byte JOYSTICK_LEFT = JOYSTICK_BASE+1; +const byte JOYSTICK_UP = JOYSTICK_BASE+2; +const byte JOYSTICK_RIGHT = JOYSTICK_BASE+3; + +/* + * These constants can be use for comparison with the value returned + * by the readButton() method. + */ +const boolean PRESSED = LOW; +const boolean RELEASED = HIGH; + +/* + * The following constants can be used with the readTemperature() + * method to specify the desired scale. + */ +const byte DEGREES_C = 0; +const byte DEGREES_F = 1; + +/* + * The following constants can be used with the readAccelerometer() + * method to specify the desired axis to return. + */ +const byte X_AXIS = 0; +const byte Y_AXIS = 1; +const byte Z_AXIS = 2; + + +class _Esplora { +private: + byte lastRed; + byte lastGreen; + byte lastBlue; + + unsigned int readChannel(byte channel); + + boolean joyLowHalf(byte joyCh); + boolean joyHighHalf(byte joyCh); + +public: + _Esplora(); + + /* + * Returns a number corresponding to the position of the + * linear potentiometer. 0 means full right, 1023 means + * full left. + */ + inline unsigned int readSlider() { return readChannel(CH_SLIDER); } + + /* + * Returns a number corresponding to the amount of ambient + * light sensed by the light sensor. + */ + inline unsigned int readLightSensor() { return readChannel(CH_LIGHT); } + + /* + * Returns the current ambient temperature, expressed either in Celsius + * or Fahreneit scale. + */ + int readTemperature(const byte scale); + + /* + * Returns a number corresponding to the amount of ambient noise. + */ + inline unsigned int readMicrophone() { return readChannel(CH_MIC); } + + inline unsigned int readJoystickSwitch() { return readChannel(CH_JOYSTICK_SW); } + + inline int readJoystickX() { + return readChannel(CH_JOYSTICK_X) - 512; + } + inline int readJoystickY() { + return readChannel(CH_JOYSTICK_Y) - 512; + } + + int readAccelerometer(const byte axis); + + /* + * Reads the current state of a button. It will return + * LOW if the button is pressed, and HIGH otherwise. + */ + boolean readButton(byte channel); + + void writeRGB(byte red, byte green, byte blue); + void writeRed(byte red); + void writeGreen(byte green); + void writeBlue(byte blue); + + byte readRed(); + byte readGreen(); + byte readBlue(); + + void tone(unsigned int freq); + void tone(unsigned int freq, unsigned long duration); + void noTone(); +}; + + + +extern _Esplora Esplora; + +#endif // ESPLORA_H_ diff --git a/libraries/Esplora/examples/EsploraKart/EsploraKart.ino b/libraries/Esplora/examples/EsploraKart/EsploraKart.ino new file mode 100644 index 0000000..4c1621c --- /dev/null +++ b/libraries/Esplora/examples/EsploraKart/EsploraKart.ino @@ -0,0 +1,125 @@ +/* + Esplora Kart + + This sketch turns the Esplora into a PC game pad. + + It uses the both the analog joystick and the four switches. + By moving the joystick in a direction or by pressing a switch, + the PC will "see" that a key is pressed. If the PC is running + a game that has keyboard input, the Esplora can control it. + + The default configuration is suitable for SuperTuxKart, an + open-source racing game. It can be downloaded from + http://supertuxkart.sourceforge.net/ . + + Created on 22 november 2012 + By Enrico Gueli <enrico.gueli@gmail.com> +*/ + + +#include <Esplora.h> + +/* + You're going to handle eight different buttons. You'll use arrays, + which are ordered lists of variables with a fixed size. Each array + has an index (counting from 0) to keep track of the position + you're reading in the array, and each position can contain a number. + + This code uses three different arrays: one for the buttons you'll read; + a second to hold the current states of those buttons; and a third to hold + the keystrokes associated with each button. + */ + +/* + This array holds the last sensed state of each of the buttons + you're reading. + Later in the code, you'll read the button states, and compare them + to the previous states that are stored in this array. If the two + states are different, it means that the button was either + pressed or released. + */ +boolean buttonStates[8]; + +/* + This array holds the names of the buttons being read. + Later in the sketch, you'll use these names with + the method Esplora.readButton(x), where x + is one of these buttons. + */ +const byte buttons[] = { + JOYSTICK_DOWN, + JOYSTICK_LEFT, + JOYSTICK_UP, + JOYSTICK_RIGHT, + SWITCH_RIGHT, // fire + SWITCH_LEFT, // bend + SWITCH_UP, // nitro + SWITCH_DOWN, // look back +}; + +/* + This array tells what keystroke to send to the PC when a + button is pressed. + If you look at this array and the above one, you can see that + the "cursor down" keystroke is sent when the joystick is moved + down, the "cursor up" keystroke when the joystick is moved up + and so on. +*/ +const char keystrokes[] = { + KEY_DOWN_ARROW, + KEY_LEFT_ARROW, + KEY_UP_ARROW, + KEY_RIGHT_ARROW, + ' ', + 'V', + 'N', + 'B' +}; + +/* + This is code is run only at startup, to initialize the + virtual USB keyboard. +*/ +void setup() { + Keyboard.begin(); +} + +/* + After setup() is finished, this code is run continuously. + Here we continuously check if something happened with the + buttons. +*/ +void loop() { + + // Iterate through all the buttons: + for (byte thisButton=0; thisButton<8; thisButton++) { + boolean lastState = buttonStates[thisButton]; + boolean newState = Esplora.readButton(buttons[thisButton]); + if (lastState != newState) { // Something changed! + /* + The Keyboard library allows you to "press" and "release" the + keys as two distinct actions. These actions can be + linked to the buttons we're handling. + */ + if (newState == PRESSED) { + Keyboard.press(keystrokes[thisButton]); + } + else if (newState == RELEASED) { + Keyboard.release(keystrokes[thisButton]); + } + } + + // Store the new button state, so you can sense a difference later: + buttonStates[thisButton] = newState; + } + + /* + Wait a little bit (50ms) between a check and another. + When a mechanical switch is pressed or released, the + contacts may bounce very rapidly. If the check is done too + fast, these bounces may be confused as multiple presses and + may lead to unexpected behaviour. + */ + delay(50); +} + diff --git a/libraries/Esplora/examples/EsploraLedShow/EsploraLedShow.ino b/libraries/Esplora/examples/EsploraLedShow/EsploraLedShow.ino new file mode 100644 index 0000000..84f049a --- /dev/null +++ b/libraries/Esplora/examples/EsploraLedShow/EsploraLedShow.ino @@ -0,0 +1,42 @@ +/* + Esplora LED Show + + Makes the RGB LED bright and glow as the joystick or the + slider are moved. + + Created on 22 november 2012 + By Enrico Gueli <enrico.gueli@gmail.com> + Modified 24 Nov 2012 + by Tom Igoe +*/ +#include <Esplora.h> + +void setup() { + // initialize the serial communication: + Serial.begin(9600); +} + +void loop() { + // read the sensors into variables: + int xAxis = Esplora.readJoystickX(); + int yAxis = Esplora.readJoystickY(); + int slider = Esplora.readSlider(); + + // convert the sensor readings to light levels: + byte red = map(xAxis, -512, 512, 0, 255); + byte green = map(xAxis, -512, 512, 0, 255); + byte blue = slider/4; + + // print the light levels: + Serial.print(red); + Serial.print(' '); + Serial.print(green); + Serial.print(' '); + Serial.println(blue); + + // write the light levels to the LED. + Esplora.writeRGB(red, green, blue); + + // add a delay to keep the LED from flickering: + delay(10); +} diff --git a/libraries/Esplora/examples/EsploraLedShow2/EsploraLedShow2.ino b/libraries/Esplora/examples/EsploraLedShow2/EsploraLedShow2.ino new file mode 100644 index 0000000..8f9f8a2 --- /dev/null +++ b/libraries/Esplora/examples/EsploraLedShow2/EsploraLedShow2.ino @@ -0,0 +1,55 @@ +/* + Esplora Led/Microphone + + This simple sketch reads the microphone, light sensor, and slider. + Then it uses those readings to set the brightness of red, green and blue + channels of the RGB LED. The red channel will change with the loudness + "heared" by the microphone, the green channel changes as the + amount of light in the room and the blue channel will change + with the position of the slider. + + Created on 22 november 2012 + By Enrico Gueli <enrico.gueli@gmail.com> + Modified 24 Nov 2012 + by Tom Igoe +*/ + +#include <Esplora.h> + +void setup() { + // initialize the serial communication: + Serial.begin(9600); +} + +int lowLight = 400; // the light sensor reading when it's covered +int highLight = 1023; // the maximum light sensor reading +int minGreen = 0; // minimum brightness of the green LED +int maxGreen = 100; // maximum brightness of the green LED + +void loop() { + // read the sensors into variables: + int mic = Esplora.readMicrophone(); + int light = Esplora.readLightSensor(); + int slider = Esplora.readSlider(); + + // convert the sensor readings to light levels: + byte red = constrain(mic, 0, 255); + byte green = constrain( + map(light, lowLight, highLight, minGreen, maxGreen), + 0, 255); + byte blue = slider/4; + + // print the light levels (to see what's going on): + Serial.print(red); + Serial.print(' '); + Serial.print(green); + Serial.print(' '); + Serial.println(blue); + + // write the light levels to the LED. + // note that the green value is always 0: + Esplora.writeRGB(red, green, blue); + + // add a delay to keep the LED from flickering: + delay(10); +} diff --git a/libraries/Esplora/examples/EsploraMusic/EsploraMusic.ino b/libraries/Esplora/examples/EsploraMusic/EsploraMusic.ino new file mode 100644 index 0000000..10c17f7 --- /dev/null +++ b/libraries/Esplora/examples/EsploraMusic/EsploraMusic.ino @@ -0,0 +1,52 @@ +/* + Esplora Music + + This sketch turns the Esplora in a simple musical instrument. + Press the Switch 1 and move the slider to see how it works. + + Created on 22 november 2012 + By Enrico Gueli <enrico.gueli@gmail.com> + modified 24 Nov 2012 + by Tom Igoe +*/ + + +#include <Esplora.h> + + +const int note[] = { +262, // C +277, // C# +294, // D +311, // D# +330, // E +349, // F +370, // F# +392, // G +415, // G# +440, // A +466, // A# +494, // B +523 // C next octave +}; + +void setup() { +} + +void loop() { + // read the button labeled SWITCH_DOWN. If it's low, + // then play a note: + if (Esplora.readButton(SWITCH_DOWN) == LOW) { + int slider = Esplora.readSlider(); + + // use map() to map the slider's range to the + // range of notes you have: + byte thisNote = map(slider, 0, 1023, 0, 13); + // play the note corresponding to the slider's position: + Esplora.tone(note[thisNote]); + } + else { + // if the button isn't pressed, turn the note off: + Esplora.noTone(); + } +} diff --git a/libraries/Esplora/examples/EsploraRemote/EsploraRemote.ino b/libraries/Esplora/examples/EsploraRemote/EsploraRemote.ino new file mode 100644 index 0000000..135b26a --- /dev/null +++ b/libraries/Esplora/examples/EsploraRemote/EsploraRemote.ino @@ -0,0 +1,94 @@ +/* + Esplora Slave + + This sketch allows to test all the Esplora's peripherals. + It is also used with the ProcessingStart sketch (for Processing). + + When uploaded, you can open the Serial monitor and write one of + the following commands (without quotes) to get an answer: + + "D": prints the current value of all sensors, separated by a comma. + See the dumpInputs() function below to get the meaning of + each value. + + "Rxxx" + "Gxxx" + "Bxxx": set the color of the RGB led. For example, write "R255" + to turn on the red to full brightness, "G128" to turn + the green to half brightness, or "G0" to turn off + the green channel. + + "Txxxx": play a tone with the buzzer. The number is the + frequency, e.g. "T440" plays the central A note. + Write "T0" to turn off the buzzer. + + + Created on 22 november 2012 + By Enrico Gueli <enrico.gueli@gmail.com> +*/ + +#include <Esplora.h> + +void setup() { + while(!Serial); // needed for Leonardo-based board like Esplora + Serial.begin(9600); +} + +void loop() { + if (Serial.available()) + parseCommand(); +} + +/* + * This function reads a character from the serial line and + * decide what to do next. The "what to do" part is given by + * function it calls (e.g. dumpInputs(), setRed() and so on). + */ +void parseCommand() { + char cmd = Serial.read(); + switch(cmd) { + case 'D': dumpInputs(); break; + case 'R': setRed(); break; + case 'G': setGreen(); break; + case 'B': setBlue(); break; + case 'T': setTone(); break; + } +} + +void dumpInputs() { + /* + * please note: a single row contains two instructions. + * one is to print the sensor value, the other to print the + * comma symbol. + */ + Serial.print(Esplora.readButton(SWITCH_1)); Serial.print(','); + Serial.print(Esplora.readButton(SWITCH_2)); Serial.print(','); + Serial.print(Esplora.readButton(SWITCH_3)); Serial.print(','); + Serial.print(Esplora.readButton(SWITCH_4)); Serial.print(','); + Serial.print(Esplora.readSlider()); Serial.print(','); + Serial.print(Esplora.readLightSensor()); Serial.print(','); + Serial.print(Esplora.readTemperature(DEGREES_C)); Serial.print(','); + Serial.print(Esplora.readMicrophone()); Serial.print(','); + Serial.print(Esplora.readJoystickSwitch()); Serial.print(','); + Serial.print(Esplora.readJoystickX()); Serial.print(','); + Serial.print(Esplora.readJoystickY()); Serial.print(','); + Serial.print(Esplora.readAccelerometer(X_AXIS)); Serial.print(','); + Serial.print(Esplora.readAccelerometer(Y_AXIS)); Serial.print(','); + Serial.print(Esplora.readAccelerometer(Z_AXIS)); Serial.println(); +} + +void setRed() { + Esplora.writeRed(Serial.parseInt()); +} + +void setGreen() { + Esplora.writeGreen(Serial.parseInt()); +} + +void setBlue() { + Esplora.writeBlue(Serial.parseInt()); +} + +void setTone() { + Esplora.tone(Serial.parseInt()); +} diff --git a/libraries/Esplora/examples/EsploraTable/EsploraTable.ino b/libraries/Esplora/examples/EsploraTable/EsploraTable.ino new file mode 100644 index 0000000..712dffa --- /dev/null +++ b/libraries/Esplora/examples/EsploraTable/EsploraTable.ino @@ -0,0 +1,213 @@ +/* + Esplora Table + + Acts like a keyboard that prints sensor + data in a table-like text, row by row. + + At startup, it does nothing. It waits for you to open a + spreadsheet (e.g. Google Drive spreadsheet) so it can write + data. 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 determined 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 the program to do something else + * in the meanwhile. In particular, it calls checkSwitchPress(). + * Note 1: it may wait longer than the specified amount, not less; + * Note 2: beware of data synchronization issues, e.g. if the + * activeDelay() function alters some variables used by the + * caller of this function. + */ +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; + } +} + diff --git a/libraries/Esplora/keywords.txt b/libraries/Esplora/keywords.txt new file mode 100644 index 0000000..02ba660 --- /dev/null +++ b/libraries/Esplora/keywords.txt @@ -0,0 +1,68 @@ +####################################### +# Syntax Coloring Map For Esplora +####################################### +# Class +####################################### + +Esplora KEYWORD3 + +####################################### +# Methods and Functions +####################################### + +begin KEYWORD2 +readSlider KEYWORD2 +readLightSensor KEYWORD2 +readTemperature KEYWORD2 +readMicrophone KEYWORD2 +readJoystickSwitch KEYWORD2 +readJoystickX KEYWORD2 +readJoystickY KEYWORD2 +readAccelerometer KEYWORD2 +readButton KEYWORD2 +writeRGB KEYWORD2 +writeRed KEYWORD2 +writeGreen KEYWORD2 +writeBlue KEYWORD2 +readRed KEYWORD2 +readGreen KEYWORD2 +readBlue KEYWORD2 +tone KEYWORD2 +noTone KEYWORD2 + + +####################################### +# Constants +####################################### + +JOYSTICK_BASE LITERAL1 +MAX_CHANNELS LITERAL1 +CH_SWITCH_1 LITERAL1 +CH_SWITCH_2 LITERAL1 +CH_SWITCH_3 LITERAL1 +CH_SWITCH_4 LITERAL1 +CH_SLIDER LITERAL1 +CH_LIGHT LITERAL1 +CH_TEMPERATURE LITERAL1 +CH_MIC LITERAL1 +CH_JOYSTICK_SW LITERAL1 +CH_JOYSTICK_X LITERAL1 +CH_JOYSTICK_Y LITERAL1 +SWITCH_1 LITERAL1 +SWITCH_2 LITERAL1 +SWITCH_3 LITERAL1 +SWITCH_4 LITERAL1 +SWITCH_DOWN LITERAL1 +SWITCH_LEFT LITERAL1 +SWITCH_UP LITERAL1 +SWITCH_RIGHT LITERAL1 +JOYSTICK_DOWN LITERAL1 +JOYSTICK_LEFT LITERAL1 +JOYSTICK_UP LITERAL1 +PRESSED LITERAL1 +RELEASED LITERAL1 +DEGREES_C LITERAL1 +DEGREES_F LITERAL1 +X_AXIS LITERAL1 +Y_AXIS LITERAL1 +Z_AXIS LITERAL1 |