Poszukując jakiejś alternatywy dla HD44780 natknąłem się przez przypadek na wyświetlacz firmy Electronic Assembly oparty na mało znanym kontrolerze SSD1803A. Wyświetlacz przykuł moją uwagę raz z uwagi na dedykowane zasilanie 3.3 V co w kontekście mikrokontrolerów PIC jest mile widziane a dwa z uwagi na piękne podświetlenie w kolorze bursztynowym. Wyświetlacz jest po za tym bardzo subtelny , grubość zaledwie 2 mm i jest prawie przezroczysty. Do dyspozycji mamy 4 linie po 20 znaków.
Podstawową zaletą jest możliwość zasterowania w kilku trybach : 8bit / 4bit / SPI / I2C, do wyboru do koloru. Poza tym fajne jest wyprowadzenie pinów w postaci szpilek, które bezpośrednio można wlutować w płytkę docelową lub wetknąć w płytkę stykową.
Ze wstępnej analizy materiałów wynika, że wyświetlacz jest bardzo szybki.
Czasy zapisu do sterownika są rzędu pojedyńczych nanosekund. Wygląda na to , że mamy do czynienia z rakietą.
Delikatnym minusem lub plusem w zależności od punktu widzenia jest konieczność dokupienia płytki podświetlającej . W podstawowej wersji kupujemy tylko sam wyświetlacz bez podświetlenia. Ponieważ kontrast jest imponujący dlatego za dnia podświetlenie jest zbędne.Płytka podświetlająca występuje w kilku opcjach kolorystycznych , mnie najbardziej spodobał się kolor bursztynowy.
Przejdźmy do konkretów. Poniżej schemat podłączeń.
Korzystamy z trybu 4-bitowego (IM1 i IM2 do +3.3 V). Ale pamiętajmy , że mamy jeszcze do dyspozycji SPI , I2C, 8-bitów. Do sterowania w trybie 4-bitowym potrzebujemy łącznie osiem pinów mikrokontrolera. Przy czym pin RW, służący do wyboru zapis/odczyt do sterownika SSD1803A, pomijamy (w programie), no chyba , że chcemy bawić się w sprawdzanie flagi zajętości ale ja ten aspekt dla uproszczenia pomijam.
Opis podłączenia wyświetlacza do mikrokontrolera PIC24HJ128GP502 :
E --> RB2
RW --> RB3 (nie będziemy korzystać w programie ale podłączamy)
RS --> RA2
RESET --> RA0
DB7 --> RB15
DB6 --> RB14
DB5 --> RB13
DB3 --> RB12
E - przed wysłaniem danych/instrukcji ustawiamy na 1 po zakończeniu wysyłania danych/instrukcji ustawiamy na 0.
RS - rejestr instrukcji - 0 / rejestr danych - 1
W zasadzie sama obsługa programowa nie wiele się różni od obsługi HD44780.
Po włączeniu zasilania, inicjalizacja (łącznie z uwzględnieniem stabilizacji napięć) trwa ok 16 ms.
Inicjalizacja w trybie 4-bitowym wygląda tak :
1. Włączenie zasilania
2. Delay 5 ms
3. Hardware Reset 10 ms (RESET --> 0)
4. Delay 1 ms
5 Wysyłamy kolejno (wartości HEX) :
- 0x33 / 0x32 / 0x2A / 0x09 / 0x06 / 0x1E / 0x29 / 0x1B / 0x6E / 0x57 / 0x72 / 0x28 / 0x0F
Jeśli wszystko podłączyliśmy poprawnie po procedurze inicjalizacji zobaczymy migający kursor.
Wyświetlacz bez żadnych dąsów się inicjalizuje. Sterowanie zapisem do rejestru danych i rozkazów oraz definiowanie własnych znaków przebiega identycznie jak w HD44780 więc dużo roboty odpada w programie. Warto nadmienić , że wyświetlana czcionka jest ładna i prezentuje się bardzo profesjonalnie.
Podsumowując uważam , że prezentowany wyświetlacz jest idealną wręcz propozycją w świecie 3.3 V i wyświetlaczy znakowych. Praca z nim to czysta przyjemność.
Zalety to : dedykowane zasilanie 3.3 V, zajmuje mało miejsca w porównaniu do kobylastych HD44780, kilka interfejsów komunikacyjnych, bardzo duża szybkość pracy (wyświetlanie nie przytka głównej pętli programu),prosta inicjalizacja, duża czytelność znaków nawet bez podświetlenia, bardzo dobre i równe podświetlenie (6 diod LED), szpilki ułatwiające montaż. Inne jeszcze nie odkryte :)
Wady : cena ok 135 zł z płytką podświetlającą, płytkę podświetlającą trzeba dokupić osobno.
Program : inicjalizuje wyświetlacz, definiuje literkę "ę", wyświetla napis.
Pozdrawiam
picmajster.blog@gmail.com
Link :
DOGM204-A - mini datasheet
SSD1803A - datasheet
Wyświetlacze EA DOGM
/*************************
File: ustaw_zegar.h
*************************/
#ifndef USTAW_ZEGAR_H
#define USTAW_ZEGAR_H
#define FCY 40000000 /* podajemy wartosc ustawionego zegara (40 MHz), wazne
aby przed includowaniem <libpic30.h>, potrzebne to jest do wyliczania delay-i*/
/*deklaracja funkcji*/
void ustaw_zegar(void) ;
#endif /* USTAW_ZEGAR_H */
/*************************
File: dogm204.h
*************************/
#ifndef LCD_H
#define LCD_H
/*_TRISB3 --> TRISBbits.TRISB3*/
#define TRIS_RESET _TRISA0
#define TRIS_RW _TRISB3
#define TRIS_RS _TRISA2
#define TRIS_E _TRISB2
#define TRIS_DB4 _TRISB12
#define TRIS_DB5 _TRISB13
#define TRIS_DB6 _TRISB14
#define TRIS_DB7 _TRISB15
/*_RB3 --> PORTBbits.RB3*/
#define RESET _RA0
#define RW _RB3
#define RS _RA2
#define E _RB2
#define DB4 _RB12
#define DB5 _RB13
#define DB6 _RB14
#define DB7 _RB15
/* przyporzadkowanie adresow pamieci DD-RAM do pol wyswietlacza*/
#define LCD_Line1 0x00 /*adres 1 znaku 1 wiersza */
#define LCD_Line2 0x20 /*adres 1 znaku 2 wiersza */
#define LCD_Line3 0x40 /*adres 1 znaku 3 wiersza */
#define LCD_Line4 0x60 /*adres 1 znaku 4 wiersza */
void Wyslij_do_LCD(unsigned char bajt);
void WlaczLCD();
void WyswietlLCD(char *napis);
void UstawKursorLCD(uint8_t y, uint8_t x);
void CzyscLCD();
void WpiszSwojeZnaki(void);
void DefineCharacter(int8_t nr, char *znak)
void DefineCharacter(int8_t nr, char *znak)
#endif /* LCD_H */
/************************
File: ustaw_zegar.c
************************/
/*Ustawiamy zegar wewnetrzny na ok 40 MHz (dokladnie na 39.61375 MHz*/
#include "xc.h" /* wykrywa rodzaj procka i includuje odpowiedni plik
naglówkowy "p24HJ128GP502.h"*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h> /*dyrektywy do uint8_t itp*/
#include "ustaw_zegar.h" /*z uwagi na FCY musi byc przed #include <libpic30.h>*/
/*definicja funkcji*/
void ustaw_zegar(void) {
/*
* to co mozemy ustawic za pomoca '#pragma' jest dostepne w pliku
* xc16/docs/config_index.html
*/
#pragma config JTAGEN = OFF
// Watchdog timer enable/disable by user software
#pragma config FWDTEN = OFF
//********************Start Ustawien Zegara************************
/*
* Fcy - zegar instrukcji , Fosc - zegar rdzenia (jest zawsze dwa razy wiekszy
* od zegara instrukcji)) Ustawiamy zegar instrukcji na 40 Mhz z wewnetrznego
* oscylatora Fin=7.37 MHz w/g wzoru Fcy=Fosc/2 gdzie Fosc=Fin x (M/(N1+N2))
* gdzie M=43, N2=2, N1=2 ustawiane w rejestrach PLLFBD/PLLPOST/PLLPRE
*/
//Select Internal FRC (Fast RC Oscillator)
#pragma config FNOSC = FRC // FOSCSEL-->FNOSC=0b000 (Fast RC Oscillator (FRC))
//Enable Clock Switching and Configure
#pragma config FCKSM = CSECMD //FOSC-->FCKSM=0b01 - wlacz zegar
#pragma config OSCIOFNC = OFF //FOSC-->OSCIOFNC=1 - Fcy b?dzie na pinie OSCO
/*Config PLL prescaler, PLL postscaler, PLL divisor*/
PLLFBD = 41 ; //M=43 (0 bit to 2 st?d 41 = 43 patrz w rejestrze), tutaj 3.685 x 43 = 158.455MHz
CLKDIVbits.PLLPRE=0 ; //N1=2, tutaj 7.37 MHz / 2 = 3.685 MHz
CLKDIVbits.PLLPOST=0 ; //N2=2, tutaj 158.455 MHz / 2 = 79.2275 MHz (Fosc)
/*
* UWAGA przerwania musza byc wylaczone podczas wywolywania ponizszych
* dwóch funkcji __builtin_write_...brak definicji w pliku naglówkowym
* to wewnetrzne funkcje kompilatora patrz help M-LAB IDE
* i datasheet str 140(11.6.3.1 Control Register Lock)
*/
/*Initiate Clock Switch to Internal FRC with PLL (OSCCON-->NOSC = 0b001)*/
__builtin_write_OSCCONH(0x01); //tutaj argumentem jest wartosc z NOSC
/*Start clock switching*/
__builtin_write_OSCCONL(0x01);
/*Wait for Clock switch to occur*/
while(OSCCONbits.COSC !=0b001);
/*Wait for PLL to lock*/
while(OSCCONbits.LOCK !=1) {};
}
/*************************
File: dogm204.c
*************************/
#include "xc.h" /* wykrywa rodzaj procka i includuje odpowiedni plik*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h> /*dyrektywy uint8_t itp*/
#define FCY 40000000UL /* podajemy wartosc ustawionego zegara (40 MHz), wazne
aby przed includowaniem <libpic30.h>, potrzebne to jest to wyliczania delay-i*/
#include <libpic30.h> /*biblioteka dajaca dostep do delay-i.*/
#include "dogm204.h"
/*definicje funkcji*/
void Wyslij_do_LCD(unsigned char bajt)
{
/*ustaw linie EN, przed wysylka danych*/
E = 1;
/*wyslanie 4 najstarszych bitow danych*/
if(bajt & 0x80) DB7 = 1; else DB7 = 0;
if(bajt & 0x40) DB6 = 1; else DB6 = 0;
if(bajt & 0x20) DB5 = 1; else DB5 = 0;
if(bajt & 0x10) DB4 = 1; else DB4 = 0;
__delay_us(1);
/*potwierdzenie wyslania danych (opadajacym zboczem EN)*/
E = 0;
/*ustaw linie EN, przed wysylka danych*/
__delay_us(1);
E = 1;
/*wyslanie 4 najmlodszych bitow danych*/
if(bajt & 0x08) DB7 = 1; else DB7 = 0;
if(bajt & 0x04) DB6 = 1; else DB6 = 0;
if(bajt & 0x02) DB5 = 1; else DB5 = 0;
if(bajt & 0x01) DB4 = 1; else DB4 = 0;
__delay_us(1);
/*potwierdz wysylke danych opadajacym zboczem EN*/
E = 0;
__delay_us(16);
}
void WlaczLCD()
{
/*ustawienie kierunku wyjsciowego linii podlaczonych do LCD*/
TRIS_RESET = 0 ;
TRIS_RW = 0 ;
TRIS_RS = 0;
TRIS_E = 0;
TRIS_DB7 = 0;
TRIS_DB6 = 0;
TRIS_DB5 = 0;
TRIS_DB4 = 0;
/*zerowanie linii*/
RESET = 1 ; /* 0 - Stan aktywny*/
RW = 0 ;
RS = 0; /* 0 - wskazuje na rejestr rozkazow / 1 - wskazuje na rejestr danych*/
E = 0;
DB7 = 0;
DB6 = 0;
DB5 = 0;
DB4 = 0;
/*Start Inicjalizacji DOGM204 tryb 4-bity*/
/*zaczekaj co najmniej 5 ms na ustabilizowanie sie napiecia*/
__delay_ms(5);
/*Hardware Reset 10ms*/
RESET = 0 ;
__delay_ms(10);
RESET = 1 ;
__delay_ms(1);
/*Sekwencja startowa dla trybu 4-bit, patrz mini-datasheet str 5*/
Wyslij_do_LCD(0x33);//wysylamy instrukcje do rejestru rozkazow
Wyslij_do_LCD(0x32);
Wyslij_do_LCD(0x2A);
Wyslij_do_LCD(0x09);
Wyslij_do_LCD(0x06);
Wyslij_do_LCD(0x1E);
Wyslij_do_LCD(0x29);
Wyslij_do_LCD(0x1B);
Wyslij_do_LCD(0x6E);
Wyslij_do_LCD(0x57);
Wyslij_do_LCD(0x72);
Wyslij_do_LCD(0x28);
Wyslij_do_LCD(0x0F); /*Display on, cursor on, blink on*/
CzyscLCD();
RS = 1 ; /*przelacz na rejestr danych*/
/*Koniec inicjalizacji i ustawien wyswietlacza DOGM204*/
}
void WyswietlLCD(char *napis)
{
while(*napis){
Wyslij_do_LCD(*napis++);
}
}
void UstawKursorLCD(uint8_t y, uint8_t x)
{
uint8_t n ;
/*y (wiersze) = 1 do 4*/
/*x (kolumna) = 1 do 20*/
/*ustal adres poczatku znaku w wierszu*/
switch(y)
{
case 1: y = LCD_Line1 ;break;
case 2: y = LCD_Line2 ;break;
case 3: y = LCD_Line3 ;break;
case 4: y = LCD_Line4 ;break;
}
/*ustal nowy adres pamieci DD RAM*/
/*ustaw bajt do Set DDRAM adres*/
/* x odejmujemy jeden aby przekonwertowac z 0-19 na 1-20 */
n = 0b10000000 + y + (x-1) ;
/*wyslij rozkaz ustawienia nowego adresu DD RAM*/
RS = 0; /*stan niski na linii RS, wybieramy rejestr instrukcji*/
Wyslij_do_LCD(n);
RS = 1; /*przelacz na rejestr danych */
}
void CzyscLCD()
{
RS = 0; /*przelacz na rejestr rozkazow*/
Wyslij_do_LCD(1);
RS = 1; /*przelacz na rejestr danych*/
__delay_us(1);
}
void WpiszSwojeZnaki(void) {
/*definicja wlasnych znaków maks 8 szt*/
char znak1[]= {0,0,14,17,31,16,14,2}; /* definicja literki e z ogonkiem */
int i;
/* adresy poczatku definicji znaku to wielokrotnosc osmiu DEC(0,8,16,24,32,40,48,56)
* ale uwaga wazne ! adresy kodowane sa na 6 mlodszych bitach dwa najstarsze bity
* to zawsze 01 (01AAAAAA-gdzie A adres).Uwzgledniajac wartosc calego bajtu
* adresy poczatku beda wygladal tak HEX(0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78)
* Aby wpisac do pamieci wyswietlacza zdefiniowany znak nalezy najpierw wyslac
* do rejestru rozkazów (RS na 0) adres poczatku definicji znaku
* a w drugim kroku przesylamy dane (RS=1) 8 x bajt (tablica) definjujace obraz znaku*/
RS = 0 ;/*stan niski na linii RS, wybieramy rejestr instrukcji*/
/*wysylamy instrukcje do rejestru rozkazow (ustaw adres poczatkowy w CGRAM
na nasz znak w tym przypadku znak na pozycji drugiej) */
Wyslij_do_LCD(0x48);/*wysylamy instrukcje do rejestru rozkazow
(ustaw adres poczatkowy w CGRAM na nasz znak w tym przypadku znak na pozycji drugiej) */
RS = 1 ;/*stan wysoki na linii RS, wybieramy rejestr danych*/
/*wysylamy 8 x bajt zdefiniowanego w tablicy znak1[] znaku*/
for(i=0;i<=7;i++)
{
Wyslij_do_LCD(znak1[i]);
}
RS = 0 ;/*stan niski na lini RS, wybieramy rejestr instrukcji*/
/*ustawiamy adres DDRAM na pierwszy znak w pierwszej linii, nie zapomnijmy
o tym poniewaz inaczej zostaniemy w pamieci CGRAM*/
Wyslij_do_LCD(0x80);
RS = 1 ; /*stan wysoki na linii RS, wybieramy rejestr danych*/
}
/*funkcja uniwersalna do definiowania znaku*/
void DefineCharacter(int8_t nr, char *znak)/*nr 0...7, *znak to wskaznik na tablice z danymi*/
{
int i;
/* adresy poczatku definicji znaku to wielokrotnosc osmiu DEC(0,8,16,24,32,40,48,56)
* ale uwaga wazne ! adresy kodowane sa na 6 mlodszych bitach dwa najstarsze bity
* to zawsze 01 (01AAAAAA-gdzie A adres).Uwzgledniajac wartosc calego bajtu
* adresy poczatku beda wygladal tak HEX(0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78)
* Aby wpisac do pamieci wyswietlacza zdefiniowany znak nalezy najpierw wyslac
* do rejestru rozkazów (RS na 0) adres poczatku definicji znaku
* a w drugim kroku przesylamy dane (RS=1) 8 x bajt (tablica) definjujace obraz znaku*/
RS = 0 ;/*stan niski na linii RS, wybieramy rejestr instrukcji*/
/*wysylamy instrukcje do rejestru rozkazow*/
Wyslij_do_LCD((nr*8)|CGRAM_SET);/*ustaw adres poczatkowy w CGRAM na nasz znak*/
RS = 1 ;/*stan wysoki na linii RS, wybieramy rejestr danych*/
/*wysylamy 8 x bajt zdefiniowanego w tablicy znak[] znaku*/
for(i=0;i<=7;i++)
{
Wyslij_do_LCD(*znak++);
}
RS = 0 ;/*stan niski na lini RS, wybieramy rejestr instrukcji*/
/*ustawiamy adres DDRAM na pierwszy znak w pierwszej linii, nie zapomnijmy
o tym poniewaz inaczej zostaniemy w pamieci CGRAM*/
Wyslij_do_LCD(0x80);
RS = 1 ; /*stan wysoki na linii RS, wybieramy rejestr danych*/
/*definiowanie znaku DefineCharacter(1,tablica) gdzie nr 0...7 a tablica to
np char tablica[]= {0x0C,0x12,0x12,0x0C,0,0,0,0} definicja stC*/
/*wywolanie zdefiniowanego znaku Wyslij_do_LCD(nr) gdzie nr to 0...7 lub
WyswietlLCD("\nr"*/
}
/*************************
File: main.c
*************************/
/*wyswietlacz DOGM204-A (4x20) firmy Electronic Assembly*/
#include "xc.h" /* wykrywa rodzaj procka i includuje odpowiedni plik naglowkowy "p24HJ128GP502.h"*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h> /*dyrektywy uint8_t itp*/
#include "ustaw_zegar.h" /*tutaj m.in ustawione FCY*/
#include <libpic30.h> // biblioteka dajaca dostep do delay-i.
#include "dogm204.h"
char napis[] = "Kocham Monik""\x01"; /* "\x01" to zapis kodu ASCII dla zdefiniowanej
literki e z ogonkiem. Dla wlasnych znaków mamy zarezerwowane kody ASCII od 0 do 7,
przyczym aby uzywac podanego sposobu wstawiania wlasnych znaków w stringa, nie mozemy
uzywac kodu ASCI 0, czyli zamiast 8 znaków korzystamy z 7 (od 1 do 7)*/
int main(void) {
ustaw_zegar();/*odpalamy zegar na ok 40MHz*/
PMD1bits.AD1MD=1; //wylaczamy ADC
AD1PCFGL = 0x1E3F; //wylaczenie linii analogowych(wszystkie linie cyfrowe)
WlaczLCD(); //inicjalizacja wyswietlacza LCD
WpiszSwojeZnaki(); //wpisz do CGRAM-u definicje znaku e z ogonkiem
UstawKursorLCD(1,4);
WyswietlLCD(napis); //wyswietl napis z tablicy napis[]
while(1)
{
/*Glowna Petla Programu*/
}
return 0;
}
-------------------------------------------------------------------------------------------------------------------------------------
Poniżej KOD dla ARDUINO napisany przez kolegę z Niemiec.
/* Init file for EA DOGM204-A (2018/2) dg9fdu@web.de
Arduino UNO and NANO compatible */
#include <LiquidCrystal.h>
int a=0;
int Eneble =4;
// Display connect PORTD
const int rs = 5, en = 4, d4 = 0, d5 = 1, d6 = 2, d7 = 3;
// set R/W DOGM of GND
// set Reset DOGM of GND or Pin6 with Prg.
LiquidCrystal lcd(rs,en,d4,d5,d6,d7);
void setup() {
DDRD = B11111111; // Pin 0 - 8 PORTD
pinMode(Eneble,OUTPUT);
lcd.begin (16,2); // !!!!!not (20,4)!!!!!!
lcd.setCursor(0,0);
lcd.print ("Test");
delay(50);
Init() ; ///Init Display
}
void loop(){
lcd.setCursor(7,2);
lcd.print ("Test-123456");
delay(1000);
}
void Init(){
if (a=0) goto Label;
PORTD =B00000011; // 8-Bit
pulse();
delay(50);
PORTD =B00000011; // 8-Bit
pulse();
delay(50);
PORTD =B00000011; // 8-Bit
pulse();
delay(50);
PORTD =B00000011; // 8-Bit
pulse();
delay(50);
PORTD =B00000011; //set 4-Bit Switch
pulse();
PORTD =B00000010;
pulse();
delay(50);
PORTD =B00000010; // set Bit Data length
pulse();
PORTD =B00001010;
pulse();
PORTD =B00000000; // set 4-Linien
pulse();
PORTD =B00001001;
pulse();
PORTD =B00000000; //Entrie Mode
pulse();
PORTD =B00000110; // Display normal
//PORTD =B00000100; ///Display drehen
pulse();
PORTD =B00000001; // set Bias
pulse();
PORTD =B00001110;
pulse();
PORTD =B00000010; //st Funktion
pulse();
PORTD =B00001001;
pulse();
PORTD =B00000001; //Internal OSC
pulse();
PORTD =B00001011;
pulse();
PORTD =B00000110; //Follower Contr.
pulse();
PORTD =B00001110;
pulse();
PORTD =B00000101; //Power Contr.
pulse();
PORTD =B00000111;
pulse();
PORTD =B00000111; //Contrast
pulse();
PORTD =B00000010;
pulse();
PORTD =B00000010; //Funtion set
pulse();
PORTD =B00001000;
pulse();
PORTD =B00000000; // Cuorsor on
pulse();
PORTD =B00001111;
pulse();
PORTD =B00100000;
Label:
a=0;
}
void pulse(){
delay(10);
digitalWrite(Eneble, HIGH);
delay(10);
digitalWrite(Eneble, LOW);
}
Witaj,
OdpowiedzUsuńna schemacie brakuje podłączenia VDD wyświetlacza do +3,3V.
Bardzo dziękuję poprawione.
UsuńFajny LCDek, ale z tego co widziałem - jego cena zabija :/ widziałem po ~60zł - za to można mieć ciekawsze, nawet kolorowe. Można wiedzieć gdzie swoje kupiłeś?
OdpowiedzUsuńTak cena to jedyna wada tego wyświetlacza ale jak się już raz z nim zaprzyjaźni to z obrzydzeniem na HD44780 się patrzy. Kupiłem tutaj https://www.elfadistrelec.pl/pl/wyswietlacz-lcd-matrycowo-punktowy-82-mm-20-electronic-assembly-ea-dogm204w/p/30051753?queryFromSuggest=true
OdpowiedzUsuńWonderful blog! I found it while surfing around on Yahoo News.
OdpowiedzUsuńDo you havfe any suggesxtions on how to get listed in Yahoo News?
I've been trying for a while but I never seem to get there!
Appreciate it
Thank you for the kind words . The blog exists from January 2017.
OdpowiedzUsuńRegards
PICmajster
Someone necessarily assist to make seriously articles
OdpowiedzUsuńI might state. This is the very first time I frequented your web page and up to now?
I amazed with the analysis you made to make this particular put
up extraordinary. Fantastic activity!
Thank you for your kind words
OdpowiedzUsuńI blog often and I genuinely thank you for your content.
OdpowiedzUsuńThe article has really peaked my interest. I am going to
take a note of your website and keep checking for new
information about once per week. I subscribed to your RSS
feed as well.
Excellent article. Keep posting such kind of info on your site.
OdpowiedzUsuńIm really impressed by your site.
Hey there, You have done a fantastic job. I will definitely digg it and individually recommend to my friends.
I'm confident they'll be benefited from this website.