mflorian24 Postat Martie 13, 2014 Partajează Postat Martie 13, 2014 După cîţiva ani buni în care am pus pistolul în cui, am revenit în lumea sîrmuliţelor.Prima dată am construit un frecvenţmetru şi apoi un generator de semnat sinusoidal/dreptunghiular. Deoarece am avut suficient spaţiu, am hotărît să le pun în aceeaşi cutie, că tot sînt înrudite. În mesajele următoare voi prezenta schemele şi codul sursă pentru ATMEGA328P-PU. Link spre comentariu
mircea888 Postat Martie 13, 2014 Partajează Postat Martie 13, 2014 Arata foarte bine, asteptam schemele si codul, eventual ceva lamuriri la cod.E programat cu Arduino ?Ai vizualizat semnalul pe osciloscop? sunt curios cum arata pe sinus.Multa bafta in continuare! Link spre comentariu
mflorian24 Postat Martie 13, 2014 Autor Partajează Postat Martie 13, 2014 Schema frecvenţmetrului. Nimic deosebit, conectarea ansamblului ATMEGA - LCD este de-acum clasică. Partea de formatare a semnalului este, de asemenea, culeasă de pe net, deci nimic original.Prima dată am făcut montajul cu un Arduino UNO şi un breadboard, ca să mă pot juca intercativ cu codul sursă. Apoi, la asamblarea finală am înlocuit placa Arduino cu un ATMEGA, ca în schema de mai jos. Link spre comentariu
mflorian24 Postat Martie 13, 2014 Autor Partajează Postat Martie 13, 2014 Mai jos codul sursă. Menţionez de la bun început că partea cea mai importantă este culeasă de pe net, mai exact de la adresa: http://interface.khm.de/index.php/lab/e ... r-library/ Tot de acolo vă recomand să descărcaţi şi librăria aferentă. Codul sursă, în forma finală este destul de simplu. În prima linie din loop() se ajustează valoarea FreqCounter::f_comp pentru a afişa o frecvenţă identică cu a unui frecvenţemetru calibrat. Eu am pus la intrare un semnal calibrat de 1MHz şi am dat diverse valori acelei variabile pînă am obţinut pe ecran valoarea exactă. Din cele observate de mine, pentru fiecare cip ATMEGA în parte valoarea este uşor diferită. Cam asta-i tot pentru partea de frecvenţmetru. // Frequency Counter Lib example/* Martin Nawrath KHM LAB3 Kunsthochschule f¸r Medien Kˆln Academy of Media Arts http://www.khm.de http://interface.khm.de/index.php/labor/experimente/ MAXIMUM 8 MHz!!!! */ //digital pin 5 -> freq In #include <FreqCounter.h>#include <LiquidCrystal.h>unsigned long frq;int cnt;LiquidCrystal lcd(13, 12, 11, 10, 9, 8);void setup() { lcd.begin(16, 2);}void loop() { // wait if any serial is going on FreqCounter::f_comp=35; // Cal Value / Calibrate with professional Freq Counter FreqCounter::start(1000); // 100 ms Gate Time while (FreqCounter::f_ready == 0) frq=FreqCounter::f_freq; lcd.clear(); lcd.setCursor(0, 0); lcd.print("f= "); if(frq < 1000.0){ lcd.print(frq); lcd.print(" Hz"); } else if (frq < 1000000.0 ) { lcd.print(frq/1000.0, 3); lcd.print(" KHz"); } else if(frq < 8000000.0 ){ lcd.print(frq/1000000.0, 6); lcd.print(" MHz"); } else { lcd.print(" Overflow" ); } delay(200); } Link spre comentariu
mflorian24 Postat Martie 13, 2014 Autor Partajează Postat Martie 13, 2014 Generatorul de semnal este construit în jurul integratului AD9850, asamblat pe o placă cu tot ce-i trebuie. Circuitul l-am cumpărat de pe net şi arată cam aşa: http://www.robotshop.com/en/ad9850-simp ... rator.html Detalii despre conectare se pot găsi aici: http://nr8o.dhlpilotcentral.com/?cat=16 Cel mai simplu program pentru a scoate din placă semnal sinus/dreptunghi arată ca mai jos. Frecvenţa este setată în ultima linie. /* * A simple single freq AD9850 Arduino test script * Original AD9851 DDS sketch by Andrew Smallbone at www.rocketnumbernine.com * Modified for testing the inexpensive AD9850 ebay DDS modules * Pictures and pinouts at nr8o.dhlpilotcentral.com * 9850 datasheet at http://www.analog.com/static/imported-files/data_sheets/AD9850.pdf * Use freely */ #define W_CLK 8 // Pin 3 - connect to AD9850 module word load clock pin (CLK) #define FQ_UD 9 // Pin 4 - connect to freq update pin (FQ) #define DATA 10 // Pin 5 - connect to serial data load pin (DATA) #define RESET 11 // Pin 6 - connect to reset pin (RST). #define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); } // transfers a byte, a bit at a time, LSB first to the 9850 via serial DATA linevoid tfr_byte(byte data){ for (int i=0; i<8; i++, data>>=1) { digitalWrite(DATA, data & 0x01); pulseHigh(W_CLK); //after each bit sent, CLK is pulsed high }} // frequency calc from datasheet page 8 = <sys clock> * <frequency tuning word>/2^32void sendFrequency(double frequency) { int32_t freq = frequency * 4294967295/125000000; // note 125 MHz clock on 9850 for (int b=0; b<4; b++, freq>>=8) { tfr_byte(freq & 0xFF); } tfr_byte(0x000); // Final control byte, all 0 for 9850 chip pulseHigh(FQ_UD); // Done! Should see output} void setup() { // configure arduino data pins for output pinMode(FQ_UD, OUTPUT); pinMode(W_CLK, OUTPUT); pinMode(DATA, OUTPUT); pinMode(RESET, OUTPUT); pulseHigh(RESET); pulseHigh(W_CLK); pulseHigh(FQ_UD); // this pulse enables serial mode - Datasheet page 12 figure 10} void loop() { sendFrequency(500.0); // freq } Urmează să arăt cum am "îmbrăcat" acest cod cu cel de tastatură, encoder şi LCD pentru a introduce comod frecvenţa dorită şi a o afişa pentru control. Link spre comentariu
mflorian24 Postat Martie 13, 2014 Autor Partajează Postat Martie 13, 2014 Schema finală a generatorului de semnal este cea de mai jos. Frecvenţa se introduce din tastatură şi se poate ajusta fin în sus şi în jos din encoder. LCD-ul nu face nimic altceva decît să afişeze valoarea pe care o primeşte AD9850.Tastei # i-am dat destinaţia de Delete, adică ştergerea ultimei cifre. Tasta * multiplică acţiunea encoderului cu 1, 10, 100 sau 1000. Link spre comentariu
mflorian24 Postat Martie 13, 2014 Autor Partajează Postat Martie 13, 2014 Codul sursă pentru generatorul de semnal în forma finală. Codul este comentat abundent. #include <Keypad.h> #include <LiquidCrystal.h> LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);#define W_CLK 3 // Pin 3 - connect to AD9850 module word load clock pin (CLK)#define FQ_UD 4 // Pin 4 - connect to freq update pin (FQ)#define DATA 5 // Pin 5 - connect to serial data load pin (DATA)#define RESET 6 // Pin 6 - connect to reset pin (RST).#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }const byte ROWS = 4; // Four rows of the keypadconst byte COLS = 3; // Three columns of the keypadconst unsigned long LIMIT = 40000000.0;//40MHz is the upper limit of this oscillator//keypad pin1 to pin7 -> arduino pin 7 to pin13byte rowPins[ROWS] = { 13, 12, 11, 10 }; // Connect keypad pin4, pin5, pin6 and pin7 to these Arduino pins.byte colPins[COLS] = { 9, 8, 7 }; // Connect keypad pin3, pin2 and pin1 to these Arduino pins.String displayValue = "0"; //initialisin of the dispalyed valueunsigned long value; //the numeric value from the keypad and encoder, to be passed to oscillatorchar keys[ROWS][COLS] = {// Define the Keymap {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'*','0','#'}};Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // Create the Keypad objectconst int pin_A = 2; // encoder pin A to Arduino pin 2const int pin_B = 1; // encoder pin B to Arduino pin 1//encoder pin C to GNDconst int CONSTANT = 1; //fine tuning for debouncing of different types of encodersunsigned long currentTime;unsigned long loopTime;unsigned char encoder_A;unsigned char encoder_B;unsigned char encoder_A_prev=0;int encoderScale, inputEvent;void tfr_byte(byte data) {// transfers a byte, a bit at a time, LSB first to the 9850 via serial DATA line for (int i=0; i<8; i++, data>>=1) { digitalWrite(DATA, data & 0x01); pulseHigh(W_CLK); //after each bit sent, CLK is pulsed high }} void sendFrequency(double frequency) { // frequency calc from datasheet page 8 = <sys clock> * <frequency tuning word>/2^32 int32_t freq = frequency * 4294967295/125000000; // note 125 MHz clock on 9850 for (int b=0; b<4; b++, freq>>=8) { tfr_byte(freq & 0xFF); } tfr_byte(0x000); // Final control byte, all 0 for 9850 chip pulseHigh(FQ_UD); // Done! Should see output} void setup() {//Serial.begin(9600); // configure arduino data pins for output pinMode(FQ_UD, OUTPUT); pinMode(W_CLK, OUTPUT); pinMode(DATA, OUTPUT); pinMode(RESET, OUTPUT); pulseHigh(RESET); pulseHigh(W_CLK); pulseHigh(FQ_UD); // this pulse enables serial mode - Datasheet page 12 figure 10 pinMode(pin_A, INPUT_PULLUP); pinMode(pin_B, INPUT_PULLUP); currentTime = millis(); loopTime = currentTime; encoderScale = 1; inputEvent = 0; lcd.begin(16, 2); lcd.print("f= 0 Hz"); lcd.setCursor(0, 1); lcd.print("o ");} void loop() { ///////////////////////////Keypad code//////////////////////////////////////// char key = kpd.getKey(); if(key){ // Check for a valid key. switch (key){ case '*': //adjust multiplier for encoder switch (encoderScale){ case 1: encoderScale = 10; break; case 10: encoderScale = 100; break; case 100: encoderScale = 1000; break; case 1000: encoderScale = 1; break; } break; case '#': //delte last digit if(displayValue != "0"){ displayValue = displayValue.substring(0, displayValue.length()-1); } break; case '0'://append a 0 digit if the value is non-zero if(displayValue != "0" && value * 10.0 < LIMIT){ displayValue += key; } break; default://for all other values add a digit to the ned if(value * 10.0 <= LIMIT){ displayValue += key; } break; } value = displayValue.toInt();//convert the string to unsigned long inputEvent = 1;//Serial.println(value); } /////////////////end of keypad code///////////////////////////////// /////////////////////encoder code/////////////////////////////////// currentTime = millis();// get the current elapsed time if(currentTime >= (loopTime + CONSTANT)){//CONSTANT compensates different type of encoders encoder_A = digitalRead(pin_A); // Read encoder pins encoder_B = digitalRead(pin_B); if((!encoder_A) && (encoder_A_prev)){// A has gone from high to low if(encoder_B) {// B is high so clockwise if(value < LIMIT - encoderScale){ value= value + encoderScale; String temp(value); displayValue = temp; } } else { // B is low so counter-clockwise if(value > encoderScale) { value = value - encoderScale; String temp(value); displayValue = temp; } } inputEvent = 1;//Serial.println(value); } encoder_A_prev = encoder_A; // Store value of A for next time loopTime = currentTime; // Updates loopTime } /////////////////end of encoder code/////////////////////////////////////////////////////////////////LCD code/////////////////////////////// if(inputEvent == 1){ lcd.clear(); lcd.setCursor(0, 0); lcd.print("f= "); if(value < 1000.0){ lcd.print(value); lcd.print(" Hz"); } else if (value < 1000000.0 ) { lcd.print(value/1000.0, 3); lcd.print(" KHz"); } else if(value < 41000000.0 ){ lcd.print(value/1000000.0, 6); lcd.print(" MHz"); } else { lcd.print(" Overflow" ); } lcd.setCursor(0, 1); switch(encoderScale){ case 1: lcd.print("o "); break; case 10: lcd.print("oo "); break; case 100: lcd.print("ooo "); break; case 1000: lcd.print("oooo"); break; } inputEvent = 0; }//////////////////////////////////end of LCD code//////////////////////// sendFrequency(value); // call to AD9850 module} Link spre comentariu
mflorian24 Postat Martie 13, 2014 Autor Partajează Postat Martie 13, 2014 E programat cu Arduino ?Da, am folosit Arduino UNO. Apoi programul este scris într-un cip ATMEGA328P-PU.Ai vizualizat semnalul pe osciloscop? sunt curios cum arata pe sinus.Din păcate nu am un osciloscop, aşa că tot ce pot spune este că un "osciloscop" Zeitnitz pe placa audio a calculatorului zice că sinusoida are sub 0.2% distorsiuni pînă pe la 12-14KHz, cît poate acesta să măsoare. Şi eu mor de curiozitate să văd sinusoida la frecvenţele cele mai mari. Cînd apuc la un osciloscop performant, scriu aici ce văd acolo. Link spre comentariu
nico_2010 Postat Martie 14, 2014 Partajează Postat Martie 14, 2014 @mflorian24: Pentru modulele cu DDS, la modul general, semnalul sinusoidal este bun, insa vei avea un semnal de amplitudine relativ mica (cel mult 1 Vpp/200 ohm). Utilizand un amplificator vei obtine un semnal de amplitudine mai mare insa nu vei mai putea obtine semnale de frecvente joase (in zona audio), asa ca va trebui sa faci un compromis.Oricum, felicitari pentru realizare. Link spre comentariu
mflorian24 Postat Martie 14, 2014 Autor Partajează Postat Martie 14, 2014 Da, aşa este, am văzut încă din faza de experimente că ieşirea sinus este de aprox. 750 mV p-p. Îmi era clar de la bun început că nu voi putea face un amplificator de la 1Hz pînă la 40MHz, liniar şi cu distorsiuni minime. Aşa că am lăsat pentru mai încolo această temă, la care m-am gîndit să fac separat amplificatoare pe domenii de frecvenţă.Ieşirea dreptunghiulară, în schimb, are amplitudine suficientă pentru o intrare TTL, dar este limitată la maximum 7MHz. Link spre comentariu
Postări Recomandate
Creează un cont sau autentifică-te pentru a adăuga comentariu
Trebuie să fi un membru pentru a putea lăsa un comentariu.
Creează un cont
Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!
Înregistrează un nou contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum