0.1.16 MultiSpeedI2CScanner

This commit is contained in:
rob tillaart 2023-01-20 19:49:46 +01:00
parent 1c27872557
commit 8205a5d047
13 changed files with 223 additions and 72 deletions

View File

@ -1,3 +1,18 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:
packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
compile: compile:
# Choosing to run compilation tests on 2 different Arduino platforms # Choosing to run compilation tests on 2 different Arduino platforms
platforms: platforms:
@ -9,3 +24,4 @@ compile:
- esp32 - esp32
- esp8266 - esp8266
- mega2560 - mega2560
- rpipico

View File

@ -0,0 +1,4 @@
# These are supported funding model platforms
github: RobTillaart

View File

@ -6,7 +6,7 @@ jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: arduino/arduino-lint-action@v1 - uses: arduino/arduino-lint-action@v1
with: with:
library-manager: update library-manager: update

View File

@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1 - uses: ruby/setup-ruby@v1
with: with:
ruby-version: 2.6 ruby-version: 2.6

View File

@ -10,7 +10,7 @@ jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: json-syntax-check - name: json-syntax-check
uses: limitusus/json-syntax-check@v1 uses: limitusus/json-syntax-check@v1
with: with:

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2013-2021 Rob Tillaart Copyright (c) 2013-2023 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,7 +1,7 @@
// //
// FILE: MultiSpeedI2CScanner.ino // FILE: MultiSpeedI2CScanner.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.1.14 // VERSION: 0.1.16
// PURPOSE: I2C scanner at different speeds // PURPOSE: I2C scanner at different speeds
// DATE: 2013-11-05 // DATE: 2013-11-05
// URL: https://github.com/RobTillaart/MultiSpeedI2CScanner // URL: https://github.com/RobTillaart/MultiSpeedI2CScanner
@ -12,18 +12,22 @@
#include <Arduino.h> #include <Arduino.h>
#include <Wire.h> #include <Wire.h>
// FOR INTERNAL I2C BUS NANO 33 BLE
// #define WIRE_IMPLEMENT_WIRE1 1
// extern TwoWire Wire1;
TwoWire *wire; TwoWire *wire;
const char version[] = "0.1.14"; const char version[] = "0.1.16";
// INTERFACE COUNT (TESTED TEENSY 3.5 AND ARDUINO DUE ONLY) // INTERFACE COUNT (TESTED TEENSY 3.5 AND ARDUINO DUE ONLY)
int wirePortCount = 1; int wirePortCount = 1;
int selectedWirePort = 0; int selectedWirePort = 0;
// scans devices from 50 to 800KHz I2C speeds. // scans devices from 50 to 800 KHz I2C speeds.
// speed lower than 50 and above 400 can cause problems // speed lower than 50 and above 400 can cause problems
long speed[10] = { 100, 200, 300, 400 }; long speed[10] = { 100, 200, 300, 400 };
int speeds; int speeds;
@ -31,44 +35,46 @@ int addressStart = 8;
int addressEnd = 119; int addressEnd = 119;
// DELAY BETWEEN TESTS // DELAY BETWEEN TESTS
// for delay between tests of found devices.
#ifndef RESTORE_LATENCY #ifndef RESTORE_LATENCY
#define RESTORE_LATENCY 5 // for delay between tests of found devices. #define RESTORE_LATENCY 5
#endif #endif
bool delayFlag = false; bool delayFlag = false;
// MINIMIZE OUTPUT // MINIMIZE OUTPUT
bool printAll = true; bool printAll = true;
bool header = true; bool header = true;
bool disableIRQ = false; bool disableIRQ = false;
// STATE MACHINE // STATE MACHINE
enum states { enum states {
STOP, ONCE, CONT, HELP STOP, ONCE, CONT, HELP
}; };
states state = STOP; states state = STOP;
// TIMING // TIMING
uint32_t startScan; uint32_t startScan;
uint32_t stopScan; uint32_t stopScan;
/////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// //
// MAIN CODE // MAIN CODE
// //
void setup() void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
while (!Serial);
#if defined (ESP8266) || defined(ESP32) #if defined (ESP8266) || defined(ESP32)
uint8_t sda = 14; // 21 uint8_t sda = 14; // 21
uint8_t scl = 15; // 22 uint8_t scl = 15; // 22
Wire.begin(sda, scl, 100000); // ESP32 - change config pins if needed. Wire.begin(sda, scl, 100000); // ESP32 - change config pins if needed.
#else #else
Wire.begin(); Wire.begin();
#endif #endif
@ -97,8 +103,7 @@ void setup()
wire = &Wire; wire = &Wire;
Serial.println(); Serial.println();
setSpeed('9'); reset();
displayHelp();
} }
@ -191,6 +196,10 @@ void loop()
setSpeed(command); setSpeed(command);
break; break;
case 'r':
reset();
break;
case 'a': case 'a':
setAddress(); setAddress();
break; break;
@ -224,6 +233,25 @@ void loop()
} }
} }
//////////////////////////////////////////////////////////////////////
void reset()
{
setSpeed('9');
selectedWirePort = 0;
addressStart = 8;
addressEnd = 119;
delayFlag = false;
printAll = true;
header = true;
disableIRQ = false;
state = STOP;
displayHelp();
}
void setAddress() void setAddress()
{ {
@ -266,11 +294,11 @@ void setSpeed(char sp)
speed[0] = 800; speed[0] = 800;
speeds = 1; speeds = 1;
break; break;
case '9': // limited to 400KHz case '9': // limited to 400 KHz
speeds = 8; speeds = 8;
for (int i = 1; i <= speeds; i++) speed[i - 1] = i * 50; for (int i = 1; i <= speeds; i++) speed[i - 1] = i * 50;
break; break;
case '0': // limited to 800KHz case '0': // limited to 800 KHz
speeds = 8; speeds = 8;
for (int i = 1; i <= speeds; i++) speed[i - 1] = i * 100; for (int i = 1; i <= speeds; i++) speed[i - 1] = i * 100;
break; break;
@ -342,19 +370,20 @@ void displayHelp()
Serial.println(F("\ta = toggle address range, 0..127 - 8..119 (default)")); Serial.println(F("\ta = toggle address range, 0..127 - 8..119 (default)"));
Serial.println(F("Speeds:")); Serial.println(F("Speeds:"));
Serial.println(F("\t0 = 100..800 Khz - step 100 (warning - can block!!)")); Serial.println(F("\t0 = 100..800 KHz - step 100 (warning - can block!!)"));
Serial.println(F("\t1 = 100 KHz")); Serial.println(F("\t1 = 100 KHz"));
Serial.println(F("\t2 = 200 KHz")); Serial.println(F("\t2 = 200 KHz"));
Serial.println(F("\t4 = 400 KHz")); Serial.println(F("\t4 = 400 KHz"));
Serial.println(F("\t9 = 50..400 Khz - step 50 < DEFAULT >")); Serial.println(F("\t9 = 50..400 KHz - step 50 < DEFAULT >"));
Serial.println(); Serial.println();
Serial.println(F("\t!! HIGH SPEEDS - WARNING - can block - not applicable for UNO")); Serial.println(F("\t!! HIGH SPEEDS - WARNING - can block - not applicable for UNO"));
Serial.println(F("\t8 = 800 KHz")); Serial.println(F("\t8 = 800 KHz"));
Serial.println(F("\tM = 1000 KHz")); Serial.println(F("\tM = 1000 KHz"));
Serial.println(F("\tN = 3400 KHz")); Serial.println(F("\tN = 3400 KHz"));
Serial.println(F("\tO = 5000 Khz")); Serial.println(F("\tO = 5000 KHz"));
Serial.println(F("\tP = 100 400 1000 3400 5000 Khz (standards)")); Serial.println(F("\tP = 100 400 1000 3400 5000 KHz (standards)"));
Serial.println(F("\n\t? = help - this page")); Serial.println(F("\n\tr = reset to startup defaults."));
Serial.println(F("\t? = help - this page"));
Serial.println(); Serial.println();
} }
@ -391,7 +420,7 @@ void I2Cscan()
for (uint8_t s = 0; s < speeds ; s++) for (uint8_t s = 0; s < speeds ; s++)
{ {
yield(); // keep ESP happy yield(); // keep ESP happy
#if ARDUINO < 158 && defined (TWBR) #if ARDUINO < 158 && defined (TWBR)
uint16_t PREV_TWBR = TWBR; uint16_t PREV_TWBR = TWBR;
@ -400,7 +429,7 @@ void I2Cscan()
{ {
Serial.println("ERROR: not supported speed"); Serial.println("ERROR: not supported speed");
TWBR = PREV_TWBR; TWBR = PREV_TWBR;
return; return;
} }
#else #else
wire->setClock(speed[s] * 1000UL); wire->setClock(speed[s] * 1000UL);
@ -434,6 +463,26 @@ void I2Cscan()
} }
} }
/*
// FOOTER
if (header)
{
for (uint8_t s = 0; s < speeds + 5; s++)
{
Serial.print(F("--------"));
}
Serial.println();
Serial.print(F("TIME\tDEC\tHEX\t"));
for (uint8_t s = 0; s < speeds; s++)
{
Serial.print(F("\t"));
Serial.print(speed[s]);
}
Serial.println(F("\t[KHz]"));
}
*/
stopScan = millis(); stopScan = millis();
if (header) if (header)
{ {
@ -443,8 +492,10 @@ void I2Cscan()
Serial.print(stopScan - startScan); Serial.print(stopScan - startScan);
Serial.println(F(" milliseconds.")); Serial.println(F(" milliseconds."));
} }
interrupts(); interrupts();
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -1,12 +1,10 @@
// //
// FILE: I2C_bus_counter.ino // FILE: I2C_bus_counter.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: I2C bus counter // PURPOSE: I2C bus counter
// DATE: 2021-11-10 // DATE: 2021-11-10
// URL: https://github.com/RobTillaart/MultiSpeedI2CScanner // URL: https://github.com/RobTillaart/MultiSpeedI2CScanner
// URL: http://forum.arduino.cc/index.php?topic=197360 // URL: http://forum.arduino.cc/index.php?topic=197360
//
#include <Arduino.h> #include <Arduino.h>

View File

@ -1,7 +1,7 @@
// //
// FILE: MultiSpeedI2CScanner.ino // FILE: MultiSpeedI2CScanner.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.1.14 // VERSION: 0.1.16
// PURPOSE: I2C scanner at different speeds // PURPOSE: I2C scanner at different speeds
// DATE: 2013-11-05 // DATE: 2013-11-05
// URL: https://github.com/RobTillaart/MultiSpeedI2CScanner // URL: https://github.com/RobTillaart/MultiSpeedI2CScanner
@ -12,18 +12,22 @@
#include <Arduino.h> #include <Arduino.h>
#include <Wire.h> #include <Wire.h>
// FOR INTERNAL I2C BUS NANO 33 BLE
// #define WIRE_IMPLEMENT_WIRE1 1
// extern TwoWire Wire1;
TwoWire *wire; TwoWire *wire;
const char version[] = "0.1.14"; const char version[] = "0.1.16";
// INTERFACE COUNT (TESTED TEENSY 3.5 AND ARDUINO DUE ONLY) // INTERFACE COUNT (TESTED TEENSY 3.5 AND ARDUINO DUE ONLY)
int wirePortCount = 1; int wirePortCount = 1;
int selectedWirePort = 0; int selectedWirePort = 0;
// scans devices from 50 to 800KHz I2C speeds. // scans devices from 50 to 800 KHz I2C speeds.
// speed lower than 50 and above 400 can cause problems // speed lower than 50 and above 400 can cause problems
long speed[10] = { 100, 200, 300, 400 }; long speed[10] = { 100, 200, 300, 400 };
int speeds; int speeds;
@ -31,44 +35,46 @@ int addressStart = 8;
int addressEnd = 119; int addressEnd = 119;
// DELAY BETWEEN TESTS // DELAY BETWEEN TESTS
// for delay between tests of found devices.
#ifndef RESTORE_LATENCY #ifndef RESTORE_LATENCY
#define RESTORE_LATENCY 5 // for delay between tests of found devices. #define RESTORE_LATENCY 5
#endif #endif
bool delayFlag = false; bool delayFlag = false;
// MINIMIZE OUTPUT // MINIMIZE OUTPUT
bool printAll = true; bool printAll = true;
bool header = true; bool header = true;
bool disableIRQ = false; bool disableIRQ = false;
// STATE MACHINE // STATE MACHINE
enum states { enum states {
STOP, ONCE, CONT, HELP STOP, ONCE, CONT, HELP
}; };
states state = STOP; states state = STOP;
// TIMING // TIMING
uint32_t startScan; uint32_t startScan;
uint32_t stopScan; uint32_t stopScan;
/////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// //
// MAIN CODE // MAIN CODE
// //
void setup() void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
while (!Serial);
#if defined (ESP8266) || defined(ESP32) #if defined (ESP8266) || defined(ESP32)
uint8_t sda = 14; // 21 uint8_t sda = 14; // 21
uint8_t scl = 15; // 22 uint8_t scl = 15; // 22
Wire.begin(sda, scl, 100000); // ESP32 - change config pins if needed. Wire.begin(sda, scl, 100000); // ESP32 - change config pins if needed.
#else #else
Wire.begin(); Wire.begin();
#endif #endif
@ -97,8 +103,7 @@ void setup()
wire = &Wire; wire = &Wire;
Serial.println(); Serial.println();
setSpeed('9'); reset();
displayHelp();
} }
@ -191,6 +196,10 @@ void loop()
setSpeed(command); setSpeed(command);
break; break;
case 'r':
reset();
break;
case 'a': case 'a':
setAddress(); setAddress();
break; break;
@ -224,6 +233,25 @@ void loop()
} }
} }
//////////////////////////////////////////////////////////////////////
void reset()
{
setSpeed('9');
selectedWirePort = 0;
addressStart = 8;
addressEnd = 119;
delayFlag = false;
printAll = true;
header = true;
disableIRQ = false;
state = STOP;
displayHelp();
}
void setAddress() void setAddress()
{ {
@ -266,11 +294,11 @@ void setSpeed(char sp)
speed[0] = 800; speed[0] = 800;
speeds = 1; speeds = 1;
break; break;
case '9': // limited to 400KHz case '9': // limited to 400 KHz
speeds = 8; speeds = 8;
for (int i = 1; i <= speeds; i++) speed[i - 1] = i * 50; for (int i = 1; i <= speeds; i++) speed[i - 1] = i * 50;
break; break;
case '0': // limited to 800KHz case '0': // limited to 800 KHz
speeds = 8; speeds = 8;
for (int i = 1; i <= speeds; i++) speed[i - 1] = i * 100; for (int i = 1; i <= speeds; i++) speed[i - 1] = i * 100;
break; break;
@ -342,19 +370,20 @@ void displayHelp()
Serial.println(F("\ta = toggle address range, 0..127 - 8..119 (default)")); Serial.println(F("\ta = toggle address range, 0..127 - 8..119 (default)"));
Serial.println(F("Speeds:")); Serial.println(F("Speeds:"));
Serial.println(F("\t0 = 100..800 Khz - step 100 (warning - can block!!)")); Serial.println(F("\t0 = 100..800 KHz - step 100 (warning - can block!!)"));
Serial.println(F("\t1 = 100 KHz")); Serial.println(F("\t1 = 100 KHz"));
Serial.println(F("\t2 = 200 KHz")); Serial.println(F("\t2 = 200 KHz"));
Serial.println(F("\t4 = 400 KHz")); Serial.println(F("\t4 = 400 KHz"));
Serial.println(F("\t9 = 50..400 Khz - step 50 < DEFAULT >")); Serial.println(F("\t9 = 50..400 KHz - step 50 < DEFAULT >"));
Serial.println(); Serial.println();
Serial.println(F("\t!! HIGH SPEEDS - WARNING - can block - not applicable for UNO")); Serial.println(F("\t!! HIGH SPEEDS - WARNING - can block - not applicable for UNO"));
Serial.println(F("\t8 = 800 KHz")); Serial.println(F("\t8 = 800 KHz"));
Serial.println(F("\tM = 1000 KHz")); Serial.println(F("\tM = 1000 KHz"));
Serial.println(F("\tN = 3400 KHz")); Serial.println(F("\tN = 3400 KHz"));
Serial.println(F("\tO = 5000 Khz")); Serial.println(F("\tO = 5000 KHz"));
Serial.println(F("\tP = 100 400 1000 3400 5000 Khz (standards)")); Serial.println(F("\tP = 100 400 1000 3400 5000 KHz (standards)"));
Serial.println(F("\n\t? = help - this page")); Serial.println(F("\n\tr = reset to startup defaults."));
Serial.println(F("\t? = help - this page"));
Serial.println(); Serial.println();
} }
@ -391,7 +420,7 @@ void I2Cscan()
for (uint8_t s = 0; s < speeds ; s++) for (uint8_t s = 0; s < speeds ; s++)
{ {
yield(); // keep ESP happy yield(); // keep ESP happy
#if ARDUINO < 158 && defined (TWBR) #if ARDUINO < 158 && defined (TWBR)
uint16_t PREV_TWBR = TWBR; uint16_t PREV_TWBR = TWBR;
@ -400,7 +429,7 @@ void I2Cscan()
{ {
Serial.println("ERROR: not supported speed"); Serial.println("ERROR: not supported speed");
TWBR = PREV_TWBR; TWBR = PREV_TWBR;
return; return;
} }
#else #else
wire->setClock(speed[s] * 1000UL); wire->setClock(speed[s] * 1000UL);
@ -434,6 +463,26 @@ void I2Cscan()
} }
} }
/*
// FOOTER
if (header)
{
for (uint8_t s = 0; s < speeds + 5; s++)
{
Serial.print(F("--------"));
}
Serial.println();
Serial.print(F("TIME\tDEC\tHEX\t"));
for (uint8_t s = 0; s < speeds; s++)
{
Serial.print(F("\t"));
Serial.print(speed[s]);
}
Serial.println(F("\t[KHz]"));
}
*/
stopScan = millis(); stopScan = millis();
if (header) if (header)
{ {
@ -443,8 +492,10 @@ void I2Cscan()
Serial.print(stopScan - startScan); Serial.print(stopScan - startScan);
Serial.println(F(" milliseconds.")); Serial.println(F(" milliseconds."));
} }
interrupts(); interrupts();
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -6,5 +6,5 @@ It is placed here to give Arduino-CI something to compile.
On the long term an I2C scanner class should be made which On the long term an I2C scanner class should be made which
will have this application as an example. will have this application as an example.
As teh application os working rather well this has no urgency As the application is working rather well this has no urgency
or priority. or priority.

View File

@ -9,7 +9,7 @@
# Arduino MultiSpeed I2C Scanner # Arduino MultiSpeed I2C Scanner
## Version: 0.1.14 ## Version: 0.1.16
## Description ## Description
@ -21,13 +21,18 @@ The scanner provides an overview of which addresses can be found
at which speed. This allows one to optimize the I2C performance of at which speed. This allows one to optimize the I2C performance of
many devices above the standard 100KHz speed. many devices above the standard 100KHz speed.
#### Related
build your own I2C scanner with:
- https://github.com/RobTillaart/I2C_SCANNER
## Menu dialog ## Menu dialog
``` ```
<speeds = 50 100 150 200 250 300 350 400 > <speeds = 50 100 150 200 250 300 350 400 >
Arduino MultiSpeed I2C Scanner - 0.1.13 Arduino MultiSpeed I2C Scanner - 0.1.15
I2C ports: 1 Current: Wire0 I2C ports: 1 Current: Wire0
@ = toggle Wire - Wire1 - Wire2 [TEENSY 3.5 or Arduino Due] @ = toggle Wire - Wire1 - Wire2 [TEENSY 3.5 or Arduino Due]
@ -42,19 +47,20 @@ Output:
h = toggle header - noHeader. h = toggle header - noHeader.
a = toggle address range, 0..127 - 8..119 (default) a = toggle address range, 0..127 - 8..119 (default)
Speeds: Speeds:
0 = 100..800 Khz - step 100 (warning - can block!!) 0 = 100..800 KHz - step 100 (warning - can block!!)
1 = 100 KHz 1 = 100 KHz
2 = 200 KHz 2 = 200 KHz
4 = 400 KHz 4 = 400 KHz
9 = 50..400 Khz - step 50 < DEFAULT > 9 = 50..400 KHz - step 50 < DEFAULT >
!! HIGH SPEEDS - WARNING - can block - not applicable for UNO !! HIGH SPEEDS - WARNING - can block - not applicable for UNO
8 = 800 KHz 8 = 800 KHz
M = 1000 KHz M = 1000 KHz
N = 3400 KHz N = 3400 KHz
O = 5000 Khz O = 5000 KHz
P = 100 400 1000 3400 5000 Khz (standards) P = 100 400 1000 3400 5000 KHz (standards)
r = reset to startup defaults.
? = help - this page ? = help - this page
``` ```
@ -108,7 +114,14 @@ Check your datasheet to see which speeds are applicable for the processor in use
## Future ## Future
#### Must
#### Should
#### Could
- add watchdog reset (at least AVR - 8 seconds 0.2.0 ) - add watchdog reset (at least AVR - 8 seconds 0.2.0 )
- create an I2Scanner class
- r = reset (defaults)
- non-AVR command behind a ```#ifdef``` ? - non-AVR command behind a ```#ifdef``` ?
- rename releaseNotes.md to changelog.md (in line with libraries)
- I2C GENERIC RESET address 0x00 CMD 0x06

View File

@ -8,12 +8,24 @@ https://github.com/RobTillaart/MultiSpeedI2CScanner
## Version ## Version
0.1.14 0.1.16
### 0.1.16 2023-01-20
- update build-ci
- add link to I2C scanner class in readme.md
### 0.1.15 2021-12-22
- change Khz =>KHz
- update license
### 0.1.14 2021-11-10 ### 0.1.14 2021-11-10
- update Arduino-CI buid process - update Arduino-CI build process
- add badges to readme.md - add badges to readme.md
- updated readme.md - updated readme.md
- support up to 5 Wire buses - support up to 5 Wire buses
@ -35,9 +47,9 @@ https://github.com/RobTillaart/MultiSpeedI2CScanner
### 0.1.11 2018-07-20 ### 0.1.11 2018-07-20
- Fix failing TWBR setting - Fix failing TWBR setting
- added yield() during scan to improve ESP behavior. - added yield() during scan to improve ESP behaviour.
- added disable interrupts flag - added disable interrupts flag
- refactor / cleanup - refactor / clean up
### 0.1.10 2018-04-02 ### 0.1.10 2018-04-02
@ -76,6 +88,8 @@ note the latter one must adjust the pins in the code.
- extended help - extended help
### older versions not documented ### older versions not documented
(started 2013-11-05 ?)
// END OF FILE // -- END OF FILE --

View File

@ -32,15 +32,19 @@ unittest_setup()
{ {
} }
unittest_teardown() unittest_teardown()
{ {
} }
unittest(test_constructor) unittest(test_constructor)
{ {
assertEqual(1, 1); assertEqual(1, 1);
} }
unittest_main() unittest_main()
// -------- // --------