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

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ę »

×