Editing Using SimpleMotion scope capture feature

Jump to: navigation, search

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.

This page supports semantic in-text annotations (e.g. "[[Is specified as::World Heritage Site]]") to build structured and queryable content provided by Semantic MediaWiki. For a comprehensive description on how to use annotations or the #ask parser function, please have a look at the getting started, in-text annotation, or inline queries help page.

Latest revision Your text
Line 1: Line 1:
 
This page is written in Finnish. Translation work in progress. If you need it now, please inquire at [[Granite Devices support]].
 
This page is written in Finnish. Translation work in progress. If you need it now, please inquire at [[Granite Devices support]].
  
==Alustus, asetetaan skoopin parametrit==
+
=== Initialization of parameters ===
 
+
*SMP_CAPTURE_BUF_LENGHT - montako samplea kaapataan 1-2048
    SMP_CAPTURE_BUF_LENGHT - montako samplea kaapataan 1-2048
+
*SMP_CAPTURE_SAMPLERATE - näytteistystaajuus (tai sen jakaja). IONIllla/ATOMIlla taajuus on 20kHz/(arvo+1), eli 0=20kHz, 1=10kHz, 2=6.66kHz jne. ARGONilla taajuus alkaa 17.5kHz:stä.
 
+
*SMP_CAPTURE_SOURCE - päälläolevat bitit tässä parametrissa määräävät mitä signaaleja bufferiin kaapataan, seuraavat on saavatilla kaikissa firmisversioissa (samat mitä granityssä valittavissa):  
    SMP_CAPTURE_SAMPLERATE - näytteistystaajuus (tai sen jakaja). Taajuus on 20kHz/(arvo+1), eli 0=20kHz, 1=10kHz, 2=6.66kHz jne
+
 
+
**    #define CAPTURE_TORQUE_TARGET 1     #define CAPTURE_TORQUE_ACTUAL 2     #define CAPTURE_VELOCITY_TARGET 3     #define CAPTURE_VELOCITY_ACTUAL 4     #define CAPTURE_POSITION_TARGET 5     #define CAPTURE_POSITION_ACTUAL 6     #define CAPTURE_FOLLOW_ERROR 7     #define CAPTURE_OUTPUT_VOLTAGE 8     #define CAPTURE_BUS_VOLTAGE 9     #define CAPTURE_DEBUG1 19     #define CAPTURE_DEBUG2 20
    SMP_CAPTURE_SOURCE - päälläolevat bitit tässä parametrissa määräävät mitä signaaleja bufferiin kaapataan, seuraavat on saavatilla kaikissa firmisversioissa (samat mitä granityssä valittavissa):
+
**Esim arvoksi tulee 68 (bitit 2 & 6) kanavilla CAPTURE_TORQUE_ACTUAL ja CAPTURE_POSITION_ACTUAL.
            #define CAPTURE_TORQUE_TARGET 1
+
            #define CAPTURE_TORQUE_ACTUAL 2
+
*SMP_CAPTURE_TRIGGER - triggeri mikä käynnistää kaappauksen, vaihtoehdot (samat mitä granityssä valittavissa):  
            #define CAPTURE_VELOCITY_TARGET 3
+
            #define CAPTURE_VELOCITY_ACTUAL 4
+
**    #define TRIG_NONE 0    #define TRIG_INSTANT 1    #define TRIG_FAULT 2    #define TRIG_TARGETCHANGE 3    #define TRIG_TARGETCHANGE_POS 4    #define TRIG_EXTERNAL_INPUT 5
            #define CAPTURE_POSITION_TARGET 5
+
            #define CAPTURE_POSITION_ACTUAL 6
+
*SMP_CAPTURE_BEFORE_TRIGGER_PERCENTS - tämä tuli vasta FW versiossa 1.6.0. asettaa kaappauksen aloituksen ennen triggausta. arvo prosentteina -1000000...100. Granityt 1.13.0 voi testailla tämän toimintaa.  
            #define CAPTURE_FOLLOW_ERROR 7
+
            #define CAPTURE_OUTPUT_VOLTAGE 8
+
=== Reading scope data ===
            #define CAPTURE_BUS_VOLTAGE 9
+
*Pollataan arvoa SMP_CAPTURE_STATE, arvot:
            #define CAPTURE_DEBUG1 19
+
**0 - idle (kaappaus valmis tai ei vielä aloitettukaan)
            #define CAPTURE_DEBUG2 20
+
**1 - odottaa triggeriä
        Esim arvoksi tulee 68 (bitit 2 & 6) kanavilla CAPTURE_TORQUE_ACTUAL ja CAPTURE_POSITION_ACTUAL.
+
**2 - kaappaus käynnissä
 
+
*Kun kaappaus valmis (käynyt arvoissa !=0 ja sitten 0), ladataan data talteen:  
    SMP_CAPTURE_TRIGGER - triggeri mikä käynnistää kaappauksen, vaihtoehdot (samat mitä granityssä valittavissa):
+
            #define TRIG_NONE 0
+
**asetetaan SMP_CAPTURE_BUFFER_GET_ADDR = 0
            #define TRIG_INSTANT 1
+
**luetaan parametria SMP_CAPTURE_BUFFER_GET_VALUE yhtä monta kertaa kuin alustuksessa asetettu parametrin arvo SMP_CAPTURE_BUF_LENGHT on  
            #define TRIG_FAULT 2
+
            #define TRIG_TARGETCHANGE 3
+
***tämän luku palauttaa kaapatut samplet. jos asetettiin kaapattavaksi kanavat a, b ja c, niin luetut arvot tulevat järjestyksesä a0,b0,c0,a1,b1,c1,a2,b2,c2,a3,b3,c3.
            #define TRIG_TARGETCHANGE_POS 4
+
            #define TRIG_EXTERNAL_INPUT 5
+
 
+
    SMP_CAPTURE_BEFORE_TRIGGER_PERCENTS - tämä tuli vasta FW versiossa 1.6.0. asettaa kaappauksen aloituksen ennen triggausta. arvo prosentteina -1000000...100. Granityt 1.13.0 voi testailla tämän toimintaa.
+
 
+
==Skoopin luku==
+
 
+
    Pollataan arvoa SMP_CAPTURE_STATE, arvot:
+
        0 - idle (kaappaus valmis tai ei vielä aloitettukaan)
+
        1 - odottaa triggeriä
+
        2 - kaappaus käynnissä
+
 
+
    Kun kaappaus valmis (käynyt arvoissa !=0 ja sitten 0), ladataan data talteen:
+
        asetetaan SMP_CAPTURE_BUFFER_GET_ADDR = 0
+
        luetaan parametria SMP_CAPTURE_BUFFER_GET_VALUE yhtä monta kertaa kuin alustuksessa asetettu parametrin arvo SMP_CAPTURE_BUF_LENGHT on
+
            tämän luku palauttaa kaapatut samplet. jos asetettiin kaapattavaksi kanavat a, b ja c, niin luetut arvot tulevat järjestyksesä a0,b0,c0,a1,b1,c1,a2,b2,c2,a3,b3,c3.
+
 
+
==Example==
+
<syntaxhighlight lang="c">
+
/* Thanks to Oskari Timperi for making part of the code */
+
#include <stdio.h>
+
#include <unistd.h> //for usleep
+
#include "simplemotion.h"
+
 
+
smbus handle;
+
int nodeAddress;
+
 
+
bool setupScope()
+
{
+
    SM_STATUS status = 0;
+
 
+
    status |= smSetParameter(handle, nodeAddress, SMP_CAPTURE_BUF_LENGHT, 2048);
+
    status |= smSetParameter(handle, nodeAddress, SMP_CAPTURE_BEFORE_TRIGGER_PERCENTS, 0); //note, requires on IONI FW 1.6.0 or later
+
    status |= smSetParameter(handle, nodeAddress, SMP_CAPTURE_SAMPLERATE, 7); //with IONI sample rate is 20000/(SMP_CAPTURE_SAMPLERATE+1) Hz, so here it is 2500 Hz
+
    status |= smSetParameter(handle, nodeAddress, SMP_CAPTURE_SOURCE, BV(CAPTURE_POSITION_ACTUAL)|BV(CAPTURE_BUS_VOLTAGE));
+
    status |= smSetParameter(handle, nodeAddress, SMP_CAPTURE_TRIGGER, TRIG_INSTANT);
+
    status |= smSetParameter(handle, nodeAddress, SMP_CAPTURE_STATE, 1); //start capture
+
 
+
    if(status!=SM_OK)
+
    {
+
        //error
+
        return false;
+
    }
+
    return true;
+
}
+
 
+
//parameters: nsamples=number of samples to read 1-2048, samples=pointer to buffer with at least nsamples length
+
bool downloadScope( int nsamples, int *samples )
+
{
+
    smint32 retval;
+
    int samplesread=0, storepos=0;
+
    SM_STATUS smStat=0;
+
 
+
    //setup for scope reading
+
    smStat|=smAppendSMCommandToQueue( handle, SMPCMD_SET_PARAM_ADDR, SMP_RETURN_PARAM_LEN );
+
    smStat|=smAppendSMCommandToQueue( handle, SMPCMD_24B, SMPRET_32B );//read 32 bit (values capped to 30 bits) samples
+
    smStat|=smAppendSMCommandToQueue( handle, SMPCMD_SET_PARAM_ADDR, SMP_RETURN_PARAM_ADDR );
+
    smStat|=smAppendSMCommandToQueue( handle, SMPCMD_24B, SMP_CAPTURE_BUFFER_GET_VALUE ); //read at get_value param
+
    smStat|=smAppendSMCommandToQueue( handle, SMPCMD_SET_PARAM_ADDR, SMP_CAPTURE_BUFFER_GET_ADDR ); //set store address to get_addr
+
    smStat|=smExecuteCommandQueue(handle,nodeAddress);
+
    smStat|=smGetQueuedSMCommandReturnValue(  handle, &retval );
+
    smStat|=smGetQueuedSMCommandReturnValue(  handle, &retval );
+
    smStat|=smGetQueuedSMCommandReturnValue(  handle, &retval );
+
    smStat|=smGetQueuedSMCommandReturnValue(  handle, &retval );
+
    smStat|=smGetQueuedSMCommandReturnValue(  handle, &retval );
+
 
+
    //loop to read samples
+
    while(samplesread<nsamples)
+
    {
+
        int i;
+
        int samplestofetch=nsamples-samplesread;
+
        if(samplestofetch>30)samplestofetch=30;//maximum per one SM cycle (4*30=120 bytes=max payload)
+
 
+
        //add read param commands to queue
+
        for(i=0;i<samplestofetch;i++)
+
        {
+
            smStat|=smAppendSMCommandToQueue( handle, SMPCMD_24B, samplesread );
+
            samplesread++;
+
        }
+
 
+
        //transmit & redeive over SM bus
+
        smStat|=smExecuteCommandQueue(handle,nodeAddress);
+
 
+
        //read values from return data queue
+
        for(i=0;i<samplestofetch;i++)
+
        {
+
            smStat|=smGetQueuedSMCommandReturnValue(  handle, &retval );
+
            samples[storepos++]=retval;
+
        }
+
    }
+
 
+
    //read one dummy variable just to cause SMP_RETURN_PARAM_ADDR to change to non-SMP_CAPTURE_BUFFER_GET_VALUE so next time we read data, we get it all from beginning
+
    smStat |= smRead1Parameter(handle, nodeAddress, SMP_NULL, &retval );
+
 
+
    if(smStat!=SM_OK)
+
        return false;
+
 
+
    return true;
+
}
+
 
+
SM_STATUS scopeWait()
+
{
+
    smint32 state;
+
 
+
    //loop until SMP_CAPTURE_STATE is 0 (scope idle)
+
    while (true)
+
    {
+
        SM_STATUS status = smRead1Parameter(handle, nodeAddress, SMP_CAPTURE_STATE, &state);
+
 
+
        if (status != SM_OK)
+
            return status;
+
 
+
        fprintf(stderr, "scope state: %d\n", state);
+
 
+
        if (state == 0)
+
        {
+
            break;
+
        }
+
 
+
        usleep(100000);
+
    }
+
 
+
    return SM_OK;
+
}
+
 
+
 
+
int main( void )
+
{
+
    const char *portName="COM3"; //bus device name
+
    nodeAddress = 4; //SM device address
+
    int samples[2048];
+
 
+
    fprintf(stderr, "opening bus %s\n", portName);
+
    handle = smOpenBus(portName);
+
 
+
    if (handle < 0)
+
    {
+
        fprintf(stderr, "could not open bus: %s\n", portName);
+
        return -4;
+
    }
+
 
+
    if(setupScope()==false)
+
        return -1;
+
 
+
    if(scopeWait()!=SM_OK)
+
        return -2;
+
 
+
    if(downloadScope( 2048, samples )==false)
+
        return -3;
+
 
+
    //sample list will be repeating list of samples defined to SMP_CAPTURE_SOURCE.
+
    //I.e if we capture 3 channels A, B and C, then samples will contain A0,B0,C0,A1,B1,C1,A2,B3,C3 etc
+
    for( int i=0; i<2048; i++)
+
    {
+
        fprintf(stderr, "samples[%d]=%d\n", i, samples[i]);
+
    }
+
 
+
    fprintf(stderr, "All done\n");
+
    return 0;
+
}
+
</syntaxhighlight>
+
 
+
[[Category:SimpleMotion]]
+

Please note that all contributions to Granite Devices Knowledge Wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see Granite Devices Knowledge Wiki:Copyrights for details). Do not submit copyrighted work without permission!

Select categories:

To edit this page, please answer the question that appears below (more info):

Cancel | Editing help (opens in new window)