PC USB scope project.

While STM32 has a slower internal clock it can access digital I/O at 84MHz. The STM32F4 line also comes with hardware FPU for onboard signal preprocessing. Even the much slower STM32F0 series has 24MHz digital I/O. If you want fast, there is STM32F7 series with 216MHz Cortex-M7 cores, built-in USB 2.0 high speed transceivers (STM32F4 required external USB3300 transceivers for USB 2.0 480Mb/s operation) and 108MHz I/O

As of the PCB, I think with signals at that speed you will need the board be implemented using as much surface mount parts as possible.

Also you can run the PIC on the same clock as the external ADC. This can eliminate your clock woes. On the other hand you can also run the ADC on the clock derived from the PIC.

As of USB interface, USB audio class can be a better option than USB HID as it allows a much higher throughput.

The PIC needs to synch to the A2D by only reading when clock is low.
Its possible to read the data as its changing otherwise which would be a disaster.

The next step is to look at DMA for reading in the port.
 
I took a different approach today and generated the a2d clock using pwm hardware on the PIC. This is 20MHz, the full speed of the a2d.
However the software could only manage 18MHz but its still better than the 10.5MHZ I was getting before.
I was worried simply reading the a2d would sometimes catch it as the data was changing but it doesn't appear to be a problem.

I did notice that sometimes the screen display had a lump of the waveform missing.
This was down to interrupts diverting the PIC away from my code momentarily.
I just disabled the interrupts and its fine now.
 
Last edited:
I took a different approach today and generated the a2d clock using pwm hardware on the PIC. This is 20MHz, the full speed of the a2d.
However the software could only manage 18MHz but its still better than the 10.5MHZ I was getting before.
I was worried simply reading the a2d would sometimes catch it as the data was changing but it doesn't appear to be a problem.

I did notice that sometimes the screen display had a lump of the waveform missing.
This was down to interrupts diverting the PIC away from my code momentarily.
I just disabled the interrupts and its fine now.
If this happens, you have a problem in your code and disabling interrupts would only result in even more problem.

I am wondering why you are not using the built-in ADC of your MCU? Those allow you run interrupts from the ADC so it can preempt whatever else that is going on.
 
If this happens, you have a problem in your code and disabling interrupts would only result in even more problem.

I am wondering why you are not using the built-in ADC of your MCU? Those allow you run interrupts from the ADC so it can preempt whatever else that is going on.

The inputting of data from the a2d mustn't be interfered with or there are missing parts of the waveform on the pc screen. Interrupt's can be disabled during data capture and re-enabled when finished.

The internal a2d is only 1 mega samples per second and I am looking for about 20MHz.
 
The inputting of data from the a2d mustn't be interfered with or there are missing parts of the waveform on the pc screen. Interrupt's can be disabled during data capture and re-enabled when finished.

The internal a2d is only 1 mega samples per second and I am looking for about 20MHz.

If this is the case, I am detecting an even more serious issue in your design: upstream bus contention. It is likely that it is not the interrupts that may cause the problem but the host interface simply being saturated. Your use case likely needs 20MB/s throughput at 20Msps 8bps and the whole theoretical maximum of USB 2.0 480Mbps is 60MB/s.

A much more common design for such frontends uses a FPGA with some RAM. The FPGA writes samples from to the RAM as a ring buffer. Some other part of the FPGA handles triggering that can match the incoming data to the trigger condition and interrupt the USB MCU when a trigger condition is met. This greatly reduces the USB bandwidth requirement as it is now bursts instead of a constant stream of samples, and MCU can throttle USB bus usage by ignoring some triggers.
 
Its much simpler than that.
The PIC just reads in 2048 samples then passes them on to the PC via USB.
If the PC is in roll mode then it just keeps requesting data from the PIC.

The FPGA version gets complicated when you take into consideration trigger modes.
Also the PIC gets a bit complicated by the different sampling speeds.
Its not always required to sample at full speed.
For example 50mS time base takes in samples very slowly.
 
I set about designing a new pcb with all the previous faults rectified.
Better decoupling, crystal close to microcontroller.
Smaller layout.
I started from scratch and "swap autoplaced" all the components to get shortest nets.
scopepcb.png
 
Its much simpler than that.
The PIC just reads in 2048 samples then passes them on to the PC via USB.
If the PC is in roll mode then it just keeps requesting data from the PIC.

The FPGA version gets complicated when you take into consideration trigger modes.
Also the PIC gets a bit complicated by the different sampling speeds.
Its not always required to sample at full speed.
For example 50mS time base takes in samples very slowly.

AFAIK almost all proper reputable brand digital storage oscilloscopes out there on the market use that FPGA-based architecture in some way, be it an FPGA or an ASIC doing the same. Trigger modes are a bit complicated though but noe impossible.

The FPGA and its memory actually decouples the MCU speed from sampling speed, and since you have some memory woo work with sampling can happen at variable speeds using taps of a clock mux.

Another chip you can consider would be a Microsemi SmartFusion 2 series. That chip is an FPGA with a hard Cortex-M3 core in it, allowing even faster ADC to MCU data transfer as the ADC interface in FPGA can use bus mastering to write MCU memory directly. Couple that with something like 64MB of SDRAM as sample buffer and you have one of the easiest to use DSO base platforms behind Xilinx Zynq. (And the Rigol DS1000Z series DSO used exactly that Zynq stack.)
 
Last edited:
I finished off building up the new pcb so I could test all the functions.
99% works ok.
With 18.5 MHZ sampling I am left with too slow op amps. While there MHz is good their slew rate isn't. Got a couple coming from RS Components today so will see how much better they are.

I reworked the pcb to the latest mods. I got a quote for 5 off pcb's but its silly money as they need to fit SMD for me. So probably wont progress that.

I decided to take a step back and go back to a slightly slower cheaper through hole PIC. I can probably manage to solder the SMD A2D myself so that will save a lot of money.
 
Nice work. Thanks for the update. Keep them coming.

This latest scope was designed to be fast but cheaper.
My previous version used a £10 microcontroller with a £5 A2D converter.
For the cheaper one I still use same A2d but only a £2 microcontroller.
I also found a much cheaper fast op amp for the front end.
The previous TLV2375 was about £3, the new one a Texas TL974 £1 op amp.
 
Been testing out latest scope.
Worked ok to start with then had problems with noise.
Depending on how fast it was running affected the noise.
I found in the end changing the PIC speed got rid of the noise.
There must be an interference frequency between the PIC PWM clock and the A2D clock.
I found moving PIC clock frequency from 48MHz to 50MHz got rid of the noise.
Works well now at all speeds and voltages.
 
I revisited one of my earlier USB scope projects tonight.
It is a 2MHz sampling scope.
I compared it to my latest 18MHZ sampling scope in regards to software.
I noticed my faster scope disables interrupts to speed it up a little.
So I tried it with the 2MHZ version and suddenly it was twice as fast !
I missed that one !
It now runs at 4.4MHZ sampling and the screen is rock solid whereas before there was a little jitter on the display.
Apparently Microchip in their wisdom run a timer interrupt in the background which slowed down my software.
 
On my third 16.5MHz sampling pcb now.
Getting the knack with the 0.65mm pitch SMD A2D converter.
Put plenty of paste flux underneath the part and it holds it in place while I dab a little solder near the pins. The solder runs up to the pins and holds the device in place without touching it and moving it with the soldering iron.
Had a little noise problem on my last pcb but it turned out to be earth noise as I forgot to earth my sig gen lead.
 
Been revisiting old projects again.
I went back to a 1 mega sample USB scope.
The code looked really tight with little room for improvement.
Just out of interest I read through the PIC32MX datasheet again in regards to onboard A2D. I spotted a flag in one the A2D registers for automatic sampling. Instead of the software setting the A2D sample bit it is done automatically.
So I tried it and was gobsmacked to find I was suddenly getting 4 mega samples per second. Another day and a little older and wiser.