How to take inputs faster using Raspberry Pi - Page 1
Forum section: electronics / general

author: john1998
author_rank: Newbie
timestamp: July 04, 2018, 12:01:38 am
content: I am trying to detect different frequency signals using a Raspberry Pi and an ADC converter (PCF8591). My initial guess was the highest frequency I could detect would be limited by the speed of the I2C bus (which is about 400000 bauds). But when I run the setup, I could only get sampling speeds of around 10000 samples/sec. This value lies very close to the time taken to run an empty for loop in python (which is about 10^(-5) seconds which is equivalent to 10^(5) samples/sec).I wanted to reach higher frequency domain (around 10 MHz) and using a better ADC won't be of much help since the limitation is set by the program itself. I wanted to know if my conclusion is correct or not. I have a feeling I am very wrong and doing something stupid. Any guidance will be much appreciated. Below is the python code I am using for signal detection.Code:#!/usr/bin/python# -*- coding:utf-8 -*-import smbusimport timeimport matplotlib.pyplot as pltstart = time.time()address = 0x48A0 = 0x40A1 = 0x41A2 = 0x42A3 = 0x43bus = smbus.SMBus(1)bus.write_byte_data(address,0,0b00010000)#control byte to tell ADC to act as a differential inputvoltage_value = [ ]time_value = [ ]try:while True:bus.write_byte(address,A0)value = bus.read_byte(address)voltage_value.append(value)time_value.append(time.time()-start)#print("AOUT:%1.3f " %(value*3.3/255))#print(value)#time.sleep(0.1)except KeyboardInterrupt:voltage_value = [x*3.3/255 for x in voltage_value]plt.plot(time_value,voltage_value)plt.ylabel('Voltage')plt.xlabel('Time')plt.show()with open('output.txt', 'w') as f:for v,t in zip(voltage_value,time_value):f.write(str(v)+' '+str(t)+'\n')

author: David Chamberlain
author_rank: Frequent Contributor
timestamp: July 04, 2018, 03:13:43 am
content: Im running i2c on the Pi at 400k but im using c rather than python so thats probably the issue. You have timed it your self as well.

author: Dubbie
author_rank: Unknown
timestamp: July 04, 2018, 04:36:45 am
content: I've found the raspberry pi to be useless at anything that requires precision timing. There is just too much else going on.I'd just use the cheapest arm cortex and use the timers to count conditioned pulses from your input. You can use a second timer to gate it. If you set it up as an i2C slave or something, you could just treat it as a peripheral.You should easily be able to measure 10Mhz accurately that way.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 04, 2018, 01:50:10 pm
content: Quote from: john1998 on July 04, 2018, 12:01:38 amHaven't you answered your own question?That said, even if you can get *much* faster execution using a language like C (so that would be your first step), you will still get bitten by timing uncertainties due to the fact that the OSs available for the RPi don't have a real-time kernel. So if you're relying on a simple loop to get accurate sample rates, you're out of luck. (Even with a real-time kernel, depending on your timing requirements, it may not satisfy them.) By the way which OS are you using? (I'm guessing Raspbian?)This is unfortunate that NO official real-time kernel that I know of is available for the RPi. You may try compiling your own but good luck with that (choosing the right set of patches for the RPi, making it reliable). I'm just guessing that if no official real-time kernel has been released (and I even haven't found any non-official ones), that must be a tough ride. Would be interested to hear from someone who has successfully built one.Some people have released info on using the RPi without any OS - bare metal. I don't recommend this approach unless you're a very seasoned programmer and have time to waste.And all that said, using a small microcontroller for those tasks will be much easier.

author: rstofer
author_rank: Super Contributor
timestamp: July 04, 2018, 03:42:47 pm
content: There is a version of FreeRTOS that runs on the Pi hardware but I'm pretty sure that Linux is right out the window.The real-time stuff needs to be pushed off onto another processor (Arduino? STM32Fxx? mbed?) that communicates with the Pi.

author: C
author_rank: Super Contributor
timestamp: July 04, 2018, 04:05:55 pm
content: john1998Think you are missing the simpleI2C is the max speed limit.If you look at data sheet for PCF8591 you will findfSCL SCL clock frequency - - 100 kHz Max on page 20If you set SCL to 400k on Raspberry Pi then you are trying to run the PCF8591 SCL clock above the max this is unknown what happens to all the specifications for this chip.Second the 100k or 400k is the bit rate for the communications.It takes many bits for each sample.Look at page 8I2C uses many bitsYou can not send or receive faster then you can talk.You want faster then this, the next step up isSerial Peripheral Interface (SPI)Here the Raspberry PI can talk faster, but again you will most likely reach a limit with the ADC/DAC chip limits for SPIQuoteYou can not reach software limit if the hardware sets the limit.For just raw data from an 8-bit ADC using a serial interface you would need an 80 Meg. + clock.Even USB 2.0 is not real fast in bytes per second ( bulk transfer is around 40 million bytes per second)Ethernet at 1G us around 100 million bytes per second raw.Actual rate becomes lower due to overhead.C

author: NorthGuy
author_rank: Super Contributor
timestamp: July 04, 2018, 06:34:21 pm
content: Get PIC16F1*. You'll be surprised how fast it is compared to the speeds you're getting.

author: rstofer
author_rank: Super Contributor
timestamp: July 04, 2018, 08:39:09 pm
content: I must not have read the first post properly but I still don't know how many samples per second you want. I'm not talking communications bit rate but AD sample rate.If a sample involves more than 1 byte that also needs to be discussed. At higher sample rates, serial comms doesn't make sense. That's why they make parallel ADCs. You hook these up to the DMA channel on one of the STM32Fxx parts and it might actually work.But first we need sample rate...

author: Dubbie
author_rank: Unknown
timestamp: July 04, 2018, 08:52:42 pm
content: I was assuming that OP didn't particularly care about the samples themselves, but rather wanted the frequency value, similar to a frequency counter might display.I figure i2C is more than fast enough for this. I think we need more info from OP.

author: NiHaoMike
author_rank: Super Contributor
timestamp: July 04, 2018, 10:35:49 pm
content: Beaglebone Black can sample 16 bits at a rate of 100MHz, but I'm not sure how to synchronize the sample clock to an ADC. A FPGA board is even faster.

author: langwadt
author_rank: Super Contributor
timestamp: July 04, 2018, 10:55:59 pm
content: Quote from: NiHaoMike on July 04, 2018, 10:35:49 pmBeagle bone is "cheating" it has extra processor doing nothing but io

author: NiHaoMike
author_rank: Super Contributor
timestamp: July 05, 2018, 04:47:34 am
content: The I/O coprocessor is precisely what makes the Beaglebone Black a good logic analyzer.

author: senso
author_rank: Frequent Contributor
timestamp: July 06, 2018, 12:10:44 pm
content: Quote from: langwadt on July 04, 2018, 10:55:59 pmI have read somewhere that the Pi CPU also as an equivalent to the TI RPU units, but there is zero docs on how to use them.

author: Nominal Animal
author_rank: Super Contributor
timestamp: July 06, 2018, 09:49:49 pm
content: Note: I am a hobbyist only, with lots of software development experience, but relatively little hardware development experience: hobby gadgets only. So take that into account when considering my opinions below!Aside from the BeagleBones and PocketBeagles with integrated PRUs, I've found that it is much better to use a separate microcontrollerwith native USB supportas a slave device to provide the real-time signal handling.Depending on the kernel used, an userspace application can suffer from latencies between 1ms (HID) to 10ms (kernels compiled with HZ=100, even under just a slight load),worst case. Installing the userspace service daemon with a realtime priority, and using C and sensible programming techniques, including multithreading, in normal operation the latency is on the order of 0.1ms, roundtrips less than 0.2ms. Using a low-latency kernel, or one with HZ=250 to 1000, should clear any latency issues. (Assuming there is sufficient CPU power to do what you want, of course.)I've got excellent results using Teensies, especiallyTeensy LCandTeensy 3.2(I'm not affiliated, just a happy customer); theforumthere is quite active, including the developer of the microcontrollers. You program them in the Arduino environment, using the optimized Teensyduino extension package. (Paul Stoffregen, the Teensy developer, is quite active in Arduino development.)Do note that with Teensy LC/3.2, one is limited to USB 1.1 speeds, i.e. 12 MBits/s, or about a million bytes per second. On the other hand, you can use an ADuM3160/4160 -based USB isolator, like the one byOlimexor the Chinese implementations using ADuM3160/4160; the Chinese $10 ones I bought off eBay were all quite okay (the circuit being quite simple, there isn't much one can do horribly wrong). The Olimex one is nice in that if you need more than the 350 mA or so (obtained from the USB bus via isolated DC-DC converter), you can use an 8V to 15V DC power supply to supply up to 750mA (at 5V) on the device side. The supply needs to be isolated from AC ground, of course, so do check. (I believe some may have a suppression capacitor that ties the negative output to AC ground. However, in Europe, the legal ones with just two prongs should be completely isolated.) The Chinese ones may have less efficient (cheaper) isolated DC-DC converters, so do check how much you can draw from those; typically it is between 250mA and 350mA, depending on the converter used. I do believe there are some even in the sub-$10 range that can provide 350mA with less than 500mA draw from host, but I'm not an EE, and only recently acquired testing equipment that allows me to measure that, so at this point, that is just a belief, not verified fact.To get over the 1 MiB/s limit, I've obtained a Cypress EZ-USB FX2LP devkit (theoretically able to reach the 480Mbit/s or over 40 MiB/s), but haven't had yet time to play with it to see how good it is in practice. Do note that the cheaper USB isolators won't work for this! Before I got my Analog Discovery 2, I was thinking of using this, and an Si866x-isolated ADC frontend (isolating the digital signals from the ADC, letting the entire frontend use the target ground as ground level), for high-speed differential ADC. Now I don't need to.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 07, 2018, 04:09:10 pm
content: Just for the record, for those adventurous enough to consider going bare metal with the RPi, this is a nice tutorial:http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/