Hallo, bevor ich zu meinem Problem komme, möchte ich euch schildern was ich überhaupt mache. Ich habe mit C++ eine Software für das Raspberry Pi geschrieben. Diese ist wesentlich in zwei Funktionen unterteilt: 1. Eine Funktion regelt den kompletten I²C verkehr, an dem einige Sensoren und DAC's hängen. D.h. I²C auslesen und den Wert in eine Membervariable einer Klasse speichern, oder Membervariable auslesen und über I²C an DAC schreiben. 2. Die andere Funktion bietet eine Ausgabe der aktuellen Sensorwerte auf der Konsole. Das Programm läuft auch so, wie ich es mir vorstelle. Alle Werte werden grundsätzlich in Membervariablen von Klassen gespeichert, dem Thread habe ich die Referenz der Klassen übergeben. Diese beiden Funktionen sind durch Threads voneinander entkoppelt und laufen völlig unsynchronisiert. Dies würde ich auch gerne so beibehalten. Meine Frage ist nun: Was passiert, wenn ich in der einen Funktion z.B. eine Variable lese und die andere Funktion zu dem selben Zeitpunkt die selbe Variable beschreiben möchte? Ist dies theoretisch überhaupt möglich, die CPU arbeitet doch sowieso alles zyklisch ab? Dann noch eine kleine Frage: Wie ist es am einfachsten möglich die Variablen auf einer Homepage auszugeben? Mir geht es hier viel mehr um die Schnittstelle. Für C++ gibt es eine schöne SQL API, jedoch halte ich es ein wenig übertrieben für ca. 10 Werte eine ganze Datenbank anzulegen.
:
Bearbeitet durch User
Thomas P. schrieb: > Ist dies theoretisch überhaupt möglich, die CPU arbeitet doch sowieso > alles zyklisch ab? ja ist es, du musst dafür sorgen das das nicht passiert. Dafür kann man z.b. eine Mutex verwenden. > Dann noch eine kleine Frage: Wie ist es am einfachsten möglich die > Variablen auf einer Homepage auszugeben? ich habe meinem Programm einfach http beigebracht. Dann kann ich sehr einfach mit Javascript auf mein Programm zugreifen. Wenn du die werte nicht speichern musst, dann ist das der einfachste Weg. Wenn du sie eh irgendwo speichern musst, dann würde ich es über eine SQL-DB machen.
Thomas P. schrieb: > Meine Frage ist nun: Was passiert, wenn ich in der einen Funktion z.B. > eine Variable lese und die andere Funktion zu dem selben Zeitpunkt die > selbe Variable beschreiben möchte? > Ist dies theoretisch überhaupt möglich, die CPU arbeitet doch sowieso > alles zyklisch ab? Wenn verschiedene Prozesse auf dieselbe Ressource zugreifen (z.B. auf eine Datei, auf einen Speicherbereich), dann braucht man Mechanismen zur Synchronisierung. Die bekommt man vom Betriebssystem. Stichworte dafür sind unter anderem Semaphoren und Mutex. > Dann noch eine kleine Frage: Wie ist es am einfachsten möglich die > Variablen auf einer Homepage auszugeben? Mir geht es hier viel mehr um > die Schnittstelle. Für C++ gibt es eine schöne SQL API, jedoch halte ich > es ein wenig übertrieben für ca. 10 Werte eine ganze Datenbank > anzulegen. Wenn Du die Variablen nur einmal anzeigen und danach "vergessen" willst, musst Du sie auch nicht in eine Datenbank stecken. Ein Webserver kann seine Daten ja auch von woanders her bekommen, z.B. über eine Ethernet-Verbindung. Was für einen Webserver verwendest Du?
Hallo, für dein erstes Problem solltest Du dir einmal Mutex angucken. https://de.wikipedia.org/wiki/Mutex Dein Beispiel liest sich so, als wären die Zugriffe nicht zu häufig und auch nicht besonders lang, da kann man auch ein sehr einfaches busy-waiting selbst implementieren.
1 | // Memebervariable |
2 | bool busy = false; |
3 | |
4 | ... |
5 | |
6 | void machwas() { |
7 | while(busy); |
8 | busy = true; |
9 | // irgendwelche Operationen |
10 | busy = false; |
11 | } |
Zum zweiten: Wie wäre es mit Sqlite?
Thomas P. schrieb: > Meine Frage ist nun: Was passiert, wenn ich in der einen Funktion z.B. > eine Variable lese und die andere Funktion zu dem selben Zeitpunkt die > selbe Variable beschreiben möchte? Chaos! > Ist dies theoretisch überhaupt möglich, die CPU arbeitet doch sowieso > alles zyklisch ab? Das ist sehr wohl möglich. Die CPU kann zwar nur 1 Ding gleichzeitig machen (wenn's nicht ein multi-Core CPU ist), aber Zugriff auf Variablen ist nicht immer atomär. Um z.B. eine Variable um 1 zu erhöhen sind u.U. 3 Schritte notwendig: 1. Lese variable aus dem RAM 2. Inkrementiere den Wert 3. Schreibe neue Wert zurück. Zwischen jeden von diesen SChritten kann dein Thread unterbrochen werden von anderen Threads. Abhilfe schaffen hier Mutexes oder Semaphoren. > Dann noch eine kleine Frage: Wie ist es am einfachsten möglich die > Variablen auf einer Homepage auszugeben? Mit einem Webserver. > Mir geht es hier viel mehr um > die Schnittstelle. Für C++ gibt es eine schöne SQL API, jedoch halte ich > es ein wenig übertrieben für ca. 10 Werte eine ganze Datenbank > anzulegen. SQLite vielleicht? oder schreibe die Werte einfach in einer Textdatei und lese die im Webserver aus.
Thomas P. schrieb: > Meine Frage ist nun: Was passiert, wenn ich in der einen Funktion z.B. > eine Variable lese und die andere Funktion zu dem selben Zeitpunkt die > selbe Variable beschreiben möchte? Wenn eine skalare "volatile" Variable maximal 32 Bits gross ist und nicht mit Gewalt misaligned wurde, dann sind einzelne lesende und schreibende Zugriffe des ARM im RasPI atomar. In dem Fall ist es möglich, die Variable ohne Mutex zu lesen. Voraussetzung dafür ist aber, dass der schreibende Thread immer korrekte Werte und keine unkorrekten Zwischenzustände schreibt und der lesende Thread nie schreibt.
:
Bearbeitet durch User
Danke erst einmal für die vielen Antworten. Das ganze ist übrigens eine Studienarbeit. Letztendlich soll es ein Labornetzteil werden, welches man über ein Webinterface ansteuern kann. Momentan arbeite ich an dem Prototypen und befasse mich mit der Regelungstechnik. Parallel dazu plane ich das Webinterface. Mark B. schrieb: > Was für einen Webserver verwendest Du? Ich wollte Apache als Webserver nutzen. Würde es jetzt auch mit einer Datenbank lösen. Fande dies nur ein wenig wie mit Kanonen auf Spatzen geschossen, bzw. war dies die Aussage von meinem Betreuer. Dem konnte ich aber zustimmen. Der Webserver, sowie die ganze Software läuft auf dem Raspberry Pi Programmieren wollte ich das ganze mit HTML, CSS, PHP, SQL, Javascript Ich werde diese Thematik wohl nochmals ansprechen, da ich die C++ API sehr angenehm finde, so müsste ich das Rad auch nicht neu erfinden. Dann wohl im Zusammenhang mit Sqlite. Aber nochmal zurück zu der Synchronisierung. Etwas verstehe ich noch nicht so ganz Ich meine, die CPU macht doch nichts anderes als auf den Adressbus des RAM die Adresse zu schreiben, dann "CHIP ENABLE" auf "1" setzen und schließlich den Wert vom Datenbus lesen. Anschließend wieder "CHIP ENABLE" auf "0". Dazwischen wird die CPU doch nicht unterbrochen? Also, sofern ich doch wirklich nur einen Kern nutze kann doch eigentlich nichts passieren? Ich meine klar, die Abarbeitung der beiden Threads wäre vollkommen zufällig. Aber das wäre für meinen Fall nicht schlimm, denn es ist nur eine Anzeige. Bei Bedarf habe ich geplant über die Konsole mit
1 | std cin<< ... |
einen Wert für die DAC zu übergeben. Dies aber wirklich sehr selten. Deswegen geht es mir wirklich nur darum, was passiert wenn z.B. zwei Kerne in dem selben Moment auf eine Ram Adresse zugreifen. Normal müsste dies doch aber sowieso verhindert werden oder nicht?
:
Bearbeitet durch User
Thomas P. schrieb: > Ich meine, die CPU macht doch nichts anderes als auf den Adressbus des > RAM die Adresse zu schreiben, dann "CHIP ENABLE" auf "1" setzen und > schließlich den Wert vom Datenbus lesen. Anschließend wieder "CHIP > ENABLE" auf "0". Dazwischen wird die CPU doch nicht unterbrochen? Das ist zwar etwas arg vereinfacht dargestellt, aber im Prinzip korrekt, solange es sich um Datentypen handelt, die vom Compiler als ein einziges Speicherwort behandelt werden, und so lange nur ein Prozessorkern im Spiel ist. Bei einem AVR an Stelle des ARM ist freilich bereits ein 16-Bit Datentyp nicht mehr atomar, weil 2 unterbrechbare Zugriffe erfolgen. > Also, sofern ich doch wirklich nur einen Kern nutze kann doch eigentlich > nichts passieren? Es sei denn zu baust beispielsweise sowas: var <<= 8; var |= c; Denn dann entsteht ein ungültiger Zwischenzustand. Bei Verwendung mehrerer Kerne lohnt sich ein Blick in das von dem Prozessor und dem entsprechenden Speicherbereich definierten "memory consistency model". Weil dann deine Vereinfachung nicht mehr greift - es gibt dank der Caches nicht nur eine Speicherstelle für eine bestimmte Adresse, sondern potentiell mehrere.
:
Bearbeitet durch User
http://en.cppreference.com/w/cpp/atomic/atomic Thomas P. schrieb: > C++ API Was soll das sein, meinst du die STL?
Thomas P. schrieb: > Dann noch eine kleine Frage: Wie ist es am einfachsten möglich die > Variablen auf einer Homepage auszugeben? Mir geht es hier viel mehr um > die Schnittstelle. Für C++ gibt es eine schöne SQL API, jedoch halte ich > es ein wenig übertrieben für ca. 10 Werte eine ganze Datenbank > anzulegen. Schreibe einfach die Daten in JSON-Notation in eine Textdatei auf die der Webserver Zugriff hat. Auf der Webseite benötigst etwas Javascript und auf dem Server ein Script in PHP, Perl oder Python - C geht wohl auch. Ist alles kein Hexenwerk und Du findest genug Beispiele im Netz. Google einfach nach JSON. Zeno
Daniel A. schrieb: > Was soll das sein, meinst du die STL? Ich meinte damit eigentlich eine SQL API für C++. Zeno schrieb: > Schreibe einfach die Daten in JSON-Notation in eine Textdatei auf die > der Webserver Zugriff hat. Auf der Webseite benötigst etwas Javascript > und auf dem Server ein Script in PHP, Perl oder Python - C geht wohl > auch. > Ist alles kein Hexenwerk und Du findest genug Beispiele im Netz. Google > einfach nach JSON. > > Zeno Werde mich da mal einlesen, danke!
Thomas P. schrieb: > Programmieren wollte ich das ganze mit HTML, CSS, PHP, SQL, Javascript Ist ja ein ganz schöner Zoo. In node.js, serverseitigem Javascript, ist ein Webserver das "Hello World". Hier ein Beispiel:
1 | //Lets require/import the HTTP module
|
2 | var http = require('http'); |
3 | |
4 | //Lets define a port we want to listen to
|
5 | const PORT=8080; |
6 | |
7 | //We need a function which handles requests and send response
|
8 | function handleRequest(request, response){ |
9 | response.end('It Works!! Path Hit: ' + request.url); |
10 | }
|
11 | |
12 | //Create a server
|
13 | var server = http.createServer(handleRequest); |
14 | |
15 | //Lets start our server
|
16 | server.listen(PORT, function(){ |
17 | //Callback triggered when server is successfully listening. Hurray!
|
18 | console.log("Server listening on: http://localhost:%s", PORT); |
19 | });
|
das stammt von hier, aber andere finden sich zu Hauf http://blog.modulus.io/build-your-first-http-server-in-nodejs Diesen HTML, CSS und eventuel nötiges clientside Javascript ausliefern zu lassen, ist kein wirkliches Problem. Ein paar tausend Werte in einem serverseitigen Javascript Array zu halten, ist kein Hexenwerk. Dieses als json in einen File zu schreiben, wenn man sich mal etwas merken will, auch nicht. Das einzige, was fehlt, ist das Auslesen des I2C Busses. Aber auch dafür gibt es bestimmt etwas https://www.npmjs.com/package/i2c-bus Das ganze könnte also ein einziges node.js Programm sein. C++, Apache, PHP und SQL kommen da nicht mehr vor. MfG Klaus
Thomas P. schrieb: > Dann noch eine kleine Frage: Wie ist es am einfachsten möglich die > Variablen auf einer Homepage auszugeben? Mir geht es hier viel mehr um > die Schnittstelle. Für C++ gibt es eine schöne SQL API, jedoch halte ich > es ein wenig übertrieben für ca. 10 Werte eine ganze Datenbank > anzulegen. Ja, man kann eine Datenbank als Middleware verwenden (spanabhebende Datenverarbeitung), Sie ist aber eigentlich für Persistenz gedacht. Link doch einfach eine HTTP Library zu deinem bestehenden C++ Programm und lass das Programm selbst die HTTP requests beantworten. Dann entfällt auch die Notwendigkeit, für Interprozesskommunikation. mfg Torsten P.S.: Wenn sich die Variablen nach Änderung automatisch in der Web-Oberfläche aktualisieren sollen, dann könntest Du z.B. Sioux: https://github.com/TorstenRobitzki/Sioux verwenden.
:
Bearbeitet durch User
Thomas P. schrieb: > Für C++ gibt es eine schöne SQL API Es gibt schon seit Urzeiten Cookies, und seit HTML5 gibt es localstorage. Da muss man sich halt einlesen. Zuerst mal wäre die Frage, ob die Werte überhaupt länger gespeichert werden müssen als die Anwendung läuft bzw. die Seite angezeigt wird. Georg
Klaus schrieb: > Ist ja ein ganz schöner Zoo. ;-) Danke für die restlichen Infos Klaus! Klaus schrieb: > Das einzige, was fehlt, ist das Auslesen des I2C > Busses. Aber auch dafür gibt es bestimmt etwas Sehr sehr sehr ungern! Ich habe mir da einen Wolf geschrieben und nun steht alles in C++. AD-Wandler auslesen, DA-Wandler beschreiben, habe auch einen I2C <=> HD44780 Display Adapter gebaut und die Software geschrieben um ein LCD am Bus zu betreiben. Das möchte ich jetzt ungern über den Haufen werfen. Georg schrieb: > Da muss man sich halt einlesen. Genau! Ich studiere (zum Glück?/leider?) Elektrotechnik ;-). Webprogrammierung wird nicht gelehrt. Aus dem Grund bin ich froh über die vielen Tipps, da ich nicht auf Anhieb weiß wonach ich wirklich suchen soll und welches Tool mir die Funktionen bietet. Jedoch bereitet mir dieses Gebiet neben der Regelungstechnik in der letzten Zeit viel Spaß. Georg schrieb: > Zuerst mal wäre die Frage, > ob die Werte überhaupt länger gespeichert werden müssen als die > Anwendung läuft bzw. die Seite angezeigt wird. Jain, im Moment nicht ABER, ich könnte mir in Zukunft eine Funktion vorstellen, die mir in einem Graphen z.B. die Leistungskurve der letzten 5 Minuten anzeigt. Da wäre es schon von Vorteil 100-500 Messwerte über paar Minuten zu speichern. Aber ansonsten sollten nur die aktuellen Werte angezeigt werden.
:
Bearbeitet durch User
Thomas P. schrieb: > Sehr sehr sehr ungern! Ich habe mir da einen Wolf geschrieben und nun > steht alles in C++. Kenn ich, ging mir auch oft so. Ich habs später aber immer bereuht. Beim zweiten Mal schreibt man meist besseren Code. Buch das erste Mal als Trainingseinheit ab. MfG Klaus
Thomas P. schrieb: > Ich habe mit C++ eine Software für das Raspberry Pi geschrieben. Diese > ist wesentlich in zwei Funktionen unterteilt: > > 1. Eine Funktion regelt den kompletten I²C verkehr, an dem einige > Sensoren und DAC's hängen. > D.h. I²C auslesen und den Wert in eine Membervariable einer Klasse > speichern, oder Membervariable auslesen und über I²C an DAC schreiben. > 2. Die andere Funktion bietet eine Ausgabe der aktuellen Sensorwerte auf > der Konsole. Das Programm läuft auch so, wie ich es mir vorstelle. > > Alle Werte werden grundsätzlich in Membervariablen von Klassen > gespeichert, dem Thread habe ich die Referenz der Klassen übergeben. > > Diese beiden Funktionen sind durch Threads voneinander entkoppelt und > laufen völlig unsynchronisiert. Dies würde ich auch gerne so > beibehalten. Wie lange dauert eine Abfrage aller Sensoren? Wenn die Antwort "weniger als 500 Millisekunden" ist, dann kannst Du Dir den ganzen Zinnober mit Multithreading, Synchronisierung etc. sparen. Und warum C++? Machst Du irgendwelche aufwändigen Berechnungen, riesige Speicheroperationen, oder irgendetwas in der Art? Ich meine, den größten Teil der Zeit wartet Dein "leseSendordaten()"-Thread doch eh nur darauf, daß die Sensoren ihre Antworten liefern. Wofür? Donald E. Knuth wußte schon in den Siebzigern: "Premature optimization is the root of all evil". Versteh' mich bitte nicht falsch, ich mag C++ auch, aber Du betreibst damit eine Laufzeitoptimierung, die an dieser Stelle höchstwahrscheinlich gar nicht nötig ist, sondern nur unnötige Fehlerquellen beinhaltet, die Wartbarkeit einschränkt und den Aufwand für die Entwicklung erhöht. > Meine Frage ist nun: Was passiert, wenn ich in der einen Funktion z.B. > eine Variable lese und die andere Funktion zu dem selben Zeitpunkt die > selbe Variable beschreiben möchte? > Ist dies theoretisch überhaupt möglich, die CPU arbeitet doch sowieso > alles zyklisch ab? Nein, tut sie nicht. Der Kernel (genauer: der Scheduler) verwaltet -- auch auf einem Single-Core -- die CPU-Zeit und teilt sie den Threads für Dich vollkommen unvorhersehbar zu bzw. entzieht sie ihnen. Wenn das in genau dem Zeitpunkt passiert, in dem der Thread ein read-modify-write auf eine Variable macht, oder mitten in einem Schreibzugriff, der mehrere Zyklen dauert, ... there be dragons. > Dann noch eine kleine Frage: Wie ist es am einfachsten möglich die > Variablen auf einer Homepage auszugeben? Mir geht es hier viel mehr um > die Schnittstelle. Wenn Du mich fragst:
1 | #!/usr/bin/env python
|
2 | from flask import Flask, render_template |
3 | from smbus import SMBus |
4 | from collections import OrderedDict as odict |
5 | |
6 | app = Flask(__name__) |
7 | |
8 | # name, address, command, converter/validator
|
9 | app.config['sensors'] = ( |
10 | ('sens1', 0x30, 3, lambda val: val), |
11 | ('sens2', 0x40, 6, lambda val: val), |
12 | ('sens3', 0x50, 9, |
13 | lambda val: 3.5 * val if val > 3 and val < 6 else -1), |
14 | )
|
15 | app.config['bus'] = SMBus(0) |
16 | |
17 | @app.route('/') |
18 | def index(): |
19 | result = odict() |
20 | for name, addr, cmnd, conv in app.config['sensors']: |
21 | result['name'] = conv(app.config['bus'].read_byte_data(addr, cmd)) |
22 | return render_template('index.html', sensors=result) |
23 | |
24 | if __name__ == '__main__': |
25 | app.run() |
Die Funktion "index()" ist ein Request-Handler, der beim Aufruf der Root-Seite ("/") aufgerufen wird, dann die konfigurierten Sensoren ausliest, die gelesenen Werte mit den konfigurierten Validator- und Konvertierfunktionen (siehe Sensor 'sens3') behandelt, die Ergebnisse dann in das Template 'index.html' einsetzt und zuletzt die solcherart erzeugte Webseite ausliefert. Natürlich kann dieses Skript erweitert werden, um Eingaben über HTML-Formulare entgegenzunehmen und an Deine DACs zu übergeben. Dazu dann noch ein kleines Systemd-User-Unitfile zum Starten, Stoppen etc., und fertig ist die Laube. > Für C++ gibt es eine schöne SQL API, Welche denn, wenn ich fragen darf? > jedoch halte ich es ein wenig übertrieben für ca. 10 Werte eine ganze > Datenbank anzulegen. Eine Datenbank ist sinnvoll, wenn Du die Daten dauerhaft persistieren willst, sonst nicht. Wenn Du nur eine Momentanaufnahme haben willst, ist eine Datenbank so überflüssig wie ein Kropf und kein Ersatz für eine ordentliche Interprozesskommunikation -- für so etwas gibt es UNIX- und Netzwerk-Sockets, (Named) Pipes, Shared Memory, ... und wenn Du auf die Daten mit sehr vielen Prozessen gleichzeitig zugreifen willst, dann ist ein simpler Key-Value-Store wie Redis viel sinnvoller. Der Memory Footprint von Redis ist winzig im Vergleich zu einem echten Datenbankserver wie PostgreSQL, Redis kann veraltete Daten nach einer gewissen Zeit automatisch wieder vergessen und ist als In-Memory-System um Größenordnungen schneller als jeder Datenbankserver.
Karl Käfer schrieb: > Wie lange dauert eine Abfrage aller Sensoren? Wenn die Antwort "weniger > als 500 Millisekunden" ist, dann kannst Du Dir den ganzen Zinnober mit > Multithreading, Synchronisierung etc. sparen. Die AD-Wandler werden maximal 20-50 mal in der Sekunde ausgelesen. Im Prinzip kann ich mir das mit dem Multithreading sparen. Ich benötige das Multithreading nur, falls ich mir über die Konsole via SSH die Messwerte anzeigen lassen möchte, oder um DAC Werte zu schreiben. Karl Käfer schrieb: > Und warum C++? Machst Du irgendwelche aufwändigen Berechnungen, riesige > Speicheroperationen, oder irgendetwas in der Art? Ich meine, den größten > Teil der Zeit wartet Dein "leseSendordaten()"-Thread doch eh nur darauf, > daß die Sensoren ihre Antworten liefern. Wofür? Dazu eine Vorgeschichte. Geplant ist eine Labornetzteilplatine welche mir geregelt 0-25V, 0-2,5A liefern kann. Die Platine soll inklusive Kühlrippe im Prinzip alles beinhalten. Das heißt wiederum, ich kann diese modular aufbauen. Lasse ich mir nun z.B. 4 Platinen entwickeln, kann ich über Klassen ganz einfach in meinem Code eine weitere Platine erzeugen mit allen Memberfunktionen und Variablen. Ich übergebe einfach nur an den Konstruktor die Adressen von den DAC und ADC und fertig. Das gleiche gilt natürlich auch für den LCD. Ich habe mal ein Blockschaltbild angehangen. Karl Käfer schrieb: >> Für C++ gibt es eine schöne SQL API, > > Welche denn, wenn ich fragen darf? Mysql bietet für C++ fertige header an, die man in seinen Code einfach einbindet.
Thomas P. schrieb: > Karl Käfer schrieb: >> Wie lange dauert eine Abfrage aller Sensoren? Wenn die Antwort "weniger >> als 500 Millisekunden" ist, dann kannst Du Dir den ganzen Zinnober mit >> Multithreading, Synchronisierung etc. sparen. > > Die AD-Wandler werden maximal 20-50 mal in der Sekunde ausgelesen. Dann dauert ein Lesezyklus also maximal 50 ms -- das merkst Du weder auf der Kommandozeile, noch im Webbrowser. > Im > Prinzip kann ich mir das mit dem Multithreading sparen. Ich benötige das > Multithreading nur, falls ich mir über die Konsole via SSH die Messwerte > anzeigen lassen möchte, oder um DAC Werte zu schreiben. Wenn das ohnehin über ein Webinterface zugänglich ist, kannst Du dieses Webinterface über ein Kommandozeilenprogramm benutzen. Der w3m und andere Kommandozeilenbrowser existieren, dann sieht die Sache sogar gut aus, und verskripten kannst Du sowas ganz einfach und mit jeder Skriptsprache. Und obendrein fallen dabei auch noch diverse andere nette Schnittstellen mit minimalem Konfigurationsaufwand aus der Tüte: Seriell über Stiftleiste und/oder USB, WLAN, ... > Karl Käfer schrieb: >> Und warum C++? Machst Du irgendwelche aufwändigen Berechnungen, riesige >> Speicheroperationen, oder irgendetwas in der Art? Ich meine, den größten >> Teil der Zeit wartet Dein "leseSendordaten()"-Thread doch eh nur darauf, >> daß die Sensoren ihre Antworten liefern. Wofür? > > Dazu eine Vorgeschichte. > Geplant ist eine Labornetzteilplatine welche mir geregelt 0-25V, 0-2,5A > liefern kann. Die Platine soll inklusive Kühlrippe im Prinzip alles > beinhalten. Das heißt wiederum, ich kann diese modular aufbauen. Lasse > ich mir nun z.B. 4 Platinen entwickeln, kann ich über Klassen ganz > einfach in meinem Code eine weitere Platine erzeugen mit allen > Memberfunktionen und Variablen. Ich übergebe einfach nur an den > Konstruktor die Adressen von den DAC und ADC und fertig. Das gleiche > gilt natürlich auch für den LCD. > > Ich habe mal ein Blockschaltbild angehangen. Das spricht für Objektorientierung, aber nicht unbedingt für C++. Python, Perl und andere Skriptsprachen können ebenfalls objektorientiert benutzt werden, und das oben von mir gezeigte Python-Flask-Skript benutzt mit den anonymen lambda-Funktionen für die Konvertierung und Validierung ja auch so etwas wie eine Objektorientierung für Arme. Natürlich kann man sowas auch in richtige Python-Klassen verpacken:
1 | class Sensor(object): |
2 | def __init__(self, address, command, validator): |
3 | self.address = address |
4 | self.command = command |
5 | self.validator = validator |
6 | |
7 | def read(self, bus): |
8 | res = bus.read_byte_data(self.address, self.command) |
9 | return (name, self.validator(res)) |
10 | |
11 | ## usage: |
12 | adc1 = Sensor(0x30, 3, lambda val: val) |
13 | wert = adc1.read(app.config['bus']) |
Das kannst Du ganz genau so modular zusammentackern wie mit C++, zu einem Bruchteil der Zeit, des Aufwandes und potentieller Fehlerquellen. Nun verstehe ich natürlich, daß Du die bereits investierte Arbeit und Zeit nicht wegwerfen willst, wer macht sowas schon gerne. Aber ich befürchte, daß Du Dir die Sache durch Deine ursprüngliche Designentscheidung und Dein Festhalten daran unnötig verkomplizierst. Andererseits ist das, was Du Dir ausgedacht hast, eine schöne Übung in Multithreading und Synchronisation, Interprozesskommunikation, Schnittstellendesign und C++. Wenn Du Zeit hast und etwas lernen willst, dann magst Du vielleicht einfach beide Varianten implementieren, Deine und meine. Dann hast Du einen ziemlich guten Lernerfolg in C++ und UNIX-Systemprogrammierung und siehst andererseits auch mal, wie sich sowas schnell, einfach, effizient und robust umsetzen läßt. Viel Spaß und Erfolg dabei! > Karl Käfer schrieb: >>> Für C++ gibt es eine schöne SQL API, >> >> Welche denn, wenn ich fragen darf? > > Mysql bietet für C++ fertige header an, die man in seinen Code einfach > einbindet. Oh, MySQL. Ich dachte, Du meintest eine generische SQL Api wie SQLAPI, nur in hübscher. Ich persönlich habe MySQL vor vielen Jahren den Rücken gekehrt und setze lieber auf PostgreSQL, für das es mit libpqxx eine (wie ich finde) sehr schöne, moderne und elegante C++-Api gibt. Aber, wie gesagt, für eine reine Interprozesskommunikation würde ich keine Datenbank benutzen, sondern entweder die klassischen UNIX-Technologien oder einen modernen in-memory KeyValue-Store wie Redis. ;-)
Thomas P. schrieb: > Sehr sehr sehr ungern! Ich habe mir da einen Wolf geschrieben und nun > steht alles in C++. AD-Wandler auslesen, DA-Wandler beschreiben, habe > auch einen I2C <=> HD44780 Display Adapter gebaut und die Software > geschrieben um ein LCD am Bus zu betreiben. Das möchte ich jetzt ungern > über den Haufen werfen. Wenn Du das schon alles gemacht hast, dann behalte es. Sehe in Deinem C Programm einfach nur noch ne Möglichkeit vor, die gewünschten Daten in eine Datei zu schreiben. Wenn Du es auf einer Webseite darstellen willst, dann ist, wie schon geschrieben, die JSON-Notation eine geeignete Methode. Ich habe mal ein Beispiel für so eine Datei angehängt. Das ist eine Datei von meiner Wetterstation. Auf der Webseite benötigst Du etwas Javascript um -einen Request an den Server zu senden (Daten abholen) -die (JSON) Daten auswerten -die dekodierten Daten in der Webseite darstellen. Auf dem Webserver benötigst Du ein Programm/Script um auf den Request antworten zu können. Da gibt es diverse Möglichkeiten. Einige hatte ich ja schon genannt. Klaus hatte ja noch serverseitiges Javascript genannt aber da kenne ich mich nicht so aus. Ich meine da auch mal was gelesen zu haben, daß es bei serverseitigem JS Sicherheitsprobleme geben kann. Aber wie gesagt ich kenne mich damit nicht so aus. Nach diesem beschriebenen Prinzip funktioniert meine Wetterwebseite schon einige Jahre. Übrigens auch auf einem Pi. Zusätzlich zur JSON-Datei schreibe ich die Daten in eine RRD-Datenbank und in eine fortlaufende CSV-Datei. Es gibt für jeden Tag eine CSV-Datei. Zeno
Zeno schrieb: > Wenn Du das schon alles gemacht hast, dann behalte es. Sehe in Deinem C > Programm einfach nur noch ne Möglichkeit vor, die gewünschten Daten in > eine Datei zu schreiben da muss er aber darauf achten, das es möglichst nicht auf dem SD-Karte landet, sonst ist sie recht schnell defekt. Man kann auch memcache verwenden, dafür gibt es eine C(++) Api und PHP kann auch darauf zugreifen. Dann läuft alles im RAM ab.
Peter II schrieb: > da muss er aber darauf achten, das es möglichst nicht auf dem SD-Karte > landet, sonst ist sie recht schnell defekt. > > Man kann auch memcache verwenden, dafür gibt es eine C(++) Api und PHP > kann auch darauf zugreifen. Dann läuft alles im RAM ab. Das hast Du natürlich recht und Dein Vorschlag vermeidet dies. Ich weiß ja nicht was er mit den Daten machen will. Wenn es über Memory läuft sind sie nach dem Ausschalten natürlich weg. Man kann ja auch ne USB-Platte an den Pi hängen. Nachteil man brauch für die Platte extra Netzteil. Ich habe es bei mir so gelöst: Bei mir sind es mehrere Pi die die Daten einsammeln. Diese hängen natürlich im Netzwerk. In diesem gibt es ein NAS-Platte für Datensicherung und so nen Kram. Auf dieser habe ich NFS-Space eingerichtet, auf den die Pi's und der Webserver Lese- und Schreibzugriff haben. Die Pi's und der Webserver mounten diesen Space und können darüber problemlos Daten austauschen. Auf dem NFS-Space liegen auch die erwähnten RRD-Datenbanken. NFS ist zwar eine ältere Sache aus der Unixwelt, funktioniert aber sehr zuverlässig und ist in meinem Fall ideal. Zeno
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.