Skip to content

Commit

Permalink
Added test for calibration mode
Browse files Browse the repository at this point in the history
  • Loading branch information
arcadien committed Nov 23, 2023
1 parent 308d191 commit 16ebfff
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 85 deletions.
12 changes: 10 additions & 2 deletions lib/Cross/Gun/SSD1306Ui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ class SSD1306Ui : public IGunUi {
public:
SSD1306Ui() {}

void setup() override{
void setup() override {
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
for (;;)
; // Don't proceed, loop forever
}
}

void displaySplash(uint16_t timeoutMs) override {
display.clearDisplay();
display.setTextColor(WHITE);
Expand Down Expand Up @@ -93,4 +93,12 @@ class SSD1306Ui : public IGunUi {
display.print(count);
display.display();
}

void displayCalibration() override {
display.fillRect(11, 0, 68, 30, 0); // clear
display.setCursor(15, 25);
display.setFont(&FreeMonoOblique9pt7b);
display.print("Calibration");
display.display();
}
};
2 changes: 1 addition & 1 deletion lib/Domain/Contactor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <Contactor.hpp>

void Contactor::checkForLongPress(long now) {
if ((downStartTime > 0) && ((now - downStartTime) > LONG_PRESS)) {
if ((downStartTime > 0) && ((now - downStartTime) >= LONG_PRESS)) {
downStartTime = 0;
onLongPress();
}
Expand Down
69 changes: 32 additions & 37 deletions lib/Domain/Gun/Gun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,32 @@

#define TICKS_BETWEEN_BATTERY_UI_UPDATE 100

// counter for ticks between battery display update
uint16_t updateBatteryDisplayCycleCount;

long now = 0;

Gun::Gun(IGunHal *hal, IGunUi *ui) {
this->hal = hal;
this->ui = ui;
calibrationMode = false;
shootCount = 0;

// display at first loop
shootCycleCountdown = 0;
batteryDisplayCycleCountdown = 0;

button.setGun(this);
trigger.setGun(this);
}

void Gun::toggleCalibrationMode() {
calibrationMode = !calibrationMode;
if (calibrationMode) {
hal->laserOn();
hal->vibrationOff();
ui->displayCalibration();
} else {
hal->laserOff();
ui->displayShootCount(shootCount);
}
}

void Gun::activateShoot() {
if (shootCycleCountdown == 0) {
shootCount += 1;
Expand All @@ -48,50 +58,35 @@ void Gun::activateShoot() {
void Gun::loop(void) {

// 10ms per loop thanks to timer2
now += 10;
millisSinceStart += 10;

trigger.processPendingEvent(now);
button.processPendingEvent(now);

button.checkForLongPress(now);

if (calibrationMode) {
hal->laserOn();
hal->vibrationOff();
trigger.processPendingEvent(millisSinceStart);
button.processPendingEvent(millisSinceStart);

} else {
button.checkForLongPress(millisSinceStart);

if (shootCycleCountdown > 0) {
if (shootCycleCountdown > 0) {
shootCycleCountdown--;
if (shootCycleCountdown == 1) {
hal->laserOff();
hal->vibrationOff();
ui->displayShootCount(shootCount);
shootCycleCountdown--;
if (shootCycleCountdown == 1) {
hal->laserOff();
hal->vibrationOff();
ui->displayShootCount(shootCount);
shootCycleCountdown--;
}
}

if (updateBatteryDisplayCycleCount > 0) {
updateBatteryDisplayCycleCount--;
}
if (updateBatteryDisplayCycleCount == 0) {
ui->displayBatteryStatus(hal->getBatteryVoltageMv(),
hal->getBatteryVoltagePercent());
updateBatteryDisplayCycleCount = TICKS_BETWEEN_BATTERY_UI_UPDATE;
}
}
if (batteryDisplayCycleCountdown > 0) {
batteryDisplayCycleCountdown--;
} else {
ui->displayBatteryStatus(hal->getBatteryVoltageMv(),
hal->getBatteryVoltagePercent());
batteryDisplayCycleCountdown = TICKS_BETWEEN_BATTERY_UI_UPDATE;
}
hal->sleep();
}

void Gun::setup(void) {

shootCount = 0;
updateBatteryDisplayCycleCount = TICKS_BETWEEN_BATTERY_UI_UPDATE;

ui->displaySplash(2000);

// mV is not used
ui->displayBatteryStatus(0, hal->getBatteryVoltagePercent());

ui->displayShootCount(0);
}
6 changes: 4 additions & 2 deletions lib/Domain/Gun/Gun.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
class Gun {

uint8_t shootCycleCountdown;
uint16_t batteryDisplayCycleCountdown;
long millisSinceStart = 0;
bool calibrationMode;

public:
/* 50 ms */
Expand All @@ -34,14 +37,13 @@ class Gun {
IGunUi *ui;
Button button;
Trigger trigger;
bool calibrationMode;
uint16_t shootCount;

Gun(IGunHal *hal, IGunUi *ui);

void activateShoot();

void toggleCalibrationMode() { calibrationMode = !calibrationMode; }
void toggleCalibrationMode();

/**
* @brief Gun loop shall be called at least each 10ms,
Expand Down
1 change: 1 addition & 0 deletions lib/Domain/Gun/IGunUi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ class IGunUi {
virtual void displayBatteryStatus(uint16_t mv, uint8_t percent) = 0;
virtual void displayChargingStatus(bool isCharging) = 0;
virtual void displayShootCount(uint16_t shootCount) = 0;
virtual void displayCalibration() = 0;
};
2 changes: 1 addition & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ upload_command = avrdude -vv -b57600 -pm328p -c avrisp -Pcom9 $UPLOAD_FLAGS -U f
build_type = debug
debug_build_flags = -Og -ggdb3 -g3 -DNATIVE
test_ignore = cross/*
debug_test = noarch/test_contactor
debug_test = native/test_gun
build_src_filter = ${env.src_filter} -<TargetApp.cpp> -<GunApp.cpp>

[env:cross]
Expand Down
99 changes: 57 additions & 42 deletions test/native/test_gun/gun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,21 @@
#include <ArduinoFake.h>
using namespace fakeit;

#define MOCK_ALL() \
When(Method(mockHal, triggerIsUp)).AlwaysReturn(true); \
When(Method(mockHal, buttonIsUp)).AlwaysReturn(true); \
When(Method(mockHal, laserOn)).AlwaysReturn(); \
When(Method(mockHal, vibrationOn)).AlwaysReturn(); \
When(Method(mockHal, vibrationOff)).AlwaysReturn(); \
When(Method(mockHal, laserOff)).AlwaysReturn(); \
When(Method(mockHal, getBatteryVoltageMv)).AlwaysReturn(5000U); \
When(Method(mockHal, getBatteryVoltagePercent)).AlwaysReturn(100U); \
When(Method(mockHal, sleep)).AlwaysReturn(); \
When(Method(mockUi, displayBatteryStatus)).AlwaysReturn(); \
When(Method(mockUi, displayShootCount)).AlwaysReturn(); \
When(Method(mockUi, displayCalibration)).AlwaysReturn(); \
When(Method(mockUi, displaySplash)).AlwaysReturn();

void tearDown() {}
void setUp() { ArduinoFakeReset(); }

Expand All @@ -32,17 +47,7 @@ void expect_gun_to_loop() {
Mock<IGunUi> mockUi;
Mock<IGunHal> mockHal;

When(Method(mockHal, triggerIsUp)).AlwaysReturn(true);
When(Method(mockHal, buttonIsUp)).AlwaysReturn(true);
When(Method(mockHal, laserOn)).AlwaysReturn();
When(Method(mockHal, vibrationOn)).AlwaysReturn();
When(Method(mockHal, vibrationOff)).AlwaysReturn();
When(Method(mockHal, laserOff)).AlwaysReturn();
When(Method(mockHal, getBatteryVoltageMv)).AlwaysReturn(5000);
When(Method(mockHal, getBatteryVoltagePercent)).AlwaysReturn(100);
When(Method(mockHal, sleep)).AlwaysReturn();
When(Method(mockUi, displayBatteryStatus)).AlwaysReturn();
When(Method(mockUi, displayShootCount)).AlwaysReturn();
MOCK_ALL();

IGunUi &ui = mockUi.get();
IGunHal &hal = mockHal.get();
Expand All @@ -51,23 +56,12 @@ void expect_gun_to_loop() {

gun.loop();
}

void expect_gun_to_shoot_50ms_on_trigger_down() {

Mock<IGunUi> mockUi;
Mock<IGunHal> mockHal;

When(Method(mockHal, triggerIsUp)).AlwaysReturn(true);
When(Method(mockHal, buttonIsUp)).AlwaysReturn(true);
When(Method(mockHal, laserOn)).AlwaysReturn();
When(Method(mockHal, vibrationOn)).AlwaysReturn();
When(Method(mockHal, vibrationOff)).AlwaysReturn();
When(Method(mockHal, laserOff)).AlwaysReturn();
When(Method(mockHal, getBatteryVoltageMv)).AlwaysReturn(5000);
When(Method(mockHal, getBatteryVoltagePercent)).AlwaysReturn(100);
When(Method(mockHal, sleep)).AlwaysReturn();
When(Method(mockUi, displayBatteryStatus)).AlwaysReturn();
When(Method(mockUi, displayShootCount)).AlwaysReturn();
MOCK_ALL();

IGunUi &ui = mockUi.get();
IGunHal &hal = mockHal.get();
Expand All @@ -93,45 +87,66 @@ void expect_gun_to_shoot_50ms_on_trigger_down() {
Verify(Method(mockHal, laserOff)).Once();
Verify(Method(mockHal, sleep)).Exactly(7);
}

void expect_ui_to_display_battery_state_each_1s() {
void expect_ui_to_display_battery_state_at_boot_and_each_1s() {
Mock<IGunUi> mockUi;
Mock<IGunHal> mockHal;

When(Method(mockHal, triggerIsUp)).AlwaysReturn(true);
When(Method(mockHal, buttonIsUp)).AlwaysReturn(true);
When(Method(mockHal, laserOn)).AlwaysReturn();
When(Method(mockHal, vibrationOn)).AlwaysReturn();
When(Method(mockHal, vibrationOff)).AlwaysReturn();
When(Method(mockHal, laserOff)).AlwaysReturn();
When(Method(mockHal, getBatteryVoltageMv)).AlwaysReturn(5000U);
When(Method(mockHal, getBatteryVoltagePercent)).AlwaysReturn(100U);
When(Method(mockHal, sleep)).AlwaysReturn();
When(Method(mockUi, displayBatteryStatus)).AlwaysReturn();
When(Method(mockUi, displayShootCount)).AlwaysReturn();
When(Method(mockUi, displaySplash)).AlwaysReturn();
MOCK_ALL();

IGunUi &ui = mockUi.get();
IGunHal &hal = mockHal.get();

Gun gun(&hal, &ui);

// displayBatteryStatus first call
gun.setup();

for (uint8_t tickCounter = 0; tickCounter < 100; tickCounter++) {
for (uint8_t tickCounter = 0; tickCounter <= 101; tickCounter++) {
// displayBatteryStatus call after 100 ticks
gun.loop();
}

// display at first loop, then each second (or 100 ticks)
Verify(Method(mockUi, displayBatteryStatus)).Exactly(2);
}

void expect_switch_to_maintenance_after_2s_button_continuous_press() {
Mock<IGunUi> mockUi;
Mock<IGunHal> mockHal;

MOCK_ALL();

IGunUi &ui = mockUi.get();
IGunHal &hal = mockHal.get();

Gun gun(&hal, &ui);

gun.button.pendingEvent = Contactor::Event::Pressed;
for (uint8_t tickCounter = 0; tickCounter <= 200; tickCounter++) {
// long press shall be accounted after 2s, 200 ticks
gun.loop();
}
gun.button.pendingEvent = Contactor::Event::Released;
gun.loop();
gun.button.pendingEvent = Contactor::Event::Pressed;
for (uint8_t tickCounter = 0; tickCounter <= 200; tickCounter++) {
// long press shall be accounted after 2s, 200 ticks
gun.loop();
}

// switch to calibration
Verify(Method(mockHal, laserOn)).Exactly(1);
Verify(Method(mockUi, displayCalibration)).Exactly(1);

// back to normal
Verify(Method(mockHal, laserOff)).Exactly(1);
Verify(Method(mockUi, displayShootCount)).Exactly(1);
}

int main(int, char **) {
UNITY_BEGIN();
RUN_TEST(expect_gun_to_loop);
RUN_TEST(expect_gun_to_shoot_50ms_on_trigger_down);
RUN_TEST(expect_ui_to_display_battery_state_each_1s);
RUN_TEST(expect_ui_to_display_battery_state_at_boot_and_each_1s);
RUN_TEST(expect_switch_to_maintenance_after_2s_button_continuous_press);

UNITY_END();
return 0;
}

0 comments on commit 16ebfff

Please sign in to comment.