help with expanding my byte

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I need to take 1 byte and expand it to two bytes adding a negative bit.

0 to -65535

128 = 0

256 to 65535

then stuff back in to two bytes.

 

This was my attempt

 

BB_ReadBuffer[3] is my in data

x is my out.

 

short neg;
short  x;
if( BB_ReadBuffer[3] < 128 ) neg=0x8000; else neg=0;//negative flag
x = (BB_ReadBuffer[3] << 7) | neg;
reportBuffer[12] = (x & 0xff);
reportBuffer[13] = (x >> 8);

 

but the ending results is more like -65535...-16512 to -16512...65535. Problem with this is I never rest at 0.

 

I guess I could add a - run code if ( BB_ReadBuffer[3] < 120 || BB_ReadBuffer[3] > 133) but is there a way to do this more efficiently? I wonder if a look up table would be better.

 

 

 

Last Edited: Thu. Dec 20, 2018 - 03:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The range -65535 to +65535 won't fit in 2 bytes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your description is very vague to me.

Maybe we're both not native English speaking persons?

 

Next. As kk6gm noted. Your range does not fit into 16 bits.

With an int16_t you can count from a little bit less than -32000 to a little bit bigger than: + 32000.

Negative numbers in C are interpreted in the form of "two's complement". You should get more info if you search for that.

 

Also:

If you make use of the unwritten, but sort of standarized conventions, it makes it a bit easier to communicate.

- Use the macro's from inttypes.h

- Use the code tag for code on the forum.

- Always use curly braces around if statements and loops.

#include <inttypes.h>

int16_t neg;
int16_t  x;

if( BB_ReadBuffer[3] < 128 ) {
    neg=0x8000;
}
else {
    neg=0;//negative flag
}

x = (BB_ReadBuffer[3] << 7) | neg;
reportBuffer[12] = x & 0xff;
reportBuffer[13] = x >> 8;

 

It also helps if you take a simple piece of paper and a pen.

Write the binary numbers down, and then write under the binary number the result you want to have.

Then write some arrows between those numbers of how you want to go from the first form to the second.

Only then start writing C code.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, I messed up. I meant -32767 to 32767. The more I look at this the more I realize it is just not practical. The application is a joysticks. The source has a one byte range and the destination accepts a two byte range. So my stepping is in the 500's. The source controller is just way to sensitive and math will not solve this. I'm going to have to use a look up table or a bunch of if's. I will need to make sure the joystick rests at 0 unless it moves a number steps and I also need to through the number up to 32767 when the stick is fully extended. So my issue was a conventional error rather then mathematical. 

Last Edited: Thu. Dec 20, 2018 - 12:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You could use an interpolation table if the response is non-linear.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd say the usual way would be:

 

int16_t convert(uint8_t input) {
	return (input << 8) - 0x8000;
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I suppose I could use a non-linear in this case.  It would help with the initial sensitivity if the greater end of the curve was near the low end. What is the advantage of this over a lookup? I can not find much on a interpolation "table".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why not simply multiply int8_t by 256? - 128 will become - 32768 and +127 will become 32512. I suppose the latter should normalise to 32767?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well the controller is not %100 still. So what happens is if I'm sitting at 128 (rest) I'm good but that never happens. I get 130 or 126 and that means 1024 or some times 1636 after calc and that makes the destination game think the stick is being pressed. The two options I have are 1) clip it, AKA add dead zones. Or 2) make a curve. I like the curve idea because I hate to lose much of my wimpy 256 precision as the entire thing is magnified. 

Last Edited: Thu. Dec 20, 2018 - 01:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Radio control sets have "dead band" in the middle of stick travel so small "noise" goes unnoticed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A simple lookup has a value for each input. This can chew a lot of flash. A interpolation table has values for each point of the curve. Google piecewise linear interpolation. Car ECUs used to use this technique to compute fuel, ignition etc. doesn’t need much storage and easy to compute.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S_K_U_N_X wrote:

Well the controller is not %100 still. So what happens is if I'm sitting at 128 (rest) I'm good but that never happens. I get 130 or 126 and that means 1024 or some times 1636 after calc and that makes the destination game think the stick is being pressed. The two options I have are 1) clip it, AKA add dead zones. Or 2) make a curve. I like the curve idea because I hate to lose much of my wimpy 256 precision as the entire thing is magnified. 

 

Is it possible to sample faster? Then you could do a moving average and smooth the values.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In this case no. The sampling is done on a co device. 

[device 1] ->[device 2] ->[device 3]->[device 4]

controller  ->  adapter  ->    interfacer -> console

In my case I'm working on the interfacer. So it just gets data from the adapter and the adapter samples the controller. 

 

The  piecewise linear interpolation  calculation maybe the way to go.  Working this..

Last Edited: Thu. Dec 20, 2018 - 03:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you aren't sure if you need lin or log, perhaps a square function (scaled as a number smaller than 1), could be a fast solution (I assume this is on a AVR with a HW mul)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

piecewise seemed to get it.

Last Edited: Tue. Jan 1, 2019 - 03:55 PM