1
\$\begingroup\$

I would be very grateful for your tips for my present problem definition:

I have a microcontroller ATmega128RFA1 with integrated Zigbee with UART-USB(TTL Converter) attached to the PC.

I have a second identically with the first one Microcontroller (ATmega128RFA1) connected by SPI to an analog-digital Termochip LTC2498.

All components

1.- I have C code for the two Microcontroller, sending and receiving data by Radio communication (Uracoli Library).

Code 1 = (http://uracoli.nongnu.org/manual/pgXmplTrxTx.html)

Code 2 = (http://uracoli.nongnu.org/manual/pgXmplTrxRx.html)

2.-On the other hand, I have the C code for recive data from LTC2498 via SPI(Current Plan with only one ATmega128RFA1):

LTC2498--SPI--uC(Programmed with code 3)--UART_USB--PC.

Code 3 = reading data of LTC2498:

#include <avr/io.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <util/delay.h>

#define DD_MISO 3
#define DD_MOSI 2
#define DD_SCK 1
#define DD_SS 0

void uart_init()
{
    uint16_t temp = ((8000000)/(9600.0*16)-1); //Berechnung Übertragungsgeschwindigkeit

    UBRR0L = temp; //Übertragungsgeschwindigkeit übermitteln
    UBRR0H = temp>>8; 
    UCSR0B |= (1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0); //Senden und Empfangen freischalten   
    UCSR0C |= (1<<UCSZ00)|(1<<UCSZ01);  //Übertragungsformat: 8-Bit
}

int sendestring(char *s)
{
    int i=0; 
    for(i=0; s[i] != '\0'; i++)
    {
        while bit_is_clear(UCSR0A, UDRE0); //warten, bis UDRE0 = 1 (Senderegister frei)
        UDR0 = s[i]; //ein Zeichen senden
    }  
    return 0;
}

void SPI_MasterInit(void)   
{
    //Outputs: MOSI, SCK, SS 
    DDRB = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
    //Enable SPI, Master-Mode, set clock rate fck/16  
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}    

int SPI_MasterTransmit(char MOSI)
{
    //start Transmission
    SPDR = MOSI;
    //white for transmission complete
    while(!(SPSR & (1<<SPIF)));

    //returned data from slave to master

    return SPDR;
}

int main()
{

    char str[20];

    // Thermoelement an CH0 und CH1
    char masterOut1 = 0b10100000;
    //char masterOut2 = 0b10000000;

    // interne Temperaturmessung:
    char masterOut2 = 0b11000000;

    char result;
    uint32_t masterIn = 0;
    uint32_t Temp = 0;

    uart_init();    

    SPI_MasterInit();


    for(;;)
    {

        _delay_ms(500);

        //CS des Thermochips auf low
        PORTB &= !(1<<DD_SS);


        //Byte1
        result = SPI_MasterTransmit(masterOut1);        
        masterIn = (result & 0b00011111);  //die ersten drei Bit löschen

        //für Debugging
        sendestring(" result1: ");
        itoa(result, str, 2); //binär darstellen
        sendestring(str);

        //Byte2
        result = SPI_MasterTransmit(masterOut2);
        masterIn = (masterIn<<8) + result;


        //Byte3
        result = SPI_MasterTransmit(0);
        masterIn = (masterIn<<8) + result;


        //Byte4
        result = SPI_MasterTransmit(0);
        masterIn = (masterIn<<8) + result;
        //CS des Thermochips auf high
        PORTB |= (1<<DD_SS);
        masterIn = (masterIn>>5) & 0b00000000111111111111111111111111; //die letzten 5 Bit löschen
        sendestring(" masterIn: ");
        sprintf(str, "%ld", masterIn);
        sendestring(str);
        Temp = (masterIn*4/1570)-273;
        sendestring(" Temp: ");
        sprintf(str, "%ld", Temp);
        sendestring(str);

        _delay_ms(2000);
    }


    return 0;
}

I need to implement reading data of LTC2498(Code 3) with the Radio Comunication. Desired Plan:

----LTC2498--SPI--uC--(Radio Link)--uC--UART_USB--PC

For example I just have an example for receive a "Hello World" messege with the desire Plan working perfectly: uC(Programmed with Code 4)--(Radio Link)--uC(Programmed with Code 5)--UART_USB--PC

I show you the changes: Code 4 = Code 1 and Code 5 = Code 2 but modified.

enter image description here

I need implement SPI like a function, and for example something like that on the sent code:

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);
    }
}

How can I do it? All my compilation attempts are wrong. Could You help me?


Thank you very much

I still have compilation problems.I have use part of your code but I am not sure if I did it correctly. Could you say me what to correct?I show you both Codes.

---LTC2498--SPI--uC(Programmed with Send Code)--(Radio Link)--uC(Programmed with Reception Code)--UART_USB--PC

Send Code:

#include "board.h"
#include "transceiver.h"
#include "ioutil.h"
#include "xmpl.h"


static volatile bool tx_in_progress;
static volatile uint8_t tx_cnt;
static volatile uint32_t temp;
static volatile uint32_t len;



int main(void)
{
trx_regval_t rval;


uint8_t txfrm[] = {1,0, /* faked ieee 802.15.4 data frame control field
                     * this is just needed, that a sniffer has to display something.*/
               42,  /* sequence counter, updated by software */
              'h','e','l','l','o',' ','µ','r','a','c','o','l','i','!', /* data */
              'X','X' /* these bytes are overwritten from transceivers CRC generator just before sent. */
              };
/* This will stop the application before initializing the radio transceiver
 * (ISP issue with MISO pin, see FAQ)
 */
trap_if_key_pressed();

/* Step 0: init MCU peripherals */
LED_INIT();
trx_io_init(SPI_RATE_1_2);
LED_SET_VALUE(LED_MAX_VALUE);
LED_SET_VALUE(0);

/* Step 1: initialize the transceiver */
DELAY_US(TRX_INIT_TIME_US);
TRX_RESET_LOW();
TRX_SLPTR_LOW();
DELAY_US(TRX_RESET_TIME_US);
TRX_RESET_HIGH();
trx_reg_write(RG_TRX_STATE,CMD_TRX_OFF);
DELAY_US(TRX_INIT_TIME_US);
rval = trx_bit_read(SR_TRX_STATUS);
ERR_CHECK_DIAG(TRX_OFF!=rval,1);
LED_SET_VALUE(1);

/* Step 2: setup transmitter
 * - configure radio channel
 * - enable transmitters automatic crc16 generation
 * - go into TX state,
 * - enable "transmit end" IRQ
 */
trx_bit_write(SR_CHANNEL,CHANNEL);
trx_bit_write(SR_TX_AUTO_CRC_ON,1);
trx_reg_write(RG_TRX_STATE,CMD_PLL_ON);
#if defined(TRX_IRQ_TRX_END)
trx_reg_write(RG_IRQ_MASK,TRX_IRQ_TRX_END);
#elif defined(TRX_IRQ_TX_END)
trx_reg_write(RG_IRQ_MASK,TRX_IRQ_TX_END);
#else
#  error "Unknown IRQ bits"
#endif
sei();
LED_SET_VALUE(2);

/* Step 3: send a frame each 500ms */
tx_cnt = 0;
tx_in_progress = false;
LED_SET_VALUE(0);

while(1)
{
    WAIT500MS();
    if (tx_in_progress == false)
    {
//------------------------------------------------------------------------------
//------------PART TO MODIFY------------------------


        temp = read_ltc2498();


        len = snprintf(&txfrm[3], 122, "temp = %d\n", temp);
//The transmission is from 122 to 127 (last), 3 byte block home and State 2.
        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);
        }
    }
}

#if defined(TRX_IF_RFA1)
ISR(TRX24_TX_END_vect)
{
/* transmission completed */
tx_in_progress = false;
tx_cnt ++;
LED_CLR(1);
}
#else  /* !RFA1 */
ISR(TRX_IRQ_vect)
{
static volatile trx_regval_t irq_cause;
irq_cause = trx_reg_read(RG_IRQ_STATUS);
if (irq_cause & TRX_IRQ_TRX_END)
{
    /* transmission completed */
    tx_in_progress = false;
    tx_cnt ++;
    LED_CLR(1);
    }
}
#endif

/* EOF */

COMPILATION ERRORS SEND CODE:

Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT xmpl_trx_tx.o -MF dep/xmpl_trx_tx.o.d  -c  ../xmpl_trx_tx.c

../xmpl_trx_tx.c: In function 'main':
../xmpl_trx_tx.c:80:13: warning: implicit declaration of function 'read_ltc2498' [-Wimplicit-function-declaration]
../xmpl_trx_tx.c:83:13: warning: pointer targets in passing argument 1 of 'snprintf' differ in signedness [-Wpointer-sign]
In file included from C:\Users\EKTOR\Desktop\Proyecto111\Progs\uracoli-src-0.4.0\xmpl\..\inc/ioutil.h:53:0,
                 from ../xmpl_trx_tx.c:3:
../xmpl_trx_tx.c:83:13: warning: format '%d' expects argument of type 'int', but argument 4 has type 'uint32_t' [-Wformat]
Build succeeded with 3 Warnings...

Reception Code:

#include "board.h"
#include "transceiver.h"
#include "ioutil.h"
#include  <util/crc16.h>
#include "xmpl.h"

#include <avr/io.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <util/delay.h>


#define DD_MISO 3
#define DD_MOSI 2
#define DD_SCK 1
#define DD_SS 0


static uint8_t rxfrm[MAX_FRAME_SIZE];
static volatile uint8_t rxcnt;


//----------------------UART-------------------------------

void uart_init()
{
uint16_t temp = ((8000000)/(9600.0*16)-1); //Berechnung Übertragungsgeschwindigkeit

UBRR0L = temp; //Übertragungsgeschwindigkeit übermitteln
UBRR0H = temp>>8;

UCSR0B |= (1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0); //Senden und Empfangen freischalten


UCSR0C |= (1<<UCSZ00)|(1<<UCSZ01);  //Übertragungsformat: 8-Bit

}


int sendestring(char *s)
{
int i=0;

for(i=0; s[i] != '\0'; i++)
{
    while bit_is_clear(UCSR0A, UDRE0); //warten, bis UDRE0 = 1 (Senderegister frei)

    UDR0 = s[i]; //ein Zeichen senden

}

return 0;
}


//--------------SPI-----------------------


void SPI_MasterInit(void)
{
//Outputs: MOSI, SCK, SS
DDRB = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);

//Enable SPI, Master-Mode, set clock rate fck/16
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

int SPI_MasterTransmit(char MOSI)
{
//start Transmission
SPDR = MOSI;

//wait for transmission complete
while(!(SPSR & (1<<SPIF)));

//returned data from slave to master
return SPDR;
}


//----------------MAIN-----------------



int main(void)
{

uart_init();
SPI_MasterInit();
trx_regval_t rval;

/* This will stop the application before initializing the radio transceiver
 * (ISP issue with MISO pin, see FAQ)
 */
trap_if_key_pressed();

/* Step 0: init MCU peripherals */
LED_INIT();
trx_io_init(SPI_RATE_1_2);
LED_SET_VALUE(LED_MAX_VALUE);
LED_SET_VALUE(0);

/* Step 1: initialize the transceiver */
TRX_RESET_LOW();
TRX_SLPTR_LOW();
DELAY_US(TRX_RESET_TIME_US);
TRX_RESET_HIGH();
trx_reg_write(RG_TRX_STATE,CMD_TRX_OFF);
DELAY_US(TRX_INIT_TIME_US);
rval = trx_bit_read(SR_TRX_STATUS);
ERR_CHECK(TRX_OFF!=rval);
LED_SET_VALUE(1);

/* Step 2: setup transmitter
 * - configure radio channel
 * - go into RX state,
 * - enable "receive end" IRQ
 */
trx_bit_write(SR_CHANNEL,CHANNEL);
trx_reg_write(RG_TRX_STATE,CMD_RX_ON);
#if defined(TRX_IRQ_TRX_END)
trx_reg_write(RG_IRQ_MASK,TRX_IRQ_TRX_END);
#elif defined(TRX_IRQ_RX_END)
trx_reg_write(RG_IRQ_MASK,TRX_IRQ_RX_END);
#else
#  error "Unknown IRQ bits"
#endif
sei();
LED_SET_VALUE(2);

/* Step 3: Going to receive frames */
rxcnt = 0;

LED_SET_VALUE(0);
while(1);
}

#if defined(TRX_IF_RFA1)
ISR(TRX24_RX_END_vect)
{
uint8_t flen, *pfrm, tmp;
uint16_t crc;

/* upload frame and check for CRC16 validity */
pfrm = rxfrm;
flen = trx_frame_read(pfrm, sizeof(rxfrm), NULL);
crc = 0;

//--------ADD MESSEGE (data from LTC2498)-----//-------


char str[20];

// Thermoelement an CH0 und CH1
char masterOut1 = 0b10100000;
//char masterOut2 = 0b10000000;

// interne Temperaturmessung:
char masterOut2 = 0b11000000;

char result;

uint32_t readLTC2498 () 
{
uint32_t masterIn = 0;

//CS des Thermochips auf low

PORTB &= !(1<<DD_SS);


//Byte1
result = SPI_MasterTransmit(masterOut1);        
masterIn = (result & 0b00011111);  //die ersten drei Bit löschen

//Byte2
result = SPI_MasterTransmit(masterOut2);
masterIn = (masterIn<<8) + result;

//Byte3
result = SPI_MasterTransmit(0);
masterIn = (masterIn<<8) + result;

//Byte4
result = SPI_MasterTransmit(0);
masterIn = (masterIn<<8) + result;

//CS des Thermochips auf high
PORTB |= (1<<DD_SS);

masterIn = (masterIn>>5) & 0b00000000111111111111111111111111; //die letzten 5 Bit löschen
return masterIn;
}
uint8_t str[127];
void sendToPC (uint32_t value)
{
sprintf(str,"masterIn: %ld",value);
sendestring(str);

Temp = (value*4/1570)-273;

sprintf(str,"Temp:%ld",Temp);

sendestring(str);
}


//--------------//-------------//--------------------//------------

do
{
    crc = _crc_ccitt_update(crc, *pfrm++);
}
while(flen--);
/* if crc is correct, update RX frame counter */
if (crc == 0)
{
    rxcnt ++;
}
/* display current rx statistics
 * LED[0] toggles with every received frame
 * LED[1:n] display the count of frames received with valid CRC
 */
tmp = (rxcnt<<1) | ((LED_GET_VALUE()&1)^1);
LED_SET_VALUE(tmp);


}
#else  /* !RFA1 */

ISR(TRX_IRQ_vect)
{
static volatile trx_regval_t irq_cause;
uint8_t flen, *pfrm, tmp;
uint16_t crc;

irq_cause = trx_reg_read(RG_IRQ_STATUS);
if (irq_cause & TRX_IRQ_TRX_END)
{
    /* upload frame and check for CRC16 validity */
    pfrm = rxfrm;
    flen = trx_frame_read(pfrm, sizeof(rxfrm), NULL);
    crc = 0;
    do
    {
        crc = _crc_ccitt_update(crc, *pfrm++);
    }
    while(flen--);

    /* if crc is correct, update RX frame counter */

    if (crc == 0)
    {
        rxcnt ++;
    }
    /* display current rx statistics

     * LED[0] toggles with every received frame
     * LED[1:n] display the count of frames received with valid CRC
     */
    tmp = (rxcnt<<1) | ((LED_GET_VALUE()&1)^1);
    LED_SET_VALUE(tmp);
    }
}
#endif  /* RFA1 */

/* EOF */

COMPILATION ERRORS RECEPTION CODE:

Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT xmpl_trx_tx.o -MF dep/xmpl_trx_tx.o.d  -c  ../xmpl_trx_tx.c

../xmpl_trx_tx.c: In function '__vector_60':
../xmpl_trx_tx.c:197:9: error: conflicting types for 'str'

../xmpl_trx_tx.c:158:6: note: previous declaration of 'str' was here
../xmpl_trx_tx.c: In function 'sendToPC':
../xmpl_trx_tx.c:200:5: warning: pointer targets in passing argument 1 of 'sprintf' differ in signedness [-Wpointer-sign]
In file included from C:\Users\EKTOR\Desktop\Proyecto111\Progs\uracoli-src-0.4.0\xmpl\..\inc/ioutil.h:53:0,
                 from ../xmpl_trx_tx.c:3:
c:\program files\atmel\avr tools\avr toolchain\bin\../lib/gcc/avr/4.7.2/../../../../avr/include/stdio.h:669:12: note: expected 'char *' but argument is of type 'uint8_t *'
../xmpl_trx_tx.c:201:5: warning: pointer targets in passing argument 1 of 'sendestring' differ in signedness [-Wpointer-sign]
../xmpl_trx_tx.c:41:5: note: expected 'char *' but argument is of type 'uint8_t *'
../xmpl_trx_tx.c:203:5: error: 'Temp' undeclared (first use in this function)
../xmpl_trx_tx.c:203:5: note: each undeclared identifier is reported only once for each function it appears in
../xmpl_trx_tx.c:205:5: warning: pointer targets in passing argument 1 of 'sprintf' differ in signedness [-Wpointer-sign]
In file included from C:\Users\EKTOR\Desktop\Proyecto111\Progs\uracoli-src-0.4.0\xmpl\..\inc/ioutil.h:53:0,
                 from ../xmpl_trx_tx.c:3:
c:\program files\atmel\avr tools\avr toolchain\bin\../lib/gcc/avr/4.7.2/../../../../avr/include/stdio.h:669:12: note: expected 'char *' but argument is of type 'uint8_t *'
../xmpl_trx_tx.c:206:5: warning: pointer targets in passing argument 1 of 'sendestring' differ in signedness [-Wpointer-sign]
../xmpl_trx_tx.c:41:5: note: expected 'char *' but argument is of type 'uint8_t *'
make: *** [xmpl_trx_tx.o] Error 1
Build failed with 2 errors and 4 warnings...
\$\endgroup\$
  • \$\begingroup\$ Sorry i still dont understand what is working and what is not working. RF communication via UART is working ? And you want to add SPI on master side and send the result via RF to slave ? slave will then send it to PC ? \$\endgroup\$ – Gossamer Sep 24 '13 at 7:11
  • \$\begingroup\$ Hello, Sorry if is not too clear¡ RF comunication via UART is working and reeding data from LTC2498 but using just one Uc:LTC2498--SPI--uC(Programmed with code 3)--UART_USB--PC. I got transmit a messege using two Uc with the modification code 4 and code 5: uC-(Radio Link)-uC-UART_USB--PC. Now I need to get data from LTC2498 but using 2 uC: -LTC2498--SPI-uC--(RadioLink)-uC-UART_USB-PC Thanks! \$\endgroup\$ – Ektor Sep 24 '13 at 7:26
  • \$\begingroup\$ Ok, so you know how to read data from LTC using one uC and you know how to make communication from one uC to another and send that data to PC, but you dont know how to combine those two use cases ? \$\endgroup\$ – Gossamer Sep 24 '13 at 9:08
  • \$\begingroup\$ Exactly! Could you help me? On the sent code I have to writte something like the last code I wrote but instead of temp = read_ltc2498(); because I have to make reference to data from LTC2498, and on the other hand I aswell have to implement UART and SPI like a function. Would be better if I show you my current code(which makes compilation errors)(and how? because on the comments is impossible,sorry I am new in this forum). Always thank you!! \$\endgroup\$ – Ektor Sep 24 '13 at 9:22
1
\$\begingroup\$

On the master side, you will have something like:

while (1) {
    if(shouldreadLTC) {
        value = readLTC2498 ();
        sendToSlave (value);
        }
    }
//some timer routine to enable shouldreadLTC

And on the slave side:

while (1) {
    if (dataInBuffer()) {
        value = readBuffer();
        sendToPC (value);
        }
     }
//uart ringbuffer handling, interrupt enabled

Basically this is what you would like to achieve ? If i understood correctly from code above, following functions are know and working:

uint32_t readLTC2498 () 
{
    uint32_t masterIn = 0;
   //CS des Thermochips auf low
    PORTB &= !(1<<DD_SS);


    //Byte1
    result = SPI_MasterTransmit(masterOut1);        
    masterIn = (result & 0b00011111);  //die ersten drei Bit löschen

    //Byte2
    result = SPI_MasterTransmit(masterOut2);
    masterIn = (masterIn<<8) + result;

    //Byte3
    result = SPI_MasterTransmit(0);
    masterIn = (masterIn<<8) + result;

    //Byte4
    result = SPI_MasterTransmit(0);
    masterIn = (masterIn<<8) + result;

    //CS des Thermochips auf high
    PORTB |= (1<<DD_SS);

    masterIn = (masterIn>>5) & 0b00000000111111111111111111111111; //die letzten 5 Bit löschen
return masterIn;
}
uint8_t g_str[128];
void sendToPC (uint32_t value)
{
    uint32_t Temp;
    sprintf(g_str, "masterIn: %ld", value);
    sendestring(g_str);

    Temp = (value*4/1570)-273;

    sprintf(g_str, " Temp: %ld", Temp);
    sendestring(g_str);
}

What you are missing is sendToSlave ? plus these timer and uart interrupt handling ?

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I have answer my onw question because here is imposiible to show you my code.;D \$\endgroup\$ – Ektor Sep 24 '13 at 22:11
  • \$\begingroup\$ @Ektor :Dont accept the answer yet, as it might not raise the attention from others, who might also help you. You can upvote it, if you think its useful. \$\endgroup\$ – Gossamer Sep 25 '13 at 6:45
  • \$\begingroup\$ OK, Thank you, I won´t accept answers yet¡ I can not upvote because I need at least 15 reputation points! Now I have add the compilation errors at the end of each code¡ \$\endgroup\$ – Ektor Sep 25 '13 at 7:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.