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:
Sun Jul 30 17:39:31 2017 +0000
Revision:
7:d23c6edecc49
Parent:
6:188304906687
Update dependencies

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 6:188304906687 7 #if MBED_LIBRARY_VERSION != 119
tomlankhorst 7:d23c6edecc49 8 /* #error HIDScope: Please select MBED revision 119 as newer versions have some known problems with HID devices. */
tomlankhorst 6:188304906687 9 #endif
tomlankhorst 6:188304906687 10
tomlankhorst 1:e44574634162 11 /** A simple HID (Human Interface Device) scope
tomlankhorst 1:e44574634162 12 * - Up to 6 channels of float data is transmitted in a single HID message (64 byte)
tomlankhorst 2:9c9226db4fb1 13 * - Theoretical maximum samplerate of 1kHz (due to HID specifications)
tomlankhorst 2:9c9226db4fb1 14 * - Data can be parsed using a client-side server
tomlankhorst 2:9c9226db4fb1 15 *
tomlankhorst 2:9c9226db4fb1 16 * See the following repository for PC software: https://bitbucket.org/tomlankhorst/hidscope
tomlankhorst 6:188304906687 17 *
tomlankhorst 6:188304906687 18 * There seem to be some issues with newest MBED revisions. Please select revision 119 for the time being.
tomlankhorst 1:e44574634162 19 *
tomlankhorst 1:e44574634162 20 * Example:
tomlankhorst 1:e44574634162 21 * @code
tomlankhorst 1:e44574634162 22 * #include "mbed.h"
tomlankhorst 2:9c9226db4fb1 23 * #include "HIDScope.h" // Require the HIDScope library
tomlankhorst 1:e44574634162 24 *
tomlankhorst 2:9c9226db4fb1 25 * HIDScope scope(2); // Instantize a 2-channel HIDScope object
tomlankhorst 2:9c9226db4fb1 26 * Ticker scopeTimer; // Instantize the timer for sending data to the PC
tomlankhorst 1:e44574634162 27 *
tomlankhorst 2:9c9226db4fb1 28 * AnalogIn a0(A0); // Using an analog input to obtain data
tomlankhorst 1:e44574634162 29 *
tomlankhorst 1:e44574634162 30 * int main()
tomlankhorst 1:e44574634162 31 * {
tomlankhorst 1:e44574634162 32 *
tomlankhorst 2:9c9226db4fb1 33 * // Attach the HIDScope::send function to the timer at a 10.000 us interval (100 Hz)
tomlankhorst 2:9c9226db4fb1 34 * scopeTimer.attach_us(&scope, &HIDScope::send, 1e4);
tomlankhorst 1:e44574634162 35 *
tomlankhorst 2:9c9226db4fb1 36 * // Read from the analog input in an endless loop. Two channels are written each iteration.
tomlankhorst 2:9c9226db4fb1 37 * // Note that the control loop can run at a different frequency (1 kHz in this case)
tomlankhorst 2:9c9226db4fb1 38 * while(1){
tomlankhorst 1:e44574634162 39 * scope.set(0, a0.read());
tomlankhorst 1:e44574634162 40 * scope.set(1, a0.read());
tomlankhorst 1:e44574634162 41 * wait_us(1000);
tomlankhorst 1:e44574634162 42 * };
tomlankhorst 1:e44574634162 43 *
tomlankhorst 1:e44574634162 44 * }
tomlankhorst 1:e44574634162 45 * @endcode
tomlankhorst 0:79e3f3072f3b 46 */
tomlankhorst 0:79e3f3072f3b 47 class HIDScope {
tomlankhorst 0:79e3f3072f3b 48 public:
tomlankhorst 0:79e3f3072f3b 49 ///Instantiate the HID Scope
tomlankhorst 5:80d551456856 50 HIDScope(int channels, bool non_blocking = true);
tomlankhorst 0:79e3f3072f3b 51
tomlankhorst 0:79e3f3072f3b 52 /** Sets the current channel value
tomlankhorst 0:79e3f3072f3b 53 @param ch : integer channel no (0-6)
tomlankhorst 0:79e3f3072f3b 54 @param val : float value
tomlankhorst 0:79e3f3072f3b 55 @return void
tomlankhorst 0:79e3f3072f3b 56 */
tomlankhorst 0:79e3f3072f3b 57 void set(int ch, float val);
tomlankhorst 0:79e3f3072f3b 58
tomlankhorst 0:79e3f3072f3b 59 /** Sets the current channel value
tomlankhorst 0:79e3f3072f3b 60 @param ch : integer channel no (0-6)
tomlankhorst 0:79e3f3072f3b 61 @param val : integer value
tomlankhorst 0:79e3f3072f3b 62 @return void
tomlankhorst 0:79e3f3072f3b 63 */
tomlankhorst 0:79e3f3072f3b 64 void set(int ch, int val);
tomlankhorst 0:79e3f3072f3b 65
tomlankhorst 0:79e3f3072f3b 66 /** Sets the current channel value
tomlankhorst 0:79e3f3072f3b 67 @param ch : integer channel no (0-6)
tomlankhorst 0:79e3f3072f3b 68 @param val : boolean value
tomlankhorst 0:79e3f3072f3b 69 @return void
tomlankhorst 0:79e3f3072f3b 70 */
tomlankhorst 0:79e3f3072f3b 71 void set(int ch, bool val);
tomlankhorst 0:79e3f3072f3b 72
tomlankhorst 0:79e3f3072f3b 73 /** Sets the current channel value
tomlankhorst 0:79e3f3072f3b 74 @param ch : double channel no (0-6)
tomlankhorst 0:79e3f3072f3b 75 @param val : float value
tomlankhorst 0:79e3f3072f3b 76 @return void
tomlankhorst 0:79e3f3072f3b 77 */
tomlankhorst 0:79e3f3072f3b 78 void set(int ch, double val);
tomlankhorst 0:79e3f3072f3b 79
tomlankhorst 0:79e3f3072f3b 80 /** Sends the channel data to the HID client
tomlankhorst 0:79e3f3072f3b 81 @return void
tomlankhorst 0:79e3f3072f3b 82 */
tomlankhorst 0:79e3f3072f3b 83 void send();
tomlankhorst 0:79e3f3072f3b 84 private:
tomlankhorst 5:80d551456856 85 bool send_non_blocking;
tomlankhorst 0:79e3f3072f3b 86 USBHID hid;
tomlankhorst 0:79e3f3072f3b 87 HID_REPORT scopeData;
tomlankhorst 0:79e3f3072f3b 88 float* bufferData;
tomlankhorst 0:79e3f3072f3b 89 int channelCount;
tomlankhorst 0:79e3f3072f3b 90 };
tomlankhorst 0:79e3f3072f3b 91
tomlankhorst 0:79e3f3072f3b 92 #endif