LoRa是semtech公司开发的一种低功耗局域网无线标准,其名称“LoRa”是远距离无线电(Long Range Radio),它最大特点就是在同样的功耗条件下比其他无线方式传播的距离更远,实现了低功耗和远距离的统一,它在同样的功耗下比传统的无线射频通信距离扩大3-5倍。 距离往往可达10公里左右。
笔者在做基于无线通信的火灾网络报警系统时,了解到LORA这一优越的通信方式,想着可以直接拿市面上的来用。没想到在网上购买到了正点原子的实物和代码后发现。正点原子的代码是和其开发板高度绑定的,没有现成的自发自收的LORA代码。
于是想着所谓LORA通信也只是串口通信的一种,而且正点原子的LORA模块已经将其与射频芯片等封装好,并且提供了对应的上位机软件。
所以我要做的只是把STM32的串口部分完成即可。
自发自收:2个STM32最小系统板 ,2个LORA模块,2个LORA模块的上位机软件,1个串口通信的上位机软件 2个OLED显示屏(用于显示接收的数据)
通过串口通信上位机将信息由串口1发送给STM32芯片,芯片(可对其处理后)转发给串口3。串口3连着的LORA模块收到信息后发出。这里可以选择透明传输或者定向传输。透明传输是发送给所有其他的LORA模块,而定向传输是发送给指定的LORA模块,其他的LORA模块收到后不作理会。为了区分LORA模块,在使用之前需要对每个LORA模块做 模块基本参数配置。如下图中间所示。
这里重点讲解一下定向传输:
先将2个LORA模块都配置为定向传输模式,分配其相应的地址,信道等数据。将2个LORA模块的数据都存储到STM32中,最好是外接一个EEPROM,将数据记录在EEPROM中,每次启动STM32,只要将原来的数据从EERPOM中读取一遍就可以了。
如果需要外扩成网络状,如成百上千个网络节点,则需要在EEPROM中记录其相邻的LORA模块节点的数据,如地址。
程序思路:
1.打开串口通信软件界面,将数据通过数据包的形式发送给STM32最小系统板的串口1。数据包应当采取的格式为:目的地址+数据
2.串口1收到后,先根据EEPROM中的网络节点联系表,查出如果要传出给目的地址,则需要传输的下一地址。然后加上自身的地址,以便于数据返回给自身。
数据包的格式应当为:下一地址高位+下一地址低位+信道+目的地址高位+目的地址低位+源地址高位+源地址低位+数据
3.串口3发送此数据包
4.下一地址的LORA模块收到后,将数据通过串口3发给其STM32最小系统板。STM32芯片先比对目的地址与自身地址是否相同,若相同对其进行处理,通过串口3发回给源地址。并将目的地址与源地址进行调换。若不匹配,则重复上述步骤直到发给目的地址。
5.原LORA模块收到后,将数据包去掉目的地址,源地址,信道等数据,发送给串口1。于是串口1就会收到此数据。
温馨提示:这里数据包内部数据设计应当包含2个方面。
1.需要设定问答标志位。如果不设定,那么目的地址收到数据后就可能发给自身的串口1了,而不是发回给串口3。
2.数据的格式应当采取:命令+数据或者 命令
如命令号01 表示删除 ,命令号02表示修改某数据
则 命令号02+数据03 表示 将对应数据改为03
基于LORA的通信网络还应该开发一个上位机软件,此上位机软件应当实现增删改查以下信息。
此节点可以通信的网络节点,参考计算机网络。应当有上级节点,同级节点,下级节点,每个节点的级别。并且有地址类似于子网的概念。每个节点有对应的下属地址范围,下级极点不能超过此地址范围。这样的话,每次转发地址,只需要先查看是否在自身地址范围内,如果在的话,看是哪个下级节点。如果没有则查看同级节点,都没有的话,就转发给上级节点。
如果增删改查需要双方都进行修改,应当先以数据包的形式发送给那个节点,通过逻辑判断是否可行,如果可行,那个节点先修改自身。再将可以修改的信息发给源节点。如果不行的话,也应当指明原因。就像访问网页失败,只要返回个404,访问者就会知道无法找到此网页。文章来源:https://www.toymoban.com/news/detail-400753.html
附件是我完成的基于LORA模块的无线火灾网络报警系统。可以实现网络中任意2个节点的通信。不过由于工作原因,关于上一自然段提到的软件一直没有时间去弄。不过完成简单的自收自发是没有问题的。有需要的可以私信我,我看到后会尽快回复。文章来源地址https://www.toymoban.com/news/detail-400753.html
#ifndef __AT24C02_H
#define __AT24C02_H
#include "stm32f10x.h"
#define AT24C02_I2Cx I2C1 //AT24C02???iic??
#define AT24C02_ADDR 0xA0 //????
extern void AT24C02_Init(void); //???
extern uint8_t AT24C02_ReadOneByte(uint8_t ReadAddr); //??????????
extern void AT24C02_WriteOneByte(uint8_t WriteAddr,uint8_t DataToWrite); //??????????
extern void AT24C02_Write(uint8_t WriteAddr,uint8_t *Buffer,uint16_t Num); //????????????????
extern void AT24C02_Read(uint8_t ReadAddr,uint8_t *Buffer,uint16_t Num); //????????????????
extern void AT24C02_WriteTwoByte(uint8_t WriteAddr, uint16_t DataToWrite);
extern uint16_t AT24C02_ReadTwoByte(uint8_t ReadAddr);
#endif
#ifndef __NODE_H
#define __NODE_H
struct NODE {
unsigned int father_ip; //´æ´¢Æ丸½ÚµãµÄIPµØÖ· E2PROM µØÖ· 0X00 0X01
unsigned int father_range[2]; //¸¸½ÚµãµÄµØÖ··¶Î§ 0X10 0X11 0X12 0X13
unsigned int mate_ip[2]; //ͬʽڵãµÄµØÖ· 0X20 0X21 0X22 0X23
unsigned int mate_range[2][2]; //ͬʽڵãµÄµØÖ··¶Î§ 0X30 0X31 0X32 0X33 0x34 0x35 0x36 0x37
unsigned int ip; //×Ô¼ºµÄµØÖ· 0X40 0X41
unsigned int range[2]; //×Ô¼ºµÄµØÖ··¶Î§ 0X50 0X51 0X52 0X53
unsigned int not_use_ip; //×Ô¼ºµØÖ··¶Î§ÖÐδÆôÓõijõʼµØÖ· 0X60 0X61
unsigned int depth; //×Ô¼ºµÄÉî¶È 0X70 0X71
unsigned int block_no; //ÎïÀíµØÖ·Â¥¶°ºÅ 15 0X80 0X81
unsigned int house_no; //ÎïÀíµØÖ·ÃÅÅƺŠÈç102 203 0X90 0X91
unsigned int son_ip[4]; //×Ó½ÚµãµÄµØÖ· 0XA0 0XA1 0XA2 0XA3 0XA4 0xA5 0xA6 0XA7 0xA8 0XA9
unsigned int son_range[4][2]; //×Ó½ÚµãµÄµØÖ··¶Î§ 0xB0 0XB1 0xB2 0XB3
// 0xB4 0Xb5 0xb6 0xb7
// 0xB8 0Xb9 0xBA 0XBB
// 0XBC 0XBD 0XBE 0XBF
//µ±Ö÷»úÏò×ӽڵ㴫ÊäÊý¾ÝµÄʱºò£¬ÓÅÏÈÑ¡ÔñÆä×ÔÉíÖ±½Ó°üº¬µÄ£¬Æä´ÎÑ¡Ôñ°üº¬Í¬Ê½ڵã¼ä½Ó´«´ïµÄ
};
#define Node_packet_length 12 //´®¿Ú3µÄÊý¾Ý°ü³¤¶È×Ϊ10¸ö£¬¼ÓÉÏÏÂÒ»¸öµØÖ·2¸öÔòΪ12¸ö
extern struct NODE mynode;
extern uint8_t NODE_Packet[Node_packet_length];
extern uint32_t search(unsigned char command);
extern uint16_t execute(unsigned char command);
extern unsigned char IS_Current_addr(uint16_t addr);
extern uint16_t Next_addr(uint16_t addr);
extern void Serial1_3_RxPacket_to_NODE_TXPacket(uint8_t packet[]);
extern uint8_t* deal_center(uint8_t packet[]);
extern void NODE_init();
extern uint8_t* deal_all_data();
extern uint8_t NODE_Packet[Node_packet_length];
extern uint8_t all_data_packet[20][4];
#endif
#ifndef __SERIAL_H
#define __SERIAL_H
#include <stdio.h>
extern uint8_t Serial_TxPacket[];
extern uint8_t Serial_RxPacket[];
void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t *Array, uint16_t Length);
void Serial_SendString(char *String);
void Serial_SendNumber(uint32_t Number, uint8_t Length);
void Serial_SendPacket(void);
uint8_t Serial_GetRxFlag(void);
void Clear_Serial_RxPacket();
void Serial_RxPacket_to_Serial3_TxPacket();
void Serial_RxPacket_to_Serial_TxPacket();
#endif
#ifndef __I2C_H
#define __I2C_H
#include "stm32f10x.h"
#define IIC_NO_ACK 1
#define IIC_ACK 0
#define SCL_CLR() GPIOB->BRR = GPIO_Pin_12
#define SCL_SET() GPIOB->BSRR = GPIO_Pin_12
#define SDA_CLR() GPIOB->BRR = GPIO_Pin_13
#define SDA_SET() GPIOB->BSRR = GPIO_Pin_13
#define SCL_READ() GPIOB->IDR & GPIO_Pin_12
#define SDA_READ() GPIOB->IDR & GPIO_Pin_13
/*SCL???*/
#define AT24C02_SCL_PIN GPIO_Pin_4
#define AT24C02_SCL_PORT GPIOC
#define AR24C02_SCL_CLK RCC_APB2Periph_GPIOC
/*SDA???*/
#define AT24C02_SCL_PIN GPIO_Pin_4
#define AT24C02_SCL_PORT GPIOC
#define AR24C02_SCL_CLK RCC_APB2Periph_GPIOC
void I2C_Configuration(void);
extern void I2C_Start(void); //??????
extern void I2C_Stop(void); //??????
extern void I2C_Send_Byte(uint8_t sebyte); // I2C???????
extern uint8_t I2C_Recieve_Byte(void); // I2C???????
#endif
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"
#include "Serial3.h"
#include "Key.h"
#include "NODE.h"
#include "i2c.h"
#include "at24c02.h"
//ÔÚOLEDÉÏÏÔʾÊÕ·¢µÄÊý¾Ý°ü£¬µÚÒ»¸ö²ÎÊýΪ´ýÏÔʾµÄÊý¾Ý°ü£¬µÚ¶þ¸ö²ÎÊýΪÏÔʾµÄÆðʼÐУ¬¿ÉÒÔÑ¡Ôñ1»òÕß3
//rowΪ1ʱºò£¬aΪT±íʾ´®¿Ú1µÄ·¢ËÍÊý¾Ý°ü£¬aΪR±íʾ´®¿Ú1µÄ½ÓÊÕÊý¾Ý°ü¡£rowΪ3±íʾ´®¿Ú3µÄÊÕ·¢Êý¾Ý°ü
void OLED_show_Packet(uint8_t* array,uint8_t row,char a)
{
OLED_ShowChar(row, 1, a);
OLED_ShowHexNum(row, 3, array[0], 2);
OLED_ShowHexNum(row, 5, array[1], 2);
OLED_ShowHexNum(row, 8, array[2], 2);
OLED_ShowHexNum(row, 10, array[3], 2);
OLED_ShowHexNum(row++, 13, array[4], 2);
OLED_ShowHexNum(row, 1, array[5], 2);
if(!(array[6]==0x00 && array[7]==0x00))
{ OLED_ShowHexNum(row, 4, array[6], 2);
OLED_ShowHexNum(row, 6, array[7], 2);
if(!(array[8]==0x00 && array[9]==0x00))
{ OLED_ShowHexNum(row, 9, array[8], 2);
OLED_ShowHexNum(row, 11, array[9], 2);
}
}
}
int main(void)
{
OLED_Init();
Serial_Init();
Serial3_Init();
NODE_init();
//´®¿Ú1 µÄ½ÓÊÕ±ê־Ϊ'A'£¬·¢ËÍΪ'B' ´®¿ÚÈýµÄ½ÓÊÕ±ê־Ϊ'Y',·¢ËÍΪ'Z'
// while (1)
// {
// if (Serial_GetRxFlag() == 1) //Èç¹û´®¿Ú1½ÓÊܵ½ÁËÊý¾Ý£¬ÔòÈô®¿Ú3·¢³öÈ¥
// {
// OLED_Clear();
// OLED_show_Packet(Serial_RxPacket,1,'R');
// Serial_RxPacket_to_Serial3_TxPacket();
// Serial3_SendPacket();
// OLED_show_Packet(Serial3_TxPacket,3,'T');
// }
// if (Serial3_GetRxFlag() == 1) //Èç¹û´®¿Ú3½ÓÊÕµ½ÁËÊý¾Ý£¬ÔòÈô®¿Ú1·¢³öÈ¥
// {
// OLED_Clear();
// OLED_show_Packet(Serial3_RxPacket,3,'R');
// Serial3_RxPacket_to_Serial_TxPacket();
// Serial_SendPacket();
// OLED_show_Packet(Serial_TxPacket,1,'T');
// }
// }
//}
while (1)
{
// AT24C02_WriteTwoByte(0x40, 0x0002);
uint16_t addr;
if (Serial_GetRxFlag() == 1) //Èç¹û´®¿Ú1½ÓÊܵ½ÁËÊý¾Ý
{
OLED_Clear();
OLED_show_Packet(Serial_RxPacket,1,'R');
if(Serial_RxPacket[0]==Serial_RxPacket[2] && Serial_RxPacket[1]==Serial_RxPacket[3])
{
//Èç¹ûÄ¿µÄµØÖ·ÓëÔ´µØÖ·Ò»Ö£¬ÄǾÍÊÇ×Ô·¢×ÔÊÕ£¬ÐèÒªÊDzéѯÅäÖã¬Êý¾Ý½Ï¶à²»ÄÜ×ß´¦ÀíÖÐÐÄ
//´¦ÀíºóÈô®¿Ú1·¢³öÊý¾Ý
deal_all_data();
for(int i=0;i<20;i++)
Serial_SendArray(all_data_packet[i],4);
}
//
else{
//×ß´¦ÀíÖÐÐÄ£¬²¢ÇÒÈô®¿Ú3·¢³öÊý¾Ý
deal_center(Serial_RxPacket);
Serial3_SendPacket(NODE_Packet);
OLED_show_Packet(Serial3_TxPacket,3,'T');
}
}
if (Serial3_GetRxFlag() == 1) //Èç¹û´®¿Ú3½ÓÊÕµ½ÁËÊý¾Ý
{
OLED_Clear();
OLED_show_Packet(Serial3_RxPacket,3,'R');
addr=Serial3_RxPacket[0]<<8;
addr+=Serial3_RxPacket[1];
//Åжϴ®¿Ú3ÊÕµ½µÄÊý¾ÝÊÇ·ñ¾¹ý´¦ÀíÖÐÐÄ£¬ÒÔ¼°ÊÇÈô®¿Ú3·¢³öÈ¥»¹ÊÇÈô®¿Ú1·¢³öÈ¥
if(IS_Current_addr(addr) && (Serial3_RxPacket[4]==0x10 || Serial3_RxPacket[4]==0x11) )
{
Serial3_RxPacket_to_Serial_TxPacket();
Serial_SendPacket();
OLED_show_Packet(Serial_TxPacket,1,'T');
}else{
// OLED_ShowHexNum(1, 1, mynode.ip , 2);
deal_center(Serial3_RxPacket);
Serial3_SendPacket(NODE_Packet);
OLED_show_Packet(Serial3_TxPacket,3,'T');
}
}
}
}
//#include "i2c.h"
//#include "at24c02.h"
//
//uint8_t data[11],str[12]="hello world";
//
//int main()
//{
// uint8_t rece_data;
// OLED_Init();
// I2C_Configuration();
//
// //AT24C02_WriteOneByte(0x00,0xFE);
//
// //rece_data=AT24C02_ReadOneByte(0x00);
//
// NODE_init();
//ÐèÒªÅäÖÃ×ÔÉíµØÖ·£¬×ÔÉíµØÖ··¶Î§
//µÚÒ»¸öÅäÖø¸½ÚµãµØÖ·¼°Æ䷶Χ£¬ÁíÒ»¸öÅäÖÃ×Ó½ÚµãµØÖ·¼°Æ䷶Χ
//µØַΪ1 ·¶Î§Îª1-1024
//×Ó½ÚµãµØַΪ2 ·¶Î§Îª2-255
// OLED_ShowHexNum(1, 1, mynode.father_ip, 4);
// AT24C02_WriteTwoByte(0x00, 0x0001);
// AT24C02_WriteTwoByte(0x50, 0x0002);
// AT24C02_WriteTwoByte(0x52, 0x00FF);
AT24C02_WriteTwoByte(0xA0, 0x0002);
AT24C02_WriteTwoByte(0xB0, 0x0002);
AT24C02_WriteTwoByte(0xB2, 0x00FF);
// //uint16_t data=AT24C02_ReadTwoByte(0x00);
// AT24C02_WriteTwoByte(0x00, 0x0001);
// AT24C02_WriteTwoByte(0x12, 0x0400);
// OLED_ShowHexNum(1, 1, mynode.father_range[1], 4);
//
// while(1)
// {
//
//
// }
//
//
//
//}
到了这里,关于基于STM32的正点原子LORA模块通信网络的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!