In embedded design, for a variable storage design with only two states, how to efficiently quantify the deviation of the tracking car…

Foreword

(1) In embedded programming, we often need to store data from various sensors. Most of the time sensors, such as infrared light sensors, return data that is either 0 or 1. Therefore, only one bit is needed to store it. However, many people often use char array storage, so that only one-eighth of the memory actually applied for is used. For microcontrollers like MCUs, where space is at a premium, this is a huge waste of memory.
(2) Therefore, I will introduce here a technology explained when I first learned C language-bit field to improve space utilization.
(3) When getting started in embedded development, most people make a tracking car, and for tracking, it is necessary to quantify the deviation of the photoelectric sensor. The corresponding PWM is output according to the quantized value of the deviation. (If it is open-loop control) To quantify the deviation, using a consortium is undoubtedly the most efficient way.

Optimize two types of state variable storage

Storage

(1) For example, my small project requires the use of a 12-channel tracking module, an infrared remote control, and a touch module (there is a touch module that will return a specified level when you touch it).
(2) In order to efficiently store these variables with only two states. We can store it as follows.

/*--- Storage structure design ---*/
typedef struct
{
uint8_t track_bit1 :1;
uint8_t track_bit2:1;
uint8_t track_bit3:1;
uint8_t track_bit4:1;
uint8_t track_bit5:1;
uint8_t track_bit6:1;
uint8_t track_bit7 :1;
uint8_t track_bit8:1;
uint8_t track_bit9:1;
uint8_t track_bit10:1;
uint8_t track_bit11:1;
uint8_t track_bit12:1; //The above are all grayscale sensor control bits
uint8_t IRDS_bit13:1; //Infrared remote control control bit
uint8_t Touch_bit14:1; //Touch module
uint8_t bit15:1; //The following 2 bits are reserved
uint8_t bit16:1;
}Bit_field;

Access

(1) Now we know how to store this and how to access it? This is actually the basic knowledge of C language bit fields, but in case some universities don’t teach this part, I’ll talk about it anyway.

Bit_field two_status_sensor;
two_status_sensor.track_bit1 = readpin(1); //Use your current MCU to read the pin level function
two_status_sensor.track_bit2 = readpin(2); //Use your current MCU to read the pin level function
two_status_sensor.IRDS_bit13 = readpin(13); //Use your current MCU to read the pin level function
if(two_status_sensor.IRDS_bit13 == 1) //Assume that the remote control is pressed and the pin is high level
{
//...
}

Use unions to quantify deviations

Use Excel to visualize deviation quantification

(1) Now we have a good storage for this 2-valued variable using bit fields. But we all know that if you want to track the module, you need to process the data. How to quantify the deviation is another problem. Here, I recommend using excl tables, which can process data very intuitively.
(2) We have several traces, so we need to write a few grids. After a hexadecimal data, it is convenient for programming. Finally, there is our deviation quantization value. The binary grid is written to facilitate conversion to hexadecimal.
(3) Beautify the form

>” title=”>” style=”outline: none ;”></p>
<blockquote>
<p>(4) Fill in the form</p>
</blockquote>
<p><img src=

(5) Then fill in the deviation quantification value that you set yourself, and fill the areas where the sensor responds with blue, which is easier to read.

How to efficiently design variable storage with only two states in embedded design? Quantify the deviation of the tracking car_#define_03

Program the deviation quantification

Junk code written by most people

(1) Use Excel to quantify the numerical deviation of the sensor, but how to program it? Presumably many students use the following very inefficient method to quantify deviations.

char deviation; //Storage deviation quantification value
if(two_status_sensor.track_bit1 == 1) deviation = -11;
if(two_status_sensor.track_bit1 == 1 & amp; & amp; two_status_sensor.track_bit2) deviation = -10;
if(two_status_sensor.track_bit1 == 1) deviation = -9;
//...

(2) This method is very troublesome to write and inconvenient to read. It can be said that the writing is quite rubbish!

Use consortium control flags

(1) In order to improve the viewing quality of the code and facilitate our debugging. I think we can optimize the code using the union approach. After doing this, we can find that the quantified value of the deviation can be very well controlled.

/*---Use the union to optimize deviation quantification ---*/
typedef union //Use union to optimize deviation quantification
{
Bit_field sensor_value;
uint16_t state;
}_two_status_sensor;

/*--- Access variables ---*/
char deviation; //Storage the current value of the deviation quantization value
_two_status_sensor two_status_sensor; //Define the value used to record the sensor
two_status_sensor.sensor_value.track_bit1 = readpin(1); //Use your current MCU to read the pin level function
//... Omit the process of reading the value of the sensor

switch(two_status_sensor.state & amp; 0x0FFF)//Deviation quantization, because it is a 12-way tracking, so only the lower 12 bits are needed
{
case 0x0001:deviation=-11;break; //000000000001b
case 0x0003:deviation=-10;break; //000000000011b
//...Omit other deviation quantification processes
default://Other special cases are judged separately
{
//...
}
}

Use macros with parameters to judge flags

(1) But can this be optimized again? Certainly, we know that in this 2-value combination, some are used for tracking, some are used for remote controls, and some are used for touch chips. To improve code readability. Can we use several parameterized macros to define it?

/*--- Use macros with parameters to judge flags ---*/
#define track_state(x) x & 0x0FFF
#define IRDS_state(x) x & 0x1000
#define Touch_state(x) x & amp; 0x2000

Use ?: and conditional compilation to improve the adaptability of code to hardware

(1) Have we found a problem? Following the code above, the black line detected is 1. Then someone must have said, what if my hardware detects that the black line is low level?
(2) In order to improve the adaptability of the code to the hardware, I think conditional compilation can be used.
(3) Because different MCUs do not necessarily return 0 and 1 when reading the level. It is possible that the low level is 0 and the high level is another non-0 value, such as 5. Therefore, in order to prevent overflow problems caused by insufficient storage of 1 bit. We can use ?: to handle it.

/*--- Improve the adaptability of code to hardware ---*/
#define track_active_level 1 //Write 1 when high level is active, write 0 when low level is active
#if track_active_level
two_status_sensor.sensor_value.track_bit1 = readpin(1)!=0?0x01:0x00;
//...Same as the other 11
#else
two_status_sensor.sensor_value.track_bit1 = readpin(1)==0?0x01:0x00;
//...Same as the other 11
#endif

Make error judgments, protect hardware, and improve hardware fault tolerance

(1) Seeing the above code, some people must think it is very good. However, let’s think about it, what if the data returned by the final result of the trace is not the expected data? For example, the car ran away.
(2) In order to prevent this abnormal situation and protect the hardware, we can add a flag bit worse to store the number of errors. If the number exceeds the limit, the vehicle will be forced to stop.
(3) Because the car tracking may just deviate from the route a little bit, or the hardware suddenly has a minor problem, we can also create a flag deviation_backup to store the past values of the deviation quantization value. Let the car keep running in the last state to improve the hardware fault tolerance rate.

/*--- Improve the adaptability of code to hardware ---*/
#define track_active_level 1 //Write 1 when high level is active, write 0 when low level is active
#if track_active_level
two_status_sensor.sensor_value.track_bit1 = readpin(1)!=0?0x01:0x00;
//...Same as the other 11
#else
two_status_sensor.sensor_value.track_bit1 = readpin(1)==0?0x01:0x00;
//...Same as the other 11
#endif
/*--- Use macros with parameters to judge flags ---*/
#define track_state(x) x & 0x0FFF
#define IRDS_state(x) x & 0x1000
#define Touch_state(x) x & 0x2000
/*---Use the union to optimize deviation quantification ---*/
typedef union //Use union to optimize deviation quantification
{
Bit_field sensor_value;
uint16_t state;
}_two_status_sensor;

/*--- Access variables ---*/
char deviation; //Storage the current value of the deviation quantization value
char deviation_backup,worse;//Storage the past values of the deviation quantization value and the number of tracking errors
_two_status_sensor two_status_sensor; //Define the value used to record the sensor
two_status_sensor.sensor_value.track_bit1 = readpin(1); //Use your current MCU to read the pin level function
//... Omit the process of reading the value of the sensor

switch(track_state(two_status_sensor.state))//Deviation quantization, because it is a 12-way tracking, so only the lower 12 bits are needed
{
case 0x0001:deviation=-11;worse/2;break; //000000000001b
case 0x0003:deviation=-10;worse/=2;break; //000000000011b
//...Omit other deviation quantification processes
default://Other special cases are judged separately
{
deviation=deviation_backup;//If it is an abnormal situation, keep the previous state
worse + + ;
}
}
if(worse == 10) //If there are multiple tracking errors, it means there is a problem. In order to protect the hardware, a forced shutdown is required.
{
//parking
}