Archiv verlassen und diese Seite im Standarddesign anzeigen : Arduino am Windows-PC: GUI zur Fernsteuerung und zum Messwerte anzeigen (per USB)
Habe mal angefangen, mein Projekt mit Arduinos am Windows-PC ein bisschen zu systematisieren -
Ziel: Arduino Fernsteuerung mit einer grafischen Oberfläche vom PC und auch Messwerte anzeigen.
Arduino ist mit Windows PC per USB verbunden, der Arduino nutzt dazu die Serial class.
PC-Programmiersprache: Borland C++ Builder 6 (freier Download): https://winworldpc.com/product/borland-c-builder/6x
Pin-Fernsteuerung (digital Pin ein/aus und auch pwm per Schieberegler) funktioniert schon.
33944
Als nächstes sollen digitale und analoge Pins ausgelesen und angezeigt werden; kA, ob ich's schaffe, die Borland-COM-Schnittstelle als add-on ist nicht so super verständlich dokumentiert.
https://github.com/dsyleixa/Borland-Cpp-Builder/blob/master/sources/BCB6_COMport.txt
Übernächster Knackpunkt: Multithreading (pthread?).
Mal gucken, wie weit ich komme und welche Fragen auftreten.
https://github.com/dsyleixa/Borland-Cpp-Builder/tree/master/Projects
ich finde UART vom PC aus generell grausam, unter Windows braucht man einen Monster-Struct mit Daten um eine UART Verbindung aufzubauen.
Ich habe was ähnliches allerdings mit Raspi und als Netzwerk Gadget aufgesetzt um mir den COM zu sparen und Mutluthreading gibts gratis dazu.
Unter Arduino würde ich es erstmal mit einem Sheduler probieren bevor du dir selber PThreads ans Bein nagelst :D
spontanes Suchergebnis das sich vernünftig anhört und die Grundlagen von PThreads gleich mit vermittelt:
https://github.com/mikaelpatel/Arduino-Scheduler
du kannst belibig viele loop()s bauen und musst nur darauf achten dass die auch mal an einem bestimmten Punkt mit yield() oder delay() warten damit der Scheduler einem anderen "Task" die Zeit gibt seine loop() zu bearbeiten.
neinnein, am Arduino ist MT kein Thema, da nutze ich ja bereits die Scheduler Lib seit ewigen Zeiten 8)
Am Raspi nutze ich hingegen pthread bereits sehr erfolgreich, ich finde pthread hier geradezu genial!
Auch habe ich auf meinem Windows PC so viele Resourcen satt, da stört mich das bisschen für UART nun wirklich nicht. Für die Borland-IDE ist UART/COM nur ein plugin unter vielen anderen (wie für Multimedia oder Datenbanken).
MT war hier nur auf die Borland-GUI bezogen, wenn später mehrere von der GUI angestoßene (auch komplexere, länger dauernde) Prozesse parallelisiert und automatisch zur Anzeige und zur Steuerung aktualisiert werden sollen.
pthread auf dem Pi funktioniert auch für solche Dashboards bereits perfekt (bis auf GUI Buttons oder Slider).
Hier geht es also allein um ein grafisches PC-Interface für Arduinos.
oh ah sorry das hatte ich falsch verstanden ... *grusel* borland und "echtes" MT ist eine sache die mich schon in meinem praxissemster verfolgt hat ... hatte den ersten PC mit 2 kernen in der firma und musste das alte DCOM modul zerlegen und als socket server reimplementieren ... multightread ist grausam mit den ganzen "sync" zwischen den prozessen ohne dabei eine gewischt zu bekommen.
ich weis nicht wie es jetzt um borland steht(zu lange her), aber persönlcih würde ich zu jedem nicht borland eigenen hilfsmittel raten um MT zu bewerktstelligen weil borland wie .Net und andere nennenswert großen aber ausgelassenen Frameworks dazu tendieren einem die finger abzuhacken wenn man sich nicht ganz penibel an die "wer darf wann was" Regeln hält
*grusel* borland
ich habe nicht vor, mit dir hier über deine Meinung zu Borland C++ Builder zu diskutieren -
ich habe ihn verwendet, und ich stelle das Projekt hier vor.
Ich freue mich über konstruktive Erweiterungen und Tipps.
Ich erwarte nicht, dass dir persönlich der Borland C++ Builder gefällt (mir selber gefällt er bislang sehr gut).
Du darfst aber gerne deinen Code zeigen, wie du die UART-Serial-Kommunikation praktisch mit anderen Borland C++-Builder add-ins nutzt, aber ebenfalls MIT dem Borland C++-Builder.
PS,
pthread macht alles bezüglich multithreading automatisch, verteilt sogar die Threads auf einzelne Kerne, und man kann sogar Kerne explizit für MT ein- oder ausschließen 8)
Aber NOCH ist MT nicht aktuell für den BCB, erst mal kommt jetzt pin-read als nächstes...
update,
habe eben gelesen: die GUI nutzt ein eigenes thread handling, das sich TThread nennt.
Übungsweise könnte man ein Label ins Formular einfügen, das eine Zahl automatisch jede Sekunde um 1 hochzählt, unabhängig ob man irgendwo was drückt oder klickt oder doch oder ob irgendwo anders eine Schleife läuft
- ist mir aber noch unklar, wie das geht.
Hallo HaWe,
ich finde die Idee sehr gut, ich habe etwas ähnliches gemacht, jedoch mit Lazarus/Pascal für Windows.
Die Windowsschnittstelle ist schon "etwas" grausam, da gebe ich CEOS recht, aber ich habe mich durchgerungen
und sie recht gut zum laufen gebracht. Ich bekomme nun 4000 Messdaten a 16 Bit pro Sekunde in "quasi" Echtzeit
von meiner Elektronik zum PC übertragen und kann sie in Kurven darstellen und skalieren
Zudem wirst Du eine Art "Synchronizer" benötigen, damit die Software auch immer richtig einrastet,
wenn das Kabel mal abezogen oder angesteckt wird. Ich hab mir dafür einen speziellen 16 Bit Code ausgedacht,
der normalerweise nicht in meinen Messwerten auftaucht und in dem jedes Nibble unterschiedlich ist.
Tests mit Original COM vom Motherboard und auch mittels Silabs Treiber USB laufen bei mir problemlos.
Ich musste teils auch in den Systemeinstellungen (Gerätemanager) einges umstellen, damit ich schneller an meine Daten rankomme.
Grade die USB Schnittstellen puffern sehr viel zwischen und entsprechend verzögert kommen dann auch die Daten an
bzw. garnicht, wenn noch nicht genügend Daten vorhanden sind.
Ich habe mir dazu einen Timer geschaffen der jede Millisekunde nachschaut ob schon Daten vorhanden sind.
Witzigerweise bzw. unverständlicherweise stellt windows dafür die Funktion
ClearCommError zur Verfügung, da muss man aber erstmal drauf kommen....
Da bekommt man die Anzahl TX und RX Daten zurück
Aber das sind Optimierungen die man zum Schluss tätigen kann, erstmal muss die Schnittstelle gut laufen.
Siro
hallo,
danke für deinen Post, allerdings: das klingt nun doch komplizierter als gedacht.
Mit der USB/COM-Schnittstelle habe ich mich absolut überhaupt nicht näher beschäftigt, ich nutze sie einfach so, wie sie ist, daher ist sie für mich genau so gut oder schlecht oder grausam wie alles andere - halt eine Blackbox.... .
Für meine Raspi-Arduino-Kommunikation nutze ich feste arrays, die außer einem Start- und einem optional Ende-Byte (0xff bzw. 0xfe) noch eine chksum und ein ack byte enthält. Das klappt absolut fehlerfrei, sogar in einem eigenen pthread Thread neben vielen anderen parallel laufenden, und das auch wenn man die Verbindung unterbricht (USB-Kabel oder BT HC06 über CH341 Adapter)
- wie du am Borland-Code sehen kannst, mache ich das fürs Senden mit BCB noch nicht, und Empfangen steht ja eh noch auf der todo-Liste.
Windows mit Borland GUI ist ja noch absolutes Neuland (habe nur vor ein paar Jahrzehnten mal ein wenig damit herumgespielt),
Falls jemand also speziellen Borland-Programmcode für mein bisheriges Programm dazu hat: gerne immer her damit. Andere Programme oder Plattformen zum Vergleich bringen mir ehrlich gesagt hingegen allerdings momentan nicht so viel, um weiter zu kommen.
Zum regelmäßigen wiederholten Abruf von Daten in einer loop (in Arduino Scheduler oder per gcc MT Endlos-thread auf dem Pi sehr einfach) brauche ich aber dann auch dieses MT TThread fürs BCB GUI, und auch das ist ja überhaupt noch nicht gelöst.
Für die allermeisten Anwendungen reicht auch eine "Blackbox", welche die entsprechnde Funktionalität für RS232 zur Verfügung stellt,
habe lange Jahre auch eine fertige Komponente genommen.
Der Borland C++ Builder sieht ja aus wie mein Lazarus bzw. Delphi.
Wie ich dem Video entnehmen kann, scheint das handeln mit der RS232 ja damit supi einfach zu sein.
Damit solltest Du recht schnelle Erfolge erzielen können.
Siro
Habe mir die IDE grad mal runtergeladen, bekomme sie aber leider nicht installiert.
Damit sind leider keine weitern Versuche möglich. Die erste .iso Datei hab ich angeklickt, dann will er irgendwann eine zweite DVD.
Muss ich die erst auf 2 DVDs brennen ?
Habe mir die IDE grad mal runtergeladen, bekomme sie aber leider nicht installiert.
Damit sind leider keine weitern Versuche möglich. Die erste .iso Datei hab ich angeklickt, dann will er irgendwann eine zweite DVD.
Muss ich die erst auf 2 DVDs brennen ?
es existieren 2 iso files in dem Download-Archiv per https://winworldpc.com/product/borland-c-builder/6x
Borland CPP Builder 6.7z
33945
jeweils für 1 CD-ROM, die man nacheinander brennen kann.
Ich habe dann die 1. CD eingelegt, dann fragt er nach Lizenzdaten (stehen auch in dem 7z Arrchiv in serial.txt), dann installiert er sie, dann verlangt er die 2.CD, und nach CD-Austausch läuft die Installation dann störungsfrei bis zum Ende.
TThread für BCB MT scheint aber auch echt ein Problem zu sein, extrem schwierig und derzeit völlig unverständlich ...
Installation hat geklappt, habe die CDs gebrannt. Man muss die IDE aber immer mit Administratorrechten starten.
Nun fehlt die Komponente CPort.
Ich habe die "comport411f.zip" runtergeladen, weis nicht ob das richtig ist und auch nicht wie man die dann installiert.
TThread brauchst Du meiner Meinung nach nicht. Ich wüste zumindest nicht wofür.
Die serielle Schnittstelle läuft in einem eigenen Thread.
Du müstet jetzt die Eigenschaft OnRxChar im Objektinspector haben.
Dort doppelt klicken und dann in die Funktion reinschreiben was passieren soll wenn ein Zeichen empfangen wurde.
Zum Testen erstmal das Zeichen anzeigen, das mache ich meisten in Form->caption
Siro
hallo,
ja, den COM Port habe ich hier nach installiert:
https://github.com/dsyleixa/Borland-Cpp-Builder/tree/master/sources
https://github.com/dsyleixa/Borland-Cpp-Builder/blob/master/sources/comport411f.zip
Installation:
http://perso.wanadoo.es/pictob/tcomport.htm
In dem Github Ordner stehen auch noch ein paar weitere Infos dazu.
später sollen dann aber die seriellen Nachrichten vom Arduino nicht nur empfangen, sondern auch ausgewertet werden (Anzeige aller inputs als "Lämpchen", die gesendeten analogen Werte auch in Zahlenform (int/float/double), und ausgerechnete Werte sollen uU auch - allgemein formuliert - z.B. in einem Graphen immer entsprechend frisch simultan aktualisiert werden können. Das Aktualisieren und Weiterverarbeiten kann sehr schnell nötig sein, je nachdem, wie schnell die Werte eintreffen, und die Verarbeitung darf andere Funktionen nicht blockieren, daher plante ich MT mit TThread.
Hallo HaWe, Danke Dir für die Info,
ich probier heute Abend nochmal ob ich die RS232 zum Laufen bzw. installiert bekomme.
Ich glaube um Geschwindigkeit brauchst Du Dir vorerst keine Gedanken machen, das die PC System Resourcen nicht ausreichen.
Mit 9600 Baud kannst Du garnicht sowviel schicken als dass der PC nicht hinterher kommt.
Ich arbeite mit 115200 Baud und die Daten sind auch gut "eng" gerückt, da bleibt eigentlich nicht viel Spielraum,
habe aber trotzdem nur einen Thread, (außer dem seriellen, der ergibt sich von selbst durch die Komponente,)
Ich hatte aber anfangs auch einige Probleme wie ich das sinnvol organisiere.
Bei mir laufen ja 1000 Messwerte auf 4 Kanälen gleichzeitig pro Sekunde und die werden auch Kurvenmässig optisch zumindest ohne Verzörung
dargestellt. Anfangs hatte ich versucht nach jedem Messwert die Kurve neu zu zeichnen, das ist natürlich SEHR aufwändig und gerät ins stocken.
Nun laufen die Messwerte in einen Puffer.
Auf dem Formular habe ich einen Timerkomponente (zu finden in der Palette System TTimer) gesetzt, die dann auf 100 Millisekunden gesetzt wird.
Dies Löst dann lediglich bei OnTimer ein Form.Invalidate aus, was ein Neuzeichnen bewirkt.
Die eigentliche Zeichnerei der Kurven findet dann nur in Form.OnPaint statt.
Hier ist meine CPU jetzt aber auch gut ausgelastet. (zumindest ein Kern) Wenn man das Fenster größer oder kleiner macht, während das Program läuft kann man im Taskmanager gut sehen
wie die Auslastung fällt bei kleinerem Fenster.
Alles was am meisten Resourcen frist, ist das Paint, bei den anderen Dingen auswerten, rechnen was auch immer, langweilt sich die CPU nur...
Siro
Danke fürs Mitmachen! 8)
habe inzwischen baud auf 115200 gesetzt als default (für Arduino Due), mit Mega geht evt auch noch mehr.
hallo,
ich habe jetzt ein Terminal-Fenster eingebunden, und die vom Arduino gesendeten Strings werden auch automatisch nacheinander angezeigt.
Der Empfangs-String müsste dann jetzt noch irgendwie zwischengespeichert werden, zur weiteren Auswertung.
Der Arduino-Sende-Code sieht so aus:
#define MSGLEN 256
char cbuf[MSGLEN]; // cstring buffer
int a0, a1, a2, a3;
a0=analogRead(A0);
a1=analogRead(A1);
a2=analogRead(A2);
a3=analogRead(A3);
sprintf(cbuf, "&a0=%d;&a1=%d;&a2=%d;&a3=%d;", a0,a1,a2,a3);
Serial.println(cbuf);
strcpy(cbuf, "");
33947
vollständiger Arduino-Code und alle BCB-Projektdateien hier:
https://github.com/dsyleixa/Borland-Cpp-Builder/tree/master/Projects/103_test
- - - Aktualisiert - - -
update, vorheriger "Fehler" lag am Arduino-Code.
Es bleibt nur dies zu tun:
Der Empfangs-String müsste dann noch irgendwie zwischengespeichert werden, zur weiteren Auswertung.
Okay, ich bin gescheitert,:(
ich bekomme es nicht installiert, da fehlt mir wohl einiges an Hintergrundwissen.
Siro
Okay, ich bin gescheitert,:(
ich bekomme es nicht installiert, da fehlt mir wohl einiges an Hintergrundwissen.
Siro
ich habe einfach nur die (spanische) Anleitung Schritt für Schritt befolgt, und danach die paar Patches, wo erst etwas auskommentiert und dann ein paar Dateien umkopiert werden mussten....
Das ist eine echte Katastrophe die Installation,
jetzt hab ich zwar die Palette mit der RS232 in der IDE drin,
aber er findet die
#include "CPort.h"
#include "CPortCtl.h"
Header Dateien nicht, die existieren auch garnicht auf meinem Rechner und auch nicht im Zip File.
Siro
Das ist eine echte Katastrophe die Installation,
jetzt hab ich zwar die Palette mit der RS232 in der IDE drin,
aber er findet die
#include "CPort.h"
#include "CPortCtl.h"
Header Dateien nicht, die existieren auch garnicht auf meinem Rechner und auch nicht im Zip File.
Siro
hast du diese Schritte gemacht...?
Es necesario reubicar los archivos generados en la carpeta "tcomport".
Copiar los 7 archivos .HPP de "C:\Archivos de Programa\Borland\CBuilder6\Imports\tcomport" a "C:\Archivos de Programa\Borland\CBuilder6\Include\Vcl".
Copiar los 9 archivos .OBJ de "C:\Archivos de Programa\Borland\CBuilder6\Imports\tcomport" a "C:\Archivos de Programa\Borland\CBuilder6\Lib\Obj".
Copiar los 3 archivos .DFM de "C:\Archivos de Programa\Borland\CBuilder6\Imports\tcomport" a "C:\Archivos de Programa\Borland\CBuilder6\Lib\Obj".
Copiar el archivo CPortImg.res de "C:\Program Files\Borland\CBuilder6\Imports\tcomport" a "C:\Archivos de Programa\Borland\CBuilder6\Lib\Obj".
Archivos de Programa
ist bei uns C:\Programme(x86),
also das Installationsverzeichnis
es läuft, was für eine Arie ;)
Ich empfange mein erstes Zeichen.
Ganz einfach nur mal zum Testen:
Clicke auf die Komponente ComPort1 und dann im Objektinspector Events "onRxChar"
//---------------------------------------------------------------------------
void __fastcall TForm1::ComPort1RxChar(TObject *Sender, int Count)
{
Form1->Caption="character detected"; // HURRA, ich habe ein Zeichen empfangen...
}
//---------------------------------------------------------------------------
oder dies hier.
Ich hab keine Ahnung wie man in C mit strings arbeitet, aber das scheint zu funktionieren,
wenn man stdio.h mit reinpackt....
void __fastcall TForm1::ComPort1RxChar(TObject *Sender, int Count)
{
char str[20];
sprintf(str,"%d",Count); // Anzahl empfangener Zeichen ausgeben
Form1->Caption=str;
}
Siro
die Methode habe ich auch, aber sie funktioniert nicht bei mir, obwohl laufend korrekte Strings vom Arduino im ComTerminal angezeigt werden
//---------------------------------------------------------------------------
void __fastcall TForm1::ComPort1RxChar(TObject *Sender, int Count)
{
AnsiString rcvStr;
ComPort1->ReadStr(rcvStr, 250);
// Liest die im Eingangspuffer vorhandenen "Count" -Bytes und kopiert sie
Label2->Caption=String("Test");
Form1->Caption="character detected";
}
//---------------------------------------------------------------------------
weder schreibt er "Test" ins Label2 noch "character detected" in den Form1 Titel
PS,
auch wenn ich das ComTerminal aus der Form1 rauslösche, ändert sich nichts - : keine Reaktion, keine Meldung
Du must im Objectinspector Connected auf TRUE setzen
oder es mit einem Button machen.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ComPort1->Connected=TRUE;
}
ich hab das vorerst mit der Standardbaudrate 9600 gemacht. Also noch nichts umgestellt
Ich sende von meinem PIC über einen RS232 zu USB Converter auf COM3
mache ich, über einen Button:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ComPort1->ShowSetupDialog();
ComPort1->Open();
if(ComPort1->Connected ) {
Button3->Enabled=true;
Button4->Enabled=true;
Button2->Enabled=true;
Button5->Enabled=true;
ScrollBar1->Position=0;
Label1->Caption=String(ScrollBar1->Position);
}
}
- - - Aktualisiert - - -
Aber auch wenn ich direkt open=connected mache und meinen COM15 fest eingebe (ohne Dialog), rührt sich nichts.
Im Terminal rauschen aber alle Strings durch.
Du fragst ab ob er "Connected" ist aber Du must ihn selbst erstmal Connecten,
ich glaube das Open Reserviert nur die Schnittstelle.
Setze mal noch Comport1.Connected = TRUE;
und versuche es
Ich weis auch noch nicht wie diese Komponente ganau funktioniert.
hast du mein Programmpaket in 13_test verwendet?
- - - Aktualisiert - - -
er ist ja connected, sonst könnte er ja auch nichts von den empfangenen ArduinoStrings im Terminal anzeigen.
Solange er nicht connected ist, zeigt er auch nichts im Terminal an.
nein ich hab lediglich ein neues Programm erstellt den Comport aufs Formular gesetzt.
Connected auf TRUE gesetzt und den Port ausgewählt, alles im Objektinspektor
dann Muss er auch in die Funktion OnRxChar reinkommen, wenn er etwas empfängt.
Mach mal ein NEUES Project, und wirklich nur die ComPort Komponente drauf.
Wenn ich das Terminalfenster drauf packe, gehts garnichts mehr ausser Fehlermeldungen.
Irgendwelche Bitmpas, keine Ahnung was das nun wieder ist.
Dann muss ich tasächlich eine neues Projekt machen, sonst geht das nie wieder.
Also einfach geht anders....https://www.roboternetz.de/phpBB2/images/smiles/icon_wink.gif
scheint auch am terminal zu liegen, das muss wohl auch raus
115200 ist eventuell ungenau vom Arduino ??
ich hab in meinem Controller dafür extra Korrekturregister, das hat aber nicht jeder
Das Terminal leitet Dir vermutlich die Daten um, klinkt sich dazwischen und dann kommt er nicht mehr in deine Funktion,
ist aber nur eine Vermutung.
So, ich muss dann mal heiern.
Viel Spass noch.
Siro
115200 funktioniert sonst immer mit dem Due und auch mit allen anderen AVRs oder ARMs.
was hast du für COM Einstellungen
parity
start
stop
9600 Baud 8N1
8 Datenbits
1 Stopbit
No Parity
habe ich auch.
Im nackten Programm, nur mit der COM-Schnittstelle, läuft es bei 9600 (Ändert Form1->Caption)
Mit meinem programm aber nicht: zeigt zwar immer connected an (auch wenn fest voreingestellt), aber ändert nicht Caption.
Er erkennt also nichts in ComPort1RxChar().
- - - Aktualisiert - - -
habe nochmal alles von vorn eingegeben:
Die Read-Funktion und die Sende-Funktion stören sich uU gegenseitig.
Immerhin ändert er jetzt beim Start die Form1->Caption, und er reagiert jetzt plötzlich auch auf die LED-Stuerung.
Habe in der Arduino-Loop ein delay(20) eingefügt.
Reagiert jetzt so wie beschrieben, egal, ob mit 9600 baud oder 115200 baud.
Habe auch alles neu hochgeladen (115200 baud, mit Arduino-Programm):
https://github.com/dsyleixa/Borland-Cpp-Builder/tree/master/Projects/105_test
(115200 funktioniert sonst auch immer mit dem Due und auch mit allen anderen AVRs oder ARMs.)
Ebenfalls funktioniert jetzt auch die rcvStr-Lesefunktion:
//---------------------------------------------------------------------------
void __fastcall TForm1::ComPort1RxChar(TObject *Sender, int Count)
{
Form1->Caption="character detected";
AnsiString rcvStr;
ComPort1->ReadStr(rcvStr, 250);
// Liest die im Eingangspuffer vorhandenen "Count" -Bytes und kopiert sie
Label2->Caption=String(rcvStr);
}
//---------------------------------------------------------------------------
(editiert)
Vielen Dank auch, Siro, für deinen Test, ohne deine Hinweise zu deinem Minimal-Programm hätte ich sicher nicht nochmal alles neu zusammengebaut... 8)
Das freut mich zu hören, dass es nun weitergeht.
Übrigens liest Du immer 250 Bytes aus dem Puffer und nicht Count,
das ist sicher vorerst für Testzwecke.
Ist das serial.prinln im Arduino eigentlich Interrupt gesteuert über einen Transmitt Puffer und kehrt sofort zurück, oder
kehrt sie erst zurück wenn alle Daten ausgesendet wurden ?
Siro
Das freut mich zu hören, dass es nun weitergeht.
Übrigens liest Du immer 250 Bytes aus dem Puffer und nicht Count,
das ist sicher vorerst für Testzwecke.
Ist das serial.prinln im Arduino eigentlich Interrupt gesteuert über einen Transmitt Puffer und kehrt sofort zurück, oder
kehrt sie erst zurück wenn alle Daten ausgesendet wurden ?
Siro
- der Puffer ist jetzt überall 1024 bytes
- über Serial.println: weiß ich nicht, aber es funktioniert! ;)
wie man das Lesen auf cnt begrenzen kann, muss ich mal sehen, eigtl wollte ich nur bis \n oder \n\r lesen
Neue Version 106 wird gleich hochgeladen:
3 digitale Pins on/off/pwm senden (frei definierbar)
9 int Variablen empfangen (frei definierbar)
6 double Variablen empfangen (frei definierbar)
33950
https://github.com/dsyleixa/Borland-Cpp-Builder/tree/master/Projects/106_ArduinoCOM_RxTx
to do:
6 analogRead
16 digitalRead per Bitmask über 1 int
6 weitere int
6 double
6 pinWrite I/O/pwm
6 pinWrite I/O (ohne pwm)
was etwas schade ist: ich habe noch keine senkrechten Slider gefunden, und auch erst recht noch keine virtuellen Joysticks, die man dann per Maus oder Touchscreen steuern könnte, analog zu den horizontalen Gleitreglern... :(
Hallo HaWe,
das Programm wächst, sehr schön.
Klick mal auf deinen Slider und dann im Objectinspector,
da gibt es die Eigenschaft :
Kind
hier kannst Du sbHorizontal oder sbVertikal einstellen.
ich hab das zwar grad nicht vor mir, aber das war bei Delphi auch so.
Für den Joystick gabs hier mal was:
https://www.roboternetz.de/community/threads/20199-Joystick-mit-dem-Borland-C-Builder-abfragen
Siro
jap!
mann, klar, auf "Kind" bin ich nicht gekommen, hatte was in der Art von "orientation" gesucht...
33955
PS,
Für den Joystick gabs hier mal was:
https://www.roboternetz.de/community/threads/20199-Joystick-mit-dem-Borland-C-Builder-abfragen
Siro
das geht da aber um einen "realen" Joystick, keinen virtuellen auf der BCC Form, oder?
Okay, das hab ich falsch verstanden, ich dachte es geht um eine "echte" Joystickabfrage.
Da gibt es aber sicher auch fertige Komponenten für.
Auf dieser Seite gibt es diverse Komponenten , die teils für Delphi und oder auch C++Builder geschrieben wurden.
https://torry.net
(https://torry.net/pages.php?s=69)
Siro
Okay, das hab ich falsch verstanden, ich dachte es geht um eine "echte" Joystickabfrage.
Da gibt es aber sicher auch fertige Komponenten für.
Auf dieser Seite gibt es diverse Komponenten , die teils für Delphi und oder auch C++Builder geschrieben wurden.
https://torry.net
(https://torry.net/pages.php?s=69)
Siro
dankeschön, super Link! Mal gucken, was sich dort finden lässt! :)
- - - Aktualisiert - - -
das hier sieht ja schon ganz vielversprechend aus:
https://torry.net/quicksearchd.php?String=joystick&Title=Yes,
ganz unten: TFlightJoyStick v.1.0
A-Bär... nur für Pascal, oder?
aktuell: https://github.com/dsyleixa/Borland-Cpp-Builder/tree/master/Projects/107_ArduinoCOM_RxTx
to do (ganz wichtig):
bei Datenunterbrechung (Kabel gezogen) den Kontakt wieder aufnehmen.
Momentan blockiert dann leider das BCB Programm komplett... :-k
(bei Arduino-Arduino oder Arduino-Raspi war das nie ein Problem...)
Ich vermute das Problem liegt bei ComPort1RxChar
Du versuchst 1024 Bytes aus dem RX Puffer zu lesen,
wieviele da aber momentan drin sind wird Dir ja in der Variablen Count mitgeteilt,
das ist auch immer unterschiedlich,
demnach kannst Du auch nicht mehr Bytes lesen.
Du musst die Empfangsbytes erstmal solange in einen Puffer ablegen, bis dein Endezeichen erkannt wurde,
also z.B. das Carriage Return /n
Erst dann rufst Du deine Auswertefunktion auf, die den Buffer zerlegt.
Also kommt in die ComPort1RxChar eigentlich nur folgende Pseudocode:
while (Count--)
{
read 1 byte
if byte is Endezeichen dann Auswerten
ansonsten in Puffer packen
}
Siro
ich meine gelesen zu haben (kann mich aber irren), dass die readString-Funktion nur maximal bis zur Pufferlänge liest, ansonsten nur bis String-Ende erreicht ist, je nach dem, was kürzer ist.
Trotzdem könnte es auch beim Byte-weisen Lesen passieren, dass er versucht, bis zum fest definierten String-Ende zu lesen, aber ebenfalls dabei unterbrochen wird, wenn das USB-Kabel unterdessen gezogen wurde, und dann folglich ebenso hängt und später nicht mehr die Verbindung beim Wieder-Einstöpseln neu aufbaut...
In der Zwischenzeit hat aber der Arduino weitergesendet, und mittlerweile wurden tausend neue Strings mit neuen Werten rausgeschickt.
Wie müsste also der korrekte lese- und verbindungsstabile und wiedereintritts-sichere Code genau aussehen?
Irgendwie bin ich grade zu blöd im Netz ne Doku zu diesem TComPort zu finden ... alles was ich bisher gesehen habe deutet darauf hin dass du Timeouts einrichten musst damit er auch nach einem unvollständigem lesen definiert zurück kommt und sich dabei nicht komplett aufhängt.
Generell würde es Sinn machen das reine lesen des Com Port in einen steuerbaren Thread auszulagern, der einfach kontinuierlich versucht "ein paar" bytes zu lesen und die dann in einen von dir kontrollierten Puffer zu speichern, von dem du dann aus dem GUI Thread lesen kannst. Das war auch damals mein Ansatz gewesen aber ich musste mich noch der Windows API für COM bedienen.
Wenn beim Lesen Bytes ankommen hängst du die in deinen Puffer und inkrementierst entsprechend den "noch zu Lesen" Counter und kannst im Hauptprogramm dann zyklisch darauf warten dass genug Daten ankommen.
Wenn beim Leseversuch keine Bytes rauskommen und ein Timeout entsteht gehst du einfach wieder auf Empfang und wartest das nächste Timeout ab oder dass neue Daten kommen, in der Schleife sollte dann auch eine Abbruchbedingungn enthaletn sein, damit du den Thread von außen auch abbrechen kannst und ein Thread.yield() damit der Prozess die CPU nicht permanent beansprucht. So hast du keine Hänger in der GUI während des wartens auf neue Daten.
Aber wie man ein Timeout bei TComPort einrichtet kann ich dir nicht sagen ich habe damals noch mit der WIN API gearbeitet und diese brutalen Riesenstructs zum COM initialisieren verwendet.
ja, genau so mit extra Threads mache ich es auch beim Pi (mit pthread) - aber pthread gibt es nicht bei BCB, nur TThread, das aber extremst viel komplizierter ist, und da bin ich mir noch nicht einmal sicher, ob die ComPort-Funktionen thread- / dataracing-safe sind (faktisch laufen sie ja bereits autonom und parallelisiert in einem eigenen Thread).
In jedem Falle führen USB-Unterbrechungen zu ComPort Errors und Exceptions, die ich nicht händeln kann, und die bislang einen Wiederaufbau verhindern.
Wie auch immer, theoretisch kann ich die Ideen von dir und Siro schon befürworten - nur: wie programmiert man sie genau?
Exceptions behandelt man in sog. Try{} Catch(...){} Blöcken, wo im Try der Code kommt der den Fehler verursacht und im Catch der Code der die übergebene Exception behandelt und entsprechenden Maßnahmen einleitet um das Problem zu behandeln
Wieder einmal kann ich leider nicht sagen wie exakt das in Borland C++ funktioniert, aber du kannst erstmal mit einer generellen Exception-Klasse beginnen und ausgeben um was für eine Subklasse es sich handelt und dann hinter einem Try mehrere Catch Blöcke zu der jeweils entsprechenden Exceptionklassen formulieren um auf verschiedene Ereignisse zu reagieren
Zum Hängen wegen zu wenig Daten brauche ich die Doku, wenn du eine Online verfügbare hast zu TComPort dann guck ich mir das mal an aber ich finde einfach nichts
theoretisch weiß ich schon, was try...catch ist und tut, die Frage ist, wie man damit welche BCB-Errors und Exceptions genau händelt ;)
Fang erstmal mit der Basisklasse für Exceptions an und lass sie dir so ausführlich wie möglich ausgeben (haben meist eine dump oder print funktion) und poste die unterschiedlichen Fehler mal, dann kann man da weiter gucken :)
Weitere Dokus zum ComPort kenne ich ja leider auch nicht, ich kenne noch nicht mal Namen/Syntax der Errors und Exceptions, keine dump oder print funktion, und wie man ihr Auftreten programmiert und abfängt.
Ich brauche hier also schon genauen Code.... 8)
https://docs.microsoft.com/de-de/windows/desktop/Debug/getexceptioncode
https://docs.microsoft.com/de-de/windows/desktop/Debug/getexceptioninformation
das als printout in einem Catch(...) (das "(...)" müsste glaube ich so funktionieren)
ob das so 1:1 in BCB funktioniert kann ich nicht versprechen, online doku ist echt mager was Borland angeht... ziemlich Blöd für die Vermarktung eigentlich
es geht nicht um Microsoft-Code, sondern um den genauen Borland ComPort Code, der nutzt keine Windows-Basisfunktionen, sondern eigene (gleiches gilt auch für die print Funktionen im Formular) ;)
Installiere doch mal den C++ Builder und teste mal selber 8)
du weist genau wie ich das ding hasse XD SOrry der kommt mir nicht aufn PC schon allein weil man keine Doku dafür hat, hatte gehofft ich könnte was helfen sorry :(
danke, aber ohne eigene Installation zum vorher selber-testen wird das mit den Hilfevorschlägen wohl leider nicht so schrecklich viel fruchten...
PS,
habe jetzt probiert:
void __fastcall TForm1::ComPort1Exception(TObject *Sender,
TComExceptions TComException, AnsiString ComportMessage,
__int64 WinError, AnsiString WinMessage)
{
try { ComPort1->Close(); }
catch (...) { }
try { Application->Initialize(); }
catch (...) { Application->Terminate(); }
}
damit ist das Beenden bei USB-Unterbrechung leichter möglich ohne dass es sich aufhängt (aber auch nicht 100% korrekt), und springt auch sonst leichter raus, wenn Fehler schon beim 1. Verbinden passieren... :-/
Ich habe mir mal den Code von ComPort genauer angesehen.
Der originale Code "Cport.Pas" ist in Delphi programmiert, (wenn es das Original ist) 3652 Zeilen Code
Den Code kann ich "teilweise" gut nachvollziehen, da ich lange Zeit mich mit Delphi beschäftigt habe
und selbst erst eine Serielle Komponente in Lazarus auf Basis der Windows API programmiert habe.
Wie diese UNIT jetzt nach C++ convertiert wird, habe ich aber ehrlich gesagt nicht verstanden.
Habe ja auch bisher nie mit Borland Builder C++ gearbeitet.
Im Code selbst sind SEHR viele Funktionen implementiert, auch Timeouts usw,
Wenn die C-Componente alle Funktionen bietet wie das Delphi Original, dann fehlt es da eigentlich an Nichts.
Wobei ich sie nicht für Optimal halte beim Empfangen, (Geschmackssache)
Ich glaube die Funktion WaitForSingleObject könnte da ein Problem werden,
sie wird unter anderem beim Lesen aufgerufen mit einer "unendlichen" Zeit
Das asynchrone Lesen ist in der Komponente erheblich anders programmiert als bei mir
und könnte, meiner Meinung nach festhängen. Da stecke ich aber auch nicht so tief in der Materie wie das laufen soll.
Daher meine Aussage "festhängen" bitte mit Vorsicht geniessen.
Ich habe bei mir einen 1ms Timer der immer wieder nachschaut ob was da ist und es in "meinem" Ringppuffer packt.
es gibt ja leider keine Interrupts mehr, wie früher mit den Uarts im DOS Modus. Achja das waren Zeiten....
Ich schaue mir das aber auch nochmal an mit dem Empfangen beim Borland C.
Zumindest mal ausprobieren ob da was hängen bleibt und gebe Bescheid.
Mit dem "catch" "exceptions" usw. muss ich gestehen kann ich garnichts anfangen. :(
Siro
Wie diese UNIT jetzt nach C++ convertiert wird, habe ich aber ehrlich gesagt nicht verstanden.
Da wird nichts konvertiert, der C++ Compiler ist binärkompatibel zum ebenfalls im C++ Builder enthaltenen Delphi Compiler. Das ganze Gemisch aus Pascal und C++ wird beim Übersetzen zusammengerührt.
@Mxt:
Achso, das wuste ich nicht, danke Dir für die Info. Ich dachte bisher C und Pascal unterscheiden sich unter anderem in der Reihenfolge bei den Paramterübergaben.
Pascal Parameterreihenfolge links nach rechts, bei C rechts nach links. :confused: Is ein anderes Thema, könnte man einen separaten Thread aufmachen...;)
oder hier gucken:
https://de.wikipedia.org/wiki/Aufrufkonvention
Siro
Ja, Pascal und C unterscheiden sich. Aber das war bei Frankensteins Monster auch so. Hat trotzdem funktioniert. (Irgendwie)
Guten Morgen HaWe und Ceos:
jetzt verstehe ich grad erst die Problematik:
Wenn Du deinen Arduino abziehst, dann ist bei Dir ja die ganze RS232 (also der virtuelle Comport) weg ?
und dann bekommst Du bei jeglichem Versuch auf die Schnittstelle zuzugreifen einen Exeption.
Diese Problematik habe ich garnicht, weil auf meinem Motherboard gibt es einen "echte" RS232 und wenn ich mein
Kabel abziehe, dann kommen lediglich keine Daten mehr, aber meine Schnittstelle existiert weiter.
Aufgefallen ist es mir nämlich grad also ich über einen CP2102 (also einen externen USB zu RS232 Converter) am USB Port arbeite.
Wenn ich dann das Kabel rausziehe, bekomme ich von Windows einen Exeption Error. Logisch Schnittstelle is ja weg.
Die Problematik war bei mir und meinen Geräten noch nie aufgetaucht,
das stellt also ein ganz neus Problem dar und da seid ihr Ceos und Du vermutlich wohl auf dem richtigen Weg.
Wie man diese Fehler abfängt weis ich auch noch garnicht, das bräuchte ich nämlich irgendwann auch für meine Basteleien.
Da wurde doch heute morgen tatsächlich nicht nur ich, sondern auch mein Forschungsdrang geweckt :)
Siro
Guten Morgen HaWe und Ceos:
jetzt verstehe ich grad erst die Problematik:
Wenn Du deinen Arduino abziehst, dann ist bei Dir ja die ganze RS232 (also der virtuelle Comport) weg ?
und dann bekommst Du bei jeglichem Versuch auf die Schnittstelle zuzugreifen einen Exeption.
(...)
Wie man diese Fehler abfängt weis ich auch noch garnicht, das bräuchte ich nämlich irgendwann auch für meine Basteleien.
Da wurde doch heute morgen tatsächlich nicht nur ich, sondern auch mein Forschungsdrang geweckt :)
Siro
genau so ist es!
Aber selbst wenn ich ein paar Sekunden später wieder den Arduino einstöpsele, und dann die COM (hier immer COM15, eine neue wird dann nicht generiert) wieder da ist, und somit dann auch über das ComPort-Verbinden-Widget angezeigt und angewählt werden kann, führt der Verbindungsversuch dennoch zu dem beschriebenen Fehler (error, exception)... :-/
Man müsste bei ComPort->nicht_verfügbar alle Programm- und System-Einstellungen und -Threads dazu/darüber schließen und resetten, bis wieder der alte ComPort auftaucht, dann wieder überall alles dazu neu starten, und die Verbindung automatisch wiederherstellen - und falls automatisch nicht möglich, dann wieder über das Verbinden-Widget manuell per Menü ermöglichen...
PS,
letztes Layout:
33960
updat:
ich habe jetzt die obige Funktion
void __fastcall TForm1::ComPort1Exception()
wieder komplett rausgenommen, sie hat letztendlich die Stabilität nicht deutlich verbessert.
Aber ich habe die Routinen fürs manuelle Verbinden leicht abgeändert, jetzt lässt sich nach USB-Unterbrechung die Verbindung ohne Störung wiederherstellen, wenn sie existiert, und es blockiert nichts mehr, wenn sie nach wie vor weg ist:
void __fastcall TForm1::Button1Click(TObject *Sender) // Button press: "Connect"
{
ComPort1->ShowSetupDialog();
try {ComPort1->Open();}
catch(...) { };
if(ComPort1->Connected ) {
// init program variables and widget states
}
}
void __fastcall TForm1::Button2Click(TObject *Sender) // Button press: "Disconnect"
{
if(ComPort1->Connected ) {
// try to send pin-stop msg to Arduino
strcat(msgcstr, "&_ALLPINS_=0;\n" );
ComPort1->WriteStr(msgcstr);
Sleep(100); // safety sleep
try { ComPort1->Close(); }
catch (...) { }
}
}
aktuelle, recht stabile und einigermaßen brauchbare Version:
https://github.com/dsyleixa/Borland-Cpp-Builder/tree/master/Projects/109_ArduinoCOM_RxTx
Hallo HaWe,
lebt das Projekt noch ?
Ich habe eben eine "uralte" Componente für die RS232 gefunden.
Hier können sogar Ereignisse abgefangen werden, wenn ein Comport hinzu oder auch entfernt wird.
Sie soll wohl auch unter Borland C++ Builder 1.0, 3.0, 4.0, 5.0, 6.0 laufen,
ich weis nur nicht wie man sie installiert.
Ich werde sie heute zunächts mal versuchen in mein Lazarus zu installieren.
Die Komponente ist aber Urheberrechtlich geschützt und darf nicht weiter gegeben werden:(
Ich habe sie damals mit dem Kauf des Buches erworben.
http://toolbox.reworld.eu/projekte/serial/index.html
Hallo HaWe,
lebt das Projekt noch ?
Ich habe eben eine "uralte" Componente für die RS232 gefunden.
Hier können sogar Ereignisse abgefangen werden, wenn ein Comport hinzu oder auch entfernt wird.
Sie soll wohl auch unter Borland C++ Builder 1.0, 3.0, 4.0, 5.0, 6.0 laufen,
ich weis nur nicht wie man sie installiert.
Ich werde sie heute zunächts mal versuchen in mein Lazarus zu installieren.
Die Komponente ist aber Urheberrechtlich geschützt und darf nicht weiter gegeben werden:(
Ich habe sie damals mit dem Kauf des Buches erworben.
http://toolbox.reworld.eu/projekte/serial/index.html
danke für die Info!
Klar lebt das Projekt noch, und es ist ja jetzt auch ziemlich stabil. Bleibt jetzt allerdings erst mal so wie es ist, auch mit dem ComPort (Freeware). https://github.com/dsyleixa/Borland-Cpp-Builder/tree/master/Projects/109_ArduinoCOM_RxTx
Nach Möglichkeit würde ich doch auch gern auf dem Raspi so etwas mit qtcreator machen, siehe anderer Thread! https://www.roboternetz.de/community/threads/72898-qtcreator-auf-Raspi-welches-gutes-deutsches-Tutorial-mit-versch-Programmbeispielen?p=649910&viewfull=1#post649910
Update zur seriellen Komponente:
Ich habe das Package "Serial44" in Lazarus installiert und ausprobiert, läuft auch.
Es gibt ein Ereignis OnCOMRemoved.
Wenn bei geöffneter Schnittstelle nun der USB Stecker gezogen wird,
verzweigt die Software in dieses Ereignis.
Ich hab mir das mal im Source Code angesehen.
Hier wird die Windows Message WM_DEVICECHANGE ausgewertet.
Eine Beschreibung gibt es hier:
https://docs.microsoft.com/en-us/windows/desktop/devio/wm-devicechange
Man muss aber die WindowsProg irgendwie umgeleitet werden, damit diese Message auch abgefangen werden kann.
Ich denke aber, Du solltest vorerst bei deiner Variante bleiben.
Siro
oderlachs
31.01.2019, 15:49
Hallo HaWe !
Ich habe mir mal den Download zu Gemühte gezogen....läuft der auch auf 64Bit, ich meine BCB ? Sonst brauche ich das erst gar nicht brennen...
Ich hatte ja von Delphi 2 bis 7 so alles von Borland/Inprise/ usw.. aber unter 64Bit nix zu machen ..schade um das Geld. Aber nun nur fürs Hobby 3stellige Summen investieren, da bleib ich bei Atmels und PICs... ;)
Gruss
Gerhard
Bei mir läuft es auf einem Windows 10 Rechner 64Bit.
Das Programm muss aber immer mit rechter Maustaste und "Als Administrator" ausführen gestartet werden.
Sonst bekommst Du merkwürdie Fehlermeldungen beim Ausführen.
Weil mein Delphi6 auch nur noch Probleme machte, bin ich umgestiegen auf das FREIE Lazarus und bereue es nicht,
gibt es solch freie, hervorragende Versionen nicht auch für C ?
Hallo HaWe !
Ich habe mir mal den Download zu Gemühte gezogen....läuft der auch auf 64Bit, ich meine BCB ? Sonst brauche ich das erst gar nicht brennen...
Ich hatte ja von Delphi 2 bis 7 so alles von Borland/Inprise/ usw.. aber unter 64Bit nix zu machen ..schade um das Geld. Aber nun nur fürs Hobby 3stellige Summen investieren, da bleib ich bei Atmels und PICs... ;)
Gruss
Gerhard
@oderlachs: ich habe Win7/64, läuft automatisch mit meinem Standard-Benutzer (allerdings hat der auch admin-Rechte). Auch der Vorgänger BCB 5 ließ sich ohne Probleme hier installieren.
@Siro: interessant, was es da alles gibt so mit COM, OnCOMRemoved, und dem ganzen Rest... 8)
oderlachs
31.01.2019, 19:17
@Siro :
Hatte mit Lazarus probiert, aber nur Probleme immer fehlten welche Packagen o.ä. . Habe es dann sein gelassen, weil ich unter Win kaum noch programmiere. Habe das ganze Delphi2....3..5 und alles was dazu sich angesammelt hatte gegen Porto verschenkt.
Darf gar nicht denken was das alles mal gekostet hatte, aber das war es mir wert.
Aber nun ärgern mich die PIC, ATMEL und STM Käfer genug, was soll ich mir damit nun auch noch den Kopf zerbrechen.
Wenn ich aber hier sowas lese, dann kribbelts doch noch nach alten Pascal, Delphi oder sonst was von Borland und Co.
@HaWe:
Habe CDs gebrannt und intalliert...menno wie in alten Zeiten die IDE Umgebung : :) :p
Gruss
Gerhard
@Siro :
@HaWe:
Habe CDs gebrannt und intalliert...menno wie in alten Zeiten die IDE Umgebung : :) :p
Gruss
Gerhard
fand ich auch :)
aber jetzt kommt die Herausforderung: ComPort Widget installieren...! :p
NumberFive
01.02.2019, 05:51
Falls es Interssant ist auch rein mit der Windows Api die RS232 zu lesen kann ich euch gerne meine Code geben. Für Threads gibt es jetzt auch C++ Standarts weiß aber leider nicht ob das Eurer Compiler das schon kann.
Falls es Interssant ist auch rein mit der Windows Api die RS232 zu lesen kann ich euch gerne meine Code geben. Für Threads gibt es jetzt auch C++ Standarts weiß aber leider nicht ob das Eurer Compiler das schon kann.
BCB 6 ist bestimmt schon über 10 Jahre alt, da gabs noch kein C++14 oder 11, AFAIK noch nicht mal C++04. Für Threads nutzt BCB kein pthread und auch nicht std::thread (zumindest nicht direkt), sondern ausschließlich das eigene TThread, was schon sehr kompliziert ist (noch brauche ich es nicht dringend, kommt aber evt noch).
Powered by vBulletin® Version 4.2.5 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.