Wir haben nun das Zeitalter der KI erreicht, weshalb hier weniger Lösungen und mehr das Technik Tagebuch Posts kommen. Lösungen verlinke ich Kategorisch extra auf den weiteren Seiten des Blogs
Dienstag, 13. Juni 2017
Netduino Netzwerk Adresse ändern
Seit langer Zeit hatte ich wieder einen Grund gefunden meinen Netduino aus zupacken und ein altes Projekt zu prüfen. Eigentlich suche ich eine Lösung, wie man eine Verbindung zum Netduino und einem SignalR Service herstellen kann. Zuvor hatte ich vor Jahren ein Beispiel mit WCF geschrieben, dass am Ende sogar relativ einfach war. Aber jetzt zum eigentlichen.
Netzwerk, Socket und Netduino
Mein Beispiel Projekt verwendete den SimpleSocket aus der Bibliothek Toolbox (https://netmftoolbox.codeplex.com/). Damit lässt sich in wenigen Codezeilen eine Verbindung zu einem anderen System über Netzwerk herstellen. Der Folgende Code Beispiel zeigt den Grundsätzlichen Aufbau einer Verbindung.
SimpleSocket socket = new IntegratedSocket(this._IpAddress, 80);
socket.Connect();
socket.Send("Hallo Welt");
socket.Close();
Das Problem
Die Verbindung blieb immer bei der Methode "socket.Connect()" stehen. Das kann dadurch festgestellt werden, wenn nach einer Weile nicht das gewünschte Ergebnis kommt und man dann die Pause Taste für das Debuggen klickt.
Ursache Prüfen
Meine Vermutung war, dass ich anscheinend nicht die richtige Adresse im Netduino Plus eingestellt hatte. Also startete ich aus dem Ordner "C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.3\Tools" das Programm MFDeploy.exe. Über den Menü Punkt "Network" (Target > Configuration > Network) kann die Adresse eingerichtet werden.
Falsche Adresse
Wie ich bereits vermutet, hatte ich noch eine andere IP Adresse sowie auch eine andere Adresse für Gateway eingestellt. Nach dem ich die gewünschte Netzwerk Adresse eingetragen hatte, sollten die Einstellungen nach dem Click auf den "Update" Button auf den Netduino geschrieben werden. Doch dies wurde verhindert und ich erhielt einen Hinweis.
Lösung
Kommt diese Hinweismeldung "Unable to erase configuration sector memory", dann muss einmal der Befehl "Reboot and Stop" (Plug-in > Debug > Reboot and Stop) gesendet werden.
Bevor die Konfiguration für das Netzwerk wieder aufgerufen werden kann, musste ich auf die Nachricht "Reboot and Stop Complete" abwarten, die wiederum im unteren Rahmen angezeigt wurde.
Nun kann die Adresse geändert und erfolgreich auf dem Netduino geschrieben werden. Nach dem klicken "Update" sollte sich das Konfigurationsfenster schließen und im unteren Rahmen "Signature PASS" oder zumindest "Chk signatu" stehen.
Jetzt kann das Netduino Projekt mit dem SimpleSocket neu gestartet werden und die Verbindung mit der Ziel Adresse sollte hergestellt werden.
Dienstag, 14. Oktober 2014
Intervallaufnahme mit der Kamera ohne Interne Funktion
Die Funktion für eine Intervallaufnahme ist simpel, daher ist es für mich unverständlich, warum nicht zumindest die Systemkameras von der Nikon 1 Serie in ihren Modellen diese Option anbieten. Nun gut, dies war kein Kaufkriterium, wäre aber schön gewesen. Ich selbst verwende die Nikon 1 J3 (die J1 hat die Intervallaufnahme), allerdings sollte mein Beispiel auch für andere Kameras funktionieren. Grundsätzlich geht es darum einen Servo auf den Auslöser zu drücken. Für diesen Zweck habe ich aus Aluminium Eckschienen eine Vorrichtung gebaut.
Wie schon am Bild zu erkennen ist, sollten zum Schutz die Alu Eckschienen nach der Verarbeitung abgerundet und ggf. mit Filzaufklebern beklebt werden.
Die Materialliste:
- Alu Eckschienen ca. 20cm
- Filzaufkleber
- ein paar 3mm Schrauben und entsprechende Muttern
- Mini Servo mit ca. 10 Ncm
- Eine passende Schraube zur Kamera dass mit dem Stativ auch verschraubt werden kann. (siehe folgendes Bild)
Zum Ansteuern wird der Netduino mit einem passenden Shield zur Ansteuerung für einen Servo verwendet. Die geringe Belastung kann das Board verkraften. Bei Normalen und größeren Servos wird eine Externe Stromversorgung notwendig.
Der Aufwand des Programmcodes gestaltet sich übersichtlich. Zusehen ist, dass noch ein Analoger Wert eingelesen wird, worauf ich im nächsten Absatz zu sprechen komme.
| public class Program // Ansteuerung des Servos für den Auslöser. // Led Status wiedergeben. // Einen Zähler. // Nach wie viel Sekunden soll ausgelöst werden. public static void Main() // Mittelstellung bei 1,5ms while (true) // Hinweis: bei Netduino 1 wird ein Wert gelesen von 0 bis 1023. _Servo.SetPulse(periode, 1710); // 1710 ist eine Einstellung, an meiner Kamera // Zähler Zurücksetzten. _IntervallCounter++; // Zurückstellen. |
Das gleiche nochmal für den Arduino.
| #include <Servo.h> void setup(){ // Dient zu Einstellgunszwecke void loop() |
Jetzt fehlt noch ein fester Wert für den Druckpunkt. Der Potentiometer wird an Pin A1 angeschlossen, die Spannungsversorgung muss beim Netduino mit 3,3V angelegt werden. Das Auslesen des Stellwertes erfolgt beim Netduino über Debug.Print() und wird über die Ausgabe angezeigt. Beim Arduino wird der Stellwert über dem Serial Monitor wiedergegeben. Je nach Belastung kann die Versorgung über USB instabil werden. Das zeigt sich dann, wenn der Servo beim Drücken des Auslösers leicht zittert. Später, mit einem 9V Akku oder Netzteil, sollten diese Schwierigkeiten nicht mehr auftauchen. Ansonsten muss der Servo einen eigenen Stromkreis erhalten, um zu verhindern, dass die Versorgung des Mikrocontrollers zu sehr schwankt und so zu einem Neustart des Programms führt.
Zu den Einstellungen der Kamera. Um ein schnelles Auslösen der Kamera zu ermöglichen, sollte auf den Kreativ Modus gewechselt werden. Die Blende, die Verschlusszeit und der Fokus sind am besten manuell festzulegen. Spätestens bei Nachtaufnahmen kommt man an diesen Einstellungen nicht vorbei. Achja, das Dateiformat JPG ist für die Ausgabe zu empfehlen. Mit dem NEF bzw. RAW ist das Bearbeiten im Video Schnittprogramm kaum machbar.
Tipp zur Nachtaufnahme: acht bis fünfzehn Sekunden für die Verschlusszeit bei maximal offener Blende reichen aus. Zu lange Belichtung führt dazu, dass die Sterne Streifen bilden, also praktisch gesehen wird die Erdrotation sichtbar. Die idealen Nächte mit Sternenhimmel sind in der Zeit um Neumond. Die besten Bedingungen sind Orte, die so dunkel sind, dass beim Hinabsehen die eigenen Füße nicht mehr zu sehen sind.
Nun noch ein paar Aufnahmen, die ich mit meiner Apparatur erstellt habe.
Zu guter Letzt auch noch der Quellcode zum Herunterladen.
Dienstag, 15. April 2014
Luftdrucksensor BMP085 mit dem Netduino - Höhenangabe (Teil 4)
Mit dem Luftdruck lässt sich in etwa auch die Höhe ermitteln. Allerdings ist dieser Wert bedingt verwendbar. Zum einen muss der Sensor beim einschalten mit der aktuellen Höhe kalibriert werden und zum anderen gibt es verschiedene Formeln für die Berechnung, die spezielle Anforderungen erfüllen.
Wie immer kommt es darauf an, was man möchte. Im Dokument selbst, wird nur der Luftdruck verwendet. Die Formel hierfür ist nicht sonderlich komplex und lässt sich daher in wenigen Codezeilen umsetzen.
| altitude = 44330 * (1 – (p/p0) 1/5.255) |
| Nach dem Dokument auf Seite 14, ist diese Formel zu verwenden. |
Auffällig dürften die festen Zahlenwerten sein, die auf den ersten Blick keinen Bezug darstellen. Die Beschreibung für diese Sache ist leider ohne Begründung, was mir selbst etwas Kopfzerbrechen bildet und mich auf den Weg brachte im weiten Internet nach einer plausiblen Antwort zu suchen. Leider mit geringen Erfolg und steht daher noch auf der TODO Liste.
Wer bereits für den Arduino nach einem Beispiel Code gesucht hat, so findet sich oft die folgende Methode mit etwas anderen Werten, die jedoch alle das selbe Ergebnis erzielen.
| float calcAltitude(float pressure){ |
Bei der Formel aus dem Dokument und das was sich aus dem Arduino Umfeld findet, fällt auf, dass die Temperatur nicht berücksichtigt wird. Das führt bedingt zu Ungenauigkeiten. Nach etwas längerem suchen fand ich die Seite Explorermagazin, auf der verschiedene Formeln vorgestellt werden. Am Ende habe ich mich für die Variante 2b entschieden.
| p(h) = p(h0) * (1 - 0.00651 K/m *(h-h0)/T0)**5.255 h: Höhe (in Meter) über NN. |
Die Höhenberechnung wird in Abhängigkeit der Temperatur berücksichtigt, die hier Minus 0,651 Kelvin pro 100 Meter (-0,65K/100m) sind. Der Wert 5,255 wurde leider hier ebenfalls nicht beschrieben. Daher belasse ich diesen Punkt und stelle die Formel für die Zielumsetzung um.
Kommen wir zum Programmcode in C#. Leider oder auch gut so, ist dass die Formel nicht in eine Zeile programmiert werden kann und sich somit in einzelnen Schritten abgebildet werden muss.
| // Zweite Variante für die Höhen Berechnung |
| Anlegen der Member Variablen mit den Werten der Höhe 0 Meter und 1013,25hPa. |
Den Quellcode den ich zur Verfügung stelle, hat noch zusätzlich die herkömliche Variante der Höhenberechnung, die nur mit dem Luftdruck berechnet wird. Für den Post verbleibe ich mit der Folgenden Methode, die mit Hilfe des Luftdrucks und der Temperatur ausgeführt wird, die sich aus der Formelumstellung ergab.
| // Die Höhenberechnung aus Luftdruck und Temperatur. // Relative Höhe des Vorangehenden Luftdrucks hinzu rechnen |
Eines sollte gleich klar sein. Das richtige Ergebnis ist nur draußen zu erhalten. Luftdruck und Außentemperatur wirken zusammen. Zuletzt noch ein Hinweis zur gemessenen Luftdrucks. Der Wert ist in Pascal und muss für die Berechnung in Hektopascal umgerechnet werden, das am Anfang der Mehtode umgerechnet wird.
Effektiv erzielt die Berechnung der Höhe ähnliche Ergebnisse wie die Formel ohne Temperatur Bezug. Für den Einsatz für Quadrocopter lohnt sich der Einsatz über fünf Meter Höhe. Für genaue und präzise Erfassung der Höhe, bleibt der Einsatz von Ultraschall- oder Optischer Distanzsensoren.
Nun das war meine kleine Serie über den Luftdruck Sensor und dessen Umsetzung. Wenn Fragen sind, können diese über die Kommentar Funktion gestellt werden.
Beispiel Programm zum Herunterladen (C# und .NET Micro Framework)
Dienstag, 31. Dezember 2013
Luftdrucksensor BMP085 mit dem Netduino - Kalibrieren (Teil 3)
Um überhaupt mit den gelesenen Daten etwas anfangen zu können, müssen diese umgerechnet werden. Bevor dies geht, müssen am Anfang Kalibrierungsdaten ermittelt werden. Im Handbuch ist in kurzer Form beschrieben, in welchen Schritten gelesen und umgerechnet wird. Fummelig ist die Umrechnung für den Luftdruck. Es sind eine Menge Variablen, welche die Kalibrierungswerte aufnehmen und andere, um die Ergebnisse zwischen zu speichern. Zu der Klasse “BMP085” aus den zwei vorigen Posts kommen nun weitere Methoden hinzu. Damit der Post nicht zu sehr in die Länge geht, habe ich nur die neuen und geänderten Inhalte zu der Klasse abgebildet.
Als erstes müssen die Kalibrierungskoeffizienten ermittelt werden, die in den Member abgelegt werden. Die Namen für die Variablen wurden direkt aus dem Datenblatt übernommen, was zugegeben etwas unschön aussieht.
| // Kalibrierungswerte private long _B5; |
Nicht alle Werte werden in ein “short” umgewandelt, denn drei davon kommen als “uint”. Daher muss am Ende der Methode für das Byte Shifting entschieden werden, als welcher Typ zurück gegeben wird.
| // Fragt den Sensor den einzelnen Kalibrierungswert ab return 0; |
Anschließend lassen sich mit einer weiteren Methode die Kalibrierungswerte in einem Block abrufen. Die Rückgabe kommt als Objekt und muss per Unboxing in den entsprechenden Typ angegeben werden, bevor es an die Member Variable zugewiesen wird.
| // Kalibrierungswerte einlesen. |
Die Temperatur umzurechnen ist relativ trivial, auch wenn die Variablen Namen aus dem Handbuch dies etwas kryptisch wirken lassen. Davon sollten Sie sich nicht abschrecken lassen. Ich hätte da lieber andere Namen, aber halten wir uns an das Handbuch.
| // Temperatur Berechnen _B5 = x1 + x2; // Temperatur wird in 0,1°C Schritten gelesen |
Den größten Teil bildet die Umrechnung für den Luftdruck, was auf den ersten Blick Augenkrebs verursachen kann. Leider ist im Datenblatt keine genauere Beschreibung darüber vorhanden, wie sich das Ganze zusammensetzt.
| // Luftdruck Berechnen // x1 = (b2 * (b6 * b6) / (2 hoch 12)) / (2 hoch 11) // x1 = ac3 * b6 / (2 hoch 13) // b7 = (up - b3) * (50000 >> oss) long p = 0; // x1 = (p / (2 hoch 8)) * (p / (2 hoch 8)) return p; |
Nun kann in der Klasse BMP085 die Methode “ReadSensorData” mit den zwei Methoden ergänzt werden. Dazu erhält das Daten Objekt SensorData zusätzlich zwei weitere Properties für das Abspeichern von Temperatur und Luftdruck.
| public class SensorData public double Temperatur = 0; public override string ToString() |
| // Sensor Daten lesen // Roh Luftdruck lesen // Temperatur berechnen // Luftdruck Berechnen |
Nun ist die Klasse schon fast fertig. Aber es sind noch weitere Möglichkeiten offen, die ich in den nachfolgenden Blog Posts beschreiben werde.
Sonntag, 29. Dezember 2013
Luftdrucksensor BMP085 mit dem Netduino - Temperatur (Teil 2)
Wie bereits in meinem vorigen Post beschrieben, soll nun der Temperatur Wert ausgelesen werden. Der Teil für das Auslesen des Luftdrucks wird in eine Methode ausgelagert. Die Methode “ReadSensorData” gibt die zwei Werte in einem Daten Objekt zurück, das zunächst angelegt wird. Die “ToString” Methode im Daten Objekt wird überschrieben, um die Wiedergabe beider Werte simpel zu gestalten.
| public class SensorData public override string ToString() |
Nach dem das Daten Objekt vorliegt, kann die Methode “ReadSensorData” für die Rückgabe umgeschrieben werden. Die Methode nimmt nun das Daten Objekt als Referenz an. Für das Einlesen der Temperatur wird ein zweites Byte Array benötigt zum zwischenspeichern. Die Methode “GetTemperature” ähnelt der Ausführung von “GetPressure”. In einen späteren Post wird dort nochmal eingegangen, wie sich diese Sinnvoll zusammenlegen lassen.
| public class BMP085 : I2CDevice // Standard Mode // Empfangspuffer für Luftdruck // Empfangspuffer für Temperatur // Konstruktor mit vererbten Konstruktor von der I2CDevice Klasse // Sensor lesen und im Referenz Daten Objekt die Eigenschaftswerte überschreiben. // Luftdruck lesen // Temperatur Wert lesen // Kurz abwarten if (Write(new byte[] { 0xF6 }) == 0) if (Read(_ReceiveT) == 0) return (int)_ReceiveT[0] << 8 | _ReceiveT[1]; // Luftdruck Wert lesen // Kurz abwarten // Sensor Ergebnis abfragen // Ergebnis einlesen // Ergebnis per Byteshifting // Sendet den Inhalt des Byte Arrays return Execute(trans, _Timeout); // Liest den zu empfangene Byte Array return Execute(trans, _Timeout); |
Für die Ausgabe muss zunächst das Daten Objekt “SensorData” angelegt werden in der “Main” – Methode. In der Schleife wird das Daten Objekt als Referenz an die Methode “ReadSensorData” übergeben, dass nun die Eigenschaftswerte überschreibt. Und am Ende wird die Ausgabe wieder über “Debug.Print()” ausgegeben.
| public class Program public static void Main() while (true) // halbe Sekunde warten |
Die Schaltung bleibt weiterhin so bestehen, wie im ersten Teil. Jetzt dürfte die Ausgabe in Visual Studio wie im folgendem Bild aussehen.
Die beiden Werte sind natürlich noch Roh Werte und müssen zunächst umgerechnet werden. Daher wird im nächsten Blog Post das Kalibrieren und Umrechnen behandelt.
Freitag, 27. Dezember 2013
Luftdrucksensor BMP085 mit dem Netduino - Luftdruck (Teil 1)
Für das Erfassen von Wetterdaten eignet sich der Sensor BMP085. In erster Linie misst dieser den Luftdruck, kann jedoch auch die Temperatur messen. Dennoch bleiben wir zunächst bei einem kurzen Testprogramm für den Netduino.
| public class BMP085 : I2CDevice // Standard Mode // Empfangspuffer // Konstruktor mit vererbten Konstruktor von der I2CDevice Klasse // Kurz abwarten // Sensor Ergebnis abfragen // Ergebnis einlesen // Ergebnis per Byteshifting // Sendet den Inhalt des Byte Arrays return Execute(trans, _Timeout); // Liest den zu empfangene Byte Array return Execute(trans, _Timeout); |
Der Programmcode ermöglicht den Messwert im Sensor auszulesen. Nun muss im Program.cs die Klasse initialisiert werden und in der Schleife der Sensor immer wieder gelesen werden.
| public class Program public static void Main() while (true) // halbe Sekunde warten |
Wie nun die Kalibrierung funktioniert, erkläre ich in einem späteren Post. Nun zu der Verkabelung. Leider war der Sensor in der Fritzing Software in einer anderen Version. Diesmal sollten diese Fotos ausreichen, um zu zeigen, wie dieser Sensor verkabelt wird.
| Verkabelung bei einem Netduino Plus 1 |
Mit dem Netduino 2 und dem Netduino Plus 2 sind die Anschlüsse für den I²C auf die andere Seite gewandert.
| Verkabelung bei einem Netduino Plus 2 |
Wenn alles soweit klappt, dürfte nun im Visual Studio – Ausgabe Fenster der Messwert angezeigt werden.
Wie sich zeigt, bildet das kleine Programm eine einfache Möglichkeit den Sensor in Betrieb zu nehmen. Im nächsten Blog Post wird auf den Temperatur Sensor eingegangen, der hier ebenfalls auf dem Sensor Modul enthalten ist.
Dienstag, 29. Oktober 2013
PWM / PPM Frequenz an Brushless Motoren mit dem Netduino
Im Modellbau ist es üblich, dass die Frequenz für PWM bei 50Hz zum Ansteuern von analogen Servos und analogen Motorenreglern verwendet wird. Wer allerdings einen digitalen Servo oder eine digitale Motorensteuerung hat, kann hier eine weit höhere Frequenz verwenden. Besonders bei Modellhelikoptern oder auch bei den Quadrocoptern wird dies gefordert. Der Grund liegt hier klar auf der Hand, dass die Periodendauer wesentlich kürzer wird und somit pro Sekunde mehrmals ein neuer Steuerwert festgelegt werden kann. Bei 50Hz liegt die Periodendauer bei 20 Millisekunden, wovon 1 bis 2 Millisekunden das eigentliche Steuersignal (Duration) abbilden und in den restlichen 18 Millisekunden nichts weiter kommt. Daher habe ich mir gedacht, wie sieht eigentlich dann das Signal aus, wenn es auf 200Hz gesetzt wird.
| Beispiel Darstellung mit 50Hz PWM Signal mit einer Periodendauer von 20ms. |
| Beispiel Darstellung mit 200Hz PWM Signal mit einer Periodendauer von 5ms |
Schnell stellt sich heraus, dass sich grundsätzlich die Periodendauer und die LOW Pegellänge verändert, wie in den Bildern zu sehen ist. Die Duration bleibt unverändert und wird auch nicht skaliert, was das Programmieren des Signals einfach gestaltet. Im nächsten Programm Beispiel wird der erste PWM Port mit 20ms und der zweite Port mit 5ms Periodendauer initialisiert.
| // PWM Signal mit 20 Millisekunden Periode und 1 Millisekunde Duration // PWM Ausgänge starten // Analogen Eingang einrichten zum verstellen der Duration für die PWM Ausgänge double addDuration = 0; while (true) // Neuen Duration Wert zuweisen zwischen 1000µs bis 2000µs |
| Dieser Inhalt wird in der ‘Main()’ Methode ausgeführt. |
Mit dem analogen Eingang wird die Duration neu festgelegt, was mit einem Potentiometer bestimmt werden kann.
| Hier sollten möglichst schwache Servos verwenden werden, um den Netduino nicht sonderlich zu belasten andernfalls ist eine externe Versorgung notwendig. |
Für diesen Test funktionierten auch die analog Mini Servos, wenn auch nicht ideal (Leider keine passenden Digital Servos). Dreht man nun an dem Potentiometer, so kann man erkennen, dass der Servo am Port mit 200Hz schneller reagiert und der andere mit 50Hz nachzieht.
| PWM Steuerung mit verschiedenen Frequenzen |
| Highspeed Aufnahme mit zwei Servos. Der mit dem Kreuzarm, wird mit 200Hz betrieben. Der mit den einzelnen Arm, wird mit 50Hz angesteuert. |
Zudem benötigt die Klasse beim Zuweisen einer neuen Duration etwas Zeit. Grund hierfür ist, dass beim Zuweisen gewartet wird (siehe dazu ggf. Interrupt). Das bedeutet, wenn im Programmcode die Duration einen neuen Wert erhält, so kann es einige Millisekunden dauern, bis es an der Stelle weiter geht. Deutlich wird dies beim Zeitstoppen. Die folgenden Ergebnisse zeigen die Dauer eines Durchlaufens vom Einlesen des Analogen Wertes und anschließend das Zuweisen der beiden PWM Ports.
| Netduino Plus 2 | Netduino Plus 1 |
Eigentlich sollte hier die Iterationsdauer fast immer gleich sein, aber sie springt teilweise von 2100 Mikrosekunden bis über 4000 Mikrosekunden bei dem Netduino Plus 1. Der Netduino Plus 2 ist da schon wesentlich konstanter und ist im Schnitt eine halbe Millisekunde schneller, was allein der höheren Taktrate zu verdanken ist.
Zusammengefasst ist klar, dass eine höhere Steuerfrequenz weniger Zeit benötigt, und die zu steuernde Einheit in kürzerer Periodendauer ein neues Steuersignal erhält. Die Frequenzen weit über 50Hz sind aber gut für digital Servos und ESC Regler (Brushless Regler) geeignet. Wie hoch die maximale Steuerfrequenz sein darf ist von der Abtastung des Reglers abhängig.
Verwendete Inhalte:
- Netduino Plus und Netduino Plus 2
- Analog Servo; 4,8V-6V (oder besser ein Digital Servo)
- Potentiometer
- Kabel
Die Beispiel Solution mit .NET Micro Framework 4.2 zum Downloaden.
Gehäuseentwurf für Signalleuchten (Part 2)
Heute morgen sah ich mir mein Druckergebnis an und dachte: Nein, das sieht nicht nach einem Kristall aus. Also im Internet gesucht und ein T...
-
Brushless am Arduino zum testen. Vielleicht für den einen oder anderen Interessant, wie eigentlich ein Brushless Motor angeschloss...
-
Arduino Nano 3.0 und Modul mit einem Beschleunigungssensor Zugegeben habe ich etwas lange gebraucht, um zu verstehen, wie ich diesen S...
-
Auf dem Markt gibt es viele verschiedene Module an Motortreibern. Diesmal verwende ich einen recht einfac...







