|
|
View previous topic :: View next topic |
Author |
Message |
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
RS232, printf, RF-link and unsigned int crazyness |
Posted: Tue Dec 21, 2010 12:27 pm |
|
|
I'm losing my head on this and I've got no clue on what's going on :shock:
PIC18F4685 running at 40MHz, using the uart1 module to receive serial data from a PIC16F690 (there is a LCD attached to the 18F).
Using a wire everything works, no big deal.
So, I've switched to a RF link, 433MHz saw ook module, they are transparent so it's pretty easy; Everything worked: when I apply power to the board I just receive one random char (noise), then the RX is silent until something is being transmitted (so, no noise, no random carrier link, no errors on single char received nor on the first ones of every transmission).
Until.. I change some code. I've been able to track down the portion of the code that is messing around the data transmission:
This is the working main:
Code: | #include <main.h>
#include <LCD.C>
char data=' ';
int1 lock = 0x0;
int8 con = 0;
#int_RDA
void RDA_isr(void)
{
data = getch(radio);
lock = 1;
}
void main()
{
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
lcd_init();
output_low(LED);
output_high(LED);
printf(lcd_putc,"\fHello World!");
delay_ms(DELAY_LED);
output_low(LED);
printf(lcd_putc,"\f");
while(true){
while (lock == 0);
lock =0;
con++;
printf(lcd_putc,"%c",dato);
if (con == 16) {printf(lcd_putc,"\f");con=0;}
}
}
|
BUT when I change:
Code: | unsigned int8 data=0; |
and
Code: | printf(lcd_putc,"%u",dato); |
and then apply power to the board, gremlings start generating 255s on the LCD, and indeed, 255s are being received and processed from the serial port.
That's insane! and I've been rewriting the code over and over stripping down features until this really innocent change - it's just a representation format going from char to unsigned int8.. or not?
I've seen, if I ground the RX pin and then reconnect it to the RF RX module the serial port is silent again ready to receive and display RAW hex data.
P.S. Sorry if some typos shows up and just ask if some code/declarations are not clear. RS232 is configure at 2400 using HW uart1 module, but it's not an issue with setup. I was thinking to some crystal/clock faults.. but it looks not the case :\ _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Tue Dec 21, 2010 12:33 pm |
|
|
Is that a typo on your part or are you really calling it "data" in one case and "dato" in the other case (printf) ??
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 21, 2010 1:03 pm |
|
|
Quote: | char data=' ';
unsigned int8 data=0; |
In the first case, you load the variable with a space (0x20).
In the 2nd case, you load it with 0 (0x00). Those are not the same. |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Wed Dec 22, 2010 3:13 am |
|
|
gpsmikey wrote: | Is that a typo on your part or are you really calling it "data" in one case and "dato" in the other case (printf) ??
mikey |
Right, just a typo, the program compiles correcly. _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Wed Dec 22, 2010 3:18 am |
|
|
PCM programmer wrote: | Quote: | char data=' ';
unsigned int8 data=0; |
In the first case, you load the variable with a space (0x20).
In the 2nd case, you load it with 0 (0x00). Those are not the same. |
But that it's not the issue here:
_ if my printf has a "%c" the system powered will just display one garbage characther on the LCD then nothing more UNTIL something is actually transmitted.
_ if my printf has a "%u" inside on the LCD I'm seeing a cascade of 255s! it lasts from few seconds to infinite, until I put the receiving pin of the PIC to ground, then back to the signal source, at that moment the 255s will stop appearing (and normal data, if transmitted, will show up).
I can initialize the "data" variable with whatever content, it does not matter at all; only the behaviour of printf is determining the output on the LCD. _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Dec 22, 2010 3:23 am |
|
|
You are probably getting the 255's using the char way, but because you are displaying it as a char it is not printing because it is an unprintable character. Either the lcd routine will ignore it or the lcd will output garbage or nothing.
You are getting random data either way. Interference or something wrong with your rf setup. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Wed Dec 22, 2010 3:29 am |
|
|
Some comments:
You talk about grounding (something). Remember the _idle_ state for TTL serial, is 5v, not 0v. If you 'ground' the input line, continuous data will be seen. All zero.
Have you got 'errors' in your serial definition?. This _must_ be present when using the hardware UART, unless you add your own code to handle receive errors. If not, and anything goes wrong, the UART _will_ be hung.
Have you got a current limiting resistor in the connection to the LED?. If not, strange behaviour _will_ be seen.
Why do you set the LED, low, then immediately high?. You will never see this.
There is a potential 'issue' in displaying the form feed to clear the screen. This takes on most LCD's several mSec (typically 40), to execute. Ten character times. With your current code that only has one character of buffering, if more than one character has been received, you will have the 'lock' set as true, but only retrieve the last character. Look at EX_SISR, for how to buffer the UART.
Best Wishes |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Wed Dec 22, 2010 4:06 am |
|
|
Wayne_ wrote: | You are probably getting the 255's using the char way, but because you are displaying it as a char it is not printing because it is an unprintable character. Either the lcd routine will ignore it or the lcd will output garbage or nothing. |
Could, but i get 255s with the "%u" inside the printf. If I put "%c" i get no random chars, and, when i send random 8 bit integers, i get on the display graph chars as well as numbers and letter (and symbols).
Wayne_ wrote: |
You are getting random data either way. interference or something wrong with your rf setup. |
I've though about that, but it's not. If I let it powered for 30 mins or more (watching it right now) I can see 6-7 "chars" showing up, random noise. The behaviour with "%%u" inside the printf is more serious, there are thousand of 255s even removing the antenna to the RX module :( _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia.
Last edited by foxOnTheRun on Wed Dec 22, 2010 4:32 am; edited 1 time in total |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Wed Dec 22, 2010 4:27 am |
|
|
Ttelmah wrote: | Some comments:
You talk about grounding (something). Remember the _idle_ state for TTL serial, is 5v, not 0v. If you 'ground' the input line, continuous data will be seen. All zero.
|
Absolutely: after powering up the system, idle state where nobody is transmitting, the line at receiving end is at 5v. Yet, with the "%u" printf will display infinite 255 on the LCD. Changing data representation to "%x" or "%c" will stop that.
Ttelmah wrote: |
Have you got 'errors' in your serial definition?. This _must_ be present when using the hardware UART, unless you add your own code to handle receive errors. If not, and anything goes wrong, the UART _will_ be hung.
|
My rs232:
Code: | #use rs232(uart1,baud=2400,parity=N,bits=8,stream=radio,STOP=1) |
No errors up now, I'm going to add it up right now; where in the help file, is written this interesting suggestion? I mean, not the errors itself, but the usefull content of your words? :\
Ttelmah wrote: |
Have you got a current limiting resistor in the connection to the LED?. If not, strange behaviour _will_ be seen.
Why do you set the LED, low, then immediately high?. You will never see this.
|
Yes, I already experinced this on the 16F, so it's limited. At the very beginning I'd like to set if low then high. I know the start state could be low, but I prefer to think at it as "undefined". My low state is just a force low-to-high for sure transition.
Ttelmah wrote: |
There is a potential 'issue' in displaying the form feed to clear the screen. This takes on most LCD's several mSec (typically 40), to execute. Ten character times. With your current code that only has one character of buffering, if more than one character has been received, you will have the 'lock' set as true, but only retrieve the last character. Look at EX_SISR, for how to buffer the UART.
|
Yep, on the transmitting end I just send a burst of 3 chars then a pause for 1000 or more m.seconds. I know that the HW uart has 2 char buffering, so if the first is alwais fetch, there's just enough space for the next two to arrive and sit somewhere. This code also is just for debugging purpose. I still receive thousand of 255s if the printf has a "%u" data format..
I've found (now in the guide) that on overflow the uart will shutdown, it's not my case though. Putting the RX pin to 5 or gnd, it doesn't matter, it stops somewhat the 255 from appearing (they come back sometimes..).
Ttelmah wrote: | Best Wishes |
Thank you for your suggestions! P.S. Adding "%x" to the printf is working righfull again, like with "%c".. I'm prone into thinking of a printf bug.. uhm uhm _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Wed Dec 22, 2010 8:28 am |
|
|
Tried also with the "errors" parameter inside user rs232 and no changes, the "%u" inside the printf is trowing 255s as before.
:\ _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Wed Dec 22, 2010 8:56 am |
|
|
What is your compiler version?.
If it something like a low 4.xxx, then there may well be huge problems....
However have you tried send "%d", with the extra space?.
I think your problem may well be related to timing. %u, can involve sending up to three characters (three digits), while %c, will send just one, and %x, a maximum of two. It will therefore take longer, both to send to the LCD, and to calculate.
Best Wishes |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Wed Dec 22, 2010 12:08 pm |
|
|
Ttelmah wrote: | What is your compiler version?.
If it something like a low 4.xxx, then there may well be huge problems....
However have you tried send "%d", with the extra space?.
I think your problem may well be related to timing. %u, can involve sending up to three characters (three digits), while %c, will send just one, and %x, a maximum of two. It will therefore take longer, both to send to the LCD, and to calculate.
Best Wishes |
4.114
The situation is evolving.. in a rather odd way.
I've added a timer0 interrupt to fire when no data is received after some time (I keep resetting the counter in the int_RDA, when no data is received it will count over), now, if I keep the.. any printf in the main-while-loop I can observe countless timer0 expiration.. much shorter than it should fire! (yeah, the tiny LED is always telling the truth).
Now.. I'm suspecting something might interfere with the normal program flow.
Shorth code:
Code: | #int_RDA
void RDA_isr(void)
{
set_timer0(0); // new data reset the timer0
timeout = 0; // I want timer0 to operate only once
// so this is a one way flag
array[i] = getch(radio);
i++;
} |
Code: | #int_RTCC
void RTCC_isr(void)
{
if (timeout == 0)
{
timeout = 1; // enters once, flag itself out
// until new data will reset it
output_toggle(LED); // can see the timer0 interrupts
max=array[0]; // temporary code
rcv=i; // temporary code
lock = 1; // calculations done, enable main workflow
}
} |
And the main:
Code: |
....
set_timer0(0);
enable_interrupts(INT_RTCC);
while(true){
while (lock == 0);
lock =0;
// so commenting the line below makes the system receive ONLY
// when data is radio-txed
// if I uncomment the line below, random "ff" or 255s shows up one after another
// AND timer0_int continuosly fires..
// printf(lcd_putc,"\fDato: %x [%x]",max,rcv);
for (n=0;n<=i;n++) array[n]=0;
max=i=0;
} |
So now I'm baffled: why timer0 is expiring so fast? This proves I'm receiving data from the serial port.. BUT flashing the unit with the previous .hex at the very same time-frame shows that NO data is received (well, it's up in the air); so, I'm still wondering from WHERE tons of 255s appears!? it looks that the problem wasn't all inside the %u..
I wish the PIC was self resetting, but I'm not seeing the boot sequence :\
Code: | setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128); |
_________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Wed Dec 22, 2010 12:41 pm |
|
|
This code for example is not trashing 255s:
Code: |
#include <main.h>
#include <LCD.C>
int1 timeout = 0;
int8 i = 0;
BYTE rcv=0;
#int_RDA
void RDA_isr(void)
{
set_timer0(0);
timeout = 0;
rcv = getch(radio);
i++;
}
#int_RTCC
void RTCC_isr(void)
{
if (timeout == 0)
{
timeout = 1;
output_toggle(LED);
}
}
void main()
{
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
// INIT STUFF
lcd_init();
output_low(LED);
output_high(LED);
printf(lcd_putc,"\fHello World!");
delay_ms(DELAY_LED);
output_low(LED);
printf(lcd_putc,"\f");
// END INIT
set_timer0(0);
enable_interrupts(INT_RTCC);
while(i<20){}
printf(lcd_putc,"\fReceived: %d",i);
while(true);
} |
Simply moving the PRINTF inside the while(i<20){} blows everything up (meaning 255s fills instantly up the counter).
It's printf now.. could it be so dead simple? _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia.
Last edited by foxOnTheRun on Wed Dec 22, 2010 12:50 pm; edited 2 times in total |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Dec 22, 2010 12:42 pm |
|
|
To allow others to check your code, you have to post a complete application, e.g. including the UART setup.
Otherwise everyone is stuck with speculations.
It may the case, that the code is however operating correctly. A char code of 255 simply means, that the UART
is receiving a false start bit with no data. So you should check first, what's actually coming out of your RF module.
As a hint, did you check to connect the Tx pin to the transmitter module directly to Rx pin of the receiver application -
shortcutting the RF path.
Before you couldn't show it explicitely, it's just a guess, that the RF modules are operating correctly and as intended. |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Wed Dec 22, 2010 12:46 pm |
|
|
FvM wrote: | To allow others to check your code, you have to post a complete application, e.g. including the UART setup.
Otherwise everyone is stuck with speculations.
It may the case, that the code is however operating correctly. A char code of 255 simply means, that the UART
is receiving a false start bit with no data. So you should check first, what's actually coming out of your RF module.
As a hint, did you check to connect the Tx pin to the transmitter module directly to Rx pin of the receiver application -
shortcutting the RF path.
Before you couldn't show it explicitely, it's just a guess, that the RF modules are operating correctly and as intended. |
RF module are idling and not picking up spurious signals; and yes, with a working program, shortcutting the RF path yields the same results. Looks like 255s are coming up from inside the PIC :)
Uart setup is the same as mentioned some post above, here it is:
Code: | #use rs232(uart1,baud=2400,parity=N,bits=8,stream=radio,STOP=1, errors) |
For a complete code, just check up my very last post before yours, it's pretty stripped down to the essential (hope). _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|