View previous topic :: View next topic |
Author |
Message |
nuno12345
Joined: 16 Jul 2008 Posts: 50
|
serial can't compare char |
Posted: Fri Aug 19, 2011 7:09 pm |
|
|
Hi, I'm using the following code:
Code: |
char data;
putc(getc());
data = getch();
if(data == "U")
{
output_high(PIN_B4);
}
|
What happens is if I connect TX to computer, I can read the right chars but PIN_B4 always stays low :(
Help?
Thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Sat Aug 20, 2011 2:28 am |
|
|
What are you actually sending?.
Think about your code:
Code: |
char data;
putc(getc()); //waits for a character, and sends this character back
data = getch(); //waits for _another_ character, and does not send it back
if(data == "U") //tests the second character, not the first
{
output_high(PIN_B4);
}
|
So what you are 'reading', is the first character sent, not the one being tested. Unless you send a pair of 'U' characters, B4, will remain low. If you are typing 'U<enter>', then the test will be looking at the enter, not the 'U'...
try:
Code: |
char data;
putc(data=getc());
if(data == "U")
{
output_high(PIN_B4);
}
|
Best Wishes |
|
|
nuno12345
Joined: 16 Jul 2008 Posts: 50
|
|
Posted: Sat Aug 20, 2011 3:53 am |
|
|
On the transmitter I have some buttons and when I press them it sends lots of "U" until the button is released.
I'll try your code but it seems that the compare function stays the same, only the way of getting data changes.
My output with computer connected to PIC is:
"00 55 00 55 00 55 00 55 00 55 00 55 00 55 00 55 .U.U.U.U.U.U.U.U"
Thank you. |
|
|
nuno12345
Joined: 16 Jul 2008 Posts: 50
|
|
Posted: Sat Aug 20, 2011 4:03 am |
|
|
Tried the code, same output, still no B4 :/ |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Sat Aug 20, 2011 4:49 am |
|
|
OK.
You would have had severe problems with the original code, unless the devices woke up exactly 'in sync', ending up testing the '0' bytes instead of the U's.
However you now need to go basic:
1) What PIC?. Is there a peripheral on port B that might stop the pin going high?.
2) Are you sure the PIC is receiving the data. You have the byte being echoed out. Is it this echo that you are looking at, or the source data?. You talk about connecting TX to a computer, this would require a MAX232 type connection. However if you are connecting to another PIC, unless this too has a MAX232, you will have the signal inverted. Remember a PIC 'talks' TTL async serial. A PC talks RS232. These are inverted, and use different signal levels, so are you sure you have the right signals at the PIC. The RX line want's to be sitting 'high' at the PIC, till data is received.
Best Wishes |
|
|
nuno12345
Joined: 16 Jul 2008 Posts: 50
|
|
Posted: Sat Aug 20, 2011 7:45 pm |
|
|
PIC is 16F628A, I would do it in 16F88 which I think it has a better support for rs232 communications, but looks like my programmer (JDM) can't get the right voltages trough serial port causing my desktop to only detect it sometimes.(?)
My setup is like: Cellular->TX->RX->MAX232->(B1)16F628A(B2)->PC
When I send U characters with my Cell I can receive them successfully in my terminal.
In my code I turn on a "working" LED at B0, I also check for other characters, from B4 to B7.
Curious thing is that if I let the PIC receive junk data from the RF the LEDs blink sometimes but I can't get on which character in my terminal.
Hope this helps you to help me |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Sat Aug 20, 2011 9:26 pm |
|
|
Is "U" a two character string, the letter U plus the terminating null?
Try data == 85 or data == 'U' instead of data == "U". _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
nuno12345
Joined: 16 Jul 2008 Posts: 50
|
|
Posted: Sun Aug 21, 2011 7:23 am |
|
|
Tried, no luck.
I think my problem is that data is getting more characters then just the U, I can't compare it because it tries to compare the whole string.
I think my solution is store it in a integer then do a for searching for my character in Dec. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Sun Aug 21, 2011 8:11 am |
|
|
Er. No.
A character _is_ an int. It holds just one character. There is no native 'string compare' in C, you have to use a function like strcmp, which handles an array of characters ending with a null character. getc, gets just _one_ character. This is not your problem.
There are several things that worry me:
1) You don't show a MAX232 between the PIC and the PC. One is needed here, yet you claim to be seeing the output on the PC. Odd....
2) The 16F628, has as good async serial as any other PIC. It has a UART, exactly the same as the 16F88.
3) You don't show your #use rs232 setup. This must have the keyword 'ERRORS', or if you fail to read a character before another arrives, the UART will be hung. However you wouldn't get the pass-through data if this was happening, so with the problem as described this is not the case.
4) What is turning B4 _off_ if it does turn on?. It may be as simple as speed. Remember if you have a loop round the outside of the function shown, it could be executing a few million instructions per second. If the loop contains a 'output_low(PIN_B4)', then you would almost certainly never see B4 go high.
5) You have go NOLVP selected?. If not, then B4 is one of the programming pins.
6) Show an entire basic program, it may simply be something else wrong, that is nothing to do with the serial.
Best Wishes |
|
|
nuno12345
Joined: 16 Jul 2008 Posts: 50
|
|
Posted: Sun Aug 21, 2011 12:13 pm |
|
|
Thought on strcmp ill try it when i get home.
I changed the program to:
Code: |
int data[1];
data[0]=getc();
printf("data: %s\n", data);
|
My output is like data: U."."
Less chars but still looks like its storing more chars than it should :/
I don't use a MAX232 between PIC and PC because in the future there will be
No pic to pc com, now its just for debug.
Also if I use both INVERT and FORCE_SW parameter on the pic i can remove the max between RX and PIC.
Nothing is turning B4 low its a power LED telling me that the pic started. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Sun Aug 21, 2011 2:34 pm |
|
|
Do yourself a BIG favour...use a MAX232 AND the hardware UART !!
The MAX232 will give better 'RS232' signalling AND the hardware UART allows for better software control over the data stream. A software UART will take a LOT of the PICs processing duties just to try to run 'right' but the hardware UART is dead simple.
You can also use a MAX488 chip (8 pins, NO caps required !) instead of the MAX232 type chip. It'll save space, 4 caps and works just as well.
Sure the 'final' project may not require RS232 communications yet....but having it onboard is great...perfect for debugging and will save you a LOT of time in the furure when the product NEEDS RS232..... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Sun Aug 21, 2011 2:46 pm |
|
|
Using invert, implies the hardware USART will be turned off, for both the receive and the transmit, and that while sending data _you cannot receive_. Since you send the received byte straight away, and the source device apparently sends two bytes one after the other the code will inherently not see the second byte. Result, it'll never see the 'U'. Exactly what you are seeing.
Fix your hardware, and your code can then work.
If you don't want a MAX 232 on the board, simply bring the TX line (and ground/power) out on a jumper, and put together a MAX 232 on a small piece of breadboard, that you can plug onto this for debugging.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 21, 2011 2:48 pm |
|
|
Quote: |
int data[1];
data[0]=getc();
printf("data: %s\n", data);
|
You're telling printf to print a string but that's not a string. A string has
a null (0x00) byte at the end (which you have to put there). Your array
doesn't have enough room for the null byte.
I think if you want this solved, you need to post a small test program
(that compiles) with the #include, #fuses, #use delay(), #use rs232(),
all necessary #define statements, variable declarations, and a main().
By small, I mean 10 lines of code in main() or in a function, at the most.
You also need to post a link to your schematic (use http://www.imageshack.com).
Also post your compiler version. |
|
|
nuno12345
Joined: 16 Jul 2008 Posts: 50
|
|
Posted: Sun Aug 21, 2011 4:35 pm |
|
|
Ttelmah I had the max just disconnected it and used INVERT for testing. I also made a small PCB with max232 and caps.
PCM I had the 0x00 being add in the TX code but removed it since i did not notice any diference. When i get home I'll post full code. |
|
|
nuno12345
Joined: 16 Jul 2008 Posts: 50
|
|
Posted: Sun Aug 21, 2011 6:35 pm |
|
|
Receiver code:
Code: | #include <16F628A.h>
#fuses INTRC_IO, NOWDT, NOPUT, NOBROWNOUT, NOMCLR, NOLVP, NOPROTECT
#use delay (clock=4000000)
//#use rs232(baud=2400,xmit=PIN_B5, rcv=PIN_B2)
#use rs232(baud=1200,rcv=PIN_B1, xmit=PIN_B2)
char data;
/*#int_rda
void serial_isr() { // InterrupciĆ³n recepciĆ³n serie USART
data = getc();
printf("data: %s\n", data);
}*/
void main()
{
//enable_interrupts ( int_rda ); // enable serial interrupt
//enable_interrupts ( global ); // enable all interrupts
output_high(PIN_B0);
delay_ms(10);
putc('A');
while(True)
{
data = getc();
putc(data);
//printf("data: %s\n", data);
if(data == 'U')
{
output_high(PIN_B4);
//putc('A');
}
else if(data == "D")
{
output_high(PIN_B5);
putc('A');
}
else if(data == "R")
{
output_high(PIN_B6);
putc('A');
}
else if(data == "L")
{
output_high(PIN_B7);
putc('A');
}
else if(data)
{
output_low(PIN_B4);
output_low(PIN_B5);
output_low(PIN_B6);
output_low(PIN_B7);
}
delay_ms(2);
}
} |
TX code doesnt really matter since its very large and not compiled for PIC but all resumes to:
Code: | int serial = OpenSerialPort();
if(serial)
{
write(serial, "U", 1);
} |
Sorry for the ugly schematic, also I forgot to add the caps in max but they are in the right place in my breadboard.
CCS 4.074 |
|
|
|