author
4Instructables126,068Views51CommentsJoined July 4th, 2014

Tell us about yourself!

Complete Your Profile

Achievements

10K+ Views Earned a bronze medal
  • Arduino High Speed Oscilloscope With PC Interface

    My recent project is a 20MHz external ADC which was inspired by an article by Bob Davis ( http://bobdavis321.blogspot.co.uk/2013/06/arduino-powered-10-million-samples-per.html )I use the TLC5510A chip to sample the data and an asynchronous fifo to get the data off the TLC at the ADC clock rate. When the fifo flags full, I can read the data at Arduino speed and output to my PC oscilloscope application.The triggering is very stable- I capture 2K of data and use the mega to establish the trig point in the data array. Starting at the trig point, I then upload 1000 data bytes to the PC.

    My recent project is a 20MHz external ADC which was inspired by an article by Bob Davis ( http://bobdavis321.blogspot.co.uk/2013/06/arduino-powered-10-million-samples-per.html )I use the TLC5510A chip to sample the data and an asynchronous fifo to get the data off the TLC at the ADC clock rate. When the fifo flags full, I can read the data at Arduino speed and output to my PC oscilloscope application.The triggering is very stable- I capture 2K of data and use the mega to establish the trig point in the data array. Starting at the trig point, I then upload 1000 data bytes to the PC.

    View Instructable »
  • Arduino High Speed Oscilloscope With PC Interface

    Working example detailed in response dated 2017-08-24.Tested on a mega.David

    Hi,I am happy to respond to questions regarding the article.Without intending to cause offence I must point out that I am not a free software writing service.David

    View Instructable »
  • Arduino High Speed Oscilloscope With PC Interface

    Hi,I presume you are using a mega or 3rd party mega?1) cli() should follow serial.begin2) the isr service subroutine is not required3) use a prescalar of 4: ADCSRA |= (1 << ADPS1); // prescalar 44) get rid of the triggering for initial testing- delete: while (!triggered) { // wait for adc conversion while ((ADCSRA & check) == check); newval = ADCH; // New conversion ADCSRA = startit; trip = newval - oldval; if (!trigplus) trip = -trip; if (trip > trigger) triggered = true; else oldval = newval; }5) As you disable the adc in the main loop at the end- you need to enable it at the beginning- mysbi(ADCSRA, ADEN); // enable ADCHave you had a look at my software link in the reply to Pacman333 2016-04-11 ?This operates with a Sainsmart 3.2" lcd for...

    see more »

    Hi,I presume you are using a mega or 3rd party mega?1) cli() should follow serial.begin2) the isr service subroutine is not required3) use a prescalar of 4: ADCSRA |= (1 << ADPS1); // prescalar 44) get rid of the triggering for initial testing- delete: while (!triggered) { // wait for adc conversion while ((ADCSRA & check) == check); newval = ADCH; // New conversion ADCSRA = startit; trip = newval - oldval; if (!trigplus) trip = -trip; if (trip > trigger) triggered = true; else oldval = newval; }5) As you disable the adc in the main loop at the end- you need to enable it at the beginning- mysbi(ADCSRA, ADEN); // enable ADCHave you had a look at my software link in the reply to Pacman333 2016-04-11 ?This operates with a Sainsmart 3.2" lcd for display and a potentiometer to set the trig level.Cheers,David

    This test program runs at 239.234Khz on a mega:Note- pin 10 is configured to produce a pwm square wave for testing..// Defines for setting register bits#ifndef mysbi#define mysbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))#endif#ifndef mycbi#define mycbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))#endifconst byte testpin = 10;// connect pin10 to analogue 0 for testing// defines for pwm output on testpin (pin 10 specific on mega!)#ifndef fastpwm#define fastpwm (TCCR2B = (TCCR2B & B11111000) | B00000010)#endif#ifndef slowpwm#define slowpwm (TCCR2B = (TCCR2B & B11111000) | B00000100)#endif#define BUF_SIZE 1000uint8_t bufa[BUF_SIZE];const byte check = 1<<ADSC;boolean writeit, startit;float elapsed;byte adport = 0;void setup(){Serial.begin(115200);Serial.println("ADC test"...

    see more »

    This test program runs at 239.234Khz on a mega:Note- pin 10 is configured to produce a pwm square wave for testing..// Defines for setting register bits#ifndef mysbi#define mysbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))#endif#ifndef mycbi#define mycbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))#endifconst byte testpin = 10;// connect pin10 to analogue 0 for testing// defines for pwm output on testpin (pin 10 specific on mega!)#ifndef fastpwm#define fastpwm (TCCR2B = (TCCR2B & B11111000) | B00000010)#endif#ifndef slowpwm#define slowpwm (TCCR2B = (TCCR2B & B11111000) | B00000100)#endif#define BUF_SIZE 1000uint8_t bufa[BUF_SIZE];const byte check = 1<<ADSC;boolean writeit, startit;float elapsed;byte adport = 0;void setup(){Serial.begin(115200);Serial.println("ADC test");cli(); // disable interruptsADCSRA = 0; // clear ADCSRA registerADCSRB = 0; // free running - only has effect if ADATE in ADCSRA=1ADMUX |= adport; //set up continuous sampling of analog pin adportADMUX |= (1 << REFS0); // set reference voltage to VccADMUX |= (1 << ADLAR); // left align the ADC value- so we can read highest 8 bits from ADCH register onlyADCSRA |= (1 << ADPS1); // prescalar 4sei(); // enable interrupts// option to start pwm wave on port 10:fastpwm;// slowpwm;analogWrite(testpin, 127);writeit = false;startit = true;}void loop(){float frequency; if (startit) startad(); if (writeit) { for(unsigned int i = 0; i < BUF_SIZE; i++){ Serial.print(i); Serial.print(" "); Serial.println(bufa[i]); } frequency = 1000 *(BUF_SIZE / elapsed); Serial.print("\nElapsed time = "); Serial.print (elapsed); Serial.print("uS Frequency "); Serial.print(frequency,3); Serial.println("KHz"); writeit = false; startit = true; delay(2000); }}/* Fast read via registerscf pages 242-260 of ATmega328P manual"A single conversion is started by writing logical 1 tothe ADC Start conversion bit ADSC. This bit stays highas long as the conversion is in progress and will be clearedby hardware when the conversion is completed.">= 237.2 KHz !!!!!*/void startad(){unsigned long starttime, endtime;startit = false;cli(); // disable interruptsmysbi(ADCSRA,ADEN); // enable ADCsei(); // enable interrupts// First conversion- initialises ADCmysbi(ADCSRA,ADSC); while((ADCSRA & check)== check); // wait for ADSC byte to go low// New conversion and use current ADCSRA value for triggerbyte startit = ADCSRA | check;ADCSRA = startit;starttime = micros(); for (unsigned int i = 0; i < BUF_SIZE; i++){ // wait for conversion while((ADCSRA & check)== check); bufa[i] = ADCH; // New conversion ADCSRA = startit; }endtime = micros();cli();mycbi(ADCSRA,ADEN); // disable ADCsei();elapsed = endtime - starttime;writeit = true;}

    View Instructable »
  • Arduino High Speed Oscilloscope With PC Interface

    Hi,I am not aware of a TLV571 library and have not released my TLV571 source code to the public. Until I find the time to write an instructable for the TLV571 project I will limit my comments (and support) ....I simply read the chip's output via 8 input lines, forming portA on the mega.The chip was configured to use software start, internal clock and end of conversion line active.To initiate a conversion I used PORTC to switch the necessary lines and polled the eoc line to detect a data ready condition.cs on PC0wr on PC1rd on PC2econ on PC3// code starts here#define BUF_SIZE 1000byte bufa[BUF_SIZE];const byte econ = 8; // PC3 8 end of conversion linevoid setup(){//setup dataline to outputDDRA = B11111111;// control line setup 3 output, 1 input (and rest input for safety) DDRC = B0000011...

    see more »

    Hi,I am not aware of a TLV571 library and have not released my TLV571 source code to the public. Until I find the time to write an instructable for the TLV571 project I will limit my comments (and support) ....I simply read the chip's output via 8 input lines, forming portA on the mega.The chip was configured to use software start, internal clock and end of conversion line active.To initiate a conversion I used PORTC to switch the necessary lines and polled the eoc line to detect a data ready condition.cs on PC0wr on PC1rd on PC2econ on PC3// code starts here#define BUF_SIZE 1000byte bufa[BUF_SIZE];const byte econ = 8; // PC3 8 end of conversion linevoid setup(){//setup dataline to outputDDRA = B11111111;// control line setup 3 output, 1 input (and rest input for safety) DDRC = B00000111;// Set the 3 output handshake lines highPORTC = B00000111;delay(1);// Configure the TLV571// write cr1 1st to ensure values are set before software control starts// INT OSC FAST,BINARYbyte cr1 = B01010000;PORTA = cr1;Serial.print(F("CR1 "));writecycle();// SOFTWARE START, EOC INTERNAL CLOCK, NORMALbyte cr0 = B00110000;PORTA = cr0;Serial.print(F("CR0 "));writecycle();// set data lines to inputDDRA = B00000000;delay(1);}void loop(){byte delayer;unsigned long starttime, endtime;starttime = micros(); for (int il = 0; il < BUF_SIZE; il ++) { sei(); delayMicroseconds(delayer); // only use if full rate not required! cli(); PORTC = B00000010; // RD low, WR high, CS low PORTC = B00000110; // RD high, WR high, CS low while ((PINC & econ) == 0 ); // wait for econ to go high bufa[il] = PINA; }endtime = micros();sei(); }// do something with data}void writecycle() {cli();PORTC = B00000110; // read high, WR high, CS low__asm__("nop\n\t"); // wait one machine cycle (at 16 MHz) // yielding a 62.5 ns (nanosecond) delayPORTC = B00000100; // read high, WR low, CS low__asm__("nop\n\t");PORTC = B00000110; // read high, WR high, CS low - transfer data__asm__("nop\n\t"); while ((PINC & econ) == 0 ); // wait for econ to go highsei();Serial.print(PORTA, BIN);Serial.println(F(" write OK"));Serial.flush();}Good luck!David

    View Instructable »
  • Arduino High Speed Oscilloscope With PC Interface

    Hi,using analogRead is a non starter for high frequency sampling.You need to read the whole article and then focus on my reponse..to albert8855 dated 2015-09-20Using 300 data values at 200Khz = 300*1/200000= 0.0015SSo a sample period of 1.5mS..You need more data points to capture a meaningful section of the input wave structure.1000 data points gives 5ms sample period David

    View Instructable »
  • Arduino High Speed Oscilloscope With PC Interface

    Hi,The uno has less memory: Flash Memory: 32 KB of which 0.5 KB used by bootloader SRAM: 2 KB (ATmega328) EEPROM: 1 KB (ATmega328)Mega: Flash Memory 256 KB of which 8 KB used by bootloader SRAM 8 KB EEPROM 4 KBAs a result I have always used mega's for storage hungry applications (and do not have a single uno)You might want to look at some of the 3rd party mega boards- they are often cheaper than a uno!Regards,David

    View Instructable »
  • Arduino High speed Oscilloscope with PC interface

    Hi JurisP1,my 238KHz code is the fastest internal ADC version I have written. It uses a mega and a colour touch screen display by sain.I have written code to run at 1.2 MHz. using the parallel interface on the ADC TLV571 chip.As a starting point, the code and details in this instructable work well.Regards,David

    View Instructable »
  • Arduino High speed Oscilloscope with PC interface

    Following limited interest I have placed a copy of my 238Khz oscilloscope software at:http://www.davepatterson.me.uk/public/Oscilloscope...The code has adequate annotation. I offer it without support.The required hardware:Arduino mega 2560Sainsmart 3.2 inch lcd and shield: $24.99 http://www.sainsmart.com/sainsmart-3-2-tft-lcd-di...A sd card to fit the sainsmart shield (less than 2GB)A good quality potentiometer between 5V and ground with the wiper to analogue 4. Any value that will not pull a large current. (This sets the trig level)Any signal conditioning circuit of your choice- connected to analogue 0.David

    Following limited interest I have placed a copy of my 238Khz oscilloscope software at:http://www.davepatterson.me.uk/public/Oscilloscope...The code has adequate annotation. I offer it without support.The required hardware:Arduino mega 2560Sainsmart 3.2 inch lcd and shield: $24.99 http://www.sainsmart.com/sainsmart-3-2-tft-lcd-di...A sd card to fit the sainsmart shield (less than 2GB)A good quality potentiometer between 5V and ground with the wiper to analogue 4. Any value that will not pull a large current. (This sets the trig level)Any signal conditioning circuit of your choice- connected to analogue 0David

    Following limited interest I have placed a copy of my 238Khz oscilloscope software at:http://www.davepatterson.me.uk/public/Oscilloscope...The code has adequate annotation. I offer it without support.The required hardware:Arduino mega 3560Sainsmart 3.2 inch lcd and shield: $24.99 http://www.sainsmart.com/sainsmart-3-2-tft-lcd-di...A sd card to fit the sainsmart shield (less than 2GB)A good quality potentiometer between 5V and ground with the wiper to analogue 4. Any value that will not pull a large current. (This sets the trig level)Any signal conditioning circuit of your choice- connected to analogue 0David

    View Instructable »