Acest ecran l-am prezentat in articolul Ecran tactil de 2,4" (6cm) si necesita libraria SWTFT.
Deoarece nu folosesc cardul microSD, m-am gandit sa fac un alt shield intermediar, care sa imi conecteze modulul de generator de semnal cu AD9850.
Schema mea este:
iar cablajul:
Fizic, montajul asamblat, respectiv componentele atata asa:
Dupa mai multe teste pana am obtinut o tastatura virtuala, am reusit sa fac un sketch care permite introducerea frecventei dorite prin folosirea functiei de ecran tactil, dupa cum se vede in filmuletul generator de semnal cu AD9850 si comenzi de pe ecran tactil (2)
Sketch-ul facut de mine nu este unul optimizat, ci unul functional, in care am folosit, pentru comanda lui AD9850 informatiile de la http://webshed.org/wiki/AD9850_Arduino:
// Code for TFT shield display provided by Smoke And Wires
// http://www.smokeandwires.co.nz
// This code has been taken from the Adafruit TFT Library and modified
// by us for use with our TFT Shields / Modules
// For original code / licensing please refer to
// https://github.com/adafruit/TFTLCD-Library
// adapted sketch by niq_ro from http://arduinotehniq.blogspot.com/
// http://nicuflorica.blogspot.ro/
// http://www.tehnic.go.ro
// http://www.niqro.3x.ro
// original virtual keyboard with DDS with AD8959 by niq_ro
// ver. 1m4a: 30.03.2015, Craiova - Romania
#include <Adafruit_GFX.h> // Core graphics library
#include "SWTFT.h" // Hardware-specific library
// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
// double up the pins with the touch screen (see the TFT paint example).
// #define LCD_CS A3 // Chip Select goes to Analog 3
// #define LCD_CD A2 // Command/Data goes to Analog 2
// #define LCD_WR A1 // LCD Write goes to Analog 1
// #define LCD_RD A0 // LCD Read goes to Analog 0
// #define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin
// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
// D0 connects to digital pin 8 (Notice these are
// D1 connects to digital pin 9 NOT in order!)
// D2 connects to digital pin 2
// D3 connects to digital pin 3
// D4 connects to digital pin 4
// D5 connects to digital pin 5
// D6 connects to digital pin 6
// D7 connects to digital pin 7
// For the Arduino Mega, use digital pins 22 through 29
// (on the 2-row header at the end of the board).
#include <TouchScreen.h>
#define YP A1 // must be an analog pin, use "An" notation!
#define XM A2 // must be an analog pin, use "An" notation!
#define YM 7 // can be a digital pin
#define XP 6 // can be a digital pin
#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
// Assign human-readable names to some common 16-bit color values:
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define ROZ 0xFBE0
#define GRI 0xBDF7
// http://stackoverflow.com/questions/13720937/c-defined-16bit-high-color
// http://wiibrew.org/wiki/U16_colors
SWTFT tft;
#define BOXSIZE 80
#define BOXSIZE2 60
#define PENRADIUS 3
int ics;
int numar, ics0, igr0, pas;
#include <EEPROM.h>
long n1, n2, n3, n4, n5, n6, n7, n8; // number for frequency;
long frecv; // value for frecvency;
byte cifru;
//Setup some items
//#define W_CLK 13 // Pin 13 - connect to AD9850 module word load clock pin (CLK)
#define CLOCK 13
//#define FQ_UD 12 // Pin 12 - connect to freq update pin (FQ)
#define LOAD 12
#define DATA 11 // Pin 11 - connect to serial data load pin (DATA)
#define RESET 10 // Pin 10 - connect to reset pin (RST)
//#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }
#define DDS_CLOCK 125000000 // http://webshed.org/wiki/AD9850_Arduino
//#define DDS_CLOCK 125000000
void setup(void) {
pinMode (DATA, OUTPUT);
pinMode (CLOCK, OUTPUT);
pinMode (LOAD, OUTPUT);
pinMode (RESET, OUTPUT);
AD9850_init();
AD9850_reset();
//SetFrequency(15000);
zaibar();
SetFrequency(frecv);
Serial.begin(9600);
Serial.print(F("DDS with AD9850 "));
Serial.println("made by niq_ro");
tft.reset();
uint16_t identifier = tft.readID();
Serial.print(F("LCD driver chip: "));
Serial.println(identifier, HEX);
tft.begin(identifier);
tft.fillScreen(BLACK);
tft.fillRect(0, 0, 320, 240, BLACK);
// tft.setRotation(0);
// tft.setCursor(5, 100);
tft.setTextColor(RED); tft.setTextSize(2);
// tft.println("Acces control");
tft.setCursor(30, 120);
tft.println("DDS with AD9850");
tft.setCursor(20, 150);
tft.setTextColor(YELLOW);
tft.println("on touch display");
tft.setCursor(70, 180);
tft.setTextColor(BLUE);
tft.println("by niq_ro");
tft.setCursor(75, 210);
tft.setTextColor(ROZ);
tft.println("ver. 1.4a");
delay(2000);
tft.fillRect(0, 0, 320, 240, BLACK);
numar = 0;
ics0 = 10;
igr0 = 280;
pas = 18;
frecv = 0;
//tft.setRotation(0);
stergere ();
cifre ();
caractere();
}
#define MINPRESSURE 10
#define MAXPRESSURE 1000
void loop()
{
// Recently Point was renamed TSPoint in the TouchScreen library
// If you are using an older version of the library, use the
// commented definition instead.
// Point p = ts.getPoint();
TSPoint p = ts.getPoint();
// if sharing pins, you'll need to fix the directions of the touchscreen pins
//pinMode(XP, OUTPUT);
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
//pinMode(YM, OUTPUT);
// we have some minimum pressure we consider 'valid'
// pressure of 0 means no pressing!
if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
// tft.setTextSize(4);
// scale from 0->1023 to tft.width
p.x = tft.width()-(map(p.x, TS_MINX, TS_MAXX, tft.width(), 0));
p.y = tft.height()-(map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));
if (p.y < BOXSIZE2) { // fist line (0, 1 & 2)
if (p.x < BOXSIZE) {
tft.fillRect(0, 0, BOXSIZE, BOXSIZE2, GRI); // one
tft.setTextColor(BLACK);
tft.setCursor(30, 20);
tft.println("1");
// caracter(1);
int ics1 = ics0+pas*numar;
caracters(1,ics1,igr0);
cifru = 1;
delay (200);
tft.fillRect(0, 0, BOXSIZE, BOXSIZE2, RED); // one
tft.setTextColor(WHITE);
tft.setCursor(30, 20);
tft.println("1");
} else if (p.x < BOXSIZE*2) {
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE2, GRI); // two
tft.setTextColor(BLACK);
tft.setCursor(110, 20);
tft.println("2");
// caracter(2);
int ics1 = ics0+pas*numar;
caracters(2,ics1,igr0);
cifru = 2;
delay (200);
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE2, YELLOW); // two
tft.setTextColor(BLACK);
tft.setCursor(110, 20);
tft.println("2");
} else if (p.x < BOXSIZE*3) {
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE2, GRI); // three
tft.setTextColor(BLACK);
tft.setCursor(190, 20);
tft.println("3");
// caracter(3);
int ics1 = ics0+pas*numar;
caracters(3,ics1,igr0);
cifru = 3;
delay (200);
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE2, BLUE); // three
tft.setTextColor(WHITE);
tft.setCursor(190, 20);
tft.println("3");
}
// numar = numar + 1;
}
if ((p.y < BOXSIZE2*2) && (p.y > BOXSIZE2)) { // second line (4, 5 & 6)
if (p.x < BOXSIZE) {
tft.fillRect(0, BOXSIZE2, BOXSIZE, BOXSIZE2, GRI); // four
tft.setTextColor(BLACK);
tft.setCursor(30, 80);
tft.println("4");
int ics1 = ics0+pas*numar;
caracters(4,ics1,igr0);
cifru = 4;
// caracter(4);
delay (200);
tft.fillRect(0, BOXSIZE2, BOXSIZE, BOXSIZE2, CYAN); // four
tft.setTextColor(BLACK);
tft.setCursor(30, 80);
tft.println("4");
} else if (p.x < BOXSIZE*2) {
tft.fillRect(BOXSIZE, BOXSIZE2, BOXSIZE, BOXSIZE2, GRI); // five
tft.setTextColor(BLACK);
tft.setCursor(110, 80);
tft.println("5");
int ics1 = ics0+pas*numar;
caracters(5,ics1,igr0);
cifru = 5;
// caracter(5);
delay (200);
tft.fillRect(BOXSIZE, BOXSIZE2, BOXSIZE, BOXSIZE2, GREEN); // five
tft.setTextColor(BLACK);
tft.setCursor(110, 80);
tft.println("5");
} else if (p.x < BOXSIZE*3) {
tft.fillRect(BOXSIZE*2, BOXSIZE2, BOXSIZE, BOXSIZE2, GRI); // six
tft.setTextColor(BLACK);
tft.setCursor(190, 80);
tft.println("6");
int ics1 = ics0+pas*numar;
caracters(6,ics1,igr0);
cifru = 6;
// caracter(6);
delay (200);
tft.fillRect(BOXSIZE*2, BOXSIZE2, BOXSIZE, BOXSIZE2, MAGENTA); // six
tft.setTextColor(WHITE);
tft.setCursor(190, 80);
tft.println("6");
}
// numar = numar + 1;
}
if ((p.y < BOXSIZE2*3) && (p.y > BOXSIZE2*2)) { // second line (7, 8 & 9)
if (p.x < BOXSIZE) {
tft.fillRect(0, BOXSIZE2*2, BOXSIZE, BOXSIZE2, GRI); // four
tft.setTextColor(BLACK);
tft.setCursor(30, 140);
tft.println("7");
int ics1 = ics0+pas*numar;
caracters(7,ics1,igr0);
cifru = 7;
// caracter(7);
delay (200);
tft.fillRect(0, BOXSIZE2*2, BOXSIZE, BOXSIZE2, RED); // four
tft.setTextColor(WHITE);
tft.setCursor(30, 140);
tft.println("7");
} else if (p.x < BOXSIZE*2) {
tft.fillRect(BOXSIZE, BOXSIZE2*2, BOXSIZE, BOXSIZE2, GRI); // five
tft.setTextColor(BLACK);
tft.setCursor(110, 140);
tft.println("8");
int ics1 = ics0+pas*numar;
caracters(8,ics1,igr0);
cifru = 8;
// caracter(8);
delay (200);
tft.fillRect(BOXSIZE, BOXSIZE2*2, BOXSIZE, BOXSIZE2, YELLOW); // five
tft.setTextColor(BLACK);
tft.setCursor(110, 140);
tft.println("8");
} else if (p.x < BOXSIZE*3) {
tft.fillRect(BOXSIZE*2, BOXSIZE2*2, BOXSIZE, BOXSIZE2, GRI); // six
tft.setTextColor(BLACK);
tft.setCursor(190, 140);
tft.println("9");
// caracter(9);
int ics1 = ics0+pas*numar;
caracters(9,ics1,igr0);
cifru = 9;
delay (200);
tft.fillRect(BOXSIZE*2, BOXSIZE2*2, BOXSIZE, BOXSIZE2, BLUE); // six
tft.setTextColor(WHITE);
tft.setCursor(190, 140);
tft.println("9");
}
// numar = numar + 1;
}
if ((p.y < BOXSIZE2*4) && (p.y > BOXSIZE2*3)) { // second line (*, 0 & #)
/*
if (p.x < BOXSIZE) {
tft.fillRect(0, BOXSIZE2*3, BOXSIZE, BOXSIZE2, GRI); // four
tft.setTextColor(BLACK);
tft.setCursor(30, 200);
tft.println("*");
int ics1 = ics0+pas*numar;
caracters(10,ics1,igr0);
// caracter(10);
delay (200);
tft.fillRect(0, BOXSIZE2*3, BOXSIZE, BOXSIZE2, CYAN); // four
tft.setTextColor(BLACK);
tft.setCursor(30, 200);
tft.println("*");
} else
*/
if ((p.x > BOXSIZE) && (p.x < BOXSIZE*2)) {
tft.fillRect(BOXSIZE, BOXSIZE2*3, BOXSIZE, BOXSIZE2, GRI); // five
tft.setTextColor(BLACK);
tft.setCursor(110, 200);
tft.println("0");
// caracter(0);
int ics1 = ics0+pas*numar;
caracters(0,ics1,igr0);
cifru = 0;
delay (200);
tft.fillRect(BOXSIZE, BOXSIZE2*3, BOXSIZE, BOXSIZE2, GREEN); // five
tft.setTextColor(BLACK);
tft.setCursor(110, 200);
tft.println("0");
}
/*
else if (p.x < BOXSIZE*3) {
tft.fillRect(BOXSIZE*2, BOXSIZE2*3, BOXSIZE, BOXSIZE2, GRI); // six
tft.setTextColor(BLACK);
tft.setCursor(190, 200);
tft.println("#");
int ics1 = ics0+pas*numar;
caracters(11,ics1,igr0);
// caracter(11);
delay (200);
tft.fillRect(BOXSIZE*2, BOXSIZE2*3, BOXSIZE, BOXSIZE2, MAGENTA); // six
tft.setTextColor(WHITE);
tft.setCursor(190, 200);
tft.println("#");
}
*/
// numar = numar + 1;
}
//caractere();
numar = numar + 1;
memorie(cifru,numar);
Serial.print(cifru);
if (numar == 2) numar = numar +1;
if (numar == 6) numar = numar +1;
if (numar == 10) {
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.setCursor(200, 250);
tft.println("ok");
Serial.print(" --> ");
// read eeprom memory and calculate the stored number (freqvency)
zaibar();
Serial.print(frecv);
Serial.println("Hz");
Serial.println("---------");
Serial.print(frecv);
/*
Serial.println(frecv);
Serial.println("---------");
for (int j=11; j<19; j++)
{
Serial.print(EEPROM.read(j));
}
*/
delay (3000);
tft.fillRect(0, 310 , 239, 5, BLACK); // for testing
tft.fillRect(199, 249 , pas*2+2, 30, BLACK); // for testing
// caractere();
numar = 0;
}
}
} // end main loop
void cifre ()
{
// number for "buttons"
tft.setTextSize(4);
tft.setTextColor(WHITE);
tft.setCursor(30, 20);
tft.println("1");
tft.setTextColor(BLACK);
tft.setCursor(110, 20);
tft.println("2");
tft.setTextColor(WHITE);
tft.setCursor(190, 20);
tft.println("3");
tft.setTextColor(BLACK);
tft.setCursor(30, 80);
tft.println("4");
tft.setTextColor(BLACK);
tft.setCursor(110, 80);
tft.println("5");
tft.setTextColor(WHITE);
tft.setCursor(190, 80);
tft.println("6");
tft.setTextColor(WHITE);
tft.setCursor(30, 140);
tft.println("7");
tft.setTextColor(BLACK);
tft.setCursor(110, 140);
tft.println("8");
tft.setTextColor(WHITE);
tft.setCursor(190, 140);
tft.println("9");
// tft.setTextColor(BLACK);
// tft.setCursor(30, 200);
// tft.println("*");
tft.setTextColor(BLACK);
tft.setCursor(110, 200);
tft.println("0");
// tft.setTextColor(WHITE);
// tft.setCursor(190, 200);
// tft.println("#");
}
void stergere ()
{
// Serial.println("erase");
// firs line
tft.fillRect(0, 0, BOXSIZE, BOXSIZE2, RED); // one
tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE2, YELLOW); // two
tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE2, BLUE); // three
// second line
tft.fillRect(0, BOXSIZE2 , BOXSIZE, BOXSIZE2, CYAN); // four
tft.fillRect(BOXSIZE, BOXSIZE2, BOXSIZE, BOXSIZE2, GREEN); // five
tft.fillRect(BOXSIZE*2, BOXSIZE2, BOXSIZE, BOXSIZE2, MAGENTA); // six
// 3rd line
tft.fillRect(0, BOXSIZE2*2 , BOXSIZE, BOXSIZE2, RED); // seven
tft.fillRect(BOXSIZE, BOXSIZE2*2, BOXSIZE, BOXSIZE2, YELLOW); // eight
tft.fillRect(BOXSIZE*2, BOXSIZE2*2, BOXSIZE, BOXSIZE2, BLUE); // nein
// 4th line
// tft.fillRect(0, BOXSIZE2*3 , BOXSIZE, BOXSIZE2, CYAN); // *
tft.fillRect(BOXSIZE, BOXSIZE2*3, BOXSIZE, BOXSIZE2, GREEN); // zero
// tft.fillRect(BOXSIZE*2, BOXSIZE2*3, BOXSIZE, BOXSIZE2, MAGENTA); // #
cifre ();
}
void caracter (int numar)
{
tft.setTextSize(4);
tft.setTextColor(WHITE);
tft.setCursor(110, 280);
tft.fillRect(0, 260 , 240, 59, BLACK); // *
if (numar == 0) tft.println("0");
if (numar == 1) tft.println("1");
if (numar == 2) tft.println("2");
if (numar == 3) tft.println("3");
if (numar == 4) tft.println("4");
if (numar == 5) tft.println("5");
if (numar == 6) tft.println("6");
if (numar == 7) tft.println("7");
if (numar == 8) tft.println("8");
if (numar == 9) tft.println("9");
//if (numar == 10) tft.println("*");
//if (numar == 11) tft.println("#");
}
void caractere()
{
tft.setTextSize(2);
tft.fillRect(0, 241 , 240, 79, BLACK); // *
tft.setTextColor(WHITE);
tft.setCursor(10, 258);
tft.println("DDS with AD9850");
tft.setTextSize(3);
tft.setCursor(10, 280);
// tft.println("??.???.???Hz");
citiremem();
// tft.println(EEPROM.read(11));
}
void caracters (int numar, int ics, int igr)
{
tft.setTextSize(3);
tft.setTextColor(WHITE);
//tft.drawLine(x1, y1, x2, y2, color); // line model
tft.drawLine(ics, igr+32, ics+pas, igr+32, BLUE);
tft.setCursor(ics, igr);
tft.fillRect(ics, igr-2 , pas, 30, YELLOW); // for testing
delay(100);
tft.fillRect(ics, igr-2 , pas, 30, BLACK);
if (numar == 0) tft.println("0");
if (numar == 1) tft.println("1");
if (numar == 2) tft.println("2");
if (numar == 3) tft.println("3");
if (numar == 4) tft.println("4");
if (numar == 5) tft.println("5");
if (numar == 6) tft.println("6");
if (numar == 7) tft.println("7");
if (numar == 8) tft.println("8");
if (numar == 9) tft.println("9");
//if (numar == 10) tft.println("*");
//if (numar == 11) tft.println("#");
tft.setTextSize(4);
}
void memorie (byte cifra, int pozitie)
{
if (pozitie == 1) {
EEPROM.write(11,cifra); // cifra zeci de MHz
// Serial.print(EEPROM.read(11));
}
if (pozitie == 2) {
EEPROM.write(12,cifra); // cifra MHZ
// Serial.print(EEPROM.read(12));
}
if (pozitie == 4) {
EEPROM.write(13,cifra); // cifra sute de kHz
// Serial.print(EEPROM.read(13));
}
if (pozitie == 5) {
EEPROM.write(14,cifra); // cifra zeci de kHz
// Serial.print(EEPROM.read(14));
}
if (pozitie == 6) {
EEPROM.write(15,cifra); // cifra kHz
// Serial.print(EEPROM.read(15));
}
if (pozitie == 8) {
EEPROM.write(16,cifra); // cifra sute de Hz
// Serial.print(EEPROM.read(16));
}
if (pozitie == 9) {
EEPROM.write(17,cifra); // cifra zeci de Hz
// Serial.print(EEPROM.read(17));
}
if (pozitie == 10) {
EEPROM.write(18,cifra); // cifra Hz
// Serial.print(EEPROM.read(18));
}
}
void citiremem ()
{
//tft.setTextSize(3);
// tft.setCursor(10, 280);
for (int ji=11; ji<19; ji++)
{
int nr = EEPROM.read(ji);
if (nr == 0) tft.print("0");
if (nr == 1) tft.print("1");
if (nr == 2) tft.print("2");
if (nr == 3) tft.print("3");
if (nr == 4) tft.print("4");
if (nr == 5) tft.print("5");
if (nr == 6) tft.print("6");
if (nr == 7) tft.print("7");
if (nr == 8) tft.print("8");
if (nr == 9) tft.print("9");
if (ji==12) tft.print(".");
if (ji==15) tft.print(".");
}
tft.println("Hz");
}
void SetFrequency(unsigned long frequency)
{
unsigned long tuning_word = (frequency * pow(2, 32)) / DDS_CLOCK;
digitalWrite (LOAD, LOW);
shiftOut(DATA, CLOCK, LSBFIRST, tuning_word);
shiftOut(DATA, CLOCK, LSBFIRST, tuning_word >> 8);
shiftOut(DATA, CLOCK, LSBFIRST, tuning_word >> 16);
shiftOut(DATA, CLOCK, LSBFIRST, tuning_word >> 24);
shiftOut(DATA, CLOCK, LSBFIRST, 0x0);
digitalWrite (LOAD, HIGH);
}
void AD9850_init()
{
digitalWrite(RESET, LOW);
digitalWrite(CLOCK, LOW);
digitalWrite(LOAD, LOW);
digitalWrite(DATA, LOW);
}
void AD9850_reset()
{
//reset sequence is:
// CLOCK & LOAD = LOW
// Pulse RESET high for a few uS (use 5 uS here)
// Pulse CLOCK high for a few uS (use 5 uS here)
// Set DATA to ZERO and pulse LOAD for a few uS (use 5 uS here)
// data sheet diagrams show only RESET and CLOCK being used to reset the device, but I see no output unless I also
// toggle the LOAD line here.
digitalWrite(CLOCK, LOW);
digitalWrite(LOAD, LOW);
digitalWrite(RESET, LOW);
delay(5);
digitalWrite(RESET, HIGH); //pulse RESET
delay(5);
digitalWrite(RESET, LOW);
delay(5);
digitalWrite(CLOCK, LOW);
delay(5);
digitalWrite(CLOCK, HIGH); //pulse CLOCK
delay(5);
digitalWrite(CLOCK, LOW);
delay(5);
digitalWrite(DATA, LOW); //make sure DATA pin is LOW
digitalWrite(LOAD, LOW);
delay(5);
digitalWrite(LOAD, HIGH); //pulse LOAD
delay(5);
digitalWrite(LOAD, LOW);
// Chip is RESET now
}
void zaibar()
{
n1 = EEPROM.read(11); //Serial.print(n1);
n2 = EEPROM.read(12); //Serial.print(n2);
n3 = EEPROM.read(13); //Serial.print(n3);
n4 = EEPROM.read(14); //Serial.print(n4);
n5 = EEPROM.read(15); //Serial.print(n5);
n6 = EEPROM.read(16); //Serial.print(n6);
n7 = EEPROM.read(17); //Serial.print(n7);
n8 = EEPROM.read(18); //Serial.print(n8);
frecv = n1*10000000 + n2*1000000+n3*100000+n4*10000+n5*1000+n6*100+n7*10+n8;
}
29.7.2015
Am facut si filmuletul generator de semnal cu AD9850 si osciloscop EM125 (2) in care se vad si formele de unda pe un osciloscop portabil: