Thinking about how to "throttle" reading from the ADC to get correct
values. A little more. One way you could potentially deal with that
situation  could be to change both loops to a while() loop, and only
increment your loop index value if the ADC index value is greater than 0.
Or maybe test if the actual ADC index value is your loop index value +1.
With that said, actually you would only need to throttle the ADC read loop,
so the printing to screen loop could be left alone.

However, this kind of loop would be very CPU intensive, but the problem
with with using usleep() is that technically htis is a system call, and in
addition to adding a hard coded delay, you're likely to also have some
system( between user space and kernel space ) non deterministic delay
penalty inured.

On Mon, Feb 6, 2017 at 10:06 AM, William Hermans <yyrk...@gmail.com> wrote:

>
> On Mon, Feb 6, 2017 at 9:12 AM, Rodrigo Mesquita <
> mesquita.rodrig...@gmail.com> wrote:
>
>> Mr, Willians, thanks for your answer.
>>
>> According to the lipruio's documentation, the variable io->DRam[0]
>> contains the index of the last ADC data read.
>>
>> About the part:
>>
>> do{
>> . . .
>> }while(io->DRam[0] < 126);
>>
>> This is inconsistent with:
>>
>> for(i = 0; i<=127; i++ ){
>> . . .
>> }
>>
>> ,
>>
>> the for is to print the values stored. The do-while is to read the sample
>> 1 to 126. the samples 0 and 127 are read before and after this loop,
>> respectively.
>>
>> What are you sugestions to improve my code, Mr. Hermans?
>>
>
> Please, in the future do not email me personally. Please email to the
> group, so everyone can see the answer, as this may help others in the
> future. It also makes it much harder for me to follow the posts, and give a
> proper answer. Anyway . . .
>
> Assuming what you say is correct. Your loops are still off by two between
> them. The do / while() loop being 1 based( starts from 1 ) where the for()
> loop being zero based( starts from 0 ). To correct this most simply, change
> your for loop to i<=125, or i<126 if that is clearer for you.
>
> After that, starting from the top down.
>
>  float n[256];
>  int a[256];
>  int i=0;
>
>
> float n[256]; is not needed. For this particular application you only
> need one float value for printing a voltage value in your printf()
> statement. In fact, in the future if you plan on expanding on this
> application you may wish to do away with float values entirely, send the
> raw PRU values to an external source( if that's what happens ) and let the
> external source do the heavy math. This makes what your beaglebone is doing
> more efficient, and if performance is needed can make a huge difference.
> Also, you can look into using fixed point numbers, but this would use more
> processor cycles than just sending out raw values.
>
> int a[256]; Assuming 128 samples, I might change this to: int
> channel_n[128]; ( n representing the actual channel you're reading from ),
> then do all the formatting in your printf() statement. If, and when you
> decide to print more than one channel worth of samples. This is however
> more a matter of semantics,  but it'll also make your code much more
> readable. Again, you need to read the C standard  for the compiler you're
> using. It does seem possible you're using a post C99 compiler as you're not
> initializing the variable i within the for() loop. Again, make sure your
> array has enough room for a NULL termination byte, if needed. Which
> wouldn't be of type byte, but instead of type int.
>
> The libpruio stuff TJF will be able to give you a much better answer on.
> As it's his code, and I know nearly nothing of the specifics for this code.
>
> if (pruio_rb_start(io)) printf("rb_start failed (%s)\n", io->Errr); //
> start measurement
> This is also a bit unclear to me, mostly due to not knowing the
> implementation, but I'd probably move this if() statement into a while
> statement. That way you can loop, and sleep 1 second between fails.
> Assuming the check fails more than once. Still it'd be clearer to at least
> me, which may not matter to you, or anyone else. Semantics . . . However,
> as it stands, if the check fails, you code will probably just exit. Maybe
> this is what you want ?
>
> As for your index values being "off" or just plain zero in some cases. The
> first thought that comes to mind is that you're trying to read from the ADC
> too fast. But again, I have no idea what TJF's code is doing, so this may
> not be possible. That would be the first place I'd look though, and in fact
> looking at your output, that seems very possible. As every value that has a
> garbage index value seems to be zero, or close to it. Ask TJF how you
> should throttle your loop. e.g. does he have something implemented in the
> library, or not.
>
> The rest of your code looks like it should work, so I'd clean up your code
> a bit, throttle the ADC reading loop how TJF suggests, and check your
> application output.
>
>
>
> On Mon, Feb 6, 2017 at 8:50 AM, William Hermans <yyrk...@gmail.com> wrote:
>
>>
>>
>> On Mon, Feb 6, 2017 at 4:21 AM, <mesquita.rodrig...@gmail.com> wrote:
>>
>>> Hello Mr. TJF
>>>
>>> First of All, thank you so much for providing support on real-time tasks
>>> using a low cost plataform.
>>> I'm trying to apply the libary "libpruio" to make a system for energy
>>> meansurement using the beaglebone black. To do this,  I need to enable 2
>>> ADC channels, set a sample time, fil a buffer with the samples and make
>>> some calculation that includes the FFT. I'm really newbie on
>>> microprocessors, but i wrote a simple C code. The idea of this code is just
>>> to make 128 samples os the two channels and print the values. Just it:
>>>
>>> #include "unistd.h"
>>> #include "../c_wrapper/pruio.h" // include header
>>> #include "time.h"
>>>
>>>
>>> //! The main function.
>>> int main(/*int argc, char **argv*/)
>>> {
>>>  float n[256];
>>>  int a[256];
>>>  int i=0;
>>>
>>>
>>>   pruIo *io = pruio_new(PRUIO_DEF_ACTIVE, 0x98, 0, 1); //! create new
>>> driver structure
>>>   pruio_adc_setStep(io, 9, 1, 0, 0, 0);
>>>                                  // step 9, AIN-0
>>>   pruio_adc_setStep(io, 10, 2, 0, 0, 0);
>>>
>>>
>>>   if (pruio_config(io, 128, 9<<10 , 156250, 4)){ // upload (default)
>>> settings, start IO mode
>>>                               printf("config failed (%s)\n", io->Errr);}
>>>   else {
>>>
>>>
>>>   if (pruio_rb_start(io)) printf("rb_start failed (%s)\n", io->Errr); //
>>> start measurement
>>>
>>>
>>>   else{
>>>         sleep(1);
>>>
>>>
>>>         i=io->DRam[0];
>>>         a[i] = i;
>>>         n[i] = io->Adc->Value[i];
>>>         do{
>>>                 if(i != io->DRam[0]){
>>>                         i=io->DRam[0];
>>>                         a[i] = i;
>>>                         n[i] = io->Adc->Value[i];
>>>                 }
>>>         }while(io->DRam[0] < 126);
>>>         a[io->DRam[0]] = io->DRam[0];
>>>         n[io->DRam[0]] = io->Adc->Value[io->DRam[0]];
>>>
>>>         for(i = 0; i<=127; i++ ){
>>>             printf("amostra %d            -----               %f \n",
>>> a[i],  (n[i]/65536)*1.8);
>>>         }
>>>
>>> }
>>> /* we're done */
>>> }
>>>   pruio_destroy(io);        /* destroy driver structure */
>>>         return 0;
>>> }
>>>
>>>   Right from the start I see several problems with your code.
>>
>> 125 zero based indexes. Or is it 128 ? Or do you really want 127 indexes
>> ? It's impossible for us to know.
>>
>> do{
>> . . .
>> }while(io->DRam[0] < 126);
>>
>> This is inconsistent with:
>>
>> for(i = 0; i<=127; i++ ){
>> . . .
>> }
>>
>> So, I have no clue what io-DRam[] *is*, but I can assume, somehow,
>> you're storing ADC values in DRAM *somehow* Based on your comments.
>> However, first off,  your indexes to not match one another from buffer
>> "packaging" to buffer "unpacking". Secondly, you're not clearing your
>> buffers(arrays) before using them. This is what the "garbage" numbers are
>> coming from. It's just random values in memory, which by the way is very
>> bad from a couple perspectives. But this also leaves these arrays without a
>> NULL termination at the end. Which is very unsafe, as a potential stack
>> overflow. At least this applies for type char[], I'd have to double check
>> the C standard that you're using for your particular case to make sure.
>> Which you can do more easily than I.
>>
>> Additionally, your code is hard to follow. With variable names such as a,
>> n, and i, and zero helpful comments. The code is not exactly self
>> documenting. But here is what seems to be happening. You're only storing
>> one ADC channel value into the first half of your array. Or maybe the
>> conditional if statement is testing for this somehow( unclear ), and taking
>> care of that ?
>>
>> Assuming what you really want is 128 samples of the two ADC channels you
>> mention, your code needs to change. You need to check and make sure you're
>> never going to overflow from your arrays. Which may mean your arrays need
>> be of size 256 + 1 for each given type. Secondly, your loops need to be
>> consistent at whichever number of values you wish to store. Thirdly, you
>> need to clear your arrays before you use them, which can be done at array
>> initialization, or by using memset(), after initialization.
>>
>> A couple of things worth mentioning. In your printf() statement I'm not
>> sure of libpruio's implementation, but from my experience with the
>> beaglebone's ADC, this does not seem right ---> (n[i]/65536)*1.8) Values
>> output from the ADC are in range 0-4095, I'd double check to make sure that
>> is correct. It could be that libpruio's values are different in
>> implementation through some sort of conversation. Secondly, for some
>> reason, it may become readily apparent that your index value may contain a
>> lot of zero's in the middle indexes. You're going to need to look into why
>> that it happening after you clean your code up some. As I said above. I am
>> not familiar with libpruio's implementation, and the rest of your code is
>> not clear enough to make a determination at a glance.
>>
>>
>>
>>
>>
>

-- 
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/CALHSORooqyJKXom6VOTn87krxrnWV7P7qhQwmLMWKrKMJP7OQw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to