Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Whats going wrong with the code?

Status
Not open for further replies.

hobby_85

Junior Member level 2
Joined
Aug 17, 2009
Messages
21
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,586
16f688.h

I bought a RF kit, transmitter and receiver, and the website of a similar product is below. Now, im trying to write code for it, just to make sure it is working.

https://www.sparkfun.com/commerce/product_info.php?products_id=8950

Im using a PIC 16f688 and if the LED lights up to a correct pattern, i know the code is working. However, it is not.

Here is the TX code:

#include <16F688.h>
//-------------------------------------------------------------------------------
#define WireTX PIN_C4 //
#define WireRX PIN_C5
//-------------------------------------------------------------------------------
#fuses XT, NOWDT, NOPROTECT,NOBROWNOUT, PUT
#use delay (clock = 4000000)
#use rs232(baud=2400,xmit=WireTX , rcv=WireRX , STREAM=COM_A )

void main(){

for(;;){

if(input(PIN_C2)==0) //if button pressed
{

output_high(PIN_A1); //output high Led
delay_ms(20); //delay 20ms
fputc('T',COM_A); //send data
delay_ms(20);
delay_ms(1000); //delay some ms
output_low(PIN_A1); // output low led
}

output_high(PIN_A1); // if button not pressed then just on off led on pin D1

delay_ms(50);
output_low(PIN_A1);
delay_ms(50);

}
}

So if the button is pressed, the letter T is meant to be sent across, and the LED should come on, then off then on a longer time.

Here is the corresponding Receiver code:

#include <16F688.h>
#fuses XT, NOWDT, NOPROTECT,BROWNOUT, PUT
#use delay (clock = 4000000)
//------------------------------
#define WireTX PIN_C4
#define WireRX PIN_C5
//------------------------------
#use rs232(baud=2400, xmit=WireTX, rcv=WireRX, STREAM=COM_A)
unsigned int8 data;
int1 flag=0;

#int_rda
void rd_isr(void){
disable_interrupts(INT_RDA); // Disable Serial Recieve Interrupt
disable_interrupts(GLOBAL); // Disable Global Interrupts

data= fgetc(COM_A);
if(data=='T'){
flag=1;
}

enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);

}

void main(){

enable_interrupts(global);
enable_interrupts(int_rda);

for(;;){

if(flag==1){
output_high(PIN_A1);
delay_ms(1000);
output_low(PIN_A1);
flag=0;
}

output_high(PIN_A1);
delay_ms(50);
output_low(PIN_A1);
delay_ms(50);
}
}

So if the message is received, the LED should come on/off in 1 sec intervals. If not, it should just flash on and off.

I have an oscilloscope, so i can look at the signals being transmitted. Here are the problems:

1) The switch - When i checked the RF signal being sent when the button was pushed, i saw a step on the oscilloscope. The message would be sent forever and the led would light as coded.
So i know something was sent across. However, after a couple of seconds, even when the switch was off, the message was sent automatically.
I connected 220k resister from the output of the MC to the LED, and then to GND.

2) The receiver - The led turns on/off, as though it didnt receive anything. However, when i connected the osc to the receiver/RX of the MC, i can see a jump in the signal, matching the signal sent by the tx. So why isnt the led lighting as expected?

Any ideas?

Thanks
 

whats going wrong

If you hook your oscilloscope to the data output of the module I think you will see whats happening. The module is AM and almost certainly has a data slicer inside it. This will track the average data level (note that this is not the same as average radio signal level). It will adapt to the absence of signal (a logic 0 going into the transmitter) and adjust its slicer to the level of the noise floor. You will probably find that random data is leaving the module and because you are only looking for a single matching byte, it occurs occasionally by chance.

There are many ways to fix the problem. Unfortunately, the module doesn't have a signal level output to monitor, otherwise you could simply ignore anything that came out when nothing was being received so you are forced into a software solution.

The simplest way to try is to transmit several zeroes (0x00, not '0') before your data to allow the receiver to adapt, then use more than one byte to carry your message. Remember that each extra byte gives you 255 times less likelyhood of the pattern being misinterpreted. In my projects I generally have to send whole strings of characters so I reserve the ASCII 'STX' character as a 'clear receive buffer and prepare to receive data' signal. I send several STX characters, my message and then a CRC value to confirm everything got through.

You are finding out the hard way that RF data communication isn't as easy as it looks. Persevere though, when you understand the reason for failure and design defensively you will get good results.

Brian.
 

    hobby_85

    Points: 2
    Helpful Answer Positive Rating
16f688 define

Hey Brian,

Thanks for the reply. That was really informative. This is the fist time I am playing with RF, so your right, its a little frustrating. But I am keen to get this working and will definitely look into what you said. I also had a couple of questions, and would really appreciate if you could guide me.

Before I get into the questions, Id like to explain my application briefly. I have 5 transmitter/receiver pairs. 1 Master and 4 slaves. Sorry if i got/get the terminology wrong. Anyway, each of the 4 slaves will have to be identified by a unique address. For now, lets just call them slave 1 , slave 2 and so on.

First, the Master Tx has to contact Slave1. Slave 1 receives a random non-important message and sends a ACK back. Once Master Rx receives this ACK, it has to contact Slave 2 and so on. If it doesnt get ACK after a certain time from any of the slaves, it automatically contacts the next slave. So your right, I need to make sure that the signals are coded properly, with checksums and all, so that I know which slave is sending the ACK back.

You mentioned that I should probably add a couple of 0's to warn the receiver that a message is imminent. This has to be in HEX like you mentioned. Ok, so lets say I send three 0's before every message. Now, Master has to contact slave 1. Since all the other slaves are within the same room, each slave will look out for a certain 'code' to make sure that the message is intended for them. this will be their slave ID. So for slave 1, lets make it 001. 2 will be 010 and so on.

So, now the message is 000-001(for slave1). Now I need to add a checksum to tell the receiver that the entire message has been received. This is where im getting confused. What should this be? Another three 0's? The inverse of the mssage with a Z to tell the receiver that all has arrived. Hows 000-001100-Z for master to slave 1, 000-010010-Z for master to slave 2 and 000-011110-Z for master to slave3?

Now lets say we get this sorted. The slave has to send its own unique ACK to the master. This will probably be 000-ACK-z. Likewise, B's ACK would be 000-BCK-z.

Am I going in the right track here? or have i got it completly wrong?

Thanks mate.

On a side note brian, youve been answering my other posts about interfacing rf modules with IO pins. The TX/RX pins of the PIC are being used by the rs232 to talk to the PC, so i need to learn how to control the RF modules using the IO pins. I believe this is called software UART. Is that correct? I have no idea how to control rf using the uart of the pic, let alone control it with IO pins. But I am willing to play catch up and learn, so if you could help me out, that would be excellent.

Thanks
 

#int_rda

Hi Hobby_85.

Your system is very similar to one of mine. I have one master control unit indoors and 5 slaves controlled from it. The master has the radio link, a link to a PC, and LCD display, keypad and a few warning lights/buzzers. The slaves do various things from monitoring RFID tags to controlling pumping equipment.

Firstly, the master/slave is a good way of naming them, it implies that one is boss and the others should obey it!

I will describe the messaging in my system although you are of course free to create your own, there are no rules, just examples. I should point out that I am addressable FM modules rather than the AM ones you are using but the principle is the same.

The extra characters you send before the real message are called 'preamble' and their purpose is two fold: They give the receiver time to adjust to the signal strength and they give the UART something the chew on to get it synchronized. Nearly all radio modules have AGC (automatic gain control) which is to help the receiver cope with weak and strong signals equally well. If they ran at full sensitivity so they could hear weak signals they would probably overload with a strong one. Similarly, if the gain is set low so the receiver doesn't overload, it will be 'deaf' to weak signals. The AGC reduces the gain as the signal gets stronger but it takes time to react so if your data starts straight away the first bits might be corrupted. Throwing a few 'ignore me' bytes out first will make sure it is ready for the real stuff.

From this you can see that the preamble should be sent before each burst of transmission, no matter which module is sending it.

You will have to make a distinction between what is data and what isn't. For example, if you are using 0x00 as preamble, you can't also use it in your data. It would be difficult to work out what is a genuine message and what should be ignored. What I do is send all data as text so only ASCII characters 0x20 through to 0x7F are used to carry information. This leaves the control part of the ASCII table to be used for control purposes. I use STX (0x02) for its original purpose which is "Start of Transmission" for example. If you wanted to send 0x1234 you would actually send 0x31, 0x32, 0x33, 0x34, the ASCII codes for individual digits.

So a typical message in my system might be:
0x00, 0x00, 0x00, STX, 'H', 'E', 'L', 'L', '0', CR, [CRC]

where CR is a carriage return (0x0D) and the [CRC] is a byte calculated from everything between the STX and CR.

It's a little more complicated in my system because I have to load routing addresses into the modules as well as data and I use something similar to Manchester encoding to improve the data integrity but you see the general idea.

If you follow my ASCII example, you would reply to a message with:
0x00, 0x00, 0x00, ACK, CR, [CRC] or if it failed, NAK instead of ACK.

You are right about the software UART, it is basically wiggling the chips pins at the right time so it looks like a real UART is doing it.

Brian.
 

    hobby_85

    Points: 2
    Helpful Answer Positive Rating
rfid triangulation

Yep, it all makes sense now. Last few questions I thought off. In my system, like i mentioned, the data within the msg itself is not important. In fact, all the msg will contain is which slave its coming from.

So does this mean for the transmitter side, I actually hard code the msg in. Like say for the code above which sends in the letter 'T', i would replace it with ....

delay_ms(20); //delay 20ms
fputc('0x00,0x00,0x00,STX, 'A', 'A', 'A', CR, C3',COM_A); //send data from MASTER TO SLAVE 1
delay_ms(20);

i calculated the CRC to be C3 by adding A+A+A = 0xC3.

I presume i neglect the commas when writing the code?

When the write the receiver code , it would something like this. Ill just write in psedo code;

while(1) // Do an infinite loop
{
int preamble;
int data1;
int data2;
int data3;
int cr;
int crc;

preamble= fgetc(COM_A);
if(preamble==0x00){
preamble = 0;
preamble= fgetc(COM_A); //do again to get the next preamble.
//check to see if next 2 preambles are 0 in hex. Make sure that preamble is cleared before it receives the next character;
//get data one letter at a time, and store into data1, data2, data3.
//next value should be cr, if not, its an error
//get crc value and store into int crc
//write if statement, add data1 +data2 + data3 in hex and see if value is crc. if not, error, if yes, light an LED or something
}

How am I going so far Brian? This looks ridiculously fun so ill let you know how it goes when test it out today. Is there anything I should change in the mean time?

Im trying to figure out RF (well the basics atlease) by the weekend. Ill have to hit you up on how to make the IO pins to act as RX/TX at some stage too.

And thanks for your long and extremely useful replies. They are brilliant. Also, for the TX, no commas right?...im just worried that when the TX sends the whole lot together, how is the RX going to seperate them and store em? unless i put a delay in between each one...but that defeats the purpose of a preamble and all that.

Thanks
 

16f688 lcd display ascii

Almost right!

You have to remember that the preamble is there to 'clear the path' for the remaining data and may itself not get through because of the AGC problem. for that reason, it's best to concentrate on finding the STX rather than the 0x00.

You are right about the commas, they are only there as part of the program syntax but I'm a bit worried that your fputc() function is handling so many parameters. Check with your compiler documents but usually it only accepts one character at a time.

This is part of my receive code to show how I do it:
Code:
void GotByte()   
{

	InByte = WaitRx();
	
	if(InByte == STX)	// STX initiates a transmission
	{
		InPtr = 0;
		*InBuffer = 0;
		LocalCRC = 0;
		return;
	}
	
	if((InByte == CR) || (InByte == ETX)) // CR or ETX terminate a transmission
	{
		ParseInBuffer(); // process the buffer contents
		return;
	}
	
	// if still space in InBuffer and character is alphanumeric, append it to InBuffer
	if((InPtr < 0x10) && (InByte > 0x1F) && (InByte < 0x7F)) 
	{
		if(InPtr < 0x0E) LocalCRC += InByte;
		InBuffer[InPtr++] = InByte;
		InBuffer[InPtr] = 0;
	}
}

The routine is called when the USART generates an interrupt to say a character has arrived. The WaitRx() function retrieves the character, InPrt is a pointer into the receive buffer which is called InBuffer. When either a CR or ETX character is found, the function called ParseInBuffer() is called to use the data that was received and LocalCRC is loaded with the sum of the ASCII values of the characters.

The transmitting end is written in assembly language so it probably wouldn't help you but basically it sends a few 0x00's then STX, then a message followed by a CRC and finally a CR.

The CRC transmitted and the one found in LocalCRC at the receiver should match, if they don't the message is ignored.

There is a 'gotcha' to be aware of with CRC calculations, its very easy to include the CRC in its own calculation, in other words, work out what it should be and add it to the total. Of course it will never work, you just have to be careful that you only add up the relevant characters. I just use the total of the ASCII values as the CRC but there are better calculations that give better security if you really need it.

If your compiler supports it, you could try sprintf() to create your messages although with such simple and short data it might just be easier to use several fputc() commands, one for each character. Example:

sprintf(MyString,"%x%x%x%xCCC%x%x",0,0,0,STX,CRC,CR);
while(MyString) fputc(MyString[i++]);

or something like that.

The bit banging routines is straight forward but is a 'blocking' routine, meaning it holds up the rest of your program (blocks it) until the function returns. Basically, you transmit the data by setting your TX pin high or low at the appropriate time to send the bits in your byte one by one. The timing depends on the speed (Baud rate) you wish to use. Receiving is done by either polling or using an interrupt to find the first edge of the data then waiting one half of one bit time and sampling again. The half bit time aligns the point you sample with the middle of the bit. then you repeat the process with a full bit time until you have sampled all the mid points of bits in the byte. To rebuild the transmitted byte, you shift the bit into a variable until all 8 bits are back together again.

Brian.
 

    hobby_85

    Points: 2
    Helpful Answer Positive Rating
18f46j11

ok gotcha,

so this is what im going to change:

1) dont search for the preamble. (the zeroes). Search for the STX
2) use fgets() to to store characters in a string
3) search for cr
3) process values in the string to make sure the ascii addition corresponds to the localcrc.
4) Error is CRC dont match, but if it does, thats the message.

Got you mate. Thanks for all the help. Once I get this going, Ill let you know.

Im using the RX/TX pins at the moment just to test it out.

Im only sending data into the PC, not receiving any. So i could probably connect the RF receiver to the RX pin, the TX to the rs232 and then Ill only need to play with the 1 IO pin and make it act like a second tx..

ps. your right about the fputc. i didnt think that through. ill check the compiler manual and sort that out.

Thanks heaps.
 

int_rda usart receive data ready ccs c

Absolutely spot on!

Let me know how you get on.
I'm currently working on a project with 2 UARTS and bit banging as well so you can imagine what that's like! It's using several 18F46J11 chips, running at 40.6MHz and has 1Mb of RAM hanging off it as well.

Where in the World are you? It would be nice if members had to place at least their country in their profiles so it gave an idea of which time zone they are in. I've had someone complain I'm slow replying (even though it is entirely voluntary) when it's 3am here.

Brian.
 

Re: Whats going wrong?

What your doing makes my project look like child's play. But in the whole scheme of things, im actually trying to make a room-level location tracking device, the key word is trying. Dont know how far ill get, but its always worth a shot i think.

Im using ultrasound and RF to get the TDOA of the signals and given i know the height of the room, the speed of sound and light, i should be able to find a location based on triangulation. Well, that somewhat explains it i suppose.

Im in sydney at the moment, in my last session of electrical engineering. But i was raised in the UK. My major is in power, so im pretty much playing catch up with telecommunications. But its def interesting.

How about you? in industry or uni?
(*crosses his fingers and hopes you dont say 'highschool'*) haha
 

Re: Whats going wrong?

HIGHSCHOOL !!!!

I wish !!

Left there 40 years ago. I'm now doing electronics primarily as a hobby but I spent many years in the telecoms and test equipment industry in the US and Europe.

Brian.
 

    hobby_85

    Points: 2
    Helpful Answer Positive Rating
Re: Whats going wrong?

betwixt said:
HIGHSCHOOL !!!!

I wish !!

Left there 40 years ago. I'm now doing electronics primarily as a hobby but I spent many years in the telecoms and test equipment industry in the US and Europe.

Brian.

haha sounds good. I had a look at your site too. has a wealth of information. i was reading the pic programming bit for a while till i had to convince myself to get back to work.

btw, appreciate the help too.

in my infinite wisdom, i broke one of the GND pins of the PIC, so i wont be able to test the RX till tomo morning. I uploaded the new tx code to the last PIC i have though, and plugged it into the osc. Your right, the signals are much clearer.

However, just one small problem. Though im not so sure if its a software one anymore. I had a switch on me circuit, controlling when the data was being sent out. Earlier, you remember when i was just sending out a 'T', and it used to go off regardless? Well, its not happening THAT often anymore, but its happening a lil bit. I dont know if its a same data being sent out (AAA), because i cant tell from the osc, but the LED lights up like its sending something.

Until i get me receiver side set up tomo, i wont know if its actually transmitting rubbish or my data for some odd reason. Is there anyway I can stop this? My circuit side is simple really....a resistor from the output of the PIC to the switch to GND. I need the tx to transmit only when programmed,...so my entire project collapses.

On a side note, ive also had to send one char at a time. Like this:

int STX = 0x02;
int CRC = 85; //85 chosen randomly for test purposes
int CR = 0x0d;

fputc('0',COM_A);
fputc('0',COM_A);
fputc('0',COM_A);
fputc(STX,COM_A);
fputc('A',COM_A);
fputc('A',COM_A);
fputc('A',COM_A);
fputc(CRC,COM_A);
fputc(CR,COM_A);

I tried doing the while loop like you mentioned, but nothings coming out of the PIC.

sprintf(data,"%x%x%x%xAAA%x%x",0,0,0,STX,CRC,CR);

while(counter<9){
fputc(data[counter],COM_A);
counter = counter+1;
}

I have a feeling its the buffer size...and also cause i prolly haven't initialized the characters right. Getting confused between hex,dec, and ascii in C.

Its nearly 3 here so im off to bed. Ill keep you posted on how it goes. If you got any tips on how to stop my data from being transmitted for no reason, that would be great.

Thanks brian.
 

Re: Whats going wrong?

For some reason, your last reply has vanished so I'll comment on what I can remember of it.

It looks OK but you could try some changes:

The STX and CR probably should be 'char' instead of 'int' but it would be better to use the '#define' directive to set them. I use a small file, shown below, called 'ascii.h' and #include it at the top of my programs.
Code:
// ASCII Control Character definitions

#define NUL 0x00
#define SOH 0x01
#define STX 0x02
#define ETX 0x03
#define EOT 0x04
#define ENQ 0x05
#define ACK 0x06
#define BEL 0x07
#define BS 0x08
#define HT 0x09
#define LF 0x0A
#define VT 0x0B
#define FF 0x0C
#define CR 0x0D
#define SOH 0x0E
#define SI 0x0F
#define DLE 0x10
#define XON 0x11
#define DC2 0x12
#define XOFF 0x13
#define DC4 0x14
#define NAK 0x15
#define SYN 0x16
#define ETB 0x17
#define CAN 0x18
#define EM 0x19
#define SUB 0x1A
#define ESC 0x1B
#define FS 0x1C
#define GS 0x1D
#define RS 0x1E
#define US 0x1F
#define DEL 0x7F

Your working code transmits '0' which is character zero rather than real zero, try changing it to plain 0 or 0x00.

Incidentally, while not wrong to use "variable = variable + 1", the clearer way to increment a variable is to use "variable++".

Brian.

Added after 2 minutes:

We cross posted.

Add:

char data[9];

at the top.

Brian.
 

Re: Whats going wrong?

ok got you. ill get it sorted out by tomo. thanks for all the help brian.

ill try and get a software uart going also, so i learn before i post.

good luck with your project too.
 

Re: Whats going wrong?

Brian,

I tested out my code...and no luck. Im starting to feel guilty that Im asking for so much assistance in setting something simple up.

The transmitter seems working. The osc is showing data being sent out. However, data is still being sent out if the switch isnt pressed. I need to stop this because my project revolves around it being precise. I cant let it shoot off data unless its meant too.

The TX code is as follows. Im making it simple for now, sending one bit at a time.

Code:
#include <16F688.h>
#include <ascii.h>

//-------------------------------------------------------------------------------
#define WireTX PIN_C4 // 
#define WireRX PIN_C5
//-------------------------------------------------------------------------------
#fuses XT, NOWDT, NOPROTECT,NOBROWNOUT, PUT
#use delay (clock = 4000000)
#use rs232(baud=2400,xmit=WireTX , rcv=WireRX , STREAM=COM_A )


int CRC = 85;                              //CRC set in code for test purposes

 void main()
  {

setup_adc_ports(NO_ANALOGS);  //set all inputs to digital

   for(;;){     

         if(input(PIN_C2)==0)         //if button pressed
         {
       
                output_high(PIN_A1); //output high Led
                delay_ms(20);
                
                  fputc(NUL,COM_A);  //send out stream AAA
                  fputc(NUL,COM_A);
                  fputc(NUL,COM_A);
                  fputc(STX,COM_A);
                  fputc('A',COM_A);
                  fputc('A',COM_A);
                  fputc('A',COM_A);
                  fputc(CRC,COM_A); //send out checksum of 85
                  fputc(CR,COM_A);
   
   
                delay_ms(20);
                delay_ms(1000);                 //delay some ms
                output_low(PIN_A1);             // output low led
                delay_ms(1000);
         }
         
         else{      
               
               output_high(PIN_A1); 
               delay_ms(50);           
               output_low(PIN_A1);
               delay_ms(50);
         }
   }
}

And for the receiver bit, Im beginning to think Im making a drastic error. Ive tried to light up an LED when the STX comes in and it doesnt.

Heres the code:

Code:
#include <16F688.h>
#include <ascii.h>

#fuses XT, NOWDT, NOPROTECT,BROWNOUT, PUT
#use delay (clock = 4000000)
//------------------------------
#define WireTX PIN_C4
#define WireRX PIN_C5 
//------------------------------
#use rs232(baud=2400, xmit=WireTX, rcv=WireRX, STREAM=COM_A)

int InByte;
char data[3];               //buffer to store data the 3 A;s

void main(){

for(;;){                      //forever

   InByte = fgetc(COM_A);          //store in InByte
   
   if(InByte == STX){                //if STX encountered, store next 3 char into data
   fgets(data,COM_A);
   }
   
   if(Inbyte == 85){                //checksum encountered, check data contents
   
      if (data[0] && data[1] && data[2] == 'A'){
         output_high(PIN_A1); //light up LED on pin A1 for 3 sec
         delay_ms(1000);
         delay_ms(1000);
         delay_ms(1000);      
      }
      
   }
   
} //end for loop

}// end main

I mean, the code i know is really simple. But all Im trying to do is get it to receive just once. After that, I can play around with bigger arrays, pointers, and what not.

Im sorry about pestering you on this issue. I wanted to get it sorted by today, and Im banging my head against the wall here.

Thanks heaps mate.
 

Re: Whats going wrong?

It looks structurally OK but I have a few comments and questions. I'm not sure which 'C' compiler you are using so please double check what I find, it may not be applicable to it's syntax.

Transmitting:
1. I assume statements like (PIN_C2) are referring to Port C, bit 2. Does the statement "input(PIN_C2)" automatically make the port bit an input? in other words, as well as reading it, does it set the TRIS bit for that pin to be an input?
Does it have a pull-up resistor to make it high until you ground it?

2. Does the "fputc" command queue the data (buffer it)? You may be force feeding it with all the bytes before they have had time to pass through the UART.

Receiving:
1. Make your data[] array at least one byte bigger for now, you can always reduce its size later. You have no way of setting the message length at the moment so the "fgets" will probably capture everything up to the CR and overflow the array.

2. Not sure about your check for the three 'A' characters being correct. As you are ANDing the logic of the characters together, there may be other combinations that pass the test. Try this instead:
if((data[0] == 'A') && (data[1] == 'A') && (data[2] == 'A')) {

Try those changes and let me know how you get on.
Brian.
 

    hobby_85

    Points: 2
    Helpful Answer Positive Rating
Re: Whats going wrong?

Brian,

Transmitting:

This part is sorted. I located a little problem in the switch i was using, and the rf transmits perfectly as wanted. Thanks for the help.

Im using the ccs compiler, so yes, (PIN_C2) is Port C, bit 2. Input C2 reads the input regardless of how the tris is set. So it does it automatically.

So TX is fine.

Receiver:

Changed the buffer size and the data check statement like you proposed. I also put LEDs at each stage. This is what I encountered.

1) Led when the STX is encountered lights up, but only once...regardless of how many times the message is sent. It only happens the first time too, and only when i turn on the power to the board.

2) I dont think it reads 85, my checksum. The led at this stage doesnt light up, at any stage. And ofcourse, the led for message received doesnt light up either.

Im not sure why STX is only received once though. atleast that should work throughout.

when i connected the osc to the rx and tx pins of the RF module, i can see that the receiver is picking it up. to an extent though. instead of picking up the perfect square wave type of signal being send, it shows triangular versions...but following the tx. So the chip is working. i hope this makes sense.

Any thoughts? Checked circuit 10 times and counting.

Thanks
 

Re: Whats going wrong?

I suspect your diagnosis of the CRC failing is correct, but not perhaps for the reason you think.

What tells the fgets() function to terminate?

My guess is that the CRC has already been received by the fgets() and stored in the array (if it hasn't overflowed) so looking for it afterward isn't going to work.

Can you try removing the fgets() and replacing it with an fgetc() loop that checks each character in turn and stores it, like I did in my example. That way you can find the CR and CRC wherever it is in the message.

Guessing again - the reason it worked once only is that the array overflowed and corrupted whatever variable is stored after it. Remember that 'C' does not perform bounds checking. If the CCS compiler creates a file showing the addresses allocated to variables, look at whatever is after the data array, it probably got overwritten.

Brian.
 

Whats going wrong?

I have a small suggestion (not knowing this particular development environment - hardware as well as PIC compiler/libraries). Try set compiler optimization to NONE (for easier debugging) and make sure that addresses of hardware peripherals have "volatile" qualifier.
Good luck.
 

Re: Whats going wrong?

hey, still working on the receiver at the moment, and will let you know how it goes.

i tried shortening the code to isolate the problem, such that when it receives STX, itll light up the led. This is with a continuous transmission every few seconds. No luck.

Still trying. Thanks for the help so far.

Added after 3 hours 39 minutes:

hey brian,

i havent been able to fix my receiver code, but managed to find C codes online that shows you how to send RF signals over the IO pins rather than the TX/RX ones of the PIC.

https://www.electro-tech-online.com/micro-controllers/92375-manchester-routines-c-pic.html


I found it on another forum. Just scroll down till you come to 2 attachments. Some guy posted it along with a pdf document explaining the process.

I tested it too. Well, to an extent. I set it up on my PIC and managed to capture the transmitted and received signal on the oscilloscope. I dont know if the receiver captured the correct message, but ill do the LED test tomo to verify.

As for my receiver, im still trying to figure out where im going wrong. I was also wondering if i should be using a HT-12 encoder and decoder. Would that help?

Thanks mate. Hope your project is coming along better than mine.
 

Re: Whats going wrong?

Sorry for not responding sooner, I've had other jobs to do today.

You might want to search this board for the topic "Problem with wireless serial transmisson" (note the spelling mistake!) which goes into heated discussions on data encoding methods for transmission.

You could use the HT-12 but it would add expense. I would persevere with a software solution before spending money. I get 100% results at 19,200 bauds over long distances with simple modules so it can be done. It's also worth noting that HT-12 and software generated Manchester codes are only beneficial if you are using FM modules but yours are AM. It will still work if you use Manchester coding but there will be less throughput because extra bits have to be sent.

PM me with the latest code you are working with so I can look at it again.

Brian.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top