Api: When do I have to call acqStart/AcqReset()
-
- Posts: 30
- Joined: Thu Feb 25, 2016 7:05 pm
Api: When do I have to call acqStart/AcqReset()
Hello,
in which situation do I have to call rp_AcqReset(), rp_AcqStart()? Just once, before every call of setTriggerSrc or whenever changes like setDecimation oder setTriggerLevel are made?
thank you
in which situation do I have to call rp_AcqReset(), rp_AcqStart()? Just once, before every call of setTriggerSrc or whenever changes like setDecimation oder setTriggerLevel are made?
thank you
-
- Posts: 1441
- Joined: Sat Jun 07, 2014 12:49 pm
- Location: Königswinter
Re: Api: When do I have to call acqStart/AcqReset()
You need to call rp_AcqStart() in order to resume recording after a trigger event was registered (and once at the start).
rp_AcqReset() resets most acquisition parameters to default values, so you probably just want to call it once at the very beginning.
rp_AcqReset() resets most acquisition parameters to default values, so you probably just want to call it once at the very beginning.
-
- Posts: 30
- Joined: Thu Feb 25, 2016 7:05 pm
Re: Api: When do I have to call acqStart/AcqReset()
Just to be sure:
When acq_Start() is called, the fpga waits until a given trigger event happens. Then trigger state is set to 'triggered' and the fpga begins to acquire fresh samples until the buffer is filled.
Right?
This code is from the example 'acquire_trigger_software':
I have some questions about it:
Why is sleep called between rp_AcqStart and rp_AcqSetTriggerSrc(RP_TRIG_SRC_NOW)?
Is it possible to reverse the order?
When is trigger source set to 'TRIGGER_SRC_DISABLED'?
What happens when I load acquired data with rp_AcqGetOldestDataV(RP_CH_1, &buff_size, buff), before the buffer is filled with fresh samples?
Like it could happen (at least I think so) if I remove sleep(1) from the while-loop:
And I guess setting the Trigger_Level doesn't make sense when using TRIGGER_SRC_NOW, right?
When acq_Start() is called, the fpga waits until a given trigger event happens. Then trigger state is set to 'triggered' and the fpga begins to acquire fresh samples until the buffer is filled.
Right?
This code is from the example 'acquire_trigger_software':
Code: Select all
uint32_t buff_size = 16384;
float *buff = (float *)malloc(buff_size * sizeof(float));
rp_AcqReset();
rp_AcqSetDecimation(1);
rp_AcqSetTriggerLevel(0.1); //Trig level is set in Volts while in SCPI
rp_AcqSetTriggerDelay(0);
rp_AcqStart();
/* After acquisition is started some time delay is needed in order to acquire fresh samples in to buffer*/
/* Here we have used time delay of one second but you can calculate exact value taking in to account buffer*/
/*length and smaling rate*/
sleep(1);
rp_AcqSetTriggerSrc(RP_TRIG_SRC_NOW);
rp_acq_trig_state_t state = RP_TRIG_STATE_TRIGGERED;
while(1){
rp_AcqGetTriggerState(&state);
if(state == RP_TRIG_STATE_TRIGGERED){
sleep(1);
break;
}
}
rp_AcqGetOldestDataV(RP_CH_1, &buff_size, buff);
Why is sleep called between rp_AcqStart and rp_AcqSetTriggerSrc(RP_TRIG_SRC_NOW)?
Is it possible to reverse the order?
When is trigger source set to 'TRIGGER_SRC_DISABLED'?
What happens when I load acquired data with rp_AcqGetOldestDataV(RP_CH_1, &buff_size, buff), before the buffer is filled with fresh samples?
Like it could happen (at least I think so) if I remove sleep(1) from the while-loop:
Code: Select all
while(1){
rp_AcqGetTriggerState(&state);
if(state == RP_TRIG_STATE_TRIGGERED){
break;
}
}
rp_AcqGetOldestDataV(RP_CH_1, &buff_size, buff);
-
- Posts: 1441
- Joined: Sat Jun 07, 2014 12:49 pm
- Location: Königswinter
Re: Api: When do I have to call acqStart/AcqReset()
Not quite. When rp_AcqStart() is called, the oscilloscope starts writing samples into its internal buffers immediately, while waiting for the trigger-condition to be met. Once a trigger is recognized, the oscilloscope logic continues to record as many samples as you programmed with rp_AcqSetTriggerDelay(). After this number of samples has been recorded, it resets the trigger source register to RP_TRIG_SRC_DISABLED.When acq_Start() is called, the fpga waits until a given trigger event happens. Then trigger state is set to 'triggered' and the fpga begins to acquire fresh samples until the buffer is filled.
Right?
This should be clear from the above.I have some questions about it:
Why is sleep called between rp_AcqStart and rp_AcqSetTriggerSrc(RP_TRIG_SRC_NOW)?
Is it possible to reverse the order?
When is trigger source set to 'TRIGGER_SRC_DISABLED'?
In my opinion, the example code is not a good demonstration of how to use the oscilloscope API. You'd rather program the amount of data you want with rp_AcqSetTriggerDelay(), then call rp_AcqStart() and rp_AcqSetTriggerSrc(RP_TRIG_SRC_NOW) - no sleep neccessary here. Then just wait for the trigger-source to return to RP_TRIG_SRC_DISABLED. Putting a sleep() or usleep() into this loop is prudent to avoid totally blocking the core the code is running on.
In the case of this example, it could indeed happen like you said. You would then read old or invalid samples. It could also happen that you read data while it is being updated, in which case you'd get a mix of old and new samples.What happens when I load acquired data with rp_AcqGetOldestDataV(RP_CH_1, &buff_size, buff), before the buffer is filled with fresh samples?
Like it could happen (at least I think so) if I remove sleep(1) from the while-loop:
Indeed.And I guess setting the Trigger_Level doesn't make sense when using TRIGGER_SRC_NOW, right?
-
- Posts: 30
- Joined: Thu Feb 25, 2016 7:05 pm
Re: Api: When do I have to call acqStart/AcqReset()
Hmm. The documentation saysNils Roos wrote:Not quite. When rp_AcqStart() is called, the oscilloscope starts writing samples into its internal buffers immediately, while waiting for the trigger-condition to be met. Once a trigger is recognized, the oscilloscope logic continues to record as many samples as you programmed with rp_AcqSetTriggerDelay(). After this number of samples has been recorded, it resets the trigger source register to RP_TRIG_SRC_DISABLED.When acq_Start() is called, the fpga waits until a given trigger event happens. Then trigger state is set to 'triggered' and the fpga begins to acquire fresh samples until the buffer is filled.
Right?
http://libdoc.redpitaya.com/rp_8h.html# ... eece37bf62 .When acquiring is started, the FPGA waits for the trigger condition on the specified source and when the condition is met, it starts writing the signal to the buffer.
I took a closer look into the api source. It seems like the fpga is using a circular buffer. Thus, the latest sample should be at pos and the oldest sample should be at pos+1 (where pos is the write pointer), right?
I've run this small program:
Code: Select all
int main(){
if(rp_Init() != RP_OK){
fprintf(stderr, "Rp api init failed!\n");
return 0;
}
rp_AcqReset();
uint32_t pos;
int k = 3;
while(k>0){
usleep(10);
--k;
rp_AcqGetWritePointer(&pos);
printf("pos: %d\n",pos);
}
rp_AcqStart();
printf("start\n");
k=3;
while(k>0){
usleep(10);
--k;
rp_AcqGetWritePointer(&pos);
printf("pos: %d\n",pos);
}
rp_Release();
}
}
Code: Select all
LD_LIBRARY_PATH=/opt/redpitaya/lib ./test
pos: 5233
pos: 7119
pos: 6789
start
pos: 1228
pos: 2901
pos: 9314
-
- Posts: 1441
- Joined: Sat Jun 07, 2014 12:49 pm
- Location: Königswinter
Re: Api: When do I have to call acqStart/AcqReset()
Let me put it this way: the API and its documentation both still have room for improvements.Hmm. The documentation says ...
When questions of this kind arise, I usually look into the source to come up with an answer.
Yes. As a sidenote: be aware that the write pointer keeps moving as long as the oscilloscope is waiting for a trigger.I took a closer look into the api source. It seems like the fpga is using a circular buffer. Thus, the latest sample should be at pos and the oldest sample should be at pos+1 (where pos is the write pointer), right?
That depends on what you have been doing before. It was already found that rp_AcqReset() is not really resetting the state of the oscilloscope - see this post, and read on for a work-around.At least the first three positions should be equal, shouldn't they?
-
- Posts: 30
- Joined: Thu Feb 25, 2016 7:05 pm
Re: Api: When do I have to call acqStart/AcqReset()
So, when I want to acquire 16384 samples I call rp_AcqSetTriggerDelay(16384). When trigger source turns to disabled all samples are acquired and I can read them by calling rp_AcqGetLatestDataV(channel, &buff_size, buffer) (where buff_size = 16384), ok? (For size = 16384 it doesn't matter if one calls getLatest or getOldest)
I extended my test program a little bit:
It generates the following output:
One can see how the buffer is filled and the scope then stops to acquire fresh samples.
But shouldn't the position be 15401 when the trigger event happend (instead of 7207) or do I mistake rp_AcqGetWritePointerAtTrig(&tr_pos)?
I extended my test program a little bit:
Code: Select all
int main(){
if(rp_Init() != RP_OK){
fprintf(stderr, "Rp api init failed!\n");
return 0;
}
rp_AcqReset();
//rp_AcqSetTriggerDelay(1); //scope is allready stopped, since program exits with stopped scope
//rp_AcqSetTriggerSrc(RP_TRIG_SRC_NOW);
uint32_t pos, tr_pos;
rp_acq_trig_src_t src = 0;
rp_acq_trig_state_t state = 0;
int k = 3;
while(k>0){
usleep(10);
--k;
rp_AcqGetWritePointerAtTrig(&tr_pos);
rp_AcqGetWritePointer(&pos);
rp_AcqGetTriggerSrc(&src);
rp_AcqGetTriggerState(&state);
printf("pos: %d; pos when triggered: %d; trigger source: %d; trigger state: %d\n",pos, tr_pos, src, state);
}
rp_AcqSetTriggerDelay(16384);
printf("start\n");
rp_AcqStart();
k=3;
while(k>0){
usleep(10);
--k;
rp_AcqGetWritePointerAtTrig(&tr_pos);
rp_AcqGetWritePointer(&pos);
rp_AcqGetTriggerSrc(&src);
rp_AcqGetTriggerState(&state);
printf("pos: %d; pos when triggered: %d; trigger source: %d; trigger state: %d\n",pos, tr_pos, src, state);
}
printf("trigger\n");
rp_AcqSetTriggerSrc(RP_TRIG_SRC_NOW);
k=3;
while(k>0){
usleep(1);
--k;
rp_AcqGetWritePointerAtTrig(&tr_pos);
rp_AcqGetWritePointer(&pos);
rp_AcqGetTriggerSrc(&src);
rp_AcqGetTriggerState(&state);
printf("pos: %d; pos when triggered: %d; trigger source: %d; trigger state: %d\n",pos, tr_pos, src, state);
}
//scope is not acquiring samples to buffer anymore ->'stopped'
rp_Release();
}
Code: Select all
pos: 0; pos when triggered: 0; trigger source: 0; trigger state: 1
pos: 0; pos when triggered: 0; trigger source: 0; trigger state: 1
pos: 0; pos when triggered: 0; trigger source: 0; trigger state: 1
start
pos: 11261; pos when triggered: 0; trigger source: 0; trigger state: 1
pos: 740; pos when triggered: 0; trigger source: 0; trigger state: 1
pos: 11715; pos when triggered: 0; trigger source: 0; trigger state: 1
trigger
pos: 11759; pos when triggered: 7207; trigger source: 1; trigger state: 0
pos: 15401; pos when triggered: 7207; trigger source: 0; trigger state: 1
pos: 15401; pos when triggered: 7207; trigger source: 0; trigger state: 1
But shouldn't the position be 15401 when the trigger event happend (instead of 7207) or do I mistake rp_AcqGetWritePointerAtTrig(&tr_pos)?
Last edited by 8lu3 on Wed Mar 23, 2016 10:01 pm, edited 1 time in total.
-
- Posts: 1441
- Joined: Sat Jun 07, 2014 12:49 pm
- Location: Königswinter
Re: Api: When do I have to call acqStart/AcqReset()
The output of your program puzzled me at first, until I noticed that rp_SetTriggerDelay() adds 8192 to its parameter internally.
So you'd do rp_setTriggerDelay(8191); if you wanted to record 16384 samples after the trigger.
So you'd do rp_setTriggerDelay(8191); if you wanted to record 16384 samples after the trigger.
The other way round, the write position should stop at 7206 (provided you set the trigger delay as explained above).But shouldn't the position be 15402 when the trigger event happend (instead of 7207) or do I mistake rp_AcqGetWritePointerAtTrig(&tr_pos)?
-
- Posts: 30
- Joined: Thu Feb 25, 2016 7:05 pm
Re: Api: When do I have to call acqStart/AcqReset()
Ok, that makes more sense now.
But, I'm not sure if I understand it fully.
I think the write_pointer points to the latest sample.
rp_AcqGetLatestDataV copies buffer values from (pos-len) to (pos-1). But, it think the buffer values (pos-len+1) to pos have to be copied, since pos refers to the latest sample.
Furthermore, I don't understand why it's 7207 and not 7209, as 15401-7207 is 8194 and not 8192.
Do you know the reason why there is a trigger delay offset?
And I guess bypassing the trigger delay offset has some bad side-effects?
Bypassing will reduce the time used for acquiring the samples drastically. So, it would be nice if bypassing is possible without any disadvantages.
But, I'm not sure if I understand it fully.
I think the write_pointer points to the latest sample.
rp_AcqGetLatestDataV copies buffer values from (pos-len) to (pos-1). But, it think the buffer values (pos-len+1) to pos have to be copied, since pos refers to the latest sample.
Furthermore, I don't understand why it's 7207 and not 7209, as 15401-7207 is 8194 and not 8192.
Do you know the reason why there is a trigger delay offset?
And I guess bypassing the trigger delay offset has some bad side-effects?
Bypassing will reduce the time used for acquiring the samples drastically. So, it would be nice if bypassing is possible without any disadvantages.
-
- Posts: 1441
- Joined: Sat Jun 07, 2014 12:49 pm
- Location: Königswinter
Re: Api: When do I have to call acqStart/AcqReset()
No, but if I had to guess I would say it is done to have an equal amount of pre- and post-trigger samples in the default case.Do you know the reason why there is a trigger delay offset?
What makes you think that ?Bypassing will reduce the time used for acquiring the samples drastically.
The trigger delay only controls the position of the window of acquired samples in relation to the trigger event. The offset just shifts the position of this window for a given value, and you can counteract it by eg. setting a negative trigger delay.
jadalnie klasyczne ekskluzywne meble wypoczynkowe do salonu ekskluzywne meble tapicerowane ekskluzywne meble do sypialni ekskluzywne meble włoskie
Who is online
Users browsing this forum: No registered users and 90 guests