Skip to content

Commit c8a4de7

Browse files
authored
Merge pull request #189 from adafruit/i2c-encode-publish
Full I2C support for AHT20
2 parents e050543 + 99c1b5c commit c8a4de7

20 files changed

+2247
-473
lines changed

library.properties

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
name=Adafruit WipperSnapper Beta
2-
version=1.0.0-beta.13
2+
version=1.0.0-beta.16
33
author=Adafruit
44
maintainer=Adafruit <[email protected]>
5-
sentence=Arduino library for Adafruit.io WipperSnapper
6-
paragraph=Arduino library for Adafruit.io WipperSnapper
5+
sentence=Arduino client for Adafruit.io WipperSnapper
6+
paragraph=Arduino client for Adafruit.io WipperSnapper
77
category=Communication
88
url=https://github.com/adafruit/Adafruit_IO_Arduino
99
architectures=*
10-
depends=Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit SleepyDog Library, Adafruit TinyUSB Library, Adafruit AHTX0
10+
depends=Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit SleepyDog Library, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit DPS310, Adafruit SCD30, Sensirion I2C SCD4x

src/Wippersnapper.cpp

Lines changed: 107 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -535,45 +535,8 @@ bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field,
535535
// Create I2C Response
536536
wippersnapper_signal_v1_I2CResponse msgi2cResponse =
537537
wippersnapper_signal_v1_I2CResponse_init_zero;
538-
if (field->tag == wippersnapper_signal_v1_I2CRequest_req_i2c_init_tag) {
539-
WS_DEBUG_PRINTLN("I2C Init Request Found!");
540-
// Decode I2CBusInitRequest
541-
wippersnapper_i2c_v1_I2CBusInitRequest msgI2CBusInitRequest =
542-
wippersnapper_i2c_v1_I2CBusInitRequest_init_zero;
543-
if (!pb_decode(stream, wippersnapper_i2c_v1_I2CBusInitRequest_fields,
544-
&msgI2CBusInitRequest)) {
545-
WS_DEBUG_PRINTLN(
546-
"ERROR: Could not decode wippersnapper_i2c_v1_I2CBusInitRequest");
547-
return false; // fail out
548-
}
549538

550-
// Create a new I2C Component
551-
if (msgI2CBusInitRequest.i2c_port_number == 0) {
552-
WS._i2cPort0 = new WipperSnapper_Component_I2C(&msgI2CBusInitRequest);
553-
WS.i2cComponents.push_back(WS._i2cPort0);
554-
// did we init. the port successfully?
555-
is_success = WS._i2cPort0->isInitialized();
556-
} else if (msgI2CBusInitRequest.i2c_port_number == 1) {
557-
WS._i2cPort1 = new WipperSnapper_Component_I2C(&msgI2CBusInitRequest);
558-
// did we init. the port successfully?
559-
is_success = WS._i2cPort1->isInitialized();
560-
WS.i2cComponents.push_back(WS._i2cPort1);
561-
} else {
562-
WS_DEBUG_PRINTLN("ERROR: Both I2C ports are in-use");
563-
is_success = false;
564-
}
565-
566-
// Fill I2CResponse
567-
msgi2cResponse.which_payload =
568-
wippersnapper_signal_v1_I2CRequest_req_i2c_init_tag;
569-
msgi2cResponse.payload.resp_i2c_init.is_initialized = is_success;
570-
571-
// Encode I2CResponse
572-
if (!encodeI2CResponse(&msgi2cResponse)) {
573-
return false;
574-
}
575-
} else if (field->tag ==
576-
wippersnapper_signal_v1_I2CRequest_req_i2c_scan_tag) {
539+
if (field->tag == wippersnapper_signal_v1_I2CRequest_req_i2c_scan_tag) {
577540
WS_DEBUG_PRINTLN("I2C Scan Request");
578541

579542
// Decode I2CBusScanRequest
@@ -586,24 +549,32 @@ bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field,
586549
return false; // fail out if we can't decode the request
587550
}
588551

589-
// Check if I2C components were previously initialized
590-
if (!WS._i2cPort0->isInitialized() && !WS._i2cPort0->isInitialized()) {
591-
WS_DEBUG_PRINTLN(
592-
"ERROR: I2C Ports were not initialized prior to scanning!");
593-
return false;
594-
}
595-
596-
// Perform I2C scan
552+
// Empty response message
597553
wippersnapper_i2c_v1_I2CBusScanResponse scanResp =
598554
wippersnapper_i2c_v1_I2CBusScanResponse_init_zero;
599-
if (msgScanReq.i2c_port_number == 0) {
600-
scanResp = WS._i2cPort0->scanAddresses();
601-
} else {
602-
scanResp = WS._i2cPort1->scanAddresses();
555+
556+
// Has the I2C bus been initialized?
557+
if (!WS._isI2CPort0Init) {
558+
WS._i2cPort0 =
559+
new WipperSnapper_Component_I2C(&msgScanReq.bus_init_request);
560+
WS.i2cComponents.push_back(WS._i2cPort0);
561+
WS._isI2CPort0Init = WS._i2cPort0->isInitialized();
562+
msgi2cResponse.payload.resp_i2c_init.bus_response =
563+
WS._i2cPort0->getBusStatus();
564+
// Fail out and publish back if not RESPONSE_SUCCESS
565+
if (msgi2cResponse.payload.resp_i2c_init.bus_response !=
566+
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS) {
567+
if (!encodeI2CResponse(&msgi2cResponse)) {
568+
WS_DEBUG_PRINTLN("ERROR: encoding I2C Response!");
569+
return false;
570+
}
571+
publishI2CResponse(&msgi2cResponse);
572+
}
603573
}
604-
WS_DEBUG_PRINTLN("Scan Complete!");
605-
WS_DEBUG_PRINT("\t# of addresses found on bus: ");
606-
WS_DEBUG_PRINTLN(scanResp.addresses_found_count);
574+
575+
// Execute I2C Scan
576+
if (WS._isI2CPort0Init == true)
577+
scanResp = WS._i2cPort0->scanAddresses();
607578

608579
// Fill I2CResponse
609580
msgi2cResponse.which_payload =
@@ -612,6 +583,8 @@ bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field,
612583
scanResp.addresses_found, sizeof(scanResp.addresses_found));
613584
msgi2cResponse.payload.resp_i2c_scan.addresses_found_count =
614585
scanResp.addresses_found_count;
586+
587+
msgi2cResponse.payload.resp_i2c_scan.bus_response = scanResp.bus_response;
615588
// Encode I2CResponse
616589
if (!encodeI2CResponse(&msgi2cResponse)) {
617590
return false;
@@ -629,30 +602,83 @@ bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field,
629602
return false; // fail out if we can't decode
630603
}
631604

632-
// Create response
605+
// Create empty response
633606
msgi2cResponse = wippersnapper_signal_v1_I2CResponse_init_zero;
634607
msgi2cResponse.which_payload =
635608
wippersnapper_signal_v1_I2CResponse_resp_i2c_device_init_tag;
636609

637-
// Initialize device and fill response
638-
if (msgI2CDeviceInitRequest.i2c_port_number == 0 &&
639-
WS._i2cPort0->isInitialized() == true) {
610+
// Has the I2C bus been initialized?
611+
if (!WS._isI2CPort0Init) {
612+
WS._i2cPort0 = new WipperSnapper_Component_I2C(
613+
&msgI2CDeviceInitRequest.bus_init_request);
614+
WS.i2cComponents.push_back(WS._i2cPort0);
615+
WS._isI2CPort0Init = WS._i2cPort0->isInitialized();
616+
msgi2cResponse.payload.resp_i2c_init.bus_response =
617+
WS._i2cPort0->getBusStatus();
618+
// Fail out and publish back if not RESPONSE_SUCCESS
619+
if (msgi2cResponse.payload.resp_i2c_init.bus_response !=
620+
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS) {
621+
if (!encodeI2CResponse(&msgi2cResponse)) {
622+
WS_DEBUG_PRINTLN("ERROR: encoding I2C Response!");
623+
return false;
624+
}
625+
publishI2CResponse(&msgi2cResponse);
626+
}
627+
}
628+
629+
// Initialize I2C device
630+
if (WS._isI2CPort0Init == true)
640631
msgi2cResponse.payload.resp_i2c_device_init.is_success =
641632
WS._i2cPort0->initI2CDevice(&msgI2CDeviceInitRequest);
642-
} else if (msgI2CDeviceInitRequest.i2c_port_number == 1 &&
643-
WS._i2cPort1->isInitialized() == true) {
644-
msgi2cResponse.payload.resp_i2c_device_init.is_success =
645-
WS._i2cPort1->initI2CDevice(&msgI2CDeviceInitRequest);
646-
}
633+
634+
// Fill device's address
635+
msgi2cResponse.payload.resp_i2c_device_init.i2c_address =
636+
msgI2CDeviceInitRequest.i2c_address;
637+
638+
msgi2cResponse.payload.resp_i2c_device_init.bus_response =
639+
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS;
647640

648641
// Encode response
649642
if (!encodeI2CResponse(&msgi2cResponse)) {
650643
return false;
651644
}
645+
} else if (field->tag ==
646+
wippersnapper_signal_v1_I2CRequest_req_i2c_device_update_tag) {
647+
WS_DEBUG_PRINTLN("=> INCOMING REQUEST: I2CDeviceUpdateRequest");
652648

649+
// New I2CDeviceUpdateRequest message
650+
wippersnapper_i2c_v1_I2CDeviceUpdateRequest msgI2CDeviceUpdateRequest =
651+
wippersnapper_i2c_v1_I2CDeviceUpdateRequest_init_zero;
652+
653+
// Decode stream into message
654+
if (!pb_decode(stream, wippersnapper_i2c_v1_I2CDeviceUpdateRequest_fields,
655+
&msgI2CDeviceUpdateRequest)) {
656+
WS_DEBUG_PRINTLN(
657+
"ERROR: Could not decode I2CDeviceUpdateRequest message.");
658+
return false; // fail out if we can't decode
659+
}
660+
661+
// Empty I2C response to fill out
662+
msgi2cResponse = wippersnapper_signal_v1_I2CResponse_init_zero;
663+
msgi2cResponse.which_payload =
664+
wippersnapper_signal_v1_I2CResponse_resp_i2c_device_update_tag;
665+
666+
// Update I2C device
667+
if (WS._isI2CPort0Init == true)
668+
msgi2cResponse.payload.resp_i2c_device_update.is_success =
669+
WS._i2cPort0->updateI2CDeviceProperties(&msgI2CDeviceUpdateRequest);
670+
671+
// Fill address
672+
msgi2cResponse.payload.resp_i2c_device_update.i2c_address =
673+
msgI2CDeviceUpdateRequest.i2c_address;
674+
675+
// Encode response
676+
if (!encodeI2CResponse(&msgi2cResponse)) {
677+
return false;
678+
}
653679
} else if (field->tag ==
654680
wippersnapper_signal_v1_I2CRequest_req_i2c_device_deinit_tag) {
655-
WS_DEBUG_PRINTLN("NEW COMMAND: I2C Device De-init");
681+
WS_DEBUG_PRINTLN("NEW COMMAND: I2C Device Deinit");
656682
// Decode stream into an I2CDeviceDeinitRequest
657683
wippersnapper_i2c_v1_I2CDeviceDeinitRequest msgI2CDeviceDeinitRequest =
658684
wippersnapper_i2c_v1_I2CDeviceDeinitRequest_init_zero;
@@ -670,11 +696,9 @@ bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field,
670696
wippersnapper_signal_v1_I2CResponse_resp_i2c_device_deinit_tag;
671697

672698
// Delete device from I2C bus
673-
if (msgI2CDeviceDeinitRequest.i2c_port_number == 0 &&
674-
WS._i2cPort0->isInitialized() == true) {
699+
if (WS._isI2CPort0Init == true)
675700
msgi2cResponse.payload.resp_i2c_device_deinit.is_success =
676701
WS._i2cPort0->deinitI2CDevice(&msgI2CDeviceDeinitRequest);
677-
}
678702

679703
// Encode response
680704
if (!encodeI2CResponse(&msgi2cResponse)) {
@@ -684,6 +708,7 @@ bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field,
684708
WS_DEBUG_PRINTLN("ERROR: Undefined I2C message tag");
685709
return false; // fail out, we didn't encode anything to publish
686710
}
711+
// Publish the I2CResponse
687712
publishI2CResponse(&msgi2cResponse);
688713
return is_success;
689714
}
@@ -1305,14 +1330,14 @@ bool Wippersnapper::registerBoard() {
13051330

13061331
// Encode and publish registration request message to broker
13071332
runNetFSM();
1308-
feedWDT();
1333+
WS.feedWDT();
13091334
WS_DEBUG_PRINT("Encoding registration request...");
13101335
if (!encodePubRegistrationReq())
13111336
return false;
13121337

13131338
// Blocking, attempt to obtain broker's response message
13141339
runNetFSM();
1315-
feedWDT();
1340+
WS.feedWDT();
13161341
pollRegistrationResp();
13171342

13181343
return true;
@@ -1368,6 +1393,7 @@ void Wippersnapper::feedWDT() {
13681393
/*******************************************************/
13691394
void Wippersnapper::enableWDT(int timeoutMS) {
13701395
#ifndef ESP8266
1396+
Watchdog.disable();
13711397
if (Watchdog.enable(timeoutMS) == 0) {
13721398
WS_DEBUG_PRINTLN("ERROR: WDT initialization failure!");
13731399
setStatusLEDColor(LED_ERROR);
@@ -1388,7 +1414,7 @@ void Wippersnapper::enableWDT(int timeoutMS) {
13881414
void Wippersnapper::processPackets() {
13891415
// runNetFSM(); // NOTE: Removed for now, causes error with virtual _connect
13901416
// method when caused with WS object in another file.
1391-
feedWDT();
1417+
WS.feedWDT();
13921418
// Process all incoming packets from Wippersnapper MQTT Broker
13931419
WS._mqtt->processPackets(10);
13941420
}
@@ -1411,7 +1437,7 @@ void Wippersnapper::publish(const char *topic, uint8_t *payload, uint16_t bLen,
14111437
uint8_t qos) {
14121438
// runNetFSM(); // NOTE: Removed for now, causes error with virtual _connect
14131439
// method when caused with WS object in another file.
1414-
feedWDT();
1440+
WS.feedWDT();
14151441
WS._mqtt->publish(topic, payload, bLen, qos);
14161442
}
14171443

@@ -1425,7 +1451,7 @@ void Wippersnapper::publish(const char *topic, uint8_t *payload, uint16_t bLen,
14251451
/**************************************************************************/
14261452
void Wippersnapper::connect(bool useStagingBroker) {
14271453
// enable WDT
1428-
enableWDT(WS_WDT_TIMEOUT);
1454+
WS.enableWDT(WS_WDT_TIMEOUT);
14291455

14301456
// TODO!
14311457
// not sure we need to track these...
@@ -1445,7 +1471,7 @@ void Wippersnapper::connect(bool useStagingBroker) {
14451471

14461472
// Run the network fsm
14471473
runNetFSM();
1448-
feedWDT();
1474+
WS.feedWDT();
14491475
setStatusLEDColor(LED_CONNECTED);
14501476

14511477
// Register hardware with Wippersnapper
@@ -1455,7 +1481,7 @@ void Wippersnapper::connect(bool useStagingBroker) {
14551481
haltError("Unable to register with WipperSnapper.");
14561482
}
14571483
runNetFSM();
1458-
feedWDT();
1484+
WS.feedWDT();
14591485

14601486
// Configure hardware
14611487
WS.pinCfgCompleted = false;
@@ -1465,7 +1491,7 @@ void Wippersnapper::connect(bool useStagingBroker) {
14651491
WS._mqtt->processPackets(10); // poll
14661492
}
14671493
// Publish that we have completed the configuration workflow
1468-
feedWDT();
1494+
WS.feedWDT();
14691495
runNetFSM();
14701496
publishPinConfigComplete();
14711497
WS_DEBUG_PRINTLN("Hardware configured successfully!");
@@ -1519,24 +1545,25 @@ void Wippersnapper::publishPinConfigComplete() {
15191545
ws_status_t Wippersnapper::run() {
15201546
// Check networking
15211547
runNetFSM();
1522-
feedWDT();
1548+
WS.feedWDT();
15231549
pingBroker();
15241550

15251551
// Process all incoming packets from Wippersnapper MQTT Broker
15261552
WS._mqtt->processPackets(10);
1527-
feedWDT();
1553+
WS.feedWDT();
15281554

15291555
// Process digital inputs, digitalGPIO module
15301556
WS._digitalGPIO->processDigitalInputs();
1531-
feedWDT();
1557+
WS.feedWDT();
15321558

15331559
// Process analog inputs
15341560
WS._analogIO->processAnalogInputs();
1535-
feedWDT();
1561+
WS.feedWDT();
15361562

15371563
// Process I2C sensor events
1538-
// WS._i2cPort0->update();
1539-
// feedWDT();
1564+
if (WS._isI2CPort0Init)
1565+
WS._i2cPort0->update();
1566+
WS.feedWDT();
15401567

15411568
return WS_NET_CONNECTED; // TODO: Make this funcn void!
15421569
}

src/Wippersnapper.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
#endif
6464

6565
#define WS_VERSION \
66-
"1.0.0-beta.15" ///< WipperSnapper app. version (semver-formatted)
66+
"1.0.0-beta.16" ///< WipperSnapper app. version (semver-formatted)
6767

6868
// Reserved Adafruit IO MQTT topics
6969
#define TOPIC_IO_THROTTLE "/throttle" ///< Adafruit IO Throttle MQTT Topic
@@ -254,6 +254,10 @@ class Wippersnapper {
254254
NULL; ///< WipperSnapper I2C Component for I2C port #0
255255
WipperSnapper_Component_I2C *_i2cPort1 =
256256
NULL; ///< WipperSnapper I2C Component for I2C port #1
257+
bool _isI2CPort0Init =
258+
false; ///< True if I2C port 0 has been initialized, False otherwise.
259+
bool _isI2CPort1Init =
260+
false; ///< True if I2C port 1 has been initialized, False otherwise.
257261

258262
uint8_t _buffer[WS_MQTT_MAX_PAYLOAD_SIZE]; /*!< Shared buffer to save callback
259263
payload */

src/Wippersnapper_Boards.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#define NEEDS_STATUS_NEOPIXEL_POWER
6060
#define STATUS_NEOPIXEL_PIN 33
6161
#define STATUS_NEOPIXEL_NUM 1
62+
#define PIN_I2C_POWER_INVERTED 7
6263
#elif defined(ARDUINO_ARCH_ESP8266)
6364
#define USB_VID 0xEA60
6465
#define USB_PID 0x10C4

0 commit comments

Comments
 (0)