We are programming a ST269 microcontroller which has two IR distance sensors. To calibrate these sensors we made one table for each sensor with the distance we measured and the corresponding value we get from the ADC.
Now we want to use one function to approximate the values in between. So we defined two two-dimensional arrays (one for each sensor) as global variables. In our function we then want to copy the one array we want to work with to a working array and approximate our values.
So here's the code:
...
unsigned int ir_werte_re[][] = {
{8,553},
...
{83,133}
};
unsigned int ir_werte_li[][] = {
{8,566},
...
{83,147}
};
...
unsigned int geradenaproximation(unsigned int messwert, unsigned int seite)
{
unsigned int working_array[16][16];
unsigned int i = 0;
if (seite == 0) {
for (i = 0; i < sizeof(working_array); i++) {
working_array[i][0] = ir_werte_li[i][0];
i++;
}
}
else {
for (i = 0; i < sizeof(working_array); i++) {
working_array[i][0] = ir_werte_re[i][0];
i++;
}
}
i = 0;
unsigned int y1 = 0;
unsigned int x1 = 0;
...
}
This code is in a file called sensor.c. We didn't write anything about our global arrays in the sensor.h should we? The sensor.h of course is included in our main.c and there the function is called.
We also tried to copy the arrays via
memcpy(working_array, ir_werte_li, sizeof(working_array));
And in every way we do this we get a
syntax error near unsigned
in the line where we're declaring
unsigned int y1 = 0;
and I'm pretty sure that there is no syntax error in this line : )
The last time I spend coding in C is a few years away so I'm not sure if the way we try to do this is good. Perhaps we can solve this by using a pointer instead of really copying the array or something. So please help me out I'll appreciate your bits on this.
In C (pre-C99), all variable definitions must appear at the top of the current block scope.
Related
I am making a program for my arduino that needs to access a eeprom but I need to find a way to send it a address, I have a int I would like to convert into binary and send to the eeprom but I need to split it into a array so I can send the data to the eeprom.
I cant think of any way to do this and I have asked some people for help but they couldn't figure out how to ether.
void int_to_bin_array(unsigned int in, int count, int* out)
{
unsigned int mask = 1U << (count-1);
int i;
for (i = 0; i < count; i++) {
out[i] = (in & mask) ? 1 : 0;
in <<= 1;
}
}
int main(void)
{
int binary_array[8];
const int bin_size = 8;
int decimal = 15;
int_to_bin_array(decimal, bin_size, binary_array);
return 0;
}
Memory addresses are hexadecimal values, not binary. You don't need to do this here.
You need to correctly understand memory interfacing with your MCU (Arduino in this case) along with embedded systems concepts and pointers in C.
You can specify address values in hexadecimal values directly (uint_t addr = (uint_t *) 0x1234ABCD) and the compiler will automatically convert it to respective binary, during compilation.
That code will run on a payment device (POS). I have to use legacy C (not C# or C++) for that purpose.
I am trying to prepare a simple Mifare card read/write software data. Below document is my reference and I am trying to achieve what is on page 9, 8.6.2.1 Value blocks explains.
http://www.nxp.com/documents/data_sheet/MF1S50YYX_V1.pdf
I just know very basics of C. All my searches in The Internet have failed. According to document:
1- There is integer variable with value of 1234567.
2- There is char array[4] which should have hex of above value which is 0x0012D687
3- I am supposed to invert that char array[4] and reach value of 0xFFED2978
I need to do some other things but I have stuck in number 3 above. What I have tried lastly is
int value = 1234567;
char valuebuffer[4];
char invertbuffer[4];
sprintf(valuebuffer, "%04x", value);
for(i = 0; i < sizeof(valuebuffer); i++ )
{
invertbuffer[i] ^= valuebuffer[i];
}
When I print, I read some other value in invertbuffer and not 0xFFED2978
Seems like you're making it more complicated than it needs to be. You can do the binary inversion on the int variable rather than messing around with individual bytes.
int value = 1234567;
int inverted= ~ value;
printf("%x\n",value);
printf("%x\n",inverted);
gives you output of
12d687
ffed2978
First of all, you must use the types from stdint.h and not char, because the latter has implementation-defined signedness and is therefore overall unsuitable for holding raw binary data.
With that sorted, you can use a union for maximum flexibility:
#include <stdint.h>
#include <stdio.h>
typedef union
{
uint32_t u32;
uint8_t u8 [4];
} uint32_union_t;
int main (void)
{
uint32_union_t x;
x.u32 = 1234567;
for(size_t i=0; i<4; i++)
{
printf("%X ", x.u8[i]);
}
printf("\n");
x.u32 = ~x.u32;
for(size_t i=0; i<4; i++)
{
printf("%X ", x.u8[i]);
}
printf("\n");
}
Notably, the access order of the u8 is endianess dependent. This might be handy when dealing with something like RFID, which doesn't necessarily have the same network endianess as your MCU.
I have an array that is made up doubles which I need to round down and convert to integers so I can use them as indices in an output array. I have just started C programming and am not sure how this works. So far the best I have been able to come up with is:
int create_hist( double input_array[], int count, int output_array[17] ) {
for ( int i = 0; i < count; i++ ) {
input_array[i] = int floor(input_array[i]);
output_array[input_array[i]]++;
However I am getting the following errors which I am having trouble deciphering:
array.c:11:20: error: expected expression before ‘int’
input_array[i] = int floor(input_array[i]);
^
array.c:12:7: error: array subscript is not an integer
hist[input_array[i]]++;
^
array.c:14:1: error: control reaches end of non-void function [-Werror=return-type]
}
^
If someone could let me know where I have gone wrong it would be greatly appreciated.
Unless you actually want to modify input_array, you would be best off saving the rounded off double in an intermediate variable to then access your integer array. And no need to use floor() casting the double to int will do that.
int create_hist(double input_array[], int count, int output_array[17]) {
for (int i = 0; i < count; i++) {
int index = (int)input_array[i];
if ((index > 16) || (index < 0)) {
return -1;
}
output_array[index]++;
}
return 0;
}
Of course, you should really pass in the size of output_array as a variable as well, instead of hard-coding it.
So let get cracking:
First error is due to the fact that you are kind of declaring a function.
input_array[i] = int floor(input_array[i]);
notice int in front of floor, that is not necessary. It should be
input_array[i] = floor(input_array[i]);
Second error is due to the fact that you are accessing array element using double in
output_array[input_array[i]]++;
either you should do it some other way or do following:
output_array[(int) input_array[i]]++;
and the third error is unbalanced parenthesizes.
I'm writing for a very limited resource embedded processor. I have a struct that captures a time series of events, and I'd like to use the same graphing function against different values of different types. Something like (very stripped down; don't sweat uninitialized values, etc):
#define GRAPH_ONE 1
#define GRAPH_TWO 2
struct _event_t {
unsigned long timestamp;
int sensorOne;
float sensorTwo;
}
typedef struct _event_t event_t;
event_t[10] MyEvents;
void GraphSensor(byte graphType) {
for (unsigned int i = 0; i < 9; i++) {
// Get minimum value from series
if (MyEvents[i].?????) ...
}
}
How can I have my function operate on different members of the struct? I can see doing it with a ton of switch (graphType) statements, but that's pretty ugly. There could easily be 8 or 10 members of the struct. I could move all of those to a separate function and make every bit of data access call that function, always returning a float (which should be OK for my graph). Finally I could convert to C++ classes, which opens other means.
None of those feel right. Is there a better approach, preferably a very lightweight one?
You could wrap the accessor you need in a function, and pass that to the function that walks the array and aggregates the results. For example
float getSensor1(const event_t* t)
{
return t->sensorOne;
}
float getSensor2(const event_t* t)
{
return t->sensorTwo;
}
void GraphSensor(float (*accessor)(const event_t*)) {
// Get minimum value from series
float min_value = MAX_FLOAT;
for (unsigned int i = 0; i < 9; i++) {
float x = accessor(MyEvents + i);
if (x < min_value)
min_value = x;
}
}
/* later on . . . */
GraphSensor(getSensor1);
GraphSensor(getsensor2);
You are basically decoupling the access of the data from the operation on it, and homogenizing it all to floats. The aggregation operation could also be encapsulated into a function, too. But that's getting pretty close to map-reduce. :)
You could change the struct to an array which uses perhaps all floats. In that way the data handling is completely homogeneous.
#define N_SENSORS 12
#define N_EVENTS 10
float MyEvents [N_EVENTS] [N_SENSORS];
void GraphSensor(byte graphType)
{
float min = 1e38;
for (unsigned int i = 0; i < N_EVENTS; i++)
{
// Get minimum value from series
if (MyEvents[i][graphType] < min)
min = MyEvents[i][graphType];
}
}
Perhaps the timestamp could be there too in element zero maybe using spreadsheet conventions: integer part is days since 1970 or 1900 and fractional part is portion of the day (so noon = .5).
I am having an issue with some code that I am writing.
I use this site often as I have found many people who have already asked the same questions I am wondering. With that I want to thank the community on here for all of the previous insight into my programming conundrums.
(And before we get too far, no this is not a 'school project' or 'school homework', I am simply trying to solve the 'Travelling Salesman Problem' and better my C skills.
This is the portion of code I have been stuck on:
void printAndFlip(int arrayone[][20], int citytotal, int arrayCities[])
{
////Finds cost:
int x, y, z;
int totalCost
int singleTrip;
int cheepestTrip;
int nCity = citytotal + 1; //nCity is the number of Cities //Adding one to accomadate going back to the first city
int gCounter;
int gCounterTrue = 1;
int cheepestTrip[20];
int totalCost = 0;
int lCounter;
int i;
int n = citytotal;
////Sets up for a default case to set cheepestTrip:
for(gCounter = 1; gCounter <= nCity; gCounter++)
{
while(gCounterTrue == 1)
{
if(gCounter == arrayCities[gCounter])
{
gCounterTrue = 1;
}
else
{
gCounterTrue = 0;
gCounter = 50; //Stopping the larger for loop with 50 (the nCity can't be larger than 20) so that it will hopefully be faster
}
if(gCounter == nCity)
{
if(arrayCities[1] == arrayCities[nCity])
{
!!!!! cheepestTrip = totalCost;
}
}
}
}
for(x = 1; x < nCity; x++)
{
y = arrayCities[x];
z = arrayCities[x+1];
singleTrip = arrayone[y][z]; //finding individual cost of each trip...will be added to 'totalCost' below
totalCost = singleTrip + totalCost;
}
!!!!!!!! if(totalCost <= cheepestTrip)
{
for(lCounter = 1; lCounter <= nCity; lCounter++)
{
cheepestTrip[lCounter] = arrayCities[lCounter];
}
}
To make it easier to show where my compile errors are at I put exclamation points on the lines.
Please tell me if I am wrong, but I am passing an array of pointers with an array when I send 'arrayone' to printANDFlip right?
I know the compile errors are relating to the pointers but I am just uncertain of where they should be placed.
Any and all help will be appreciated.
Much thanks,
Alex
To make explicit what some of the other replies are saying: You have two variables with the same name but different types:
int cheepestTrip; /* This is an single integer... */
and
int cheepestTrip[20]; /* ...but this is an array of integers. */
This should be triggering a warning at compile time (probably something about redeclaring an existing variable).
Here you are comparing an array pointer with a int value
if(totalCost <= cheepestTrip)
For example you should compare it to an element of that array
if(totalCost <= cheepestTrip[0])
cheepestTrip is the name of the array, which is equivalent to a pointer to the first element. totalCost is an int. Just remove the [20] from your declaration at the top part of the code.
you are comparing a pointer to an int, which your particular compiler might not be allowing (though I though with C you could). but cheapestTrip is essentially a pointer to the first element in your array of ints, while totalcost is simply an int primative