How data hiding is different from Encapsulation

Thread Starter

John99407

Joined Jul 12, 2019
77
I do not understand the difference between data hiding and Encapsulation. Are these two same or different? If these two are different then what is the difference between the two

Encapsulation Is the process of hiding sensitive data of object from user. To achieve this, we must declare class variables/attributes as private.

Here's an example of typical encapsulation:
Code:
class MyClass
{
public:
  int a //public member
private:
  int x;  //private member
  int y; 
};
Can you help me to understand the difference between the two. How they are different from each other ?
 

WBahn

Joined Mar 31, 2012
32,746
There's no defining authority for these terms and phrases, so you aren't going to find a rigid, universally-agreed upon definition.

But in general "data hiding" is going to be a looser, more flexible phrase than "encapsulation" or "abstraction", which most authors are going to use with more precise meanings (even if two different authors are likely to have somewhat different meanings). The term also may or may not apply to functions and procedures as well as the data, that depends on the context of use and who is using it.

Encapsulation, in an object-oriented sense, usually refers to packaging the data, its representation, and the methods that operate directly on it in such a way that the user has no awareness of, or ability to directly interact with, that data. That allows you to change how you represent the data or how you manipulate it without having to worry about breaking the user's code. The user may still be working at the same level as the raw data, but they are insulated from its representation. An example might be a complex number class. The user of the class may want/need to work with the data right down at the real/imaginary or mag/arg level, but they still don't need to know how you are implementing it internal to the class. Maybe you initially represent it as two doubles that are the real and the imaginary part and you provide methods for the user to work with it and later you decide to represent it as two doubles that are the magnitude and the angle in radians. You simply change the methods so they are compatible with the new representation but the user still sees the exact same methods that use the exact same arguments and return the exact same values, so their code still works just fine.

Abstraction is largely the same but the distinction here is more about intent. When you abstract something you create methods that let the user interact with the object at a higher level and you are hiding the lower-level data and methods not so much to keep the user from directly manipulating them, but to let them work with that object at a higher conceptual level. An example here might be printing a report. The user wants to enter a bunch of information and then just call a method named "printReport()" and see a report come out on their printer. But internally your code is dealing with formatting and arranging the data and generating the output that has to be sent to the printer.

The bottom line, from my perspective, is that encapsulation and abstraction are techniques to accomplish particular kinds of data hiding to achieve particular goals.
 

Thread Starter

John99407

Joined Jul 12, 2019
77
The bottom line, from my perspective, is that encapsulation and abstraction are techniques to accomplish particular kinds of data hiding to achieve particular goals.
I can find many example on internet for encapsulation that is not related to embedded mcu programming. I have searched but have not found any so that I can understand it

I understand encapsulation is encapsulation, no matter where it is use in PC programming or MCU programming

Can you give me a one example of encapsulation that is related to embedded mcu programming ? I am looking one meaningful and suitable example that is related to embedded mcu programming ?

.
 

nsaspook

Joined Aug 27, 2009
16,266
A simple C example of one type of encapsulation. The data from the MCU ADC module is binary integer data that should be isolated from the rest of the system that uses real 'float' numbers with an API of access functions.

The 'static' functions of ADC collection, scaling calculations and internal data are 'private' to this text file and to the rest of the C program. The main program on sees 'real' numbers, not the raw ADC data.

C:
/*
 * 12-bit analog 64 sample average per channel on ports A and B
 * uses the compute burst average mode threshold interrupt to auto change
 * channels during interrupt after a repeat count
 */

#include "daq.h"

typedef struct R_data { // internal variables
    adc_result_t raw_adc[ADC_BUFFER_SIZE];
    int16_t n_offset[NUM_C_SENSORS];
    uint8_t scan_index;
    uint16_t scan_select;
    bool done;
} R_data;

static volatile R_data R = {
    .done = false,
    .scan_index = 0,
    .n_offset[0] = N_OFFSET0,
    .n_offset[1] = N_OFFSET1,
};

static void adc_int_handler(void);
static void adc_int_t_handler(void);

/*
 * start computed ADC results: 64 samples per average value per selected channel from
 * AN channel zero to LAST_ADC_CHAN
 * check_adc_scan returns true when sequence is complete
 */
bool start_adc_scan(void)
{
    if (R.done)
        return false;

    R.scan_index = 0;
    R.scan_select = (uint16_t) ((ANSELB << 8) + ANSELA) & ADC_SCAN_CHAN; // skip digital pins PORT A and B
    ADCC_SetADIInterruptHandler(adc_int_handler);
    ADCC_SetADTIInterruptHandler(adc_int_t_handler);
    ADCC_DischargeSampleCapacitor(); // short ADC sample cap before channel sampling
    ADCC_StartConversion(R.scan_index & 0xf);
#ifdef DEBUG_DAQ1
    DEBUG1_SetHigh();
#endif
#ifdef DEBUG_DAQ2
    DEBUG2_SetHigh();
#endif
    return true;
}

/*
 * check scan done flag
 */
bool check_adc_scan(void)
{
    return R.done;
}

/*
 * clear scan done flag
 */
void clear_adc_scan(void)
{
    R.done = false;
}

/*
 * update the raw adc values
 */
bool update_adc_result(void)
{
    if (R.done) {
        clear_adc_scan();
        start_adc_scan();
        StartTimer(TMR_ADC, ADC_SCAN_SPEED);
        while (!TimerDone(TMR_ADC) && !check_adc_scan());
        return true;
    } else {
        return false;
    }
}

/*
 * read average value of a channel after scan completion (done)
 */
adc_result_t get_raw_result(const adcc_channel_t index)
{
    return R.raw_adc[index];
}

/*
 * turn ADC values into standard program values
 */
float conv_raw_result(const adcc_channel_t chan, const adc_conv_t to_what)
{

    switch (to_what) {
    case CONV:
        if (!(ADC_SCAN_CHAN >> chan & 0x1))
            return NAN;

        if (ADC_C_CHAN >> chan & 0x1) { // current conversion
            if (ADC_C_CHAN_TYPE >> chan & 0x1) {
                return((float) (int16_t) get_raw_result(chan) - R.n_offset[0]) * C_A200;
            } else {
                return((float) (int16_t) get_raw_result(chan) - R.n_offset[1]) * C_A100;
            }
        } else {
            if (ADC_T_CHAN >> chan & 0x1) { // temp conversion
                return 25.0; // filler until sensor is selected
            } else { // voltage conversion
                return((float) get_raw_result(chan) * V_SCALE) / 1000.0;
            }
        }
        break;
    case O_CONV:
        if (ADC_C_CHAN >> chan & 0x1 || ADC_T_CHAN >> chan & 0x1)
            return((float) get_raw_result(chan) * C_SCALE) / 1000.0;

        return((float) get_raw_result(chan) * V_SCALE) / 1000.0;
        break;
    default:
        return 0.0;
        break;
    }
    return 0.0;
}

/*
 * ADC per conversion interrupt
 */
static void adc_int_handler(void)
{
#ifdef DEBUG_DAQ2
    DEBUG2_Toggle();
#endif
}

/*
 * ADC per channel average interrupt
 */
static void adc_int_t_handler(void)
{
    /*
     * use the filter result buffer for raw adc data
     */
    R.raw_adc[R.scan_index] = ((adc_result_t) ((ADFLTRH << 8) + ADFLTRL));
    do {
        if (++R.scan_index > LAST_ADC_CHAN) {
            R.done = true;
#ifdef DEBUG_DAQ1
            DEBUG1_SetLow();
#endif
            return;
        }
    } while (!((R.scan_select >> R.scan_index) &0x1)); // check for analog port bit
    ADCC_DischargeSampleCapacitor(); // short ADC sample cap before next channel sampling
    ADCC_StartConversion(R.scan_index & 0xf);
#ifdef DEBUG_DAQ1
    DEBUG1_Toggle();
#endif
}

The program only accesses the data using functions, not the raw results. This means I could completely change the ADC type and mechanism without changing the code that uses the result from the API functions.
C:
/*
 * find rate of change of battery voltage under load
 */
void calc_ror_data(void)
{
    static float bvror = 0.0, bcror = 0.0; // must remember prior values

    C.bc_ror = fabs(conv_raw_result(C_BATT, CONV) - bcror);
    bcror = conv_raw_result(C_BATT, CONV);
    C.bv_ror = fabs(conv_raw_result(V_BAT, CONV) - bvror);
    if (C.bv_ror < ROR_LIMIT_NOISE) // skip noise values
        C.bv_ror = ROR_LIMIT_LOW + ROR_LIMIT_SET; // keep trying value
    bvror = conv_raw_result(V_BAT, CONV);
}
 

WBahn

Joined Mar 31, 2012
32,746
Your original post seemed like the context in which you were asking about encapsulation was object-oriented programming.

The context of use is important. Also important is the context of the question being asked. Why do you need one "meaningful and suitable example that is related to embedded MCU programming"? Meaningful in what way? Suitable for what purpose?

This sounds more like some question on a homework assignment than anything else.
 

Thread Starter

John99407

Joined Jul 12, 2019
77
This sounds more like some question on a homework assignment than anything else.
It's not like that. The question that came to my mind was encapsulation for embedded MCU programming

Why do you need one "meaningful and suitable example that is related to embedded MCU programming"? Meaningful in what way? Suitable for what purpose?
When we do not understand anything, then we take a general example of it to understand So that we can understand it easily

At first I understood what encapsulation is and how it works. After that I saw some examples and understood them After that I started writing the programs for encapsulation

Now I was looking for some examples where encapsulation was used in program with context of embedded MCU programming

Meaning full means that where encapsulation is really needed. There are many ways we can create program. What is the best option to do this work. Is this really a better option? Do we really need?
 

nsaspook

Joined Aug 27, 2009
16,266
What's important about using encapsulation in embedded MCU programming is OO design, not a specific OO Language. Encapsulation (structured programming) increases the power of debugging (often only using simple gpio bits) by improving program element isolation while reducing side-effects. Eliminating or reducing the need to debug is the goal. When you engineer programs instead of just writing them, you always think about what can go wrong. OOD is one way to design programs that can be debugged easier during the source code writing and execution phases. Timing is usually the hard restraint on what's possible using structured programming on embedded MCU. When the timing is loose you can go full tilt with structured programming but when it's tight, isolate the problem to a specific module and make it work correctly, period.
 

402DF855

Joined Feb 9, 2013
271
Consider an alternative design to encapsulation and data hiding. At the other extreme we see highly coupled modules and functions sometimes referred to as "spaghetti code". Such designs are difficult to understand fully, and often fixing a bug or adding features breaks the code or at least requires much more effort.

In my university data structures class we were introduced to the related but perhaps deprecated concept of "abstract data types". One assignment required us to process a group of records (probably students and test scores) where we provided three different implementations for the data structure: simple array, binary tree, and hash table. The code that used the data structure's features did not change regardless of what the underlying storage implementation was.

One possible example in an embedded system is that often we have a variety of serial interfaces on the part: UART, I2C, SPI, ethernet etc. It might be beneficial to encapsulate the common features of a serial device so code that uses the transmit and receive mechanisms is unaware of the specific interface type and its underlying details. This can be helpful in many ways including testing and perhaps adding a newly supported interface; the "client" code may need no modification at all.
 

nsaspook

Joined Aug 27, 2009
16,266
In my university data structures class we were introduced to the related but perhaps deprecated concept of "abstract data types". One assignment required us to process a group of records (probably students and test scores) where we provided three different implementations for the data structure: simple array, binary tree, and hash table. The code that used the data structure's features did not change regardless of what the underlying storage implementation was.
It's not deprecated. It been co-opted by the OOP language priests as a renamed part of the orthodoxy.
 

Thread Starter

John99407

Joined Jul 12, 2019
77
For example There are many types of switches in market https://www.electronicshub.org/switches/

SPST Single Pole Single Throw Switch
SPDT Single Pole Double Throw Switch
DPST Double Pole Single Throw Switch
DPDT Double Pole Double Throw Switch
Push Button Switch

This is an example of encapsulation
Code:
class Switch
{
/* public, protected and private
variables and functions */
};

class SPST : public Switch
{
/* public, protected and private
variables and functions */
};
My question is, do I really need encapsulation to read all type of switch? I do not think I can easily do with structure programming

I can not make good examples of myself. This was the reason I was looking for a suitable and useful example of encapsulation for Embedded MCU Programming
 

WBahn

Joined Mar 31, 2012
32,746
You were given a very good example previously -- namely the peripherals found on most microcontrollers. If you want to get the voltage on a particular ADC input or set the voltage on a particlular DAC output, do you really want to have to jump through a bunch of hoops that are specific and different for every member of a family of microcontrollers, or would you rather like to have a single set of functions that you use that behave the same way regardless of which microcontroller you happen to be using within that family? If you see the advantage of the latter option, then you see the advantage of encapsulation and/or abstraction.
 

MrAl

Joined Jun 17, 2014
13,677
I do not understand the difference between data hiding and Encapsulation. Are these two same or different? If these two are different then what is the difference between the two

Encapsulation Is the process of hiding sensitive data of object from user. To achieve this, we must declare class variables/attributes as private.

Here's an example of typical encapsulation:
Code:
class MyClass
{
public:
  int a //public member
private:
  int x;  //private member
  int y;
};
Can you help me to understand the difference between the two. How they are different from each other ?
Hi,

A namespace is an interesting idea for keeping some things out of reach to some parts of the program.

But encapsulation is a part of abstraction if you want to get picky.
Encapsulation is when you have variables that are accessed through a function.
Abstraction is more general in that you have variables accessed through a function but you can also have functions that do other things.
Data hiding i think is related to derived classes and what the derived class is allowed to use from the base class.

For me i dont take such a restricted view though for example i think of encapsulation as a feature of a class to have functions and data that work together to form a particular overall purpose and the functions or data may be public or private, but the main idea is to have the data private accessible only through functions. One of the outcomes is simpler project maintenance (in many cases maybe not all).
So for me i guess i think of "class" and "encapsulation" as almost the same thing with the idea that a class is made for obtaining encapsulation. So this means even functions would be thought of as being encapsulated.
An example would be to have two different classes, each one having a function that is named the same like "MyFunction()". The name of the function is like it is encapsulated too because each one, even though the two have the same name, is accessible only though its given class.
 

Thread Starter

John99407

Joined Jul 12, 2019
77
A simple C example of one type of encapsulation. The data from the MCU ADC module is binary integer data that should be isolated from the rest of the system that uses real 'float' numbers with an API of access functions.
I do not understand your code. I have not seen any classes in your code. You haven't used private, protected access specifier anywhere. Encapsulation Is the process of hiding sensitive data of object from user

Assuming you have ADC that read analog signal and send to MCU but I can read ADC without encapsulation.

Why did you think you should use encapsulation. ?

What was the reason that you did not follow the normal process which all do ?
 

nsaspook

Joined Aug 27, 2009
16,266
I do not understand your code. I have not seen any classes in your code. You haven't used private, protected access specifier anywhere. Encapsulation Is the process of hiding sensitive data of object from user

Assuming you have ADC that read analog signal and send to MCU but I can read ADC without encapsulation.

Why did you think you should use encapsulation. ?

What was the reason that you did not follow the normal process which all do ?
I know what you're looking for but you didn't specify that you only wanted examples using C++ syntax for structured programming of MCU code. Data hiding (data security) and encapsulation (hiding complexity) are universal programming concepts not just the domain of some OOP language.
 

402DF855

Joined Feb 9, 2013
271
Regarding switches, in software there may be less emphasis on the number of poles and throws. You'd probably be interested in the state of the switch at any given time, and furthermore want to do something when the state changes.
C:
class Switch;
class OnOffSwitch;
class MultiSwitch;

class Switch {
	public:
		Switch() {}
		virtual int GetState() const = 0;
};

class OnOffSwitch : public Switch {
	protected:
		int *source;
	public:
		OnOffSwitch(int *pSource) {source = pSource;}
		virtual int GetState() const {
			return *source!=0;
		}
};

class MultiSwitch : public Switch {
	protected:
		int *source;
	public:
		MultiSwitch(int *pSource) {source = pSource;}
		virtual int GetState() const {
			if (*source&1)
				return 0;
			if (*source&2)
				return 1;
			return 2;
		}
};

OnOffSwitch sw1(DINPUT1);
MultiSwitch sw2(DINPUT2to4);

Switch *switches[2] = {
	&sw1,
	&sw2
};
 

Thread Starter

John99407

Joined Jul 12, 2019
77
I know what you're looking for but you didn't specify that you only wanted examples using C++ syntax for structured programming of MCU code.
You can say that, Codes were not necessary. I just wanted to know why you only used encapsulation for MCU code. So far i have only two examples given here one ADC example you gave and serial communication gave 402DF855. I gave example of switch that is not suitable because I can read multiple switch without encapsulation.
 

WBahn

Joined Mar 31, 2012
32,746
You can say that, Codes were not necessary. I just wanted to know why you only used encapsulation for MCU code.
Perhaps because that is specifically what you asked for ... repeatedly.

"Now I was looking for some examples where encapsulation was used in program with context of embedded MCU programming "

"I can not make good examples of myself. This was the reason I was looking for a suitable and useful example of encapsulation for Embedded MCU Programming "

So far i have only two examples given here one ADC example you gave and serial communication gave 402DF855. I gave example of switch that is not suitable because I can read multiple switch without encapsulation.
You never NEED encapsulation. It is an approach to programming (or other things) to achieve an objective in a certain way or with certain benefits. But you always solve the underlying problem without using it.
 

nsaspook

Joined Aug 27, 2009
16,266
You can say that, Codes were not necessary. I just wanted to know why you only used encapsulation for MCU code. So far i have only two examples given here one ADC example you gave and serial communication gave 402DF855. I gave example of switch that is not suitable because I can read multiple switch without encapsulation.
I used structured programming (OOP and many of today's concepts originated in the 60's with ALGOL 68) for the MCU code. Why you use one or another method is a matter of programming style, experience and how actually useful X method is at solving the problem at hand. I could say my ADC example also used Polymorphism (the redheaded stepchild of OOP) because the conv_raw_result function returns several types (class voltage, current temperature) of measurements results using the same interface. What you do to solve the problem is what's important, not X label assigned to some X method.
 
Last edited:

Thread Starter

John99407

Joined Jul 12, 2019
77
I used structured programming (OOP and many of today's concepts originated in the 60's with ALGOL 68) for the MCU code.
You have done OOP concept for MCU Code and Encapsulation for ADC conversion right

I need to think a bit more about this, I didn't understand your code. I think you must have used a many ADC in your project.And for all you don't want to write code. so You used encapsulation
 

nsaspook

Joined Aug 27, 2009
16,266
You have done OOP concept for MCU Code and Encapsulation for ADC conversion right

I need to think a bit more about this, I didn't understand your code. I think you must have used a many ADC in your project.And for all you don't want to write code. so You used encapsulation
Yes, that's the point. You don't need to understand the bit-banging details in my code to use it. In the C++ OOP implementation it would be much like an Interface. If you request a conversion from a current sensor port (ENUM value of a ADC input pin) it returns a Ampere float value, a voltage sensor port returns a voltage float value and a temperature sensor port returns a Celsius float value.

https://www.tutorialspoint.com/cplusplus/cpp_interfaces.htm
 
Top