µC Logger für serielle Ports / UARTs

Programmierung und Hardwaredesign mit AVR, PIC und Konsorten.

Moderatoren: SeriousD, ebastler, MaxZ

Antworten
Nachricht
Autor
Benutzeravatar

Thread-Ersteller
Heisath
Beiträge: 510
Registriert: Mi 26. Jun 2013, 15:44
Hat sich bedankt: 33 Mal
Danksagung erhalten: 79 Mal
Kontaktdaten:

µC Logger für serielle Ports / UARTs

#1 Beitrag von Heisath »

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;
}

IMG_20210425_173912.jpg
IMG_20210425_173357.jpg
ehemals "Count-Doku".

Benutzeravatar

Paul
Admin
Beiträge: 3474
Registriert: So 7. Aug 2005, 14:34
Schule/Uni/Arbeit: HW/SW-Entwickler
Wohnort: Braunschweig
Hat sich bedankt: 541 Mal
Danksagung erhalten: 175 Mal
Kontaktdaten:

Re: µC Logger für serielle Ports / UARTs

#2 Beitrag von Paul »

Moin,

sehr cooles Teil! So ein kleines, handliches Terminal hätte ich auch schon oft brauchen können! :awesome:

Beste Grüße!
“With great power come great heat sinks.”
paulwilhelm.de -- mosfetkiller.de

Benutzeravatar

gamerpaddy
Beiträge: 2528
Registriert: Mo 13. Aug 2012, 09:03
Spezialgebiet: Spezialgebiet
Schule/Uni/Arbeit: Schule/Uni/Arbeit
Wohnort: Mannheim
Hat sich bedankt: 31 Mal
Danksagung erhalten: 261 Mal
Kontaktdaten:

Re: µC Logger für serielle Ports / UARTs

#3 Beitrag von gamerpaddy »

Sehr praktisch, hatte ich damals brauchen können.
Stattdessen bin ich den direkten umweg gegangen :D (µF für umwandlung von 2400_8E1 auf 9600_8N1 -> hc05 bt modul -> bluetooth terminal app die loggen kann)
:wurst:


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

Re: µC Logger für serielle Ports / UARTs

#4 Beitrag von ataio »

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

Antworten