CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Part of the code stops working after another one is executed

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
moothz



Joined: 09 Sep 2011
Posts: 8

View user's profile Send private message

Part of the code stops working after another one is executed
PostPosted: Fri Nov 04, 2011 2:24 pm     Reply with quote

Hello there!

I developed a code using CCS. The part that I'm having some problems (1 week) is the one that sends and receives data.

If I execute leitura() first, everything will work as expected - It'll read the string that is being sent to it.
If I execute the enviaStream() first, it'll work flawlessly and send the data - however, the function leitura() won't work as expected anymore.
It'll start to shift/forget some bits at random... Making
chars like 53 (5) becomes 32 (space) (it eats the 0, 2 and 4 bits), but it depends on the char position, so don't have this in mind while thinking of the problem.

Note that they don't share pins, they don't share variables, they are called in different instances.

tl;dr;
Quote:

Execute leitura() before enviaStream() and it works. Execute enviaStream() before, leitura() doesn't work.
They don't share pins, they don't share variables, they are called in different instances.



Defines and global variables used:
Code:

#define SEND1 PIN_D5    // A0
#define SEND2 PIN_D6    // A1
#define DATA PIN_D7     // A2
#define READY PIN_C4   

#define _SEND1 PIN_C6    // C0
#define _SEND2 PIN_D2    // C1
#define _DATA PIN_D3     // B1
#define _READY PIN_C7   // A3

#define TIME 2

int8 streamDados[8];


The function leitura():
Code:

void leitura(){

  int stream2[8]={0,0,0,0,0,0,0,0};
  char nome[11];
  char caracter='0';
  int k=0,i=0;
  int8 recebendo = 1;
 
  memset(nome,0,11);
 
   //lcd_putc("\f");
   k=0;
  /*for(i=0;i<11;i++){
              nome[i] = 32;
    }
    */
   while(recebendo){
 
           while(INPUT(_READY)){ // Espera ready ser 0
               lcd_gotoxy(1,1);
               //printf(lcd_putc,"Dado: %d%d%d%d%d%d%d%d", stream2[0],stream2[1],stream2[2],stream2[3],stream2[4],stream2[5],stream2[6],stream2[7]);     
               printf(lcd_putc,"Autenticado!");
               lcd_gotoxy(1,2);
               printf(lcd_putc,"Abrindo porta...");
               //printf(lcd_putc,"Char: %c  (%3d)", caracter, caracter);
               delay_ms(1);
           }
         
// -------------------------------------------------------------------------------           
            while(!INPUT(_SEND1));
                       
            if(INPUT(_DATA)) { stream2[0] = 1; } else { stream2[0] = 0; }
                       
// -------------------------------------------------------------------------------           
            while(!INPUT(_SEND2));
         
            if(INPUT(_DATA)) { stream2[1] = 1; } else { stream2[1] = 0; }
// -------------------------------------------------------------------------------           
            while(!INPUT(_SEND1));
                       
            if(INPUT(_DATA)) { stream2[2] = 1; } else { stream2[2] = 0; }
                       
// -------------------------------------------------------------------------------           
            while(!INPUT(_SEND2));
         
            if(INPUT(_DATA)) { stream2[3] = 1; } else { stream2[3] = 0; }
// -------------------------------------------------------------------------------           
            while(!INPUT(_SEND1));
                       
            if(INPUT(_DATA)) { stream2[4] = 1; } else { stream2[4] = 0; }
                       
// -------------------------------------------------------------------------------           
            while(!INPUT(_SEND2));
         
            if(INPUT(_DATA)) { stream2[5] = 1; } else { stream2[5] = 0; }
// -------------------------------------------------------------------------------           
            while(!INPUT(_SEND1));
                       
            if(INPUT(_DATA)) { stream2[6] = 1; } else { stream2[6] = 0; }
                       
// -------------------------------------------------------------------------------           
            while(!INPUT(_SEND2));
         
            if(INPUT(_DATA)) { stream2[7] = 1; } else { stream2[7] = 0;
            }
// -------------------------------------------------------------------------------           
           
         
            caracter = stream2[0] + stream2[1]*2 + stream2[2]*4 + stream2[3]*8 + stream2[4]*16 + stream2[5]*32 + stream2[6]*64 + stream2[7]*128;
           
            nome[k] = (char)caracter;
 
            k++;
           
            if(k>9) {
               nome[10] = '\0';
               recebendo = 0;
               break;
            }

         
   }
   
   lcd_putc("\f");
   lcd_gotoxy(1,1);
   printf(lcd_putc,"Ola, %s !", nome);     
   delay_ms(1000);
}


The function enviaStream():
Code:

void enviaStream(){
   
   
   output_low(SEND1);
   output_low(SEND2);

   output_low(READY);
   delay_ms(TIME);
   output_high(READY);
   


   
   //delay_ms(TIME);
   output_toggle(PIN_A1);
   if(streamDados[0]==1) { output_high(DATA); } else { output_low(DATA); }
   output_high(SEND1);
   delay_ms(TIME);
   output_low(SEND1);
 
   
   output_toggle(PIN_A1);
   if(streamDados[1]==1) { output_high(DATA); } else { output_low(DATA); }
   output_high(SEND2);
   delay_ms(TIME);
   output_low(SEND2);
   
   output_toggle(PIN_A1);
   if(streamDados[2]==1) { output_high(DATA); } else { output_low(DATA); }
   output_high(SEND1);
   delay_ms(TIME);
   output_low(SEND1);
 
   output_toggle(PIN_A1);
   if(streamDados[3]==1) { output_high(DATA); } else { output_low(DATA); }
   output_high(SEND2);
   delay_ms(TIME);
   output_low(SEND2);
   
   output_toggle(PIN_A1);
   if(streamDados[4]==1) { output_high(DATA); } else { output_low(DATA); }
   output_high(SEND1);
   delay_ms(TIME);
   output_low(SEND1);
 
   output_toggle(PIN_A1);
   if(streamDados[5]==1) { output_high(DATA); } else { output_low(DATA); }
   output_high(SEND2);
   delay_ms(TIME);
   output_low(SEND2);
   
   output_toggle(PIN_A1);
   if(streamDados[6]==1) { output_high(DATA); } else { output_low(DATA); }
   output_high(SEND1);
   delay_ms(TIME);
   output_low(SEND1);
   
   output_toggle(PIN_A1);
   if(streamDados[7]==1) { output_high(DATA); } else { output_low(DATA); }
   output_high(SEND2);
   delay_ms(TIME);
   output_low(SEND2);
   
   
   output_low(SEND1); 
   
   
   output_high(READY);
   
   return;
   
 }




Thank you in advance!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 04, 2011 9:25 pm     Reply with quote

Quote:

If I execute the enviaStream() first, it'll work flawlessly and send the
data - however, the function leitura() won't work as expected anymore.

To debug this, first comment out all the code inside the enviaStream()
function. Call enviaStream() first, then call leitura(). See if leitura() now works.
If it does, then un-comment several lines of enviaStream(), re-compile,
and test leitura() again. Keep doing this until you get a failure. By
commenting and un-commenting lines of code inside enviaStream(),
try to find the exact line (or lines) that cause leitura() to fail.

If you can't see the reason for the problem by reading the code, this is a
simple technique to help you find the problem.
moothz



Joined: 09 Sep 2011
Posts: 8

View user's profile Send private message

PostPosted: Sat Nov 05, 2011 12:42 pm     Reply with quote

PCM programmer wrote:
Quote:

If I execute the enviaStream() first, it'll work flawlessly and send the
data - however, the function leitura() won't work as expected anymore.

To debug this, first comment out all the code inside the enviaStream()
function. Call enviaStream() first, then call leitura(). See if leitura() now works.
If it does, then un-comment several lines of enviaStream(), re-compile,
and test leitura() again. Keep doing this until you get a failure. By
commenting and un-commenting lines of code inside enviaStream(),
try to find the exact line (or lines) that cause leitura() to fail.

If you can't see the reason for the problem by reading the code, this is a
simple technique to help you find the problem.


Oh, I did this already, like a lot of times, with all the other functions, till I found out the problem was this one :P. But thank you! This tip is so awesome and will probably help more people that get this problem.

The more I uncomment from the enviaStream() the less leitura() works.
Ex.:
0% commented - Send Jeann, receives `~snn
50% commented - Send Jeann, receives J~snn
100% commented - Send Jeann, receives Jeann

The chars are ALWAYS replaced with the same one (on the same 'comment percentage', ofc) - If the code is 0% commented, it'll -1 of the characters. c will become b, d will become c... etc. Except for some that never change.



The weird thing is - Some characters WILL show up right no matter how much of the enviaStream() is commented. z, n and b are the ones I remember. They can be ANYWHERE on the string I'm sending and they won't be changed for other stuff.


I can't just make a replace, like if(char == '`) char = 'c'; because some of them become the same. Eg: '3', '4' and '5' become '0',

What bothers me is: Execute leitura() first, works flawlessly. Execute it after enviaStream() and it'll STILL receive ALL characters, all of them! But some of them messed up.
If you take a look at how to code is written, it would just STOP if a character is missing until you send it. :
while(!SEND1); < Won't move from here till a pulse from SEND1, etc.



I thought it was the way I'm converting a binary vector to an integer was the problem, can you suggest another way of converting binary to integers?

Thank you in advance
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Nov 05, 2011 2:30 pm     Reply with quote

Can you tell us the purpose of your program ? What external devices
are connected to the PIC ? What data does the PIC read or write to them ?

In this typical polling loop, what is the PIC waiting for ? What status
signal, and why ? What is the average estimated waiting time ?
Quote:

while(!INPUT(_SEND2));



Can you post a complete program that has an #include for the PIC,
#fuses, #use delay, any other #use statements, variable declarations
and #define statements. Try to make a program in main() that only
calls the two functions that you posted. Call them in the order that
causes the failure. Test this small program to be sure that it fails.

Especially, keep it short. Don't put any code in main() except for a few
lines to initialize the lcd, etc., and then call the two routines in the order
that causes the failure. You should be able to cut your large program
down into a very small program that I am requesting.

And, when I copy and paste your post into MPLAB, it must compile with
no errors, no missing files, or missing declarations, etc.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sat Nov 05, 2011 4:10 pm     Reply with quote

Though it is very difficult to tell what the actual operations are, my guess would be 'time'. The code that goes faulty, seems to do an operation based on patterns of input bits. The other code's main effect on this, will depend on how long it takes (vary with 'TIME'), but looks as if it could be an absolute age. Unless the bit patterns are waiting for something the first code does, it will probably miss them....

The normal answer would be to 'rethink'. Have a clock (tick based on an interrupt), and make the operations into a state machine, that steps through at the required intervals using the clock _while the other code is also executing, also based on the clock_.

Best Wishes
moothz



Joined: 09 Sep 2011
Posts: 8

View user's profile Send private message

PostPosted: Sat Nov 05, 2011 6:59 pm     Reply with quote

Here's an explanation of the whole program, in case you want. If not, just skip it.

Code:

Devices
- A PIC16f877A with an analog keyboard and a relay.
- A Pic MiniWEB, from Olimex.
The reason for using the 16F:  I'm using this because C18 took me 1 month just to debug why the AN0 input wasn't being read and why the itoa (or any string.h function) function wasn't working... Plus, I can't select ANY pins I want for the LCD on C18... (data bus)

1. The PIC16F877A receives a login and a password through the keyboard
2. I store this as a char vector
3.I have to send this information to the PIC Miniweb. So I decided to implement a really simple protocol that took about 1 hour to complete.
   (Skip to 4 if you don't want to get bored)   
   It converts an integer to binary and place the bits one by one on a pin.
   The READY pin tells the other pic I'll be sending information, making it stop everything it's doing to read the data I'm sending.
   The algorith for it is the following:
   - Send Ready Signal. Receiver is now waiting for the SEND1 signal
   - Place first bit on the DATA pin (Highs if 1, lowers if 0)
   - Send a SEND1 signal, telling the receiver to read the DATA
   - Disable the SEND1. Receiver is now waiting for the SEND2 signal
   - Send a SEND2 signal, telling the receiver to read the DATA
   .... Loops alternating between SEND1 and SEND2.
   I use 2 send signals so I don't have to worry about synchronization.

4. The PIC MiniWeb puts the received data on a webpage, my Java App will detect this data and try to authenticate it on a server (LDAP/MySql).
5. The java app will return a answer of "allowed" or "denied".
6. the Pic Mini Web proceeds to send the web-received signal to the PIC16F877A
7. Based on what signal it received from the Pic Mini Web, the PIC16fF877A will or won't open the lock of the door.

Everything works absolutely fine till here! We could have stoped now, but we wanted something more. :)
I'm waiting on some RFID antennas and cards to arrive so I can remove the keyboard and connect the RFID module to it. What feedback would the user have?

Take a look at the Step 5. The Pic Mini Web is sending only a allow or deny signal... I've adapted it so it also sends the name of the person!
I want to display this name on the LCD, the LCD is connected to the PIC16F877A. So I thought, well, no problem! I'm already sending data with my protocol to the Pic Mini Web, let's just make the Pic mini web use the same protocol!
So I proceed to develop it, programmed the PIC16F877A with the reading code (the leitura() function) and it worked! YES!
then I reprogrammed it with the whole program (keyboard reading, sending data, etc...) PLUS the leitura() function.

That's where my problems began... Took me like 2 days to debug it till I found out that the function that was screwing me up was the enviaStream()

(I hope the above answers your questions, feel free to ask more).




The function enviaStream() sends the keyboard input data to the Pic Mini web.

So, yeah, I have no idea of what could be happening, I've tested EVERYTHING I could think of already.


As for what PCM programmer asked, I don't have the devices with me right now so I can't confirm the code will work and give the problems (although I've done that already, didn't save it).



Also, some more debug info I forgot:
- If I comment all the output_high/low of the enviaStream() function, it'll work...
I've tried greping for those functions to see how CCS does the "low level" high/low thing so I could mess around with it. I couldn't find it though, LOL, where is it located? Is it hard coded?
I have also tried manually setting the TRIS for those pins and for the whole port too.
I have a video of it 'working' (faking the enviaStream function and hard sending the allow/deny signal plus the name of the person). I could post this too if you would like (not sure how it would help, but hey.)

Ps.: Sorry for my bad english ):


Last edited by moothz on Mon Nov 07, 2011 3:27 pm; edited 2 times in total
moothz



Joined: 09 Sep 2011
Posts: 8

View user's profile Send private message

PostPosted: Mon Nov 07, 2011 1:51 pm     Reply with quote

Shameless bump
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 07, 2011 2:12 pm     Reply with quote

I think the reason why you didn't get any more responses is this:
Quote:

So I decided to implement a really simple protocol that took about 1 hour to complete.

It converts an integer to binary and place the bits one by one on a pin.

At least for me, when I read that you invented your own protocol,
I backed away. I suspect others did the same. I don't mean any
disrespect but my reaction was "OK, he's inventing his own signaling
method. I'm out of here". Very Happy

It sounds funny but that's why. Again, no disrespect intended.
moothz



Joined: 09 Sep 2011
Posts: 8

View user's profile Send private message

PostPosted: Mon Nov 07, 2011 3:20 pm     Reply with quote

PCM programmer wrote:
I think the reason why you didn't get any more responses is this:
Quote:

So I decided to implement a really simple protocol that took about 1 hour to complete.

It converts an integer to binary and place the bits one by one on a pin.

At least for me, when I read that you invented your own protocol,
I backed away. I suspect others did the same. I don't mean any
disrespect but my reaction was "OK, he's inventing his own signaling
method. I'm out of here". Very Happy

It sounds funny but that's why. Again, no disrespect intended.


I know what you mean by that. I'll edit the post to make it... clearer
But man, the thing is: It works, but only if I don't execute that single function.
I just don't have the time to mess with C18 to use i2c or a serial protocol (it's really buggy). And this signaling method is so simple and works very nicely for what I need.

You asked me to explain the purpouse, I did. I thought explaining the whole situation would help (since this problem doesn't make any sense).

It barely has something to do with my problem, it actually has nothing to do with it. I just want some help because I'm executing a function that makes my program buggy for no reason whatsoever.


I've tried replacing the 16F with another 2 I had, same problem.
It's not the wiring or the board - It IS receiving the data.

Edit:
Sorry, It is NOT working on a simulation on Proteus. Gives me the same problem.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 08, 2011 6:39 pm     Reply with quote

Quote:
I've tried greping for those functions to see how CCS does
the "low level" high/low thing so I could mess around with it. I couldn't
find it though, LOL, where is it located?

Just look at the .LST file. The ASM code will be right there. It will set the
TRIS and set the Port bit for the pin. For 16F there will also be some
"bank select" code generated. So you will see 4 lines of ASM code,
usually, per line of C source code.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Wed Nov 09, 2011 3:09 am     Reply with quote

Try something really simple.
Replace enviaStream with:
Code:

void enviaStream(void){
    delay_ms(TIME*10);
}

and execute this before leitura.
What happens?.

Best Wishes
moothz



Joined: 09 Sep 2011
Posts: 8

View user's profile Send private message

PostPosted: Wed Nov 09, 2011 11:49 am     Reply with quote

PCM programmer wrote:
Quote:
I've tried greping for those functions to see how CCS does
the "low level" high/low thing so I could mess around with it. I couldn't
find it though, LOL, where is it located?

Just look at the .LST file. The ASM code will be right there. It will set the
TRIS and set the Port bit for the pin. For 16F there will also be some
"bank select" code generated. So you will see 4 lines of ASM code,
usually, per line of C source code.


Ttelmah wrote:
Try something really simple.
Replace enviaStream with:
Code:

void enviaStream(void){
    delay_ms(TIME*10);
}

and execute this before leitura.
What happens?.

Best Wishes


I'll take a look into this tomorrow!

Thanks a lot for your support
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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