Debugging RF project

I am trying to create a RF project where it communicates from one AVR to another. I decided to start with a simple transmitter/receiver combo (Maybe my first mistake of many!) I am following the tutorial from: http://winavr.scienceprog.com/example-a … llers.html and I modified the code for the AVR I am using, ATMega168A. I utilized an external crystal to get reliable USART results and made sure the CKDIV8 was not programmed. Of course, after I wired everything, it didn’t work Sad So now I need to figure out why. I thought I should be able to see the signal being transmitted by connecting an oscilloscope to tx pin of the AVR and see the wave generated since it should be at 1200 baud or about 1/1000 of a second. The output was a steady positive voltage (VDD)Any suggestions on debugging this? Here is the transmitter code I am using:

/*
 * transmitter168P.cpp
 *
 * Created: 5/30/2013 9:49:40 PM
 *  Author: RTS
 * first version for use with:
 * tx433 and Atmega168A using 11.0592MHz crystal

 * Note: for initial testing purposes connect TX to RX and connect LEDs on same board
 */ 

#define F_CPU 11059200
#include <avr/io.h>
#include <util/delay.h>

//Set desired baud rate
#define BAUDRATE 1200

//calculate UBRR value (Using UBBR0)
#define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1)

//define transmit parameters
#define SYNCBIT 0xAA //syncronization bit (10101010)
#define RADDR 0x44 //Transmitter ID # (01000100) Change this to two hex numbers in Ver 2.
#define LEDON 0x11 //turn on LED command
#define LEDOFF 0x22 //turn off LED command

void USART_Init(void) //initialize USART settings
{
	//set baud rate in USART Baud Rate Register (UBRR0)
	UBRR0L= (uint8_t) UBRRVAL;  //low byte
	UBRR0H= (UBRRVAL>>8);  //high byte

	//set data frame format: asynchronous mode, no parity, 1 stop bit, 8 bit size
	UCSR0B=(1<<RXEN0)|(1<<TXEN0); //sets to mode to receive and transmit...probably don't need RXEN in final version
	UCSR0C=(0<<USBS0)|(3<<UCSZ00);//0<<USBS0 sets 1 stop bit. 3<<UCSZ00 sets 8 data bits *** Check this in simulator
}

void USART_vSendByte(uint8_t u8Data)
{
	while (!(UCSR0A &(1<<UDRE0))); //wait for transmit buffer to be empty
	UDR0=u8Data; //puts data into send buffer and sends it
}

void Send_Packet(uint8_t addr,uint8_t cmd)
{
	USART_vSendByte(SYNCBIT); //sends sync byte
	USART_vSendByte(addr); //sends tx address...change to RADDR?
	USART_vSendByte(cmd); //sends data byte....add additional bytes here after functioning
	USART_vSendByte((addr+cmd)); //send checksum for error checking.
}

void delayms(uint8_t t) //delay in ms...use delay function instead?
{
	for (int i=0;t;i++)
	_delay_ms(1);
}

int main(void)
{
	USART_Init();
	while(1)
	{
		Send_Packet(RADDR, LEDON);
		delayms(100);
		Send_Packet(RADDR, LEDOFF);
		delayms(100);
	}
	return 0;
}

Any ideas?

I found the problem, typo in my code:

void delayms(uint8_t t) //delay in ms...use delay function instead?
{
   for (int i=0;t;i++)
   _delay_ms(1);
}

should have been:

void delayms(uint8_t t) //delay in ms...use delay function instead?
{
   for (int i=0;i<t;i++)
   _delay_ms(1);
}

So now the problem is with the receiver portion. With an oscilloscope, the rx pin on the MCU is receiving a wave that “looks” the same as the one being sent by the transmitter (I am going to pick up a second probe to see both waves at the same time to verify) but the circuit is not working. What can I do to trace the probable problem? Here is the receiver code:

/* 
 * receiver168A.cpp 
 *first version for use with: 
 *rx413 and Atmega168A using 11.0592MHz crystal 
 * Created: 6/10/2013 9:32:49 PM 
 *  Author: RTS 
 */ 

#define F_CPU 11059200UL 
#include <avr/io.h> 
#include <util/delay.h> 
#include <avr/interrupt.h> 


//Set desired baud rate 
#define BAUDRATE 1200UL 

//calculate UBRR value (Using UBBR0) 
#define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1) 

//define transmit parameters 
#define SYNCBIT 0xAA //synchronization bit (10101010) 
#define RADDR 0x44 //Transmitter ID # (01000100) Change this to two hex numbers in Ver 2 and read from EEPROM 
#define LEDON 0x11 //turn on LED command 
#define LEDOFF 0x22 //turn off LED command 

void USART_Init(void) //initialize USART settings 
{ 
   //set baud rate in USART Baud Rate Register (UBRR0) 
   UBRR0L= (uint8_t) UBRRVAL;  //low byte 
   UBRR0H= (UBRRVAL>>8);  //high byte 

   //set data frame format: asynchronous mode, no parity, 1 stop bit, 8 bit size 
   UCSR0B=(1<<RXEN0)|(1<<RXCIE0)|(1<<TXEN0); //sets to mode to receive and transmit also sets up RX complete interrupt...probably don't need TXEN in final version 
   UCSR0C=(0<<USBS0)|(3<<UCSZ00);//0<<USBS0 sets 1 stop bit. 3<<UCSZ00 sets 8 data bits *** Check this in simulator 
} 

uint8_t USART_vReceiveByte(void) 
{ 
   while (!(UCSR0A &(1<<RXC0))); //wait for data to be received 
   return UDR0; 

} 

void Main_Init(void) // initialization...move to main() 
{ 
   DDRC=(1<<PC0); //define PORTC pin0 as output, use appropriate mask!! 
   PORTC|=(1<<0); //LED off 
   sei(); 
} 


int main(void) 
{ 
   Main_Init(); 
   USART_Init(); 
   uint8_t raddress, data,chk; //define variables for transmitter address, data and checksum 
   while(USART_vReceiveByte() !=SYNCBIT){}//wait for correct data 
    
      raddress=USART_vReceiveByte();//get transmitter address (add routine for multiple TX and two bytes) 
      data=USART_vReceiveByte();//get transmitted data(in future version will be beam break status?) 
      chk=USART_vReceiveByte();//get checksum to validate data 
      if (chk==(raddress+data)) //if correct data, continue 
      { 
         if(raddress==RADDR) //check for valid transmitter address add switch () case for all valid...check time for many addresses. Might have to limit to certain number 
         { 
            if(data==LEDON) //data sent is to turn on LED 
            { 
               PORTC &=~(1<<0); //Turn on Portc Pin0 
            } 
            else if (data==LEDOFF) //data sent to turn off LED 
            { 
               PORTC |=(1<<0);  //Turn off PORTC Pin0 
            } 
            else //bad data blink error 
            { 
               PORTC |=(1<<0); //LED on 
               _delay_ms(10); 
               PORTC &=~(1<<0); //LED off 
            } 
         } 
       
   } 
   return 0; 
}

Which RF Modules are you using?

Looking at both serial data signals with an O’scope is a good idea. Let us know what you find and post a scope picture if you can.

I am using this module: https://www.sparkfun.com/products/10535 I changed the transmit routine to transmit a continuous 0xAA and here is the wave forms.

http://racetrainingsystems.com/graphics/tx-rx_wave.JPG

They are pretty close, not sure where the longer portion of the waves come from?

Here is the code I used:

/*
 * transmitter168P.cpp
 *
 * Created: 5/30/2013 9:49:40 PM
 *  Author: RTS
 * first version for use with:
 * tx433 and Atmega168A using 11.0592MHz crystal

 * Note: for initial testing purposes connect TX to RX and connect LEDs on same board
 */ 

#define F_CPU 11059200
#include <avr/io.h>
#include <util/delay.h>

//Set desired baud rate
#define BAUDRATE 2400 

//calculate UBRR value (Using UBBR0)
#define UBRRVAL ((F_CPU/(BAUDRATE*16UL))-1)

//define transmit parameters
#define SYNCBIT 0xAA //synchronization bit (10101010)
#define RADDR 0xAA
#define LEDON 0xAA

void USART_Init(void) //initialize USART settings
{
	//set baud rate in USART Baud Rate Register (UBRR0)
	UBRR0L= (uint8_t) UBRRVAL;  //low byte
	UBRR0H= (UBRRVAL>>8);  //high byte

	//set data frame format: asynchronous mode, no parity, 1 stop bit, 8 bit size
	UCSR0B=(1<<RXEN0)|(1<<TXEN0); //sets to mode to receive and transmit...probably don't need RXEN in final version
	UCSR0C=(0<<USBS0)|(3<<UCSZ00);//0<<USBS0 sets 1 stop bit. 3<<UCSZ00 sets 8 data bits *** Check this in simulator
}

void USART_vSendByte(uint8_t u8Data)
{
	while (!(UCSR0A &(1<<UDRE0))); //wait for transmit buffer to be empty
	UDR0=u8Data; //puts data into send buffer and sends it
}
Where do  I go from here?

void Send_Packet(uint8_t addr,uint8_t cmd)
{
	
	USART_vSendByte(SYNCBIT); //sends sync byte
	USART_vSendByte(addr); //sends tx address...change to RADDR?
	USART_vSendByte(cmd); //sends data byte....add additional bytes here after functioning
		
	
}

void delayms(uint8_t t) //delay in ms...use delay function instead?
{
	for (int i=0;i<t;i++)
	_delay_ms(1);
}

int main(void)
{
	USART_Init();
	while(1)
	{
		Send_Packet(RADDR, LEDON);
		
	}
	return 0;
}

dusteater:
They are pretty close, not sure where the longer portion of the waves come from?

I didn't read the code closely, but they could be async start and stop bits.

I didn’t think about the start and stop bits, but it looks like there are not enough signals between the “pauses” and why would the positive pulses be shorter than the others. I would think that for timing purposes they should be identical?

Is the top trace from the UART output? I guess that it is and there the 0’s and 1’s have equal periods.

Guess then the bottom trace is out of the RF receiver and is not surprising that there 1’ and 0 periods are not equal. This is due to these RF modules are OOK modulation (I am surprised the receiver signals are that good). I’ll bet that the first bytes sent do not look good at all and may not be good if sending more 0’s or 1’s in a single byte.

What character are you receiving when sending 0x55 (ASCII ‘U’)?? Don’t send 0xaa since this is not a printable ASCII character.

Google OOK modulation to learn how this actually works and some solutions for using it.

Then read and study the code in the VirtualWire code:

http://www.airspayce.com/mikem/arduino/

I will make the change to 0x55, and post the results after I do that, but I have a couple questions.

  1. How do I know what character I am receiving when I send 0x55?

  2. Where and how do I verify this?

  3. VirtualWire is an Arduino library…I am not using Arduino…I will read it to understand it, but not sure how it would be relevant.

1- Its in my post, 0x55 is an ASCII ‘U’. Or google “ASCII Table” to learn all of the ASCII characters.

2- In a terminal program running on your PC (use a MAX232 between the RF receiver and a PC com port).

Or output the received data from the UART to an 8bit port on the AVR that drives LEDs.

3- VirtualWire is written in C which is very portable between processors. The only changes needed is processor hardware dependencies like PORT addresses, setup registers, UART setup and data. These functions should be written in a low level module that the VirtualWire high level functions call.