WIoTa 中医馆

为了帮大家快速上手WIoTa,解决AT接口使用和二次开发过程中遇到的问题,在这里开一个汇总贴。把平时经常遇到的问题做个产总结和归档。避免多位同学在同一个地方踩坑。

本贴的宗旨是:你上手,我上心,大家都别上头~

1. Q:从github上取下来的代码异步协议在跑自带Demo程序的时候,串口出现乱码是怎么回事?


A: 这是因为Demo代码里面开启了低功耗模式,模组进低功耗之后会降低系统主频,造成的串口波特率变化。对应API函数为:

`  uc_wiota_set_lpm_mode(1);    // enter lpm mode`

处理办法是注释掉该条语句,或者参数给成0。不让模组进入低功耗状态。


修改代码重新编译之后,程序串口输出正常显示。
另一个可能原因是模组休眠时,串口的发送FIFO中还有数据没有发送完成,导致重新启动之后,继续发送之前的剩余数据。这有可能会造成数据错位的问题,导致持续乱码。
处理方法有两个:要么在休眠前,等待串口数据发送完成,要么在系统启动的时候,清一下FIFO。以下是在发休眠前等待数据发送完完的例子:

2. Q:用WIoTa转485的DTU硬件,通过AT指令操作,经常出现发送数据失败的问题。
现象如下图:


上图中,可以看到用AT指令发送数据的时候,经常出现失败的情况。同时,原本发送指令过程中模组回复的符号">"也未能正确接收。经常收到“非法指令”的提示。

A: 这是由于硬件电路中采用了自动收发切换电路,如下图所示。但是在AT指令流程中,没有考虑到485传输的半双工模式。

在做数据发送的过程中,模组会给上位机回复“>”符号,提示模组准备好了接收数据,如果上位机在模组返回该符号的时候,正好处于数据发送状态,则485电路的收发切换会导致模组不能正常接收上位的给的数据,出现错位的情况,从而导致模组判断指令非法。

处理方法:将数据发送指令分成两个次传递,第一次传递AT+WIOTASEND,等收到模组返回的提示后,第二次再传递要发送的数据。如下图所示:

3. Q:用WIoTa同步协议部署多网关应用的话,需要注意哪些问题?
A: 多网关同区域部署的话,需要考虑频点干扰问题。
(1)建议相邻区域的网关之前频点隔离做到2MHz以上。
(2)每个网关之间的子系统ID相互区分也可以降低互相干扰的问题。
(3)如果条件允许,建议打开网关间的时钟同步功能,可以进一步降低互想之间的干扰。目前,WIoTa同步协议支持通过GPS和以太网进行时钟同步。WIoTa的AP模组自带GPS授时功能,应用部署时,需要将GPS天线引出。以太网时钟同步需要用户网关支持以太网。

4. Q: WIoTa模组有时候会有复位不成功或者不复位后功能异常的问题,如何避免?
A: 目前有一种可能是串口漏电,导至复位时,模组不能全部掉电。即在对模组进行复位期间,外部TTL串口向模组的RX口有漏电进来。
处理方法:(1)在复位前,先将与模组连接的IO口拉低,再进行复位。(2)在TTL电路中加二级管等元件,防止电流倒灌。

5. Q: 为何WIoTa做通信距离测试的时候,结果有时会有较大的差异?
A: 无线通信的距离受多种因素影响,在系统的带宽和编码等配置不变的情况下,引起结果差异的外界因素也有很多,比如:
(1)天线匹配:一般的天线有效带宽可能只在10MHz范围之内,系统设置的频点在这之外的话,会有可能造成通信结果的差异;
(2)空口噪声:如果测试期间选定频点有较高的噪声,也会影响通信测试结果。
(3)天气因素:雨天和大雾天对无线信号的传播也会有较大影响。
因此,在做通信效果测试或做应用产品时,需要充分考虑这些因素。做好应用的天线匹配,针对应用场景做好频点的选取等。

6. Q:WIoTa通信协议可以用在国外不?
A:各个国家的非授权频点资源会有差异,目前在国内WIoTa模组默认按照470~510MHz频段做的适配,各用户需要把天线选择到该频段进行应用开发。如果是在国外使用,433MHz频段相对比较普遍,同时WIoTa协议也可以支持其他Sub1GHz的频段。在出货时,需要适当调整模组上的匹配电路,有批量出货需要的客户请联系销售。

7. Q:为何我的AP配置频点是160,IoTE设置的频点是100,但是IoTE还能连上AP发送数据?
A:目前已知在12M间隔会有比较大的谐波,用户在实际部署网络的时候,应尽量避免频点间隔12M以及其整数倍的频点。

8. Q: 为何用串口连模组测试低功耗的时候,会发现经常会有误唤醒状态?固件版本为异步2.6
状态和设置如下图所示:



系统在监听几次过后,自动就启动了。
A: 造成这该问题的可能原因有几种:
(1)空口中有其他用户在发唤醒信号,且配置跟当前接收端匹配。
(2)系统配置的设置的灵敏度偏高,导致虚警率高,引起系统误唤醒。
(3)供电问题,模组上接了两个不同源的电源,可能会导致电源干扰接收,产生虚警。比如,该例中,模组电源采用的电源是直流分析仪,而为了检测串口打印,在电脑上接了USB转TTL模组,并把两个TTL模块的GND和电源GND并在一起。就出现了虚警的问题。
处理方法:
(1)根据应用需求,合理配置唤醒参数;
(2)测试时,流程电源同源的问题。

9. Q: 为何在做低功耗唤醒的时候,发送侧给了指令过后,系统未能在设置的时间内正常结束发送?固件版本异步v2.6.
现象:测试时发被唤醒侧在总次被唤醒后,再进低功耗空口唤醒状态时会马上被唤醒,经过排查发现发送侧一直处理唤醒信号发送状态,如下图所示:


发送侧给的指令如下图所示:

A: 如指令空口截图所示,用户在发送侧给指令AT+WIOTALPM=1,0这个指令时,重复输入的间隔小于AT+WIOTAPAGINGTX中给定的单次发送时长,这会导致之前的发送流程无法正常结束,系统进入持续发送状态。
处理方法:
(1)用户在该版本固件使用此功能时,注意两次唤醒指令之前的时间间隔要大于信号发送的时长。
(2)升级新版本的固件。后续固件版本会优化该逻辑,防止该状态的发生。

10. Q:使用交流电源转直流给模组供电时,需要注什么?
A:需要注意电源转换后给模组提供尽量干净的电源,目前 WIoTa评估版采用LDO提供3.3V DC电源纹波在50mV左右。应用现场的硬件条件尽量降低纹波,对射频性能会比较友好。以往案例测试发现,当3.3V电源的的纹波达到500mV时,snr会恶化10dB左右,当3.3V电源纹波在200mV左右时,snr恶化在1~2db左右。
处理方法:通过单点地、添加磁珠、共轭电感等方式,尽可能滤除电源纹波噪声。

关于纹波的介绍可参考:电源中纹波和谐振产生的原因及危害分析 - 模拟技术 - 电子发烧友网

11. Q:如果评估我的网络容量呢?同步协议的系统需要部署多少个AP?异步协议的网络单次发送需要多长时间?
A:网络容量评估需要从业务模型和无线环境等方面进行评估。其中,无线环境是指在应用实际部署场景条件下,网络覆盖的范围以及在此范围内终端的分布情况。
在终端数量确定的情况下,系统的容量取决于业务模型,比如每个终端多久要发送一次数据,每次发送数据的数据长度。附件是一个容量评估计算工具,供参考。

业务模型理论值计算_v1.6.1.zip (39.2 KB)

12. Q:通过单机连接模组时,有时候会出现,有上电复位失败的问题,导致模组不能正常工作,AT指令无响应
A:模组上电时,需要保持外部引脚没有外灌电流,不然会导致上电复位异常。对于外部有单外机连接uart引脚的情况。有几种操作方式。
(1)通过修改外部单处机的引脚状态来规避。在对模组进行上电时,把与模组串口相连的单个机引脚设置为输出状态,并输出低电平。
(2)通过模组复位引脚进行复位,把模组的RESET脚拉低可以对模组进行硬复位。
(3)通过增加保护电路来防止电流倒灌,在模组串口的RX和TX上都加上二级管,起到阻断作用。一种参考接法如下图所示:
lQLPJxM72lEUc_rNAd3NAmmwzQ0Of5gIfxsENOFCskB1AA_617_477
参考二:左边是UART_TX,右边是UART_RX,VDDA和VDDB分别是各自芯片的供电电源
dbe808a09645aa30ef642e94c0c43b79
(4)上电过程中的电源毛刺造成芯片启动异常,该现象也常见于系统短时断电再上电无法启动。建议通过在模组外面增加复位芯片或看门狗芯片,在电源正常之前拉低模组复位脚,来强制对模组进行复位。常用的复位芯片如CN809.
image

13. Q: 为何烧录器有时候不能正常烧录?
A: 可能的原因有:

  1. 烧录器驱动丢失。由于当前驱动器驱动跟电脑USB接口绑定,所以烧录器在初始安装驱动时接入的USB接口需要作为烧录的专门接口,后续烧录如果根据USB接口,会出现不能识别的情况。处理方法是在更换的USB接口上,重新安装一次驱动。

解决方案:UC DAP5烧录器换USB驱动需重装问题解决

  1. 模组未能正常复位,FLASH未能正常访问。现象是烧录完成后校验不通过(卡在进度92%)。处理方法是点击烧录后,手动复位一下模组。若模组在低功耗休眠状态,可点击烧录后,再给模组上电(插入烧录排线)。
    注:新版本的烧录软件v3.2.0以后已经解决这个问题。

14. Q: 为何系统启动需要花100ms的时间?
A:系统启动时,默认会进行RTC校准,该过程会花费比较长的时间。在不需要精确定时的情况下,可以跳过此过程。关闭过后,系统启动时间在20ms内。


15. Q:SDK中没有设置Paging模式时开启外部中断的模式,如果要同时使用空中唤醒和外部中断的话,需要怎么操作?
A:目前,UCM200的外部唤醒可以使用CS脚、UART_RX和Wakeup脚。如果要同时使用外部唤醒和空中唤醒,可以使用CS脚拉低的方式来实现,此时不需要打开外部中断。

16. Q:为何我在IoTE上做二次开发后,做收发测试过程中,程序会自动跑死?*
串口2收到提示:

gen first data mode assert: D:/jpwang/wiota_riscv/PS/platform/adapter/src/adp_mem.c 112

A: 这个ASSERT报错是因为内存开辟失败,用户在做二次开发时,需要流程内存使用情况。
一是自己的线程中所申请的内存在用完后需要释放;
二是WIoTa在收到消息时,会申请内存,用户在自己的消息接收回调函数中,需要对内存进行释放。

17. Q:为何用异步协议测试的时候发3个字节数据时,不管目的地址设置成什么,对端都能收到消息?*
A:出现这个现象的原因是协议在当前版本下(异步v2.7)对第一个子帧没有做地址校验的动作,所以单播消息所有终端都能收到。当消息长度超过3字节后,这个现象将消失。
目前的规避方法是客户发送的数据量,不要少于3个字节。由于当前的异步单次发送的协议帧结构最小子帧数量为3个子帧,因此对于小数据的发送不会降低发送效率。

18. Q: 使用VS Code环境加scons编译AP固件时报错,无法正常编译


A:已知用scons的版本在4.5以上时会出现这个问题,是python数据类型不兼容导致。解决方案有两个。(1)用rt thread的env(版本1.2)工具来编译; (2)降低scons的版本到4.4。

19. Q:使用CS脚做唤醒休眠测试发现如果CS脚电平抖动或毛刺多的话,容易出现休眠失败的情况。
A:该问题是由于CS脚的电平毛刺的原因,有概率在进休眠时可能处于低电平状态,导致芯片被拉起休眠失败。
该问题存在于异步2.9和同步2.7及以前的版本,在二次开发过程中,使用了休眠逻辑的场景。新版本会修复该问题。
临时处理方法
在执行休眠指令后,加入如下代码:

        uc_wiota_sleep_enter(0,0);

        while(REG(0x1a10a000) & (1<<27))
        {
            REG(0x1a10a000) |= (1<<26);
            REG(0x1a10a000) &= ~(1<<1);
            REG(0x1a10a000) |= (1<<1);
        }

20. SPI接口调试的时候插上烧录器不通,是怎么回事?
UC8288芯片的SPI口有SPI Master和SPI Slave,这两个SPI接口在芯片引脚上有复用,而烧录器接口会使用芯片的SPI Slave接口进行程序的烧写,因此,用户在使用芯片的SPI口时,调试过程中尽量不要接烧录器,以免信号受到干扰导致SPI通信异常。

想请问下,我使用锂锰电池给UCM200供电,电池输出电压范围为2.5V~3.2V,供给模块可以正常工作吗?我看手册上写的3.3V~3.7V,模块上应该是有DC-DC的吧?

UCM200上是有DC-DC的,2.5V供给模块可以正常工作,可以再验证下2.5V供电时,发射功率是否能够达到21dBm

1. 多个终端模组一起工作收不到基站发送数据?
解决思路:查看终端模组是否修改不同userid ,测试同步连接是否建立,上行通信是否正常

2. 模组发送AT指令,只打印CCCC
解答:没有等到系统启动完成就发送AT导致的,因为AT版本有uboot启动,会有两秒的延迟,等到+SYSTEM:START打印出来之后,才能发送AT

3. 固件烧录后,板子一直重启
解决思路:

  • 确认固件版本与开发板是否匹配
  • 确认AT固件版本,WIoTa使用标准AT固件,请从github地址_bin 目录获取
  • 检查代码是否死循环,导致未释放CPU ,造成看门狗超时复位

4. 自己开发的bin烧录要注意什么
解决思路:第一次烧写的时候可以全片擦除,然后再修改静态数据(导入固件相同版本的静态配置表,先读取、修改再写入)

5. 基站插上烧写器广播则终端接收成功,如果基站直接供电则终端接收失败
解决思路:发送端在发送完成之后,做个小延时

6. 同一个传感器数据,WIoTa 终端开发板发送成功,WIoTa DTU 发送失败,怎么处理?
解决思路:考虑DTU 晶振未校准,采用SDK包内校准流程和API解决

7. WIoTa 低功耗API工作流程?
解答:开启协议栈之前,先开启低功耗,以低功耗模式运行,电流才会比较小,然后再发送数据,最后再sleep

8. 传感器采集数据不准,采用多次采集去极值算平均数,整体功耗大怎么解决?
解决思路:

  • 分析传感器采集周期,测试采集数据准确性,缩短传感器工作时间;
  • 测试传感器采集芯片最低工作主频,降低采集功耗;
  • 根据通信场景要求,配置合适的发射功率;
  • 去掉uboot界面,减少工作时间。

9.开发板同步协议测试时,终端和AP连接正常,通信距离非常短?
解决思路:
检查终端和AP协议栈启动配置参数,查看功率是否设置太低
检查AP供电,推荐使用电源适配器或者充电宝独立供电,电脑USB口供电影响测试结果

二次开发时,应用的task优先级设置,需要至少为3或更大的数值(rt_thread系统中,数值越大,优先级越低),由于协议栈内部task使用了0~2的优先级,应用层task不能比底层task优先级高。

Q:iote回调函数中发送数据给ap可能导致数据发送异常?
A:回调函数里面不要写特别复杂,特别是申请内存,超时时回调会挂掉
错误样例:

同步v2.7_iote协议栈打开event_flag后,使用at或api,在uc_wiota_exit()出现内存异常的解决办法:

:请更新到v2.9_iote版本

iote烧写时采用全擦除模式,用户id被恢复为默认id的问题:

模组出厂默认已配置唯一的用户id,不用单独设置。若重新烧写过固件,并选择了全擦除模式,会造成用户id恢复为默认值。

解决办法:
1、不使用全擦除模式
2、在应用层使用uc_wiota_get_module_id()接口,获取模组flash唯一id,再使用uc_wiota_set_userid()接口在wiota run之前设置一次id,即可以让终端具有唯一的id链接ap或网关。
注意:uc_wiota_get_module_id()返回的是字符串格式,需要转为int类型传递给uc_wiota_set_userid()

1,问题:UCM200模组的SPI可以接3个从设备么?极性和相位也能修改,操作不同的设备

解决办法:可以支持,驱动需要配合修改

2,问题:
关于AT接口中,使用va_list 、va_start、 va_arg、 vsscanf、 va_end等ANSI C宏进行格式化输出的问题:

 封装at接口时,需要用到格式化输出 va_list 、va_start、 va_arg、 vsscanf、 va_end等ANSI C宏,

由于va_arg会根据最后一个固定参数的地址,加上当前类型的长度,计算下一个可变参数的地址。
在定义临时整型变量,作为可变参数时,类型都按照最长的类型定义,比如参数中有char,有int,就都按照int类型定义,让地址对齐,
测试发现如果按照变量需求定义类型,会出现地址不连续的情况,导致解析失败。
如:以下代码中,id_len,symbol,bandwidth,pz,btvaule,spectrum等实际是unsigned char类型,systemid和subsystemid为int类型,需按照以下方式定义,才能正确获取结果:

            if (at_obj_exec_cmd(g_at_wiota_iote_client, resp, "AT+WIOTACONFIG?") == 0)
            {
                unsigned int id_len = 0;
                unsigned int symbol_length = 0;
                unsigned int bandwidth = 0;
                unsigned int pz = 0;
                unsigned int btvalue = 0;
                unsigned int spectrum_idx = 0;
                unsigned int systemid=0;
                unsigned int subsystemid = 0;
                
                if (at_resp_parse_line_args_by_kw(resp, "+WIOTASYSTEMCONFIG=", "+WIOTASYSTEMCONFIG=%d,%d,%d,%d,%d,%d,0x%x,0x%x",
                                                  &id_len, &symbol_length,&bandwidth, &pz,&btvalue,&spectrum_idx,&systemid,&subsystemid) > 0)
                {
                     config->id_len = id_len;
                     config->symbol_length = symbol_length;
                     config->bandwidth = bandwidth;
                     config->pz = pz;
                     config->btvalue = btvalue;
                     config->spectrum_idx = spectrum_idx;
                     config->systemid = systemid;
                     config->subsystemid = subsystemid;

                    break;
                }
            }

可变参数宏原理请参考: C语言函数之可变参数原理:va_start、va_arg及va_end-CSDN博客

3,问题:
编译提示counter backwards(from xxx to xxx)的问题

此问题是分配的ram空间不够,ram空间根据代码量可以自己调整,具体方式如下:
在link.flash.ld文件

4,问题:
UCM200二开时flash和ram的余量问题:

8288二开时flash和ram的余量如下:
1、flash二开时的分配情况
总共512KB,留8KB给静态存储区,如果要用uboot,还需要留28KB,
分配规则见link.flash.ld的这个区域,如下图:


其中1区的instrram需根据代码量调整大小,分配后,不管用不用,都会在flash中强占着,
其len的最大值计算方法:flash总大小512KB-静态区8KB-instrram区起始0x1D000-2区中datarom的大小,
2区中datarom的起始值和长度,在ld文件中的值没有实际意义,大小可以参考编译文件的segment 4 size这个值,请参考图2:
1a08847e0ac4c17ccf04d7229f2ca62
经过测试,当instrram的len调整到0x45000,固件大小为506KB时,基础代码还能正常运行。
即给用户的代码空间,最大可调整到0x45000(276K左右)
但代码增加,datarom可能也会随着变化,所以instrram的len值可能还需要往小了调,所以用户使用的代码空间会小于276K
2、内存使用情况
内存是240KB,但大部分已给协议栈使用,基本代码,未开启协议栈时,运行后,给用户使用的内存,
total 23924 used 5348 maxused 5484(最大23KB,基本例程已使用5KB)
开启协议栈(uc_wiota_run)后,还会占用10KB左右的内存,所以最后给用户使用的约10多K左右。

5,问题
UCM200的浮点运算选项
8288具有FPU单元,开启此单元需要在编译选项中加入f选项,例如:

-march=rv32imfc中加入f,即表示打开了fpu单元

6,问题
UCM200的ADC设计

规格书中定义的测量范围为0~1.6v,如果要测量更高电压,需要分压。
ADC 的输入,要距离电源和地超过 100mV,最好是150mV以上,避免电路进入线性区
例如:输入电压范围:0.15V~1.3V
C通道有个agc,会有个倍率在里面。平时一般使用建议用A/B通道。

7,ucm200 wakeup引脚
不推荐使用此引脚唤醒,因为比较器只能在相等时触发,一个抖动就容易数过,就再也触发不了了
推荐使用拉低spi cs引脚的方式唤醒

8,关于wiota扫频
a、配置的超时时间,是频点列表或者单个频点的超时时间,如果是全频段扫频,就没有用超时时间了,
默认超时2分钟,是基于symbol len=256配置的,如果是1024,超时差不多是256的4倍
b、如果是网关扫频,信号越好,说明此频点的干扰越大
c、如果是终端扫频,信号越好,说明次频点的干扰越小

9,关于UCM200模组的temp in a 和temp in b
1、temp_in_a/b两个通道的adc和电压值计算方式有点不一样,请参考图1
2、按照adc特性,在CHB的电路上,调整好分压,就可以直接用CHB通道测量vbat的值了,不用CHA做0点参考,也不用TEMP_IN_A做AVDD_CAP参考如图2
3、temp_b和temp_a内部的参考电压不同,不要同时使能