Skip to content

Feat led controller#310

Merged
nitin710 merged 7 commits intomasterfrom
feat-LedController
Aug 14, 2024
Merged

Feat led controller#310
nitin710 merged 7 commits intomasterfrom
feat-LedController

Conversation

@nitin710
Copy link
Collaborator

@nitin710 nitin710 commented Jun 11, 2024

Description

  • Adds LED controller

Requirements

Issues Referenced

Notes for Reviewer

  • Add detailed notes explaining code changes, algorithms or any other information that can help the reviewer understand the PR better.

Testing

  • Led Controller Unit test (Feather ESP32)
    • Flash the binary linked below (unit test) on a Feather ESP32. You may use the EmotiBit FirmwareInstaller to do so.
    • plug in to serial monitor.
    • reset feather
    • Enter 6 into Serial input when prompted (set No Line Ending option). (This way you can start the example on a V5 and force the version to be V6 for testing the change of address for the IC)
      • image
    • Notice the LED cycle through.
  • EmotiBit complete FW test
    • Flash the Test Feather with the binary linked below 1.11.1.feat-LedController.0.
    • Place the frankedn V6 on the test jig as the DUT.
    • Start the factory test. (Follow the SOP if required, but the factory test software should be a sufficient guide)
    • You may use one of the following barcodes in the "barcode scanning phase" (remember that you need to print the barcode to be able to scan them. the barcode reader cannot read the barcode off a screen)
    • barcode
    • barcode(1)

Results

  • Led Controller Unit test
    • V5: ✔️
    • V6: ✔️
  • Complete FW test:
    • ✔️V5
      • ✔️ Button press
      • ✔️ hibernate
      • ✔️ setup led sequence
      • ✔️ recording
      • ✔️ wifi connection
      • ✔️ Oscilloscope connection
      • ✔️ Factory Test Serial Message prompts
    • ✔️ Franken-F5-V6

Feature Tests

Shared files

Checklist to allow merge

  • All dependent repositories used were on branch master
  • Firmware
    • Set testingMode to TestingMode::NONE
    • Set const bool DIGITAL_WRITE_DEBUG = false (if set true while testing)
    • Update version in EmotiBit.h
    • Update library.properties to the correct version (should match EmotiBit.h)
  • doxygen style comments included for new code snippets
  • Required documentation updated

Screenshots:

@produceconsumerobot
Copy link
Collaborator

produceconsumerobot commented Jun 14, 2024

LedController-testLedSequence-share confirmed working on V6 frankenboard
I believe the test jig has an M0, but we should build FW for both M0 and ESP to be sure we're covered when we dial-in to the factory (and since we need them both anyway)

@produceconsumerobot
Copy link
Collaborator

produceconsumerobot commented Jun 20, 2024

V6 frankenboard run successfully on the EmotiBit FactoryTest:
image

Copy link
Collaborator

@produceconsumerobot produceconsumerobot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally just style comments.
Biggest question is around LedStatus multiple source of truth with the NCP driver.

struct LedStatus
{
bool state = false;
bool isChanged = false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isChanged is slick, though I wonder how much value keeping track of isChanged practically has. It saves a little bit of CPU, but I think we have to tune our ISR cycles based on worst-case, which would be changing all 3 LEDs.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this lead to a multiple source of truth with each the NCP driver and the LED controller separately keeping track of state?
Would it have been better to keep LedStatus only in the NCP driver?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here was my thought process:

  1. Since we now have the LED controller, it becomes the user facing element and all seek/update calls will only go to the controller, so I thought it was necessary for the controller to hold the state of LEDs.
  2. Yes, there can be a mismatch in the LED states as stored in the controller and the driver, but, the state update is only unidirectional. The EmotiBit class updates the LedController which in turn updates the driver. Since EmotiBit only has access to the LedController, the multiple source of truth although present is not realized.
  3. Furthermore, I think we we want to remove the MSOT, we should drop the storage element in the driver. And use it purely for communicating with the IC. I think, in the future, that is the way to proceed. Hence, I am going to leave it as is now because removing it from the LedController may go against the final change we want to make.

Let me if there is something I missed in the reasoning.

Copy link
Collaborator

@produceconsumerobot produceconsumerobot Aug 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nitin710 why not push the SSOT down to the driver?
Is there anything uniquely EmotiBit about LED states?

Copy link
Collaborator Author

@nitin710 nitin710 Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After thinking about it, I think I agree it should be pushed down to the driver 😅. Below is the reason.
EDIT: consider a emotibit variant where the LEDs are directly controlled by GPIOs (for example), it makes more sense the the LedController holds the LED states. Need to dig deeper. But maybe, in that case, there is a separate driver that controls LEDS using GPIOs? (notes for future self. Don't hate me.)

TLDR;
If we keep the state storage in the driver, the driver can be used asynchronously, but if the storage lives in a wrapper class above the driver, then the driver can only be used synchronously without additionally creating a wrapper class.

image

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to issue: #317

EmotiBit stock FW only allows I2C communication during ISR.
* @return true is successful, else false
*/
bool update();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason you use update() here but utilize the pass-through send() fn in the NCP driver?
Generally consistency can be nice to keep things intuitive.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

send is now hidden from the EmotiBit class and I was trying to play with the set and update terminology. Update made more sense looking from EmotiBit class's perspective.

That's the only reason, but if you think this may lead to confusion with the usage, the change would look something like

  1. EmotiBitLedController::update() -> EmotiBitLedController::send()
  2. EmotiBitLedController::_updateNcp() -> EmotiBitLedController::_sendNcp()

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My recollection is that we specifically chose send when we adapted the driver. I think perhaps it was to distinguish sending internal register to the LEDs (unidirectional) vs updating internal registers to match LEDs (bidirectional), but I can't totally remember. I like the idea of creating consistency across the EmotiBit ecosystem. Is there anywhere else update() is used other than emotibit.h/cpp though?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found the following places we use update

  1. updating button press
  2. updating data (reading form the sensors)
  3. NVM controller uses it with both read/write.

I think we have run out of time to make the change and test it again. I will add this to an issue for my future self.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nitin710
Copy link
Collaborator Author

Created issue #317 for unresolved comments.

Merging PR.

@nitin710 nitin710 merged commit f9166c9 into master Aug 14, 2024
@nitin710 nitin710 deleted the feat-LedController branch August 14, 2024 22:25
@produceconsumerobot
Copy link
Collaborator

produceconsumerobot commented Aug 16, 2024

Testing

Bootup V6 M0

Results

  • Blue and red LEDs work as expected
  • Serial log looks good
  • One time it crashed after a few mins of being connected to oscilloscope

Serial Log

I2C data pin: 11
I2C clk pin: 13
hibernate pin: 6
chip sel pin: 19
Firmware version: 1.12.0
firmware_variant: EmotiBit_stock_firmware
vregEnablePinLogic: Active HIGH(V3+)
EmotiBit ready
Setting up I2C For M0...
Setting clock to 100000
Initializing NVM controller: success
Successfully read variant info from NVM
[NVM VARIANT INFO] HW version: V06a
[NVM VARIANT INFO] SKU version: MD
[NVM VARIANT INFO] EmotiBit Number: 506
[NVM VARIANT INFO] EmotiBit device ID: MD-V6-0000506

EmotiBit HW version: V06a
Firmware version: 1.12.0
firmware_variant: EmotiBit_stock_firmware
Enter C to enter WiFi config edit mode (Add/ Delete WiFi creds)

Sensor setup:

Set Samples averaged:
Initializing LedController....Completed
Initializing MAX30101....Completed
Initializing BMI160+BMM150.... DEVICE ID: D1 ... Completed
Initializing MLX90632... Success
Updated Register contents
EE_MEAS1: 840D
EE_MEAS2: 841D
Refresh Rate: 8
MODE_STEPChecking for ADC Correction...
data on atwinc corrupted or not present
Using the ADC without any correction

Initializing EDA...
edaSeriesResistance: 0.00
samplingRate: 15.00
Configuring ADS ADC...
enableDigitalFilter: 0
clipMin: -26500
clipMax: 26500
adcBits: 16
_ads.setDataRate: RATE_ADS1115_475SPS
_ads.setGain: GAIN_TWO
edaTransformSlope: 728.84
edaTransformIntercept: 14179797.00
Completed

Loading EDA calibration...
0R, -19623.800781
10K, -19610.800781
100K, -19486.771484
1M, -18246.628906
10M, -5850.875000
edaTransformSlope = 725.72
edaTransformIntercept = 14241910.00
Completed
Sensor setup complete

Initializing SD card...0,card initialized.

Loading configuration file: config.txt
Number of network credentials found in config file: 6
Adding SSID: GalaxyBot7 -pass:daringcaution2009 ... success
Adding SSID: EmotiNet -pass:emotibitrocks ... success
Adding SSID: Produce Consume -pass:daringcaution2009 ... success
Adding SSID: TP-LINK_A2990E -pass:62882392 ... success
Adding SSID: TP-LINK_9BB3CE -pass:279BB3CE ... success
Adding SSID: UNR-EXT -userid:cfl@as -pass:prf29imi ... success

Setting up WiFi
[{"info":{
"source_id":"EmotiBit FeatherWing",
"hardware_version":"V06a",
"sku":"MD",
"device_id":"MD-V6-0000506",
"feather_version":"Adafruit Feather M0 WiFi",
"feather_wifi_mac_addr":"4c:d4:00:00:cd:e2",
"firmware_version":"1.12.0",
"firmware_variant":"EmotiBit_stock_firmware",
"free_memory":"4699",
}}]
WiFi101 firmware check.
WiFi101 shield: DETECTED
Firmware version installed: 19.6.1
Latest firmware version available : 19.6.1
Attempting to connect to SSID: GalaxyBot7
WiFi.begin() duration = 951
WiFi.status() = 6, total duration = 952
<<<<<<< Switching WiFi Networks >>>>>>>
Attempting to connect to SSID: EmotiNet
WiFi.begin() duration = 920
WiFi.status() = 6, total duration = 920
<<<<<<< Switching WiFi Networks >>>>>>>
Attempting to connect to SSID: Produce Consume
WiFi.begin() duration = 920
WiFi.status() = 6, total duration = 920
<<<<<<< Switching WiFi Networks >>>>>>>
Attempting to connect to SSID: TP-LINK_A2990E
WiFi.begin() duration = 2480
WiFi.status() = 3, total duration = 2481
WiFi.begin() attempts = 2
Connected to WiFi
SSID: TP-LINK_A2990E
IP Address: 192.168.0.100
signal strength (RSSI):-52 dBm
Starting EmotiBit advertising connection on port 3131
WiFi setup Completed
Setting up FTP
Setting Protocol
Setting Auth
PowerMode::NORMAL_POWER
EmotiBit Setup complete
Free Ram :4663 bytes

Feather M0 detected.

Switch to EmotiBit Oscilloscope to stream Data

Bootup V6 ESP32

Results

  • Blue and red LEDs work as expected
  • Serial log looks good

Serial Log

I2C data pin: 27
I2C clk pin: 13
hibernate pin: 32
chip sel pin: 4
Firmware version: 1.12.0
firmware_variant: EmotiBit_stock_firmware
vregEnablePinLogic: Active HIGH(V3+)
EmotiBit ready
Setting up I2C For ESP32...
I2c setup complete
Setting clock to 100000
Initializing NVM controller: success
Successfully read variant info from NVM
[NVM VARIANT INFO] HW version: V06a
[NVM VARIANT INFO] SKU version: MD
[NVM VARIANT INFO] EmotiBit Number: 152
[NVM VARIANT INFO] EmotiBit device ID: MD-V6-0000152

EmotiBit HW version: V06a
Firmware version: 1.12.0
firmware_variant: EmotiBit_stock_firmware
Enter C to enter WiFi config edit mode (Add/ Delete WiFi creds)

Sensor setup:

Set Samples averaged:
Initializing LedController....Completed
Initializing MAX30101....Completed
Initializing BMI160+BMM150.... DEVICE ID: D1 ... Completed
Initializing MLX90632... Success
Updated Register contents
EE_MEAS1: 840D
EE_MEAS2: 841D
Refresh Rate: 8
MODE_STEP
Initializing EDA...
edaSeriesResistance: 0.00
samplingRate: 15.00
Configuring ADS ADC...
enableDigitalFilter: 0
clipMin: -26500
clipMax: 26500
adcBits: 16
_ads.setDataRate: RATE_ADS1115_475SPS
_ads.setGain: GAIN_TWO
edaTransformSlope: 728.84
edaTransformIntercept: 14179797.00
Completed

Loading EDA calibration...
0R, -19561.966797
10K, -19548.000000
100K, -19422.914063
1M, -18171.300781
10M, -5662.266602
edaTransformSlope = 719.10
edaTransformIntercept = 14066901.00
Completed
Sensor setup complete

Initializing SD card...0,card initialized.

Loading configuration file: /config.txt
Number of network credentials found in config file: 6
Adding SSID: GalaxyBot7 -pass:daringcaution2009 ... success
Adding SSID: EmotiNet -pass:emotibitrocks ... success
Adding SSID: Produce Consume -pass:daringcaution2009 ... success
Adding SSID: TP-LINK_A2990E -pass:62882392 ... success
Adding SSID: TP-LINK_9BB3CE -pass:279BB3CE ... success
Adding SSID: UNR-EXT -userid:cfl@as -pass:prf29imi ... success

Setting up WiFi
[{"info":{
"source_id":"EmotiBit FeatherWing",
"hardware_version":"V06a",
"sku":"MD",
"device_id":"MD-V6-0000152",
"feather_version":"Adafruit Feather HUZZAH32",
"feather_wifi_mac_addr":"0c:9c:0f:a7:db:cc",
"firmware_version":"1.12.0",
"firmware_variant":"EmotiBit_stock_firmware",
}}]
Attempting to connect to SSID: GalaxyBot7
WiFi.begin() duration = 72
WiFi.status() = 1, total duration = 4073
<<<<<<< Switching WiFi Networks >>>>>>>
Attempting to connect to SSID: EmotiNet
WiFi.begin() duration = 172
WiFi.status() = 1, total duration = 4173
<<<<<<< Switching WiFi Networks >>>>>>>
Attempting to connect to SSID: Produce Consume
WiFi.begin() duration = 115
WiFi.status() = 1, total duration = 4116
<<<<<<< Switching WiFi Networks >>>>>>>
Attempting to connect to SSID: TP-LINK_A2990E
WiFi.begin() duration = 116
WiFi.status() = 3, total duration = 2116
WiFi.begin() attempts = 2
Connected to WiFi
SSID: TP-LINK_A2990E
IP Address: 192.168.0.102
signal strength (RSSI):-40 dBm
Starting EmotiBit advertising connection on port 3131
WiFi setup Completed
Setting up FTP
Setting Protocol
Setting Auth
PowerMode::NORMAL_POWER
EmotiBit Setup complete

The data acquisition is executing on core: 1

HUZZAH32 Feather detected.

Switch to EmotiBit Oscilloscope to stream Data
The main loop is executing on core: 1

Starting control connection to server: 192.168.0.101 : 3133 ... connected
Starting data connection to server: 192.168.0.101 : 3132
501965,9,1,RB,1,100,2024-08-16_17-04-53-780670
Creating new file to write data
** Recording Begin: 2024-08-16_17-04-53-780670.csv **
35097,1653,1,RB,1,100,2024-08-16_17-04-53-780670

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants