Arduino平台下LoRa星型拓扑网络子节点通信模块

写在前面

仅提供思路与参考!!搭建整个工程需要稍作优化

需求分析

本项目需求设计一个低速星型无线通信系统,由于网络拓扑结构的限制,所以两个子节点之间的通信只能依靠主节点的转发,所以组帧是非常必要的,同时需要设计一个帧结构解析函数对帧结构进行解析,通过对帧的源地址和目的地址进行解析,以避免不同子节点之间发包时会提前抓包进行处理。同时主节点需要抓包复制到自己的缓存区buffer里面上传至与PC之间的接口,以供PC端通过VISA进行处理,在LABVIEW平台进行可视化的显示。同时为了避免冲突,通信阶段分为不同的时隙,在每个由主节点依次询问控制子节点向自己发送数据包

调试过程

概述

根据项目要求设计一个星型通信网络,所以由于网络拓扑结构的限制,子节点之间通信的数据包需要由主节点来进行转发,同时进行抓包,上传至PC通过VISA在LABVIEW平台进行可视化显示。首先,要设计一个帧结构,拟使用一个byte类型的结构体来作为帧结构,在此平台中byte类型的数据与unsigned char一样占用一个字节的空间,为了使得程序可读性更好选择这种面向字节的编码方式,后面需要打印的时候可以根据需要进行强制类型转换进行串口打印。帧结构设计示意性代码为FRAME{头部,目的地址,源地址,数据段,帧尾},其中数据段的长度固定为50个字节,使用byte类型的数组来表示。同时发送一个帧只需要按照此顺序逐步发,收端只需要对帧进行解析,解析函数会返回帧中的某一个字节然后进行比对源地址和目的地址来确保子节点之间不会提前收到包。

然后此模块还设计当主节点或者子节点收到包后,会将收到的数据写入自己的receivedbuffer然后根据不同的节点进行不同的处理,子节点收到数据后需要给主节点返回ACK进行转发给发端,若为主节点收到数据包后需要将此数据包更改目的地址后进行转发,收到ACK的回应后,则需要将此数据包通过串口打印给PC。

帧结构收发设计


帧结构

typedef struct
{
  byte header;
  byte targetAddress;
  byte selfAddress;
  byte Message[50];
  byte end;
}FRAME;

发送帧模块

void sendframe(FRAME frame)
{
  LoRa.beginPacket();
  LoRa.write(frame.header);
  LoRa.write(frame.targetAddress);
  LoRa.write(frame.selfAddress);
  for(int i = 0; i < 50; i++)
  {
    LoRa.write(frame.Message[i]);
  }
  LoRa.write(frame.end);
  LoRa.endPacket();
}

帧解析模块

byte procframe(int8_t x)
{
  int8_t packetSize = LoRa.parsePacket();
  if (packetSize)
  {
    int8_t i = 0;
    while(LoRa.peek() != 0xFF)
    {
      receivedbuffer[i] = LoRa.read();
      i++;
    }
    receivedbuffer[i] = 0xFF;
    return receivedbuffer[x];
  }
  else
  {
    return 0x00;
  }
}

系统核心--任务调度

系统设计概述

由于此次的Arduino Uno平台不支持JLINK,所以在硬件平台上调试通信程序存在困难,但是我设计了良好的软件接口和添加调试输出,可以通过串口监视器查看程序运行状态,方便调试,同时我们小组经过前期良好的方案设计,加上嵌入式操作系统的前序知识储备,我们决定在主循环里面采用任务调度的方式来进行整个系统的运行,这样使得模块之间的耦合比较小,实现了低耦合的总体设计。

任务注册表

typedef struct
{
  uint8_t cur;
  void (*CurrentOperation)(void);

}TASK_TABLE;

这样,在loop里面就只用放下任务调度了!!!是不是非常简洁,而且最重要的是:

模块之间的耦合会非常的小!!

void loop() 
{
  t_table[current].CurrentOperation();
}

发送节点模式

void Sendermode(void)
{
  
  inittime = millis();
  sendframe(send);
  curtime = millis();
  while (1)
  {
    //Serial.println("now its sendermode");
    received = procframe(3);
    if (millis() - inittime > 500)
    {
      current = 0;
      break;
    }

    else if (received != ACK)
    {
      if (millis() - curtime > 100)
      {
        sendframe(send);
        curtime = millis();
      }
    }
    else if (received == ACK)
    {
      if (millis() - curtime < 500)
      {
        Serial.print("received ack form B!");
        current = 0;
        break;
      }
    }
  }
}

接收节点模式

void Receivermode(void)
{
  bool flag = false;
  inittime1 = millis();
  while(!flag)  
  { 
    if (millis() - inittime1 < 20000)
    {  
      //Serial.println("now its receivermode");
      received = procframe(3);
      if (received != 0x00 && receivedbuffer[2] == 0x10 && receivedbuffer[1] == 0xAA)
      {
        switch(received)
        {
          case DIANMING:
          {  
            Serial.print("DIANMING..........................");
            Serial.println("");
            current = 1;// go to sendermode
            flag = true;
            break;
          }
          case REQUIREMENT:
          {  
            Serial.print("REQ...............................");
            LoRa.beginPacket();
            LoRa.write(RESPOND);
            LoRa.endPacket();
          }
          //case CHANGE:
          
          default:
          { 
            Serial.print("DEFAULT..................................................");
            procframe(0);
            sendframe(ack);
            flag = true;

            //break;
          }
        }
      }
    }
    else
    {
      current = 2;// go to ruwang
      flag = true;
      //break;`
    }
  }
}

注意,运行不要忘记帧结构和任务表的实例化与任务注册!

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Arduino平台下,使用两个ESP8266 WiFi模块实现互相通信可以通过以下步骤进行: 1. 首先,确保每个ESP8266模块都正常工作,并将它们连接到Arduino主板上。可以使用软串口库(如SoftwareSerial)来模拟额外的串口。 2. 在Arduino IDE中,安装并引入ESP8266WiFi库,以便能够轻松地使用WiFi功能。这个库提供了与ESP8266通信所需的功能。 3. 配置每个ESP8266模块的WiFi连接。使用`WiFi.begin()`函数连接到你的WiFi网络,并使用`WiFi.localIP()`函数获取每个模块的IP地址。 4. 在每个模块上,创建一个服务器或客户端来实现通信。你可以使用`WiFiServer`和`WiFiClient`类来创建服务器和客户端。 5. 在一个ESP8266模块上创建一个服务器,并在另一个模块上创建一个客户端。使用`server.begin()`函数启动服务器,并使用`client.connect()`函数连接到服务器。 6. 在服务器端,使用`server.available()`函数检查是否有客户端连接,并使用`server.read()`函数读取客户端发送的数据。 7. 在客户端端,使用`client.available()`函数检查是否有数据可用,并使用`client.read()`函数读取服务器发送的数据。 8. 在每个模块上,你可以使用`client.write()`函数向对方发送数据,或者使用`server.write()`函数将数据发送给连接的客户端。 通过以上步骤,你可以实现两个ESP8266模块之间的互相通信。你可以在代码中添加适当的控制逻辑和数据处理来满足你的需求。记得在代码中使用正确的IP地址和端口号来确保连接有效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DivinerNJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值