不爱胡萝卜的仓鼠 发表于 2024-11-4 22:41

[STM32H7R/S]测评 ⑦制作一个NANO EDGE AI STUDIO采集数据使用的Data Logger

<div class='showpostmsg'> 本帖最后由 不爱胡萝卜的仓鼠 于 2024-11-6 21:09 编辑

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们使用nano edge ai这个软件训练模型时,需要提供样本数据用于训练。在nano edge ai中可以有2中方式上传样本数据:提前准备好的CSV文件、串口实时采集。这两种方案可以根据大家自己的实际情况来选择</p>

<div style="text-align: center;"></div>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>CSV:适合已经有样本数据,或者不方便实时采集的场景使用。然后需要把数据按照制定文件格式填写再上传。</p>

<p>串口:串口实时采集的好处是可以现场采集,但是需要单片机可以通过串口实时传输制定格式的</p>

<p>&nbsp;</p>

<p>针对串口这种方式,我们可以选择使用ST提供的现成的datalogger,也可以选择自己做的</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:24px;">一.ST 提供的dataLogger</span></strong></p>

<p>在nano edge ai界面的左上角有个dataLogeer的按钮</p>

<div style="text-align: center;"></div>

<p>点击后就会展示ST为你提供了哪些开发板</p>

<div style="text-align: center;"></div>

<div style="text-align: center;"></div>

<p>数量还是比较可观的,有接近20种</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 我们随便点一个开发板,就可以选择采集数据的传感器和配置参数</p>

<div style="text-align: center;"></div>

<p>当生成后你会得到一个压缩包</p>

<div style="text-align: center;"></div>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这个bin直接烧录就可以使用了。因为我手上没有对应的开发板,因此没法给大家试用</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 如果你想得到源码,ST也是提供了的,在下面这个地方就可以得到源码</p>

<div style="text-align: center;"></div>

<div style="text-align: center;">&nbsp;</div>

<p><strong><span style="font-size:24px;">二.自己做dataLogger</span></strong></p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 因为上面说了,我没有对应的开发板,并且我们本次是H7R/S开发板的测评,所以我就用H7R/S开发板做一个dataLogger。</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; 在写代码前,我们需要了解一下dataLogger到底实现了一个怎样的功能,或者说他需要发出什么格式的数据。软件数据说明界面如下</p>

<div style="text-align: center;"></div>

<p>在界面中ST其实已经简单描述了他所需的数据内容,这个东西已经写得很生动形象了。我们需要采集很多轮的数据,对应界面中的line。然后每一轮数据采集时,需要以一定的频率采样数据,每轮采样最多采集256次。</p>

<p>&nbsp;</p>

<p>例如我这边是采集的加速度计的数据,并且3轴数据都采集,采集M轮,每轮采样N+1次数据,那么最终得到的结果就是</p>

<p>line1(第一轮采样):ACC_X_0&nbsp; ACC_Y_0&nbsp; ACC_Z_0&nbsp; ACC_X_1&nbsp; ACC_Y_1&nbsp;&nbsp;ACC_Z_1&nbsp;......&nbsp;ACC_X_N&nbsp; ACC_Y_N&nbsp; ACC_Z_N</p>

<p>。。。。。。</p>

<p>lineM(第M轮采样):。。。。。。</p>

<p>&nbsp;</p>

<p>如果你是其他数据,假设每次采样只有一个数据,假设为一个轴的加速度,那么每一轮数据如下</p>

<p>lineX:ACC_X_0&nbsp; ACC_X_1&nbsp;......&nbsp;ACC_X_N</p>

<p>&nbsp;</p>

<p>这是最终呈现在软件中的,那么我们开发板上传数据格式是怎么样的呢?是有什么协议?而且如何区分那几个字符是这个数据,那几个字符是那个数据?每一轮的数据是如何区分的呢?这部分并没有在这个页面中详细展示。</p>

<p>以下是我摸索的结果,数据传输没有很正式的协议,只有一些简单的数据格式,打印都是以文本的形式发送的:【数据】【分隔符】【数据】【分隔符】。。。。。。【数据】【/r/n】【数据】【分隔符】。。。。。。</p>

<p>每次采样有几个数据在nano dege ai工程配置时就已经设置好了,这个软件是知道的。然后每个数据之间是通过分隔符来进行区分的,分隔符可以有很多种选择,例如逗号、空格等等,具体后面有说明。每轮数据之间用换行回车进行区分(/r/n都要,不然会识别异常)</p>

<p>&nbsp;</p>

<p>思路都理清楚了,下面就开始修改代码,我的代码沿用上次<a href="https://bbs.eeworld.com.cn/thread-1296583-1-1.html" target="_blank">测评 ⑤X-NUCLEO-IKS4A1 MEMS传感器移植</a>的工程</p>

<p>首先要定义一些变量</p>

<pre>
<code class="language-cpp">#define ACC_SAMPLE_MAX 64
#define AXIS3</code></pre>

<pre>
<code class="language-cpp">static int acc_sample_buffer = {0};</code></pre>

<p>我们会把采样得到的数据存放到这个buffer中,然后再统一打印出来</p>

<div style="text-align: center;">
<div style="text-align: center;"></div>

<p>&nbsp;</p>
</div>

<p>&nbsp;</p>

<p>接下来改造while1,因为我们只使用了开发板上的一个传感器,因此之前的for循环就可以不要了,直接改成如下</p>

<pre>
<code class="language-cpp">while (1)
{
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
#if 1
    Accelero_Sensor_Handler(0);
    HAL_Delay(100);
#endif

}
/* USER CODE END 3 */
</code></pre>

<div style="text-align: center;">
<div style="text-align: center;">
<div style="text-align: center;"></div>

<p>&nbsp;</p>
</div>

<p>&nbsp;</p>
</div>

<p>直接调用ACC传感器处理函数,入参为0,因为只有一个传感器,第一个传感器的序号在数组中就是0。delay函数是为了给打印留足时间(不知道为什么,我切回这个分支后,原先调通的printf突然不能用了,很奇怪,我就只能用HAL_UART_Transmit函数,但是他需要delay一下,不然他数据无法打印出来)</p>

<p>&nbsp;</p>

<p>然后我们需要对Accelero_Sensor_Handler函数进行修改,原先的demo是会把很多乱七八糟的数据都打印出来,现在不需要了,我们要在里面for循环完成数据采集,然后再for循环按之前说的格式把数据打印出来。改造后的函数如下</p>

<pre>
<code class="language-cpp">static void Accelero_Sensor_Handler(uint32_t Instance)
{

IKS4A1_MOTION_SENSOR_Axes_t acceleration;
uint16_t i = 0;

for (i = 0; i &lt; ACC_SAMPLE_MAX;)
{
    if (0 == IKS4A1_MOTION_SENSOR_GetAxes(Instance, MOTION_ACCELERO, &amp;acceleration))
    {
      acc_sample_buffer = (int)acceleration.x;
      acc_sample_buffer[(AXIS * i) + 1] = (int)acceleration.y;
      acc_sample_buffer[(AXIS * i) + 2] = (int)acceleration.z;

      i++;
    }
}

unsigned char data = {0};
uint8_t len = 0;
for(i = 0; i &lt; ACC_SAMPLE_MAX - 1; i++)
{
    sprintf(data, "%d,%d,%d,", acc_sample_buffer, acc_sample_buffer, acc_sample_buffer);
    len = strlen(data);
    HAL_UART_Transmit(&amp;huart4, data, len, 0xFFFF);
}
sprintf(data, "%d,%d,%d", acc_sample_buffer, acc_sample_buffer, acc_sample_buffer);
len = strlen(data);
HAL_UART_Transmit(&amp;huart4, data, len, 0xFFFF);



unsigned char data2[] = {"\r\n"};
len = strlen(data2);
HAL_UART_Transmit(&amp;huart4, data2, len, 0xFFFF);

}</code></pre>

<p>&nbsp;</p>

<div style="text-align: center;"></div>

<p>&nbsp;</p>

<p>然后为了提高串口打印速率,我还把波特率从默认的115200改成了921600(我直接改代码了,就不再cubemx中修改了,一来这个分支的代码以后不会再重新生成工程了,而来重新生成又要改ld,太麻烦了)</p>

<div style="text-align: center;"></div>

<p>&nbsp;</p>

<p>这样基本上就完工了,代码写的有点乱,调试了太久时间了,大家见谅,但是基本功能是OK的。</p>

<p>运行后SSCOM日志如下:</p>

<div style="text-align: center;"></div>

<p>&nbsp;</p>

<p><strong><span style="font-size:24px;">三.测试功能</span></strong></p>

<p>&nbsp; &nbsp; 接下来我们就去nano edge ai中测试一下功能。nano edge ai怎么创工程等步骤和说明会在后续的文章中说,我们今天就直接跳到数据采集的步骤。</p>

<p>&nbsp;</p>

<p>首先需要选择上传数据,并使用串口上传数据</p>

<div style="text-align: center;"></div>

<div style="text-align: center;">
<p>&nbsp;</p>

<div style="text-align: center;"></div>
</div>

<p>当我们选择串口的方式后,会弹出如下界面</p>

<div style="text-align: center;"></div>

<p>需要选择开发板的串口和波特率</p>

<div style="text-align: center;"></div>

<p>然后我们可以配置采样数据的最大轮数,如果不选的话,他会一直采集,知道你按下stop。反之到了最大值他就自动停止了</p>

<div style="text-align: center;"></div>

<p>最后点击start就可以开始采样了,我们可以实时看到采样的轮数,还有每次采样得到的数据</p>

<div style="text-align: center;"></div>

<div style="text-align: center;">&nbsp;</div>

<div style="text-align: center;">
<div style="text-align: center;"></div>

<p>&nbsp;</p>
</div>

<p>采样结束后点击continue就会对数据进行解析,然后就可以得到数据解析的结果,如下界面所示</p>

<div style="text-align: center;"></div>

<p>在这个界面的左边,我们就可以选择使用哪种分隔符,第一个就是逗号,也是我使用的,这块就不用改。右边就是解析得到的结果。</p>

<p>line_index就是采样的轮数。</p>

<p>nb_columns就是数据个数,例如我代码中写的3轴数据*采样64次=192个数据</p>

<p>&nbsp;</p>

<p>如果数据正常就是白色的,如果解析有明显异常会是红色的(如果只有一两条数据有错误,那可能是串口传输误码,如果有很多建议你好好看看原始数据是否符合规定,我一开始每轮之间用了/n,他就异常了,前面5条数据全部标红,后面白,但是白的数据明显也是错误的)。</p>

<p>我们可以选择delete打钩,删除掉异常数据。白色数据其实也要看看,因为里面可能会存在一些采样到的数据明显是不正常的,这个就需要人工过滤了</p>

<p>&nbsp;</p>

<p>数据检查无误后,就可以点击import,加载数据了</p>

<div style="text-align: center;"></div>

<p>这些数据如何进一步使用,我们就在后续文章中说了。今天这个dataloger的制作与使用算是圆满完成</p>

<p>&nbsp;</p>


补充内容 (2024-11-12 11:49):
本文datalogger的代码中打印输出结果部分代码有重大BUG,已在链接文章中修复:测评 ⑨nano edge ai studio 训练一个模型--下 https://bbs.eeworld.com.cn/thread-1298763-1-1.html</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

电子烂人 发表于 2024-11-7 09:22

<p>请问下,这个用的是三轴的数据吗,我用的一轴加速度但是软件采集数据不正确</p>

不爱胡萝卜的仓鼠 发表于 2024-11-7 09:54

电子烂人 发表于 2024-11-7 09:22
请问下,这个用的是三轴的数据吗,我用的一轴加速度但是软件采集数据不正确

<p>我这个是3轴的,然后nano edge ai第一步我也是选择的加速度计,三轴。</p>

<p>&nbsp;</p>

<p>你看看是不是你第一步配置的时候不是配置的1轴?还有SSCOM收到的数据、nano edge ai显示数据不正确的截图方便放一下吗?我们交流交流</p>

电子烂人 发表于 2024-11-7 13:06

<p>第一步配置的是一轴,我做的电机监测,当震动传感器用,故也不需要太多</p>

<p>当时的截图:<img src="https://bbs.21ic.com/data/attachment/forum/202409/18/194540k31zh9sfim999h9s.png.thumb.jpg" /></p>

<p>感觉像是数据收发不正常,只收到了一点点,然后就扔进数据处理了</p>

<p>&nbsp;</p>

不爱胡萝卜的仓鼠 发表于 2024-11-7 14:04

电子烂人 发表于 2024-11-7 13:06
第一步配置的是一轴,我做的电机监测,当震动传感器用,故也不需要太多

当时的截图:

感觉像是数据收 ...

<p>这个解析结果肯定有问题,他这里都打感叹号了。</p>

<p>首先得确定一下你一共采样了几轮,还有每轮采样几次?</p>

<p>他这边解析出来采样138轮,每轮采样3次,每轮每个周采样3次。说明一个轴这个配置应该是没啥问题了。</p>

<p>我认为每轮采样3次太少了(这个要具体看代码你是不是写的一轮只采样3次)。还有一种可能就是数据格式有问题,导致他解析不正确</p>

电子烂人 发表于 2024-11-7 14:29

不爱胡萝卜的仓鼠 发表于 2024-11-7 14:04
这个解析结果肯定有问题,他这里都打感叹号了。

首先得确定一下你一共采样了几轮,还有每轮采样几次? ...

<p>这边我是用的datalogger的源代码修改的,因为涉及到多个传感器,所以把其他的部分全都删掉;只留下了加速度计的一轴数据。</p>

<p>我猜测也是修改的时候改的数据格式有问题,采样的图窗只有前几段的数据,后面的数据就看不见了。等我回去看一下当时具体的采样速度。</p>

电子烂人 发表于 2024-11-29 10:11

<p>&nbsp; 您好大佬,采集的数据是这样的,您那份代码我重新看了,还是不太理解这个数据的格式</p>

<p>我的数据格式为:</p>

<p> &nbsp;</p>

<p>识别到的却还是一轴的加速度计</p>

不爱胡萝卜的仓鼠 发表于 2024-11-29 11:19

电子烂人 发表于 2024-11-29 10:11
&nbsp; 您好大佬,采集的数据是这样的,您那份代码我重新看了,还是不太理解这个数据的格式

我的数据格 ...

<p>我不太理解你要采样什么样的数据?是三轴的还是一轴的?看你的软件截图,你是配置了一轴(就是Number of values per aixs,这个是你在软件第一步中选择传感器时配置的)。但是你的单片机输出的却是3轴数据。</p>

<p>如果你要三轴数据,那么就要回到上一步,选择3轴。</p>

<p>如果要1轴,就要改代码,打印时另外两轴别打印(采样时是否读取或保存另外两轴数据随意,只要不打印出来就好)</p>

<p>&nbsp;</p>

<p>另外还有一个问题,就是你每次采样完成后,貌似直接换行回车了,这也是不对的,换行回车的含义是一轮采样结束了,就是对应软件中的line。(一轮=采样n次)只要还没有到达本轮采样的max,所有数据之间都是用分割符隔开(就是你的那个逗号)</p>

<p>&nbsp;</p>

<p>例如你只想采集X轴的数据,采样200次/轮,共采样100轮。</p>

<p>1.先完成200次X轴数据的采样并保存到一个数组中(Y和Z轴是否读取数据或是否保存随意)(每次采样间隔根据你的实际需求来,是10ms采样一次还是20ms采样一次看你的需求,我的代码里是没有定时啥的,就是传感器ready就读取数据)。</p>

<p>2.采样完成后,开始打印数据:,,......换行回车</p>

<p>3.打印完后再回到1,继续采样</p>

<p>&nbsp;</p>

<p>100轮这个参数由上位机读取数据的那个界面配置</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>如果你是要三轴的,打印的数据格式就是:,,,,,,......,,换行回车</p>

<p>&nbsp;</p>

<p>最后关于代码,要看文末补充内容指向的那篇文章,本文代码有问题,是不对的</p>
页: [1]
查看完整版本: [STM32H7R/S]测评 ⑦制作一个NANO EDGE AI STUDIO采集数据使用的Data Logger