MSBPackage Software Library für Multiplex Sensor Bus an Arduino Plattform

Hallo,
mal wieder eine Anfängerfrage

Habe eine Sketch der von einem 2S Lipo die Spannung misst, im Serialmonitor wird 7.35 angezeigt am Sender aber nur 0,7 wo habe ich da einen Fehler drin

Hier mal das Prog.

#include <NewSoftSerial.h>
#include <MSBPackage.h>

MSBProcess myMSB(4); // Benutze Pin 4 als MSB-Daten I/O

MSBPackage P1(1,3,0); // Sensor Klasse 1 (Voltage) / Adresse 3 / Startwert 0
MSBPackage P2(1,5,0); // Sensor Klasse 1 (Voltage) / Adresse 5 / Startwert 0


MSBPackage* HandleRequest(byte msbAdr)
{
if (msbAdr==P1.getAddress())
return &P1;
else if (msbAdr==P2.getAddress())
return &P2;
else
return NULL;
}


void LoopTimeMeasure()
{
unsigned long Time;

Time=micros();
loop(); // loop once
Time=micros()-Time;
//Serial.print("Looptime: ");Serial.println(Time);
}

void setup()
{

analogReference(INTERNAL);

Serial.begin(9600); // Für Debugausgaben - nicht vergessen den Serial Monitor auch umzuschalten

myMSB.onRequest(HandleRequest); // Request Handler Funktion (siehe oben) registrieren
/*
Aus Performance Gründen wird die HandleRequest Funktion nur für MSB-Adressen, die auf "aktiv" geschaltet sind,
aufgerufen. Dies erledigt die Methode setAddressActvie
*/
myMSB.setAddressActive(P1.getAddress()); // Addresse von MSB-Package P1 aktivieren
myMSB.setAddressActive(P2.getAddress()); // Addresse von MSB-Package P2 aktivieren



//analogReference(DEFAULT); // Messbereich des A/D Wandlers auf 0..Vcc (5V) setzen

//LoopTimeMeasure(); // Messung zu Testzwecken

/* Die MSBProcess Klasse übernimmt die Steuerung der loop-Funktion des Sketeches. Daher wird der Methode
StartLoop ein Verweis auf die loop()-Funktion des Sketches übergeben.
*/
myMSB.StartLoop(loop);

}

void loop()
{
int val;
unsigned int ra = 9700;
unsigned int rb = 1000;
float v;

val = analogRead(3);
//Serial.println(val);
v = (float)val * (float)(rb + ra) / (float)rb*1.1/1023;
Serial.println(v);

P1.setValue(v);

/*
s=ReadAndScaleAnalog(1);
P2.setValue(s);
*/
}

Im voraus besten Dank

Gruß Ralf
 
Auch wenn ich anscheinend zur Zeit der Einzige bin, der hier am versuchen ist die Telemetrie so zu verwenden, möchte ich doch meine Erfahrungen hier einstellen.
Dieser Sketch funktioniert schon mal sehr gut, wenn jemand von den Profis etwas sieht was total falsch ist bin ich über eine Info natürlich sehr dankbar.

#include <NewSoftSerial.h>
#include <MSBPackage.h>

float vout = 0.0;
float vin = 0.0;
float R1 = 99500.0; // resistance of R1 (100K) -see text!
float R2 = 9920.0; // resistance of R2 (10K) - see text!
int value = 0;


MSBProcess myMSB(4); // Benutze Pin 4 als MSB-Daten I/O


MSBPackage P1(1,3,0); // Sensor Klasse 1 (Voltage) / Adresse 3 / Startwert 0
MSBPackage P2(1,5,0); // Sensor Klasse 1 (Voltage) / Adresse 5 / Startwert 0


/* Callback-Routine die von der MSBProcess Klasse aufgerufen wird um das MSBPackage Objekt für
eine bestimme Adresse zu ermitteln. Eine Callback Routinen können in der Regel nach dem gleichen
Schema aufgebaut werden. Die HanldeRequest Routine muss einfach für die übergebene MSB Adresse (Parameter msbAdr)
das einen Zeiger auf das entsprechende MSBPackage Objekt zurückliefern.

*/
MSBPackage* HandleRequest(byte msbAdr)
{
if (msbAdr==P1.getAddress())
return &P1;
else if (msbAdr==P2.getAddress())
return &P2;
else
return NULL;
}


/*
Diese Funktion misst die Zeit in Microsekunden für einen Durchlauf der loop() Funktion und gibt sie auf der seriellen Schnittstelle aus.
Grund für diese Messung - siehe unten
*/

void LoopTimeMeasure()
{
unsigned long Time;

Time=micros();
loop(); // loop once
Time=micros()-Time;
//Serial.print("Looptime: ");Serial.println(Time);
}

void setup()
{


Serial.begin(9600); // Für Debugausgaben - nicht vergessen den Serial Monitor auch umzuschalten

myMSB.onRequest(HandleRequest); // Request Handler Funktion (siehe oben) registrieren
/*
Aus Performance Gründen wird die HandleRequest Funktion nur für MSB-Adressen, die auf "aktiv" geschaltet sind,
aufgerufen. Dies erledigt die Methode setAddressActvie
*/
myMSB.setAddressActive(P1.getAddress()); // Addresse von MSB-Package P1 aktivieren
myMSB.setAddressActive(P2.getAddress()); // Addresse von MSB-Package P2 aktivieren



analogReference(INTERNAL); // Messbereich des A/D Wandlers auf 0..Vcc (5V) setzen

LoopTimeMeasure(); // Messung zu Testzwecken

/* Die MSBProcess Klasse übernimmt die Steuerung der loop-Funktion des Sketeches. Daher wird der Methode
StartLoop ein Verweis auf die loop()-Funktion des Sketches übergeben.
*/
myMSB.StartLoop(loop);


}

/*
Die Funktion ReadAndScaleAnalog hat dient hier nur dazu die Werte der Arduino A/D Wandler auf den Messbereich
0...5V zu skalieren.
*/

float ReadAndScaleAnalog(int port)
{
long rawValue; // Als long deklariert damit in der Formel unten eine 32Bit Multipilaktion verwendet wird um Überläufe zu vermeiden
//const long MSBVoltageRange=50L; // A/D Wandler Range ist 0.5V, auf dem MSB entspricht das dem Wert 50 (0,1V Auflösung)
//const int ADMax=1023; // Der A/D Wandler hat eine Auflösung von 10 Bit - daher max. Wert 1023

rawValue=analogRead(port);
vout = (rawValue*1.1) / 1023;
vin = vout / (R2/(R1+R2));
//Serial.println(vin);
return float (vin);
}


/*
Die MSBProcess Klasse ruft die loop Funktion immer dann auf wenn Zeit ist. Zur Vermeidung von Problemen mit Reentrance und "Race Conditions"
wird die loop Funktion nicht unterbrochen wenn ein MSB-Adresstoken gesendet wurden. Es wird mit dem Senden des MSB Paketes daher gewartet, bis
die Loop Funktion zurückkehrt. Falls die Loop Funktion zu lange braucht wird der Sendevorgang verworfen. Um also zu vermeiden dass diese
ständig passiert muss die Loop Funktion eine entsprechend kurze Laufzeit haben. Idealerweise sollte die Laufzeit kürzer als 500us sein.
*/

void loop()
{
float s,t;

s=ReadAndScaleAnalog(0);
t=(s*0.9893) *10;// Korrekturwert
P1.setValue(t);
if (t < 113.21) P1.setAlarm(true); //Alarm ausloesen


//s=ReadAndScaleAnalog(1);
//P2.setValue(s);

}

Auch vielen Dank an Thomas für die tolle Library, tolle Arbeit

Gruß Ralf
 

-Bob-

User
Tolle Programmierarbeit!

Tolle Programmierarbeit!

Hallo zusammen,

bin gerade auf eure Software Entwicklung gestoßen. Tolle Arbeit habt ihr da geleistet!
Ich war noch nicht auf dem Arduino Platform unterwegs, sondern gestartet auf dem RaspberryPi und somit einiges in Python geschrieben.
Habe mittlerweile auch ein wenig Erfahrung mit den Prozessoren wie auf dem Trinket M0 oder ItsyBitsy M0... da komme ich mit CircuitPython einigermaße zurecht ;)

Hat einer von Euch die Multiplex Sensor Bus über Python oder CircuitPython mit z.B. Trinket M0 o.ä. probiert aus zu lessen? Gibt ers dort evtl. auch schon Lib's die man runterladen kann?

LG,

Bob
 

Gorbi

User
Hallo
Ich möchte einen MSB Datenlogger mit Arduino realisieren. Die Library von Thomas ist schon mal ein super Ausgangspunkt. Nur habe ich momentan das Problem, dass mit den Standardeinstellungen folgendes Werte geliefert werden:
M_Link_01.png

Eigentlich sollte nur auf der Adresse 0 die Empfängerspannung und auf der Adresse 1 der LQI Wert dargestellt werden. Es listen sich aber immer wieder falsche Werte auf der Adresse 0 auf. Z.B. ein falscher Volt-Wert (1.3V) oder sogar ein Ampere-Wert von 51.3A.
Ich benütze ein Arduino Pro Mini 3,3V 8MHz Board. An was könnte dies liegen ?
Viele Grüsse
Gorbi
 

Gorbi

User
und es scheint so, dass immer 5x richtige Werte aufgelistet werden und dann wieder die falschen Werte und anschliessend wieder 5x richtige Werte. Hinweis: LQI ist momentan auf 0 , weill ich noch keinen Sender eingeschaltet habe...
 

Gorbi

User
Super Input, dann wird dieses evtl. von dieser Library noch nicht berücksichtigt. Werde nun mal mit angeschlossenem GPS testen...
 
Alle 5 Zyklen werden die GPS Daten vom Empfänger mit der 2Byte Sequenz 0x80, 0x00 angefordert
Gut zu wissen. Ich glaube auch in den neueren Versionen der Multiplex MSB Spec ist das nicht dokumentiert.
Aber ich kann da mal fragen, ich habe gute Kontakte zu Multiplex ;)
Bei meinen Empfängern habe ich aber diese Sequenz noch nicht gesehen. Muss man das irgendwo "freischalten" oder hängt es vom Softwarestand des Empfängers ab?

@Gorbi : Danke für Deine Analyse.

Momentan fehlt mir leider die Zeit mich da intensiver drum zu kümmern. Man muss dazu sagen, das die MSB Monitor Demo eigentlich nur ein Testprogramm war, um die Daten vom MSB zu verifizieren. Die Library ist hauptsächlich dafür gedacht Sensoren zu implementieren. Und da die Sensoradresse 0 ja üblicherweise schon vom Empfänger belegt ist, stört es da nicht, das sie mit den GPS Daten nicht klarkommt.

Die Methode
C++:
 MSBProcess::ReadPackage(MSBPackage &Package)
ist nicht wirklich "Bullet-Proof" was das korrekte Timing des MSB Protokolls angeht.
Ich muss aber auch sagen, dass ich mittlerweile eine sehr stark weiterentwickelte Version der Library für meine eigenen Projekte verwende. Nur nutze ich keine Arduinos mehr, sondern STM32 Boards, sodass ein Backport doch etwas Aufwand wäre.

Die Library so umzubauen, das sie die GPS Koordinaten auswertet und anzeigt ist ein etwas größerer Umbau. Wenn es nur darum geht, sie zu ignorieren, dann müsste man die Methode MSBProcess::WaitForToken() etwas verändern.
Ich habe das unten mal - komplett ungetestet - reingeschrieben, wie es aussehen könnte:


C++:
byte MSBProcess::WaitForToken()
// Synchronizes with the MSB. Every MSB transaction starts with an address token (0x0..0x0f) followed by a
// idle time between 256 and 560 microseconds.
{
byte msbByte, nextByte;
bool GPSToken = false;

#if DEBUG_LEVEL == 3
  Serial.println("WaitForToken call");
#endif
  do
  {
    WaitNext(); // Wait until a byte is available
#if DEBUG_LEVEL == 3
  Serial.println("After WaitNext in WaitForToken call");
#endif
    msbByte= (byte)read();
#if DEBUG_LEVEL == 3
    Serial.print("::");Serial.println(msbByte,HEX);
#endif
  // TH: Anpassungen um GPS "Token" zu ignorieren
   if (msbByte == 0x80) {
        GPSToken = true;
    }
    else if (msbByte >= 0x0f)  {
         continue; // Tokens can only be 0x0..0x0f
   }
  // Ende  GPS Token
    WaitNext();
    nextByte=(byte)peek(); // Only look aheaed - dont read it....
     // TH: Anpassungen um GPS "Token" zu ignorieren
    if  (GPSToken &&  nextByte  == 0x00) {
        GPSToken = false;
        continue;
    }
    // Ende GPS Token
    if ( (nextByte >> 4) == msbByte )  // If next byte is the package header for the token
    {
      // Success
       return msbByte;
    }
      // Otherwise we will continue waiting
  } while (true);
}

Ich habe das jetzt hier nur im RC-Network Editor eingetippt, es ist also möglich, das es nicht mal compiliert. An besten ist, Du tauschst einfach die ganze Methode im der Datei MSBPackage.cpp aus.

@Gorbi: Wie fit bist Du in C/C++ Programmierung? Eventuell könnte ich Dir einigen Code aus meiner - nicht veröffentlichen - aktuellen Library schicken. Den müsste man relativ leicht an die alte Library anpassen können, der ist für das Monitoring wesentlich robuster als die alte ReadPackage Methode.
 

Gorbi

User
Hallo Thomas

Antwort auf Deine Frage:
"Wenn es nur darum geht, sie zu ignorieren, dann müsste man die Methode MSBProcess::WaitForToken() etwas verändern."

Es geht mir eigentlich nur darum, dass keine falschen Werte angezeigt werden.

Habe soeben Deine Aenderung 1:1 in der Datei MSBPackage.cpp eingefügt.

Die gute Nachricht: es lässt sich Compilieren

Leider ist das Resultat noch das selbe:
1673971699660.png


Leider bin ich C/C++ nicht fit genug, um Deine Library entsprechend Deinem neuen Code anzupassen.

Hinweis: Auf meinem RX-7-DR Empfänger ist die Software Version 1.26 installiert (welche die aktuellste Version für diesen Empfänger ist).

Viele Grüsse
Gorbi
 
Ich habe mich nur blind auf das verlassen was @ingo_s geschrieben hat. Ich habe jetzt mal meinen Kontakt bei MPX nach mehr Informationen gefragt. Muss mal mit dem Logik Analyser an einen meiner MPX Empfänger gehen…
 

ingo_s

User
Der MSB funktioniert auf Basis eines Idle Line Protokolls.
Wenn mehr als ein Zeichen nach Idle Line event/timeout gekommen ist, ist es kein Sensor Request.

Gruß Ingo
 
Wenn mehr als ein Zeichen nach Idle Line event/timeout gekommen ist, ist es kein Sensor Request.
Ich weiß sehr genau wie MSB funktioniert - zumindest den offiziell dokumentierten Teil. Die ReadPackage Methode meiner uralten Library von 2012 implementiert es aber nicht wirklich korrekt, sie war, wie oben beschrieben, nur für eine grobe Analyse gedacht.

Das 0x80, 0x00 führt in der oben dargestellten Methode WaitForToken dazu, das er das 0x80 ignoriert (weil nicht im richtigen range) und das 0x00 als Sensoradresse 0 interpretiert. Was dann passiert, hängt davon ab, wie der Datensatz nach dem 0x80,0x00 aussieht. Und das weiß ich eben nicht.

Mein Kontakt bei MPX hat mir übrigens geschrieben ihm ist keine solche 2 Byte Sequenz für den GPS bekannt :confused:

Weißt Du unter welchen Umständen der Empfänger sie ausgibt?
 
Zuletzt bearbeitet:

ingo_s

User
Alle Telemetrie-Empfänger geben den GPS Request jeden 5. MSB Zyklus immer aus, seit es den GPS Sensor gibt.
 

Anhänge

  • msb_gpsreq.jpg
    msb_gpsreq.jpg
    111,9 KB · Aufrufe: 45
  • msb_gpsreq2.jpg
    msb_gpsreq2.jpg
    116 KB · Aufrufe: 43
Ja ok, ich kann es reproduzieren:
1674071708376.png


Ich habe mich nun gewundert, warum eines meiner - wenigen - Arduino Projekte, in OLED Telemetrie Display, dieses Problem nicht hat.
Scheinbar liegt es daran, dass ich für dieses Projekt den ReadPackage Methode etwas "spezifikationskonformer" gemacht habe.

@Gorbi
Ich habe diese Version mal hier hochgeladen: https://bitbucket.org/thornschuh/msbpackage-public-release/downloads/MSB_unofficial_180123.zip

Bitte einfach beide enthaltenen Verzeichnisse komplett austauschen. Ich habe jetzt gerade leider weder die Zeit es selber zu testen, noch genau zu schauen was alles gegenüber die ursprünglichen Version verändert wurde.
Vielleicht am Wochenende, aber bin mir nicht sicher. Wie gesagt, eigentlich mache ich mit Ardunios und der "offiziellen" Ardunio IDE nichts mehr. Wenn überhaupt nutze ich dann Platformio.

Gruß
Thomas
 

Gorbi

User
Hallo Thomas
Zuerst ein riesen Dankeschön, dass Du dich hier Support lieferst!
Ich habe mit Deinen neuen Dateien getestet. Es gibt nun keine falschen Werte mehr. Das einzige was jetzt noch "unschön" ist:
1674231913493.png


Viele Grüsse
Gorbi
 

Gorbi

User
Hallo
Eine weiter Frage ist aufgetaucht. Kann man mit einem Arduino Nano auch ein GPS Empfänger anschliessen und die GPS Werte auf den Multiplex Bus ausgeben? Also 1x serielle Schnittstelle für GPS und 1x serielle Schnittstelle für Multiplex BUS ?
Viele Grüsse
Gorbi
 

Gorbi

User
Und noch eine Frage: kann man mit dieser Library gleichzeitig Werte auf den Multiplex Bus senden und alle Werte des Multiplex BUS loggen ?
Sofern dies alles geht, könnte man den SM Modellbau GPS Logger mit Arduino realisieren...
 
Eine weiter Frage ist aufgetaucht. Kann man mit einem Arduino Nano auch ein GPS Empfänger anschliessen und die GPS Werte auf den Multiplex Bus ausgeben? Also 1x serielle Schnittstelle für GPS und 1x serielle Schnittstelle für Multiplex BUS ?
Grundsätzlich ja. Macht aber keinen Spaß und ist viel Gebastel. Problem mit den AVR8 MCUs ist, das sie nur eine Hardware UART (serielle Schnittstelle) haben, und die beim Standard Arduino "Programmiermodel" für die Programmierung und die Debug Ausgabe schon belegt sind.
Dann muss man alles andere per Software Serial bedienen und muss schon ziemlich drauf achten, das man dabei keine Timing Probleme bekommt. Mann kann sich natürlich damit behelfen, das man die Schnittstellen abwechselnd bedient, sprich wenn man Daten vom GPS liest, ignoriert man den MPX Bus einfach so lange.

Es gibt diverse Alternativen:
Und noch eine Frage: kann man mit dieser Library gleichzeitig Werte auf den Multiplex Bus senden und alle Werte des Multiplex BUS loggen ?
Nicht direkt, wie gesagt die Monitor Funktion dient eher testzwecken. Wenn Du es einfach machen willst. wechselt Du halt immer ab:
Alle paar Monitoring Durchläufe fragst Du den GPS Sensor ab, und gehst dann in den MSB "Sende Betrieb" bis die Werte gesendet wurden.

Wenn man das richtig sauber machen will, programmiert man sowas Interrupt getrieben, die Arduino Methode mit Polling-Loops hat da so ihre Schwächen. In der Praxis reicht aber das, was ich oben beschrieben habe, aus, wenn man nicht den Anspruch hat, keinen Sensorwert auf dem Bus zu verpassen.

Ich freue mich ja über Deinen Enthusiasmus, aber Du schreibst ja auch:
Leider bin ich C/C++ nicht fit genug, um Deine Library entsprechend Deinem neuen Code anzupassen.
Wenn Du sowas wie den SM Modellbau GPS Logger selber realisieren willst, kannst Du meine Library durchaus als Grundlage nehmen, aber Du wirst schon etwas tiefer einsteigen müssen, um die eventuell dabei auftretenden Probleme zu lösen. Das ist durchaus schaffbar, auch wenn man noch nicht viel Erfahrung hat - irgendwo muss man ja mal anfangen.
Ich kann Dir auch im vernünftigen Rahmen Fragen beantworten, aber bitte komme nicht auf die Idee, mir nicht funktionierenden Code mit der Frage "warum geht der nicht?" zu schicken. Das ist die Essenz beim Programmieren, das man herausfindet warum etwas nicht geht ;)

Gruß
Thomas
 
Ansicht hell / dunkel umschalten
Oben Unten