目录
题目
赛题
格式说明
计分规则
评分步骤
题目解析
核心代码
正文
题目
赛题
如图所示,平台节点不安装天线,已知0号节点位于左上角,其他11个节点ID号随机(0<ID<255),参赛队需编写所有12个节点的代码,完成节点间的信息传递,并通过0号节点打印输出ID号未知的11个节点的ID号,以表明完成了节点间的数据通信。
1) 12个节点只允许编写一份代码;
2)本题开销指的是12个节点无线通信发送数据包的总和;
3)代码中可通过宏TOS_NODE_ID 获取节点自身ID号;
4)参赛队编写的和结果无关的printf 调试语句,必须在最终代码中注释掉,
以免造成最终结果输出错误;
格式说明
1) Printf输出的格式为:标志位(ID)+11个ID号(十进制,空格隔开顺序不限,结尾应加上换行符“\n”以表明语句的完结)输出结果示例:ID135678 10 20 12 33 44
若0号节点输出的ID号个数低于11个,则只核对这几位的ID号的正确性;
若0号节点输出的ID号个数超过11个,则只会取前11个作为依据,并去掉重复和错误的ID号来计算得分。
2)0号节点可重复输出结果,多次输出结果时评冗在予只云以u了m日人l山口
有ID标志位的行作为判分依据;
计分规则
本赛题满分为30分,其中正确性得分22分,开销得分8分;
1)正确性得分:共22分,正确性得分不小于14分才可以获得开销分;正确性得分=2 ×mm为正确的ID号数量
2)开销得分:共8分,开销超过200得分0分,小于200按如下公式计算:开销得分=8×30-"(200-nrn20nm >7)n为12个节点的开销总和
评分步骤
1)烧录Null程序,清空所有节点状态;
2)编译烧录参赛队代码(所有节点);
3)对12个节点进行Printf 监听并开始计时;
4)检测到0号节点输出ID标志位或10秒时间到停止评分,核对结果和开销,计算出得分;
题目解析
12个节点编写一套代码,但据题意很明显0号节点与其他节点的代码不一样,0号节点只负责无线接收,而其他11个节点负责无线发包。
核心代码
主要是利用数据汇聚的知识点
这一部分是设置根节点与非根节点的
event void Timer1.fired() { if (rootid == 0) { call RootControl.setRoot(); //设置位根节点 rootid = TOS_NODE_ID; //用宏定义将自己ID号存储在变量rootid中 rms->rootid = rootid; rms->stop = stop; call Update.change(rms); //? } if (TOS_NODE_ID != rootid && rootid != 0) { //节点ID不等于0,并且rootid也不为0(rootid初始化位0) call RootControl.unsetRoot(); //设置为非根节点 call Leds.led0On(); } call Timer0.startPeriodic(2000); }
这一部分是只有根节点会相应的Receive.receive函数
event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len) { //Receive.receive只有根节点相应 uint16_t flag = 0, i = 0; call Leds.led1Toggle(); if (len == sizeof(EasyCollectionMsg)) //接收到的包的长度是否和节点结构体的长度一样 { EasyCollectionMsg* btrpkt= (EasyCollectionMsg*)payload; for (i=0; i<count; i++) { //判断是否是已接受的ID号,如果是,则flag==1; if (btrpkt->nodeid == nodes[i]) { flag = 1; break; } } if (flag == 0 && btrpkt->nodeid != 0) { //接收到的是新节点的id号 nodes[count] = btrpkt->nodeid; //加到nodes数组里面去 count++; } if (count > 10) { //如果已经收集到11个ID号了 stop = TRUE; for (i=0; i<11; i++) { rms->data[i] = nodes[i]; } rms->stop = stop; call Leds.led2On(); call Update.change(rms); } flag = 0; } return msg; }