ich habe hier einen Deltang TX1-K1 2,4GHz RC Sender.
Diesen muss per serial die einzelnen Poti und Schalter Positionen bekommen.
Aber hier hab ich ein Verständnis Problem.
In der Beschreibung steht
Byte 1 Checksum (sum of bytes 2-16 cast to 1 byte)
Byte 2 Not used (can be any value)
Bytes 3-16 2 bytes per channel with following struc
ture 0b000 CCC 9876543210
9876543210 = 10bit channel position
DT receivers with a serial output can be used to pr
ovide an input to Tx1 for testing.
Dort steht ja immer was von Byte aber sind das nicht alles Bits,
Denn Zusammen (so wie ich es versteh sind es 16 Bits also 2 Byte oder ein Word)
Also wäre der komplette Datenstrom für Kanal 3=Rud in Mittlerstellung z.b. so
000 unbenutzt
010 für Kanal 3
100000000 512 für die Mittelstellung (0-1023)
Oder hab ich da einen Denkfehler?
Und wo kommt da jetzt die Checksumme hin?
Die Checksumme ist die Summe aller Bytes auf Byte gecastet
Wenn man die Daten mal in Gruppen von 4 Bit aufspaltet sieht man etwas besser was was ist:
000C CC98 7654 3210
Also bekommst du die Nutzdaten einfach so:
byte high = ...;
byte low = ...;
unsigned int data = word(high, low);
data = data & 0x03FF;
Das & am Ende setzt die oberen 6 Bits auf 0
Das hat man dann 7 mal für alle Kanäle. Also 1 + 1 + 7 * 2 = 16 Bytes
Hallo Fennek,
Danke für deinen Antwort.
Kling zu mindestens einleuchtend.
Ich habe das mal zum Teil in ein Beispiel umgesetzt.
int test;
byte hi, lo;
byte dumy = 0; // für Beyt 2
//diese Werte müssen zum highByte dazu gerechnet werden (4=Kanal 1,... 28=Kanal 7) um den Kanal zu bestimmen.
int kanal[7] = {4, 8, 12, 16, 20, 24, 28};
void setup(){
Serial.begin(9600);
}
void loop(){
for (int i=0; i <= 6; i++){
test=random(0, 1023); //zufallswert für die einzelnen Kanäle
hi = highByte(test); //in case you're wondering this should be 0xA
lo = lowByte(test); // and this should be 0xB.
hi=hi+kanal[i];
Serial.print(hi, HEX);
Serial.println(lo,HEX);
}
delay(1000);
Serial.println("#######");
}
Nun ist die Frage, ob ich das so richtig umgesetzt habe und wie erstelle ich jetzt die Checksumme?
Die y in der ersten teile sind eigentlich Sonderzeichen y mit Pünktchen drüber.
Lasse ich mir die Daten auf einem andern Serial Monitor im RAW Format ausgeben wird folgendes angezeigt.
test<0D><0A>b<00><03><07><0B><0F><13><17><1B>testende
hier finde ich aber die 62, von der Checksumme nicht wieder.
aber dafür habe ich ja das Externe Programm genommen was dies kann.
Daher meine frage wegen der Checksumme. Diese müsste doch dann auch auftauchen
oder habe ich dann wieder einen Denkfehler?
Gruß ingo
jep ich hab es auch gerade gesehen.
Nach dem mir eingefallen ist das ich ja Zeilenumbruch habe (Serial.println) als als Raw Daten 0d 0a
da kam mir der Gedanke, dass es bei dem b ja laut Zeichentabelle ja Hex werte gibt, und dementsprechend ist es 62.
Wenn ich es so ausgebe wie du es oben geschrieben hast.
for(int i = 0; i < 16; i++)
{
Serial.print(data[i],HEX);
Serial.print(",");
}
bekomme ich es ja so ausgegeben.
62,0,3,FF,7,FF,B,FF,F,FF,13,FF,17,FF,1B,FF,
Laut Vorgabe ist für die Übertragung ja LSB first angegeben.
Wäre das dann so richtig?
Da die Seriale Schnittstelle vom Sendemodul nicht mit 5 V arbeitet,
habe ich ein level shifter hier nach gebaut.
So habe es jetzt erfolgreich mit Zufallswerten getestet.
Vielen Dank noch mal an Serenifly für die Unterstürzung
/* the TX requires 16 bytes
Byte 1 Checksum (sum of bytes 2-16 cast to 1 byte)
Byte 2 Not used (can be any value)
Bytes 3-16 2 bytes per channel with following structure 0b000 CCC 9876543210
- 000 = not used (normally zeros)
- CCC = channel number (0=Thr, 1=Ail, 2=Ele, 3=Rud, 4=Gear, 5=Aux1, 6=Aux2)
- 9876543210 = 10bit channel position
so send something like:
sum needs calculated
0x00 second byte is not used
B000000PPPPPPPPPP // all chan send same data PPPPPPPPPP is a 10 bit int or 8 would be easier depending on the accuracy you need
B000001PPPPPPPPPP
B000010PPPPPPPPPP
B000011PPPPPPPPPP
B000100PPPPPPPPPP
B000101PPPPPPPPPP
B000111PPPPPPPPPP
*/
void setup(){
Serial.begin(115200);
}
void loop()
{
byte data[16]; // Array of 16 Byte
data[1] = 0;
for(int i = 0; i < 7; i++)
{
unsigned int value = random(0, 1023); //The Random Value for each channel.
byte high = highByte(value) | (i << 2); //Hige and
byte low = lowByte(value); //Low Byte from the 10 Bit of Channlel Value
data[i * 2 + 2] = high; // Storing the high and
data[i * 2 + 3] = low; // low share of each channel in byte array
}
unsigned int checksum = 0; // Checksumme set to 0
for(int i = 1; i < 16; i++) // Current calculate checksum
{
checksum += data[i];
}
data[0] = (byte)checksum;
delay(500); // can be determined even reduced or eliminated
for(int i = 0; i < 16; i++)
{
}
Serial.write(data,16); // Output of the byte array at the transmitter module
}
Zum Binden des Empfängers muss der Bindestecker auf dem Empfänger gesteckt werden und dann mit Strom versorgt werden.
Dann wird das Sendemodule mit Strom versorgt (Der Arduino muss dafür nicht angeschlossen werden).
Jetzt muss Pin 1 vom Sendemodul mit GND für ca. 2 Sec. verbunden werden (Obere und Untere Pin NICHT den Mitlernen Pin !!!)
Pinbelegung und Beschreibung -> http://www.micronradiocontrol.co.uk/docs/dt/dt-tx1-k1-1.pdf
wen der Bindevorgang abgeschlossen ist, den Empfänger ausschalten und den Bindestecker entfernen.
Nun kann das Sendemodul mit Strom und dem Aruino verbunden werden. zum Schluss den Empfänger mit Strom versorgen.
Wenn alles glatt gegangen ist, solltet ein Angeschlossenes Servo zufällige Positionen anfahren.
Winzige Kleinigkeit:
deine Zufalls-Werte gehen nur bis 1022. Der zweite Parameter ist exklusiv, d.h. rnd(0, n) erzeugt Zahlen von 0 bis n-1. Keine Ahnung wieso, aber das ist auch in einigen anderen Sprachen so.