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:
Wed May 20 09:32:40 2015 +0000
Revision:
2:9c9226db4fb1
Parent:
1:e44574634162
Child:
5:80d551456856
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 2:9c9226db4fb1 9 * - Theoretical maximum samplerate of 1kHz (due to HID specifications)
tomlankhorst 2:9c9226db4fb1 10 * - Data can be parsed using a client-side server
tomlankhorst 2:9c9226db4fb1 11 *
tomlankhorst 2:9c9226db4fb1 12 * See the following repository for PC software: https://bitbucket.org/tomlankhorst/hidscope
tomlankhorst 1:e44574634162 13 *
tomlankhorst 1:e44574634162 14 * Example:
tomlankhorst 1:e44574634162 15 * @code
tomlankhorst 1:e44574634162 16 * #include "mbed.h"
tomlankhorst 2:9c9226db4fb1 17 * #include "HIDScope.h" // Require the HIDScope library
tomlankhorst 1:e44574634162 18 *
tomlankhorst 2:9c9226db4fb1 19 * HIDScope scope(2); // Instantize a 2-channel HIDScope object
tomlankhorst 2:9c9226db4fb1 20 * Ticker scopeTimer; // Instantize the timer for sending data to the PC
tomlankhorst 1:e44574634162 21 *
tomlankhorst 2:9c9226db4fb1 22 * AnalogIn a0(A0); // Using an analog input to obtain data
tomlankhorst 1:e44574634162 23 *
tomlankhorst 1:e44574634162 24 * int main()
tomlankhorst 1:e44574634162 25 * {
tomlankhorst 1:e44574634162 26 *
tomlankhorst 2:9c9226db4fb1 27 * // Attach the HIDScope::send function to the timer at a 10.000 us interval (100 Hz)
tomlankhorst 2:9c9226db4fb1 28 * scopeTimer.attach_us(&scope, &HIDScope::send, 1e4);
tomlankhorst 1:e44574634162 29 *
tomlankhorst 2:9c9226db4fb1 30 * // Read from the analog input in an endless loop. Two channels are written each iteration.
tomlankhorst 2:9c9226db4fb1 31 * // Note that the control loop can run at a different frequency (1 kHz in this case)
tomlankhorst 2:9c9226db4fb1 32 * while(1){
tomlankhorst 1:e44574634162 33 * scope.set(0, a0.read());
tomlankhorst 1:e44574634162 34 * scope.set(1, a0.read());
tomlankhorst 1:e44574634162 35 * wait_us(1000);
tomlankhorst 1:e44574634162 36 * };
tomlankhorst 1:e44574634162 37 *
tomlankhorst 1:e44574634162 38 * }
tomlankhorst 1:e44574634162 39 * @endcode
tomlankhorst 0:79e3f3072f3b 40 */
tomlankhorst 0:79e3f3072f3b 41 class HIDScope {
tomlankhorst 0:79e3f3072f3b 42 public:
tomlankhorst 0:79e3f3072f3b 43 ///Instantiate the HID Scope
tomlankhorst 0:79e3f3072f3b 44 HIDScope(int channels);
tomlankhorst 0:79e3f3072f3b 45
tomlankhorst 0:79e3f3072f3b 46 /** Sets the current channel value
tomlankhorst 0:79e3f3072f3b 47 @param ch : integer channel no (0-6)
tomlankhorst 0:79e3f3072f3b 48 @param val : float value
tomlankhorst 0:79e3f3072f3b 49 @return void
tomlankhorst 0:79e3f3072f3b 50 */
tomlankhorst 0:79e3f3072f3b 51 void set(int ch, float val);
tomlankhorst 0:79e3f3072f3b 52
tomlankhorst 0:79e3f3072f3b 53 /** Sets the current channel value
tomlankhorst 0:79e3f3072f3b 54 @param ch : integer channel no (0-6)
tomlankhorst 0:79e3f3072f3b 55 @param val : integer value
tomlankhorst 0:79e3f3072f3b 56 @return void
tomlankhorst 0:79e3f3072f3b 57 */
tomlankhorst 0:79e3f3072f3b 58 void set(int ch, int val);
tomlankhorst 0:79e3f3072f3b 59
tomlankhorst 0:79e3f3072f3b 60 /** Sets the current channel value
tomlankhorst 0:79e3f3072f3b 61 @param ch : integer channel no (0-6)
tomlankhorst 0:79e3f3072f3b 62 @param val : boolean value
tomlankhorst 0:79e3f3072f3b 63 @return void
tomlankhorst 0:79e3f3072f3b 64 */
tomlankhorst 0:79e3f3072f3b 65 void set(int ch, bool val);
tomlankhorst 0:79e3f3072f3b 66
tomlankhorst 0:79e3f3072f3b 67 /** Sets the current channel value
tomlankhorst 0:79e3f3072f3b 68 @param ch : double channel no (0-6)
tomlankhorst 0:79e3f3072f3b 69 @param val : float value
tomlankhorst 0:79e3f3072f3b 70 @return void
tomlankhorst 0:79e3f3072f3b 71 */
tomlankhorst 0:79e3f3072f3b 72 void set(int ch, double val);
tomlankhorst 0:79e3f3072f3b 73
tomlankhorst 0:79e3f3072f3b 74 /** Sends the channel data to the HID client
tomlankhorst 0:79e3f3072f3b 75 @return void
tomlankhorst 0:79e3f3072f3b 76 */
tomlankhorst 0:79e3f3072f3b 77 void send();
tomlankhorst 0:79e3f3072f3b 78 private:
tomlankhorst 0:79e3f3072f3b 79 USBHID hid;
tomlankhorst 0:79e3f3072f3b 80 HID_REPORT scopeData;
tomlankhorst 0:79e3f3072f3b 81 float* bufferData;
tomlankhorst 0:79e3f3072f3b 82 int channelCount;
tomlankhorst 0:79e3f3072f3b 83 };
tomlankhorst 0:79e3f3072f3b 84
tomlankhorst 0:79e3f3072f3b 85 #endif