Long range wireless communication is getting more and more attention. Today, I would like to share with you my experience with a LoRa module — SX1278 and also the drive for this device.
Update!
I have recently published a complementary driver which can be used with this and similar LoRa modules on Raspberry Pi. Additionally, a Python wrapper comes with the package so you can easily start your project using this driver. Here you can find the details — LoRa driver for Raspberry Pi with Python wrapper.
LoRa took its name from “Long Range”. It is a proprietary communication system which is using chirp spread spectrum radio modulation technology. In other words, it uses chirps to encode a piece of information. What is really interesting about the LoRa is a fact that it can transmit data over very long distance. By very long distance I mean over a couple of kilometres and sometimes more and all of this is done very power–efficiently.
I decided to work on SX1278 LoRa module. It is an affordable radio module and offers not only LoRa but other types of modulation like FSK. The test platform is an STM32F103C8T6 development board.
Prerequisite
You need two boards equipped with STM32F103C8T6 MCU and two SX1278 modules.
One of the boards will work as master and the other one will work as slave. Master is sending data to slave. Both boards have the same firmware. The mode in which the board is working in is determined by the state of input pin PB2.
Above you can see screen shoot from CubeMX where MCU’s pins are configured.
To actually see what is being send over via radio SWV interface was used. For this to work you need to have a debugger, preferably ST-Link V2, with support for SWV. Sometimes when you want to take advantage of SWV it does not work out of the box. The most probable reason for this is that the debugger firmware outdated. Please remember to upgrade the firmware of ST-Link in advance.
Wiring
The module has to be connected with the MCU board with following pins:
MCU pin | SX1278 pin | Description |
---|---|---|
PA4 | NSS | SPI chip–select |
PA5 | SCK | SPI SCK |
PA6 | SO | SPI MISO |
PA7 | SI | SPI MOSI |
PB0 | DIO0 | LoRa interrupt indicator pin (for receiver mode) |
PB1 | RST | LoRa reset |
——- | ———- | ———– |
VDD | VCC | +3V3 |
VSS | GND | GND |
The SX1278 communicates with STM32 MCU via SPI those are PA4, PA5, PA6 and PA7. There are two other logic pins — PB0 which is DIO0 of radio module and PB1 which is Reset pin of this module. The meaning of the reset input if obvious, what is not is the DIO0. It is used for pulling the state of LoRa module. If the DIO0 output is high it means that there are received data and MCU can read it. MCU can be configured for detecting rising edge to trigger immediate action of reading the data. However, in this example polling was used (checking manually if the DIO0 is high).
Compilation
The example was prepared for SW4STM32 IDE. However, nothing stands in the way to use other IDE like i.e. TrueSTUDIO – Atollic.
Run
After flashing the image you should mind the PB2 port. It is configured as input and depending on its state the board boots as a master or as a slave. For master mode the PB2 has to be pulled high. For slave mode the PB2 has to be pulled low.
All the communication is going through redirected printf() function to SWV. To read the communicates you have to have ST-Link Utility installed. There you can chose Printf via SWO viewer and set the right frequency.
Before you start transmitting and receiving data via LoRa you need to set up the driver. Below is an example how to do this.
//define necessary structures SX1278_hw_t SX1278_hw; SX1278_t SX1278; //initialize hardware for LoRa module SX1278_hw.dio0.port = DIO0_GPIO_Port; SX1278_hw.dio0.pin = DIO0_Pin; SX1278_hw.nss.port = NSS_GPIO_Port; SX1278_hw.nss.pin = NSS_Pin; SX1278_hw.reset.port = RESET_GPIO_Port; SX1278_hw.reset.pin = RESET_Pin; SX1278_hw.spi = &hspi1; //initialize logic for LoRa module SX1278.hw = &SX1278_hw; //configure module printf("Configuring LoRa module\r\n"); SX1278_begin(&SX1278, SX1278_433MHZ, SX1278_POWER_17DBM, SX1278_LORA_SF_8, SX1278_LORA_BW_20_8KHZ, 10); printf("Done configuring LoRaModule\r\n"); //entry transmitter (master) or receiver (slave) mode if (master == 1) ret = SX1278_LoRaEntryTx(&SX1278, 16, 2000); else ret = SX1278_LoRaEntryRx(&SX1278, 16, 2000);
Provided example works in ordinary fashion, the master board is constantly sending messages while the slave is constantly reading them. That’s simple, isn’t it? Below a code snippet was provided to clarify the situation.
while (1) { if (master == 1) { printf("Master ...\r\n"); HAL_Delay(2500); printf("Sending package...\r\n"); message_length = sprintf(buffer, "Hello %d", message); ret = SX1278_LoRaEntryTx(&SX1278, message_length, 2000); printf("Entry: %d\r\n", ret); printf("Sending %s\r\n", buffer); ret = SX1278_LoRaTxPacket(&SX1278, (uint8_t *) buffer, message_length, 2000); message += 1; printf("Transmission: %d\r\n", ret); printf("Package sent...\r\n"); } else { printf("Slave ...\r\n"); HAL_Delay(1000); printf("Receiving package...\r\n"); ret = SX1278_LoRaRxPacket(&SX1278); printf("Received: %d\r\n", ret); if (ret > 0) { SX1278_read(&SX1278, (uint8_t *) buffer, ret); printf("Content (%d): %s\r\n", ret, buffer); } printf("Package received ...\r\n"); } }
Working example
Below you can see two screen shoots. The first one shows a log from master session. The second image shows a log from slave session.
Master:
Slave:
Source code
If you are intrigued enough you can go and download the driver or the whole example. Both are available at my github. The driver is written in C and it can be easily ported to other targets. Also the hardware layer was separated from the driver logic so it is not a hassle to actually port it.
The driver — SX1278
The example — SX1278-example
Thanks a lot, it is a great job!
I want to use stm32f4 discovery board instead of stm32f1 board. what should I do?
The driver was written using HAL so it will work with different MCU. You need to create a new project in CubeMX. After that migrate the CubeMX project which was provided with the example. It will import the configuration for your MCU. Then you should regenerate the project. And that is almost all.
If you change the pin configuration you should update hardware structure of the driver with your configuration.
when i work in master mode, do i need to connect dio0 or not
Best regard
Why in function sx1278_LoraTxPacket, you use the statement: sx1278_hw_GetDIO0???
Tkanks you.
To answer both of your questions.
Yes, I’m using dio0. The purpose of this is to read irq when the data (or a portion of the data) has been sent over.
Also please look into the module documentation. There is a sequence diagram for transmission.
You could actually omit reading the dio0 but you would have to wait longer to make sure it was sent over plus clear the irq nevertheless.
Tkanks you. But i want to ask you, In master mode, need to connect PB0 and DIO0 (hardware) or not???
Yes, you need to connect those two.
Tkanks you very much. I have done. You are great.
You are very welcome!
Have you tested yet? how far is the farthest distance?
Not yet but I have this on my to do list. I need to prepare some set-up to make it portable. When I collect some data I will share it here.
Thanks you very much ?
Hi Nhan , can you please help me on my project , I want to use F4 (F407VGTx) , I tried but still got many Worn and errors , NOT WORKING TO ME
Please add more details. What exactly does not work? The driver has hardware abstraction layer to adjust it for a selected MCU.
hi, thanks for your blog.
i have two stm32l152 and lora sx1278. i’m going to send and receive data with keil IDE.
your example is for SW4STM32.
could you help me please?
Yes, the example was prepared for SW4STM32. Unfortunately, I do not use Keil software but you should be able to import this example. If not you can try to create an empty project and copy source files which are inside SX1278-example repository — it should work flawlessly.
As a matter a fact I have forgotten to mention a different path.
You can take the STM32CubeMX file and change the Toolchain to MDK-ARM and regenerate the code. I think it will be the most straight forward way to do this.
Thanks for sharing your works.
Hi thank you.
i have questions!
What is the maximum distance?
and how can we get it?
The program must be change?
I am still planning to do some range testing. You do not have to change the program. However, tweeting the parameters as spread factor can give you better results.
Hello Sir
I am working on Lora module SX1278 my receiver part is working fine but my receiver is not give any response. what could be problem can u tell me and also i interchange there position too (make receiver part as transmitter part and transmitter part as receiver part ) then also my receiver part is not responding.
what is used DIO0 pin i don’t understand ????what is function mode pin ???(what i found that mode is used to differ the master and slave )but in in main loop i am not using mode pin i using variable master to decide that is master=1 then it is master and master =0 then it is slave .please help me out.
DIO0 is being used to e.g. pool for package receivement.
How did you check if transmitter is sending something? I would suggest to use SDR to quickly see if anything is being transmitted. If not then probably something with module configuration is not right. The example should work out of the ox. Please check pinouts.
I ask some where if you shift 0x10000 in DIO1 – 5 . in for example 1 ms .it work for 9600 meters.
but i don’t test it.
Sorry, but I do not know how it should work. The DIO pins are described in the datasheet and they perform specific functions as described in there. Where did you get that idea?
sorry type mistake my transmitter part is working fine but not receiving part is not responding.
Please me out.
some one who test this way…and it worked.
Could you give some reference?
i did not see any where in internet….
but i will asked him.
hi
Thanks for sharing your works.
but i have a little problem with your project. Can you help me with project for stm32f0?
i use two board for test, and i make program for master and slave and it not work…maybe you can check my project?
thank you
Did you migrate the project in Cube for your STM32F0? After that you have regenerate the project.
yes. copy your project on the stm32f0 via cube after generate code and add your files gpio/spi/sxlib and i use your code from main file. I change pin for my board and now my project success compile. But between board tx/rx not work
if you want i can send my project with cube on your mail
You are only required to copy the driver of the SX1278 and some of the code from main. While regenerating the code Cube will take care of adjusting GPIO and so on. You should not copy them to the new project. Just a quick question, did you connected all required pins of the LoRa module to your STM32?
You can send it to me but I do not have STM32F0 to check it. The best way of sharing your project would be by using Github and sending me a link to it.
ok, thank you, i try again make project
it my project with cube dropmefiles. com/R8hjd
Ok. I took a look at your code. Everything looks all right. The reason you do not see anything is that because you did not redefined _write() function. In the example I am using SWV as a debug interface. It is using SWO pin at which it is sending the data. You could use an UART interface if you wish.
thank you,. yes, now i use interface usart for debug. Now i make
if (master == 1) {
HAL_USART_Puts(USART1,”Mode: Master\r\n”);
HAL_GPIO_WritePin(…);
…
//init lora module
…
HAL_USART_Puts(USART1, “Configuring LoRa module\n\r”);
now in my serial port i see only the master, but I do not see the initialization parameter and other parameters 🙁
Where did you get this function HAL_USART_Puts() from? From HAL lib you get only HAL_UART_Transmit() and similar. I advice you to sort out the communication first. After that you can use it to properly redefine _write() to use your serial interface as output for printf(). Also, the less you change the original code the better. The example I have uploaded works and was tested with STM32F1 and it should work also for you. I have confirmations that it was also ported to STM32F4 where it also works. You only need to sort out the communication issue.
thank you for help. F0 not support swo, but on f1 and f4 i can use swo for debug
You welcome! As for the SWV that is why I did write to use a serial interface like UART. Then you only need to redefine the _write() function and everything should work out of the box provided that the serial interface is properly configured. Redefinition of _write() function can look like this for UART:
int _write(int file, char *ptr, int len) {
HAL_UART_Transmit(&huart2,ptr,len,50);
return len;
}
hi Wojciech Domski
You have f4 board?
Yes, I have some nucleo for F4 but if you are going to ask if I have used it on that board then no. However, as I have written earlier I know that one guy has successfully run the code on STM32F4.
i can’t launch your library. Did the necessary for checks SPI and he work, the registers are read and written, the state of GPIO is the same as yours, what else needs to be change? If there is an opportunity, share an example for a f4disc…
in serial wire i see only:
Mode: Slave
Configuring LoRa module
Done configuring LoRaModule
Slave …
Receiving package…
Received: 0
Package received …
Slave …
Receiving package…
Received: 0
Package received …
Slave …
and master side:
Master …
Sending package…
Entry: 0
Sending Hello 2
Transmission: 0
Package sent…
Master …
Sending package…
Entry: 0
Sending Hello 3
what i can check for launch lib?
It seams that the Master does not send any data. Look at what you have received from debug log of the Master:
It means that the function SX1278_LoRaTxPacket() returned 0 because of timeout. There was no signal on DIO0 of the SX1278. Also check what value is returned by
ret = SX1278_LoRaEntryTx(&SX1278, 16, 2000);
at the very beginning.
oh, yah, i see, on the tx board not needed use DIO for transmit. Now in the debug i see:
Transmission: 1
Package sent…
Master …
Sending package…
Entry: 1
Sending
Transmission: 1
Package sent…
Master …
Sending package…
Entry: 1
Sending
Transmission: 1
Package sent…
Master ..
but not see it on the receiver
What did:
ret = SX1278_LoRaEntryRx(&SX1278, 16, 2000);
return?
Also, below function:
ret = SX1278_LoRaRxPacket(&SX1278);
is also using DIO0 to know if there are any pending data to be read. From what you have written before I think that you did not connect the DIO0 on the slave side.
Please connect all pins as described in the table inside the post.
hello Sir
Thank you for reply me. It is very nice of you.
My transmit part is working fine but my receiver is not receiving the data. It found DIO0 is not working as interrupt (what is pin output of DIO0).
This is the serial output(Slave part)
Receiving package…
.Received: 0
.Package received …
.Slave …
.Receiving package…
.Received: 0
.Package received …
.Slave …
.Receiving package…
.Received: 0
.Package received …
.Slave …
.Receiving package…
.Received: 0
I am using PB0 as input(no pull up or no pull down).I do not what is the problem.
Please help out.
good day
tell me please, how correctly read rssi ? have you checked this function?
Reading raw value from LoRa module is pretty straightforward. However, SX1278_RSSI_LoRa() returns RSSI after some calculations. The way you calculate the RSSI differs depending on what configuration you are using. Please refer to SX1278 documentation for more information.
Thank you so much for your help, actually i want o implement code of SX1278 on STM32L152 as you mentioned earlier i have added the header files and other necessary files into the folders but i have one doubt regarding the pins,
1. MODE pin where i have to connect on board and on Module.
2. Same for the DIO0 pin.
Thank You!
The MODE pin can be any GPIO configured as input same goes for DIO0. Just remember to update hardware initialization structure for LoRa module:
SX1278_hw.dio0.port = DIO0_GPIO_Port;
SX1278_hw.dio0.pin = DIO0_Pin;
The MODE pin is selecting whether the board works as master or as slave. If you stick to the same labels in Cube and regenerate code everything should work right of the box. Since you are running this example on STM32L1 the easiest way is to import my example and change appropriate pins.
hello
Wojciech, have you any update for this project?
What kind of update do you have in your mind?
Hi
Why does the transmission crash when the send time is accelerated from 2,500 milliseconds to for example 100 milliseconds?
I did no try this out. But you can do that kind of experiment. The minimum gap between data transfers is defined by the parameters of transmission and how many data you want to send. You can calculate it based on datasheet of SX1278 device.
Hi,
I did followed your instructions with the Dragino LoRa Shield instead of SX1278. I connected the wire and also use SX11278.c to do just like you. However, ret = SX1278_LoRaEntryTx(&SX1278, message_length, 2000) or ret = SX1278_LoRaTxPacket(&SX1278, (uint8_t *) buffer, message_length, 2000) always returned to 0 not 1 like you to send and receice the package. I do not know how to fix that. I used KeilC to do that. Do you have any idea to solve it?
My first step in solving this would be to actually check if there is proper ongoing SPI transmission. You can verify that by reading some register with constant value or using a logic analyser. SX1278_LoRaEntryTx() returns 0 when the timeout has been reached. That is why I would check SPI communication first.
Hi,
can i use multiple transmitters sending data to one receiver with your driver? i have a project to set multiple node of wireless sensor network, and i’m interested to use sx1278 lora module and stm32f103.
Yes, you can do this. There are two ways. You can use single SPI and share MISO, MOSI and SCK pins (as it was intended) or you can use different SPIs. The best way would be to use single SPI and multiple CSes (chip select pins) to chose with which device you want to communicate with. Also remember to use different pins for DIO0 and RST for each LoRa module.
hello
maybe you have example with crypto lib?
No, I don’t.
Good day, Wojciech Domski
Help me please, can you show me how i can read rssi from your lib? i see function but if i use this function i see only data “H#” on the receiver. I can’t understand why…
please, show me a little example
Hi!
You have two functions for this: SX1278_RSSI_LoRa() and SX1278_RSSI().
SX1278_RSSI_LoRa() read data from 0x1B register and returns the absolute RSSI value in dBm.
SX1278_RSSI() read data from 0x11 register and returns the current RSSI value in dBm.
All RSSI values returned by the functions are positive. You can always refer to SX1278 manual for more documentation. It is explained there. However, I do not know how you got 2 bytes “H#” instead one since both functions in question return uint8_t.
Good day, Wojciech Domski
Help me please, i want to implement code of SX1278 on STM32F0 and i have a question:
1. How could i change parameters such as Frequency, SpreadFactor, LoRaBandwidth, Power
Hi. Have you had a look at the example. In the main.c file you have initialization of the LoRa module:
SX1278_begin(&SX1278, SX1278_433MHZ, SX1278_POWER_17DBM, SX1278_LORA_SF_8, SX1278_LORA_BW_20_8KHZ, 10);
Through this function you can initialize the module and set all the necessary parameters.
Thanks for sharing your great work.
I’m thinking of implementing a Half-Duplex communication (both transmit and receive, but not simultaneously) and in your code I see that to receive any data, I must configure a transceiver as a slave necessarily. In a communication in which the Master constantly sends data to the Slave, there will be some way in which the Master can receive data that the Slave sends, but does not know when ?. Thank you
The driver is written to support Full-Duplex. Also, please look at the SX1278 datasheet. The Semtech company only mentions Full-duplex configuration.
Hi, Wojciech Domski
I’m using an RA-02 module like this: https://www.tindie.com/products/IOTMCU/sx1278-lora-433mhz-ra-02-breakout-board-2pcs/
This module seems to be similar to yours, but, the datasheet (Semtech SX1276/77/78) indicates that the maximum power is +20 dBm (the RA-02 module indicates +18 dBm). Do you think there will be a problem if I set my module (RA-02) to +20 dBm (using the PA_BOOST pin in the RegPaConfig register)?
I am trying to reach the maximum possible range but without exceeding SF = 7 and BW = 125KHz
Thank you
Hi Alvaro,
Yes, I think you can give it a try. Since both modules are based on the same Semtech chip it should work. If you have modified other values in RegPaConfig, also set OutputPower to 0x0F (it’s default value).
Please leave a comment when you run some tests. I am really curious about the results.
Sorry for the late reply.
As I mentioned, I am using the RA-02 module (based on the SX-1278 chip) and it indicates that the maximum power is +18 dBm. I set the registers: RegPaConfig = 0x8F (PA_BOOST selected) and RegPaDac = 0x87 (Enables the + 20dBm option on PA_BOOST pin). I directly connected the SMA output of the LoRa module to two attenuators (each of 30 dBm) and then to the RTL-SDR. I could see that, between the configuration of +17 dBm and +20 dBm, there was a difference of 2-3 dB (It would be better if this was done with a spectrum analyzer)
It is curious that the module indicates + 18dBm, already the datasheet indicates that it could be +17 dBm or +20 dBm, but nothing intermediate. I also noticed that the SX-1278 chip, although it has two outputs (RFO and PA_BOOST), the only output enabled is the PA_BOOST, since when configuring RegPaConfig and selecting RFO pin, I did not get anything in the output
Also, it is worthy of a note that LoRa modules have additional components on the board. If you design your own module you could overcome some limitations. For example, the SX1278 chip’s frequency can be altered in broad range. However, on the LoRa modules there are filters which block the signal.
Good afternoon please tell me if it is all the necessary parameters for organizing lora communication
Yes, in the example project you have all necessary parameters which ought to configured for proper work of LoRa module.
Hi, I have four lora nodes. Each node is made with STM32 and RA-01 (sx1278) Lora module.
On of the nodes is considred as master. How can I send data to one of the three other slave nodes?
Can I assign a dedicated code to each slave node?
Basically when you use LoRa module it does not have a support for any protocol. Generally, it broadcast data to all recipients. You can implement a simple data frame which has an ID field through which it identifies nodes. After each node receives this datagram it checks if it is addressed to it, if not then it drops it. On the other hand, you can use LoRaWAN protocol which uses LoRa as a transportation layer. The choice is yours. However, for a simple communication you can implement what I have described at the beginning.
Hello, is there anyone who has made this project for keil?
Hi,
Can I use this code for LoRa RA02- 525MHZ?
525MHZ is not define in sx1289.h. Is it true?
Answering your both questions.
Keil is only IDE. You can either import the project or add necessary files by hand (driver and some example). That’s all.
As for different frequencies. Yes, you can change the frequency by modifying proper registers in SX1278 module. I believe it was already answered in the comments, if not then you you have to modify three registers such as RegFrfMsb (0x06), RegFrfMid (0x07) and RegFrfLsb (0x08). The frequency is a multiplication of Frf (value concatenated from previously mentioned three registers) times frequency step (61Hz). Have a look at the manual for the SX1278.
Please also keep in mind that you need to have a proper module prepared for required band. If you use module for different band it will not work.
Hi,
My module ‘s frequency is 525Mhz what should I do in line 173 of sx1278.h?
Yes, you can do this by calculating the value of register RegFrf. Since the frequency step is 61Hz and you want to get 525MHz you can obtain the correct value of RegFrf like this
525MHz / 61Hz (approx)= 8606557 = 0x83535D.
Now, you put this value to RegFrf like so
RegFrfMsb (0x06) = 0x83, RegFrfMid (0x07) = 0x53 and RegFrfLsb (0x08) = 0x5D.
Keep in mind that this is approximate value. The real frequency would be 8606557 * 61Hz = 524999977Hz (approx)= 525MHz.
Now, you have to make some alteration to the code and change the line:
static const uint8_t SX1278_Frequency[1][3] = { { 0x6C, 0x80, 0x00 }, //434MHz
or better yet make a new definition
#define SX1278_433MHZ 0
#define SX1278_525MHZ 0
static const uint8_t SX1278_Frequency[2][3] = { { 0x6C, 0x80, 0x00 }, //434MHz
{ 0x83, 0x53, 0x5D }, //525MHz
};
During the initialization you have to pass correct frequency.
It is written on that 410-525Mhz. this code will work on it?
Yes, it will but with some alteration. Please look at my other comment.
Good day, Wojciech Domski
I implement your code in microcontroller’s board. Unfortunately one of boards was burned. I bought it but it comes to me a week later. I connected one of the LoRa module to the board, Now in the debug just I see:
Mode: Master
Configuring LoRa module
or
Mode: Slave
Configuring LoRa module
Although I only set up the sender’s (receiver’s) side, is this normal? Is the module burned too:( ?
Hi Mr.Domski
I used your code in my project.
But unfortunately one of my microcontroller was burn. I bought it, but they will sent it the next week.
Now I connected one of Lora madule to my board and I see:
Mode: master(or slave)
Lora configuration…
Compiler stopped in sx1278-begin function.
Is it normal? Or my madule burned too?!
It is hard to say what is going on. You should debug the code to see where exactly it is hanging. Also I quite don’t get how compiler could stop at sx1278_begin function. I assume that you meant it hangs there during the execution.
Could you also verify that all GPIOs are correctly connected?
Did the module worker prior to the damage?
Daniel, how did you solve this issue of stopped at sx1278 begin? Thanks
Excuse me.I thought my previous message could not be sent.
Dear Mr.Domski
thank your for your help. It solved.
May you Explain about:
ret1 = SX1278_LoRaEntryTx(&SX1278, message_length, 2000);
And,
ret2 = SX1278_LoRaTxPacket(&SX1278, (uint8_t *) buffer, message_length,2000);
I think when massage was send to slave madole, ret2 will be ‘1’.
But about ret1 I do not know anything.
regards, Masoud
SX1278_LoRaEntryTx() returns 1 if the module entered transmission mode successfully.
SX1278_LoRaTxPacket() also returns 1 if the message was sent successfully.
Both functions return 0 if a timeout period was reached.
Hi, Mr.Domski
I wanna set up some LoRa network that don’t interfere with each other. for example three group that each group has two modules. which parameters of the code should be change ?
The quickest and the easiest way would be to change the frequency by a reasonable step. Although I would recommend implementing a simple protocol with acknowledgements where it would resend a message to ensure it was delivered.
Hi
can we use this code for rfm95 (sx1276)?
Yes, you should be able to runt the driver with SX1276. However, I haven’t tested it with this module.
It run successfully on sx1276.
Thank you.
Please Send me a Your Example Code of SX1276
Hello,
Do you have any source code about LoRaWAN with rn2903 or sx1278?
I do not have stack for LoRaWAN. However, there is an open source implementation from one of the vendors if I am correct. You can find it by downloading examples for LoRaWAN from ST.
Can you use this for sx1272?
Yes, you should be able to use it but with some minor modifications.
Hello
Thank you for sharing your work.
but I have a little problem with your project. Can you help me with a project for stm32f405?
I use two boards for the test, and it does not work … maybe you can check my project?
I connected everything correctly, the module is working.
thanks
How did you verify that the module is working?
Hello I am using your HAL STM32 Library as a base for the MSP430G2553 and the LoRa chip I am using is a SX1278. I just wanted to ask, is ret defined as a bool? And what are in the buffer and message?
Like is buffer = 256 and message = “Hello World\n\r” ?
additionally, why do you take message +=1?
This is just an incrementation of a variable to see that the message which is being sent over is changing.
Could you tell the function name you are asking about? Buffer is just a buffer to hold temporary data for further processing.
I ‘ve built a transmiter with STM32F030F4P6 and a Lora RA-01.
But I ‘m struggling a month now (!!!) to make it work without any success.
I have multiple-times checked my hardware connections, they must be correct!
From the SX1278_LoRaEntryTx I get a 0 as an answer, so I suppose it cannot enter transmission mode.
How can I debug the SX1278_LoRaEntryTx function?
Every detail plus my code as I have modified it can be found here: https://github.com/panosss/sx1278-test-code/blob/master/README.md
Any help is welcome.
The best way to figure out what is going on is to enter debug mode and step into the function in question. Also, does your module has the same chip. To my knowledge RA-01 should be the same but I would verify it, just to be sure.
A more ‘correct’ link: https://github.com/panosss/sx1278-test-code
I tried some debugging with printf in function SX1278_LoRaEntryTx:
int SX1278_LoRaEntryTx(SX1278_t * module, uint8_t length, uint32_t timeout) {
uint8_t addr;
uint8_t temp;
module->packetLength = length;
SX1278_defaultConfig(module); //setting base parameter
SX1278_SPIWrite(module, REG_LR_PADAC, 0x87); //Tx for 20dBm
SX1278_SPIWrite(module, LR_RegHopPeriod, 0x00); //RegHopPeriod NO FHSS
SX1278_SPIWrite(module, REG_LR_DIOMAPPING1, 0x41); //1000001: DIO0=01, DIO1=00,DIO2=00, DIO3=01
SX1278_clearLoRaIrq(module);
SX1278_SPIWrite(module, LR_RegIrqFlagsMask, 0xF7); //Open TxDone interrupt
SX1278_SPIWrite(module, LR_RegPayloadLength, length); //RegPayloadLength 21byte
addr = SX1278_SPIRead(module, LR_RegFifoTxBaseAddr); //RegFiFoTxBaseAddr
SX1278_SPIWrite(module, LR_RegFifoAddrPtr, addr); //RegFifoAddrPtr
printf(“1. SX1278_LoRaEntryTx addr: %u\r\n”, addr);
while (1) {
temp = SX1278_SPIRead(module, LR_RegPayloadLength);
printf(“2. SX1278_LoRaEntryTx temp: %u\r\n”, temp);
if (temp == length) {
module->status = TX;
return 1;
}
The first printf prints ‘addr:0’.
The second one prints: ‘temp:0’.
So, SPIRead of register LR_RegPayloadLength returns 0.
Is this normal?
Best way to debug the code is to use debugger instead of printfs. You could check with the documentation for the module if the data you have received is correct.
Also I had a quick look at your project. It seems that the SPI configuration is wrong. By default the data size is set to 8 bits for the module, while you have configured it to 4 bits.
Best practise is to check if the SPI communication is working by itself. For example, you can try to read some registers which have predefined value, an equivalent to WHOAMI register for I2C interface.
Hello Domski!
I have another question! So my get_DIO0 is sending back a 0 or a non 1 (HIGH) number, thus the txPacket is not getting triggered and the package is not being sent. I understand that the GPIO0 pin is reading low. How do I go about fixing this? If you need any more details, please let me know.
The DIO0 is an input which inform you if the package was sent over. It is not a trigger.
There is also a possibility to pull it with software but in my opinion this is better approach. You can adjust it easily.
Yes it has the SX1278: https://www.banggood.com/Ra-01-Smart-Electronics-SX1278-LoRa-Spread-Spectrum-Wireless-Module-Ultra-Far-10KM-433M-p-1130769.html?utm_source=google&utm_medium=cpc_ods&utm_content=nolan&utm_campaign=nolan-pc-all-sds-summung-19725-content&ad_id=372927316204&gclid=Cj0KCQiA04XxBRD5ARIsAGFygj8NZq0lK345Cv7ShnNVXIWUnQFb4X8CuKLArID3RpruYthn8kYlKzcaAo2eEALw_wcB&cur_warehouse=CN
(Sorry for not answering directly to your answer but I clicked on your answer but no ‘answer’ button appears)
(At STM32CubeMX->Inout & Configuration->Connectivity->SPI1->Sarameters Settings->Data Size)
I changed the ‘Data Size’ to 8….and…IT WORKS!!
I can ‘t believe it!! It works!!!
Wojciech I can ‘t thank you enough! Thank you!!Thank you!!Thank you!!!!
But now I have another problem: the transmitter emits a 100 messages (‘Hello’ plus a number: ‘Hello 1’, ‘Hello 2’, ‘Hello 3’ etc).
But the receiver receives, about, only 7 messages out of this one hundred.
Maybe it ‘s because my receiver uses LoRa.setSyncWord(syncWord) which defaults to 0x12?
(syncWord – byte value to use as the sync word, defaults to 0x12)
https://github.com/sandeepmistry/arduino-LoRa/blob/master/API.md
Glad to hear that!
As I understand, you are using a different transmitter? The reason for dropping frames is usually a bad link. Check your antenna if it is fixed properly, maybe there is a little or no contact. Also maybe you are pulling too slow for the new data. How quickly the transmitter sends the data and how often do you pull?
I have two transmitters, one with Arduino (works ok) and one with STM32.
The Lora RA-01 module is ok because it works fine with Arduino.
So it ‘s not a hardware issue.
It ‘s something in the hardware. It must be in the software.
It maybe has to do with frequency.
I want to make the Lora work at 433MHz.
The equation is f = (32 * SX1278_FRF_VALUE) / 2^19. (https://github.com/jgromes/LoRaLib/issues/8#issuecomment-390381373)
So I found that SX1278_FRF_VALUE should have the value 0x6C4000.
LoRa_writeRegister(module, LR_RegFrfMsb, 0x6C);
LoRa_writeRegister(module, LR_RegFrfMid, 0x40);
LoRa_writeRegister(module, LR_RegFrfLsb, 0x00);
But still the same, most of the transmitions are not received by the receiver.
About ‘ pulling too slow for the new data’… I have no idea if I ‘m pulling slowly or fast! 🙂
How can I check this?
The transmitter is sending a message every 10 seconds.
Does the transmitter and receiver use the same frequency? Even if you configure the module to use a certain frequency then the hardware can not allow it since the modules have a band pass filter.
Maybe the Arduino code is using different frequency while it is not explicit?
A correction: in ‘It ‘s something in the hardware. It must be in the software.’
I meant: It ‘s NOT something in the hardware. It must be in the software.
I have tried MANY differrent frequencies manually but didn’t achieve anything.
Changing frequencies would not do anything because of hardware filter. Could you please share your code, upload it, e.g. on Github.
I uploded it at github: https://github.com/panosss/sx1278-test-code
You can find the Inc and Src folders (and in the zip file the whole project).
Well, I had a look on your code and it seems that you have the same problem as it was already mentioned here.
You have misconfigured the SPI, in your code it uses 4 bits instead of 8 bits.
Recheck your configuration.
In file spi.c:
/* SPI1 init function */
void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
So it ‘s correctly configured at 8 bit.
Why do you say I have it misconfigured?
(anyway, if I had it at 4 bit it would not work at all)
It was in the repository which you have shared. You also mentioned something about a zip file. Is your code there? If yes, please put it directly on the repo so it can be checked.
I have uploaded the zip file on the repository.
Isn’t it visible?
Yes, it’s visible but if you would like me to look into it please extract it on the repository. Generally, pushing zips or other binaries is not a good practice unless it’s required.
You can do this on a different branch.
This is the direct link: https://github.com/panosss/sx1278-test-code/blob/master/SX1278-example-STM32F030F4P6.zip
Ok, I uploaded the whole project on https://github.com/panosss/sx1278-test-code.
Except for the folders ‘Drivers’ and ‘startup’ because they contain files for STM32F1 (the project is for STM32F1, so I guess they are not used).
I think I uploaded all the files, if you have any problem please let me know.
I also uploaded folders ‘Drivers’ and ‘startup’ because they are necessary.
can we connect two loRa module which are transmitting to single loRa module which will be receiving the data
Yes. You can connect multiple transmitters to a single receiver.
However, keep in mind that if two or more transmitters are transmitting a portion of data you can receive garbage or nothing at all.
For this, it is good to have a simple protocol with delivery system such as acknowledgments of reception to make sure that what was sent was also received. Also you can use LoraWAN for this but sometimes it is a bit too much piece of machinery for small problems.
hey,
i recreated your project on keil but i’m missing one file, specifically: stm32f1xx_hal_exti.h
and i think its important file, because i get like 20+ errors when compiling.
if anyone could help me i would be honored.
thanks
It seems like lack of path for header files. Check it. It does not matter in what IDE you are compiling as long as you have configured paths properly. Wast majority is suing the same ARM GNU compiler.
Hi ,I’m having problem to migrate the code from F1 to F4.
Can you please help me , I’m new in the domain
Hi
,I’m having problem to implementing a Full-Duplex communication . when we switch from transmitter(m=1) to receiver(m=0) we must create hal_delay(50) but Data rates are low ,if commented hal_delay(50) communication between two module is Disconnected. i debug mycode and see ret=0 in ret =1278_LoRaRxPacket(&SX1278); What is the problem؟؟؟
——————————————————————————————————————————————————————————-
SX1278_begin(&SX1278, SX1278_433MHZ, SX1278_POWER_20DBM, SX1278_LORA_SF_6,SX1278_LORA_BW_500KHZ, 64);
master=1;
for(int i=0 ; i0)
{
master = 0;
ret = SX1278_LoRaEntryRx(&SX1278, 64, 400);
// HAL_Delay(50);
}
}
else
{
ret = SX1278_LoRaRxPacket(&SX1278);
if (ret > 0)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
SX1278_read(&SX1278, my_packet, ret);
HAL_UART_Transmit(&huart1, my_packet, 64, 100);
master =1;
ret = SX1278_LoRaEntryTx(&SX1278, 64, 400);
}
}
}
————————————————————————————————————————————————
Could you add an exact snipped of your code or better yet publish it on Github? Now, there are some syntax errors. Also what you want to achieve is rather Half duplex than full duplex.
Hii!
How can I used SWO for STM32F103? I am using ST Link. So I can not read the messsages.
If you use Nucleo board or discovery board the SWV should be already connected. Use St-link utility for this or build in extension in STM32 Cube IDE.
Hi ,
I megrated with your program to STMF4 using Keil IDE , but I can’t see the output of the program as you did with serial wire !
can you help me . THANKS FOR YOUR EFFORT.
In the example I’m using SWV. You need to use an application for this, e.g. st-link utility. There is a tool for this.
In the example I have provided serial port is not being used.
is your __Write function still working for me even if I am using F4 and Keil IDE with link utility ! I’m stuck here , I can’t know if it’s working for me or not.
Yes, it should work. However, did you connect SWO pin? What board do you use. Nucleo boards have it already connected to appropriate pin of ST-Link programmer.
Hi
Ysn_ba , what microcontroller did you use to make the project? F405 ?
Hello, it’s really exciting, what you’ve done. I’ll be very grateful if you help me. What exactly should I change to make it work with sx1272?
I’ve already changed the frequency (this 0x6C, 0x80, 0x00 to this 0xD9, 0x00, 0x00), but it doesn’t work. The frequency is 868MHz
Are you using the chip as a module? Or is it a bare bone chip? If it is the first case changing frequency will not do any difference since there is a band pass filter on the module.
I use SX1272 mbed shield SX1272MB2xAS
There is also bandpass filter. Are you sure that you have the right version? Depending on the country to which the module is being send it can have different **hardware** settings, different components.
Firstly, thank you so much for this unique project. I have two questions related with it.
1- I will use STM32F407. To be able to use it I regenerate a new project on CubeMX. After that I will only copy and paste which is SX127 c and h. Is it true way? Then I will set the SPI as half dublex mode.
2- I will read the print commands with UART and RS-232 usb to ttl converter.
Are the my ways true or not? Thanks.
Yes, your understanding is correct. Please keep close eye on SPI configuration since this is usually the most common issue due to default configuration provided by STM32CubeMX.
So, what is the mode of SPI exactly and what is the NSS signal? Is it output or input?
Hi Farouk ,SPI mode is Full duplex master , NSS signal is an output.
I’m working on the same project ,would you contact me [email protected] !
yassine.
For the MODE pin should I set it SET for master and RESET for the slave respectively? or Should I debug it randomly to the both master and slave? I could not understand how the MCUs understand slave or master with MODE pin? Can you inform me? Thanks!
Hi dear Wojciech Domski!
I have problem with the project. I use stm32f103 and also dorji drf1278f RF module. I rewrite codes and added main.c codes, SX1278.c and h codes. Then, even though the master which I determined with MODE PIN which is PULLUP sends the data correctly on Putty, in the slave part which is the PULLDOWN (MODE PIN) I got ret value as 255 but I could not get the data. I mean that the data that I received was like “?????????”. Also, Im using UART and RS232 to be able to read data from serial port. Can you help me please?
I shared codes on this link: https://github.com/frkkilic/sx1278-project
It looks like an initialization problem. Have you checked what are return values of SX1278_begin(), SX1278_LoRaEntryTx(), etc.?
On the Master Side:
Sending Hello 74
Transmission: 1
Package sent…
Master …
Sending package…
Entry: 1
Sending Hello 75
Transmission: 1
Package sent…
Master …
Sending package…
Entry: 1
Sending Hello 76
Transmission: 1
Package sent…
On the Slave side:
Slave …
Receiving package…
Received: 0
Package received …
Slave …
Receiving package…
Received: 0
Package received …
Slave …
Receiving package…
Received: 0
Package received …
Slave …
Receiving package…
Received: 0
Package received …
Slave …
So what is the problem I can not understand((
It means that the receiving part is not working. Have you tried to debug it? I would start with checking the configuration. There is a lot of discussion on this matter. Maybe looking through it can help you solve your problem.
Yes I debug it by setting MODE PIN as pulldown. Also everything is same with yours.
That is interesting. Setting the mode pin should do the trick. I have also checked your code on github and I do not see that there is some misconfiguration.
One other thing to check. Could you read some values from the LoRa module registers (before initialization) and verify it if the value you are reading is correct one. Check any configuration register against its default value.
I have checked SX1278_LoRaEntryTx and SX1278_LoRaEntryRx for each master, slave(MODE PIN is pullup and pullldown respectively). I got 1 for SX1278_LoRaEntryTx which equals to ret variable and I got 255 for SX1278_LoRaEntryRx which equals to ret variable again. On the other hand, I could not see the that what does the SX1278_begin() return on the serial window on Keil. So, now I have no any idea to access to the result. Im still reading value as “???????” .
Also, the 1278 RF module that I use is this one; https://pdf.direnc.net/upload/dorji-drf1278f-20dbm-lora-uzun-menzilli-rf-front-end-modulu.pdf
Maybe, there might be different working parameters. Are these kind of reasons effecting to get correct result?
Sorry, could you clarify. Does the SX1278_LoRaEntryRx() return 255?
Dear Wojciech Domski
Now, SX1278_LoRaEntryTx() is returning 1 and its sending “Hello 1,2,3 etc.”. I see its correct. But SX1278_LoRaEntryRx() is returning 0. So, now I got nothing from the slave side. 🙁
hellom thank you very much for sharing your work i treidto import your project yousing SW and i, facing this error: OpenOCD Script not found (or not support yet) while debbuging could you help me please
SW, meaning System Workbench for STM32? I would recommend to create a new debug profile. The message you are getting indicates that there is no debug configuration for the OpenOCD.
it is my first time using this ide so dont know how to o config
I would recommend to use STM32CubeIDE. It is a good start for beginners since almost everything is done automatically. If you want to, in time, you can get to the nitty gritty of it since it allows to configure almost everything.
thank you for your help i will try it
Hello, I decided to use your driver, but the data is not transmitted, sx1278_begin and sx1278_entry_tx returns 1, but sx1278_tx_packet returns 0. I looked at this method, where you read the dio0 pin, but why read it if this pin is only used when receiving data. I removed this check, but the data is still not sent. What might be the problem? Here is a link to my code on github : https://github.com/gug2/lora_radio_test
When SX1278_LoRaTxPacket() returns 0 it means that the package was not sent. Also the DIO0 is being used to check if the message actually was sent over. Removing dependencies on DIO0 from configuration is not advised. Also, I believe end of transmitting can be pulled using internal registers but it required to change the configuration. Please check the manual for this.
Hi am using your project
On the Master Side:
Sending Hello 3
Transmission: 1
Package sent…
Master …
Sending package…
Entry: 0
Sending Hello 4
Transmission: 1
Package sent…
Master …
Sending package…
Entry: 0
Sending Hello 5
Transmission: 1
Package sent…
why the Entry is 0 and the transmission is 1 ! what I can understand from this ?
SX1276 module
why in the SX1278_LoRaEntryRx()
SX1278_SPIWrite(module, REG_LR_DIOMAPPING1, 0x01);
//does 0x01 mean DIO0=0, DIO1=0, DIO2=0, DIO3=1 ? if I am using DIO0 should it be 0x08 ??
and in the SX1278_LoRaEntryTx()
SX1278_SPIWrite(module, REG_LR_DIOMAPPING1, 0x41); // what does 0x41 mean !!
DIO0 is used by default and this is how the LoRa module was configured. You do not need to change it.
Hello! Thank you for sharing this project. I am currently working on implementing this project for my STM32F0. For some reason System Workbench says that „expected ‚=’, ‚,’, ‚;’, ‚asm’ or ‚__attribute__’ before void (or any datatype)” on lines 256-262 and „unknown type name ‚__weak’ on line 260 of SX1278.h . What would be your advice of solving those issues? Thank you!
You have to add a definition. Best it is to add it for your compiler with -D option
“__weak=__attribute__((weak))”
The errors are gone! Thank you for that. I have another question: I would like to change the frequency operated to 915MHz as I am using an SX1276. I noticed that you defined the frequency as : “#define SX1278_433MHZ 0” and “static const uint8_t SX1278_Frequency[1][3] = { { 0x6C, 0x80, 0x00 }, };” on lines 169-172. May I ask what those numbers mean and some guidance on how to change the number so that it is suitable for 915MHz? Thank you again.
Please disregard the reply. I got the answer from your previous replies.
This is my calculation: 915MHz/61Hz = 15000000;
15000000 base 10 = 0xE4E1C0
then at those registers I have to overwrite 0xE4 0xE1 0xC0.
Would that be right? Thank you.
I was about to propose the very same, to check out the previous answers. Generally yes. You have to overwrite the 3 bytes.
Also, please keep in mind that usually modules have a bandpass filter. Even if you change the frequency in the LoRa module the transmitted signal will be very weak.
Will the signal be weak even though SX1276 is designed for frequencies between 137-1030MHz? I noticed that SX1278 only has a frequency range of 137-525MHz but the spreading factor, bandwidth, effective bitrate, and sensitivity ranges on the datasheet are the same. Because the datasheet has SX1276, 77, 78, and 79 combined, I think the SX1276 chip should work in the same way as the SX1278 chip.
It is not a matter of supported frequencies of the SX1276 chip. Depending on what kind of the module you are using some have a bandpass filter which reduces other frequencies.
Although, I believe that you should be able to receive some signal on your desk. Moreover, you can always design your own RF PCB with SX1278 LoRa chip.
Hello!
Thanks a lot for provide this Library!
I didn’t understand the role of the function SX1278_LoRaEntryTx, in the Master code. Can you explain?
The example works fine for me. I’m using keil.
The function which you have mentioned is used to configure the module in transmitter mode. You can change the operation mode by calling its receiver counterpart.
My application need bidirectional communication. In order to do that, i used the function that you described, however, didn’t work.
I initially uses the F103_1 as master and the F103_2 as slave, and did work. But when I try to change (F103_1 as slave and F103_2 as master), the same code didn’t work. I used the functions ret = SX1278_LoRaEntryRx(&SX1278, 16, 2000); and ret = SX1278_LoRaEntryTx(&SX1278, 16, 2000);. Both returned 1 in ret, and the function ret = SX1278_LoRaTxPacket(&SX1278, (uint8_t *) buffer, message_length, 2000); in the F103_2 (working as master) return 1 to ret too, but the F103_1 doesnt receive the package.
Can you help me? Did you already test bidirection code with this lib?
Thanks a lot
To speak frankly, I have not tested the bidirectional transmission. However, I have this on my bucket list. Currently, I am working on a different driver. When I will have some time I will check this. Probably modify the driver and corresponding example.
Hi, you wrote a code specifically for sx1278. ST provides code for sx1276 for example. Do you know if sx1278 chip will run on sx1276 drivers for 433 MHZ? since the supported frequencies seem to be the only difference between the chips. The pinout and registers are the same as far as 433mhz goes.
Yes, those two chips are virtually the same. The difference is about frequency range. This subject was already tuckled many times and also one of the Readers has successfully used the code with some changes. Please keep in mind that if you use a module there is usually a bandpass filter and changing the frequency can have very poor effect.
Hello, I configured your driver as in the example, but nothing is visible at the frequency of 433-434mHz. I looked at other frequencies and it turned out that there are some signals on the frequency 234mHz. I attach a photo. The question is, should LoRa packages look like this and if so, why is it transmit on the wrong frequency? Link to picture: https://ibb.co/YfNFdx7
I wanna thank you,
It works for me, I’m using sx1276, 868MHZ, STMF4 discovery with Keil v5.
I’m setting SPi baud rate to 2.0Mbits/s (for F4 discovery: clock 128MHz and Spi prescaler to 32 ) .
I’m really glad that it is working for you. So, the driver works on SX1276 at 868MHz. Have you changed anything other than frequency in the driver configuration?
Can you share the project? I’ve been trying to migrate the example to my board with an stm32f4 and I can’t get it. You tell me if you have Github or if you can mail it to me.
Thanks
Can you share me a your SX1276 project with STM32
I also decided to check the RegIrqFlags register to read the tx_done interrupt, but it reads as 0x00, SPI is working, all other registers are read and written. What might be the problem?
Which chip do you use? Is it SX1278 or a different one. Also what is the frequency you have set?
I’m using SX1278 chip. Frequency set to 434mHz (0x6C 0x80 0x00 in registers RegFRMsb, RegFRMid and RegFRLsb)
Hi again! Through trial and error, it turned out that the module is in sleep mode,because the RegOpMode (0x01) register in the last 3 bits contains 000 (Sleep mode), the problem is that if i write data to these 3 bits, they are ignored and remain 000. (bit 7, 6 and 3 write and read normally) What am I doing wrong?
It is strange, that after the initialization the chip goes to sleep mode. Could you verify if you can get some data from the chip. For example, please read some data from a configuration register without initialization of the device. This will let us verify if communication is working properly.
I have read the RegVersion register and other registers and it is readable (link: https://ibb.co/LgF7QzH)
don’t pay attention to the ‘error’ parameter (nothing is read here, just the value 0xFF)
Do the registers hold the correct value as described in the manual?
Yes, for example register preambleMsb and preambleLsb contains 0x00 and 0x08 as it is written in the datasheet
And what happens after initialization and entering receiver mode? In what state is the device, is it still in sleep mode?
Yes after initialization i read register 0x01 (RegOpMode) the last 3 bits are ALWAYS in the zero state, the write to these bits of StandBy mode is ignored
That’s strange. Could you check one more thing, namely read the mode register without initialization and please give the value.
I provide two cases: read register in the setup and read register in the loop. In both cases value 0x08. In the setup i make reset as follows: RESET_PIN to GPIO_PIN_RESET -> HAL_Delay(1) -> RESET_PIN to GPIO_PIN_SET -> HAL_Delay(100). In the loop i read register once per second. In the datasheet write that reset state of the RegOpMode – (bit 7 long range mode – 0, bit 6 accessSharedReg – 0, bit 5-4 reserved – 0, bit 3 lowFrequencyModeOn – 1, bit 2-0 mode – 0x01. The value 0x08 describe that all bits right but first 3 bits contain 000 instead of 0x01.
It seems like you have permanently enabled low frequency mode. Can you change it by hand and verify if it was changed. Please keep in mind that it can be changed when conditions are are met. Please refer to manual.
I change in RegOpMode register bit 4 lowFrequencyModeOn to 0. It is written and read. And still the first 3 bits of the MODE do not change. When im write 0b1000001 to RegOpMode its read as 0b10000000
I do not quite understand. You are changing the LowFrequencyModeOn bit (bit number 3 starting from 0) and you want to change the value of the Mode bits?
I would suggest to read the RegOpMode and modify only LowFrequencyModeOn bit.
I cleared 3 bit LowFrequencyModeOn like that:
SX1278_SPIWrite(&SX1278, 0x01, SX1278_SPIRead(&SX1278, 0x01) & ~(1 << 3));
And read this register again and return value is 0x00 (bit3 cleared).
What should I do next?
Thank you in advance!
I would suggest now setting the state of the SX1278 accordingly. Just try to move it from the sleep state by changing the value of the last three bits. Please mind the state machine diagram in the manual.
After setting it to other state try to read the value of this register once again. If it was done correctly i should indicate a different state.
Nevertheless, it is very strange that your device behaves in this way. Do you have a different unity to try it? Also, could you share which unit you are using?
I’m trying to change 0 bit like that:
SX1278_SPIWrite(&SX1278, 0x01, SX1278_SPIRead(&SX1278, 0x01) | (1 << 0));
but register OpMode still contains 0x00. Bit 0 don't change.
I use this radio lora chip:
https://aliexpress.ru/item/32956607098.html?spm=a2g0o.cart.0.0.207d3c00GfLDk6&mp=1
From manual point of view you are doing this right. You are transferring from sleep mode to standby mode. This should be possible.
Please try instead of reading current value of the register under 0x01, write there 0x01 directly. Then we will be certain that you are entering standby mode.
Maybe the problem is the wrong clocking setting? The link attached clock configuration for my stm32f405.
https://ibb.co/18F4qW0
I also have an external 8 MHz quartz resonator.
I doubt that. What is your SPI frequency setting?
SPI Frequency is 18 Mbits/s
This is my SPI configuration in STM Cube MX https://ibb.co/yFfp1D2
And there we have it! The clock speed is to high. According to the manual maximum is 10MHz.
Have you shared your project on Github or something else?
This is my project on github: https://github.com/gug2/SX1278AndSTM32F405
And how do I set the SPI frequency to 10mHz if it is specified in Mbits/s?
Just increase the prescaler of the SPI. Now you have it set to 2. Increasing it to 4 should be fine.
Wojciech I tried all the SPI prescalers, but the result didn’t change
I also noticed that if you first write to the first 3 bits (mode) then the the following write are not readable (everything is read as 0x00) and if you write first to 7 bits (Lora mode) that value is read EXCEPT for the last 3 bits. I have 2 LoRa modules, I tried each one, I don’t think the problem is with the chip itself.
I have noticed that you have two versions of LoRa drivers. Please clean up the project and use the appropriate one. If you are using SX1276 then make changes to SX1278 driver. Now, it is hard to say what’s going on. Please push the changes to the repo and let me know.
I change my github project. https://github.com/gug2/SX1278AndSTM32F405
Wojciech I replaced STM32 with a copy, and now LoRa in RegOpMode register shows 0x09! It seems to be transmitting, but I haven’t checked it yet. I will check and write the results.
You mean you have used different microcontroller?
The microcontroller model is the same, just a different unit. I will check radio module soon and write here.
Wojciech, I checked your driver, entryTx and txPacket return 1, but the data is not transmitted. In the txPacket function, instead of listening for pin Dio0 i read the loraIrqFlags register.
Wojciech thank you very much for your help! LoRa is finally transmitting the data! Most likely, the problem was in a defective microcontroller, everything works on its copy!
I am glad that everything worked out. That is a bit curious that a defective MCU turned out to be a problem. If you would use blue pill then yes. Allegedly lots of those have STM32 MCU clones.
It is not known for sure whether the microcontroller is to blame, because I replaced both the LoRa module and the microcontroller, so there is a 50/50 chance that the microcontroller was to blame. The LoRa module may have been faulty.
I tried on the Arduino and the module is working
If you need to know I use the stm32f4.
Can I Use This Library to SX1276 Module ?
Yes you can! Please look through the comments. There are a few people who have successfully deployed it for this chip.
Wojciech do you have any ideas about my problem?
Hello,
First, Thank you for this collaboration, are helping a lot.
Second, Can I use the program in STM32G0? I use the STM32CubeIDE with the HAL.. which would be the steps to make that happen?
(Ive looking for code examples but the ones i used had a lot of information and didnt work)
Yes, you only need SPI if your MCU supports it that’s that.
Also remember to update hardware dependant parts of the driver, then it should work out of the box.
THanks A lot , working for SX1276 chip , only frequency change.
hola, pregunta ¿sobre que tarjeta realizo el proyecto con el sx1276 ?, ¿se deben de tener los dos modulos conectados y programados para poder tener alguna respuesta en el debuger?
hola excelente documento
tengo varias dudas
1) ¿puedo usar este codigo para un STM32L051C8Tx?
2)¿como puedo usar el debug?
Hello, I want to ask how to use interruption mode.
what should I change on the sender side and the receiver side ?
Is it with keeping the same sending and receiving function ?
I’m trying too use exti interruption to send the lora messege when the user butten is pressed.
First ,I tried to send msg on the usart serial port and it works fine , but when I use your SX1278_LoRaEntryTx() and SX1278_LoRaTxPacket() functions it stucks there and never get over it( checked in debugging mode ).
I did include your the sx1278.h library in the it.c file and redefined every used variable as extern in the it.c file.
can you help .
Delegating sending/receiving to user-mode part of code is the best option. You should not use sending receiving commands in the interrupt mode.
dear Wojciech.
I’m using pure CMSIS coding.
Not a HAL.
Maybe you have that project in CMSIS code?
It is hard to migrate and resolve a structures like:
SX1278_hw.dio0.port = DIO0_GPIO_Port;
SX1278_hw.dio0.pin = DIO0_Pin;
SX1278_hw.nss.port = NSS_GPIO_Port;
SX1278_hw.nss.pin = NSS_Pin;
SX1278_hw.reset.port = RESET_GPIO_Port;
SX1278_hw.reset.pin = RESET_Pin;
SX1278_hw.spi = &hspi1;
Would you HELP with this, please?
Thank you.
In general port filed of the hardware structure holds pointers to void. This allows you to hold any kind of address in this structure including raw register address.
You can adjust the code to completely drop HAL.
Hello! just a feedback of my experience with sx1276.
I’ve done tests with a sx1276 chip (RF95) with the original code and worked, but with very short range. After that I changed the frequency following the Z comment to 915MHz. I walked outside 90m from the radio(more or less) and still there was signal. Then I had to return.
By the way, where can I find this information about the set up of the radio frequency and maybe other valued information? thanks
I’m glad it works. The frequency set up is described in the manual of the chip. Only a change in one register is required. It boils down to changing adequate lines in the source file.
Thanks Domski for this helpful article.
I have a question , in order to achieve a bidirectional link between nodes (tx and rx) , what we should do to switch front and back between tx and rx in the same node ?
Does this need some specific work besides this library ?
Regards,
Mohammed
No, you do not need anything else. Only thing which is required is to invoke entry function before sending or receiving data. Please keep in mind that you need to invoke entry TX mode function only once you want to send multiple of data packages.
Thanks guru,
I confirm the library is working with SX1276 with a good range (1Km) :
static const uint8_t SX1278_Frequency[8][3] = {
{ 0xE2 , 0x1A, 0xF0 }, //903.9MHz
{ 0xE2 , 0x27, 0xBF }, //904.1MHz
{ 0xE2 , 0x34, 0x8E }, //904.3MHz
{ 0xE2 , 0x41, 0x5C }, //904.5MHz
{ 0xE2 , 0x4E, 0x2B }, //904.7MHz
{ 0xE2 , 0x51, 0xFA }, //904.9MHz
{ 0xE2 , 0x67, 0xC8 }, //905.1MHz
{ 0xE2 , 0x74, 0x97 }, //905.3MHz
};
Now i’m going to test a bidirectional link with a custom protocol (LOWAPP).
Thanks again
Nice! Please stay tuned because in a near future I plan to add some improvements to the library.
Just keep in mind that bidirectional means Half-Duplex, meaning that simultaneously you can either transmit or receive.
Great.
Which improvements you have in mind ?
Another rapid question ,how to put the module in the most saving energy mode ? and how to wake it up ? Should we reconfigure the module after such steps ?
I plan to publish the new feature which will lower the entry level of starting tinkering with LoRa. It will allow to specify the frequency instead of manually changing the register values. Also something additional is in plan 😉
For low power modes I would suggest to consult the manual. It is described in it which level is the best for power saving. Also keep in mind that in some modes you won’t be able to receive anything, like sleep mode. I reckon that you are interested in receiving data while idling on low power mode. I believe that you can use IRQ to wake up MCU on data reception via LoRa module by configuring its DIO pins.
Seems interesting , can’t wait to see the update.
Thanks a lot man
Hello, Wojciech.
Thanks for the library for SX1278, as I understand it can be used for SX1276? But I have a question – I looked at the example and did not find the activation procedure there (OTAA or ABP). Or is activation unnecessary and the device can simply broadcast packets?
Hello Mr. Domski,
Hello first. Thank you very much for sharing the project and answering the questions asked. I want to use this module on STM32F407 and STM32F429 boards. I have compiled the code but cannot send or receive data. Ret = 0 always. I shared my code in githup. Can you examine where I am making mistakes.
https://github.com/MahmutKocamann/SX1276/tree/master/Src
Thank you very much for everything Mr. Domski. A healthy data transmission occurred in the receiver and transmitter. It worked on STM32F407 and STM32f429 cards. sx1276.
Hello, can you share how it works on Sx1276
It works on this chip. Please look through the comments. Also the new version of the driver supports setting frequency during initialization so you should be good to go.
Hi Mahmut, can you tell me how to make it work? I also get ret0 in receiver and transmitter.
Hi Mahmut, please tell me what was your mistake?
Dear Mahmut,
Any chance we can share the SX1262 code changes? Thanks!
[email protected]
John
hi, excellent documentation for using these great LoRa modules
although I have a question
What is the minimum and maximum speed in baud / s of the SPI bus configuration?
Greetings from Colombia
Please refer to the LoRa chip manual. If I remember well, the maximum clock frequency is 10MHz.
Hi
I’ve gave it a try, It works greatly!
But I’ve an issue receiving from ESP8266 using RadioLib.
I’ve tried my best to have common configuration. But I receive in esp8266 side around tenth of total messages sent via stm32 bluepill.
Any Idea what could be incompatible ?
RadioLib example code : https://github.com/jgromes/RadioLib/blob/master/examples/SX127x/SX127x_Receive/SX127x_Receive.ino
My tweaked init to meet the other side configs :
SX1278_init(&SX1278, 434000000, SX1278_POWER_11DBM, SX1278_LORA_SF_9,
SX1278_LORA_BW_125KHZ, SX1278_LORA_CR_4_7, SX1278_LORA_CRC_EN, 10);
Hi
I’ve found the answer, It was that library doesn’t enable CRC.
And the provided library here uses LoRaWAN syncWord 0x34, while RadioLib defaults it to 0x12,
I suggest to make it selectable too, I can contribute to library too.
Hello, Wojciech Domski!
Thank you for the driver!
I`m using MC STM32f103C8 and SX1276 LORA module and have some problems with a receiver.
In my opinion, a transmitter doing just fine, but in a receiver part of code, in the function SX1278_LoRaRxPacket an operator if (SX1278_hw_GetDIO0(module->hw)) doesn`t work.
Would you help me with this, please?
Thank you.
I would check if there is any transmission going on. Beside that please double check the SPI configuration. It is the most common issue.
Hi, I am using STM32L053 with this library. But problem is transmitter is not transmitting at all.
temp = SX1278_SPIRead(module, LR_RegPayloadLength);
if (temp == length) {
module->status = TX;
return 1;
This is LoRAEntryTX function which I can’t understand. What is the meaning of it?
My problem is temp = SX1278_SPIRead(module, LR_RegPayloadLength);
SPIRead function always returns 255 which is not compatible with temp == length condition. Do you have any idea? I think I correctly initialized spi.
Thanks.
Hi Wojciech, I am using your driver in combination with STM32L053 but I have problem with transmission. SPIRead function always returns 255. Do you have any idea on this? I think I am correctly done SPI.
Hi! Of you are getting problems related to transmission or reception the the most probable cause is SPI misconfiguration. Also make sure that all the pins are correctly connected.
Hi Wojciech, Thanks for quick reply. Could you please quick check my code?
https://github.com/magicaldev3000/transmitter
It works great. Thanks Wojciech. The problem was I changed MISO and MOSI lines each other. I just copied SX1278 directory to STM32L053 hal directory and included that. For distance 1Km, it works without any problems. Really appreciate your work.
Cool! Glad to hear that!
Hi Wojciech, I am using the „SX1272 mbed shield SX1272MB2xAS”. You said I can use your example (and driver) with this board. What minor modifications need to be made to your example to make it work with this board???
Thanks.
Best regards,
Now, no additional changes are required since you only need to set the correct frequency. With the new release of the driver it is easier.
Dear Wojciech, can we use sx1262 for this driver? This chip is set to replace sx1278 and sx1276 and had lower power consumption. Thanks
Edited comment: No you can not. This chip is different.
What changes I have to made in order to work this driver for SX1262? Seems some registers also different. Is it really work with SX1262.Please help I stuck on this issue for a month.
I used this driver for sx1262.but it always return 0 for both transmission and reception. Could you please help me?
The driver was intended to be used with SX1276/77/78/79. The SX1262 has a different configuration. However, after adjusting the initialization and sending/receiving everything should work as with the original driver.
Dear brother Wojceich, can we please have more hints on which parts of the code to change to make it work with sx1262 please?
hi, the ret value of my receiver keeps returning zero for the ret = SX1278_LoraRxPacket(&SX1278) function even though it returns 1 right at the beginning for the ret = SX1278_LoRaEntryRx(&SX1278, 16, 2000) function. I am using the STM32 Nucleo F901RC board as my receiver (slave )and the Nucleo F446RE for my transmitter. Upon debugging using breakpoints and checking the return values of the functions linked with the SX1278_LoRaRXPacket fucntion, it seems that my DIO0 pin is not being set and remains Zero, which then causes the ret value to be Zero.
My transmitter on the other hand works well and seems to be transmitting the data as the hello message is incrementing.
Please assist ASAP, it’s part of my University project.
The most common reason for this is wiring or misconfiguration of SPI. Could you share yours? As for the transmitter, how did you make sure that it is actually sending something?
Hello,
i use the SX1276 with the STM32F103C8Tx on a custom made pcb. Unfortunately when using your test program, I am not able to get anything sent out of the module. Both modules have the same configuration, one is the master which sends data the other is the slave which receives it. The master says it sends data, the slave doesn’t receive anything. I also checked the frequency band with an rtl-sdr and there is nothing visible.
Can you please take a look on my code, which is a modified version of your example program. I also uploaded the schematics of the pcb.
Also, on the current version of the pcb the DIO0 Pin and the Reset Pin are not connected on the SX1276 chip. Is that a problem?
my github: https://github.com/mizweimueller/telemetry_right_chip
Kind regards
You have the master variable set to 1 , did u change that on slave node ?
I’m glad that you have mentioned these pins DIO0 and RESET. These are required.
@med: Yes I did change that on the slave node.
@Wojciech Domski: So if I do not have these pins connected I can’t get anything sent from the module?
Without the DIO0 I believe you could manage, although you would need to read status registers RegIrqFlags and therefore change the driver itself.
I think that reset pin is not necessary. However, it makes things easier. You would need to consult the documentation for this.
Dear Wojciech, Can you show us how to change these configurations for the SX1262? Or can you share an example where SX1262 can communicate with SX1276? I’ve been stuck on this for a month. Please help, Mr. Domski.
RSSI value is always between 20 to 40.. it should be around 100 – 140 for long distances, isn’t it?
ThankS!
Dear Wojciech, Can you show us how to change these configurations for the SX1262? Or can you share an example where SX1262 can communicate with SX1276? I’ve been stuck on this for a month. Please help, Mr. Domski.
Hi SX1261 and SX1262 are newer chips from Semtech. I did not have a chance to work with them yet. They offer lower power consumption in receiver mode.
Have a look on registry map and adjust the configuration in init function. From what I could see in the documentation the configuration would be similar.
Thank you for your reply, Mr. Domski. If I have the configuration right, they can communicate with each other, right? I think the important thing here is frequency. I could not communicate even though I made the frequency the same on ST’s own samples. I will write the code from scratch again. I hope it works.
Matching signal parameters is the most important thing. You should match not only the frequency but also spread factor, bandwidth. Generally all parameters that impact transmition. For example, SX1262 can go with spread factor equal to 5 while for SX1278 it starts at 6.
Thanks you, I really appreciate your work!
I am a beginner, just started studying Lora …
Thanks to your example, everything working well between one master and one slave!
Questoin: I have one board a Meser and two boards of slaves.
How to implement the sending of personal messages from the MASTER to the SLAVE?
Do do this you need to introduce addressing at least. Each slave will listen for the incoming messages and when the address in a message matches with slave’s address you act upon it.
You could implement a whole protocol for your devices, e.g. LORAWAN or something much simpler if you only need address matching.
Please have a look at NRF905 it has build in capabilities for address matching but it is using different modulation.
Dear Domski, actually I managed to communicate the Sx1276 and Sx1262, but I have a small problem. First, I configured the Sx1262 as a transmitter and I configured the Sx1276 as a receiver. When I do this, both work flawlessly. However, when I configure the Sx1276 as a transmitter and I configure the Sx1262 as a receiver, the SX1262i cannot receive messages. I am using the Sx1276 as an external module and I am using the Sx1262 on the STM32WLE. I am still working on this problem.
I vote for Wojceich to make one for SX1262 because he’s a champion!! A trillion thanks!
I’m voting too. It would be really cool if he could share an example of the Sx1262. Many thanks to him for everything.
Thanks guys! Maybe in future I will dive into it. BTW. what is wrong with SX1278 or SX127X in general that you WAN to use SX126X?
Dear Domski, actually I managed to communicate the Sx1276 and Sx1262, but I have a small problem. First, I configured the Sx1262 as a transmitter and I configured the Sx1276 as a receiver. When I do this, both work flawlessly. However, when I configure the Sx1276 as a transmitter and I configure the Sx1262 as a receiver, the SX1262i cannot receive messages. I am using the Sx1276 as an external module and I am using the Sx1262 on the STM32WLE. I am still working on this problem.
Worked a treat. Nucleo411 and Blackpill411 using two Adafruit Rfm96W modules.
Up and running in a few hours – well impressed, thanks
Thanks! Much appreciated.
Hi again, I’ve been using you library for a while now and it is rock solid.
I’m confused about one thing though, this is switching beween Tx and RX modes.
Below is your example, but with just the LoRa master switching logic.
I think the call “ret = SX1278_LoRaEntryTx(&SX1278, 16, 2000);” is not required – I dont seem to need it in my code.
Can you also explain what parameter value 16 is for. Is this a dummy value and could be anything?
Thanks,
Mark
while (1) {
if (master == 1) {
ret = SX1278_LoRaEntryTx(&SX1278, message_length, 2000);
ret = SX1278_LoRaTxPacket(&SX1278, (uint8_t*) buffer, message_length, 2000);
} else {
ret = SX1278_LoRaRxPacket(&SX1278);
SX1278_read(&SX1278, (uint8_t*) buffer, ret);
}
master = ~master & 0x01;
if (master == 1) {
ret = SX1278_LoRaEntryTx(&SX1278, 16, 2000);
} else {
ret = SX1278_LoRaEntryRx(&SX1278, 16, 2000);
}
}
Hello,
First of all, thank you for your work, it helped me a lot!
I have a small problem that I could not solve:
When I use my STM32f7 card as a transmitter and my nucleof7 as a receiver everything works perfectly! But when I exchange the roles the nucleo sends the data and the stm32 is in reception mode (ret = 1 at the beginning) but it does not receive any data (Received: 0)
I wonder if it is not a problem of clock I configured them with CubeMX and for the stm32 I put a prescaler of 8 what gives me a baud rate of 6,75 MBits/s and for the nucleo I also put a prescaler of 8 but I have a baud rate of 9MBits/s
Thank you for your help
hi
i use sx1278
but i have an error at this line :
SX1278_begin(&SX1278, SX1278_433MHZ, SX1278_POWER_20DBM, SX1278_LORA_SF_6,SX1278_LORA_BW_500KHZ, 64);
sofware cant know this function : sx1278_begin(….)
why ?
please help me thank you.