Hallo zusammen,
ich hab mir mit meinem Arduino Micro eine vierkanal-Stoppuhr gebastelt.
Funktioniert ansich auch ganz prima (war ich ja angehnehm überrascht,
wie schnell und "einfach" das umzusetzen ging.)
Ich hab also eine Ausgabe der Uhrzeit auf den frolgenden drei
"Gerätschaften"
- Serielle Schnittstelle -> (Serieller Monitor in der Arduino IDE)
- OLED-Display
- EPSON Thermodrucker
Es werden eben die Startzeiten und die Stopzeiten, die Rundendauer usw.
angezeigt bzw. ausgedruckt..
Dies alles funktioniert sehr gut. Bei der Durchsicht meines Codes fiel
mir dann irgendwann auf, dass ja ständig das gleiche gemacht werden
muss, nur eben von jeweils 'nem anderen "Gerät".
Meine vier Zeiten kopier' ich zur Ausgabe lokal um (Startzeit1-4,
Endzeit): ABER wie kann ich jetzt ein Ausgabedevice meiner "PRINT_TIME"
- Funktion zuordnen?
Ich weiss es wirklich nicht. ich habe schon mit "&" und "*" und ohne
probiert. Hab schon in der Funktion "Stream.print" angeben wollen. Aber
das muss ich ja dann (am Ende der Funktion) mit dem tatsächlichen
Ausgabemedium "verheiraten".
Es interessiert mich wirklich, wie man das macht!
Grüße
Äxl
(TestCode auch im Anhang)
1
#include<SPI.h>
2
#include<Wire.h>
3
#include"DS3231.h"
4
#include<Adafruit_GFX.h>
5
#include<Adafruit_SSD1306.h>
6
#include"thermalprinter.h"
7
8
#define SCREEN_WIDTH 128 // OLED display width, in pixels
9
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Was du vor hast setzt voraus, dass alle Ausgabeobjekte einen gemeinsamen
Vorfahren haben, der die print() Methode bereitstellt.
Die Serial Klasse ist von der Stream Klasse abgeleitet, welche wiederum
von der Print Klasse abgeleitet ist, wo die print() Methode definiert
ist.
Deine Adafruit_SSD1306 ist von Adafruit_GFX abgeleitet, welche von Print
abgeleitet ist. Das passt also schonmal.
Die Epson Klasse ist auch von Print abgeleitet. Du hast Glück!
Du musst deine Funktion so schreiben, dass sie als Input ein Objekt
erwartet, das vom Typ Print ist oder davon abgeleitet wurde. Dabei hast
du die Wahl, das Objekt als Referenz oder als Zeiger zu übergeben.
Referenz scheint mir in diesem Fall einfacher:
Das Datum würde ich vielleicht auch als Referenz übergeben. Dadurch
würdest du den Speicherbedarf eventuell etwas reduzieren. So wie du es
jetzt gerade machst, wird eine Kopie vom Datum an die Funktion
übergeben.
Ich sag mal ganz lieb "DANKE!!!" es funktioniert freu.
(Im Ernst; ich freue mich tatsächlich)
Dann mach ich mal ans "optimieren" ;)
der ATMega32u4 ist schon randvoll. Jetzt kann ich eventuell noch'n
kleines Menü zum Uhrzeitstellen etc. mit einbauen. Platz sollte jetzt,
wenn auch knapp, ausreichen.
(Die OLED-Lib nimmt sich ganz schön viel Flash...)
Nochmals: vielen Dank für diese wertvolle Hilfestellung zum Eingangs
genannten Problem!
Mit dem Thema "Referenzen" hab ich mich (jetzt erst in diesem
Zusammenhang) letzte Nacht belesen. Unterschied konnte ich schonmal
herausarbeiten, mal seh'n, wie man das umsetzt...
LG
Äxl
Hier hat jemand eine andere Library veröffentlicht, die mit weniger RAM
auskommt - dafür aber auf Textausgabe beschränkt ist.
Für solch kleine Mikrocontroller eignen sich Displays mit eingebautem
Zeichen-Generaot und ggf. Grafik-Engine besser.
>Für solch kleine Mikrocontroller eignen sich Displays mit eingebautem>Zeichen-Generaot und ggf. Grafik-Engine besser.
Das denke ich auch.
Viel interessanter ist die Tatsache, dass, wenn ich den Seriellen
Monitor ausschalte, sich nach einigen (noch genau herauzufindener)
Anzahl Zeichen (denke mal 64) die "Serial.print" in einen ein-sekündigen
Timeout geht und meinen ganzen Ablauf aufhält. Gut - sind im Moment nur
Debugausgeben, die nachher rausfliegen können. Aber blöd ist das
trotzdem.- Wird mit dem USB zusammenhängen.
Ein anderer, "netter" Effekt hingegen ist, dass, wenn man mit
"Serial.begin(9600)" gestartet hat und man im Seriellen Monitor im
laufendem Betrieb 115200 einstellt, sich die Serial automatisch auf jene
Baudrate umstellt -on the fly- quasi. witzig...
(Nur mit dem Timeout ist natürlich doof)
Googlet man mal nach diesem Phänomen, kommen nur "Beschwerden" darüber,
dass sich der Arduino resettet, wenn man den seriellen Port neu aufmacht
(über die DTR(?) Leitung). Das macht mein Micro Pro
https://www.reichelt.de/arduino-micro-atmega32u4-microusb-arduino-micro-p130166.html?
nicht.
Soll ich jetzt in den Tiefen des CDC rumwühlen, um jene Abfrage
auszuschalten? Hab ich doch garkeine Ahnung von :))
Vielleicht mach hich hier mal nen eigenen Thread zu eben jenem Thema
auf. Ich werde ja wohl nicht der erste sein, dem das auffällt.
Gruß
Äxl
Nimmt man higegen ein anderes, (Hier "Terminal")
https://sites.google.com/site/terminalbpp/
ergibt eine öffnen und schliessen des COM-Ports auf Rückfrage mit
"If(!Serial)" ein korrektes Ergebins.
Port offen und da -> Print Sekunden
Port geschlossen (disconnect) -> Print ("Serial off")
Bei geöffnetem Port lässt sich das mit setzen/löschen der DTR-Leitung
ebenso
provozieren. Nur der serielle Monitor der Arduino - IDE macht da nicht
"ordentlich" den Port zu, denk' ich mal.
1
if(!Serial){
2
display.setTextSize(1);// Normal 1:1 pixel scale
3
display.setTextColor(WHITE);// Draw white text
4
display.setCursor(16,40);// Start at top-left corner
5
display.println("Serial off");
6
}
7
elsePrint_Time(display,time_now);
8
display.display();
Ich verwende noch die Arduino-IDE Version 1.6.11, sehe ich gerade. Ich
werde mal n update auf die 1.8.x machen, wenn ich hier mit diesem
Projekt durch bin.
Danke fürs mitlesen bis hierher.
LG
Äxl
Äxl schrieb:> Viel interessanter ist die Tatsache, dass, wenn ich den Seriellen> Monitor ausschalte, sich nach einigen (noch genau herauzufindener)> Anzahl Zeichen (denke mal 64) die "Serial.print" in einen ein-sekündigen> Timeout geht und meinen ganzen Ablauf aufhält.
Das liegt an der USB spezifischen Implementierung der Serial Klasse. Sie
ist so geschrieben, dass bei vollem Puffer möglichst nichts verloren
gibt. Es gibt andere Implementierungen die sich in dieser Situation ganz
aufhängen würden. Mit if(Serial) gekommst du das in den Griff:
https://www.arduino.cc/en/Serial/IfSerial> Ein anderer, "netter" Effekt hingegen ist, dass, wenn man mit> "Serial.begin(9600)" gestartet hat und man im Seriellen Monitor im> laufendem Betrieb 115200 einstellt, sich die Serial automatisch auf jene> Baudrate umstellt -on the fly- quasi. witzig...
Das liegt daran, dass es sich nur um eine virtuelle serielle Verbindung
handelt. In Wirklich hat sie gar keine Baudrate. Die
Übertragungsgeschwindigkeit wird vom USB Bus diktiert.
display.setCursor(16,40);// Start at top-left corner
5
display.println("Serial off");
6
}
7
elsePrint_Time(display,time_now);
8
display.display();
Ja, hab ich probiert (wollte ja eigentlich am Menü schreiben, aber
nunja)
mit jedem anderen Terminalprogramm und/oder mit händischem Setzen der
DTR-Leitung funktioniert das auch. [TerraTerm, Putty, Terminal(@bray)].
Nur im seriellen Monitor der IDE (hier unter 1.6.11) eben NICHT :|
Ich installiere mal die 1.8.8 und werde brav berichten. ;)
So - gleiche "in grün". Serieller Monitor schliessen: Arduino bekommt
nichts davon mit uns sendet ins leere, bis irgendwo ein Buffer
überläuft, was dann in einem Time-Out endet.
Der serielle Monitor der Arduino IDE setzt die DTR Leitung bei öffnen
des virtuellen COM-Ports, löscht die Leitung aber aber nicht. Das sagt
mein Serieller Monitor.
Mitm Terminalprogramm gegengetestet: DTR wird gesetzt, wenn der Port
geöffnet wird und gelöscht, wenn der Port geschlossen wird. In dem
Moment geht "IF (!Serial)" auch auf. Natürlich kann man im
TerminalProgramm die DTR Leitung auch händisch setzen/löschen. Kein
Timeout am Arduino "Ein "IF(!Serial)" in Zeile42 springt sofort an.
Anderenfalls sendet der Arduino noch fleissig weiter, bis er dann so ca.
3 Sekunden Time-Out zwischen jeder Aussendung hinlegt.
https://www.heise.de/download/product/free-serial-port-monitor-26030https://sites.google.com/site/terminalbpp/Terminal20141030.zip?attredirects=0&d=1http://playground.arduino.cc/interfacing/java
Wird's wohl hier zu suchen sein...
http://rxtx.qbang.org/wiki/index.php/Main_Page