Hallo! Ich wäre sehr dankbar für eure Tipps zu meiner derzeitigen Problemstellung: Meine Vorgängerin hat schon in dieses Forum über vorherigen Schritten in dieses Proyekt geredet,ich habe dieses Link(Beitrag "Re: LTC2498 und Atmega128rfa1: c-code Beispiel" Ihrem Bericht zu diesem Thread mit reingenommen. Ich habe einen Mikrocontroller mit integriertem Zigbee (ATmega128RFA1,,http://www.dresden-elektronik.de/funktechnik/products/radio-modules/eval-derfmega/) von UART-USB(USB Pegelwandler,https://shop.dresden-elektronik.de/accessories-1/levelshifter/usb-pegelwandler-stick-low-power.html) an den PC angeschlossen. Auf der anderen Seite habe ich eine zweite identisch mit den ersten Mikrocontroller (ATmega128RFA1) mit einer Analog-Digital-Termochip (LTC2498,http://www.linear.com/product/LTC2498) durch SPI und empfangen von Daten aus einer verbundenen Sonde Temperatur verbunden.(Bild im Anhang) 1.- Ich habe C-Kode für beide Microcontroller, für das Senden und empfangen von Daten über Funkverbingung (Uracoli Library). Kode 1 = (http://uracoli.nongnu.org/manual/pgXmplTrxTx.html) Kode 2 = (http://uracoli.nongnu.org/manual/pgXmplTrxRx.html) 2.- Auf der anderen Seite des C-Codes ist Implementierung einer funktionsfähigen Abfrage der Sensordaten vom LTC2498 via SPI. Kode 3 = Lesen von Daten von LTC2498.(Im Anhang) ---Aktuelles Schema mit nur eine ATmega128RFA1: LTC2498--SPI-uC(mit Kode 3 programmiert)-UART_USB-PC. Ich brauche implementieren einer funktionsfähigen Abfrage der Sensordaten vom LTC2498 via SPI und Verknüpfung der Sensordatenabfrage mit der Funkverbindung. ---Gewünschten Schema: LTC2498--SPI--uC--(FUNKVERBINDUNG)--uC--UART_USB--PC Wie muss ich es tun? Alle meine Kompilation Versuche sind falsch. Könnten Sie mir helfen? Schonmal Danke, Héctor
Hallo Hector, ich seh zwar die Anhaenge nicht, aber soweit ich das sehe musst du Kode 1 und Kode 3 zu einem Programm zusammenfassen. Danach aenderst du die Loop in Kode 1 in etwa so um:
1 | while(1) |
2 | { |
3 | WAIT500MS(); |
4 | if (tx_in_progress == false) |
5 | { |
6 | temp = read_ltc2498(); |
7 | len = snprintf(&txfrm[3], 122, "temp = %d\n", temp); |
8 | txfrm[0] = len + 3 + 2; |
9 | txfrm[2] = tx_cnt; |
10 | trx_frame_write (sizeof(txfrm), txfrm); |
11 | tx_in_progress = true; |
12 | TRX_SLPTR_HIGH(); |
13 | TRX_SLPTR_LOW(); |
14 | LED_SET(1); |
15 | LED_TOGGLE(0); |
16 | } |
17 | } |
Das sprintf bewirkt dass die Daten als String uebertragen werden, was zwar etwas Ressourcenverschwendung ist - aber fuer den ersten Schuss ist das gut genug - premature optimization is the root of all evil (D. Knuth). Die Magische 122 kommt durch 127 (max. laenge eines Frames) - 3 byte Header - 2 Byte CRC zustande. Viel Erfolg.
Ok, jetzt hab ich Kode 3 gesehen ... du musst die SPI Zugriffe als Funktion read_ltc2498() zusammenfassen ...
Hallo AW! Danke sehr! D. Knuth ist ein Genie!;D A. W. schrieb: >... du musst die SPI Zugriffe als > Funktion Ich habe es schon gemacht.Denken Sie es ist gut gemacht.(Kode 7 im anhang) > read_ltc2498() zusammenfassen ... Wie mache Ich das?,Soll ich die Variable "str" am anfang in Zusammenhang bringen mit Array txfrm[0] = len + 3 + 2; ? while(1) { WAIT500MS(); if (tx_in_progress == false) { temp = read_ltc2498(); len = snprintf(&txfrm[3], 122, "temp = %d\n", temp); txfrm[0] = len + 3 + 2; txfrm[2] = tx_cnt; trx_frame_write (sizeof(txfrm), txfrm); tx_in_progress = true; TRX_SLPTR_HIGH(); TRX_SLPTR_LOW(); LED_SET(1); LED_TOGGLE(0); } -Zum beispiel kann Ich die Meldung "207" auf meine Hterm mit diesen beiden Änderungen lesen(Bild im Anhang)und mit die änderung am anfang von Code 2(RX):(Sehen Sie Code 6,im anhang) Mit diesem Schema: uC--(FUNKVERBINDUNG)--uC--UART_USB--PC Danke.
:
Bearbeitet durch User
Sorry fuer die Verwirrung
1 | txfrm[0] = len + 3 + 2; |
2 | txfrm[2] = tx_cnt; |
3 | trx_frame_write (sizeof(txfrm), txfrm); |
war totaler Unfug meinerseits, so wird es aber funktionieren:
1 | txfrm[2] = tx_cnt; |
2 | trx_frame_write (len + 3 + 2, txfrm); |
3 = Anzahl Bytes des Frame Headers (IEEE 802.15.4 Datenframe ohne Adressen). len = Anzahl der Bytes im String 2 = Anzahl der CRC Bytes. Das sprintf() in der IRQ Routine geht prinzipiell, ist aber kein besonders guter Stil (man sollte in IRQ Routinen nur kurz verweilen und nur das noetigste berechnen - hier Frame in einen Puffer kopieren). Am besten im IRQ eine volatile Variable setzen und in der Mainloop die Variable abfragen, die Ausgabe erledigen und die Variable loeschen:
1 | volatile uint8_t frame_rxd = 0 |
2 | |
3 | void main() |
4 | { |
5 | |
6 | while(1) |
7 | { |
8 | if (frame_rxd) |
9 | { |
10 | printf(...); |
11 | cli(); |
12 | frame_rxd = 0; |
13 | sei(); |
14 | } |
15 | } |
16 | } |
17 | IRQ |
18 | { |
19 | if (frame_rxd == 0) |
20 | { |
21 | save frame ... |
22 | frame_rxd = 1; |
23 | } |
24 | else |
25 | { |
26 | ignore frame since last data was not processed |
27 | } |
28 | } |
Mit sprintf(buffer, ">%s", &txframe[3]); sollte die Ausgabe dann funktionieren. ¡Que te diviertas! Axel
Hallo Axel! Vielen Dank! Ich glaube, Ich bin ein bisschen verloren mit deinem Code. Könntest du mir sagen, wo finde Ich Informationen, um besser zu verstehen? Könntest du mir ein bisschen mehr mit dem Code führen? Ich wirklich es brauche. A. W. schrieb: >
1 | > txfrm[2] = tx_cnt; |
2 | > trx_frame_write (len + 3 + 2, txfrm); |
3 | > |
> 3 = Anzahl Bytes des Frame Headers (IEEE 802.15.4 Datenframe ohne > Adressen). > len = Anzahl der Bytes im String > 2 = Anzahl der CRC Bytes. Ich glaube, ich verstehe: 2 = Anzahl der Bytes CRC weil Ich 2 CRC16 brauche, wegen ich muss 32 bits benutze aus LTC2498. Ich habe (Trx_frame_write (Len + 3 + 2, Txfrm);) Nach (Txfrm [2] = Tx_cnt;) in der Versand-Code hinzugefügt. Ich kann nicht gut verstehen trotzdem habe Ich das Datenblatt von ATmega128RFA1 und Uracoli Manual gelesen, wo soll Ich dein nächste Teil setzen? >
1 | > volatile uint8_t frame_rxd = 0 |
2 | > |
3 | > void main() |
4 | > { |
5 | > |
6 | > while(1) |
7 | > { |
8 | > if (frame_rxd) |
9 | > { |
10 | > printf(...); |
11 | > cli(); |
12 | > frame_rxd = 0; |
13 | > sei(); |
14 | > } |
15 | > } |
16 | > } |
17 | > IRQ |
18 | > { |
19 | > if (frame_rxd == 0) |
20 | > { |
21 | > save frame ... |
22 | > frame_rxd = 1; |
23 | > } |
24 | > else |
25 | > { |
26 | > ignore frame since last data was not processed |
27 | > } |
28 | > } |
29 | > |
> > Mit sprintf(buffer, ">%s", &txframe[3]); sollte die Ausgabe dann > funktionieren. Hier die Buffer wäre Array txfrm sein? Hier zeige ich Ihnen meine aktuellen Codes(Im Anhang). Schonmal Danke,Hector.
Hector, einen ganzen Programmierkurs kann ich dir leider nicht geben, das ist Sache der Uni, die werden dafuer bezahlt ;-) Am besten wird es sein, wenn du das Problem Stueck fuer Stueck loest. Also Fang mal neu an und schreib zunaechst ein Programm das den LTC ausliest und die Daten aufs Terminal schreibt. Implementiere die Funktion read_ltc2498() - kein Transceiver Code nur UART und LTC. Den Code poste dann hier. Wir werden den Code solange umbauen, bis die Funkschnittstelle ganz einfach einzubauen geht.
:
Bearbeitet durch User
Hallo Axel, Ich habe die folgenden zwei Kode, Senden(Send_ektor_.c) und Empfangen(Send_ektor_.c)geschreiben und villeicht bin ich inzwischen einen Schritt weiter. Ich habe die nächte gemacht: -Code Versand liest die Temperatur und zersetzt es aus einer Anzahl auf eine Anzahl von Zeichen (4 Bytes). Diese Zeichen werden an den sendenden Puffer kopiert, angesichts der Tatsache, dass wir immer wissen, dass sie 4 Frame ist immer die gleiche Größe. -Der Code des Empfangs ist fast unverändert, nur, dass wir wissen, in welcher Position sie Temperaturdaten jetzt das Datenpaket erhalten sind. Alles, was übrig ist, ist diese 4 Bytes, und 32-Bit-Ganzzahl ohne Vorzeichen wieder zu komponieren. So verschiedenen Bytes werden gefangen und zu bewegen. Ich kann keine Daten aufs Terminal lesen. Ist es ein guter Versuch?, Braucht mein Programm Programmunterbrechung(IRQ)? A. W. schrieb: > Den Code poste dann hier. Wir werden den Code solange umbauen, bis die > Funkschnittstelle ganz einfach einzubauen geht. Ich zeige auch hier das Programm das den LTC ausliest und die Daten aufs Terminal schreibt (Read_ltc2498). Schonmal Danke,Hector.
Hector, >Ich kann keine Daten aufs Terminal lesen. Ist es ein guter Versuch?, Das sieht doch schon ganz gut aus. Der UART scheint mir nicht richtig benutzt. Woher weiss printf, dass es UART0 nutzen soll? Lösungen: a) nimm sprintf und ruf hinterher sendestring() auf. b) verwende Stdio: http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html (siehe Example) c) nimm die hif_.... Funktionen von uracoli. >Braucht mein Programm Programmunterbrechung(IRQ)? Gegenfragen: - Welche Interrupts werden denn verwendet? - Was macht sei()/cli()? Nächste Schritte: Wenn du die Ausgabe des printf auf dem Terminal siehst, lösche allen unbenutzten Code (Hinweis: #if ...).
Hallo Axel, A. W. schrieb: > Der UART scheint mir nicht richtig benutzt. Woher weiss printf, dass es > UART0 nutzen soll? I habe sprintf genommen und sendestring() angerufen aber Ich kann nur "0" mit dem folgende auf dem Terminal sehen:
1 | //Do something with temperature! |
2 | sprintf(buf, "%lu", temperature); |
3 | sendestring(buf); |
Was mache Ich falsch? > - Welche Interrupts werden denn verwendet? Aus dein Kode es gibt ISR Interrupts aber du hast mir im letzten Post empfohlen, dass Ich IRQ muss benutzen. > - Was macht sei()/cli()? sei()-(set I) aus SREG. Ermöglicht Unterbrechungen durch das Setzen der globalen Unterbrechungsmaske. cli()-(Clean I) aus SREG. I habe auch hier(http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html#gaad5ebd34cb344c26ac87594f79b06b73) gelesen. Aber braucht mein Programm Programmunterbrechung? Schonmal Danke, Héctor.
Hast du einen JTAG-Debugger (Dragon/JTAG-Ice)? Das macht die Suche einfacher. Um zu testen, ob es an der Ausgabe liegt oder an der Messroutine, probier mal der Variable temperature einen festem Wert zuzuweisen, siehst du die Zahl auf dem Terminal?
1 | sprintf(buf, "temp=%d\n", 42); |
2 | sendestring(...) |
IRQ's brauchst du fuer den Transceiver, den RX/TX_END IRQ. Der UART is gepollt.
:
Bearbeitet durch User
Hallo Axel, A. W. schrieb: > Hast du einen JTAG-Debugger (Dragon/JTAG-Ice)? Das macht die Suche > einfacher. Ja, Ich habe AVR Dragon.;D > Um zu testen, ob es an der Ausgabe liegt oder an der Messroutine, > probier mal der Variable temperature einen festem Wert zuzuweisen, > siehst du die Zahl auf dem Terminal? >
1 | > sprintf(buf, "temp=%d\n", 42); |
2 | > sendestring(buf) |
3 | > |
Genau, mit dieses in meine Kode, Ich lese "temp=4™". Ich denke dass, Ich die Temperatur aus LTC2498 nicht bekomme. > IRQ's brauchst du fuer den Transceiver, den RX/TX_END IRQ. Der UART is > gepollt. So, In meine Kode bleiben alle die notwendig IRQ routine aus Ihren Uracoli Kode, oder? Schonmal Danke, Héctor.
>Genau, mit dieses in meine Kode, Ich lese "temp=4™". Ich denke dass, Ich >die Temperatur aus LTC2498 nicht bekomme. Ist das letzte Zeichen (die 2) beim kopieren in den Thread kaputt gegangen? Wenn buf nur vier byte hat (wie im alten Programm), dann produzierst du so einen Speicherueberlauf - was zu debuggen auch eine huebsche Selbsterfahrung sein kann - inklusive Biss in die Tischkante. Bei Strings immer besser die "n"-Funktionen verwenden, snprintf, strncpy, strncat, ... >Ich denke dass, Ich die Temperatur aus LTC2498 nicht bekomme. Schau dir mal das return Verhalten von read_temperature() an. >So, In meine Kode bleiben alle die notwendig IRQ routine aus Ihren >Uracoli Kode, oder? Ja, aber du kannst den Code in den Bloecken #else /*!RFA*/ rauswerfen, weil der bei dir nicht verwendet wird und macht das Programm an der Stelle nur unuebersichtlich. PS: Mit dem Dragon und JTAG kannst du durch dein Programm schrittweise durchgehen, dann findest du leichter logische Fehler im Code.
:
Bearbeitet durch User
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.