Samk humidity control#121
Conversation
feature: add sensor data access methods.
Vavat
left a comment
There was a problem hiding this comment.
Sam, this is very good. Nicely done. Let's have pair programming session sometime next week to go through key problems. Specifically, ::run() method. We can then discuss hardware testing. I am in the process of building actual chamber, so this is the right time I think.
| #include "CPIDLoop.h" | ||
| #include "IHardwareMap.h" | ||
|
|
||
| #define CHANNEL_NUMBER 8 |
There was a problem hiding this comment.
Why do we have multiple channels?
There was a problem hiding this comment.
In the temperature controller code, it looks like a heater is assigned per channel. In my humidity controller code, I utilize all the heaters in changing the humidity.
| private: | ||
| void sendStatus(IComChannel *p_comchannel); | ||
| ICommand::command_error_code_t setHumidity(ICommand *p_command); | ||
| ICommand::command_error_code_t overrideHeater(ICommand *p_command); |
There was a problem hiding this comment.
I see you made an assumption that we are going to use heater as a humidifier. For now this is acceptable, but since part of the goal here is to educate you I thought I'd be appropriate to demonstrate how this would be working in a more advanced object oriented design.
Since we right now don't know what humidifier we are going to use, a more flexible design decision would have been to have another class
CHumidifier with methods such as CHumidifier::startEvaporation() and CHumidifier::stopEvaporation() or something along those lines.
Having said that, your design is fairly easy to adapt to having external humidifier and we will perhaps do that once this bit is done.
|
|
||
| IHardwareMap *mp_hw; | ||
|
|
||
| CBME280 *hum_sensor; |
There was a problem hiding this comment.
This member variable should be called CBME280* mp_humidity_sensor
mp_ prefix means that it's a member pointer. Also, we try to avoid shortening names since it detracts from readability.
|
|
||
| CBME280 *hum_sensor; | ||
|
|
||
| float target_humidity; |
| { | ||
| if (actual_humidity != target_humidity) | ||
| { | ||
| if (actual_humidity < target_humidity) |
There was a problem hiding this comment.
This entire if... else... construct is unnecessary. CPIDLoop class will take care of it automatically if you set it up correctly. Let's discuss this part of the code in pair programming session.
| for (int i = 0; i < CHANNEL_NUMBER; i++) | ||
| { | ||
| float power = 0; | ||
| actual_humidity = hum_sensor->getHumidity(); |
There was a problem hiding this comment.
You don't need to call humidity sensor withing the loop. The value of actual humidity is not going to change, so you are just wasting cycles. This entire construct is a bit confusing to me, so perhaps we should have a pair programming session to discuss what you were trying to achieve and how to best approach it.
There was a problem hiding this comment.
Yes, we can talk about it during the session.
| } | ||
| mp_hw->setHardPwmOutput(power, i); | ||
| } | ||
| while (actual_humidity != target_humidity) |
There was a problem hiding this comment.
::run() method must exist. This version of the method hogs the control until humidity is reached. The superloop design pattern assumes that each controller will execute ::run() method to do quick work and exit. Looping like you did will likely cause a lock up since nothing else is getting processed.
There was a problem hiding this comment.
I see, didn't think of that
| bool b_command_recognised = false; | ||
| ICommand::command_error_code_t result = ICommand::COMMAND_OK; | ||
| /** | ||
| * Query about current state of all active channels. |
There was a problem hiding this comment.
One of the things you will need to learn is where to comment. One habit that is worth developing is avoiding comments. If you feel like a piece of code requires comment, then first thing you should consider is whether you should refactor it to make code very clear and not require comments.
This type of comment is superfluous. Your code is very clean and easy to read, so cluttering it with comments that do not really add new information is detrimental.
Generally, comments should be placed where complex piece of logic is happening, e.g. you're doing some numerical approximation using your own algorithm. Or you have implemented another algorithm in which case brief description is in order and then a reference to a book or a website where algorithm is described in details. Another possibility for comments are in places where you have optimised the if... else construct for execution speed and this reduced readability, but you really want speed improvement, so explain what you've done.
This will come with experience, so don't worry about it too much now, but try to follow the principle.
| } | ||
|
|
||
| /** | ||
| * @brief Set humidity value |
There was a problem hiding this comment.
Incomplete doxy header. Should have
@param p_command field.
We need to make sure you have right setup to do automatic doxygen headers generation.
|
@samkno1, when you address the issues raised during the code review, you can mark them as resolved. |
|
@Vavat I intend on implementing the humidifier class to control the humidifier device. Since this is the case, do I currently need to worry about including the IHardwareMap class in my code since all access to external hardware will go through either the CHumidifier class or the CBME280 class |
|
@samkno1, when you think you have addressed all review comments and pushed new code you need to request review again. This restarts review process with your new code. Three are circular arrows next to the reviewers name - mine in this case - that will notify me that new changes are ready for review. |
@samkno1, I have clicked the request review, but then realised you may not have pushed everything, so let's follow proper process. When you think code is ready, let me know. |
|
Hi Vavat,
It isn’t ready yet maybe I might have pushed to the wrong branch. Last week was really busy for me cause of school and there was a hurricane. I’ll request a new review once it’s ready, hopefully this week.
Sent from Mail<https://go.microsoft.com/fwlink/?LinkId=550986> for Windows
From: Salavat ***@***.***>
Sent: October 1, 2022 9:14 AM
To: ***@***.***>
Cc: Samuel ***@***.***>; ***@***.***>
Subject: Re: [Niuslar/Multichannel-Temperature-Control] Samk humidity control (PR #121)
CAUTION: The Sender of this email is not from within Dalhousie.
@samkno1<https://github.com/samkno1>, when you think you have addressed all review comments and pushed new code you need to request review again. This restarts review process with your new code. Three are circular arrows next to the reviewers name - mine in this case - that will notify me that new changes are ready for review.
@samkno1<https://github.com/samkno1>, I have clicked the request review, but then realised you may not have pushed everything, so let's follow proper process. When you think code is ready, let me know.
—
Reply to this email directly, view it on GitHub<#121 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AQI7YBGSZTL2ATURR6CEP3TWBATKRANCNFSM573V2HAQ>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
|
@samkno1, in the meantime I am going to create a humidifier interface within the hardware maps. You can choose to merge them to your code when they are ready. |
Sounds good |
Feature/srm humidifier hardware
|
@Vavat You mentioned the runtime for which CDispatcher will run the humidity controller. Is the run time something I need to define somewhere? |
|
I have the CPIDLoop defining the power variable for the humidifier
Never mind. I just realized I included it as an argument in the Humidity controller class constructor. |
Vavat
left a comment
There was a problem hiding this comment.
Let's have a pair programming session as soon as you can.
| @@ -8,6 +8,7 @@ | |||
| #include "CHumidityController.h" | |||
| #include <stdio.h> | |||
| #include "CBME280.h" | |||
There was a problem hiding this comment.
The header files that are included in CHumidityController.h do not need to be included here. They will be visible. Only include here header file for own class and whatever headers you need to operate, e.g. stdio.h.
There was a problem hiding this comment.
Noted. I was a bit confused about including header files in the .cpp and .h. Thanks
| #include "CHumidityController.h" | ||
| #include <stdio.h> | ||
| #include "CBME280.h" | ||
| #include "CHumidifier.h" |
There was a problem hiding this comment.
Is this used? This might have been something legacy or something I introduced. Check if it does anything and if not remove.
There was a problem hiding this comment.
No, I included that while I was previously using the CHumidifier class to do the humidifier abstraction. I forgot to remove it since it's no longer being used.
|
|
||
| CBME280 hum_temp_reader(p_spi, p_slave_select_port, slave_select_pin); | ||
| hum_sensor = &hum_temp_reader; | ||
| CBME280 humidity_sensor(p_spi, p_slave_select_port, slave_select_pin); |
There was a problem hiding this comment.
What is the point of these operations? Line 36 already creates humidity_sensor, so reassigning its pointer to another variable is useless operation. Am I missing something?
There was a problem hiding this comment.
I think this is related to your comment on the SPI port not being set up. When I directly use the CBME280 humidity_sensor object. I get the following error "error: 'humidity_sensor' was not declared in this scope". So I opted for dynamically accessing the class with the m_humidity sensor pointer to the CBME280 class.
| @@ -32,8 +33,8 @@ CHumidityController::CHumidityController(IHardwareMap *p_hardware, | |||
| // TODO Auto-generated constructor stub | |||
There was a problem hiding this comment.
Just realised that this constructor is not going to work because when CHumidityController is created, the SPI port hardware will not be setup yet, so the constructor pointers will be all nullptr. This is actually quite important aspect of c++ for you to understand, so let's have a pair programming session. Drop me an invite.
| float actual_humidity; | ||
| for (int i = 0; i < CHANNEL_NUMBER; i++) | ||
| float power = 0; | ||
| if (m_power_override == DISABLE_OVERRIDE) |
There was a problem hiding this comment.
I would recommend that special numbers are not used. They can be confusing. I would recommend that you create a special member variable bool mb_humidifier_override;. Move power variable from ::run() method into becoming actual member variable m_power. Then logic becomes much cleaner.
if (!mb_humidifier_override)
{
... here you do the control of power since power is not overriden.
}
mp_hw->setHumidifierPower(m_power);
m_power is set to override value when command to override is executed.
This is much cleaner to read and is much less likely to cause confusion with API.
There was a problem hiding this comment.
when processing commands, if you get a command that overrides the power, then you simply toggle mb_power_override.
| } | ||
| float power = *p_command; | ||
|
|
||
| // Execute command |
There was a problem hiding this comment.
Unnecessary comment. And it's wrong, since you are sanitising before executing.
| { | ||
| return ICommand::ERROR_ARG_COUNT; | ||
| } | ||
| float power = *p_command; |
There was a problem hiding this comment.
This is a mistake. To access first argument of the command it should be:
float power = (*p_command)[0];
| { | ||
| power = MAX_POWER; | ||
| } | ||
| if ((power < MIN_POWER) && (power != DISABLE_OVERRIDE)) |
There was a problem hiding this comment.
This is complex logic and would be much easier if you used boolean switch to control override.
| } | ||
| if (b_command_recognised) | ||
| { | ||
| switch (result) |
There was a problem hiding this comment.
There is now a method in CController that will do what this switch statement does, so you can take advantage of it.
|
|
||
| void CHumidityController::sendStatus(IComChannel *p_comchannel) | ||
| { | ||
| etl::string<MAX_STRING_SIZE> message; |
There was a problem hiding this comment.
We are currently discussing how to return responses to be understood by higher layers. This might change drastically in the future.
Humidity controller created.
Assumptions: