Thursday, June 27, 2013

Arduino powered 5 Million samples per second oscope with CA3306

This Arduino powered 5 Million samples per second oscilloscope uses an external CA3306 analog to digital converter.  the Ca3306 produces less glitches than the AD775 did.  Here is the video on YouTube. http://youtu.be/f_RD1oQuKiw   I fixed the memory issue and even sped it up some more by changing the array from 320 integers to 240 bytes.  Integers are 16 bits long and bytes are 8 bits long, so it is much faster and uses less memory. 

I also added a trigger and speed selection switch on D12 and D13 to ground.  The speed selection has 10 modes.  They range from no loop, to a loop with no delay, to eight available delay settings.

Here is a picture of the screen of the oscilloscope running in its fastest mode.


Here is a picture of the CA3306 wiring, it is much easier than the other Analog to digital converter was.


Here is the CA3306 schematic diagram;
Here is a oscilloscope like input section schematic.  I used two 9 volt batteries to test it out.  It give the ability to handle inputs of up to 50 volts and also allows gain selection. It is a much simpler design than the input section that was in my book "Digital and Computer projects".

Here is the code.  It uses two push buttons, one on D12 and one on D13 to select the sample rate and the trigger level.  To be honest the trigger does not work very well yet.
 
//****************************************
// Three color 5msps ext AtoD Scope
// By Bob Davis
// UTFT_(C)2012 Henning Karlsen
// web: http://www.henningkarlsen.com/electronics
//
// Switches on D12 & D13 determine sweep speed and trigger level
//*******************************************

#include 
// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];

// Note that the control pins are now assigned to 8-11
UTFT myGLCD(ILI9325C,8,9,10,11);  
int Input=0;
byte Sample[320];
byte OldSample[320];
int StartSample=0;
int EndSample=0;
int MaxSample=0;
int MinSample=0;
int mode=0;
int dTime=1;
int Trigger=10;
int SampleSize=0;
int SampleTime=0;

void DrawMarkers(){
  myGLCD.setColor(0, 220, 0);
  myGLCD.drawLine(0, 0, 0, 240);
  myGLCD.drawLine(60, 0, 60, 240);
  myGLCD.drawLine(120, 0, 120, 240);
  myGLCD.drawLine(180, 0, 180, 240);
  myGLCD.drawLine(239, 0, 239, 240);
  myGLCD.drawLine(319, 0, 319, 240);
  myGLCD.drawLine(0, 0, 319, 0);
  myGLCD.drawLine(0, 60, 319, 60);
  myGLCD.drawLine(0, 120, 319, 120);
  myGLCD.drawLine(0, 180, 319, 180);
  myGLCD.drawLine(0, 239, 319, 239);
}

void setup() {
  myGLCD.InitLCD();
  myGLCD.clrScr();
  pinMode(12, INPUT);
  digitalWrite(12, HIGH);
  pinMode(13, INPUT);
  digitalWrite(13, HIGH);
  pinMode(14, INPUT);
  pinMode(15, INPUT);
  pinMode(16, INPUT);
  pinMode(17, INPUT);
  pinMode(18, INPUT);
  pinMode(19, INPUT);
}

void loop() {
// Set the background color(Red, Green, Blue) 
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(BigFont);
  char buf[12]; 
  while(1) {
    DrawMarkers();
    if (digitalRead(13) == 0) mode++;
    if (mode > 10) mode=0;
// Select delay times for scan modes
    if (mode == 0) dTime=0;
    if (mode == 1) dTime=0;
    if (mode == 2) dTime=1;
    if (mode == 3) dTime=2;
    if (mode == 4) dTime=5;
    if (mode == 5) dTime=10;
    if (mode == 6) dTime=20;
    if (mode == 7) dTime=50;
    if (mode == 8) dTime=100;
    if (mode == 9) dTime=200;
    if (mode == 10) dTime=500;
// Select trigger level
    if (digitalRead(12) == 0) Trigger=Trigger+10;
    if (Trigger > 50) Trigger=0;
// Wait for input to be greater than trigger
  while (Input < Trigger){
    Input = PINC;
    }

// Collect the analog data into an array
  if (mode == 0) {
// Read analog port as a parallel port no loop
  StartSample = micros();
    Sample[0]=PINC;
    Sample[1]=PINC;     Sample[2]=PINC;    Sample[3]=PINC;    
    Sample[4]=PINC;     Sample[5]=PINC;    Sample[6]=PINC;
    Sample[7]=PINC;     Sample[8]=PINC;    Sample[9]=PINC;
    Sample[10]=PINC;    Sample[11]=PINC;    Sample[12]=PINC;
    Sample[13]=PINC;    Sample[14]=PINC;    Sample[15]=PINC;
    Sample[16]=PINC;    Sample[17]=PINC;    Sample[18]=PINC;
    Sample[19]=PINC;    Sample[20]=PINC;    Sample[21]=PINC;
    Sample[22]=PINC;    Sample[23]=PINC;    Sample[24]=PINC;
    Sample[25]=PINC;    Sample[26]=PINC;    Sample[27]=PINC;
    Sample[28]=PINC;    Sample[29]=PINC;    Sample[30]=PINC;
    Sample[31]=PINC;    Sample[32]=PINC;    Sample[33]=PINC;
    Sample[34]=PINC;    Sample[35]=PINC;    Sample[36]=PINC;
    Sample[37]=PINC;    Sample[38]=PINC;    Sample[39]=PINC;
    Sample[40]=PINC;    Sample[41]=PINC;    Sample[42]=PINC;
    Sample[43]=PINC;    Sample[44]=PINC;    Sample[45]=PINC;
    Sample[46]=PINC;    Sample[47]=PINC;    Sample[48]=PINC;
    Sample[49]=PINC;    Sample[50]=PINC;    Sample[51]=PINC;
    Sample[52]=PINC;    Sample[53]=PINC;    Sample[54]=PINC;
    Sample[55]=PINC;    Sample[56]=PINC;    Sample[57]=PINC;
    Sample[58]=PINC;    Sample[59]=PINC;    Sample[60]=PINC;
    Sample[61]=PINC;    Sample[62]=PINC;    Sample[63]=PINC;
    Sample[64]=PINC;    Sample[65]=PINC;    Sample[66]=PINC;
    Sample[67]=PINC;    Sample[68]=PINC;    Sample[69]=PINC;
    Sample[70]=PINC;    Sample[71]=PINC;    Sample[72]=PINC;
    Sample[73]=PINC;    Sample[74]=PINC;    Sample[75]=PINC;
    Sample[76]=PINC;    Sample[77]=PINC;    Sample[78]=PINC;
    Sample[79]=PINC;    Sample[80]=PINC;    Sample[81]=PINC;
    Sample[82]=PINC;    Sample[83]=PINC;    Sample[84]=PINC;
    Sample[85]=PINC;    Sample[86]=PINC;    Sample[87]=PINC;
    Sample[88]=PINC;    Sample[89]=PINC;    Sample[90]=PINC;
    Sample[91]=PINC;    Sample[92]=PINC;    Sample[93]=PINC;
    Sample[94]=PINC;    Sample[95]=PINC;    Sample[96]=PINC;
    Sample[97]=PINC;    Sample[98]=PINC;    Sample[99]=PINC;
    Sample[100]=PINC;    Sample[101]=PINC;    Sample[102]=PINC;
    Sample[103]=PINC;    Sample[104]=PINC;    Sample[105]=PINC;
    Sample[106]=PINC;    Sample[107]=PINC;    Sample[108]=PINC;
    Sample[109]=PINC;    Sample[110]=PINC;    Sample[111]=PINC;
    Sample[112]=PINC;    Sample[113]=PINC;    Sample[114]=PINC;
    Sample[115]=PINC;    Sample[116]=PINC;    Sample[117]=PINC;
    Sample[118]=PINC;    Sample[119]=PINC;    Sample[120]=PINC;
    Sample[121]=PINC;    Sample[122]=PINC;    Sample[123]=PINC;
    Sample[124]=PINC;    Sample[125]=PINC;    Sample[126]=PINC;
    Sample[127]=PINC;    Sample[128]=PINC;    Sample[129]=PINC;
    Sample[130]=PINC;    Sample[131]=PINC;    Sample[132]=PINC;
    Sample[133]=PINC;    Sample[134]=PINC;    Sample[135]=PINC;
    Sample[136]=PINC;    Sample[137]=PINC;    Sample[138]=PINC;
    Sample[139]=PINC;    Sample[140]=PINC;    Sample[141]=PINC;
    Sample[142]=PINC;    Sample[143]=PINC;    Sample[144]=PINC;
    Sample[145]=PINC;    Sample[146]=PINC;    Sample[147]=PINC;
    Sample[148]=PINC;    Sample[149]=PINC;    Sample[150]=PINC;
    Sample[151]=PINC;    Sample[152]=PINC;    Sample[153]=PINC;
    Sample[154]=PINC;    Sample[155]=PINC;    Sample[156]=PINC;
    Sample[157]=PINC;    Sample[158]=PINC;    Sample[159]=PINC;
    Sample[160]=PINC;    Sample[161]=PINC;    Sample[162]=PINC;
    Sample[163]=PINC;    Sample[164]=PINC;    Sample[165]=PINC;
    Sample[166]=PINC;    Sample[167]=PINC;    Sample[168]=PINC;
    Sample[169]=PINC;    Sample[170]=PINC;    Sample[171]=PINC;
    Sample[172]=PINC;    Sample[173]=PINC;    Sample[174]=PINC;
    Sample[175]=PINC;    Sample[176]=PINC;    Sample[177]=PINC;
    Sample[178]=PINC;    Sample[179]=PINC;    Sample[180]=PINC;
    Sample[181]=PINC;    Sample[182]=PINC;    Sample[183]=PINC;
    Sample[184]=PINC;    Sample[185]=PINC;    Sample[186]=PINC;
    Sample[187]=PINC;    Sample[188]=PINC;    Sample[189]=PINC;
    Sample[190]=PINC;    Sample[191]=PINC;    Sample[192]=PINC;
    Sample[193]=PINC;    Sample[194]=PINC;    Sample[195]=PINC;
    Sample[196]=PINC;    Sample[197]=PINC;    Sample[198]=PINC;
    Sample[199]=PINC;    Sample[200]=PINC;    Sample[201]=PINC;
    Sample[202]=PINC;    Sample[203]=PINC;    Sample[204]=PINC;
    Sample[205]=PINC;    Sample[206]=PINC;    Sample[207]=PINC;
    Sample[208]=PINC;    Sample[209]=PINC;    Sample[210]=PINC;
    Sample[211]=PINC;    Sample[212]=PINC;    Sample[213]=PINC;
    Sample[214]=PINC;    Sample[215]=PINC;    Sample[216]=PINC;
    Sample[217]=PINC;    Sample[218]=PINC;    Sample[219]=PINC;    
    Sample[220]=PINC;    Sample[221]=PINC;    Sample[222]=PINC;
    Sample[223]=PINC;    Sample[224]=PINC;    Sample[225]=PINC;
    Sample[226]=PINC;    Sample[227]=PINC;    Sample[228]=PINC;
    Sample[229]=PINC;    Sample[230]=PINC;    Sample[231]=PINC;
    Sample[232]=PINC;    Sample[233]=PINC;    Sample[234]=PINC;
    Sample[235]=PINC;    Sample[236]=PINC;    Sample[237]=PINC;
    Sample[238]=PINC;    Sample[239]=PINC;    Sample[240]=PINC;
  EndSample = micros();
  }
  if (mode == 1) {
// Read analog port as a parallel port no delay
  StartSample = micros();
  for(int xpos=0; xpos<240; xpos++) {
    Sample[xpos]=PINC;
  } 
  EndSample = micros();
  }
  if (mode >= 2) {
// Read analog port as a parallel port variable delay
  StartSample = micros();
  for(int xpos=0; xpos<240; xpos++) {
    Sample[xpos]=PINC;
    delayMicroseconds(dTime);
  } 
  EndSample = micros();
  }

// Display the collected analog data from array
  for(int xpos=0; xpos<239; xpos++) {
// Erase the old stuff
    myGLCD.setColor(0, 0, 0);
    myGLCD.drawLine (xpos+1, 255-OldSample[xpos+1]*4, xpos+2, 255-OldSample[xpos+2]*4);  
    if (xpos==0) myGLCD.drawLine (xpos+1, 1, xpos+1, 239);
// Draw the new data
    myGLCD.setColor(255, 255, 255);
    myGLCD.drawLine (xpos, 255-Sample[xpos]*4, xpos+1, 255-Sample[xpos+1]*4); 
  }  

//  Determine sample voltage peak to peak
  MaxSample = Sample[100];
  MinSample = Sample[100];
  for(int xpos=0; xpos<240; xpos++) {
    OldSample[xpos] = Sample[xpos];  
    if (Sample[xpos] > MaxSample) MaxSample=Sample[xpos];
    if (Sample[xpos] < MinSample) MinSample=Sample[xpos];
    }
// display the sample time, delay time and trigger level  
  myGLCD.setColor(0, 0, 255);
  SampleTime=EndSample-StartSample;
  myGLCD.print("uSec.", 240, 10);
  myGLCD.print("     ", 240, 30);
  myGLCD.print(itoa(SampleTime, buf, 10), 240, 30);
  myGLCD.print("Delay", 240, 70);
  myGLCD.print("     ", 240, 90);
  myGLCD.print(itoa(dTime, buf, 10), 240, 90);
  myGLCD.print("Trig.", 240, 130);
  myGLCD.print(itoa(Trigger, buf, 10), 240, 150);
// Range of 0 to 64 * 78 = 4992 mV
  SampleSize=(MaxSample-MinSample)*78;
  myGLCD.print("mVolt", 240, 190);
  myGLCD.print(itoa(SampleSize, buf, 10), 240, 210);
    } 
}


Arduino Powered 10 Million samples per second Oscilloscope

I have created an Arduino Powered 10 Million samples per second Oscilloscope. It even works at 25 Million samples per second. The secret is using an external Analog to digital converter and a FIFO. Here is the video on YouTube.http://youtu.be/RcepVnXUlJY

Here is the schematic diagram.
Here is a picture of the wiring, it is a little complicated.


There is an optional 74LS10 that prevents writes to the FIFO once it is full.  Otherwise about every 10 scans you will get a lot of garbage.

You could also add two 74LS390 dual divide by 10's and an ten position switch to have a method of selecting the recording frequency.

An op amplifier on the input would also improve the performance.  Then you could select AC/DC coupling, Gain, and divide by 10 for input options.  The position control works better with an op amp too.

Monday, June 24, 2013

Arduino 3 Million samples per second oscilloscope

I have built an Arduino powered 3 million samples per second oscilloscope. The secret to the speed is using an external Analog to Digital Converter.  Here is the video on YouTube; http://youtu.be/fG7trChbg88

This is the schematic of the AD775 Fast analog to digital converter setup;

Here is a picture of the screen.
Here is the code for 3 million samples per second, to get that fast you need to say Sample[1]=PINC a total of 320 times!
//****************************************
// Three color 3MspS ext AtoD Scope
// By Bob Davis
// UTFT_(C)2012 Henning Karlsen
// web: http://www.henningkarlsen.com/electronics
//

#include 

// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];

// Note that control pins are now assigned to 8-11
UTFT myGLCD(ILI9325C,8,9,10,11);  
int Input=0;
int Sample[320];
int StartSTime=0;
int EndSTime=0;
float SampleTime=0;

void DrawMarkers(){
  myGLCD.setColor(0, 200, 0);
  myGLCD.drawLine(0, 0, 0, 240);
  myGLCD.drawLine(54, 0, 54, 240);
  myGLCD.drawLine(107, 0, 107, 240);
  myGLCD.drawLine(160, 0, 160, 240);
  myGLCD.drawLine(213, 0, 213, 240);
  myGLCD.drawLine(266, 0, 266, 240);
  myGLCD.drawLine(319, 0, 319, 240);
  myGLCD.drawLine(0, 0, 319, 0);
  myGLCD.drawLine(0, 50, 319, 50);
  myGLCD.drawLine(0, 100, 319, 100);
  myGLCD.drawLine(0, 150, 319, 150);
  myGLCD.drawLine(0, 200, 319, 200);
  myGLCD.drawLine(0, 239, 319, 239);
}

void setup() {
  myGLCD.InitLCD();
  myGLCD.clrScr();
  pinMode(14, INPUT);
  pinMode(15, INPUT);
  pinMode(16, INPUT);
  pinMode(17, INPUT);
  pinMode(18, INPUT);
  pinMode(19, INPUT);
}

void loop() {
  // set color(Red, Green, Blue) range = 0 to 255
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setFont(BigFont);
  char buf[12]; 
  while(1) {
    DrawMarkers(); 
// wait for trigger of a positive input
  while (Input == 0){
    Input = digitalRead(A1);
    }

// collect the analog data into an array
// Read analog port as a parallel port using PINC
// Code with no loop is about 50% faster!
  StartSTime = micros();
    Sample[0]=PINC;
    Sample[1]=PINC;     Sample[2]=PINC;    Sample[3]=PINC;    
    Sample[4]=PINC;     Sample[5]=PINC;    Sample[6]=PINC;
    Sample[7]=PINC;     Sample[8]=PINC;    Sample[9]=PINC;
    Sample[10]=PINC;    Sample[11]=PINC;    Sample[12]=PINC;
    Sample[13]=PINC;    Sample[14]=PINC;    Sample[15]=PINC;
    Sample[16]=PINC;    Sample[17]=PINC;    Sample[18]=PINC;
    Sample[19]=PINC;    Sample[20]=PINC;    Sample[21]=PINC;
    Sample[22]=PINC;    Sample[23]=PINC;    Sample[24]=PINC;
    Sample[25]=PINC;    Sample[26]=PINC;    Sample[27]=PINC;
    Sample[28]=PINC;    Sample[29]=PINC;    Sample[30]=PINC;
    Sample[31]=PINC;    Sample[32]=PINC;    Sample[33]=PINC;
    Sample[34]=PINC;    Sample[35]=PINC;    Sample[36]=PINC;
    Sample[37]=PINC;    Sample[38]=PINC;    Sample[39]=PINC;
    Sample[40]=PINC;    Sample[41]=PINC;    Sample[42]=PINC;
    Sample[43]=PINC;    Sample[44]=PINC;    Sample[45]=PINC;
    Sample[46]=PINC;    Sample[47]=PINC;    Sample[48]=PINC;
    Sample[49]=PINC;    Sample[50]=PINC;    Sample[51]=PINC;
    Sample[52]=PINC;    Sample[53]=PINC;    Sample[54]=PINC;
    Sample[55]=PINC;    Sample[56]=PINC;    Sample[57]=PINC;
    Sample[58]=PINC;    Sample[59]=PINC;    Sample[60]=PINC;
    Sample[61]=PINC;    Sample[62]=PINC;    Sample[63]=PINC;
    Sample[64]=PINC;    Sample[65]=PINC;    Sample[66]=PINC;
    Sample[67]=PINC;    Sample[68]=PINC;    Sample[69]=PINC;
    Sample[70]=PINC;    Sample[71]=PINC;    Sample[72]=PINC;
    Sample[73]=PINC;    Sample[74]=PINC;    Sample[75]=PINC;
    Sample[76]=PINC;    Sample[77]=PINC;    Sample[78]=PINC;
    Sample[79]=PINC;    Sample[80]=PINC;    Sample[81]=PINC;
    Sample[82]=PINC;    Sample[83]=PINC;    Sample[84]=PINC;
    Sample[85]=PINC;    Sample[86]=PINC;    Sample[87]=PINC;
    Sample[88]=PINC;    Sample[89]=PINC;    Sample[90]=PINC;
    Sample[91]=PINC;    Sample[92]=PINC;    Sample[93]=PINC;
    Sample[94]=PINC;    Sample[95]=PINC;    Sample[96]=PINC;
    Sample[97]=PINC;    Sample[98]=PINC;    Sample[99]=PINC;
    Sample[100]=PINC;    Sample[101]=PINC;    Sample[102]=PINC;
    Sample[103]=PINC;    Sample[104]=PINC;    Sample[105]=PINC;
    Sample[106]=PINC;    Sample[107]=PINC;    Sample[108]=PINC;
    Sample[109]=PINC;    Sample[110]=PINC;    Sample[111]=PINC;
    Sample[112]=PINC;    Sample[113]=PINC;    Sample[114]=PINC;
    Sample[115]=PINC;    Sample[116]=PINC;    Sample[117]=PINC;
    Sample[118]=PINC;    Sample[119]=PINC;    Sample[120]=PINC;
    Sample[121]=PINC;    Sample[122]=PINC;    Sample[123]=PINC;
    Sample[124]=PINC;    Sample[125]=PINC;    Sample[126]=PINC;
    Sample[127]=PINC;    Sample[128]=PINC;    Sample[129]=PINC;
    Sample[130]=PINC;    Sample[131]=PINC;    Sample[132]=PINC;
    Sample[133]=PINC;    Sample[134]=PINC;    Sample[135]=PINC;
    Sample[136]=PINC;    Sample[137]=PINC;    Sample[138]=PINC;
    Sample[139]=PINC;    Sample[140]=PINC;    Sample[141]=PINC;
    Sample[142]=PINC;    Sample[143]=PINC;    Sample[144]=PINC;
    Sample[145]=PINC;    Sample[146]=PINC;    Sample[147]=PINC;
    Sample[148]=PINC;    Sample[149]=PINC;    Sample[150]=PINC;
    Sample[151]=PINC;    Sample[152]=PINC;    Sample[153]=PINC;
    Sample[154]=PINC;    Sample[155]=PINC;    Sample[156]=PINC;
    Sample[157]=PINC;    Sample[158]=PINC;    Sample[159]=PINC;
    Sample[160]=PINC;    Sample[161]=PINC;    Sample[162]=PINC;
    Sample[163]=PINC;    Sample[164]=PINC;    Sample[165]=PINC;
    Sample[166]=PINC;    Sample[167]=PINC;    Sample[168]=PINC;
    Sample[169]=PINC;    Sample[170]=PINC;    Sample[171]=PINC;
    Sample[172]=PINC;    Sample[173]=PINC;    Sample[174]=PINC;
    Sample[175]=PINC;    Sample[176]=PINC;    Sample[177]=PINC;
    Sample[178]=PINC;    Sample[179]=PINC;    Sample[180]=PINC;
    Sample[181]=PINC;    Sample[182]=PINC;    Sample[183]=PINC;
    Sample[184]=PINC;    Sample[185]=PINC;    Sample[186]=PINC;
    Sample[187]=PINC;    Sample[188]=PINC;    Sample[189]=PINC;
    Sample[190]=PINC;    Sample[191]=PINC;    Sample[192]=PINC;
    Sample[193]=PINC;    Sample[194]=PINC;    Sample[195]=PINC;
    Sample[196]=PINC;    Sample[197]=PINC;    Sample[198]=PINC;
    Sample[199]=PINC;    Sample[200]=PINC;    Sample[201]=PINC;
    Sample[202]=PINC;    Sample[203]=PINC;    Sample[204]=PINC;
    Sample[205]=PINC;    Sample[206]=PINC;    Sample[207]=PINC;
    Sample[208]=PINC;    Sample[209]=PINC;    Sample[210]=PINC;
    Sample[211]=PINC;    Sample[212]=PINC;    Sample[213]=PINC;
    Sample[214]=PINC;    Sample[215]=PINC;    Sample[216]=PINC;
    Sample[217]=PINC;    Sample[218]=PINC;    Sample[219]=PINC;    
    Sample[220]=PINC;    Sample[221]=PINC;    Sample[222]=PINC;
    Sample[223]=PINC;    Sample[224]=PINC;    Sample[225]=PINC;
    Sample[226]=PINC;    Sample[227]=PINC;    Sample[228]=PINC;
    Sample[229]=PINC;    Sample[230]=PINC;    Sample[231]=PINC;
    Sample[232]=PINC;    Sample[233]=PINC;    Sample[234]=PINC;
    Sample[235]=PINC;    Sample[236]=PINC;    Sample[237]=PINC;
    Sample[238]=PINC;    Sample[239]=PINC;    Sample[240]=PINC;
    Sample[241]=PINC;    Sample[242]=PINC;    Sample[243]=PINC;
    Sample[244]=PINC;    Sample[245]=PINC;    Sample[246]=PINC;
    Sample[247]=PINC;    Sample[248]=PINC;    Sample[249]=PINC;
    Sample[250]=PINC;    Sample[251]=PINC;    Sample[252]=PINC;
    Sample[253]=PINC;    Sample[254]=PINC;    Sample[255]=PINC;
    Sample[256]=PINC;    Sample[257]=PINC;    Sample[258]=PINC;
    Sample[259]=PINC;    Sample[260]=PINC;    Sample[261]=PINC;
    Sample[262]=PINC;    Sample[263]=PINC;    Sample[264]=PINC;
    Sample[265]=PINC;    Sample[266]=PINC;    Sample[267]=PINC;
    Sample[268]=PINC;    Sample[269]=PINC;    Sample[270]=PINC;
    Sample[271]=PINC;    Sample[272]=PINC;    Sample[273]=PINC;
    Sample[274]=PINC;    Sample[275]=PINC;    Sample[276]=PINC;
    Sample[277]=PINC;    Sample[278]=PINC;    Sample[279]=PINC;
    Sample[280]=PINC;    Sample[281]=PINC;    Sample[282]=PINC;
    Sample[283]=PINC;    Sample[284]=PINC;    Sample[285]=PINC;
    Sample[286]=PINC;    Sample[287]=PINC;    Sample[288]=PINC;
    Sample[289]=PINC;    Sample[290]=PINC;    Sample[291]=PINC;
    Sample[292]=PINC;    Sample[293]=PINC;    Sample[294]=PINC;
    Sample[295]=PINC;    Sample[296]=PINC;    Sample[297]=PINC;
    Sample[298]=PINC;    Sample[299]=PINC;    Sample[300]=PINC;
    Sample[301]=PINC;    Sample[302]=PINC;    Sample[303]=PINC;
    Sample[304]=PINC;    Sample[305]=PINC;    Sample[306]=PINC;
    Sample[307]=PINC;    Sample[308]=PINC;    Sample[309]=PINC;
    Sample[310]=PINC;    Sample[311]=PINC;    Sample[312]=PINC;
    Sample[313]=PINC;    Sample[314]=PINC;    Sample[315]=PINC;
    Sample[316]=PINC;    Sample[317]=PINC;    Sample[318]=PINC;
    Sample[319]=PINC;   
   EndSTime = micros();
// display the collected analog data from array
  for(int xpos=0; xpos<319; xpos++) {
    // Erase old stuff
    myGLCD.setColor(0, 0, 0);
    myGLCD.drawLine (xpos+1, 1, xpos+1, 180);
    // Draw new data
    if (xpos%10==0) DrawMarkers(); 
    myGLCD.setColor(255, 255, 255);
    myGLCD.drawLine (xpos, Sample[xpos]*2, xpos+1, Sample[xpos+1]*2);  }  
  // display the sample time  
  myGLCD.setColor(0, 0, 255);
  SampleTime = EndSTime - StartSTime;
  myGLCD.print("uSeconds=          ", 10, 220);
  myGLCD.print(ltoa(SampleTime, buf, 10), 170, 220);
    } 
}

Thursday, June 20, 2013

Universal 8 Bit Graphics Library bug

A while back I posted a video that showed a strange bug that was happening with my oscilloscope LCD program. It used U8GLib or the Universal 8 Bit Graphics Library.  The video is available at, http://youtu.be/1qPy6FVSllY

** UPDATE ** This problem is caused by updating the data while it is being displayed.  The update must not happen within the display loop.

Then I made a perfectly working oscilloscope using the Universal TFT Library and a better LCD. So then I thought I would go back and see what was the problem with U8GLib.

To rule out the LCD display I purchased a KS0108 compatible display because I could run it with its own support software or with the U8GLib.  With the KS0108 driver, I could not scale the amplitude of the input waveform, a new issue.  However the sine wave turned out perfectly using the KS0108 driver.  Then the same software really went crazy when I tried to use the U8GLib drivers.  Here is the video on YouTube, http://youtu.be/l-I4vf83OIc

Does anyone else have this problem or know of a solution??

Here is a picture of what the display should look like;


 But this is what happens when you move the position control to center the sine wave;

Monday, June 17, 2013

Six channel 3 Million samples per second Arduino powered logic analyzer

I DID IT!  I not only got the six channel logic analyzer to work, but I have also succeeded in breaking the 2 million samples per second limit.
Here is the video of it working on YouTube: YouTube Video
Here is a close up of the screen showing the outputs of a 74LS390, with a 10 MC clock input.  The top trace is 100 KC and the bottom one is 1 MC.
How did I do it?  The sample rate is much faster, if you code it like this:

sample[1]=PINC
sample[2]=PINC
sample[3]=PINC
sample[4]=PINC
sample[5]=PINC
sample[6]=PINC
sample[7]=PINC
sample[8]=PINC
sample[9]=PINC
sample[10]=PINC
etc.

It takes a while to type in the code, but using a "loop" slows the sampling time down by more than 50%!

Blogger keeps trashing my code buy hopefully here it is;
/***********************************
128 by 64 LCD Logic Analyzer 6 channel and 3Mb/s
By Bob Davis
Uses Universal 8bit Graphics Library, http://code.google.com/p/u8glib/
  Copyright (c) 2012, olikraus@gmail.com   All rights reserved.

********************************************/
#include "U8glib.h"

// 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
//U8GLIB_ST7920_128X64_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16); 
//  **** NOTE **** I Moved the three control pins !!!
U8GLIB_ST7920_128X64_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 1, 2, 3); 

int Sample[128];
int Input=0;
int OldInput=0;
int xpos=0;
 
void u8g_prepare(void) {
  u8g.setFont(u8g_font_6x10);
  u8g.setFontRefHeightExtendedText();
  u8g.setDefaultForegroundColor();
  u8g.setFontPosTop();
}
void DrawMarkers(void) {
  u8g.drawFrame (0,0,128,64);
  u8g.drawPixel (20,1);
  u8g.drawPixel (40,1);
  u8g.drawPixel (60,1);
  u8g.drawPixel (80,1);
  u8g.drawPixel (100,1);
  u8g.drawPixel (20,62);
  u8g.drawPixel (40,62);
  u8g.drawPixel (60,62);
  u8g.drawPixel (80,62);
  u8g.drawPixel (100,62);
}

void draw(void) {
  u8g_prepare();
  DrawMarkers(); 
// wait for a trigger of a positive going input
  Input=digitalRead(A0);
  while (Input != 1){
    Input=digitalRead(A0);
  }
// collect the analog data into an array
// No loop is about 50% faster!
    Sample[1]=PINC;    Sample[2]=PINC;    Sample[3]=PINC;    Sample[4]=PINC;    
    Sample[5]=PINC;    Sample[6]=PINC;    Sample[7]=PINC;    Sample[8]=PINC;
    Sample[9]=PINC;    Sample[10]=PINC;    Sample[11]=PINC;    Sample[12]=PINC;
    Sample[13]=PINC;    Sample[14]=PINC;    Sample[15]=PINC;    Sample[16]=PINC;    
    Sample[17]=PINC;    Sample[18]=PINC;    Sample[19]=PINC;    Sample[20]=PINC;
    Sample[21]=PINC;    Sample[22]=PINC;    Sample[23]=PINC;    Sample[24]=PINC;
    Sample[25]=PINC;    Sample[26]=PINC;    Sample[27]=PINC;    Sample[28]=PINC;
    Sample[29]=PINC;    Sample[30]=PINC;    Sample[31]=PINC;    Sample[32]=PINC;
    Sample[33]=PINC;    Sample[34]=PINC;    Sample[35]=PINC;    Sample[36]=PINC;
    Sample[37]=PINC;    Sample[38]=PINC;    Sample[39]=PINC;    Sample[40]=PINC;
    Sample[41]=PINC;    Sample[42]=PINC;    Sample[43]=PINC;    Sample[44]=PINC;
    Sample[45]=PINC;    Sample[46]=PINC;    Sample[47]=PINC;    Sample[48]=PINC;
    Sample[49]=PINC;    Sample[50]=PINC;    Sample[51]=PINC;    Sample[52]=PINC;
    Sample[53]=PINC;    Sample[54]=PINC;    Sample[55]=PINC;    Sample[56]=PINC;
    Sample[57]=PINC;    Sample[58]=PINC;    Sample[59]=PINC;    Sample[60]=PINC;
    Sample[61]=PINC;    Sample[62]=PINC;    Sample[63]=PINC;    Sample[64]=PINC;
    Sample[65]=PINC;    Sample[66]=PINC;    Sample[67]=PINC;    Sample[68]=PINC;
    Sample[69]=PINC;    Sample[70]=PINC;    Sample[71]=PINC;    Sample[72]=PINC;
    Sample[73]=PINC;    Sample[74]=PINC;    Sample[75]=PINC;    Sample[76]=PINC;
    Sample[77]=PINC;    Sample[78]=PINC;    Sample[79]=PINC;    Sample[80]=PINC;
    Sample[81]=PINC;    Sample[82]=PINC;    Sample[83]=PINC;    Sample[84]=PINC;
    Sample[85]=PINC;    Sample[86]=PINC;    Sample[87]=PINC;    Sample[88]=PINC;
    Sample[89]=PINC;    Sample[90]=PINC;    Sample[91]=PINC;    Sample[92]=PINC;
    Sample[93]=PINC;    Sample[94]=PINC;    Sample[95]=PINC;    Sample[96]=PINC;
    Sample[97]=PINC;    Sample[98]=PINC;    Sample[99]=PINC;    Sample[100]=PINC;
    Sample[101]=PINC;    Sample[102]=PINC;    Sample[103]=PINC;    Sample[104]=PINC;
    Sample[105]=PINC;    Sample[106]=PINC;    Sample[107]=PINC;    Sample[108]=PINC;
    Sample[109]=PINC;    Sample[110]=PINC;    Sample[111]=PINC;    Sample[112]=PINC;
    Sample[113]=PINC;    Sample[114]=PINC;    Sample[115]=PINC;    Sample[116]=PINC;
    Sample[117]=PINC;    Sample[118]=PINC;    Sample[119]=PINC;    Sample[120]=PINC;
    Sample[121]=PINC;    Sample[122]=PINC;    Sample[123]=PINC;    Sample[124]=PINC;
    Sample[125]=PINC;    Sample[126]=PINC;    Sample[127]=PINC;
// display the collected analog data from array
  for(int xpos=0; xpos<128; xpos++) {
    u8g.drawLine (xpos, ((Sample[xpos]&B00000001)*4)+4, xpos, ((Sample[xpos+1]&B00000001)*4)+4);
    u8g.drawLine (xpos, ((Sample[xpos]&B00000010)*2)+14, xpos, ((Sample[xpos+1]&B00000010)*2)+14);
    u8g.drawLine (xpos, ((Sample[xpos]&B00000100)*1)+24, xpos, ((Sample[xpos+1]&B00000100)*1)+24);
    u8g.drawLine (xpos, ((Sample[xpos]&B00001000)/2)+34, xpos, ((Sample[xpos+1]&B00001000)/2)+34);
    u8g.drawLine (xpos, ((Sample[xpos]&B00010000)/4)+44, xpos, ((Sample[xpos+1]&B00010000)/4)+44);
    u8g.drawLine (xpos, ((Sample[xpos]&B00100000)/8)+54, xpos, ((Sample[xpos+1]&B00100000)/8)+54);
  }  
}

void setup(void) {
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A4, INPUT);
  pinMode(A5, INPUT);

  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) 
    u8g.setColorIndex(255);     // RGB=white
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT )
    u8g.setColorIndex(3);       // max intensity
  else if ( u8g.getMode() == U8G_MODE_BW )
    u8g.setColorIndex(1);       // pixel on, black
}

void loop(void) {
// picture loop  
//  u8g.firstPage();  
  do { draw(); }  
  while( u8g.nextPage() );
  // rebuild the picture after some delay
  delay(100);
}


Thursday, June 13, 2013

Help my Arduino Logic Analyzer crashes when I display more than 2 channels

My two channel logic analizer works very well, the video is even on youTube.  Here is a link to it: http://www.youtube.com/watch?v=lrrpdXiO8Nc
This is what it looks like:


However when I try to display more than two channels the display crashes.  I wonder if it is a bug in the display software.  Perhaps there is a problem with the UTFT library displaying that much information?

Here is a picture of the crashed display:
Any suggestions or ideas?  I have already made the memory reducing change in the UTFT library and that did not fix the problem.

SOLUTION?  The Arduino will crash if you open and access more that 5 arrays at a time.  Basically is is a bug in the Arduino code.  My solution was to only use one array for a six channel logic analyzer and now it is working great.  I will post something about it soon.

Friday, June 7, 2013

Arduino LCD Projects book

Update: "Arduino LCD Projects" is now on Amazon, eBay and CreateSpace.  Here is a cover shot:



My Arduino LCD Projects book is almost ready to publish!

Here is a YouTube video of one of the projects,

Here is the Table of Contents so far:


Introduction

1. Introduction to LCD’s

2. Installing the Arduino Drivers

3. Single Line LCD 16 by 1
            Temperature Display

4. Two Line LCD 16 by 2
            Indoor/Outdoor temperature display
            Simulated analog meter
            Bar graph meter

5. Two Line LCD 40 by 2
            Six analog inputs
            Stereo bar graph meter

6. Four Line LCD 20 by 4
            Four temperature display
            Dual simulated analog meter

7. Low Resolution Graphics LCD 48 by 84
            Text display test program
            Six analog inputs displayed
            Simple Arduino oscilloscope
            Analog meter simulation

8. Medium Resolution Graphics LCD 128 by 64
            Analog meter simulation
            Six channel Logic Analyzer
           Better Arduino oscilloscope

9. High Resolution Graphics LCD 320 by 240
            Analog meter simulation
           Six channel logic analyzer
           External AtoD Oscilloscope
           
Bibliography