Forum: Mikrocontroller und Digitale Elektronik Verknüpfung der Sensordatenabfrage(LTC2498) mit der Funkverbindung(ATmega128RFA1)


You were forwarded to this site from EmbDev.net. Back to EmbDev.net
von Hector C. (Firma: Technische Universität München) (cuenca)


Angehängte Dateien:

Lesenswert?

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

von A. W. (uracolix)


Lesenswert?

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.

von A. W. (uracolix)


Lesenswert?

Ok, jetzt hab ich Kode 3 gesehen ... du musst die SPI Zugriffe als 
Funktion
read_ltc2498() zusammenfassen ...

von Hector C. (Firma: Technische Universität München) (cuenca)


Angehängte Dateien:

Lesenswert?

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
von A. W. (uracolix)


Lesenswert?

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

von Hector C. (Firma: Technische Universität München) (cuenca)


Angehängte Dateien:

Lesenswert?

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.

von A. W. (uracolix)


Lesenswert?

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
von Hector C. (Firma: Technische Universität München) (cuenca)


Angehängte Dateien:

Lesenswert?

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.

von A. W. (uracolix)


Lesenswert?

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 ...).

von Hector C. (Firma: Technische Universität München) (cuenca)


Lesenswert?

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.

von A. W. (uracolix)


Lesenswert?

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
von Hector C. (Firma: Technische Universität München) (cuenca)


Lesenswert?

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.

von A. W. (uracolix)


Lesenswert?

>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
Noch kein Account? Hier anmelden.