0

I have 3 sensors that each provide either 0 or 1 (repeatedly in a loop). They are stored individually as int variables. These are then printed using the following:

print ("%d%d%d", Sensor1, Sensor2, Sensor3);

I want to store each combination (ex: 010, 001, 110, etc.) temporarily so that I can use it do something else (I want to have a switch or something eventually where I can do a different operation depending on the value of the sensor combination). I can't store it as an int since that drops the 0s in front.

How can I store these combinations?

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • 2
    How does storing them as an `int` "drop the 0s in front"? – Carl Norum Oct 11 '14 at 04:45
  • I was declaring a new int as equal to the four sensors. When I was using this in a switch code it was dropping the 0s in front such that 000 would be the same as 010. Or at least that's as far as I can tell. I'm probably confusing something though. – Ekundayo Green Oct 11 '14 at 04:47
  • 1
    @EkundayoGreen You mean, `010` would be same as `10`? Well, is that a problem? Note, encoding your values in base 10 is not a good solution, this is just a note about your "dropping zeros in front" logic. Note2: Do not write `010` as number in C code, it will interpret numbers starting with 0 as octal, IOW `010 == 8`. – hyde Oct 11 '14 at 05:14
  • @hyde Yes that is a problem for me. I need to be able to take the 010 value and do something with it. I'm sorry hyde, I am not completely sure what you mean as I am not all too familiar with C yet. Is there a better way to store 010 so that I can call it later in my switch case function? Thanks! – Ekundayo Green Oct 11 '14 at 05:18
  • @EkundayoGreen Well, in base 10, just store it as number, possible values 0(='000'), 1(='001'), 10(='010'), 100, 11(='010'), 101, 110, 111. But it'd be better to store it in binary, value between 7 and 0 (use some calculator to convert decimal numbers 7..0 to binary, if you can't do that in your head). – hyde Oct 11 '14 at 05:23
  • Also, "drops 0's in front", what does it mean? Try `printf("%03d", 0)`, you see it has 3 zeros... Or as many as you like, basic math... – hyde Oct 11 '14 at 05:26
  • Oh that's very interesting. So would I be able to do the following: int ALLSENSORS = Sensor1, Sensor2, Sensor3; ..? And then later I can call the decimal equivalent in my switch case statement? – Ekundayo Green Oct 11 '14 at 05:30
  • I think I was just completely unaware of how binary/decimal would impact things. Ignore my drop 0s in front comments. =) – Ekundayo Green Oct 11 '14 at 05:31
  • @Jongware : Don't rush him; it is not unreasonable to wait at least 24 hours before accepting an answer so that users from *all* time-zones get a chance to answer! – Clifford Oct 11 '14 at 10:10
  • 1
    @Clifford: no rushing was intended, just a friendly reminder ;) as the OP did not choose to Take The Tour™ when signing on. – Jongware Oct 11 '14 at 10:13

5 Answers5

1

You can use structure bit field for this.

struct Bit{
    bool Sensor1 : 1;
    bool Sensor2 : 1;
    bool Sensor3 : 1;
};

int main(void)
{
    struct Bit bit = {0, 1, 0};
    printf ("%d%d%d", bit.Sensor1, bit.Sensor2, bit.Sensor3);
}
haccks
  • 104,019
  • 25
  • 176
  • 264
  • I've never seen this before (new to programming)! Very interesting. So I take it that the first struct just sets the intial sensor values to 1 each. Then in the main function you have another bit which again sets the bit values to something and then prints them? But how does the bit within the main function grab the int sensor readings that I have? Thanks for your help! =) – Ekundayo Green Oct 11 '14 at 05:16
  • `bool Sensor1 : 1;` declares `Sensor1` as a `bool` type which is having width 1-bit only. In `main` I just initialize the struct members. Read about bit field with the provided link. – haccks Oct 11 '14 at 05:38
1

So you have

int Sensor1, Sensor2, Sensor3;
// have code to initialize above variables to 0 or 1

To store these as one integer in base 10, assuming they really all are 0 or 1, you can do:

int Sensors_10 = Sensor1 * 100 + Sensor2 * 10 + Sensor3;

And then to get them back:

Sensor1 = Sensors_10 / 100 % 10;
Sensor2 = Sensors_10 / 10 % 10;
Sensor3 = Sensors_10 % 10;

Obviously order of sensors can be whatever, as long as it matches between packing and unpacking.


But, you only need 1 bit to store each sensor, so could use binary:

int Sensors_2 = Sensor1 * 4 + Sensor2 * 2 + Sensor3;

...

Sensor1 = Sensors_2 / 4 % 2;
Sensor2 = Sensors_2 / 4 % 2;
Sensor3 = Sensors_2 % 2;

But, with computer binary numbers are special, so the binary version is more commonly written like this:

int Sensors_2 = Sensor1 << 2 | Sensor2 << 1 | Sensor3;

...

Sensor1 = Sensors_2 >> 2 & 1;
Sensor2 = Sensors_2 >> 1 & 1;
Sensor3 = Sensors_2 & 1;

Where |, <<, >> and & are bitwise OR, shift and AND operators, and explaining what they do is beyond scope of this question, but one note about them: When there are no "overlapping" one-bits and numbers are positive, then result of | is same as result of +.

Answer of haccks covers how to make C compiler do this for you, without doing your own bit manipulation.


To print Sensors_10 with leading zeros, you can do printf("%03d", Sensors_10);. C standard library does not have a way to print binary numbers directly, so you need your own code to print the bits one-by-one, so you might as well printf("%d%d%d", Sensor1, Sensor2, Sensor3); then.

hyde
  • 60,639
  • 21
  • 115
  • 176
  • Thanks for all your help hyde! Reading over all the comments (especially yours) made me realize that my approach didn't make sense. I was convinced that I absolutely needed to be able to store and recall numbers like 010 when there would be no difference between that and 10. I was complicating things for no reason. Your first answer of "Well, is that a problem?" was actually spot on. It wasn't a problem after all. =D – Ekundayo Green Oct 11 '14 at 07:01
0

You can use a 2D int array to store the values and use it later.

E.g int sen_value[1000][3]; use it in the loop to store the values.

Example how you can use it in loop:

#include <stdio.h>
int main ()
{
    int i;
    int sen_value[10][3];
    for(i=0;i<10;i++)
    {
        //Assigning the values
        sen_value[i][0] = 0;
        sen_value[i][1] = 0;
        sen_value[i][2] = 0;

        //Use the way you want
        printf("%d %d %d\n",sen_value[i][0],sen_value[i][1],sen_value[i][2]);
    }
    return 0;
}

Or you can use it just once and then reset it after each operation, For example:

#include <stdio.h>
int main ()
{
    int sen_value[1][3];
    //Assigning the values
    sen_value[0][0] = 0;
    sen_value[0][1] = 0;
    sen_value[0][2] = 0;

    //Use the way you want
    printf("%d %d %d\n",sen_value[0][0],sen_value[0][1],sen_value[0][2]);
    return 0;
}
ani627
  • 5,578
  • 8
  • 39
  • 45
  • I just want to take that 000 and use it instantly in my switch statement later. Can you explain to me how you would feed my sensor readings into an array? Sorry for being such a bother and thank you for your help. – Ekundayo Green Oct 11 '14 at 05:12
  • @EkundayoGreen: Check the updated answer, To feed sensor readings into an array simply use assignment operator. – ani627 Oct 11 '14 at 05:27
0

If you are using a linux environment then by using the command you can easily save the output that are displayed in your console.

Let here sensor.c be your source file Then,

$ gcc -o a sensor.c
$ ./a > senser.txt

Then you have a .txt file with all output stored in a txt file. And these can be again used as inputs in your other.c files like :

$ gcc -o other other.c
$ ./other < senser.txt

If you want to store those sensor1,sensor2,sensor3 internally and use internally then you can simply use the arrays or Structure like :

main(){
   int Sensor[1][3];
   Sensor[0][0] = 0;
   Sensor[0][1] = 1;
   Sensor[0][2] = 0;  

   print ("%d%d%d", Sensor[0][0], Sensor[0][1], Sensor[0][2]);  

}
Asis
  • 683
  • 3
  • 23
0

While the leading zeroes of an integer are not displayed when printed, that does not mean they are "dropped"; they are merely implicit - that is a matter of the format specifier used in teh output of the value rather than the zeros not being present. An int is always a fixed number of binary digits.

Consider:

uint32_t sensor_state = (sensor3 << 3) | (sensor2 << 1) | sensor1 ;

Note that uint32_t is a type alias for an unsigned integer 32 bits in length. It is defined by including the <stdint.h> header file. In this case a plain int would work, but when you are dealing with data at the bit level it is good to be explicit (and unsigned). Here of course a uint8_t would work too, and if your target is an 8 bit device, I suggest you use that.

Here sensor_state is a binary combination of the three sensor values and will have one of the following values:

Sensors        sensor_state
3 2 1     binary  decimal   hexadecimal
---------------------------------------
0 0 0     0000      0         0x00
0 0 1     0001      1         0x01
0 1 0     0010      2         0x02
0 1 1     0011      3         0x03
1 0 0     0100      4         0x04
1 0 1     0101      5         0x05
1 1 0     0110      6         0x06
1 1 1     0111      7         0x07

So you can switch on any combination:

switch( sensor_state )
{
    case 0x00 :
        ...
    break ;

    case 0x01 :
        ...
    break ;

    case 0x02 :
        ...
    break ;

    ...

    case 0x07 :
        ...
    break ;

    default :
        // unexpected invalid combination
    break ;
}

You might usefully create an enumeration for each combination:

enum eSensorStates
{
    NO_SENSOR = 0,
    SENSOR1,
    SENSOR2,
    SENSOR12,
    SENSOR3,
    SENSOR13,
    SENSOR23,
    SENSOR123
}

Then you can write:

switch( sensor_state )
{
    case NO_SENSOR :
        ...
    break ;

    case SENSOR1:
        ...
    break ;

    case SENSOR2:
        ...
    break ;

    ...

    case SENSOR123 :
        ...
    break ;

    default :
        // unexpected invalid combination
    break ;
}

You may of course use enumeration names that make specific sense in your application - that reflect the meaning or action for each combination rather than the generic names I have chosen.

Clifford
  • 88,407
  • 13
  • 85
  • 165