Welcome! Log In Create A New Profile

Advanced

Compatibility BV4618 with PIC18

Posted by salvatore 
Compatibility BV4618 with PIC18
January 29, 2014 10:11PM
Hi, I am trying to run the BV4618 with a PIC 18F series with the RS232.
With the Display everything works fine. To read the keys I have a problem.
When I give the command (ESC [k). I should then receive three bytes from BV representing the keypad code.
But apparently the hardware UART of the PIC does not allow input of three consecutive
bytes but only two. Receive the first and the second correctly, but not the third.
Is there a solution? Why the BV4618 must send three bytes to indicate a key when it would be enough to just one?

My code is written in 'C' and I use the CCS compiler

The configuration of the RS232:

#use rs232(baud=4800,xmit=PIN_C6,rcv=PIN_C7,ERRORS,TIMEOUT=500)

The routine for reading the keys is the following:


void KeyPadControl() {

char ByteTasto[10];
int count

fputc(0x1b);printf("[n"); // see if there are keypresses
delay_ms(20);

ncarBuffer=fgetc();
delay_ms(20);

GotoxyLCD(1,2);
WriteIntLCD(NcarBuffer,4,' '); // test for look the result

fputc(0x1b);printf("[k"); // command receiving the key
delay_ms(200);

count=0;

while (kbhit()){

ByteTasto[count]=getc();
conta++;
}


//-----------the following is the test that writes on dispaly the received codes---------------


GotoxyLCD(2,1);
WriteIntLCD(ByteTasto[0],4,' ');
WriteIntLCD(ByteTasto[1],4,' ');
WriteIntLCD(ByteTasto[2],4,' ');

GotoxyLCD(3,12);
WriteIntLCD(conta,4,' ');

}

//-------there are only the first two bytes and count stops in fact two
//-------the program continues only because I set "ERRORS and TIMEOUT=500" in the declaration of the RS232

I also tried to use "ACK" but I could not get anything,
the only thing that I can receive is the same code ACK ..
no information on the keys pressed.


sorry for my english ... J use translate.google ....
Thanks to all



Edited 1 time(s). Last edit at 01/30/2014 12:09PM by salvatore.
Re: Compatibility with PIC18
January 30, 2014 12:23PM
hello,
The BV4618 will send "text" as a reply to the esc[k command and also the esc[n command, the number of bytes will be determined by the value it is sending back. However with ACK turned off only one byte is sent back, with no keys in the buffer this will be 0x30 which is the ASCII code for '0'.

You may run into problems when there are keys in the buffer, in which case up to 3 bytes may be sent back. For example a scan code may be "221" in which case the BV4618 will send back the byte values 0x32, 0x32 and 0x31.

It is not a good idea to rely on a hardware buffer, in fact most PIC's only have a single byte buffer. There are several ways of dealing with this; most set up an interrupt and when a character is received place it in a buffer to be read later, this way no characters will be missed and you do not need to continually look for them.

If you need to poll the characters like you are doing above then the best way is to put them in a buffer. If you set the ACK character using esc[<num>k first then you can look for that which will tell you when the input has been received.

Example:
  fputc(0x1b);printf("[42k"); // set ACK to be 42 - only needs doing once at setup
  char c = 0, count=0, buf[5];
  while(c != 42) {
       // key() should wait until a key is available and then return it
       c = key(); 
       if(c !=42)  // don't want 42 to be part of input
           buf[count++]=c;
  }

You may want to look at buffered serial examples using interrupts as that will give you much more flexibility. This is really a PIC question but others may find it useful.
Re: Compatibility with PIC18
January 30, 2014 11:07PM
Hi Jimeer, thanks very much for the prompt response to my question.
Tonight I tried a thousand ways to use "ack" as you suggested.
I have not had any positive results, I do not understand where I'm wrong.

I add the code again with the latest tests done with a few more comments.

I would love to win this battle, to see the BV4618 no longer exclusive
Arduino.

Thanks again for everything.
Salvatore Mannino

-----------------------------------------------------------------


void KeyPadControl() {

char c = 0, count=0, buf[]="XXXXX"; // in this way I see the display if the font is updated

fputc(0x1b);printf("[n"); // I ask how many keys in the Buffer
delay_ms(20);

ncarBuffer=fgetc(); // If I did not set "Ack" I see correctly increase with each press
delay_ms(20); // of a button. If set to "Ack" I get only 42 ever.

GotoxyLCD(1,2);
WriteIntLCD(NcarBuffer,4,' '); // print N buffer on display

// fputc(0x1b);printf("[?31d"); // If you ask many "device" or "version"
// fputc(0x1b);printf("[?31f"); // Without "Ack" I always get the first two characters.
// With "Ack" nothing


fputc(0x1b);printf("[k"); // Same result for the request button pressed

delay_ms(200); // Large delay for safety


while (kbhit()){ // Only in this way, and without the "Ack" I can catch the first two bytes
c=getc();
if (c!=42){
buf[count]=c;
count++;
if (count>5) break;
}
}


GotoxyLCD(2,1); // For testing I use these screens
WriteIntLCD(buf[0],4,' ');
WriteIntLCD(buf[1],4,' '); //In this way mold the decimal value of the byte
WriteIntLCD(buf[2],4,' '); //in 4 boxes filling the display with "Space" on the left.
WriteCharLCD(32);
WriteCharLCD(32);
WriteCharLCD(buf[0]);
WriteCharLCD(buf[1]); //The following two spaces after the corresponding characters in a row
WriteCharLCD(buf[2]);
WriteCharLCD(buf[3]);
WriteCharLCD(buf[4]);



GotoxyLCD(3,12); // With this information I can see if the cycle "While" is executed
WriteIntLCD(count,4,' ');


delay_ms(3000); //Delay that allows me to observe what happens at each cycle.

}



Edited 1 time(s). Last edit at 01/30/2014 11:08PM by salvatore.
Re: Compatibility with PIC18
January 31, 2014 08:35AM
What compiler are you using?
Re: Compatibility with PIC18
January 31, 2014 11:44AM
Using the CCS compiler, as mentioned in the first post version 4.130
Re: Compatibility with PIC18
February 01, 2014 07:30AM
Unfortunately I am not familiar with that compiler and how it handles serial communication. The BV4618 is a very straight forward serial device and so you would get a far better answer to your question in the forum for the CCS compiler, unless there is somebody else with the same compiler in this forum?. I had a quick look and there are lots of posts about serial communication, so it looks like it is a common problem.

You need to look for a buffered serial input, hope that helps.
Re: Compatibility with PIC18
February 04, 2014 10:02AM
I looked in the forum I also ccsinfo. It is a common problem and it seems that it resolves itself using an interrupt,
which I wanted to avoid.
I tried to see what was possible using the C18 compiler, but I think it's the same.
Thank you for now, let you know when solved.

PS.

Instead I was reading the datasheet for the BV4619, I understand that in this case the key code is sent one byte
at a time, is it? Because it would be more appropriate to work as I want.



Edited 1 time(s). Last edit at 02/04/2014 10:18AM by salvatore.
Re: Compatibility with PIC18
February 04, 2014 01:36PM
The BV4619 will still send out more than one byte for the scan code.

At some point in time you are going to have to deal with receiving more than one key and an interrupt is the best way to go. It can still be done without though. The following technique can be used. I will use sudo code as I am not familiar with the CCS compiler:

You will need to wait until a byte has been put in the UART and then put it in a buffer, ALWAYS on any serial system you need to determine when the message has been received. On most systems this is when a CR or LF has been received, assume that it is 42 as in the previous example.
{
char c, buffer[20], count =0;
    while(1) { // loop forever
        while(no_keys_in_UART); // wait until a key comes in
        c = get_byte_from_uart();
        if( c == 42) break;
        buffer[count++]=c;
    }
    // buffer now contains a string of bytes
}
For a PIC32 the code would look like this:
{
char c, buffer[20], count =0;
    while(1) {
	while(!U2STAbits.URXDA); // wait for char
      	c =  U2RXREG;
        if( c == 42) break;
        buffer[count++]=c;
    }
}

Re: Compatibility BV4618 with PIC18
February 09, 2014 09:28PM
I have solved all.

I did not want, but if I use the interrupt, then all is well.

Regards and good luck to all.

//------- My Code ----

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)


#define BUFFER_SIZE 32
BYTE KeyBuffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;

#int_rda
void serial_isr() {
   int t;
   KeyBuffer[next_in]=getc();
   t=next_in;
   next_in=(next_in+1) % BUFFER_SIZE;
   if(next_in==next_out) next_in=t;           // Buffer full !!
}

#define bkbhit (next_in!=next_out)

BYTE bgetc() {
   BYTE c;
   while(!bkbhit) ;
   c=KeyBuffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(c);
}







void KeyPadControl() {
  
  char c=0, count=0, nCarBuffer=0, buf[]="XXXXX";

  fputc(0x1b);printf("[n");   // asks how many keys in the buffe
  delay_ms(10);
 
  while(bkbhit) {
     c=bgetc();
     nCarBuffer=c-48;
     count++;
     if (count>4) break;
  }

  if (NcarBuffer>0){
  count=0;
      c=0;
      fputc(0x1b);printf("[k");   // Reads the key from buffer
      delay_ms(10);
      while (bkbhit){
         c=bgetc();
         buf[count]=c;
         count++;
         if (count>5) break;
      }
  }

  
//  decoding the key pressed

  if (buf[0]!='X'){
    if (buf[0]=='1'){
       if (buf[1]=='1'){
         if (buf[2]=='9'){keypressed='D';}
       }
       if (buf[1]=='2'){
         if (buf[2]=='3'){keypressed='C';}
         if (buf[2]=='5'){keypressed='B';}
         if (buf[2]=='6'){keypressed='A';}
       }
       if (buf[1]=='8'){
         if (buf[2]=='3'){keypressed='#';}
         if (buf[2]=='7'){keypressed='9';}
         if (buf[2]=='9'){keypressed='6';}
       }
       if (buf[1]=='9'){
         if (buf[2]=='0'){keypressed='3';}
       }
    }
    if (buf[0]=='2'){
       if (buf[1]=='1'){
         if (buf[2]=='5'){keypressed='0';}
         if (buf[2]=='9'){keypressed='8';}
       }
       if (buf[1]=='2'){
         if (buf[2]=='1'){keypressed='5';}
         if (buf[2]=='2'){keypressed='2';}
       }
       if (buf[1]=='3'){
         if (buf[2]=='1'){keypressed='*';}
         if (buf[2]=='5'){keypressed='7';}
         if (buf[2]=='7'){keypressed='4';}
         if (buf[2]=='8'){keypressed='1';}
       }
    }
  }
}


Re: Compatibility BV4618 with PIC18
February 10, 2014 08:20AM
Thanks for publishing the code.
Sorry, only registered users may post in this forum.

Click here to login