Browse Source

初始化工程

master
zhaohe 1 year ago
parent
commit
638f45ceea
  1. 3
      .vscode/settings.json
  2. 186
      app/app.uvoptx
  3. 20
      app/app.uvprojx
  4. 6
      app/src/board/board.h
  5. 12
      app/src/board/board_ecg_sensor.c
  6. 8
      app/src/device_state.h
  7. 108
      app/src/heart_ware_sample_data_mgr.c
  8. 9
      app/src/heart_ware_sample_data_mgr.h
  9. 107
      app/src/heart_wave_sample_data_pre_process.c
  10. 9
      app/src/heart_wave_sample_data_pre_process.h
  11. 227
      app/src/heart_wave_sample_service.c
  12. 313
      app/src/heart_wave_sample_service.c.bak
  13. 23
      app/src/one_conduction_main.c

3
.vscode/settings.json

@ -187,7 +187,8 @@
"pan_tompkins_detect.h": "c",
"qrs_time_domain_zh.h": "c",
"board_eeprom_driver.h": "c",
"board_power_mgr.h": "c"
"board_power_mgr.h": "c",
"heart_ware_sample_data_mgr.h": "c"
},
"files.encoding": "gbk"
}

186
app/app.uvoptx

@ -739,6 +739,30 @@
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>32</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\src\heart_ware_sample_data_mgr.c</PathWithFileName>
<FilenameWithoutPath>heart_ware_sample_data_mgr.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>33</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\src\heart_wave_sample_data_pre_process.c</PathWithFileName>
<FilenameWithoutPath>heart_wave_sample_data_pre_process.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
@ -749,7 +773,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>32</FileNumber>
<FileNumber>34</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -769,7 +793,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>33</FileNumber>
<FileNumber>35</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -781,7 +805,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>34</FileNumber>
<FileNumber>36</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -801,7 +825,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>35</FileNumber>
<FileNumber>37</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -821,7 +845,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>36</FileNumber>
<FileNumber>38</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -833,7 +857,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>37</FileNumber>
<FileNumber>39</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -845,7 +869,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>38</FileNumber>
<FileNumber>40</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -857,7 +881,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>39</FileNumber>
<FileNumber>41</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -869,7 +893,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>40</FileNumber>
<FileNumber>42</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -881,7 +905,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>41</FileNumber>
<FileNumber>43</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -893,7 +917,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>42</FileNumber>
<FileNumber>44</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -905,7 +929,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>43</FileNumber>
<FileNumber>45</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -925,7 +949,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>6</GroupNumber>
<FileNumber>44</FileNumber>
<FileNumber>46</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -945,7 +969,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>45</FileNumber>
<FileNumber>47</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -957,7 +981,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>46</FileNumber>
<FileNumber>48</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -969,7 +993,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>47</FileNumber>
<FileNumber>49</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -981,7 +1005,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>48</FileNumber>
<FileNumber>50</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -993,7 +1017,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>49</FileNumber>
<FileNumber>51</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1005,7 +1029,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>50</FileNumber>
<FileNumber>52</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1017,7 +1041,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>51</FileNumber>
<FileNumber>53</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1029,7 +1053,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>52</FileNumber>
<FileNumber>54</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1041,7 +1065,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>53</FileNumber>
<FileNumber>55</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1053,7 +1077,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>54</FileNumber>
<FileNumber>56</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1065,7 +1089,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>55</FileNumber>
<FileNumber>57</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1077,7 +1101,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>56</FileNumber>
<FileNumber>58</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1089,7 +1113,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>57</FileNumber>
<FileNumber>59</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1101,7 +1125,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>58</FileNumber>
<FileNumber>60</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1113,7 +1137,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>59</FileNumber>
<FileNumber>61</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1125,7 +1149,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>60</FileNumber>
<FileNumber>62</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1137,7 +1161,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>61</FileNumber>
<FileNumber>63</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1149,7 +1173,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>62</FileNumber>
<FileNumber>64</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1161,7 +1185,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>63</FileNumber>
<FileNumber>65</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1173,7 +1197,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>64</FileNumber>
<FileNumber>66</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1193,7 +1217,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>65</FileNumber>
<FileNumber>67</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1205,7 +1229,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>66</FileNumber>
<FileNumber>68</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1217,7 +1241,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>67</FileNumber>
<FileNumber>69</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1229,7 +1253,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>68</FileNumber>
<FileNumber>70</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1241,7 +1265,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>69</FileNumber>
<FileNumber>71</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1253,7 +1277,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>70</FileNumber>
<FileNumber>72</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1265,7 +1289,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>71</FileNumber>
<FileNumber>73</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1277,7 +1301,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>72</FileNumber>
<FileNumber>74</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1289,7 +1313,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>73</FileNumber>
<FileNumber>75</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1301,7 +1325,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>74</FileNumber>
<FileNumber>76</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1313,7 +1337,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>75</FileNumber>
<FileNumber>77</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1325,7 +1349,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>76</FileNumber>
<FileNumber>78</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1337,7 +1361,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>77</FileNumber>
<FileNumber>79</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1349,7 +1373,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>78</FileNumber>
<FileNumber>80</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1361,7 +1385,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>79</FileNumber>
<FileNumber>81</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1373,7 +1397,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>80</FileNumber>
<FileNumber>82</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1385,7 +1409,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>81</FileNumber>
<FileNumber>83</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1397,7 +1421,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>82</FileNumber>
<FileNumber>84</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1409,7 +1433,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>83</FileNumber>
<FileNumber>85</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1421,7 +1445,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>84</FileNumber>
<FileNumber>86</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1433,7 +1457,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>85</FileNumber>
<FileNumber>87</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1445,7 +1469,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>86</FileNumber>
<FileNumber>88</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1457,7 +1481,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>87</FileNumber>
<FileNumber>89</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1469,7 +1493,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>88</FileNumber>
<FileNumber>90</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1481,7 +1505,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>89</FileNumber>
<FileNumber>91</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1493,7 +1517,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>90</FileNumber>
<FileNumber>92</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1505,7 +1529,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>91</FileNumber>
<FileNumber>93</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1525,7 +1549,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>92</FileNumber>
<FileNumber>94</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1537,7 +1561,7 @@
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>93</FileNumber>
<FileNumber>95</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1549,7 +1573,7 @@
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>94</FileNumber>
<FileNumber>96</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1561,7 +1585,7 @@
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>95</FileNumber>
<FileNumber>97</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1573,7 +1597,7 @@
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>96</FileNumber>
<FileNumber>98</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1585,7 +1609,7 @@
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>97</FileNumber>
<FileNumber>99</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1605,7 +1629,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>98</FileNumber>
<FileNumber>100</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1617,7 +1641,7 @@
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>99</FileNumber>
<FileNumber>101</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1629,7 +1653,7 @@
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>100</FileNumber>
<FileNumber>102</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1649,7 +1673,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>11</GroupNumber>
<FileNumber>101</FileNumber>
<FileNumber>103</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1661,7 +1685,7 @@
</File>
<File>
<GroupNumber>11</GroupNumber>
<FileNumber>102</FileNumber>
<FileNumber>104</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1673,7 +1697,7 @@
</File>
<File>
<GroupNumber>11</GroupNumber>
<FileNumber>103</FileNumber>
<FileNumber>105</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1693,7 +1717,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>12</GroupNumber>
<FileNumber>104</FileNumber>
<FileNumber>106</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1705,7 +1729,7 @@
</File>
<File>
<GroupNumber>12</GroupNumber>
<FileNumber>105</FileNumber>
<FileNumber>107</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1717,7 +1741,7 @@
</File>
<File>
<GroupNumber>12</GroupNumber>
<FileNumber>106</FileNumber>
<FileNumber>108</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1737,7 +1761,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>13</GroupNumber>
<FileNumber>107</FileNumber>
<FileNumber>109</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1749,7 +1773,7 @@
</File>
<File>
<GroupNumber>13</GroupNumber>
<FileNumber>108</FileNumber>
<FileNumber>110</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1769,7 +1793,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>14</GroupNumber>
<FileNumber>109</FileNumber>
<FileNumber>111</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1781,7 +1805,7 @@
</File>
<File>
<GroupNumber>14</GroupNumber>
<FileNumber>110</FileNumber>
<FileNumber>112</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1793,7 +1817,7 @@
</File>
<File>
<GroupNumber>14</GroupNumber>
<FileNumber>111</FileNumber>
<FileNumber>113</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1805,7 +1829,7 @@
</File>
<File>
<GroupNumber>14</GroupNumber>
<FileNumber>112</FileNumber>
<FileNumber>114</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>

20
app/app.uvprojx

@ -538,6 +538,16 @@
<FileType>1</FileType>
<FilePath>.\src\board\board_power_mgr.c</FilePath>
</File>
<File>
<FileName>heart_ware_sample_data_mgr.c</FileName>
<FileType>1</FileType>
<FilePath>.\src\heart_ware_sample_data_mgr.c</FilePath>
</File>
<File>
<FileName>heart_wave_sample_data_pre_process.c</FileName>
<FileType>1</FileType>
<FilePath>.\src\heart_wave_sample_data_pre_process.c</FilePath>
</File>
</Files>
</Group>
<Group>
@ -4457,6 +4467,16 @@
<FileType>1</FileType>
<FilePath>.\src\board\board_power_mgr.c</FilePath>
</File>
<File>
<FileName>heart_ware_sample_data_mgr.c</FileName>
<FileType>1</FileType>
<FilePath>.\src\heart_ware_sample_data_mgr.c</FilePath>
</File>
<File>
<FileName>heart_wave_sample_data_pre_process.c</FileName>
<FileType>1</FileType>
<FilePath>.\src\heart_wave_sample_data_pre_process.c</FilePath>
</File>
</Files>
</Group>
<Group>

6
app/src/board/board.h

@ -41,9 +41,9 @@
#define LIGHT_PWM_INSTANCE 1
#define APP_BATTERY_PROTECT_LEVEL 2 // 低于此电量不能开机,保护电
#define APP_AUTO_STANDY_BATTERY_LEVEL 5 // 低于此电量自动待机,保持时
#define APP_WORK_BATTERY_LEVEL 10 // Main初始化时候和从standy切换到work的时候,检查这个电量
// #define APP_BATTERY_PROTECT_LEVEL 2 //
// #define APP_AUTO_STANDY_BATTERY_LEVEL 5 // ,
// #define APP_WORK_BATTERY_LEVEL 10 // Main初始化时候和从standy切换到work的时候
#define APP_LOW_BATTERY_WARNING_LIMIT 20 //
#define LOW_BATTERY_REMINDER_DELAY_MS 3000

12
app/src/board/board_ecg_sensor.c

@ -18,7 +18,7 @@ static void module_tmr_cb(void *context) { //
memset(&appevent, 0, sizeof(appevent));
// ZLOGI("ecg sensor %d",m_plod_state_connected_state);
if (!nrf_gpio_pin_read(ECG_PLOD_PIN)) {
if (true) {
connecte_state_trigger_cnt++;
m_connecte_state_last_trigger_timepoint = znordic_getpower_on_ms();
} else {
@ -39,8 +39,8 @@ static void module_tmr_cb(void *context) { //
}
void BoardEcgSensor_init() {
nrf_gpio_cfg_sense_input(ECG_NLOD_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg_sense_input(ECG_PLOD_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE); // µÍÓÐЧ
// nrf_gpio_cfg_sense_input(ECG_NLOD_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE);
// nrf_gpio_cfg_sense_input(ECG_PLOD_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE); // µÍÓÐЧ
app_timer_create(&module_tmr, APP_TIMER_MODE_REPEATED, module_tmr_cb);
app_timer_start(module_tmr, APP_TIMER_TICKS(100), NULL);
@ -48,9 +48,9 @@ void BoardEcgSensor_init() {
void BoardEcgSensor_load() { BoardAdc_load(); }
void BoardEcgSensor_unload() { BoardAdc_unload(); }
int16_t BoardEcgSensor_nlod_get_connected_state() { return nrf_gpio_pin_read(ECG_NLOD_PIN); }
int16_t BoardEcgSensor_plod_get_connected_state() { return !nrf_gpio_pin_read(ECG_PLOD_PIN); }
int16_t BoardEcgSensor_plod_get_ecg_val() { return BoardAdc_get_val(ECG_ADC_CHANNEL); }
int16_t BoardEcgSensor_nlod_get_connected_state() { return true; }
int16_t BoardEcgSensor_plod_get_connected_state() { return true; }
int16_t BoardEcgSensor_plod_get_ecg_val() { return 0; }
int16_t BoardEcgSensor_plod_get_connected_state_after_filter() { return plod_state_is_connected(); }
int16_t BoardEcgSensor_plod_state_has_disconnected_ms() { return plod_state_has_disconnected_ms(); }

8
app/src/device_state.h

@ -17,9 +17,7 @@ typedef enum {
kevent_capture_little_data_block_event, //
} app_event_type_t;
typedef struct {
uint16_t data;
} one_frame_data_t;
typedef uint16_t one_frame_t;
typedef struct {
app_event_type_t eventType;
@ -27,8 +25,8 @@ typedef struct {
uint32_t plod_connected_accumulation_time; //
uint8_t* capture_data_cache; // 256
struct {
uint32_t frameIndex;
one_frame_data_t data[LITTLE_DATA_BLOCK_FRAME_NUM];
uint32_t frameIndex;
one_frame_t data[LITTLE_DATA_BLOCK_FRAME_NUM];
} little_data_block;
} val;
} app_event_t;

108
app/src/heart_ware_sample_data_mgr.c

@ -0,0 +1,108 @@
#include "app_event.h"
#include "app_event_distribute.h"
#include "basic/qrs_time_domain_zh.h"
#include "board/board_ecg_sensor.h"
#include "heart_wave_sample_service.h"
#include "nrfx_timer.h"
static uint32_t m_frame_index = 0; //
/***********************************************************************************************************************
* ab buffer *
***********************************************************************************************************************/
#define FRAME_BUFFER_SIZE (256 / sizeof(one_frame_t))
static one_frame_t m_capture_buffer_a[FRAME_BUFFER_SIZE];
static one_frame_t m_capture_buffer_b[FRAME_BUFFER_SIZE];
static one_frame_t* m_capture_buffer;
static one_frame_t m_capture_buffer_index = 0;
static void eeprom_cache_buffer_swap() {
if (m_capture_buffer == NULL) {
m_capture_buffer = m_capture_buffer_a;
m_capture_buffer_index = 0;
return;
}
if (m_capture_buffer == m_capture_buffer_a) {
m_capture_buffer = m_capture_buffer_b;
} else {
m_capture_buffer = m_capture_buffer_a;
}
m_capture_buffer_index = 0;
return;
}
/***********************************************************************************************************************
* littlebuffer *
***********************************************************************************************************************/
static one_frame_t m_prepare_data_cache[LITTLE_DATA_BLOCK_FRAME_NUM];
static uint32_t m_prepare_data_cache_index;
static inline void preview_data_cache_push_data(one_frame_t data) {
if (m_prepare_data_cache_index >= LITTLE_DATA_BLOCK_FRAME_NUM) {
return;
}
m_prepare_data_cache[m_prepare_data_cache_index] = data;
m_prepare_data_cache_index++;
}
static inline bool preview_data_cache_is_full(void) {
if (m_prepare_data_cache_index >= LITTLE_DATA_BLOCK_FRAME_NUM) {
return true;
}
return false;
}
static inline void preview_data_cache_clear(void) { m_prepare_data_cache_index = 0; }
static inline void preview_data_trigger_event() {
static app_event_t event;
event.eventType = kevent_capture_little_data_block_event;
for (uint32_t i = 0; i < LITTLE_DATA_BLOCK_FRAME_NUM; i++) {
event.val.little_data_block.data[i] = m_prepare_data_cache[i];
}
event.val.little_data_block.frameIndex = m_frame_index - LITTLE_DATA_BLOCK_FRAME_NUM;
AppEvent_pushEvent(&event);
}
/***********************************************************************************************************************
* EXT *
***********************************************************************************************************************/
void hwsd_mgr_push_one_frame(one_frame_t data) {
m_frame_index++;
/***********************************************************************************************************************
* EEPROM数据采样存储 *
***********************************************************************************************************************/
if (m_capture_buffer == NULL) eeprom_cache_buffer_swap();
if (m_capture_buffer_index < FRAME_BUFFER_SIZE) {
m_capture_buffer[m_capture_buffer_index++] = data;
}
if (m_capture_buffer_index == FRAME_BUFFER_SIZE) {
app_event_t evt;
evt.eventType = kevent_capture_256data_event;
evt.val.capture_data_cache = (uint8_t*)m_capture_buffer;
eeprom_cache_buffer_swap();
AppEvent_pushEvent(&evt);
}
/*******************************************************************************
* *
*******************************************************************************/
/**
* @brief
*/
preview_data_cache_push_data(data);
if (preview_data_cache_is_full()) {
preview_data_trigger_event();
preview_data_cache_clear();
}
}
void hwsd_mgr_reset_buffer(){
m_frame_index = 0;
m_capture_buffer = NULL;
m_capture_buffer_index = 0;
preview_data_cache_clear();
}

9
app/src/heart_ware_sample_data_mgr.h

@ -0,0 +1,9 @@
#pragma once
#include <stdint.h>
#include "app_event.h"
#include "app_event_distribute.h"
#include "nrfx_timer.h"
void hwsd_mgr_push_one_frame(one_frame_t data);
void hwsd_mgr_reset_buffer();

107
app/src/heart_wave_sample_data_pre_process.c

@ -0,0 +1,107 @@
#include "heart_wave_sample_data_pre_process.h"
/***********************************************************************************************************************
* ALGO *
***********************************************************************************************************************/
typedef struct {
float value;
float efectiveFactor;
} filter_t;
typedef struct {
float coef[2];
float v_out[2];
} LPFilter;
#define PI 3.14159265358979323846f
static float Filter(filter_t* filter, float newInput) {
float newv = ((float)filter->value * (1.0f - filter->efectiveFactor)) + ((float)newInput * filter->efectiveFactor);
filter->value = newv;
return newv;
}
void LPFilter_Init(LPFilter* filter, float cutoffFreqHz, float sampleTimeS) {
float RC = 0.0;
RC = 1.0 / (2 * PI * cutoffFreqHz);
filter->coef[0] = sampleTimeS / (sampleTimeS + RC);
filter->coef[1] = RC / (sampleTimeS + RC);
filter->v_out[0] = 0.0;
filter->v_out[1] = 0.0;
}
float LPFilter_Update(LPFilter* filter, float v_in) {
filter->v_out[1] = filter->v_out[0];
filter->v_out[0] = (filter->coef[0] * v_in) + (filter->coef[1] * filter->v_out[1]);
return (filter->v_out[0]);
}
/**
* @brief
*
* @param val
* @param valcener
* @param amp
* @return float
*/
static float amp_display_val(uint16_t val, uint16_t valcener, float amp) {
float valf = (float)val - valcener;
valf = valf * amp;
valf += valcener;
if (valf >= 100) {
valf = 100;
}
if (valf <= 0) {
valf = 0;
}
return valf;
}
uint16_t getRecommendedMagnification() {
// return 0;
uint16_t max = QRS_getMaxValueLastVal();
if (max == 0) {
return 15;
}
// 3750.0f
if (max <= (3750 / 2)) {
return 15;
}
float af = (3750 / 2) / (max - 3750 / 2);
if (af > 15) {
return 15;
}
return af;
}
/***********************************************************************************************************************
* VAR *
***********************************************************************************************************************/
static one_frame_t m_datacache;
static one_frame_t m_displaydata;
filter_t m_filter = {0, 0.8};
LPFilter m_lpfilter_01;
LPFilter m_lpfilter_02;
void hwsd_pre_processer_init() { QRS_resetBuf(); }
void hwsd_pre_processer_process(one_frame_t framdata) { //
m_datacache = framdata;
m_displaydata = framdata;
/*******************************************************************************
* *
*******************************************************************************/
// QRS_getMaxValueLastVal();
// float lowpassf_val = LPFilter_Update(&m_lpfilter_01, framdata);
// QRS_processData(lowpassf_val);
// float val_af100 = (float)lowpassf_val / 3750.0f * 100; // 3.6v,3.3v
// val_af100 = amp_val(val_af100, 50, getRecommendedMagnification());
// val_af100 = LPFilter_Update(&m_lpfilter_02, val_af100);
// m_displaydata = m_datacache;
}
uint16_t hwsd_pre_processer_get_display_data() { return m_displaydata; }
one_frame_t hwsd_pre_processer_get_storage_data() { return m_datacache; }

9
app/src/heart_wave_sample_data_pre_process.h

@ -0,0 +1,9 @@
#pragma once
#include <stdint.h>
#include "app_event.h"
void hwsd_pre_processer_init();
void hwsd_pre_processer_process(one_frame_t framdata);
one_frame_t hwsd_pre_processer_get_display_data();
one_frame_t hwsd_pre_processer_get_storage_data();

227
app/src/heart_wave_sample_service.c

@ -4,189 +4,31 @@
#include "app_event_distribute.h"
#include "basic/qrs_time_domain_zh.h"
#include "board/board_ecg_sensor.h"
#include "heart_ware_sample_data_mgr.h"
#include "heart_wave_sample_data_pre_process.h"
#include "nrfx_timer.h"
static uint16_t m_capture_buffer_a[128];
static uint16_t m_capture_buffer_b[128];
typedef enum {
kidle,
kprepare,
kcapture,
} capture_state_t;
static uint16_t* m_capture_buffer;
static uint16_t m_capture_buffer_index = 0;
volatile static float m_sensor_display_data = 0; // 0->100
static uint32_t m_start_capture_tp;
static uint32_t m_frame_index = 0;
static bool m_prepare_capture = false;
static one_frame_data_t m_sensor_little_frame_cache[LITTLE_DATA_BLOCK_FRAME_NUM];
static uint32_t m_little_frame_index;
static capture_state_t m_prepare_capture_state = kidle;
static uint32_t m_start_capture_tp;
static nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(HEART_WAVE_SAMPLE_TMR_INSTANCE);
static void swap_buffer() {
if (m_capture_buffer == NULL) {
m_capture_buffer = m_capture_buffer_a;
m_capture_buffer_index = 0;
return;
}
if (m_capture_buffer == m_capture_buffer_a) {
m_capture_buffer = m_capture_buffer_b;
} else {
m_capture_buffer = m_capture_buffer_a;
}
m_capture_buffer_index = 0;
return;
}
static float amp_val(uint16_t val, uint16_t valcener, float amp) {
float valf = (float)val - valcener;
valf = valf * amp;
valf += valcener;
if (valf >= 100) {
valf = 100;
}
if (valf <= 0) {
valf = 0;
}
return valf;
}
typedef struct {
float value;
float efectiveFactor;
} filter_t;
typedef struct {
float coef[2];
float v_out[2];
} LPFilter;
#define PI 3.14159265358979323846f
filter_t m_filter = {0, 0.8};
LPFilter m_lpfilter_01;
LPFilter m_lpfilter_02;
static float Filter(filter_t* filter, float newInput) {
float newv = ((float)filter->value * (1.0f - filter->efectiveFactor)) + ((float)newInput * filter->efectiveFactor);
filter->value = newv;
return newv;
}
void LPFilter_Init(LPFilter* filter, float cutoffFreqHz, float sampleTimeS) {
float RC = 0.0;
RC = 1.0 / (2 * PI * cutoffFreqHz);
filter->coef[0] = sampleTimeS / (sampleTimeS + RC);
filter->coef[1] = RC / (sampleTimeS + RC);
filter->v_out[0] = 0.0;
filter->v_out[1] = 0.0;
}
float LPFilter_Update(LPFilter* filter, float v_in) {
filter->v_out[1] = filter->v_out[0];
filter->v_out[0] = (filter->coef[0] * v_in) + (filter->coef[1] * filter->v_out[1]);
return (filter->v_out[0]);
}
/*******************************************************************************
* *
*******************************************************************************/
static inline void prvf_little_block_cache_push_one_frame(uint16_t data) {
if (m_little_frame_index >= LITTLE_DATA_BLOCK_FRAME_NUM) {
return;
}
m_sensor_little_frame_cache[m_little_frame_index].data = data;
m_little_frame_index++;
}
static inline bool prvf_light_block_cache_is_full(void) {
if (m_little_frame_index >= LITTLE_DATA_BLOCK_FRAME_NUM) {
return true;
}
return false;
}
static inline void prvf_light_block_cache_clear(void) { m_little_frame_index = 0; }
static inline void prvf_light_block_trigger_event() {
static app_event_t event;
event.eventType = kevent_capture_little_data_block_event;
for (uint32_t i = 0; i < LITTLE_DATA_BLOCK_FRAME_NUM; i++) {
event.val.little_data_block.data[i].data = m_sensor_little_frame_cache[i].data;
}
event.val.little_data_block.frameIndex = m_frame_index - LITTLE_DATA_BLOCK_FRAME_NUM;
// ZLOGI("%d", event.val.little_data_block.frameIndex);
AppEvent_pushEvent(&event);
}
// QRS_getMaxValueLastVal();
uint16_t getRecommendedMagnification() {
// return 0;
uint16_t max = QRS_getMaxValueLastVal();
if (max == 0) {
return 15;
}
// 3750.0f
if (max <= (3750 / 2)) {
return 15;
}
float af = (3750 / 2) / (max - 3750 / 2);
if (af > 15) {
return 15;
}
return af;
}
void nrfx_timer_event_handler(nrf_timer_event_t event_type, void* p_context) { //
uint16_t val = BoardEcgSensor_plod_get_ecg_val(); // 12bit
/*******************************************************************************
* *
*******************************************************************************/
// QRS_getMaxValueLastVal();
int16_t lowpassf_val = LPFilter_Update(&m_lpfilter_01, val);
QRS_processData(lowpassf_val);
float val_af100 = (float)lowpassf_val / 3750.0f * 100; // 3.6v,3.3v
val_af100 = amp_val(val_af100, 50, getRecommendedMagnification());
val_af100 = LPFilter_Update(&m_lpfilter_02, val_af100);
m_sensor_display_data = val_af100;
if (m_prepare_capture) return;
/*******************************************************************************
* *
*******************************************************************************/
m_frame_index++;
if (m_capture_buffer == NULL) {
swap_buffer();
}
if (m_capture_buffer_index < 128) {
m_capture_buffer[m_capture_buffer_index++] = val;
}
if (m_capture_buffer_index == 128) {
app_event_t evt;
evt.eventType = kevent_capture_256data_event;
evt.val.capture_data_cache = (uint8_t*)m_capture_buffer;
swap_buffer();
AppEvent_pushEvent(&evt);
}
/*******************************************************************************
* *
*******************************************************************************/
/**
* @brief
*/
prvf_little_block_cache_push_one_frame(val);
if (prvf_light_block_cache_is_full()) {
prvf_light_block_trigger_event();
prvf_light_block_cache_clear();
static uint16_t val = 25;
val++;
if (val > 75) val = 25;
if (m_prepare_capture_state == kprepare) {
hwsd_pre_processer_process(val);
} else if (m_prepare_capture_state == kcapture) {
hwsd_pre_processer_process(val);
hwsd_mgr_push_one_frame(hwsd_pre_processer_get_storage_data());
}
}
@ -214,44 +56,29 @@ void hwss_init(void) {
}
void hwss_uninit(void) { nrfx_timer_disable(&m_timer); }
void hwss_start_prepare_capture(void) {
m_start_capture_tp = znordic_getpower_on_s();
m_prepare_capture = true;
m_frame_index = 0;
swap_buffer();
LPFilter_Init(&m_lpfilter_01, 30, 0.002);
LPFilter_Init(&m_lpfilter_02, 30, 0.002);
QRS_resetBuf();
prvf_light_block_cache_clear();
m_start_capture_tp = znordic_getpower_on_s();
m_prepare_capture_state = kprepare;
hwsd_pre_processer_init();
hwsd_mgr_reset_buffer();
nrfx_timer_enable(&m_timer);
}
void hwss_start_capture(void) {
m_start_capture_tp = znordic_getpower_on_s();
m_prepare_capture = false;
// swap_buffer();
// m_frame_index = 0;
// LPFilter_Init(&m_lpfilter_01, 30, 0.002);
// LPFilter_Init(&m_lpfilter_02, 30, 0.002);
// QRS_resetBuf();
// prvf_light_block_cache_clear();
// nrfx_timer_enable(&m_timer);
m_start_capture_tp = znordic_getpower_on_s();
m_prepare_capture_state = kcapture;
}
void hwss_stop_capture(void) {
m_prepare_capture_state = kidle;
nrfx_timer_disable(&m_timer);
m_frame_index = 0;
prvf_light_block_cache_clear();
hwsd_mgr_reset_buffer();
}
float hwss_read_val(void) {
__disable_irq();
float val = m_sensor_display_data;
float val = hwsd_pre_processer_get_display_data();
__enable_irq();
return val;
}
float hwss_read_heart_rate(void) { //
return QRS_getHeartRate();
}
int hwss_has_captured_time_ms() { return (znordic_getpower_on_s() - m_start_capture_tp) * 1000; }

313
app/src/heart_wave_sample_service.c.bak

@ -1,313 +0,0 @@
#include "heart_wave_sample_service.h"
#include "app_event.h"
#include "app_event_distribute.h"
#include "basic/FIR.h"
#include "basic/HC_Chen_detect.h"
#include "basic/So_Chen_detect.h"
#include "basic/adaptive_algorithm.h"
#include "basic/Pan_Tompkins_detect.h"
#include "board/board_ecg_sensor.h"
#include "nrfx_timer.h"
static uint16_t m_capture_buffer_a[128];
static uint16_t m_capture_buffer_b[128];
static uint16_t* m_capture_buffer;
static uint16_t m_capture_buffer_index = 0;
volatile static float m_sensor_display_data = 0; // 0->100
static uint32_t m_start_capture_tp;
static uint32_t m_frame_index = 0;
static one_frame_data_t m_sensor_little_frame_cache[LITTLE_DATA_BLOCK_FRAME_NUM];
static uint32_t m_little_frame_index;
static bool m_prestart_flag;
static nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(HEART_WAVE_SAMPLE_TMR_INSTANCE);
typedef struct {
int heartSignalCnt;
int heart_rate;
uint32_t last_qrs_point;
uint32_t time_cnt;
uint32_t origin_time_cnt;
uint32_t index;
float index_f;
} QRS_t;
QRS_t m_qrs;
void QRS_reset() {
m_qrs.heartSignalCnt = 0;
m_qrs.heart_rate = 0;
m_qrs.time_cnt = 0;
m_qrs.index = 0;
m_qrs.index_f = 0;
FIR_reset_buffer();
}
void QRS_process(float value) {
bool isPeak = false;
#if 1
float result = value;
SignalPoint sp;
sp.value = result;
sp.index = m_qrs.time_cnt;
SignalPoint peak = So_Chen_detect(sp, SAMPLING_RATE * 0.25f, 4, 16);
if (peak.index != -1) {
isPeak = true;
}
#endif
#if 0
isPeak = HC_Chen_detect(value);
#endif
#if 0
static const float CV_LIMIT = 50.0f;
static const float THRESHOLD_FACTOR = 3.0f;
double mean = CalculateMean(value);
double rms = CalculateRootMeanSquare(value);
double cv = CalculateCoefficientOfVariation(value);
double threshold;
if (cv > CV_LIMIT) {
threshold = rms;
} else {
threshold = rms * (cv / 100.0f) * THRESHOLD_FACTOR;
}
bool is_peak;
SignalPoint result;
result = PeakDetect(value, m_qrs.time_cnt, threshold, &is_peak);
if (result.index != -1) {
if (is_peak) {
isPeak = true;
}
}
#endif
#if 0
double result = value;
double bandpass;
double integral;
double square;
bandpass = result;
result = Derivative(result);
result = Squar(result);
square = result;
result = MovingWindowIntegral(result);
integral = result;
SignalPoint peak = ThresholdCalculate(m_qrs.time_cnt,value,bandpass,square,integral);
if(peak.index != -1){
isPeak = true;
}
#endif
// if (isPeak) {
// uint32_t time_diff = m_qrs.time_cnt - m_qrs.last_qrs_point;
// m_qrs.last_qrs_point = m_qrs.time_cnt;
// m_qrs.heartSignalCnt++;
// // m_qrs.heart_rate = m_qrs.heartSignalCnt;
// if (m_qrs.last_qrs_point != 0) {
// m_qrs.heart_rate = 60 * (1 / (time_diff * 1.0 / SAMPLING_RATE));
// }
// }
m_qrs.time_cnt++;
}
static const void compute_heart_rate(float sample_data) {
ZASSERT(SAMPLE_RATE == 500);
m_qrs.index_f = m_frame_index / 500.0 * 360;
if ((m_qrs.index_f - m_qrs.index) > 1) {
m_qrs.index = m_qrs.index_f;
float val = sample_data;
QRS_process(FIR_filter(val));
}
}
static void swap_buffer() {
if (m_capture_buffer == NULL) {
m_capture_buffer = m_capture_buffer_a;
m_capture_buffer_index = 0;
return;
}
if (m_capture_buffer == m_capture_buffer_a) {
m_capture_buffer = m_capture_buffer_b;
} else {
m_capture_buffer = m_capture_buffer_a;
}
m_capture_buffer_index = 0;
return;
}
static float amp_val(uint16_t val, uint16_t valcener, float amp) {
float valf = (float)val - valcener;
valf = valf * amp;
valf += valcener;
if (valf >= 100) {
valf = 100;
}
if (valf <= 0) {
valf = 0;
}
return valf;
}
typedef struct {
float value;
float efectiveFactor;
} filter_t;
filter_t m_filter = {0, 0.8};
static float Filter(filter_t* filter, float newInput) {
float newv = ((float)filter->value * (1.0f - filter->efectiveFactor)) + ((float)newInput * filter->efectiveFactor);
filter->value = newv;
return newv;
}
/*******************************************************************************
* 小包数据上报 *
*******************************************************************************/
static inline void prvf_little_block_cache_push_one_frame(uint16_t data) {
if (m_little_frame_index >= LITTLE_DATA_BLOCK_FRAME_NUM) {
return;
}
m_sensor_little_frame_cache[m_little_frame_index].data = data;
m_little_frame_index++;
}
static inline bool prvf_light_block_cache_is_full(void) {
if (m_little_frame_index >= LITTLE_DATA_BLOCK_FRAME_NUM) {
return true;
}
return false;
}
static inline void prvf_light_block_cache_clear(void) { m_little_frame_index = 0; }
static inline void prvf_light_block_trigger_event() {
static app_event_t event;
event.eventType = kevent_capture_little_data_block_event;
for (uint32_t i = 0; i < LITTLE_DATA_BLOCK_FRAME_NUM; i++) {
event.val.little_data_block.data[i].data = m_sensor_little_frame_cache[i].data;
}
event.val.little_data_block.frameIndex = m_frame_index - LITTLE_DATA_BLOCK_FRAME_NUM;
// ZLOGI("%d", event.val.little_data_block.frameIndex);
AppEvent_pushEvent(&event);
}
void nrfx_timer_event_handler(nrf_timer_event_t event_type, void* p_context) { //
uint16_t val = BoardEcgSensor_plod_get_ecg_val(); // 12bit
float val_af100 = (float)val / 4096.0f * 100;
if (m_prestart_flag) {
compute_heart_rate(val_af100);
return;
} else {
compute_heart_rate(val_af100);
}
/*******************************************************************************
* 显示数据计算并赋值 *
*******************************************************************************/
m_frame_index++;
val_af100 = amp_val(val_af100, 45, 3.5f);
val_af100 = Filter(&m_filter, val_af100);
m_sensor_display_data = val_af100;
/*******************************************************************************
* 采样数据缓存 *
*******************************************************************************/
if (m_capture_buffer == NULL) {
swap_buffer();
}
if (m_capture_buffer_index < 128) {
m_capture_buffer[m_capture_buffer_index++] = val;
}
if (m_capture_buffer_index == 128) {
app_event_t evt;
evt.eventType = kevent_capture_256data_event;
evt.val.capture_data_cache = (uint8_t*)m_capture_buffer;
swap_buffer();
AppEvent_pushEvent(&evt);
}
/*******************************************************************************
* 实时采样数据事件上报 *
*******************************************************************************/
/**
* @brief 缓存数据,并触发小数据块事件
*/
prvf_little_block_cache_push_one_frame(val);
if (prvf_light_block_cache_is_full()) {
prvf_light_block_trigger_event();
prvf_light_block_cache_clear();
}
}
void hwss_init(void) {
static bool m_timer_inited = false;
if (!m_timer_inited) {
/**
* @brief 初始化定时器
*/
static nrfx_timer_config_t timer_cfg = {
.frequency = NRF_TIMER_FREQ_500kHz,
.mode = NRF_TIMER_MODE_TIMER,
.bit_width = NRF_TIMER_BIT_WIDTH_24,
.p_context = NULL,
.interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY,
};
// nrfx_timer_init(&m_timer, &timer_cfg, nrfx_timer_event_handler);
ZERROR_CHECK(nrfx_timer_init(&m_timer, &timer_cfg, nrfx_timer_event_handler));
uint32_t timer_ticks = nrfx_timer_ms_to_ticks(&m_timer, 2); //
ZASSERT(SAMPLE_RATE == 500);
nrfx_timer_extended_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, timer_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
m_timer_inited = true;
}
}
void hwss_uninit(void) { nrfx_timer_disable(&m_timer); }
void hwss_pre_start_capture(void) {
m_start_capture_tp = znordic_getpower_on_s();
swap_buffer();
m_frame_index = 0;
QRS_reset();
prvf_light_block_cache_clear();
nrfx_timer_enable(&m_timer);
m_prestart_flag = true;
}
void hwss_start_capture(void) { m_prestart_flag = false; }
void hwss_stop_capture(void) {
nrfx_timer_disable(&m_timer);
m_frame_index = 0;
prvf_light_block_cache_clear();
}
float hwss_read_val(void) {
__disable_irq();
float val = m_sensor_display_data;
__enable_irq();
return val;
}
float hwss_read_heart_rate(void) { //
return m_qrs.heart_rate;
}
int hwss_has_captured_time_ms() { return (znordic_getpower_on_s() - m_start_capture_tp) * 1000; }

23
app/src/one_conduction_main.c

@ -181,7 +181,8 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) {
else if (BoardEcgSensor_plod_get_connected_state_after_filter() && znordic_haspassed_ms(lasttrypoweron_time) >= LOW_BATTERY_REMINDER_DELAY_MS) {
lasttrypoweron_time = znordic_getpower_on_ms();
if (BoardBattery_get_battery_level() > APP_WORK_BATTERY_LEVEL) {
// if (BoardBattery_get_battery_level() > APP_WORK_BATTERY_LEVEL) {
if (true) {
state_machine__change_to_poweroning_state();
} else {
BoardLight_load();
@ -195,9 +196,9 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) {
if (!znordic_rtc_has_setted()) {
ENTER_DEEP_SLEEP();
}
if (APP_BATTERY_PROTECT_LEVEL > BoardBattery_get_battery_level()) {
ENTER_DEEP_SLEEP();
}
// if (APP_BATTERY_PROTECT_LEVEL > BoardBattery_get_battery_level()) {
// ENTER_DEEP_SLEEP();
// }
}
}
@ -245,10 +246,12 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) {
}
}
#if 0
//
else if (BoardBattery_get_battery_level() < APP_AUTO_STANDY_BATTERY_LEVEL && ds_cur_state_haspassed_ms() > 3000) {
state_machine__change_to_standby_state();
} //
#endif
else if (!ble_is_upload_record() && zble_module_is_connected() && zdatachannel_last_rx_data_haspassed_s() >= BLE_UNCONNECTED_OVERTIME_S) {
ZLOGI("auto sleep because ble unconnected");
@ -339,11 +342,11 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) {
//
ZASSERT(LITTLE_DATA_BLOCK_FRAME_NUM == 5);
ble_cmder_try_report_one_sample_data(p_event->val.little_data_block.frameIndex, //
p_event->val.little_data_block.data[0].data, //
p_event->val.little_data_block.data[1].data, //
p_event->val.little_data_block.data[2].data, //
p_event->val.little_data_block.data[3].data, //
p_event->val.little_data_block.data[4].data);
p_event->val.little_data_block.data[0], //
p_event->val.little_data_block.data[1], //
p_event->val.little_data_block.data[2], //
p_event->val.little_data_block.data[3], //
p_event->val.little_data_block.data[4]);
}
/*******************************************************************************
@ -431,7 +434,7 @@ void one_conduction_main() {
BoardEcgSensor_init();
BoardLight_Init();
BoardBattery_load();
#if 1
#if 0
if (BoardBattery_get_battery_level() < APP_WORK_BATTERY_LEVEL) {
BoardLight_load();
BoardLight_blockFlash(3, 100);

Loading…
Cancel
Save