A simple but very effective scope. Up to 6 channels of 32 bit float data at 1 kHz.

Dependencies:   USBDevice

Dependents:   HIDScope TEST Project5-Motorcontrol EMG_HIDScope_Gr6 ... more

The HID Scope comes in handy for debugging purposes. You can easily specify which values you want to monitor, whether it are Analog inputs, filtering floats or boolean states.

This step by step instruction will guide you through the process and it will be easy to adjust this setup to your needs.

The newest MBED library has some issues with USB devices. For the time being, select MBED library revision 119.

Using the HIDScope on your MBED

If there is no project you currently working on, create one first. Now simply import the HIDScope library into your project by clicking on 'Import Library' on the homepage of this library.

Include the HIDScope library in your header

include the HIDScope library

#include "HIDScope.h"

And define the HIDScope beneath your #include-s, outside of any function. The only parameter that it takes is the number of channels you would like to use. In this case we will use one channel.

define the scope

HIDScope    scope(1);

Now set the data and send it over USB! This example reads and sends at 100hz the value of the analog in.

The simple way, send data at 100hz

#include "mbed.h"
#include "HIDScope.h"

// Define the HIDScope and Ticker object
HIDScope    scope(1);
Ticker      scopeTimer;

// Read the analog input
AnalogIn    a0(p2);

// The data read and send function
void scopeSend()
{
    scope.set(0,a0.read());
    scope.send();
}

int main()
{
    // Attach the data read and send function at 100 Hz
    scopeTimer.attach_us(&scopeSend, 1e4);   
    
    while(1) { }
}

If you have a control-loop running at 10kHz you certainly wouldn't want to transfer the data at 10kHz (that isn't even possible using this device). You could SET the data in the 10kHz loop and SEND the data in a 50hz loop. See the following example using 2 channels:

The better way, separate send and control loop

#include "mbed.h"
#include "HIDScope.h"

// Define the HIDScope and Ticker objects
HIDScope    scope(2);
Ticker      scopeTimer;
Ticker      controllerTimer;

// Two analog inputs to read from
AnalogIn    a0(p2);
AnalogIn    a1(p3);

void controlAndMeasure()
{
    // Do some control
    // ** control code here **

    // Store values in the scope
    scope.set(0,a0.read());
    scope.set(1,a1.read());
}

int main()
{
    // Attach the HIDScope::send method from the scope object to the timer at 50Hz
    scopeTimer.attach_us(&scope, &HIDScope::send, 2e4); 

    // Attach the controlAndMeasure method to the controller timer at 1kHz
    controllerTimer.attach_us(&controlAndMeasure, 1e3);
    
    while(1) { }
        
}

Upload it and you are ready to go!

Using the HID Scope software

The software is written in Python and currently compatible with Windows. A deprecated NodeJS version exists that is compatible with OSX and Unix but it is not supported anymore.

Quick Start

Alternative: Run from source

Alternatively the program can be run from source - Download Python 2.7 - Clone the repo - Run python server.py

Committer:
tomlankhorst
Date:
Mon Sep 08 09:38:36 2014 +0000
Revision:
1:e44574634162
Parent:
0:79e3f3072f3b
Child:
2:9c9226db4fb1
Updated documentation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tomlankhorst 0:79e3f3072f3b 1 #ifndef _HIDSCOPE_H_
tomlankhorst 0:79e3f3072f3b 2 #define _HIDSCOPE_H_
tomlankhorst 0:79e3f3072f3b 3
tomlankhorst 0:79e3f3072f3b 4 #include "mbed.h"
tomlankhorst 0:79e3f3072f3b 5 #include "USBHID.h"
tomlankhorst 0:79e3f3072f3b 6
tomlankhorst 1:e44574634162 7 /** A simple HID (Human Interface Device) scope
tomlankhorst 1:e44574634162 8 * - Up to 6 channels of float data is transmitted in a single HID message (64 byte)
tomlankhorst 1:e44574634162 9 * - Theoretical maximum samplerate of 1kHz
tomlankhorst 1:e44574634162 10 * - Data can be parsed using a client-side server like NodeJS
tomlankhorst 1:e44574634162 11 *
tomlankhorst 1:e44574634162 12 * Example:
tomlankhorst 1:e44574634162 13 * @code
tomlankhorst 1:e44574634162 14 * #include "mbed.h"
tomlankhorst 1:e44574634162 15 * #include "HIDScope.h"
tomlankhorst 1:e44574634162 16 *
tomlankhorst 1:e44574634162 17 * HIDScope scope(2);
tomlankhorst 1:e44574634162 18 * Ticker scopeTimer;
tomlankhorst 1:e44574634162 19 *
tomlankhorst 1:e44574634162 20 * AnalogIn a0(A0);
tomlankhorst 1:e44574634162 21 *
tomlankhorst 1:e44574634162 22 * int main()
tomlankhorst 1:e44574634162 23 * {
tomlankhorst 1:e44574634162 24 *
tomlankhorst 1:e44574634162 25 * scopeTimer.attach_us(&scope, &HIDScope::send, 1e4); // Send data at 100 Hz
tomlankhorst 1:e44574634162 26 *
tomlankhorst 1:e44574634162 27 * while(1){ // Generate some data
tomlankhorst 1:e44574634162 28 * scope.set(0, a0.read());
tomlankhorst 1:e44574634162 29 * scope.set(1, a0.read());
tomlankhorst 1:e44574634162 30 * wait_us(1000);
tomlankhorst 1:e44574634162 31 * };
tomlankhorst 1:e44574634162 32 *
tomlankhorst 1:e44574634162 33 * }
tomlankhorst 1:e44574634162 34 * @endcode
tomlankhorst 0:79e3f3072f3b 35 */
tomlankhorst 0:79e3f3072f3b 36 class HIDScope {
tomlankhorst 0:79e3f3072f3b 37 public:
tomlankhorst 0:79e3f3072f3b 38 ///Instantiate the HID Scope
tomlankhorst 0:79e3f3072f3b 39 HIDScope(int channels);
tomlankhorst 0:79e3f3072f3b 40
tomlankhorst 0:79e3f3072f3b 41 /** Sets the current channel value
tomlankhorst 0:79e3f3072f3b 42 @param ch : integer channel no (0-6)
tomlankhorst 0:79e3f3072f3b 43 @param val : float value
tomlankhorst 0:79e3f3072f3b 44 @return void
tomlankhorst 0:79e3f3072f3b 45 */
tomlankhorst 0:79e3f3072f3b 46 void set(int ch, float val);
tomlankhorst 0:79e3f3072f3b 47
tomlankhorst 0:79e3f3072f3b 48 /** Sets the current channel value
tomlankhorst 0:79e3f3072f3b 49 @param ch : integer channel no (0-6)
tomlankhorst 0:79e3f3072f3b 50 @param val : integer value
tomlankhorst 0:79e3f3072f3b 51 @return void
tomlankhorst 0:79e3f3072f3b 52 */
tomlankhorst 0:79e3f3072f3b 53 void set(int ch, int val);
tomlankhorst 0:79e3f3072f3b 54
tomlankhorst 0:79e3f3072f3b 55 /** Sets the current channel value
tomlankhorst 0:79e3f3072f3b 56 @param ch : integer channel no (0-6)
tomlankhorst 0:79e3f3072f3b 57 @param val : boolean value
tomlankhorst 0:79e3f3072f3b 58 @return void
tomlankhorst 0:79e3f3072f3b 59 */
tomlankhorst 0:79e3f3072f3b 60 void set(int ch, bool val);
tomlankhorst 0:79e3f3072f3b 61
tomlankhorst 0:79e3f3072f3b 62 /** Sets the current channel value
tomlankhorst 0:79e3f3072f3b 63 @param ch : double channel no (0-6)
tomlankhorst 0:79e3f3072f3b 64 @param val : float value
tomlankhorst 0:79e3f3072f3b 65 @return void
tomlankhorst 0:79e3f3072f3b 66 */
tomlankhorst 0:79e3f3072f3b 67 void set(int ch, double val);
tomlankhorst 0:79e3f3072f3b 68
tomlankhorst 0:79e3f3072f3b 69 /** Sends the channel data to the HID client
tomlankhorst 0:79e3f3072f3b 70 @return void
tomlankhorst 0:79e3f3072f3b 71 */
tomlankhorst 0:79e3f3072f3b 72 void send();
tomlankhorst 0:79e3f3072f3b 73 private:
tomlankhorst 0:79e3f3072f3b 74 USBHID hid;
tomlankhorst 0:79e3f3072f3b 75 HID_REPORT scopeData;
tomlankhorst 0:79e3f3072f3b 76 float* bufferData;
tomlankhorst 0:79e3f3072f3b 77 int channelCount;
tomlankhorst 0:79e3f3072f3b 78 };
tomlankhorst 0:79e3f3072f3b 79
tomlankhorst 0:79e3f3072f3b 80 #endif