Go Down

Topic: New oscilloscope for arduino (linux-only for now) (Read 5 times) previous topic - next topic

Alvaro

Hi :)

I started a new oscilloscope project for arduino. The UI frontend only runs in GTK for now, and it's quite poor.



Features:

* Fast sampling rate, using self-triggered ADC. It's independent of serial baud rate.
* Trigger support (inside arduino), with holdoff and auto-trigger. More to come.
* Fully configurable through the UI (in progress).

For those starting with arduino, code implements some "paradigms":
* Finite-state machines
* Packet-oriented serial communication, with error detection.

You can get code here:

http://github.com/alvieboy/arduino-oscope/

You will need gtk+2 and cairo to build UI successfully.

Awaiting your feedback :)

Álvaro

selfonlypath

Hi Alvaro,

What arduino board are you using ?
Can you explain self-trigger ADC ?
What is max sampling speed and how many quatize bits precision do you get ?

Alvaro

Hi there :)
Quote
What arduino board are you using ?

Duemilenove.

Quote
Can you explain self-trigger ADC ?

Sure. ATMEGA328 ADC can trigger interrupts when a conversion ends, and can route this end-of-conversion interrupt signal (ADIF) to trigger start of conversion. This is so-called the Free Running Mode. So, whenever a conversion ends, another conversion starts. I call it "self-trigger" because it triggers  based on its own output signal.

Quote
What is max sampling speed and how many quatize bits precision do you get ?

Max sampling speed is maximum ADC sampling speed in Free Running Mode - which is 13 ADC clock cycles + 1 for the self-trigger. If you use the max. prescaler (128) you get an ADC clock speed of 125KHz. This makes about 9Ksamples/second. Doubles whenever you divide the prescaler by two (meaning a prescaler of 64 will give you almost 18ksamples/s). See page 254 of ATMEGA datasheet for more details.

The current resolution is 8-bit, but can easily be increased to 10-bit, if needed.

Álvaro

selfonlypath

#3
Oct 31, 2009, 04:55 am Last Edit: Oct 31, 2009, 04:56 am by selfonlypath Reason: 1
Quote
Max sampling speed is maximum ADC sampling speed in Free Running Mode - which is 13 ADC clock cycles + 1 for the self-trigger. If you use the max. prescaler (128) you get an ADC clock speed of 125KHz. This makes about 9Ksamples/second. Doubles whenever you divide the prescaler by two (meaning a prescaler of 64 will give you almost 18ksamples/s). See page 254 of ATMEGA datasheet for more details.

The current resolution is 8-bit, but can easily be increased to 10-bit, if needed.

What is max ADC clock speed can I set on arduino boards in Free Running-mode and what would be then the associated bit resolution ?

What is best method to download then display the fastest sampled stream to a Macintosh with either a duamilanove board or mega board which i'm using in my projects ?



Udo Klein

Great!

Do you plan to make support multiple channels as well?
Check out my experiments http://blog.blinkenlight.net

Alvaro

Quote
Do you plan to make support multiple channels as well?
Quote


Yes, either interpolating (sample A,B,A,B...) or framed (trigger A, sample 512A, trigger again A, sample 512B). The former scenario is more accurate, but only gives half sample rate, latter has full sample rate but might not work well if your two channels are of different frequencies.

Álvaro

bruceKG

Alvaro -

This is really a good design.  It avoids the timing problems of using a serial packet to trigger the acquisition.  The FTDI USB/Serial driver has issues with buffering on the chip side (384 bytes), the driver side (64-4K bytes) and when the buffers are flushed to the application ( 1 msec polled).

Could you describe the serial protocol a little bit more ?  So I can try to interface your Arduino code with a PC Processing oscope program.

Keep up the good work !!

Alvaro

Quote
This is really a good design.  It avoids the timing problems of using a serial packet to trigger the acquisition.  The FTDI USB/Serial driver has issues with buffering on the chip side (384 bytes), the driver side (64-4K bytes) and when the buffers are flushed to the application ( 1 msec polled).

Could you describe the serial protocol a little bit more ?  So I can try to interface your Arduino code with a PC Processing oscope program.


Lemme try:

[font=Courier]--- Serial protocol definition for arduino-oscope --

Arduino and display device (PC) communicate over a serial link, using a
simple packet-oriented protocol. The protocol is the same for both
directions.

Packet description:


+--------------+----------+---------------------+----------+
| Payload Size | Command  | Payload             | Checksum |
|  (2 bytes)   | (1 byte) | (0 to payload size) |  1 byte  |
+--------------+----------+---------------------+----------+

* Payload size
  - Size of payload, in big-endian. Can be zero for simple commands (i.e.,
    no payload at all)

* Command
  - Command or reply. 1 byte long. See list below for supported commands.

* Payload
  - Variable size payload for this packet. Size is depicted by Payload
    Size. If Payload Size is zero, this field is not present in packet.
   
* Checksum
  - Packet checksum, using XOR with 0 as start value. To compute checksum
    for an outgoing packet, XOR all values of the packet except for the
    checksum itself. To validate checksum of a packet, XOR all bytes
    received including checksum. If result is zero, then packet has no
    errors.
 
Packets received by arduino have a size limit, due to memory size constraints.
Any packet received with size greater than this limit is ignored.

Supported commands (version 1.2):

 * COMMAND_PING           0x3E
   > Payload size: variable
   
     Request a ping from arduino. Arduino will reply with COMMAND_PONG and
     same payload.
 
 * COMMAND_GET_VERSION    0x40
   > Payload size: 0
   
     Request arduino oscope version. Arduino will reply with
     COMMAND_VERSION_REPLY.
     
 * COMMAND_START_SAMPLING 0x41
   > Payload size: 0
   
     Request arduino to start sampling. Arduino will reply with
     COMMAND_BUFFER_SEG once sampling is done.
     
 * COMMAND_SET_TRIGGER    0x42
   > Payload size: 1
   
     Set trigger level. Payload byte 0 depicts the desired trigger level.
     
 * COMMAND_SET_HOLDOFF    0x43
   > Payload size: 1
   
     Set holdoff value. Payload byte 0 depicts the desired holdoff samples.
   
 * COMMAND_SET_TRIGINVERT 0x44
   > Payload size: 1
   
     Set invert trigger flag. Payload byte 0 depicts if trigger is not
     inverted (a 0 value) or if it is inverted (a 1 value).
     
 * COMMAND_SET_VREF       0x45
   > Payload size: 1
   
     Set VREF source for Arduino. Payload byte 0 defines VREF source value.
     Values can be 0 (AREF), 1 (AVcc) or 3 (Internal 1.1v).
     
 * COMMAND_SET_PRESCALER  0x46
   > Payload size: 1
   
     Set ADC prescaler value. Payload byte 0 defines the log2 of the
     desired prescaler value (7 gives prescaler of 128, 6 prescaler of 64,
     and so on). Minimum prescaler value is 2.
     
 * COMMAND_GET_PARAMETERS 0x47
   > Payload size: 0
   
     Request configured parameters from arduino oscope. Arduino will reply
     with COMMAND_PARAMETERS_REPLY
     
 * COMMAND_VERSION_REPLY  0x80
   > Payload size: 2
   
     Arduino reply with version. Payload byte 0 depicts upper version,
     and byte 1 lower version.
     
 * COMMAND_BUFFER_SEG     0x81
   > Payload size: NUM_SAMPLES
   
     Arduino reply with sampled data. Packet size may vary depending on
     number of samples configured. This data is unsigned 8-bit (higher
     ADC sampled values).
     
 * COMMAND_PARAMETERS_REPLY 0x87
   > Payload size: 6
   
     Current configured values. Payload will contain the following values
     at byte offset:
     
       0 - Trigger level
       1 - Holdoff samples
       2 - ADC reference
       3 - ACD prescaler
       4,5 - Number of samples (NUM_SAMPLES). Big-endian.
       
 * COMMAND_PONG           0xE3
   > Payload size: variable
   
     Arduino reply to PING command. Payload is the same as ping request.
     
 * COMMAND_ERROR          0xFF
   > Payload size: 0
   
     Arduino reply to some unknown command.
[/font]

Álvaro

Alvaro

Hi,

I've changed some parameters, like number of samples (which was increased to 962, so we can have a much nicer timebase).

To test the timebase, I added a simple grid to the scope, and a time indicator. I then connected the arduino to a signal generator, with a 1KHz sinewave output. Here are the results for different prescales, and zoom:

Prescaler 128, no zoom:


Prescaler 64, no zoom:


Prescaler 32,  zoom 2x:


Prescaler 32,  zoom 10x:


Hope you enjoy it.

Questions ?

Álvaro

bruceKG

That's an excellent interface definition. Looks like you are defining an "Arduino/PC Interface Standard".  Do you have a standards review process in mind ?

The packet structure is concise and could be used for many things.  How about a src/dest field so that a UI could combine data from several independent sources ?  Like multiple boards on different USB/Serial channels.

Why big-endian ?  Seems like Serial.write(0xDEAD) is little-endian with AD byte sent first followed by DE. Are the AVR 32-bit  or ARM processors big-endian?


Alvaro

Quote
That's an excellent interface definition. Looks like you are defining an "Arduino/PC Interface Standard".  Do you have a standards review process in mind ?

Not actually. But yes, this might be useful for other projects, but I'll have to rethink some smaller parts (like start checksum and maybe reduce size field).

Quote
The packet structure is concise and could be used for many things.  How about a src/dest field so that a UI could combine data from several independent sources ?  Like multiple boards on different USB/Serial channels.

That would only make sense if you were to use a shared transmission medium. Serial links like these one are point to point, so there is no much point on doing that.

Quote
Why big-endian ?  Seems like Serial.write(0xDEAD) is little-endian with AD byte sent first followed by DE. Are the AVR 32-bit  or ARM processors big-endian?

I have actually not tried Serial.write() with larger values than 8 bits. But yes, AVR32 is big-endian, and ARM is bi-endian.

TCP/IP also uses big-endian byte order, so that made more sense to me.

Álvaro

Alvaro

Quote
What is max ADC clock speed can I set on arduino boards in Free Running-mode and what would be then the associated bit resolution ?

For ATMEGA328, you need up to 200KHz to get full 10 bit resolution. Higher frequencies only give you 8-bit resolution (no mention about max frequency however). At much higher frequencies we must make sure ADC is still slower converting that we processing the ISR.

Quote
What is best method to download then display the fastest sampled stream to a Macintosh with either a duamilanove board or mega board which i'm using in my projects ?

See my post about the protocol I'm using. You don't actually need a faster serial link for this. If you do however need to sample constantly (and that is not what a scope does) you will need some other sort of protocol, maybe with compression, or use a parallel port.

Álvaro

selfonlypath

#12
Nov 01, 2009, 09:54 am Last Edit: Nov 01, 2009, 10:30 am by selfonlypath Reason: 1
hey Alvaro, the way I understand your project but i could be wrong:
- free Running-mode ADC totally independent of the way you'll transfer the samples to a computer via USB
- a specific arduino sketch to capture the ADC samples via ISR management so the samples are stored inside arduino local memory
- a special fast transfer protocol to send samples from local arduino memory to a computer via USB
- miror protocol on the computer able to decode protocol then display nicely on the screen a scope like
so there are 4 distincts modules.

I was asking you about high sampling frequency because my project involves tuning non-linear parametric oscillators via arduino control so I need to have a scope view of a phenomae which is periodic. This means I can have have low ADC resolution and high frequency time synchronize many captures then average mean the samples to increase bits precision by software. Please note this would not be feasible if the visualize scope signal is non-peridoic or rapidly changing shape through short time.

Not easy to explain by mail plus i'm not englihs native. I'm using my arduino as special frequency generator to control different PWM outputs connected to mosfet-drivers and other electro-magnetci components,.... On the other hand, i wish to scope monitor specific voltages from my electro-magnetic oscilator device to perform parametric tuning. This means but i don't know if it is feasible: I need to trigger the free-running ADC on the same phase of my oscillator so then, I can integrate in phase & get more scope sample definition.



Alvaro

Quote
- free Running-mode ADC totally independent of the way you'll transfer the samples to a computer via USB

True

Quote
- a specific arduino sketch to capture the ADC samples via ISR management so the samples are stored inside arduino local memory

True. the ISR also performs trigger and holdoff.
Quote
a special fast transfer protocol to send samples from local arduino memory to a computer via USB

Fast and safe.
Quote
miror protocol on the computer able to decode protocol then display nicely on the screen a scope like

Yes, protocol is implemented in both Arduino and PC. Code is actually similar.

Quote
I was asking you about high sampling frequency because my project involves tuning non-linear parametric oscillators via arduino control so I need to have a scope view of a phenomae which is periodic. This means I can have have low ADC resolution and high frequency time synchronize many captures then average mean the samples to increase bits precision by software. Please note this would not be feasible if the visualize scope signal is non-peridoic or rapidly changing shape through short time.

I wonder if undersampling might help here (see http://en.wikipedia.org/wiki/Undersampling.

Quote
Not easy to explain by mail plus i'm not englihs native. I'm using my arduino as special frequency generator to control different PWM outputs connected to mosfet-drivers and other electro-magnetci components,.... On the other hand, i wish to scope monitor specific voltages from my electro-magnetic oscilator device to perform parametric tuning. This means but i don't know if it is feasible: I need to trigger the free-running ADC on the same phase of my oscillator so then, I can integrate in phase & get more scope sample definition.

You can trigger sampling start based on any pin, or you can use the analog comparator for this.

I actually designed this so I can take a look at back-EMF from a motor, driven by two or three half-bridges. I'll let you know my progress.

Álvaro


selfonlypath

Quote
You can trigger sampling start based on any pin, or you can use the analog comparator for this.

What i'm looking is to arduino internally trigger since my arduino is the frequency generator & the ADC capturer. By software, i know exactly when i'll hit a new period of my generated signal so I would need the ADC to capture N samples from that specific moment.

Quote
I actually designed this so I can take a look at back-EMF from a motor, driven by two or three half-bridges. I'll let you know my progress.

Great, my projects involve special management & joule stealing from BMEF spikes.

Is there any chance you can compile your computer code so it can be run on my Macintosh ?


Go Up