I'm a hobbyist with a recent BBB and I want to use a couple of ADC channels in real time (alternate). As nearly as I can tell, this is not supported by the two risk units.
Have I missed something?

BBB and Linux are new to me. One of the things I would like to do is compute a ratio between two voltages, each of which might exceed 1.8 VDC. One solution might be to use DACs to sent feedback voltages to operational amplifiers that are supplied by 1.8 VDC. The goal is to determine the ratio as quickly as possible and without waiting for Linux to get around to it (waiting for the ADC to happen).

John

You can’t feed more than 1.8V to ADC without damaging it. You can, however, scale it with a simple resistor divider (resistor R1 connected between the ground and second resistor R2, which is then connected to your signal), and hook the ADC to the middle of the divider where it will be scaled down by the ratio R1/(R1+R2). How quickly do you want the result? If it’s miliseconds, Linux is perfectly capable of that; if microseconds, then PRUs can do it; otherwise, you’d have to come with an analog multiplier circuit.

A resistor divider is not going to protect the BBB. if you want true
protection you will need to feed the BBB ADC
from a 1.8v op amp that way the BBB input cannot go over the rails of
the op amp.
OR see attached jpg for another method
A zener doide will also not be 100% protective as the zener may not be
fast enough to react to
a high voltage

Hi John!

As Przemek mentioned, a simple voltage divider can scale the input voltage. Additionaly I use a LED (orange color) between the ADC input and ground in order to block overvoltage. (The LED starts to light up at 1V5 and consumes full power at 1V8. 1 / 6 of the ADC resolution get lost (is less accurate), but the burning LED as indicatior is a nice side effect.)

Regarding software you should have a look at libpruio.

BR

BBB and Linux are new to me. One of the things I would like to do is compute a ratio between two voltages, each of which might exceed 1.8 VDC. One solution might be to use DACs to sent feedback voltages to operational amplifiers that are supplied by 1.8 VDC. The goal is to determine the ratio as quickly as possible and without waiting for Linux to get around to it (waiting for the ADC to happen).

What sample rate do you need ? If something around only a few thousand samples a second. This can be done from userspace without using the PRU’s. You can even use mmap() with /dev/mem/ and directly manipulate the ADC’s registers, which can sample the ADC faster than 200ksps. However, the sample rate would not be as deterministic as using the PRU’s.

You can use a PRU to read the ADC’s for sure. If you search the web for Beaglebone PRU + ADC

, you will find many ways. People have been doing this for a long time( since the beaglebone white ), and if you search this google group, you’ll even find full code for something someone called “ADCcollector”. It’s C, and PASM assembly, but is a very short / easy read / understanding.

As for how to physically connect to the ADC, I’d listen to evilwulfile. He’s been an EE for longer than many people on this group have been alive, and he knows his stuff ( I know him personally ). Don’t risk burning up your board, as I’ve seen several people on these groups do . . .

I need to maintain the ratio of the two voltages and I don't know how high they will get. Milliseconds is OK, but faster is better. I didn't realize the PRU's could do ADC.

By the way, the ADC gives out a value of 0-4095. So scaling voltage is really simple. Say you get a value of 4024 for a reading. In order to get a reading from 0-1.8v from this . . .

((4024 / 4096) * 1.8) or 1.768359375v

The max voltage on the pins still can not exceed 1.8v, this is why one needs an opamp, or similar device to keep the input scaled down. But, in this manner you could even track large voltages. Hundreds or even thousands of volts, at the cost of resolution. Which unfortunately can not be avoided. So going by the above example . . .

((4024 / 4096) * 300) or 294.7265625v

Does this make sense ?

I need to maintain the ratio of the two voltages and I don’t know how high they will get. Milliseconds is OK, but faster is better. I didn’t realize the PRU’s could do ADC.

Technically, they can’t. But they can access the on chip ADC, and very fast. It’s the most deterministic was to access the on chip ADC. Unless, perhaps you ran the board bare metal. Which does not make much sense . . .

Yes, I like the method shown in the schematic. Once the ADC voltages are known for a certain analog input voltage (equal on each channel) the D/A voltages can be compared and the math done.

A few milliseconds to determine the voltage ratio is fast enough. If I can somehow shorten that with a PRU, that is even better. I would rather not add outboard A/Ds.

Some of my problem is I don't know how fast some of the other tasks will take. Those include three stepping motors, a frequency counter, and Ethenet. Possibly, too, a web page server.

BR,

Thanks for the info. I'll take a look at libpruio.

Thanks for the tip. That sample rate is plenty as long as other things can be done while the sampling continues.

I'll search Beaglebone PRU + ADC.

Or 4024 * 1.8 / 4096?

Or 4024 * 1.8 / 4096?

Ok, so let us put this another way. Do you think that is clear when written in code ? What if 1.8 were actually assigned to a constant pointer ?

No, I don't, but having taught programming for over 40 years, I know that students would take your equation and plug it in and then be surprised that they get 0 for an answer.

really now. Prey tell, enlighten us then with your logic.

Anyway, since you do not seem to know why that does not work.

Math on two integer values can not give out a float value. This is not a math problem, but a compiler behavior issue. Intentional or no, one value in the equation brackets has to be forced to a float value as such.

1. ((4024 / 4096.0) * 1.8)

OR

1. const float max_value = 4096; ((4024 / max_value) * 1.8)

It’s also why I suggested using a const above.

#include <stdio.h>

int main(void)
{
const float max_val = 4096;

float test = ((4024 / max_val) * 1.8);
printf("%f\n", test);

return 0;
}

\$ gcc test.c -Wall -o test
\$ ./test
1.768359

Anyway Chad, it is not my responsibility to teach basic C skills. So hopefully your Students were taught to understand why something like this would / could fail. And how to figure out why. Honestly though. Any 6 year old with a browser + know how to use google could figure this out in 2 minutes.

William,
I sincerely apologize to you and to this forum.
Best regards