Skocz do zawartości
deshipu

utty - malutki zewnętrzny terminal do debugowania

Pomocna odpowiedź

Pomysł jest stary jak świat, praktycznie każdy ma go na swojej liście "kiedyś trzeba będzie zrobić". No to w końcu się za to zabrałem. Do rzeczy.

Idea jest taka, że dobrze jest móc wyświetlić jakieś diagnostyczne logi z robota, ale niefajne jest bieganie za nim z kablem od PC ani komplikowanie konstrukcji wbudowywaniem wyświetlacza -- zatem mamy prosty terminal seryjny, który podłączamy do naszego robota tylko wtedy, gdy chcemy. Terminal ma prosty wyświetlacz, procesorek, który zajmuje się dekodowaniem sygnału i wyświetlaniem, oraz kilka przycisków na dodatkowe funkcje. Całość jest banalnie prosta i tania, a zapewnia sporą wygodę.

Konstrukcja, jak widać na poniższym zdjęciu, jest banalnie prosta. Z jednej strony wszystkie nóżki modułu Pro Mini podlączone są bezpośrednio do pinów wyświetlacza, z drugiej do przycisków.

Oprogramowanie także jest banalne, bo użyłem bibliotek Adafruit. Kod dostępny jest w repozytorium: https://bitbucket.org/thesheep/tty

Co pozostało? Planuję dodać do urządzenia buforowanie tak, żeby można było sobie przyciskami przewijać nasze logi. Może też jakieś menu do zmiany parametrów transmisji danych. No i jak się będę naprawdę bardzo nudził, to może opcję wyświatlania liczb otrzymywanych na wejściu w postaci wykresu.

IMG_20150806_152655.thumb.jpg.375de3dacd6e414e30fd6c543ecbdaa5.jpg

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

deshipu, ciekawy projekt, szkoda tylko tych przycisków z tyłu 😃

Proponowałbym do listy "do zrobienia" dodać obudowę, teraz trochę strach wozić urządzenie na zawody, mogłoby nie przetrwać podróży.

Dołącz proszę dla pewności kod w załączniku, przynajmniej zostanie wtedy jakaś wersja "dożywotnio" 😉

Udostępnij ten post


Link to post
Share on other sites

Dorobiłem "obudowę" ze starej karty kredytowej przykręconej 4 wkrętami oraz jeszcze jeden przycisk. Terminal ma teraz 64-liniowy bufor, który możemy przewijać po jednej linii albo po całej stronie (6 linii). Pozostałe 2 przyciski służą do wyłączenia i włączenia zbierania danych, co by nam się nie przewijało jak czytamy.

Kod najnowszej wersji:

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

Adafruit_PCD8544 display = Adafruit_PCD8544(4, 5, 6, 7, 8);

const int MAX_BUTTONS = 6;
const int buttons[MAX_BUTTONS] = {A3, A2, A1, 12, 11, 10};

const int MAX_BUFFER = 64;
const int WIDTH = 14;
char buffer[MAX_BUFFER][WIDTH] = {};
int buffer_tail = 0;
int buffer_cursor = 0;
int scroll_position = 6;
bool freeze = false;


void setup()   {
   pinMode(3, OUTPUT);
   digitalWrite(3, HIGH);
   pinMode(2, OUTPUT);
   digitalWrite(2, HIGH);
   for (unsigned char button=0; button < MAX_BUTTONS; ++button) {
       pinMode(buttons[button], INPUT_PULLUP);
   }

   Serial.begin(115200);

   display.begin();
   display.setContrast(18);
   display.clearDisplay();

   display.setTextSize(0);
   display.setTextWrap(false);
   display.setTextColor(BLACK, WHITE);
}

void add_character(char c) {
   if (c == '\n' || buffer_cursor >= WIDTH) {
       buffer_cursor = 0;
       buffer_tail = (buffer_tail + 1) % MAX_BUFFER;
       for (int i=0; i < WIDTH; ++i) {
           buffer[buffer_tail][i] = '\0';
       }
   }
   if (c == '\n' || c == '\r') { return; };
   buffer[buffer_tail][buffer_cursor] = c;
   ++buffer_cursor;
}

void do_buttons() {
   static long last_buttons = 0;

   if (millis() - last_buttons < 300) { return; }

   for (unsigned char button=0; button<MAX_BUTTONS; ++button) {
       if (!digitalRead(buttons[button])) {
           switch (button) {
               case 0:
                   scroll_position = max(scroll_position - 1, 6);
                   break;
               case 1:
                   scroll_position = max(scroll_position - 6, 6);
                   break;
               case 2:
                   freeze = true;
                   break;
               case 3:
                   freeze = false;
                   break;
               case 4:
                   scroll_position = min(scroll_position + 6, MAX_BUFFER - 1);
                   break;
               case 5:
                   scroll_position = min(scroll_position + 1, MAX_BUFFER - 1);
                   break;
           }
           Serial.println(scroll_position);
           last_buttons = millis();
       }
   }
}

void display_buffer() {
   int line = (buffer_tail - scroll_position) % MAX_BUFFER;
   while (line < 0) { line += MAX_BUFFER; }

   display.setCursor(0, 0);
   for (int j=0; j < 6; ++j) {
       for (int i=0; i < WIDTH; ++i) {
           if (buffer[line][i]) {
               display.print(buffer[line][i]);
           } else {
               display.print(' ');
           }
       }
       display.println();
       line = (line + 1) % MAX_BUFFER;
   }
   display.display();
}

void loop() {
   do_buttons();
   if (!freeze) {
       while (Serial.available()) {
           add_character(Serial.read());
           do_buttons();
       }
   }
   display_buffer();
   delay(10);
}
  • Lubię! 2

Udostępnij ten post


Link to post
Share on other sites

Świetna sprawa. Muszę taki terminal sobie zbudować. Bardzo przydatne urządzenie. 

Udostępnij ten post


Link to post
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »

×