0


接收节点无线广播发送的数据,并printf打印出来(含核心代码)_物联网挑战赛第四届第一题

题目

赛题

数据广播节点—>
如图所示,平台节点不安装天线,12 个节点 ID 号随机,左上角的节点作为数据广播节
点,每隔 1 秒往外重复广播负载为 1 个字节的数据包(该广播代码由组委会提供),参赛队
需编写其他 11 个节点的代码,在考虑多跳传输的情况下,获取到该广播包的负载,最终 11
个节点通过 printf 语句将该负载打印到平台,从而表明任务的完成。

1) 11 个节点只允许编写一份代码,代码中可通过宏 TOS_NODE_ID 获取自身 ID 号;
2)本题开销指的是除左上角节点外的另外 11 个节点无线通信发送数据包的总和;
3)左上角节点代码由组委会提供,参赛队可自行查阅和修改负载内容(不可修改格式)
以验证代码;
4)左上角节点烧录完成 10 秒后停止评分,参赛队需在 10 秒内完成数据包的发送;
5)广播的数据为同一数据,参赛队无需多次接收并转发,多次转发时需考虑其造成的
网络开销;
6)参赛队编写的和结果无关的 printf 调试语句,必须在最终代码中注释掉,以免造成
最终结果输出错误。

格式说明

1)左上角广播的数据包的负载为一个字节,示例如下:
00 FF FF 00 00 01 00 06 12
前 8 个字节 00 FF FF 00 00 01 00 06 固定,后 1 个字节 12 为随机的某字节,参赛队
需编写代码接收此结构的数据包;
2) Printf 输出的格式为:标志位(Data)+1 个字节负载(十进制,并以空格隔开,结
尾应加上换行符“In”以表明语句的完结)
广播数据包:00 FF FF 00 00 01 00 06 12
正确的输出结果:Data 18
注意:输出的结果应完整正确,数据必须以十进制输出,例如上述示例的 0x12 的
十进制为 18;
3)每个节点的结果可重复输出,计分时只会以每个节点最后一组含有标志位 Data 的
行作为判分依据;

计分规则

本赛题满分为 30 分,其中正确性得分 22 分,开销得分 8分;
1)正确性得分:共 22 分,正确性得分不少于 14 分才可以获得开销分;
正确性得分 =22*(m/11) (m≥7)
m 为 11 个节点正确输出结果的数量
2)开销得分:共 8 分,开销超过 50 得分 0 分,小于 50 按如下公式如下:
开销得分 =8*(50-n)/50 (0<n<50)
n 为 11 个节点的开销总和

评分步骤

1)烧录 Null程序,清空节点状态;
2)编译烧录参赛队代码(参赛队的 11 个节点);
3)对 11 个节点进行 printf 监听;
4)烧录左上角数据广播节点代码,烧录完成后,开始计时;
5) 10 秒后停止监听,核实各节点的输出结果和开销量,计算出得分;

题目解析

由题目可知,右上角的节点是由主委会给出的,但因为我们这是平时练习,所以右上角节点的无线发送数据的代码,也由我们自己来写吧。

右上角节点代码解析

由题意可知,右上角这个节点,是个工具节点,其目的就是给其余11个节点每隔一秒发一个固定数据包,所以我们只需要用到无线通信的发包函数就可,再用一个定时器每隔1000毫秒调用以下无线发包函数,就完成啦。

其余11个节点代码解析

比赛时的思考

这11个节点的代码也很简单,但我们比赛更要注意分数,在每个节点都完成任务的同时,要使发包数达到最小,才算胜利。而这道题目,这11个节点根本不用发包,也能完成任务。

具体解析

只需要用到无线接收函数即可。先定义一个与右上角发送数据包同类型的结构体,这个结构体在收包的时候进行判断是否是我们需要的数据包,判断成功后,printf打印出来即可。这里不用限制打印次数,反正发包数还是为0。

核心代码

右上角节点代码

event void MilliTimer.fired() {
    if (locked) {    //锁机制的实现AMSend.sendDone判断发包正确后,会解除锁机制
        return;
    }
    else {
        radio_count_msg_t* rcm = (radio_count_msg_t*)call Packet.getPayload(&packet, sizeof(radio_count_msg_t));    //rcm指向packet的负载
        if (rcm == NULL) {
            return;
        }
        //如果负载不为空,就将counter的值赋值给rcm->counter
        rcm->counter = 0x16;        //定义发包的内容
        //AM_BROADCAST_ADDR:无线通信中,代表广播
        //如果改成  0x01,那就是向1号节点发送单播
        if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(radio_count_msg_t)) == SUCCESS) {    //无线发包
            locked = TRUE;                                                                                //打开锁机制 ,锁住后,转到senddone
        }
    }
}

其余11个节点代码

event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len) {    //节点接收数据,无线收包
    if (len != sizeof(radio_count_msg_t)) {return bufPtr;}    //判断是否是我想要的包
    else {                                                    //如果是我想要的包
    radio_count_msg_t* rcm = (radio_count_msg_t*)payload;    //rcm指向包的负载
    //如果rcm->counter == 1,那么 1 & 0x1 == 0x1,所以LED0会亮,以下同理
    printf("Data %d",rcm->counter);
    printfflush();
    return bufPtr;
    }
}

如果有帮助的话,欢迎点赞收藏哦🤩,有不同见解或更好的观点也可以在评论区留言,也可以笔者点点关注,互通有无,互相进步。关于物联网挑战赛更多内容,请订阅笔者的物联网挑战赛的专题哦,持续更新中


本文转载自: https://blog.csdn.net/weixin_53050357/article/details/127146497
版权归原作者 勾栏听曲_0 所有, 如有侵权,请联系我们删除。

“接收节点无线广播发送的数据,并printf打印出来(含核心代码)_物联网挑战赛第四届第一题”的评论:

还没有评论