Exploring Esplora – II: Creating a Data Stream

In the prior post, I had decided on a reasonably straightforward project that should provide some good motivation for learning about the Esplora and what it might be capable of.  A fun project seemed to be one which would create a stream of sensor data from the Esplora and push that data out onto the internet where it could be accessed by browsers for online game playing, or perhaps pushed to remote devices for controlling positioning of a camera, or a telescope, a solar panel, or whatever needs positioning.

In this post, I will consider the first component of the project which is to generate a stream of data from the Esplora.  At it’s most basic, a data streaming sketch could simply read the current state of all the sensors, create an output string, send the string over the serial port, and repeat.  For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Read the various sensors
slider = Esplora.readSlider();
xAxis = Esplora.readAccelerometer(X_AXIS);
yAxis = Esplora.readAccelerometer(Y_AXIS);
zAxis = Esplora.readAccelerometer(Z_AXIS);
joystickX = Esplora.readJoystickX();
joystickY = Esplora.readJoystickY();
lightSensor = Esplora.readLightSensor();
microphone = Esplora.readMicrophone();
temperature = Esplora.readTemperature(DEGREES_F);

// "print" the sensor data to a string.
sprintf(outBfr, "s:%d,x:%d,y:%d,z:%d,j:%d,k:%d,l:%d,m:%d,t:%d,u:%d", slider, xAxis, yAxis, zAxis, joystickX, joystickY, lightSensor, microphone, temperature, userVariable);

// "Print" the data string to the serial port
Serial.println(outBfr);
delay(10);

Note in the above bit of code, that reading the values of the sensors has been made trivial with use of library functions provided for each sensor.  Reading the position of the slider is as simple as calling “readSlider()” or reading the level on the light sensor, “readLightSensor()”.  It really can not get any simpler.

As appealing simple the above code is, I wanted a little more control over the stream.  I want to be able to toggle sending on and off as well as control the rate at which the stream is sent.  It would also be nice to have some feedback via the RGB LED as to what state the sketch is in – red for stopped, green for sending, etc.

The four different push buttons on the right hand side of the Esplora seem a natural set of controls for toggling the stream as well as incrementing or decrementing the update rate.  I decided to use the left and right buttons (switch 2 and 4) for turning the stream on and off, and the up and down buttons (switch 1 and 3) for adjusting the update rate.  In addition to simple presses, I would also like to monitor for long presses and take different actions based on the length of the button press.  For example, holding down button 1 for 1/2 second, resets the update interval back to its default value or pressing button 4 for a full second or more, will cause a special value to be assigned to the “user variable” (which will be discussed later).

For handling switch presses, the Esplora library contains a convenient “readButton” function which returns the current status of a specified button.  To deal with longer presses, I wrote a simple function, “ButtonHold” which returns the number of milliseconds for which a button is pressed.

1
2
3
4
5
6
7
8
9
10
11
12
13
long ButtonHold(int switchId) {
long startMillis;

startMillis = millis();      // Initial millis value

// Wait until button is released
while(Esplora.readButton(switchId) == LOW) {
delay(1);
}

// Return the total # of milliseconds button was pressed
return  millis() - startMillis;
}

When a button is pressed, I provide some auditory feedback by sounding a brief tone on the piezo buzzer then I check to see if the button is being held rather than clicked via the above “ButtonHold” function.  If a button is pressed for long enough, my code takes action accordingly.   For example, the code for handling switch 1 (down button) presses is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// If SWITCH_1 pressed, decrease limit by 100 (lower bound is 100)
if (Esplora.readButton(SWITCH_1) == LOW) {
if (limit > 100) {
limit -= 100;
counter = 0;  // Reset the counter to restart interval
// Tone to indicate button was pressed
Esplora.tone(5000, 5);
}
else {
// Different tone indicates that we've reached lower bound of limit
Esplora.tone(880, 20);
}

// If SWITCH_1 pressed for more than 400 milliseconds, reset limit to default of 1,000 milliseconds
if (ButtonHold(SWITCH_1) > 400) {
limit = 1000;
// Sound an obvious tone to indicate action occured
ConfirmationTone();
}
}

In this way, I can monitor the status of the four buttons and use them to control the sketch as it is running.  An issue though is how do I know what state the program is in?  Sure, I can try and remember that I have pressed the left button seven times since startup, or was it eight?  Obviously, it would be easy to lose track of things quickly.  An easy solution is to use the RGB LED to provide some feedback via different colors.  I chose red to indicate that the stream was completely off, i.e. not being sent out over the serial port.  A color of blue means that the stream is on, but the “userVariable” is set to zero.  A green LED indicates that the stream is on and the “userVariable” is set to 1.  By glancing at the LED it’s possible to immediately know what state the program is in.

The final item to discuss is this “userVariable” I have mentioned several times.  This is simply a value passed in the data stream from the Esplora to be used by whatever program is receiving the data.  It would be easy to add more than one “user variable” to the stream, or even add more complex types (JSON perhaps), but for now, my application just needs the one value.  I am using this variable to indicate whether the receiving program should forward the data onwards, or not.  During development, it is sometimes not desirable to be pushing data out onto the internet until I am certain that the code generating the data is working properly.  The “userVariable” is interpreted by the Python receiving app to indicate if the data stream should be forwarded to the internet, or not and the value of the variable is controlled via a push button on the Esplora.

So far, so good.  As described above, it’s rather simple to generate a stream of sensor data from the Esplora and control the stream using various controls on the Esplora.  The next logical step will be to describe how to receive and handle the data stream with a Python script.  However, I will ignore the logic and in the next post in this series I will examine a hosted API which can be used to push the data directly to browsers.   With an understanding of how that works, I will circle back to the Python script.  Until then, back to the code mines.

The code for this post can be located at:  https://github.com/volksdata/esplora  (the esplorastream directory)

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>