找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5733|回复: 3
打印 上一主题 下一主题
收起左侧

SI1143心率血氧检测模块arduino与processing源代码

[复制链接]
跳转到指定楼层
楼主
最近使用arduino玩了一下这个检测心率血氧的模块
SI1143_Pulse_Prox_Sensors-master





单片机源程序如下:
  1. // SI114.h
  2. // Code for the Modern Device Pulse Sensor
  3. // Based on the SI1143 chip
  4. // Also includes subset of JeeLabs Ports library - thanks JCW!
  5. // paul@moderndevice.com 6-27-2012


  6. #include "SI114.h"
  7. #include <avr/sleep.h>
  8. #include <util/atomic.h>

  9. // flag bits sent to the receiver
  10. #define MODE_CHANGE 0x80    // a pin mode was changed
  11. #define DIG_CHANGE  0x40    // a digital output was changed
  12. #define PWM_CHANGE  0x30    // an analog (pwm) value was changed on port 2..3
  13. #define ANA_MASK    0x0F    // an analog read was requested on port 1..4


  14. byte PulsePlug::readParam (byte addr) {
  15.     // read from parameter ram
  16.     send();   
  17.     write(PulsePlug::COMMAND);
  18.     write(0x80 | addr); // PARAM_QUERY
  19.     stop();
  20.     delay(10);
  21.     return getReg(PulsePlug::PARAM_RD);
  22. }

  23. byte PulsePlug::getReg (byte reg) {
  24.     // get a register
  25.     send();   
  26.     write(reg);
  27.     receive();
  28.     byte result = read(1);
  29.     stop();
  30.     delay(10);
  31.     return result;
  32. }

  33. void PulsePlug::setReg (byte reg, byte val) {
  34.     // set a register
  35.     send();   
  36.     write(reg);
  37.     write(val);
  38.     stop();
  39.     delay(10);
  40. }

  41. void PulsePlug::initPulsePlug(){
  42.     PulsePlug::setReg(PulsePlug::HW_KEY, 0x17);
  43.     // pulsePlug.setReg(PulsePlug::COMMAND, PulsePlug::RESET_Cmd);
  44.    
  45.     Serial.print("PART: ");
  46.     Serial.print(PulsePlug::getReg(PulsePlug::PART_ID));
  47.     Serial.print(" REV: ");
  48.     Serial.print(PulsePlug::getReg(PulsePlug::REV_ID));
  49.     Serial.print(" SEQ: ");
  50.     Serial.println(PulsePlug::getReg(PulsePlug::SEQ_ID));
  51.    
  52.     PulsePlug::setReg(PulsePlug::INT_CFG, 0x03);       // turn on interrupts
  53.     PulsePlug::setReg(PulsePlug::IRQ_ENABLE, 0x10);    // turn on interrupt on PS3
  54.     PulsePlug::setReg(PulsePlug::IRQ_MODE2, 0x01);     // interrupt on ps3 measurement
  55.     PulsePlug::setReg(PulsePlug::MEAS_RATE, 0x84);     // see datasheet
  56.     PulsePlug::setReg(PulsePlug::ALS_RATE, 0x08);      // see datasheet
  57.     PulsePlug::setReg(PulsePlug::PS_RATE, 0x08);       // see datasheet
  58.     PulsePlug::setReg(PulsePlug::PS_LED21, 0x66 );      // LED current for LEDs 1 (red) & 2 (IR1)
  59.     PulsePlug::setReg(PulsePlug::PS_LED3, 0x06);        // LED current for LED 3 (IR2)
  60.    
  61.     Serial.print( "PS_LED21 = ");
  62.     Serial.println(PulsePlug::getReg(PulsePlug::PS_LED21), BIN);
  63.     Serial.print("CHLIST = ");
  64.     Serial.println(PulsePlug::readParam(0x01), BIN);
  65.    
  66.     PulsePlug::writeParam(PulsePlug::PARAM_CH_LIST, 0x77);         // all measurements on
  67.    
  68.     // increasing PARAM_PS_ADC_GAIN will increase the LED on time and ADC window
  69.     // you will see increase in brightness of visible LED's, ADC output, & noise
  70.     // datasheet warns not to go beyond 4 because chip or LEDs may be damaged
  71.     PulsePlug::writeParam(PulsePlug::PARAM_PS_ADC_GAIN, 0x00);
  72.    
  73.     PulsePlug::writeParam(PulsePlug::PARAM_PSLED12_SELECT, 0x21);  // select LEDs on for readings see datasheet
  74.     PulsePlug::writeParam(PulsePlug::PARAM_PSLED3_SELECT, 0x04);   //  3 only
  75.     PulsePlug::writeParam(PulsePlug::PARAM_PS1_ADCMUX, 0x03);      // PS1 photodiode select
  76.     PulsePlug::writeParam(PulsePlug::PARAM_PS2_ADCMUX, 0x03);      // PS2 photodiode select
  77.     PulsePlug::writeParam(PulsePlug::PARAM_PS3_ADCMUX, 0x03);      // PS3 photodiode select
  78.    
  79.     PulsePlug::writeParam(PulsePlug::PARAM_PS_ADC_COUNTER, B01110000);    // B01110000 is default
  80.     PulsePlug::setReg(PulsePlug::COMMAND, PulsePlug::PSALS_AUTO_Cmd);     // starts an autonomous read loop
  81.    
  82. }

  83. void PulsePlug::setLEDcurrents(byte LED1, byte LED2, byte LED3){
  84. /* VLEDn = 1 V, PS_LEDn = 0001        5.6
  85. VLEDn = 1 V, PS_LEDn = 0010        11.2
  86. VLEDn = 1 V, PS_LEDn = 0011        22.4
  87. VLEDn = 1 V, PS_LEDn = 0100        45
  88. VLEDn = 1 V, PS_LEDn = 0101        67
  89. VLEDn = 1 V, PS_LEDn = 0110        90
  90. VLEDn = 1 V, PS_LEDn = 0111        112
  91. VLEDn = 1 V, PS_LEDn = 1000        135
  92. VLEDn = 1 V, PS_LEDn = 1001        157
  93. VLEDn = 1 V, PS_LEDn = 1010        180
  94. VLEDn = 1 V, PS_LEDn = 1011        202
  95. VLEDn = 1 V, PS_LEDn = 1100        224
  96. VLEDn = 1 V, PS_LEDn = 1101        269
  97. VLEDn = 1 V, PS_LEDn = 1110        314
  98. VLEDn = 1 V, PS_LEDn = 1111        359   */

  99. LED1 = constrain(LED1, 0, 15);
  100. LED2 = constrain(LED2, 0, 15);
  101. LED3 = constrain(LED3, 0, 15);

  102. PulsePlug::setReg(PulsePlug::PS_LED21, (LED2 << 4) | LED1 );
  103. PulsePlug::setReg(PulsePlug::PS_LED3, LED3);      

  104. }

  105. void PulsePlug::setLEDdrive(byte LED1pulse, byte LED2pulse, byte LED3pulse){
  106. // this sets which LEDs are active on which pulses
  107. // any or none of the LEDs may be active on each PulsePlug
  108. //000: NO LED DRIVE
  109. //xx1: LED1 Drive Enabled
  110. //x1x: LED2 Drive Enabled (Si1142 and Si1143 only. Clear for Si1141)
  111. //1xx: LED3 Drive Enabled (Si1143 only. Clear for Si1141 and Si1142)
  112. // example setLEDdrive(1, 2, 5); sets LED1 on pulse 1, LED2 on pulse 2, LED3, LED1 on pulse 3

  113. PulsePlug::writeParam(PulsePlug::PARAM_PSLED12_SELECT, (LED1pulse << 4) | LED2pulse );  // select LEDs on for readings see datasheet
  114. PulsePlug::writeParam(PulsePlug::PARAM_PSLED3_SELECT, LED3pulse);   

  115. }

  116. void PulsePlug::fetchData () {
  117.     // read out all result registers as lsb-msb pairs of bytes
  118.     send();   
  119.     write(PulsePlug::RESPONSE);
  120.     receive();
  121.     byte* p = (byte*) &resp;
  122.     for (byte i = 0; i < 16; ++i)
  123.         p[i] = read(0);
  124.     read(1); // just to end cleanly
  125.     stop();
  126. }


  127. void PulsePlug::fetchLedData() {

  128.     // read only the LED registers as lsb-msb pairs of bytes
  129.     send();   
  130.     write(PulsePlug::PS1_DATA0);
  131.     receive();
  132.     byte* q = (byte*) &ps1;
  133.     for (byte i = 0; i < 6; ++i)
  134.         q[i] = read(0);
  135.     read(1); // just to end cleanly
  136.     stop();
  137. }


  138. void PulsePlug::writeParam (byte addr, byte val) {
  139.     // write to parameter ram
  140.     send();   
  141.     write(PulsePlug::PARAM_WR);
  142.     write(val);
  143.     // auto-increments into PulsePlug::COMMAND
  144.     write(0xA0 | addr); // PARAM_SET
  145.     stop();
  146.     delay(10);
  147. }


  148. uint16_t Port::shiftRead(uint8_t bitOrder, uint8_t count) const {
  149.     uint16_t value = 0, mask = bit(LSBFIRST ? 0 : count - 1);
  150.     for (uint8_t i = 0; i < count; ++i) {
  151.         digiWrite2(1);
  152.         delayMicroseconds(5);
  153.         if (digiRead())
  154.             value |= mask;
  155.         if (bitOrder == LSBFIRST)
  156.             mask <<= 1;
  157.         else
  158.             mask >>= 1;
  159.         digiWrite2(0);
  160.         delayMicroseconds(5);
  161.     }
  162.     return value;
  163. }

  164. void Port::shiftWrite(uint8_t bitOrder, uint16_t value, uint8_t count) const {
  165.     uint16_t mask = bit(LSBFIRST ? 0 : count - 1);
  166.     for (uint8_t i = 0; i < count; ++i) {
  167.         digiWrite((value & mask) != 0);
  168.         if (bitOrder == LSBFIRST)
  169.             mask <<= 1;
  170.         else
  171.             mask >>= 1;
  172.         digiWrite2(1);
  173.         digiWrite2(0);
  174.     }
  175. }


  176. PortI2C::PortI2C (uint8_t num, uint8_t rate)
  177.     : Port (num), uswait (rate)
  178. {
  179.     sdaOut(1);
  180.     mode2(OUTPUT);
  181.     sclHi();
  182. }

  183. uint8_t PortI2C::start(uint8_t addr) const {
  184.     sclLo();
  185.     sclHi();
  186.     sdaOut(0);
  187.     return write(addr);
  188. }

  189. void PortI2C::stop() const {
  190.     sdaOut(0);
  191.     sclHi();
  192.     sdaOut(1);
  193. }

  194. uint8_t PortI2C::write(uint8_t data) const {
  195.     sclLo();
  196.     for (uint8_t mask = 0x80; mask != 0; mask >>= 1) {
  197.         sdaOut(data & mask);
  198.         sclHi();
  199.         sclLo();
  200.     }
  201.     sdaOut(1);
  202.     sclHi();
  203.     uint8_t ack = ! sdaIn();
  204.     sclLo();
  205.     return ack;
  206. }

  207. uint8_t PortI2C::read(uint8_t last) const {
  208.     uint8_t data = 0;
  209.     for (uint8_t mask = 0x80; mask != 0; mask >>= 1) {
  210.         sclHi();
  211.         if (sdaIn())
  212.             data |= mask;
  213.         sclLo();
  214.     }
  215.     sdaOut(last);
  216.     sclHi();
  217.     sclLo();
  218.     if (last)
  219.         stop();
  220.     sdaOut(1);
  221.     return data;
  222. }

  223. bool DeviceI2C::isPresent () const {
  224.     byte ok = send();
  225.     stop();
  226.     return ok;
  227. }

  228. byte MilliTimer::poll(word ms) {
  229.     byte ready = 0;
  230.     if (armed) {
  231.         word remain = next - millis();
  232.         // since remain is unsigned, it will overflow to large values when
  233.         // the timeout is reached, so this test works as long as poll() is
  234.         // called no later than 5535 millisecs after the timer has expired
  235.         if (remain <= 60000)
  236.             return 0;
  237.         // return a value between 1 and 255, being msecs+1 past expiration
  238.         // note: the actual return value is only reliable if poll() is
  239.         // called no later than 255 millisecs after the timer has expired
  240.         ready = -remain;
  241.     }
  242.     set(ms);
  243.     return ready;
  244. }

  245. word MilliTimer::remaining() const {
  246.     word remain = armed ? next - millis() : 0;
  247.     return remain <= 60000 ? remain : 0;
  248. }

  249. void MilliTimer::set(word ms) {
  250.     armed = ms != 0;
  251.     if (armed)
  252.         next = millis() + ms - 1;
  253. }

  254. Scheduler::Scheduler (byte size) : maxTasks (size), remaining (~0) {
  255.     byte bytes = size * sizeof *tasks;
  256.     tasks = (word*) malloc(bytes);
  257.     memset(tasks, 0xFF, bytes);
  258. }

  259. Scheduler::Scheduler (word* buf, byte size) : tasks (buf), maxTasks (size), remaining(~0) {
  260.     byte bytes = size * sizeof *tasks;
  261.     memset(tasks, 0xFF, bytes);
  262. }

  263. char Scheduler::poll() {
  264.     // all times in the tasks array are relative to the "remaining" value
  265.     // i.e. only remaining counts down while waiting for the next timeout
  266.     if (remaining == 0) {
  267.         word lowest = ~0;
  268.         for (byte i = 0; i < maxTasks; ++i) {
  269.             if (tasks[i] == 0) {
  270.                 tasks[i] = ~0;
  271.                 return i;
  272.             }
  273.             if (tasks[i] < lowest)
  274.                 lowest = tasks[i];
  275.         }
  276.         if (lowest != ~0) {
  277.             for (byte i = 0; i < maxTasks; ++i) {
  278.                 if(tasks[i] != ~0) {
  279.                     tasks[i] -= lowest;
  280.                 }
  281.             }
  282.         }
  283.         remaining = lowest;
  284.     } else if (remaining == ~0) //remaining == ~0 means nothing running
  285.         return -2;
  286.     else if (ms100.poll(100))
  287.         --remaining;
  288.     return -1;
  289. }


  290. void Scheduler::timer(byte task, word tenths) {
  291.     // if new timer will go off sooner than the rest, then adjust all entries
  292.     if (tenths < remaining) {
  293.         word diff = remaining - tenths;
  294.         for (byte i = 0; i < maxTasks; ++i)
  295.             if (tasks[i] != ~0)
  296.                 tasks[i] += diff;
  297.         remaining = tenths;
  298.     }
  299.     tasks[task] = tenths - remaining;
  300. }

  301. void Scheduler::cancel(byte task) {
  302.     tasks[task] = ~0;
  303. }


复制代码

所有资料51hei提供下载:
SI1143_Pulse_Prox_Sensors-master.rar (759.03 KB, 下载次数: 34)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:138247 发表于 2020-4-20 14:46 | 只看该作者

感谢分享,学习学习。
回复

使用道具 举报

板凳
ID:435193 发表于 2020-8-12 18:01 | 只看该作者
想请教一下pulse.writeParam和 pulse.setReg是什么意思
回复

使用道具 举报

地板
ID:435193 发表于 2020-8-12 18:02 | 只看该作者
我想使用STM32来驱动这两行代码没看懂,硬件不干活
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表