@@ -60,14 +60,53 @@ class ModulinoClass {
6060 friend class Module ;
6161protected:
6262 HardwareI2C* _wire;
63+ friend class ModulinoHub ;
64+ friend class ModulinoHubPort ;
6365};
6466
6567extern ModulinoClass Modulino;
6668
69+ // Forward declaration of ModulinoHub
70+ class ModulinoHub ;
71+
72+ class ModulinoHubPort {
73+ public:
74+ ModulinoHubPort (int port, ModulinoHub* hub) : _port(port), _hub(hub) {}
75+ int select ();
76+ int clear ();
77+ private:
78+ int _port;
79+ ModulinoHub* _hub;
80+ };
81+
82+ class ModulinoHub {
83+ public:
84+ ModulinoHub (int address = 0x70 ) : _address(address){ }
85+ ModulinoHubPort* port (int _port) {
86+ return new ModulinoHubPort (_port, this );
87+ }
88+ int select (int port) {
89+ Modulino._wire ->beginTransmission (_address);
90+ Modulino._wire ->write (1 << port);
91+ return Modulino._wire ->endTransmission ();
92+ }
93+ int clear () {
94+ Modulino._wire ->beginTransmission (_address);
95+ Modulino._wire ->write ((uint8_t )0 );
96+ return Modulino._wire ->endTransmission ();
97+ }
98+
99+ int address () {
100+ return _address;
101+ }
102+ private:
103+ int _address;
104+ };
105+
67106class Module : public Printable {
68107public:
69- Module (uint8_t address = 0xFF , const char * name = " " )
70- : address(address), name((char *)name) {}
108+ Module (uint8_t address = 0xFF , const char * name = " " , ModulinoHubPort* hubPort = nullptr )
109+ : address(address), name((char *)name), hubPort(hubPort) {}
71110 virtual ~Module () {}
72111 bool begin () {
73112 if (address >= 0x7F ) {
@@ -88,6 +127,9 @@ class Module : public Printable {
88127 if (address >= 0x7F ) {
89128 return false ;
90129 }
130+ if (hubPort != nullptr ) {
131+ hubPort->select ();
132+ }
91133 Modulino._wire ->requestFrom (address, howmany + 1 );
92134 auto start = millis ();
93135 while ((Modulino._wire ->available () == 0 ) && (millis () - start < 100 )) {
@@ -103,17 +145,26 @@ class Module : public Printable {
103145 while (Modulino._wire ->available ()) {
104146 Modulino._wire ->read ();
105147 }
148+ if (hubPort != nullptr ) {
149+ hubPort->clear ();
150+ }
106151 return true ;
107152 }
108153 bool write (uint8_t * buf, int howmany) {
109154 if (address >= 0x7F ) {
110155 return false ;
111156 }
157+ if (hubPort != nullptr ) {
158+ hubPort->select ();
159+ }
112160 Modulino._wire ->beginTransmission (address);
113161 for (int i = 0 ; i < howmany; i++) {
114162 Modulino._wire ->write (buf[i]);
115163 }
116164 Modulino._wire ->endTransmission ();
165+ if (hubPort != nullptr ) {
166+ hubPort->clear ();
167+ }
117168 return true ;
118169 }
119170 bool nonDefaultAddress () {
@@ -123,8 +174,14 @@ class Module : public Printable {
123174 return p.print (name);
124175 }
125176 bool scan (uint8_t addr) {
177+ if (hubPort != nullptr ) {
178+ hubPort->select ();
179+ }
126180 Modulino._wire ->beginTransmission (addr / 2 ); // multply by 2 to match address in fw main.c
127181 auto ret = Modulino._wire ->endTransmission ();
182+ if (hubPort != nullptr ) {
183+ hubPort->clear ();
184+ }
128185 if (ret == 0 ) {
129186 // could also ask for 1 byte and check if it's truely a modulino of that kind
130187 return true ;
@@ -135,12 +192,15 @@ class Module : public Printable {
135192 uint8_t address;
136193 uint8_t pinstrap_address;
137194 char * name;
195+ ModulinoHubPort* hubPort = nullptr ;
138196};
139197
140198class ModulinoButtons : public Module {
141199public:
142- ModulinoButtons (uint8_t address = 0xFF )
143- : Module(address, " BUTTONS" ) {}
200+ ModulinoButtons (uint8_t address = 0xFF , ModulinoHubPort* hubPort = nullptr )
201+ : Module(address, " BUTTONS" , hubPort) {}
202+ ModulinoButtons (ModulinoHubPort* hubPort, uint8_t address = 0xFF )
203+ : Module(address, " BUTTONS" , hubPort) {}
144204 PinStatus isPressed (int index) {
145205 return last_status[index] ? HIGH : LOW;
146206 }
@@ -196,8 +256,10 @@ class ModulinoButtons : public Module {
196256
197257class ModulinoJoystick : public Module {
198258public:
199- ModulinoJoystick (uint8_t address = 0xFF )
200- : Module(address, " JOYSTICK" ) {}
259+ ModulinoJoystick (uint8_t address = 0xFF , ModulinoHubPort* hubPort = nullptr )
260+ : Module(address, " JOYSTICK" , hubPort) {}
261+ ModulinoJoystick (ModulinoHubPort* hubPort, uint8_t address = 0xFF )
262+ : Module(address, " JOYSTICK" , hubPort) {}
201263 bool update () {
202264 uint8_t buf[3 ];
203265 auto res = read ((uint8_t *)buf, 3 );
@@ -248,8 +310,10 @@ class ModulinoJoystick : public Module {
248310
249311class ModulinoBuzzer : public Module {
250312public:
251- ModulinoBuzzer (uint8_t address = 0xFF )
252- : Module(address, " BUZZER" ) {}
313+ ModulinoBuzzer (uint8_t address = 0xFF , ModulinoHubPort* hubPort = nullptr )
314+ : Module(address, " BUZZER" , hubPort) {}
315+ ModulinoBuzzer (ModulinoHubPort* hubPort, uint8_t address = 0xFF )
316+ : Module(address, " BUZZER" , hubPort) {}
253317 void (tone)(size_t freq, size_t len_ms) {
254318 uint8_t buf[8 ];
255319 memcpy (&buf[0 ], &freq, 4 );
@@ -275,8 +339,10 @@ class ModulinoBuzzer : public Module {
275339
276340class ModulinoVibro : public Module {
277341public:
278- ModulinoVibro (uint8_t address = 0xFF )
279- : Module(address, " VIBRO" ) {}
342+ ModulinoVibro (uint8_t address = 0xFF , ModulinoHubPort* hubPort = nullptr )
343+ : Module(address, " VIBRO" , hubPort) {}
344+ ModulinoVibro (ModulinoHubPort* hubPort, uint8_t address = 0xFF )
345+ : Module(address, " VIBRO" , hubPort) {}
280346 void on (size_t len_ms, bool block, int power = MAXIMUM ) {
281347 uint8_t buf[12 ];
282348 uint32_t freq = 1000 ;
@@ -326,8 +392,12 @@ class ModulinoColor {
326392
327393class ModulinoPixels : public Module {
328394public:
329- ModulinoPixels (uint8_t address = 0xFF )
330- : Module(address, " LEDS" ) {
395+ ModulinoPixels (uint8_t address = 0xFF , ModulinoHubPort* hubPort = nullptr )
396+ : Module(address, " LEDS" , hubPort) {
397+ memset ((uint8_t *)data, 0xE0 , NUMLEDS * 4 );
398+ }
399+ ModulinoPixels (ModulinoHubPort* hubPort, uint8_t address = 0xFF )
400+ : Module(address, " LEDS" , hubPort) {
331401 memset ((uint8_t *)data, 0xE0 , NUMLEDS * 4 );
332402 }
333403 void set (int idx, ModulinoColor rgb, uint8_t brightness = 25 ) {
@@ -366,9 +436,11 @@ class ModulinoPixels : public Module {
366436
367437class ModulinoKnob : public Module {
368438public:
369- ModulinoKnob (uint8_t address = 0xFF )
370- : Module(address, " ENCODER" ) {}
371- bool begin () {
439+ ModulinoKnob (uint8_t address = 0xFF , ModulinoHubPort* hubPort = nullptr )
440+ : Module(address, " ENCODER" , hubPort) {}
441+ ModulinoKnob (ModulinoHubPort* hubPort, uint8_t address = 0xFF )
442+ : Module(address, " ENCODER" , hubPort) {}
443+ bool begin () {
372444 auto ret = Module::begin ();
373445 if (ret) {
374446 auto _val = get ();
@@ -453,6 +525,8 @@ extern ModulinoColor WHITE;
453525
454526class ModulinoMovement : public Module {
455527public:
528+ ModulinoMovement (ModulinoHubPort* hubPort = nullptr )
529+ : Module(0xFF , " MOVEMENT" , hubPort) {}
456530 bool begin () {
457531 if (_imu == nullptr ) {
458532 _imu = new LSM6DSOXClass (*((TwoWire*)getWire ()), 0x6A );
@@ -505,6 +579,8 @@ class ModulinoMovement : public Module {
505579
506580class ModulinoThermo : public Module {
507581public:
582+ ModulinoThermo (ModulinoHubPort* hubPort = nullptr )
583+ : Module(0xFF , " THERMO" , hubPort) {}
508584 bool begin () {
509585 if (_sensor == nullptr ) {
510586 _sensor = new HS300xClass (*((TwoWire*)getWire ()));
@@ -535,6 +611,8 @@ class ModulinoThermo: public Module {
535611
536612class ModulinoPressure : public Module {
537613public:
614+ ModulinoPressure (ModulinoHubPort* hubPort = nullptr )
615+ : Module(0xFF , " PRESSURE" , hubPort) {}
538616 bool begin () {
539617 if (_barometer == nullptr ) {
540618 _barometer = new LPS22HBClass (*((TwoWire*)getWire ()));
@@ -569,6 +647,8 @@ class ModulinoPressure : public Module {
569647
570648class ModulinoLight : public Module {
571649public:
650+ ModulinoLight (ModulinoHubPort* hubPort = nullptr )
651+ : Module(0xFF , " LIGHT" , hubPort) {}
572652 bool begin () {
573653 if (_light == nullptr ) {
574654 _light = new LTR381RGBClass (*((TwoWire*)getWire ()), 0x53 );
@@ -723,6 +803,8 @@ class _distance_api {
723803
724804class ModulinoDistance : public Module {
725805public:
806+ ModulinoDistance (ModulinoHubPort* hubPort = nullptr )
807+ : Module(0xFF , " DISTANCE" , hubPort) {}
726808 bool begin () {
727809 // try scanning for 0x29 since the library contains a while(true) on begin()
728810 getWire ()->beginTransmission (0x29 );
@@ -787,8 +869,10 @@ class ModulinoDistance : public Module {
787869
788870class ModulinoOptoRelay : public Module {
789871public:
790- ModulinoOptoRelay (uint8_t address = 0xFF )
791- : Module(address, " OPTO_RELAY" ) {}
872+ ModulinoOptoRelay (uint8_t address = 0xFF , ModulinoHubPort* hubPort = nullptr )
873+ : Module(address, " OPTO_RELAY" , hubPort) {}
874+ ModulinoOptoRelay (ModulinoHubPort* hubPort, uint8_t address = 0xFF )
875+ : Module(address, " OPTO_RELAY" , hubPort) {}
792876 bool update () {
793877 uint8_t buf[3 ];
794878 auto res = read ((uint8_t *)buf, 3 );
@@ -834,8 +918,10 @@ class ModulinoOptoRelay : public Module {
834918
835919class ModulinoLatchRelay : public Module {
836920public:
837- ModulinoLatchRelay (uint8_t address = 0xFF )
838- : Module(address, " REL" ) {}
921+ ModulinoLatchRelay (uint8_t address = 0xFF , ModulinoHubPort* hubPort = nullptr )
922+ : Module(address, " LATCH_RELAY" , hubPort) {}
923+ ModulinoLatchRelay (ModulinoHubPort* hubPort, uint8_t address = 0xFF )
924+ : Module(address, " LATCH_RELAY" , hubPort) {}
839925 bool update () {
840926 uint8_t buf[3 ];
841927 auto res = read ((uint8_t *)buf, 3 );
0 commit comments