Real-time USB DAQ PIC18F - Page 1
Forum section: electronics / projects

author: xeta123
author_rank: Newbie
timestamp: December 09, 2011, 10:06:07 am
content: Hello,I have seen Microchip PIC18F USB implementation with related issues and still have a few confusions. I have the common requirements of the real-time data acquisition. In my current implementation I am using Microchip USB Framework. I have developed applications in LabVIEW, Matlab and Microsoft .NET environment by calling the functions in the library mpusbapi.dll. I am basically polling the function MPUSBRead and MPUSBWrite routines in loops. The problem here is that it only provides sampling rates below 100 Hz. Seeing the high capabilities of the PIC ADC and USB protocol, there seems a problem with this approach.If the polling approach in windows environment achieves only these rates than what else can be done. What has any one done to achieve a simple real-time data acquisition implementation that can utilize the full potential of this micro controller. If any one has gone through these or has some related applications like real-time waveform visualization then please provide these here for reference.Thanks

author: ejeffrey
author_rank: Super Contributor
timestamp: December 09, 2011, 10:50:36 am
content: Yeah, you are fighting an uphill battle. First off, USB has a limited polling rate. A bit of google searching says that the OS may default to polling USB at 125 Hz, but can be increased to a maximum of 1000 Hz:http://www.codinghorror.com/blog/2007/04/mouse-dpi-and-usb-polling-rate.htmlLabview is also not generally very good at high speed polling, although it has improved of late. Even so, any general purpose OS can have the occasional long scheduling delay that keeps you from getting up-to-date data.The best way to do this is to program the PIC to poll the ADC at the desired rate and buffer the samples. Then stream them to the PC as fast as possible. Now you will be able to get multiple readings per polling cycle and should dramatically increase your throughput. Depending on how hard you push you may still need to deal with possible buffer overflow due to scheduling randomness, but it should start being a problem at a much higher sample rate.

author: Mechatrommer
author_rank: Super Contributor
timestamp: December 09, 2011, 02:50:05 pm
content: after me having problem with ftdi, now this pic. cant they just copycat how cypress cy7c68013a works? ie 10 of Mbps easily or up to speced 480Mbps depending on your PC limitation? sigh!... end of moan.

author: Unknown
author_rank: Unknown
timestamp: December 09, 2011, 11:07:58 pm
content: Why would you choose an 8-bit MCU if you want to shuffle lots of data? How many bits do you expect it to transfer per clock cycle? Either get a MCU with more power or something with DMA support like the Cypress USB SoC. USB isn't exactly a low latency protocol either, and the PIC won't have the memory to buffer for any length of time.

author: xeta123
author_rank: Newbie
timestamp: December 10, 2011, 11:48:05 am
content: It seems that we can't avoid polling using microchip framework. However, the firmware of the DAQ is configured such that it reads the specified ADC channel or digital input and sends outputs to Digital Outputs or PWM channels. A command over USB must have to be received by the 18F controller to perform any of these actions.What about an interrupt based approach?What other alternatives like HID USB offer?

author: ejeffrey
author_rank: Super Contributor
timestamp: December 10, 2011, 01:32:05 pm
content: Not sure exactly what you mean here. Do you mean that you can't cut the PC out of low-latency loop? This is, the computer needs to read a single sample from the ADC, make some decision, and send a command back to the micro to adjust the digital/PWM outputs? That just isn't going to be high throughput no matter what you do. The link I provided and some other searching around may let you improve the polling rate, but apparently 1 kHz is going to be the maximum set by the USB protocol.USB doesn't support host interrupts at all. All transfers must be initiated by the host. This is different from previous serial architectures like RS232 where the presence of a data byte could cause an interrupt to the host OS and be serviced immediately.How many samples per second do you need?As I said: the only way I think you are going to be happy with this is to program the PIC to do the low latency stuff. That is what it is for. You would set up a polling loop or periodic interrupt in the PIC, read the ADC, decide what to do, and update the digital/PWM outputs. A separate process would communicate with the USB host PC to return the read data in bulk, or to allow the PC to update the feedback parameters.If this isn't sufficient for you, you are going to have to look at a more powerful architecture. The sledgehammer solution is to switch to labview realtime with a reconfigurable IO system (the ones with FPGAs built in). This is going to be a quite expensive undertaking, but requires the least development effort. You might be able to get away with one of the standard low-cost PCIe based DAQ cards from NI in single point acquisition mode, but I don't know what kind of latency you can get even then. A more affordable solution would be to use a more powerful embedded processor like an ARM or PIC32 that could handle everything, but again this would require programming your main loop on the embedded side rather than using labview -- the host communication via USB would still be a communications bottleneck.The other option is to look for a lower latency communication protocol. However, there are not really great options here. RS232 is low latency but probably not high enough bandwidth, and getting harder to come by in any case. Parallel ports kind of suck and are even less common. Internal expansion like PCI and PCIe have a fairly high barrier to entry. Ethernet may be your best option: a dedicated ethernet port on which you have disabled all interrupt aggregation and offload features can be very low latency. You just have to find an MCU with a decent ethernet implementation. I don't know how easy this will be, I have never used ethernet on an MCU.

author: xeta123
author_rank: Newbie
timestamp: December 10, 2011, 02:55:31 pm
content: Actually, I can't implement the control loop inside the DAQ card because doing so will vanish its purpose. The DAQ needs to be general purpose with the aim of acquisition (input) and (output) control signals like digital or PWM outputs. The control loop has to be present in a PC application like Microsoft .NET, Matlab Simulink etc.In the current implementation, the main loop in the DAQ PIC18F controller performs USB related tasks. Upon request of the PC like turning ON a particular ADC channel, the PIC sends its reading in a USB packet back to the PC.My sampling rate requirement is at least 2 KHz.

author: ejeffrey
author_rank: Super Contributor
timestamp: December 10, 2011, 04:00:39 pm
content: OK, well I think you have given yourself an impossible task. You need to revisit one or more of your assumptions.For the third time, the right way is to put the control loop on the embedded side. .NET, simulink, labview, and any other system you are likely to want can target embedded platforms. If your applications are at all important (missing deadlines is unacceptable for whatever reason), you must do this -- no exceptions. A general purpose PC running a general purpose OS simply cannot guarantee sub millisecond latency.If you only need to meet the 2 kHz sample rate "most of the time" and an occasional stall is acceptable you can look at ditching USB. High-speed USB2 can do better if you can find an MCU that supports it. You will have to test a specific choice or examine data sheets in great detal, as I wouldn't count on every chip being able to reach the minimum latency allowed by the protocol. If USB2 doesn't work or you can't find a suitable MCU, RS232, Ethernet, and PCI(e) are all capable of lower latency.

author: xeta123
author_rank: Newbie
timestamp: December 10, 2011, 04:21:26 pm
content: Ok, let me forget the control loop for some time.http://www.semifluid.com/?p=24What if we just want a simple real-time visualization application like the one mentioned in the link. It offers an oscilloscope application developed on PC side. It is using the same USB PIC18F and claims to have 60 KSPS rate.

author: Unknown
author_rank: Unknown
timestamp: December 10, 2011, 05:09:13 pm
content: For real time you don't need low latency, just sending a few thousand samples a few times per second might be sufficient. Especially in the case of a scope, which usually grabs a lot of samples, sends them to the host, waits for a (relatively) long time, and starts again.

author: ejeffrey
author_rank: Super Contributor
timestamp: December 10, 2011, 10:44:12 pm
content: That is no problem. The acquisition loop is on the PIC, and the samples are buffered and streamed to the host. Latency isn't an issue, and you are only limited by the throughput of the USB / serial implementation.

author: slateraptor
author_rank: Frequent Contributor
timestamp: December 11, 2011, 01:54:06 am
content: Quote from: xeta123 on December 09, 2011, 10:06:07 amGame over.

author: scrat
author_rank: Frequent Contributor
timestamp: February 24, 2012, 01:12:32 am
content: In a previous thread I asked for advice about something similar, and so xeta sent me a PM about this thread, but I've just checked my PM box now.In my application I didn't need any feedback control (so no latency problems), just acquisition for visualization on a PC, and I decided to use what I had by hand and was easy to use, a PIC18F2550/4550. I made few tests, but couldn't go much above 1kS/s (8bit/sample), although I don't remember exactly the limit. I think there still is some room for improvement, but I don't think it's too much.It was done within the Microchip USB Framework CDC (serial emulation), in a quite simple way. The acquisition started on a certain char received from the PC, and was terminated after receiving another command. I started the A/D conversion inside a timer interrupt routine, paying attention to trigger the AD GO/DONE bit as the first instruction. After triggering the conversion I pushed the previous converted value in an array (inside the interrupt too), while the free running code sent the bytes at a certain buffer fulfilment (something like 5 bytes, I think). An overlapped writing on the output buffer would be registered on a flag set, so I could be sure about the throughput.I chose the serial emulation for its easiness of use and portability on the PC side. In fact my code was in Matlab, and the communication part is very simple, few lines indeed.If I had to start that thing right now, I'd just use a microcontroller as a coordinator (perhaps the same, because of its simplicity), an external ADC and an FTDI232 as UART to USB (which goes up to nearly 1Mbit/s). If the system was a one-off and I had a little more budget, I'd use a C2000 (perhaps in a ControlCard, to make things simpler) and an FTDI too.

author: xeta123
author_rank: Newbie
timestamp: February 24, 2012, 02:24:58 am
content: Thanks everyone, I understood.