Připojte řadič ENC28J60 k desce FRDM-KL25Z, zprovozněte TCP/IP stack a vytvořte jednoduchý TELNET server, pomocí kterého bude možné příkazy ovládat RGB LED.
Projekt je navržen na vývojové desce FRDM-KL25Z od společnosti Freescale. Tato vývojová deska má na sobě již implementovanou RGB LED diodu, která bude v projektu použita. Ethernetový řadič ENC28J60 je použitý v podobě kitu určeného pro Arduino a již obsahuje všechny podpůrné součástky. Zároveň má na hřebínek vyvedeny komunikační piny. Obvod komunikuje pomocí sběrnice SPI. Celé zapojení tedy spočívá pouze v propojení SPI komunikačních pinů. KL25Z má implementovány dvě SPI sběrnice (SPI_0, SPI_1). Je použita SPI_0 s piny které zobrazuje obrázek 1 s menší obměnou u SCK pinu. Je totiž společný pro modrou diodu, která slouží jako signalizace komunikace. Tím by byla modrá dioda blokována, a proto je použit pin PTC5. Všechny použite piny na vývojové desce shrnuje následující tabulka.
obr.1 Pinout vývojové desky FDRM-KL25Z
obr.2 Arduino kit ENC28J60
FDRM-KL25Z | ENC28J60 |
---|---|
PTD3 | MISO |
PTD2 | MOSI |
PTC5 | SCK |
PTD0 | CS |
3V3 | VCC |
GND | GND |
Řídicí program je psán a kompilován ve webovém vývojovém prostředí mbed.org . Tento výběr byl učiněn kvůli absenci nutnosti instalace nějakého prostředí na PC a s tím spojené možné komplikace. Dále tak bylo proto, že prostředí má velikou podporu komunity a mnoho knihoven. Jednou z nich je právě knihovna UIPEthernet. Jejím použitím je zajištěna komunikace s modulem ENC28J60 a odpadá zdlouhavá a pracná činnost na tvorbě knihovny vlastní.
obr.3 Zapojení
Po zapnutí dojde k inicializaci kitu ENC28J60 a program otevře server který čeká na 23 portu (telnet) na spojení. Pokud dojde k připojení klienta, server odešle uvítací zprávu a čeká na příkazy. Možné příkazy jsou následovné:
V programu je možné definicí preprocesorové proměnné #DHCP přepínat mezi IP adresou statickou nebo IP adresou získávanou z DHCP serveru.
Následující video ukazuje funkčnost projektu. Jsou použity dvě náhodně vygenerované barvy pro ověření správného zobrazení:
#include "mbed.h" #include <string> #include "UIPEthernet.h" #include "UIPServer.h" #include "UIPClient.h" //setting led's ports PwmOut gled(LED_GREEN); PwmOut bled(LED_BLUE); PwmOut rled(LED_RED); Serial pc(USBTX, USBRX); //debug over serial port //#define DHCP 1 // if you'd like to use static IP address comment out this line #if defined(TARGET_LPC1768) UIPEthernetClass UIPEthernet(p11, p12, p13, p8); // mosi, miso, sck, cs #elif defined(TARGET_NUCLEO_F103RB) || defined(TARGET_NUCLEO_L152RE) || defined(TARGET_NUCLEO_F030R8) \ || defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F302R8) || defined(TARGET_NUCLEO_L053R8) \ || defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F334R8) || defined(TARGET_NUCLEO_F072RB) \ || defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F070RB) \ || defined(TARGET_KL25Z ) || defined(TARGET_KL46Z) || defined(TARGET_K64F) || defined(TARGET_KL05Z) \ || defined(TARGET_K20D50M) || defined(TARGET_K22F) \ || defined(TARGET_NRF51822) \ || defined(TARGET_RZ_A1H) UIPEthernetClass UIPEthernet(D11, D12, PTC5, D10); // mosi, miso, sck, cs #endif //prototypes and global variables void print_line(string text); EthernetClient client; //MAC address const uint8_t MY_MAC[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; const uint16_t MY_PORT = 23; EthernetServer server = EthernetServer(MY_PORT); int main(void) { //turning off all LEDs rled = 1; bled = 1; gled = 1; // setting IP address #if defined(DHCP) pc.printf("Searching for DHCP server..\r\n"); if(UIPEthernet.begin(MY_MAC) != 1) { pc.printf("No DHCP server found.\r\n"); pc.printf("Exiting application.\r\n"); return 0; } pc.printf("DHCP server found.\r\n"); #else const IPAddress MY_IP(192, 168, 1, 10); UIPEthernet.begin(MY_MAC, MY_IP); #endif IPAddress localIP = UIPEthernet.localIP(); pc.printf("Local IP = "); for(uint8_t i = 0; i < 3; i++) pc.printf("%d.", localIP[i]); pc.printf("%d\r\n", localIP[3]); server.begin(); //main cycle while(1) { uint8_t size; char buffer[256]; if (client = server.available()) { pc.printf("Client connected.\r\n"); //welcome message print_line("RGB telnet server"); print_line(" - Write help for options..\n"); client.write((uint8_t*)"> ", 2); while(1) { size = client.available(); if (size <= 0) continue; //get incoming string to buffer uint8_t* msg = (uint8_t*)malloc(size); size = client.read(msg,size); sprintf(buffer,"%s",msg); buffer[size] = '\0'; //color setting if (strncmp(buffer, "color",5) == 0) { char color[2]; uint8_t col; sprintf(color, "%c%c",buffer[6],buffer[7]); //get HEX char sscanf(color, "%x", &col); sprintf(color, "%u", col); // convert to DEC number rled = (float)(~atoi(color) & 0xff)/255; // inverse number, set value to PWM between 0-1 sprintf(color, "%c%c",buffer[8],buffer[9]); sscanf(color, "%x", &col); sprintf(color, "%u", col); gled = (float)(~atoi(color) & 0xff)/255; sprintf(color, "%c%c",buffer[10],buffer[11]); sscanf(color, "%x", &col); sprintf(color, "%u", col); bled = (float)(~atoi(color) & 0xff)/255; } //turning off all LEDs else if (strncmp(buffer, "stop",4) == 0) { rled = 1; bled = 1; gled = 1; } //disconnecting else if (strncmp(buffer, "exit",4) == 0) break; //help message else if (strncmp(buffer, "help",4) == 0) { print_line("-----Help-----"); print_line("color HEX_COLOR_CODE - set color"); print_line(" HEX_COLOR_CODE - in hex rrggbb (white = ffffff)"); print_line("stop - ALL LEDs OFF"); print_line("exit - end connection"); print_line("--------------"); } else if (strchr(buffer, '\n') != NULL) { client.write((uint8_t*)"> ", 2); } } client.stop(); pc.printf("Client disconnected.\r\n"); } } } //printing out line of string void print_line(string text) { char buffer[256]; sprintf(buffer, "%s\r\n",text); client.write((uint8_t*)buffer, strlen(buffer)); return; }
Zadaní projektu bylo kompletně splněno a vše je funkční tak jak má být. Během řešení jsem neměl s ničím problém a na zadání jsem byl dostatečně připraven jak z předchozích zkušeností tak z předmětu MPOA.
Velikou výhodou bylo nalezení již hotové knihovny k řadiči ENC28J60. Bez toho bych byl nucen strávit několik dní studiem datasheetu k obvodu a následným experimentováním. Použití HEXa barevného kódu pro nastavování barvy mi přijde jako zajímavé řešení, kterým je využit celý rozsah možností RGB LED diody.