[beagleboard] Re: BBB Libpruio Analog Data

2021-03-11 Thread Ritesh Bhatt
Hello TJF,

Thank you for the explanation that is very useful! With parsing the file, 
I'm doing that in Node-Red reading in the file as a binary buffer, but for 
some reason the buffer is 4x the number of sampling points I set. Like 
let's say I tell the script to sample the analog inputs 5000 times, the 
file will come back with 2 when I read it into Node-Red (I'd expect 
1 points since I'm using 2 analog inputs). What could be the cause?

Thanks!

On Wednesday, March 10, 2021 at 2:26:30 PM UTC-5 TJF wrote:

> Hi!
>
> ritesh...@gmail.com schrieb am Dienstag, 9. März 2021 um 21:15:01 UTC+1:
>
>> Specifically, they are collecting the data using Ring Buffer mode and 
>> saving it to a text file to be processed further for some feature 
>> extraction and further analysis.
>>
>> What I'm trying to understand is this: how does Ring Buffer sampling 
>> actually work? As in, if I'm reading data using two analog inputs and 
>> saving it to a text file, what order are the values in? How do I parse them 
>> into meaningful sensor values? I've attached the C code I'm working with, 
>> and greatly appreciate any help or pointers!
>>
>
> Your code doesn't save to a text file. Instead it saves the raw data to a 
> binary file. The unshifted values (0-4095) are stored as 16-bit (unsigned 
> short) binary numbers in the order as captured, like
>
> AIN-1, AIN-2, AIN-1, AIN-2, AIN-1, AIN-2, AIN-1, AIN-2, ...
>
> In order to parse the file, just read it into a buffer and access that 
> buffer by a unsigned short pointer variable. 0 (null) means 0V, 4095 means 
> 1V8. So multiply the unsigned shorts by the factor 1.8/4095 to get the 
> voltage as a real value.
>

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to beagleboard+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/beagleboard/c5efd6f1-2dd7-48ee-a693-182a8710f539n%40googlegroups.com.


[beagleboard] BBB Libpruio Analog Data

2021-03-09 Thread Ritesh Bhatt
Hello! I'm a graduate student working with a BBB trying to collect analog 
data from some sensors through the onboard PRUs (we need high sampling rate 
on the order of 20kHz since it's a frequency based experiment). I'm working 
with code from previous students that worked on this project and they used 
Libpruio to accomplish this. Specifically, they are collecting the data 
using Ring Buffer mode and saving it to a text file to be processed further 
for some feature extraction and further analysis.

What I'm trying to understand is this: how does Ring Buffer sampling 
actually work? As in, if I'm reading data using two analog inputs and 
saving it to a text file, what order are the values in? How do I parse them 
into meaningful sensor values? I've attached the C code I'm working with, 
and greatly appreciate any help or pointers!

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to beagleboard+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/beagleboard/a2fe783e-6b1f-44df-a8ca-92e7a5114747n%40googlegroups.com.
/** \file rb_file.c
\brief Example: fetch ADC samples in a ring buffer and save to file.
This file contains an example on how to use the ring buffer mode of
libpruio. A fixed step mask of AIN-0, AIN-1 and AIN-2 get configured
for maximum speed, sampled in to the ring buffer and from there saved
as raw data to some files. Find a functional description in section
\ref sSecExaRbFile.
Licence: GPLv3, Copyright 2014-\Year by \Mail
Thanks for C code translation: Nils Kohrs 
Compile by: `gcc -Wall -o readTwoADCChannel readTwoADCChannel.c -lpruio`
\since 0.4.0
*/

#include "unistd.h"
#include "time.h"
#include "stdio.h"
#include "libpruio/pruio.h"

//! The main function.
int main(int argc, char **argv)
{
  const uint32 tSamp = (uint32) atoi(argv[1]);  //!< The number of samples in the files (per step).
  const uint32 tmr = (uint32) atoi(argv[2]); //!< The sampling rate in ns (2 -> 50 kHz).
  const uint32 NoStep = 2;  //!< The number of active steps (must match setStep calls and mask).
  const uint32 NoFile = 2;  //!< The number of files to write.
  const char *NamFil = "output2.%u";

  struct timespec mSec;
  mSec.tv_nsec = 100;

  pruIo *io = pruio_new(PRUIO_DEF_ACTIVE, 0, 0, 0); //! create new driver
  if (io->Errr){
   printf("constructor failed (%s)\n", io->Errr); return 1;}

  do {
//Set-up the AIN-1 channel
if (pruio_adc_setStep(io, 10, 1, 0, 0, 0)){ //  step 10, AIN-1
printf("step 10 configuration failed: (%s)\n", io->Errr); break;}
//Set-up the AIN-2 channel
if (pruio_adc_setStep(io,11, 2, 0, 0, 0)){ // step 11, AIN-2
   printf("step 11 configuration failed: (%s)\n", io->Errr); break;}

//Define bit mask for the ADC channels (AIN-1 and AIN-2)
uint32 mask = 6 << 9; //!< The active steps (10 to 11) (6<<9 --> 1100)

uint32 tInd = tSamp * NoStep; //!< The maximum total index.
uint32 half = ((io->ESize >> 2) / NoStep) * NoStep; //!< The maximum index of the half ring buffer.

if (half > tInd){ half = tInd;}  //   adapt size for small files
uint32 samp = (half << 1) / NoStep; //!< The number of samples (per step).

if (pruio_config(io, samp, mask, tmr, 0)){ //   configure driver
   printf("config failed (%s)\n", io->Errr); break;}

if (pruio_rb_start(io)){
 printf("rb_start failed (%s)\n", io->Errr); break;}

/* Writing the recorded values to a buffer */
uint16 *p0 = io->Adc->Value;  //!< A pointer to the start of the ring buffer.
uint16 *p1 = p0 + half;   //!< A pointer to the middle of the ring buffer.
uint32 n;  //!< File counter.
char fName[20];
for(n = 0; n < NoFile; n++){
  sprintf(fName, NamFil, n);
  FILE *oFile = fopen(fName, "w");
  uint32 i = 0;   //!< Start index.
  while(i < tInd){
i += half;
if(i > tInd){ // fetch the rest(maybe no complete chunk)
  uint32 rest = tInd + half - i;
  uint32 iEnd = p1 >= p0 ? rest : rest + half;
  while(io->DRam[0] < iEnd) usleep(1000);
  //printf("  writing samples %u-%u\n", tInd -rest, tInd-1);
  fwrite(p0, sizeof(uint16), rest, oFile);
  uint16 *swap = p0;
  p0 = p1;
  p1 = swap;
  break;
}
if(p1 > p0) while(io->DRam[0] < half) usleep(1000);
elsewhile(io->DRam[0] > half) usleep(1000);
//printf("  writing samples %u-%u\n", i-half, i-1);
fwrite(p0,  sizeof(uint16), half, oFile);
uint16 *swap = p0;
p0 = p1;
p1 = swap;
  }
  fclose(oFile);
  //printf("Finished file %s\n", fName);
}
  } while(0);