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

from circular buffer to signed int16

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



Joined: 02 Oct 2009
Posts: 123
Location: Denmark

View user's profile Send private message

from circular buffer to signed int16
PostPosted: Tue Jan 21, 2014 2:14 pm     Reply with quote

Hi,
The function i want to develop should update the value of a signed int16 variable every time there is a new value from the rs232 (terminated with CR).
I receive correctly and store in a circular buffer (ex_SISR.C).

Queston is: How should I organise the program to do this?

I guess I have to:
- check in the isr if I receive a CR: set a flag.
- Read the flag from the main, and de-load the buffer with bgetc() filling a character array. value[10]
- Then use atol. (does it work for signed int??) and empty the character array. (how? value='';??)
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Jan 22, 2014 3:14 am     Reply with quote

In your previous post you sorted out how to do a circular buffer.
Can I encourage you to take a similar approach again.
Have a go, ask questions with your code, if/when you get stuck.
Someone will gladly help if you show you've put in the effort.
You'll also learn a lot more.
Best of luck.

Mike

PS In the time which has elapsed since your post you could have had a least one try.
webgiorgio



Joined: 02 Oct 2009
Posts: 123
Location: Denmark

View user's profile Send private message

PostPosted: Wed Jan 22, 2014 1:00 pm     Reply with quote

I'll give it a go Smile
dorinm



Joined: 07 Jan 2006
Posts: 38

View user's profile Send private message

PostPosted: Wed Jan 22, 2014 5:08 pm     Reply with quote

Usually you use a circular buffer when you don't have enough time to process all the incoming data and need a buffer (that's what really is, nothing more).

If you want to update a var every time you read a new value you need a much simpler aproach, I think (something like read the first byte in a temp. var, then wait for "some" time for the second byte (could use a simple state machine or something), if it arrives, make a int16 and update your variable, reset the state machine.....)... my 2 cents...
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jan 22, 2014 7:34 pm     Reply with quote

code snippet....
Code:
signed int16 x;
int8 vhi=0;
int8 vlo=0;

void main() {
while(true){
delay_ms(5000);

vhi=0x12;
vlo=0x34;
x=make16(vhi,vlo);
printf("\n\r%02x %02x %0ld ",vhi,vlo,x);

vhi=0x92;
vlo=0x34;
x=make16(vhi,vlo);
printf("\n\r%02x %02x %0ld ",vhi,vlo,x);


x1234= 4660
x9234= -28108

vhi, vlo would be the bytes from your serial input.
I would suggest a 'marker' of some kind to be sure the data received is in correct order!

hth
jay
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jan 22, 2014 7:44 pm     Reply with quote

test program
OK, ain't pretty but it does work...

Code:
//46k22 test program
#include <18f46k22.h>
#include "46k22_fuses.h"
#include "46k22_pins.h"
#use delay(clock=16000000)
#use rs232(baud=9600, UART2, ERRORS,stream=u2)
//===============================
signed int16 x;
int8 vhi=0;
int8 vlo=0;

void main() {
while(true){

   vhi=fgetc(U2);
   vlo=fgetc(U2);
   x=make16(vhi,vlo);
   printf("\n\r%02x %02x %0ld ",vhi,vlo,x);
}//end of forever while
}//end of main program


sent data by Realterm as 0x12 0x34 , then 0x92 0x34

hth
jay
webgiorgio



Joined: 02 Oct 2009
Posts: 123
Location: Denmark

View user's profile Send private message

PostPosted: Tue May 27, 2014 2:27 pm     Reply with quote

Hi,
I understand your code but I don't understand how to apply it to my case.
I send from hyperterminal to the PIC a command like MF=123 terminated with CR. I store it in a circular buffer (an array of characters).

So, I have an array that at the index 4 5 6 has the characters of the number I want to put into an int16 (or int8 would be ok also). I don't see the "high" and "low" byte.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Tue May 27, 2014 2:46 pm     Reply with quote

You are sending ASCII text, not binary values. It was the latter that temtronic assumed.
Look at 'atol' in the manual. Write the characters into an array. When you see the CR, write a '\0', and then call atol with the address of the array. It does the conversion to int16.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue May 27, 2014 2:48 pm     Reply with quote

webgiorgio wrote:
Hi,
I understand your code but I don't understand how to apply it to my case.
I send from hyperterminal to the PIC a command like MF=123 terminated with CR. I store it in a circular buffer (an array of characters).

So, I have an array that at the index 4 5 6 has the characters of the number I want to put into an int16 (or int8 would be ok also). I don't see the "high" and "low" byte.

That's because you have not got the "high" and "low" bytes.
In your case of MF=123 followed by CR, you've got ASCII characters '1' '2' '3' at indicees 4,5,6 in the buffer.
You convert your ASCII characters to binary then to int16.
(Or use the built in ASCII to int16 conversion.)

Mike

EDIT
Mr T. got in whilst I was typing.


Last edited by Mike Walne on Tue May 27, 2014 2:49 pm; edited 1 time in total
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue May 27, 2014 2:49 pm     Reply with quote

Ok NOW you've changed the data.....

originally I assumed you were receiving the int16 data as 2 bytes..

Now though,you'll have to 'parse' your buffer which contains 'MF=123', looking for the '=' the grab the next 3 bytes( 123 ).
Those I assume are 'one hundred and twenty three'.
From there you'll have to 'convert' and place into an int16 variable.

hint...decimal 123 is 7B in hex
problem though...an int16 can hold up to 65535, so your 'incoming data' might be 65 thousand,five hundred and thirty five...so you'll need to grab the next 5 bytes(if present) after the equal sign.
hint. if you 'pad' the data to always have 5 bytes it might be easier for you to decode.


hth
jay
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Tue May 27, 2014 2:59 pm     Reply with quote

Hi,

I'd forget the 'circular' buffer as it unnecessarily complicates a simple project. A 'linear' buffer is more than adequate - start buffering when you receive the 'M' character, and stop when you receive the <CR> character.

Now, keep in mind that the buffer will contain the ASCII values for the digits you've sent. You'll need to convert those ASCII values to their decimal equivalents. I use a routine like this for that purpose:

Code:

// This routine is used to convert characters for checking the checksum
// It simply converts an ASCII hex value into true decimal form
// ASCII allows for a quick and dirty conversion routine!

byte gethexbyte(char digit) {
   if(!BIT_TEST(digit,6))      // Its a number if bit 6 is 0
      return(digit & 0x0F);   // Simple way to convert 0-9
   else
      return((digit & 0x0F) + 9);
}


Here is one way you could 'decode' the example command string (eg. 'MF=123') you've provided:

Code:

Value = (gethexbyte(RxBuffer[3]) * 100) + (gethexbyte(RxBuffer[4]) * 10) + (gethexbyte(RxBuffer[5]));


Hopefully this gives you what you are missing!

John
webgiorgio



Joined: 02 Oct 2009
Posts: 123
Location: Denmark

View user's profile Send private message

PostPosted: Wed May 28, 2014 3:10 am     Reply with quote

sorry for the misunderstanding. Yes I send ASCII characters to the PIC serial port from hyperterminal. And yes temtronic, 123 i mean 'one hundred and twenty three' (or any other value 0-255). I will try atol().

But, is a string an array of characters??
webgiorgio



Joined: 02 Oct 2009
Posts: 123
Location: Denmark

View user's profile Send private message

PostPosted: Wed May 28, 2014 4:14 am     Reply with quote

Code:
      if (data_ready){ //read cmd_string and empty buffer
         data_ready=0;
         i=1;
         printf("\r\nBuffered data => ");
         //memset(cmd_string,0,sizeof(cmd_string));
         cmd_string[0]=0; //empty the array
         while((data_in_buffer)){
            cmd_string[i]=buffer_getc();
            putc(cmd_string[i]);
            i++;
            }
         cmd_string[i]='\0';
         printf("\nstring= %s\n", cmd_string);
      }


data_ready is set to 1 when the ISR receives a '\r' character.
I sent something to the pic, "MF=123" or "test", whatever string. I see it printed back from the putc(), but not from the printf(). ...why?
Quote:
***** booting... ******

test

Buffered data => test
string=
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed May 28, 2014 4:50 am     Reply with quote

At first glance your code looks OK.
It is difficult to say why printf doesn't work because you didn't post a complete test program.

Is it possible you have multiple '#use RS232' lines?
printf() by default uses the last '#use RS232' line it encounters. To avoid these problems it is better to use fprintf() and a stream name:
Code:
#use RS232 (uart1, baud=9600, stream=SERIAL_PC)

fprintf(SERIAL_PC, "Test\n");
webgiorgio



Joined: 02 Oct 2009
Posts: 123
Location: Denmark

View user's profile Send private message

PostPosted: Wed May 28, 2014 5:49 am     Reply with quote

I solved! it was the way I initialized the string.
Code:
strcpy(cmd_string, ""); //empty the array

works
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