Hey zusammen. Ich habe grad ein kleines Problem. Ich versuche die daten meines SCD30 CO2 Sensors in ein array zu speichern (via I2C an meinem PIC) und die daten dann über UART an mein Travos3 modul zuschicken. Das gleiche Modul habe ich auch an meine PC angeschloßen und will die Werte dann auf HTerm lesen können. Nur leider klappt es nicht so ganz, I2C funktioniert aber wenn ich die Daten dann schicken sehe ich nur Nuller auf HTerm. Ich habe schon probiert nur gewissen Bytes zu schicken, wo der wirkliche Inhalt (laut Datenbaltt) drin ist. Funktioniert aber leider auch nicht. Danke für euere Hilfe im vorraus.
Hast du schon probiert, deinen Quellcode hier zu posten? Alles andere klingt nach "Mach mir das mal jemand!"
Kannst Du einen festen Text, wie z.B. "Hallo Welt !" an HTerm schicken ? Wenn nein, gelingt es ohne die Module dazwischen ? P.S. : Es gibt hier kaum jemanden im Forum, der per Gedankenübertragung in Deinen Quelltext schauen kann.
Du musst vor dem Senden das "SendNotNull" Bit setzen.
Ein Hello World kann ich an meine modul schicken und sehe es auch auf HTerm. Das wär meine while loop; Wieso ich diese Bytes gewählt hab zum schicken liegt im Anhang beim Datenblatt. (Seite 12) uint8_t data[3]; data[0] = 0xC2; data[1] = 0x03; data[2] = 0x00; I2C1_WriteNBytes(0x61, data, 3); I2C1_ReadNBytes(0x61, i2c_payload, 19); UART5_Write(0x02); UART5_Write(0x00); UART5_Write(0x0C); UART5_Write(i2c_payload[1]); UART5_Write(i2c_payload[2]); UART5_Write(i2c_payload[4]); UART5_Write(i2c_payload[5]); UART5_Write(i2c_payload[7]); UART5_Write(i2c_payload[8]); UART5_Write(i2c_payload[10]); UART5_Write(i2c_payload[11]); UART5_Write(i2c_payload[13]); UART5_Write(i2c_payload[14]); UART5_Write(i2c_payload[16]); UART5_Write(i2c_payload[17]); uint8_t summe = 0; summe = summe ^ 0x02; summe = summe ^ 0x00; summe = summe ^ 0x0C; summe = summe ^ i2c_payload[3]; summe = summe ^ i2c_payload[6]; summe = summe ^ i2c_payload[9]; summe = summe ^ i2c_payload[12]; summe = summe ^ i2c_payload[15]; summe = summe ^ i2c_payload[18]; UART5_Write(summe);
Dass Du in hterm die byte-Werte und keine ASCII-Zeichen mit dieser Methode empfängst, ist dir klar?
STK500-Besitzer schrieb: > Dass Du in hterm die byte-Werte und keine ASCII-Zeichen mit dieser > Methode empfängst, ist dir klar? Verzeih aber kannst du mir das erklären.
Leonidas T. schrieb: > Verzeih, aber kannst du mir das erklären. Sofern dein I²C-Device keine ASCII-Zeichen sendet (von Menschen lesbare Zeichen), steht im Empfangfenster nur Kauderwelsch, sofern du die Anzeige nicht auf Hex oder Dezimal gestellt hast.
Leonidas T. schrieb: > Verzeih aber kannst du mir das erklären. Wenn ein Wert 0 sein soll, gibt es bei der Übertragung entweder den Byte-Wert 0, also 0x00, oder das Ascii-Zeichen für "0", das wäre 48 bzw. 0x30 als Byte-Wert. Wenn du deinen Messwert von "3" nun nicht als ASCII-Zeichen 51 (0x33) überträgst, sondern als Byte-Wert von 3 (0x03), dann zeigt dein Terminal dir keine 3 an, sondern irgendeinen Indikator dafür, dass ein Steuerzeichen "End of Text" gesendet wurde. Denn das hat den Byte-Wert 3. Um aus dem Wert "54.3" nun einen ASCII-String mit den entsprechenden Zeichen zu machen, gibt es ein paar Funktionen (printf und solche Späßchen)
Leonidas T. schrieb: > data[0] = 0xC2; > data[1] = 0x03; > data[2] = 0x00; > > I2C1_WriteNBytes(0x61, data, 3); Kann nicht klappen. In der PDF ist die komplette Übertragung auf dem Bus zu sehen. Die I²C-Adresse wird aber bei I2C1_WriteNBytes extra übergeben, daher darf nicht noch mal 0xC2 gesendet werden. 0xC2 ist bei I²C Schreiben an Adresse 0x61.
STK500-Besitzer schrieb: > Sebastian R. schrieb: > > Man kann auch in hTerm die Anzeige umstellen... Jap das weiss ich. Ich kann trotzdem nur Nuller sehen. Danke für eure Antworten
:
Bearbeitet durch User
Mario M. schrieb: > Leonidas T. schrieb: >> data[0] = 0xC2; >> data[1] = 0x03; >> data[2] = 0x00; >> >> I2C1_WriteNBytes(0x61, data, 3); > > Kann nicht klappen. In der PDF ist die komplette Übertragung auf dem Bus > zu sehen. Die I²C-Adresse wird aber bei I2C1_WriteNBytes extra > übergeben, daher darf nicht noch mal 0xC2 gesendet werden. 0xC2 ist bei > I²C Schreiben an Adresse 0x61. Also soll ich 0xC2 nicht schreiben und es probieren oder wie? Verzeih ich habs nicht ganz verstanden
Genau, schreib nur 2 Bytes, das 0xC2 wird automatisch voran gesendet. Zwischen Schreiben und Lesen müssen laut des PDFs mehr als 3ms Pause sein. Lege Dir so einen billigen Logikanalysator zu, dann kannst Du überprüfen, was über den Bus geht.
Mario M. schrieb: > Genau, schreib nur 2 Bytes, das 0xC2 wird automatisch voran gesendet. > Zwischen Schreiben und Lesen müssen laut des PDFs mehr als 3ms Pause > sein. Lege Dir so einen billigen Logikanalysator zu, dann kannst Du > überprüfen, was über den Bus geht. Das hat geholfen danke dir, jetzt bekomm ich nur Trash values.
Also am ende vom Datenblatt finde ich wie ich die werte in physik. Werte umwandel. Nur denk ich es ist am ende eine variable und ich kann die nicht über UART schicken. Über UART kann ich nur Byte by Byte schicken. (Da spezielles format) Gibts es eine Möglichkeit die variable in ein array aufzuteilen um es eben in bytes zu unterteilen? Ich danke euch
Leonidas T. schrieb: > Gibts es eine Möglichkeit die variable in ein array aufzuteilen um es > eben in bytes zu unterteilen? man verschiebt die einzelnen Bytes der größeren Variablen um die entsprechende Anzahl von Bits:
1 | uint16_t word = 0xAABB; |
2 | uint8_t bytes[2] = {0}; |
3 | bytes[0] = word >> 8; // MSB |
4 | bytes[1] = word & 0x00FF; // LSB |
Man könnte den "Berechnungen" noch ein Cast verpassen. Sollte aber nicht notwendig sein. Solche Bitschubsereien sind Grundlagen...
Leonidas T. schrieb: > I2C1_ReadNBytes(0x61, i2c_payload, 19); > > UART5_Write(0x02); > UART5_Write(0x00); > UART5_Write(0x0C); > > UART5_Write(i2c_payload[1]); > UART5_Write(i2c_payload[2]); > UART5_Write(i2c_payload[4]); Die Zahl der gelesenen Bytes sollte durch 3 teilbar sein (also 18 statt 19), weil immer MSB, LSB, CRC gesendet werden. Außerdem beginnt i2c_payload bei Null, die Messwerte liegen also bei 0, 1 und 3, 4 usw.
STK500-Besitzer schrieb: > man verschiebt die einzelnen Bytes der größeren Variablen um die > entsprechende Anzahl von Bits: > >
1 | > uint16_t word = 0xAABB; |
2 | > uint8_t bytes[2] = {0}; |
3 | > bytes[0] = word >> 8; // MSB |
4 | > bytes[1] = word & 0x00FF; // LSB |
5 | >
|
> Man könnte den "Berechnungen" noch ein Cast verpassen. Sollte aber nicht > notwendig sein. > > Solche Bitschubsereien sind Grundlagen... Dankeschön das war sehr hilfreich, ich probiers aus und sag euch bescheid :)
:
Bearbeitet durch User
Ich komm leider nicht weiter, also im datenblatt steht folgendes: float co2Concentration; unsigned int tempU32; unsigned char buffer[4]; buffer[0] = 0x43; // MMSB CO2 buffer[1] = 0xDB; // MLSB CO2 buffer[2] = 0x8C; // LMSB CO2 buffer[3] = 0x2E; // LLSB CO2 tempU32 = (unsigned int)((((unsigned int)buffer[0]) << 24) | (((unsigned int)buffer[1]) << 16) | (((unsigned int)buffer[2]) << 8) | ((unsigned int)buffer[3])); co2Concentration = *(float*)&tempU32; // co2Concentration = 439.09f Die sache ist nur, ich weiss nicht wie ich co2Concentration über UART verschicken soll, da ich nur byte by byte verschicken kann. ICh würde es gerne in ein array abspeichern. Was denkt ihr??
Leonidas T. schrieb: > Ich komm leider nicht weiter, also im datenblatt steht folgendes: > > co2Concentration = *(float*)&tempU32; // co2Concentration = 439.09f > > Die sache ist nur, ich weiss nicht wie ich co2Concentration über UART > verschicken soll, da ich nur byte by byte verschicken kann. ICh würde es > gerne in ein array abspeichern. Was denkt ihr?? Bitte sprintf() (Library-Funktion, oder fprintf()) nachschlagen. Eventuell ein Buch benutzen (bei solchen Fragen reicht Kernighan & Ritchie aus). Gruesse Th.
Der Sensor gibt drei Messwerte zurück: CO2-Gehalt, Feuchtigkeit und Temperatur. Diese werden als Float-Werte mit einer Länge von jeweils 4 Bytes übermittelt. Das Programmbeispiel zeigt, wie die 4 Bytes in eine Float-Variable kopiert werden.
Leonidas T. schrieb: > Die sache ist nur, ich weiss nicht wie ich co2Concentration über UART > verschicken soll, da ich nur byte by byte verschicken kann. Will man mehr als ein Byte übertragen, benötigt man ein Protokoll. Die UART kann nicht unterscheiden, welches Byte in einem Datenstrom welche Bedeutung hat. Ein einfaches Protokoll ist eine Textzeile, die mit CR/LF abgeschlossen wird und nur Textzeichen enthält. Werte lassen sich leicht als Text mit printf ausgeben, bzw. mit scanf einlesen. Binärprotokolle sind zwar kompakter, aber auch deutlich komplexer und nicht direkt lesbar.
Mario M. schrieb: > Der Sensor gibt drei Messwerte zurück: CO2-Gehalt, Feuchtigkeit und > Temperatur. Diese werden als Float-Werte mit einer Länge von jeweils 4 > Bytes übermittelt. Das Programmbeispiel zeigt, wie die 4 Bytes in eine > Float-Variable kopiert werden. Das ist sehr hilfreich, ich danke dir. Kann dich das programmieren, also das es von alleine passiert.
Mario M. schrieb: > Der Sensor gibt drei Messwerte zurück: CO2-Gehalt, Feuchtigkeit und > Temperatur. Diese werden als Float-Werte mit einer Länge von jeweils 4 > Bytes übermittelt. Das Programmbeispiel zeigt, wie die 4 Bytes in eine > Float-Variable kopiert werden. Sowas ist einigermaßen ungewöhnlich, denn Gleitkommaformate können unterschiedlich sein. Sowohl vom schieren Format her als auch in den dargestellten Wertigkeiten. Muß aber nicht. Auf alle Fälle ist es hilfreich, im PIC all das, was da vom Sensor kommt, zunächst in ein Format zu wandeln, mit dem die GK-Routinen des verwendeten Compilers zurecht kommen und dann zur Übertragung diese in Text zu konvertieren. Und das dann senden. Ob das, was da in deinem Datenblatt als funktionale Konvertierroutine angesehen werden kann, ist deshalb fraglich. Nach meiner Erfahrung sind Audrücke, wo extensiv gecastet wird, recht fehleranfällig. Versuche doch erstmal, die vom Sensor kommenden Bytes als Hexzahlen zu senden, etwa so:
1 | String_Out("CO2: ",toUART1); |
2 | HexB_Out(Buffer[0],toUART1); Char_Out(',',toUART1); |
3 | HexB_Out(Buffer[1],toUART1); Char_Out(',',toUART1); |
4 | HexB_Out(Buffer[2],toUART1); Char_Out(',',toUART1); |
5 | HexB_Out(Buffer[3],toUART1); Crlf_Out(toUART1); |
W.S.
1 | String_Out("CO2: ",toUART1); |
2 | HexB_Out(Buffer[0],toUART1); Char_Out(',',toUART1); |
3 | HexB_Out(Buffer[1],toUART1); Char_Out(',',toUART1); |
4 | HexB_Out(Buffer[2],toUART1); Char_Out(',',toUART1); |
5 | HexB_Out(Buffer[3],toUART1); Crlf_Out(toUART1); |
Daran erkennt man den Könner, der unbegabte Laie würde viel umständlicher
1 | printf("CO2: %02x,%02x,%02x,%02x\r\n", Buffer[0], Buffer[1], Buffer[2], Buffer[3]); |
schreiben. Da sieht man förmlich, wie viel eleganter die Nutzung eigener Ausgabefunktionen ist. Schön, dass hier ein Fachmann und Könner zeigt, wie es richtig gemacht wird. Auch die Quelltextformatierung ist mit mehreren Statements in einer Zeile viel überschaubarer. Wie lange man wohl braucht, um diesen Level an Exzellenz zu erlangen?
Profibewunderer schrieb: > Wie lange man wohl braucht, um diesen > Level an Exzellenz zu erlangen? Naja, es sind halt die bekannten Koniferen des Forums . . .
Falk B. schrieb: > Naja, es sind halt die bekannten Koniferen des Forums . . . Diese Koniferen möchten halt dem Compiler noch etwas Optimierungsarbeit überlassen.
Profibewunderer schrieb: > Daran erkennt man den Könner,... Nö, sondern man erkennt das Prinzip. Das ist alles. Aber mal im Detail: Wenn jemand eine Ausgabefunktion benutzt, die neben den Zeigern auf 4 Bytes obendrein auch noch einen Formatstring benötigt und dieser von einem in der Firmware befindlichen Textinterpreter auseinandergenommen werden muß, um dann dort viermal die eigentlichen Konvertier- und Ausgabefunktionen aufzurufen, dann ist das für dich eine bessere Lösung? Und das in einem PIC (allerdings ohne detaillierte Bezeichnung) mit vermutlich nur wenig Programmspeicher? Ich habe da so den Eindruck, daß deine Vorstellungskraft nicht über einen C-Quelltext hinausreicht. W.S.
Das ist es ja, was ich an Profis wie Dir bewundere. Die rufen neun Funktionen nacheinander auf, und schwabulieren immer was davon, wie unendlich kompliziert das doch alles ist, was printf veranstaltet. Bekommen die Geld für nicht genutzes Flash-ROM ihrer Controller zurück?
Profibewunderer schrieb: > Bekommen die Geld für nicht genutzes Flash-ROM ihrer Controller zurück? Sie retten das Weltklima!!!
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.