+- HomeMade (http://sp-hm.pl)
+-- Dział: Urządzenia nadawczo odbiorcze KF (/forum-62.html)
+--- Dział: Syntezy częstotliwości i moduły DSP (/forum-74.html)
+--- Wątek: Fork-Heńka... czyli jak sobie poradzić z DDS za pomocą ARDUINO (/thread-2164.html)
RE: Fork-Heńka... czyli jak sobie poradzić z DDS za pomocą ARDUINO - SQ9MDD - 12-10-201417:57
Tak jak Rysio mówi każde arduino jest dobre bo wyjścia są takie same.
Ok Rysio doczytałem że masz 4 impulsy na ząbek inni mogą mieć jeszcze inaczej.
W takim razie zmieniłem program i wyciągnałem zmienną na górę do modyfikacji, każdy ustawi pod swój enkoder.
Kod:
//************************************************************************//
// Złomek - kumpel Heńka, projekt pogladowy obsługi DDS AD9850,
// wyświetlacza nokii 5110 i jakiegoś enkodera.
// Projekt otwarty http://sp-hm.pl
// SQ9MDD - początkowy szkielet programu v 1.0.0
// S_____ -
// S_____ -
//
//************************************************************************//
/* CHANGELOG (nowe na górze)
2014.10.12 - początek projektu wspólnego na sp-hm.pl
wymiana biblioteki wyświetlacza lcd na LCDD5110 basic
2014.05.22 - pierwsza wersja kodu warsztaty arduino w komorowie.
*/
//************************************************************************//
//podłączamy bibliotekę syntezera
#include <AH_AD9850.h>
//inicjalizujemy enkoder
//AO - w lewo
//A1 - w prawo
//nalezy pamiętać o kondensatorach (100nF) pomiędzy liniami encodera a masą
RotaryEncoder encoder(A0,A1,5,6,1000);
//kontrast wyświetlacza
const int kontrast = 70; //kontrast wyświetlacza
const int pulses_for_groove = 2; //ilość impulsów na ząbek enkodera zmienić w zależności od posiadanego egzemplarza
//zmienna pomocnicza do wyrzucania danych na lcd
char buffor[] = " ";
//zmienna dla częstotliwości, wstawiamy tam częstotliwość od której startujemy
long czestotliwosc = 28500000;
//zmienna pomocnicza do liczenia impulsów z enkodera
int enc_sum = 0;
//funkcja do obsługi wyświetlania zmiany częstotliwości
void show_frequency(){
lcd.setFont(SmallFont); //ustawiamy czcionkę
sprintf(buffor,"%lu",czestotliwosc); //konwersja danych do wyświetlenia (ładujemy longa do stringa
lcd.print(buffor,CENTER,0); //wyświetlamy dane na lcd
}
// setup funkcja odpalana przy starcie
void setup(){
//uruchamiam port szeregowy w celach diagnostycznych
Serial.begin(9600);
//odpalamy syntezer i ustawiamy częstotliwość startową
AD9850.set_frequency(0,0,czestotliwosc); //set power=UP, phase=0, 1MHz frequency
delay(1000); //sekunda opóźnienia
lcd.InitLCD(kontrast); //odpalamy lcd ustawiamy kontrast
show_frequency(); //pokazmy cos na lcd
}
void loop(){
//czytamy wartość z encodera
int enc = encoder.readEncoder();
if(enc != 0) { //jeśli wartość jest inna niż zero sumujemy
enc_sum = enc_sum + enc; //jeden ząbek encodera to +2 lub -2 tutaj to zliczam
Serial.println(enc);
}
//jesli zaliczyliśmy ząbek dodajemy lub odejmujemy do częstotliwości wartość kroku (na razie na sztywno 100Hz)
if(enc_sum >= pulses_for_groove){
czestotliwosc = czestotliwosc + 100; //docelowo czestotliwosc = czestotliwosc + krok
AD9850.set_frequency(czestotliwosc); //ustawiam syntezę na odpowiedniej częstotliwości
show_frequency(); //drukuję częstotliwość na wyświetlaczu za pomocą gotowej funkcji
enc_sum = 0; //reset zmiennej zliczającej impulsy enkodera
}
if(enc_sum <= -(pulses_for_groove)){
czestotliwosc = czestotliwosc - 100; //docelowo czestotliwosc = czestotliwosc - krok
AD9850.set_frequency(czestotliwosc); //ustawiam syntezę na odpowiedniej częstotliwości
show_frequency(); //drukuję częstotliwość na wyświetlaczu za pomocą gotowej funkcji
enc_sum = 0; //reset zmiennej zliczającej impulsy enkodera
}
delayMicroseconds(5); //małe opóźnienie dla prawidłowego działania enkodera
}
RE: Fork-Heńka... czyli jak sobie poradzić z DDS za pomocą ARDUINO - SP6IFN - 12-10-201418:36
Ryszard!
Wpisz startową F=10MHz i juz jej nie zmieniaj.
A co do obecnej wersji programu to jest błąd wyświetlania. Poniżej wpisanej 10000000 źle czyta wyświetlacz, dodaje na początku ";" i przesuwa wiersz nieco w prawo. Nie wiem czy to czasem coś w bibliotece się psuje.
Rysio!
RE: Fork-Heńka... czyli jak sobie poradzić z DDS za pomocą ARDUINO - SQ9MDD - 12-10-201419:05
Hej.
To nie jest błąd biblioteki tylko mój, już wyjaśniam.
Dane drukujemy w taki sposób:
Kod:
lcd.print(buffor,CENTER,0);
"CENTER" Oznacza to że wyświetlamy częstotliwość na środku, 10MHz to 10 i sześć zer jak damy w dół to będzie 9 i sześć zer czyli cyfrę mniej i zostają śmieci z przodu i z tyłu.
Przygotowując dane do wyświetlenia za pomocą sprintf możemy zapanować nad tym co się dzieje jeśli dane są zbyt krótkie i nie pasują do stringa.
Mieliśmy tak:
Kod:
sprintf(buffor," %lu ",czestotliwosc);
A jak damy tak:
Kod:
sprintf(buffor," %08lu ",czestotliwosc);
To jeśli dane będą krótsze to sprintf dopełni je z przodu zerami.
Czyli można to łatwo naprawić
Ogólnie sprintf jest kluczem do właściwego wyświetlania danych na lcd.
Pełny kod po poprawkach
Kod:
//************************************************************************//
// Złomek - kumpel Heńka, projekt pogladowy obsługi DDS AD9850,
// wyświetlacza nokii 5110 i jakiegoś enkodera.
// Projekt otwarty http://sp-hm.pl
// SQ9MDD - początkowy szkielet programu v 1.0.0
// S_____ -
// S_____ -
//
//************************************************************************//
/* CHANGELOG (nowe na górze)
2014.10.12 - początek projektu wspólnego na sp-hm.pl
wymiana biblioteki wyświetlacza lcd na LCDD5110 basic
2014.05.22 - pierwsza wersja kodu warsztaty arduino w komorowie.
*/
//************************************************************************//
//podłączamy bibliotekę syntezera
#include <AH_AD9850.h>
//inicjalizujemy enkoder
//AO - w lewo
//A1 - w prawo
//nalezy pamiętać o kondensatorach (100nF) pomiędzy liniami encodera a masą
RotaryEncoder encoder(A0,A1,5,6,1000);
//kontrast wyświetlacza
const int kontrast = 70; //kontrast wyświetlacza
const int pulses_for_groove = 2; //ilość impulsów na ząbek enkodera zmienić w zależności od posiadanego egzemplarza
//zmienna pomocnicza do wyrzucania danych na lcd
char buffor[] = " ";
//zmienna dla częstotliwości, wstawiamy tam częstotliwość od której startujemy
long czestotliwosc = 10000000;
//zmienna pomocnicza do liczenia impulsów z enkodera
int enc_sum = 0;
//funkcja do obsługi wyświetlania zmiany częstotliwości
void show_frequency(){
lcd.setFont(SmallFont); //ustawiamy czcionkę
sprintf(buffor," %08lu ",czestotliwosc); //konwersja danych do wyświetlenia (ładujemy longa do stringa
lcd.print(buffor,CENTER,0); //wyświetlamy dane na lcd
}
// setup funkcja odpalana przy starcie
void setup(){
//uruchamiam port szeregowy w celach diagnostycznych
Serial.begin(9600);
//odpalamy syntezer i ustawiamy częstotliwość startową
AD9850.set_frequency(0,0,czestotliwosc); //set power=UP, phase=0, 1MHz frequency
delay(1000); //sekunda opóźnienia
lcd.InitLCD(kontrast); //odpalamy lcd ustawiamy kontrast
show_frequency(); //pokazmy cos na lcd
}
void loop(){
//czytamy wartość z encodera
int enc = encoder.readEncoder();
if(enc != 0) { //jeśli wartość jest inna niż zero sumujemy
enc_sum = enc_sum + enc; //jeden ząbek encodera to +2 lub -2 tutaj to zliczam
Serial.println(enc);
}
//jesli zaliczyliśmy ząbek dodajemy lub odejmujemy do częstotliwości wartość kroku (na razie na sztywno 100Hz)
if(enc_sum >= pulses_for_groove){
czestotliwosc = czestotliwosc + 100; //docelowo czestotliwosc = czestotliwosc + krok
AD9850.set_frequency(czestotliwosc); //ustawiam syntezę na odpowiedniej częstotliwości
show_frequency(); //drukuję częstotliwość na wyświetlaczu za pomocą gotowej funkcji
enc_sum = 0; //reset zmiennej zliczającej impulsy enkodera
}
if(enc_sum <= -(pulses_for_groove)){
czestotliwosc = czestotliwosc - 100; //docelowo czestotliwosc = czestotliwosc - krok
AD9850.set_frequency(czestotliwosc); //ustawiam syntezę na odpowiedniej częstotliwości
show_frequency(); //drukuję częstotliwość na wyświetlaczu za pomocą gotowej funkcji
enc_sum = 0; //reset zmiennej zliczającej impulsy enkodera
}
delayMicroseconds(5); //małe opóźnienie dla prawidłowego działania enkodera
}
RE: Fork-Heńka... czyli jak sobie poradzić z DDS za pomocą ARDUINO - SP6IFN - 12-10-201420:01
Wszystko jasne. Po poprawce jest dobrze. Pewnie też już myślałeś o poprawce wyświetlania częstotliwości, bo u mnie dla 10MHz wyświetlanej częstotliwości jest za dużo aż o 440 Hz. Ale może wyprzedzam zbytnio. Koledzy też muszą przećwiczyć swoje Arduino.
Rysio!
RE: Fork-Heńka... czyli jak sobie poradzić z DDS za pomocą ARDUINO - SQ9MDD - 12-10-201420:08
Ryśku chodzi Ci o kalibrację DDS-a? Odchyłka zależy od danej sztuki, ale jest na to sposób, tyle że to nie teraz.
Myślę że na razie musimy się skupić na tym by każdy zainteresowany odpalił syntezę, by wszystko działało a jak już napiszemy coś sensownego obsługowo to ten ważny detal, też ogarniemy.
No dobra Panowie kto jest z nami i jakie macie postępy?
RE: Fork-Heńka... czyli jak sobie poradzić z DDS za pomocą ARDUINO - SP6IFN - 12-10-201420:25
Tak też myślałem. Czekamy więc na postęp prac u zainteresowanych. Przyznam się też że mam już działającą syntezę z tym wyświetlaczem. Oprogramowanie jest takie samo jak w syntezie o której pisałem w wątku o Arduino (praca konkursowa PUK z 2013r), przystosowane do wyświetlacza Nokia5110. Ale syntez nigdy za wiele......ta będzie zapewne lepsza, bo wypracowana większymi siłami.
Rysio!
RE: Fork-Heńka... czyli jak sobie poradzić z DDS za pomocą ARDUINO - SQ9MDD - 14-10-201422:19
Hejka Panowie... mam nadzieję że jesteście z nami, bo coś ucichło.
W dzisiejszym odcinku ogarniania arduino i DDS-a zajmiemy się zmianą kroku syntezy.
No bo co to za synteza jak by kroku się zmienić nie dało.
W poprzednich wersjach krok był zapisany na sztywno i stanowił 100Hz. Wyglądało to tak że po wykryciu ząbka na enkoderze do bieżącej wartości częstotliwości dodawaliśmy lub odejmowaliśmy 100Hz:
Kod:
czestotliwosc = czestotliwosc + 100;
czestotliwosc = czestotliwosc - 100;
Teraz będziemy to robić nieco inaczej:
Kod:
frequency = frequency + step_value;
frequency = frequency - step_value;
Oczywiście by to zadziałało musimy zmienną "step_value" wcześniej zadeklarować:
Kod:
long step_value = 100;
Zmienna ta jest typu long by uniknąć niespodzianek nieoczekiwanej konwersji typu zmiennych.
Ok mamy zmienną która przechowa wartość kroku syntezy ale musimy napisać obsługę zmiany tego kroku. Zrobimy to za pomocą wejścia A2. Oczywiście każdy może użyć dowolnego innego wejścia.
Po pierwsze musimy zdefiniować zmienną która przechowa numer używanego przez nas portu:
Kod:
const int step_input = A2;
Następnie w funkcji setup musimy ustawić odpowiedni typ wejścia:
Kod:
pinMode(step_input,INPUT_PULLUP);
I tutaj słowo wyjaśnienia, INPUT_PULLUP oznacza że wejście jest wewnętrznie podciągnięte do +5V więc łatwo wykryjemy zmianę stanu gdy zewrzemy je do masy.
Następny krok to stworzenie funkcji pokazującej bieżący krok syntezera:
Kod:
void show_step(){
lcd.setFont(SmallFont); //ustawiamy czcionkę
sprintf(buffor,"%08lu",step_value); //konwersja danych do wyświetlenia (ładujemy longa do stringa
lcd.print(buffor,CENTER,8); //wyświetlamy dane na lcd (8 oznacza drugi rząd)
}
A gdy już wszystko mamy gotowe musimy obsłużyć przyciśnięcie przycisku w pętli głównej programu:
Kod:
//obsługa klawisza zmiany kroku
if(digitalRead(step_input) == LOW){ //sprawdzanie czy przycisk jest wcisnięty
delay(100); //odczekajmy 100msec
if(digitalRead(step_input) == LOW){ //jeśli klawisz nadal jest wcisnięty (czyli nie są to zakłócenia)
switch(step_value){ //za pomocą instrukcji swich zmieniamy krok
case 100000: //jeśli krok jest 100kHz ustaw 100Hz
step_value = 100;
break;
case 10000: //jeśli krok jest 10kHz ustaw 100kHz
step_value = 100000;
break;
case 1000: //jeśli krok jest 1kHz ustaw 10kHz
step_value = 10000;
break;
case 100: //jeśli krok jest 100Hz ustaw 1kHz
step_value = 1000;
break;
}
}
show_step(); //pokazuję zmianę kroku na lcd
delay(300); //zwłoka po zmianie kroku 300msec
}
Używamy tutaj dwóch instrukcji if oraz instrukcji switch. Te dwie instrukcje if służą wykrywaniu wciśnięcia klawisza i eliminują drgania przycisku, natomiast instrukcja switch służy już konkretnie zmianie kroku.
Oczywiście sposób wyświetlania danych na wyświetlaczu nie jest idealny ale póki co zajmujemy się poprawnym ustawieniem mechanizmów pracy syntezera a kosmetykę zostawimy sobie na później.
Poniżej pełny kod po modyfikacjach i spakowane źródło.
Następny odcinek poświęcimy ograniczeniu pracy syntezera do zdefiniowanych widełek częstotliwości górnej i dolnej...
Kod:
//************************************************************************//
// Złomek - kumpel Heńka, projekt pogladowy obsługi DDS AD9850,
// wyświetlacza nokii 5110 i jakiegoś enkodera.
// Projekt otwarty http://sp-hm.pl
// SQ9MDD - początkowy szkielet programu v 1.0.0
// S_____ -
// S_____ -
//
//************************************************************************//
/* CHANGELOG (nowe na górze)
2014.10.14 - zmiana kroku syntezy
2014.10.12 - początek projektu wspólnego na sp-hm.pl
wymiana biblioteki wyświetlacza lcd na LCDD5110 basic
2014.05.22 - pierwsza wersja kodu warsztaty arduino w komorowie.
*/
//************************************************************************//
//podłączamy bibliotekę syntezera
#include <AH_AD9850.h>
//inicjalizujemy enkoder
//AO - w lewo
//A1 - w prawo
//nalezy pamiętać o kondensatorach (100nF) pomiędzy liniami encodera a masą
RotaryEncoder encoder(A0,A1,5,6,1000);
//zmienne do modyfikacji
const int kontrast = 70; //kontrast wyświetlacza
const int pulses_for_groove = 2; //ilość impulsów na ząbek enkodera zmienić w zależności od posiadanego egzemplarza
const int step_input = A2; //wejście do podłączenia przełącznika zmiany kroku
//zmienne wewnętrzne,
//jeśli nie trzeba proszę nie modyfikować
char buffor[] = " "; //zmienna pomocnicza do wyrzucania danych na lcd
long frequency = 10000000; //zmienna dla częstotliwości, wstawiamy tam częstotliwość od której startujemy
long step_value = 100; //domyślny krok syntezy
int enc_sum = 0; //zmienna pomocnicza do liczenia impulsów z enkodera
//funkcja do zmiany kroku syntezy
//funkcja do obsługi wyświetlania zmiany częstotliwości
void show_frequency(){
lcd.setFont(SmallFont); //ustawiamy czcionkę
sprintf(buffor,"%08lu",frequency); //konwersja danych do wyświetlenia (ładujemy longa do stringa
lcd.print(buffor,CENTER,0); //wyświetlamy dane na lcd
}
//funkcja do wyświetlania aktualnego kroku syntezera
void show_step(){
lcd.setFont(SmallFont); //ustawiamy czcionkę
sprintf(buffor,"%08lu",step_value); //konwersja danych do wyświetlenia (ładujemy longa do stringa
lcd.print(buffor,CENTER,8); //wyświetlamy dane na lcd (8 oznacza drugi rząd)
}
// setup funkcja odpalana przy starcie
void setup(){
Serial.begin(9600); //uruchamiam port szeregowy w celach diagnostycznych
AD9850.set_frequency(0,0,frequency); //odpalamy syntezer i ustawiamy częstotliwość startową
delay(1000); //sekunda opóźnienia
lcd.InitLCD(kontrast); //odpalamy lcd ustawiamy kontrast
show_frequency(); //pokazmy cos na lcd
pinMode(step_input,INPUT_PULLUP); //inicjalizujemy wejście zmiany kroku i podciągamy je do plusa
show_step();
}
void loop(){
int enc = encoder.readEncoder(); //czytamy wartość z encodera
if(enc != 0) { //jeśli wartość jest inna niż zero sumujemy
enc_sum = enc_sum + enc; //jeden ząbek encodera to +2 lub -2 tutaj to zliczam
Serial.println(enc); //wyrzucamy na port rs-232 wartość licznika enkodera (debugowanie)
}
//obsługa klawisza zmiany kroku
if(digitalRead(step_input) == LOW){ //sprawdzanie czy przycisk jest wcisnięty
delay(100); //odczekajmy 100msec
if(digitalRead(step_input) == LOW){ //jeśli klawisz nadal jest wcisnięty (czyli nie są to zakłócenia)
switch(step_value){ //za pomocą instrukcji swich zmieniamy krok
case 100000: //jeśli krok jest 100kHz ustaw 100Hz
step_value = 100;
break;
case 10000: //jeśli krok jest 10kHz ustaw 100kHz
step_value = 100000;
break;
case 1000: //jeśli krok jest 1kHz ustaw 10kHz
step_value = 10000;
break;
case 100: //jeśli krok jest 100Hz ustaw 1kHz
step_value = 1000;
break;
}
}
show_step(); //pokazuję zmianę kroku na lcd
delay(300); //zwłoka po zmianie kroku 300msec
}
//jesli zaliczyliśmy ząbek dodajemy lub odejmujemy do częstotliwości wartość kroku (na razie na sztywno 100Hz)
if(enc_sum >= pulses_for_groove){
frequency = frequency + step_value; //docelowo frequency = frequency + krok
AD9850.set_frequency(frequency); //ustawiam syntezę na odpowiedniej częstotliwości
show_frequency(); //drukuję częstotliwość na wyświetlaczu za pomocą gotowej funkcji
enc_sum = 0; //reset zmiennej zliczającej impulsy enkodera
}
if(enc_sum <= -(pulses_for_groove)){
frequency = frequency - step_value; //docelowo frequency = frequency - krok
AD9850.set_frequency(frequency); //ustawiam syntezę na odpowiedniej częstotliwości
show_frequency(); //drukuję częstotliwość na wyświetlaczu za pomocą gotowej funkcji
enc_sum = 0; //reset zmiennej zliczającej impulsy enkodera
}
delayMicroseconds(5); //małe opóźnienie dla prawidłowego działania enkodera
}
RE: Fork-Heńka... czyli jak sobie poradzić z DDS za pomocą ARDUINO - SP6IFN - 14-10-201423:47
No i pięknie. Wprowadziłem już u siebie nową wersję softu, no i DZIAŁA wszystko jak należy. Wielkie GRATULACJE, bo ładnie to wszystko opisane, można kombinować też po swojemu. Ciekawy jestem bardzo czy jest zainteresowanie tym projektem? Boję się że prowadzący może się zdegustować i zrezygnować z dalszego prowadzenia, a tego bym bardzo nie chciał. Ładnie jak na razie się zapowiada. Co Koledzy na to?
Rysio!
RE: Fork-Heńka... czyli jak sobie poradzić z DDS za pomocą ARDUINO - M0OSH - 15-10-20141:02
U mnie działa musiałem tylko zmienić wartość encodera i kontrast ustawić na 65
Mocno kibicuję projektowi
Wojtek M0OSH
RE: Fork-Heńka... czyli jak sobie poradzić z DDS za pomocą ARDUINO - SQ6IYY - 15-10-20147:29
Witam rano dzieci do szkole auto w mechanika od 14 do prace i tak mam od 1.5 tygodnia Uno lcd synteza czeka na podpięcie pozdrawiam gonie do szkoły