Array Problems: Possible<stdio.h>

Hello, I would appreciate if anyone can help me out with this arrray statement. I’m not sure if I have to put it in a function or import a header library so I can use an array. Here is my code, also it is available to anyone who wants to use it. It uses one joystick to drive a a 2 wheel drive bot with the wheels in the centre, like a tank. It also solves the problem of having the joystick go forward and the bot turn and vice versa.

/Alex Wijtowych’s Little addition to the code to make a dual axis drive system with a smoother control!!!/
/Let PWM 09 represent the right wheel of the bot and PWM 10 represent the left wheel of the bot/
int speed_array[255] ={0,0,0,0,0,0,0,4,8,12,16,20,23,27,30,34,37,40,43,45,
48,51,53,56,58,60,63,65,67,69,71,73,75,76,78,80,81,83,84,86,87,88,90,91,
92,93,94,96,97,98,99,100,100,101,102,103,104,105,105,106,107,107,108,
109,109,110,111,111,112,112,113,113,114,114,114,115,115,116,116,116,
117,117,117,118,118,118,119,119,119,119,120,120,120,120,121,121,121,
121,121,122,122,122,122,122,122,123,123,123,123,123,123,123,124,124,
124,124,124,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
127,127,127,127,127,127,127,130,130,130,130,130,131,131,131,131,131,
131,131,132,132,132,132,132,132,133,133,133,133,133,134,134,134,134,
135,135,135,135,136,136,136,137,137,137,138,138,138,139,139,140,140,
140,141,141,142,142,143,143,144,145,145,146,147,147,148,149,149,150,
151,152,153,154,154,155,156,157,158,160,161,162,163,164,166,167,168,
170,171,173,174,176,178,179,181,183,185,187,189,191,194,196,198,201,
203,206,209,211,214,217,220,224,227,231,234,238,242,246,250,254,255,
255,255,255,255,255,255};
if (p1_y > 127 )
{
if (p1_x > 127)
{
pwm09 = speed_array[255 - (2 *(p1_x - 127))];
pwm10 = speed_array[p1_y];
}
else if (p1_x < 127)
{
pwm09 = speed_array[255 - p1_y];
pwm10 = speed_array[255 - (2 *(127 - p1_x))];
}
else if (p1_x == 127)
{
pwm09 = speed_array[p1_y - 127];
pwm10 = speed_array[p1_y];
}
}
else if (p1_y < 127)
{
if (p1_x > 127)
{
pwm09 = speed_array[255 - (2 *(p1_x - 127))];
pwm10 = speed_array[p1_y];
}
else if (p1_x < 127)
{
pwm09 = speed_array[255 - p1_y];
pwm10 = speed_array[2 *(127 - p1_x)];
}
else if (p1_x == 127)
{
pwm09 = speed_array[127 + (127 - p1_y)];
pwm10 = speed_array[p1_y];
}
}
else if (p1_y == 127)
{
if (p1_x < 127)
{
pwm09 = speed_array[127 + (127 - p1_x)];
pwm10 = speed_array[p1_x];
}
else if (p1_x > 127)
{
pwm09 = speed_array[127 - (p1_x - 127)];
pwm10 = speed_array[p1_x];
}
else if (p1_x == 127)
{
pwm09 = 127;
pwm10 = 127;
}
}

You may want to consider making your array a “rom const”.

You don’t need to include anything or do anything special to use an array. It’s just a variable like anything else.

Matt

I had to change two things to make your code compile. First, I changed the array dimension to 256, since you have 256 initializer values. (Remember the range from 0 to 255 contains 256 values.)

I also had to change the array definition from “int speed_array” to “rom const int speed_array” as Mike suggested. Without the “rom const”, the linker complained: “Error - section ‘.idata_user_routines.o’ can not fit the section. Section ‘.idata_user_routines.o’ length=0x00000208”.

It would probably be possible to edit the .LKR file to make the data fit without making it “rom const”, but this way is easier. There’s no reason to sweat making data fit into RAM when the program will never change it.

Personally I would have come up with a formula to automate this for you.

Either way, you shouldn’t use an integer array as the values range from 0-255. Because of that, all you need are unsigned chars, which range from 0 to 255.

Just incase you’re unsure of the syntax…

 **unsigned char** speed_array[255] ={0,0, ... 255};

Ints normally use 2 bytes, while chars use 1 byte. The integer array of 256 would be 512 bytes while the char array only 256 bytes. That’s one method of code optimization that you should look out for. It’s easy to just write ints for everything, when all that’s required is a char whether it’s signed or unsigned. Remember that the system we’re coding under has limited resources, and little things like these can mean cutting off an extra feature.

Still, if we had some more resources…

If a look-up table is semetric (meaning the values below 127 are just as low as the values above are high), then you can cut the table size in half.

Here’s my code for it:


const rom signed char JOYSTICK_SMOOTHING[128] = 
{
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2,
2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8,
8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 16, 17, 17,
18, 19, 20, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 45, 46, 48, 49,
50, 51, 53, 54, 55, 56, 58, 59, 61, 62, 63, 65, 66, 68, 69, 71,
72, 74, 75, 77, 78, 80, 81, 83, 85, 86, 88, 89, 91, 93, 95, 96,
98, 100, 102, 103, 105, 107, 109, 111, 113, 114, 116, 118, 120, 122, 124, 126
};

void Drive_Joystick(char Left, char Right)
{
	if(Left > 127)
	{
		Left_CIM = Left_Drill =  (128 + JOYSTICK_SMOOTHING[Left - 127]);
	}
	else
	{
		Left_CIM = Left_Drill = (127 - JOYSTICK_SMOOTHING[127 - Left]);
    }
    
//	Right_CIM = Right_Drill = Right;
   	if(Right > 127)
	{
		Right_CIM = Right_Drill =  (128 + JOYSTICK_SMOOTHING[Right - 127]);
	}
	else
	{
		Right_CIM = Right_Drill = (127 - JOYSTICK_SMOOTHING[127 - Right]);
    }
}

Note: Each side had 2 motors which always had to be the same value. They were named CIM and Drill (guess what kind they were). So Left_CIM and Left_Drill were the left-side motors and Right_CIM and Right_Drill were the right-side motors.

This could be reduced to a macro:


#define SMOOTHED_VALUE(joy) ( (128 + JOYSTICK_SMOOTHING(((joy)>127) ? ((joy) - 127) : (127 - (joy)))]) )

(Macros are kinda like Perl one-liners: only the author really knows what’s going on.)

When the array is stored in the ROM does that mean the array has to be global? I had a smoothing function last year but i just called the array like so: motor1 = smooth[joy]; However, this year i wanted to put it in function and i kept getting errors saying the stack size was too large. I have a feeling this is due to a variable’s scope in a function. Could i use static to place the variables in a function?

No, it doesn’t have to be global. If it’s outside a function, it will have global scope by default. But you can restrict its visibility to the file only by assigning it “static” storage class. You can also hide the array inside a function. It compiled cleanly when I defined it as “static rom const unsigned char speed_array[256]…” inside a function. (Thank you Arthur(Ssbfalcon) for pointing out that all the data values in the array would fit in char sized elements.)