Programmierung und Hardwaredesign mit Arduino, AVR, PIC und Konsorten.
Moderatoren: MaxZ , ebastler , SeriousD
Heisath
Beiträge: 539 Registriert: Mi 26. Jun 2013, 15:44
Hat sich bedankt: 33 Mal
Danksagung erhalten: 81 Mal
Kontaktdaten:
Beitrag
von Heisath » So 25. Apr 2021, 17:11
Hallo,
Wochenendprojekt: kleiner µC basierter Logger für serielle Ports, liest die Daten per USB oder UART ein, zeigt sie auf einem Display an und schreibt sie auf eine SD Karte (sofern eingesteckt). Das Display hat Touch, damit lässt sich die Baudrate und Rotation einstellen. Außerdem leeren der Ausgabe und Abschalten. Eingeschaltet wird über einen Taster, der dann über Transistoren den Rest durchschaltet, der µC nutzt dann einen Pin zur Selbsthaltung. Gehäuse 3D gedruckt. Ist gut, wenn man öfter Geräte im Feld auslesen will oder länger einen Logger rumliegen lassen möchte. Versorgung entweder über interne 9V Block, USB oder 7-12V Pin.
Schaltplan gibts nicht, kann man sich aber anhand des Bilds und dem Code sicherlich zusammenpuzzeln. Bei Fragen helfe ich natürlich gern weiter.
Schönen Sonntag noch!
Code (Arduino Nano, braucht die XPT2046, ILI9341 und SD Bibliotheken):
Spoiler:
Code: Alles auswählen
#include <SoftwareSerial.h>
#include <SD.h>
#include <XPT2046_Touchscreen.h>
#include <Adafruit_ILI9341.h>
#define TFT_DC 10
#define TFT_RS 9
#define TFT_CS 8
#define TCH_CS 7
#define SDC_CS 6
#define SWITCH A1
enum tft_layout_e{
WIDESCREEN,
LETTERBOX
};
tft_layout_e tft_layout = WIDESCREEN;
int SCREEN_WIDTH = 320;
int SCREEN_HEIGHT = 240;
const int MENU_ITEMS = 4;
int item_width;
const long Baudrates[] = { 1200, 4800, 9600, 115200 };
int CurrentBaudrateIndex = 2;
int line_cntr = 0;
char buffer[100];
int buffer_pos = 0;
uint8_t sdavail;
#define CurrentBaudrate Baudrates[CurrentBaudrateIndex]
SoftwareSerial softSerial = SoftwareSerial(5, 4, false);
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RS);
XPT2046_Touchscreen touch(TCH_CS);
void setup() {
pinMode(SWITCH, OUTPUT);
digitalWrite(SWITCH, HIGH);
tft.begin();
touch.begin();
sdavail = SD.begin(SDC_CS);
setupScreen();
Serial.begin(CurrentBaudrate);
softSerial.begin(CurrentBaudrate);
softSerial.listen();
}
uint32_t lastTouched = millis();
char msg;
void loop() {
while (Serial.available() || softSerial.available()) {
msg = Serial.available() ? (char)Serial.read() : (char)softSerial.read();
if (tft.getCursorY() > SCREEN_HEIGHT - 16) {
tft.setCursor(1, 18);
}
buffer[buffer_pos++] = msg;
if (msg == '\n') {
tft.setTextWrap(false);
tft.print("\034\n");
tft.setTextWrap(true);
break;
}
else tft.print(msg);
if (buffer_pos >= sizeof(buffer)) break;
}
if (msg == '\n' || buffer_pos >= sizeof(buffer))
{
writeBuffer();
}
bool istouched = touch.touched() && ((millis() - lastTouched) > 250);
if (istouched) {
TS_Point p = getTouchPoint();
if (p.y < 32) {
if (p.x < 1 * item_width) {
CurrentBaudrateIndex = (CurrentBaudrateIndex + 1) % (sizeof(Baudrates) / sizeof(long));
drawHeader();
Serial.begin(CurrentBaudrate);
softSerial.begin(CurrentBaudrate);
softSerial.listen();
}
else if (p.x < 2 * item_width) {
tft.fillScreen(ILI9341_BLACK);
writeBuffer();
drawHeader();
}
else if (p.x < 3 * item_width) {
toggleScreenRotation();
}
else {
writeBuffer();
delay(1000);
digitalWrite(SWITCH, LOW);
}
}
lastTouched = millis();
}
}
void writeBuffer() {
if (sdavail) {
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
dataFile.write(buffer, buffer_pos);
dataFile.close();
}
}
buffer_pos = 0;
}
inline void toggleScreenRotation() {
if (tft_layout == WIDESCREEN)
tft_layout = LETTERBOX;
else
tft_layout = WIDESCREEN;
setupScreen();
}
void setupScreen() {
if (tft_layout == WIDESCREEN) {
tft.setRotation(3);
SCREEN_WIDTH = 320;
SCREEN_HEIGHT = 240;
item_width = (SCREEN_WIDTH / MENU_ITEMS);
}
else if (tft_layout == LETTERBOX) {
tft.setRotation(0);
SCREEN_WIDTH = 240;
SCREEN_HEIGHT = 320;
item_width = (SCREEN_WIDTH / MENU_ITEMS);
}
touch.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setCursor(1, 0);
tft.setTextWrap(true);
drawHeader();
}
void drawHeader() {
tft.fillRect(0, 0, SCREEN_WIDTH, 16, ILI9341_BLACK);
tft.drawFastHLine(0, 16, SCREEN_WIDTH, ILI9341_DARKGREY);
tft.drawFastHLine(0, 17, SCREEN_WIDTH, ILI9341_DARKGREY);
for (int i = 0; i < MENU_ITEMS; i++) {
tft.drawFastVLine(i * item_width, 0, 16, ILI9341_DARKGREY);
}
tft.setCursor(0* item_width + 2, 0);
tft.print(CurrentBaudrate);
tft.setCursor(1 * item_width + 2, 0);
tft.print("CLR");
tft.setCursor(2 * item_width + 2, 0);
tft.print("ROT");
tft.setCursor(3 * item_width + 2, 0);
tft.print("QUIT");
tft.setCursor(1, 18);
}
TS_Point getTouchPoint() {
TS_Point p = touch.getPoint();
static const double x_offset = -400, y_offset = -250, x_scale = 11, y_scale = 15;
if (tft_layout == WIDESCREEN) {
p.x = constrain((p.x + x_offset) / x_scale, 0, SCREEN_WIDTH);
p.y = constrain((p.y + y_offset) / y_scale, 0, SCREEN_HEIGHT);
}
else if (tft_layout == LETTERBOX) {
int y = constrain((p.x + x_offset) / x_scale, 0, SCREEN_HEIGHT);
p.x = constrain((p.y + y_offset) / y_scale, 0, SCREEN_WIDTH);
p.y = SCREEN_HEIGHT - y;
}
return p;
}
Paul
Admin
Beiträge: 3595 Registriert: So 7. Aug 2005, 14:34
Schule/Uni/Arbeit: HW/SW-Entwickler
Wohnort: Braunschweig
Hat sich bedankt: 632 Mal
Danksagung erhalten: 210 Mal
Kontaktdaten:
Beitrag
von Paul » Mo 26. Apr 2021, 10:59
Moin,
sehr cooles Teil! So ein kleines, handliches Terminal hätte ich auch schon oft brauchen können!
Beste Grüße!
gamerpaddy
Beiträge: 2624 Registriert: Mo 13. Aug 2012, 09:03
Spezialgebiet: Spezialgebiet
Schule/Uni/Arbeit: Schule/Uni/Arbeit
Wohnort: Mannheim
Hat sich bedankt: 33 Mal
Danksagung erhalten: 303 Mal
Kontaktdaten:
Beitrag
von gamerpaddy » Mo 26. Apr 2021, 17:03
Sehr praktisch, hatte ich damals brauchen können.
Stattdessen bin ich den direkten umweg gegangen
(µF für umwandlung von 2400_8E1 auf 9600_8N1 -> hc05 bt modul -> bluetooth terminal app die loggen kann)
ataio
Beiträge: 603 Registriert: Fr 13. Okt 2006, 21:54
Spezialgebiet: seltsame Geräte :)
Wohnort: Karlsruhe
Hat sich bedankt: 2 Mal
Danksagung erhalten: 14 Mal
Beitrag
von ataio » Di 11. Mai 2021, 21:50
Hi Heisath,
das Gerät sieht interessant aus!
mir ist aber nicht klar, wozu es gut ist. Irgend etwas wird geloggt, also abgespeichert?
Werden Daten aus dem PC auf das Gerät gespeichert oder Daten von einem Sensor über das Gerät auf den PC gespeichert und worum geht es überhaupt?
ich bin sehr gespannt!
Viele Grüsse
ataio