{"id":22120230,"url":"https://github.com/joshbrew/max86141_arduino","last_synced_at":"2025-10-15T22:06:17.829Z","repository":{"id":133634759,"uuid":"218963306","full_name":"joshbrew/MAX86141_Arduino","owner":"joshbrew","description":"MAX86141 Heart Rate Monitor IC library for Arduino","archived":false,"fork":false,"pushed_at":"2023-01-16T20:33:06.000Z","size":7401,"stargazers_count":10,"open_issues_count":1,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-09T18:05:18.852Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joshbrew.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-01T10:20:53.000Z","updated_at":"2023-04-27T12:16:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"88511fb6-b143-4b96-9583-79e6cea02d47","html_url":"https://github.com/joshbrew/MAX86141_Arduino","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/joshbrew/MAX86141_Arduino","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbrew%2FMAX86141_Arduino","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbrew%2FMAX86141_Arduino/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbrew%2FMAX86141_Arduino/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbrew%2FMAX86141_Arduino/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joshbrew","download_url":"https://codeload.github.com/joshbrew/MAX86141_Arduino/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbrew%2FMAX86141_Arduino/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267007597,"owners_count":24020261,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-25T02:00:09.625Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-01T14:21:35.282Z","updated_at":"2025-10-15T22:06:17.726Z","avatar_url":"https://github.com/joshbrew.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"WORK IN PROGRESS, WORKING EXAMPLES\r\n\r\nChange the MAX86141::init function in MAX86141.cpp or change after calling pulseOx.setup() in the .ino.\r\n\r\nMAX86141 LIBRARY FOR ARDUINO\r\n\r\nREQUIRES A MAX86141 DEVICE (you gotta make it yourself as there are no breakouts available yet)\r\n\r\nInstall: Drag the example folder and libraries folder to your Arduino sketch repository and merge with any existing\r\nlibraries folder.\r\n\r\nThe example is set up for a MAX86141 running on an ESP32 on VSPI. \r\n\r\nIf designing from scratch you need to give it a separate 1.8V power source or level translator and ensure there is voltage translation on the SPI pins between 1.8V on the MAX86141 and the 3.3V on the ESP32 (or whatever board), adjust it for what you need.\r\n\r\n![Block](https://github.com/joshbrew/MAX86141_Arduino/blob/master/docs/Block_Diag.PNG?raw=true)\r\n\r\n\r\n--------------------------------------\r\npseudocode:\r\n\r\n```\r\nMAX86141 pulseOx;\r\nuint8_t[128] output;\r\n\r\nvoid setup(){\r\n  pulseOx.spi = new SPIClass(VSPI);\r\n  pulseOx.SS = SSpin;\r\n  pulseOx.spi-\u003ebegin();\r\n}\r\n\r\nvoid loop(){\r\n  uint8_t sample_count;\r\n  pulseOx.read_reg(REG_FIFO_DATA_COUNT, \u0026sample_count);\r\n  if((int)sample_count == 128){\r\n\t  pulseOx.read_fifo(output,sample_count);\r\n  }\r\n  Serial.print(\"LED1 P1: \");\r\n  Serial.println(pulseOx.led1A);\r\n  Serial.print(\"LED1 P2: \");\r\n  Serial.println(pulseOx.led1B);\r\n  Serial.print(\"LED2 P1: \");\r\n  Serial.println(pulseOx.led2A);\r\n  Serial.print(\"LED2 P2: \");\r\n  Serial.println(pulseOx.led2B);\r\n}\r\n\r\n/*\r\nSPI notes:\r\nEach byte register is 8 bits wide\r\nEX. vspi-\u003etransfer(0x01,0b01010101) sends the binary data to the register. Hex bytes are binary shorthand\r\nand the register applies the binary in reverse order where the index is 0b[7,6,5,4,3,2,1,0] in MSB_MODE for SPI\r\nThe datasheet describes all of the parameters you can enter.\r\n\r\nNote: If a sample rate is set that can not be supported by the selected pulse width and number of exposures per sample, then\r\nthe highest available sample rate will be automatically set. The user can read back this register to confirm the sample rate.\r\nADC Output is 18 bits. Number of exposures controlled in LED sequence registers (1 to 6)\r\n\r\nPPG_SR (sampling rate).\r\nRegister    SPS     Pulses per Sample\r\n0x0A        8       1\r\n0x0B        16      1\r\n0x0C        32      1\r\n0x0D        64      1\r\n0x0E        128     1\r\n0x0F        256     1\r\n0x10        512     1\r\n0x11        1024    1\r\n0x12        2048    1\r\n0x13        4096    1\r\n\r\n0x00        25      1\r\n0x01        50      1\r\n0x02        84      1\r\n0x03        100     1\r\n0x04        200     1\r\n0x05        400     1\r\n0x06        25      2\r\n0x07        50      2\r\n0x08        84      2\r\n0x09        100     2\r\n\r\nSample Average SMP_AVE\r\nBits    Sample Average\r\n000     1\r\n001     2\r\n010     4    \r\n011     8\r\n100     16\r\n101     32\r\n110     64\r\n111     128\r\n\r\nADC Full Scale Input Current ADC_RGE\r\nReg     Amps\r\n0x0     4.0uA\r\n0x1     8.0uA\r\n0x2     16.0uA\r\n0x3     32.0uA\r\n\r\nIntegration time PPG_TINT\r\nReg     Time\r\n0x0     14.8uS\r\n0x1     29.4uS\r\n0x2     58.7uS\r\n0x3     117.3uS\r\n\r\nLED Amplitude Range LEDx_RGE (LEDx_PA = 0xFF) - not sure how to set this.\r\nReg     Amps\r\n0x0     31mA\r\n0x1     62mA\r\n0x2     93mA\r\n0x3     124mA\r\n\r\nLED Settling LED_SETLNG\r\nbits    Time    \r\n00      4uS\r\n01      6uS (default)\r\n10      8uS\r\n11      12uS\r\n\r\nPhoto Diode Bias REG_PDIODE_BIAS\r\nRegister    Photo Diode Capacitance\r\n0x001       0pF to 65pF\r\n0x101       65pF to 130pF\r\n0x110       130pF to 260pF\r\n0x111       260pF to 520pF\r\n\r\nSelect digital filter type DIG_FILT_SEL \r\n0x0     Use CDM\r\n0x1     Use FDM\r\n*/\r\n\r\n//pseudocode from datasheet\r\n/*\r\nDEVICE OPEN\r\nSTART;\r\n // AFE Initialization\r\nWRITE RESET[0] to 0x1; // Soft Reset (Register 0x0D[0])\r\nDELAY 1ms;\r\nWRITE SHDN[0] to 0x1; // Shutdown (Register 0x0D[1])\r\nREAD Interrupt_Status_1; // Clear Interrupt (Register 0x00)\r\nREAD Interrupt_Status_2; // Clear Interrupt (Register 0x01)\r\nWRITE PPG_TINT[1:0] to 0x3; // Pulse Width = 123.8ms (Register 0x11[1:0])\r\nWRITE PPG1_ADC_RGE1:0] to 0x2; // ADC Range = 16μA (Register 0x11[3:2])\r\nWRITE PPG2_ADC_RGE1:0] to 0x2; // ADC Range = 16μA (Register 0x11[3:2])\r\n // For MAX86141 when used in Dual Channel only\r\nWRITE SMP_AVE[2:0] to 0x0; // Sample Averaging = 1 (Register 0x12[2:0])\r\nWRITE PPG_SR[4:0] to 0x00; // Sample Rate = 25sps (Register 0x12[7:3])\r\nWRITE LED_SETLNG[1:0] to 0x3; // LED Settling Time = 12ms (Register 0x13[7:6])\r\nWRITE PD_BIAS1[2:0] to 0x01; // PD 1 Biasing for Cpd = 0~65pF (Register 0x15[2:0])\r\nWRITE PD_BIAS2[2:0] to 0x01; // PD 1 Biasing for Cpd = 0~65pF (Register 0x15[2:0])\r\n // For MAX86141 when used in Dual Channel only\r\nWRITE LED1_RGE[1:0] to 0x3; // LED Driver 1 Range = 124mA (Register 0x15[2:0]) \u003c--- ???\r\nWRITE LED2_RGE[1:0] to 0x3; // LED Driver 2 Range = 124mA (Register 0x15[2:0]) \u003c--- ???\r\nWRITE LED1_DRV[1:0] to 0x20; // LED 1 Drive Current = 15.36mA (Register 0x23[7:0])\r\nWRITE LED2_DRV[1:0] to 0x20; // LED 2 Drive Current = 15.36mA (Register 0x24[7:0])\r\nWRITE LP_Mode[0] to 0x1; // Low Power mode enabled\r\n // FIFO Configuration\r\nWRITE FIFO_A_FULL[6:0] to 0xF; // FIFO INT triggered condition (Register 0x09[6:0])\r\nWRITE FIFO_RO to 0x1; // FIFO Roll Over enabled (Register 0x0A[1])\r\nWRITE A_FULL_EN to 0x1; // FIFO_A_FULL interrupt enabled (Register 0x02[7])\r\nWRITE LEDC1[3:0] to 0x1; // LED1 exposure configured in time slot 1\r\nWRITE LEDC2[3:0] to 0x2; // LED2 exposure configured in time slot 1\r\nWRITE LEDC3[3:0] to 0x0;\r\nWRITE LEDC4[3:0] to 0x0;\r\nWRITE LEDC5[3:0] to 0x0;\r\nWRITE LEDC6[3:0] to 0x0\r\nWRITE SHDN[0] to 0x0; // Start Sampling STOP;\r\n*/\r\n```\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshbrew%2Fmax86141_arduino","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoshbrew%2Fmax86141_arduino","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshbrew%2Fmax86141_arduino/lists"}