mirror of
				https://github.com/manuelbl/ttn-esp32.git
				synced 2025-10-31 10:40:35 +01:00 
			
		
		
		
	Receive downlink messages
This commit is contained in:
		| @ -1,4 +1,2 @@ | ||||
| CFLAGS += -Wno-error=maybe-uninitialized -Wno-error=unused-value | ||||
|  | ||||
| COMPONENT_ADD_INCLUDEDIRS := include | ||||
| COMPONENT_SRCDIRS := src | ||||
|  | ||||
							
								
								
									
										3
									
								
								examples/send_recv/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								examples/send_recv/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| PROJECT_NAME := hello_world | ||||
|  | ||||
| include $(IDF_PATH)/make/project.mk | ||||
							
								
								
									
										1
									
								
								examples/send_recv/components/ttn-esp32
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								examples/send_recv/components/ttn-esp32
									
									
									
									
									
										Symbolic link
									
								
							| @ -0,0 +1 @@ | ||||
| ../../../../ttn-esp32/ | ||||
							
								
								
									
										0
									
								
								examples/send_recv/main/component.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								examples/send_recv/main/component.mk
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										87
									
								
								examples/send_recv/main/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								examples/send_recv/main/main.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | ||||
| /******************************************************************************* | ||||
|  * Copyright (c) 2018 Manuel Bleichenbacher | ||||
|  *  | ||||
|  * All rights reserved. This program and the accompanying materials | ||||
|  * are made available under the terms of the Eclipse Public License v1.0 | ||||
|  * which accompanies this distribution, and is available at | ||||
|  * http://www.eclipse.org/legal/epl-v10.html | ||||
|  * | ||||
|  * Sample program showing how to send a test message every 30 second. | ||||
|  *******************************************************************************/ | ||||
|  | ||||
| #include "freertos/FreeRTOS.h" | ||||
| #include "esp_event.h" | ||||
|  | ||||
| #include "TheThingsNetwork.h" | ||||
|  | ||||
| // NOTE: | ||||
| // The LoRaWAN frequency and the radio chip must be configured by running 'make menuconfig'. | ||||
| // Go to Components / The Things Network, select the appropriate values and save. | ||||
|  | ||||
| // Copy the below hex string from the "Device EUI" field | ||||
| // on your device's overview page in the TTN console. | ||||
| const char *devEui = "????????????????";; | ||||
|  | ||||
| // Copy the below two lines from bottom of the same page | ||||
| const char *appEui = "????????????????"; | ||||
| const char *appKey = "????????????????????????????????"; | ||||
|  | ||||
|  | ||||
| static TheThingsNetwork ttn; | ||||
|  | ||||
| const unsigned TX_INTERVAL = 30; | ||||
| static uint8_t msgData[] = "Hello, world"; | ||||
|  | ||||
|  | ||||
| void sendMessages(void* pvParameter) | ||||
| { | ||||
|     while (1) { | ||||
|         printf("Sending message...\n"); | ||||
|         ttn_response_t res = ttn.sendBytes(msgData, sizeof(msgData) - 1); | ||||
|         if (res == TTN_SUCCESSFUL_TRANSMISSION) | ||||
|             printf("Message sent.\n"); | ||||
|         else if (res == TTN_SUCCESSFUL_RECEIVE) | ||||
|             printf("Message sent and message received\n"); | ||||
|         else | ||||
|             printf("Message transmission failed.\n"); | ||||
|  | ||||
|         vTaskDelay(TX_INTERVAL * 1000 / portTICK_PERIOD_MS); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void messageReceived(const uint8_t* message, size_t length, port_t port) | ||||
| { | ||||
|     printf("Message of %d bytes received on port %d:", length, port); | ||||
|     for (int i = 0; i < length; i++) | ||||
|         printf(" %02x", message[i]); | ||||
|     printf("\n"); | ||||
| } | ||||
|  | ||||
| extern "C" void app_main(void) | ||||
| { | ||||
|     gpio_install_isr_service(ESP_INTR_FLAG_IRAM); | ||||
|  | ||||
|     // Initialize SPI bus | ||||
|     spi_bus_config_t spi_bus_config; | ||||
|     spi_bus_config.miso_io_num = 19; | ||||
|     spi_bus_config.mosi_io_num = 27; | ||||
|     spi_bus_config.sclk_io_num = 5; | ||||
|     spi_bus_config.quadwp_io_num = -1; | ||||
|     spi_bus_config.quadhd_io_num = -1; | ||||
|     spi_bus_config.max_transfer_sz = 0; | ||||
|  | ||||
|     esp_err_t ret = spi_bus_initialize(HSPI_HOST, &spi_bus_config, 1); | ||||
|     assert(ret == ESP_OK); | ||||
|  | ||||
|     ttn.configurePins(HSPI_HOST, 18, TTN_NOT_CONNECTED, 14, 26, 33); | ||||
|  | ||||
|     ttn.provision(devEui, appEui, appKey); | ||||
|  | ||||
|     ttn.onMessage(messageReceived); | ||||
|  | ||||
|     printf("Joining...\n"); | ||||
|     ttn.join(); | ||||
|     printf("Joined.\n"); | ||||
|  | ||||
|     xTaskCreate(sendMessages, "send_messages", 1024 * 4, (void* )0, 3, NULL); | ||||
| } | ||||
| @ -15,9 +15,6 @@ | ||||
| #include <stdint.h> | ||||
| #include "driver/spi_master.h" | ||||
|  | ||||
| #define TTN_DEFAULT_SF 7 | ||||
| #define TTN_DEFAULT_FSB 2 | ||||
|  | ||||
| /** | ||||
|  * @brief Constant for indicating that a pin is not connected | ||||
|  */ | ||||
| @ -37,6 +34,14 @@ enum ttn_response_t | ||||
|   TTN_SUCCESSFUL_RECEIVE = 2 | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * @brief Callback for recieved messages | ||||
|  *  | ||||
|  * @param payload  pointer to the received bytes | ||||
|  * @param length   number of received bytes | ||||
|  * @param port     port the message was received on | ||||
|  */ | ||||
| typedef void (*message_cb_t)(const uint8_t* payload, size_t length, port_t port); | ||||
|  | ||||
| /** | ||||
|  * @brief TTN device | ||||
| @ -114,11 +119,35 @@ public: | ||||
|      */ | ||||
|     bool join(); | ||||
|  | ||||
|     /** | ||||
|      * @brief Send a message | ||||
|      *  | ||||
|      * @param payload  bytes to be sent | ||||
|      * @param length   number of bytes to be sent | ||||
|      * @param port     port (default to 1) | ||||
|      * @param confirm  flag indicating if a confirmation should be requested. Default to 'false' | ||||
|      * @return TTTN_SUCCESSFUL_TRANSMISSION    Successful transmission | ||||
|      * @return TTTN_SUCCESSFUL_RECEIVE         Successful transmission and a message has been received | ||||
|      * @return TTN_ERROR_SEND_COMMAND_FAILED   Transmission failed | ||||
|      * @return TTTN_ERROR_UNEXPECTED_RESPONSE  Unexpected response | ||||
|      */ | ||||
|     ttn_response_t sendBytes(const uint8_t *payload, size_t length, port_t port = 1, bool confirm = false); | ||||
|  | ||||
|     /** | ||||
|      * @brief Set the function to be called when a message is received | ||||
|      *  | ||||
|      * When a message is received, the specified function is called. The | ||||
|      * message, its length and the port is was received on are provided as | ||||
|      * parameters. The values are only valid during the duration of the | ||||
|      * callback. So they must be immediately processed or copied. | ||||
|      *  | ||||
|      * @param callback  the callback function | ||||
|      */ | ||||
|     void onMessage(message_cb_t callback); | ||||
|  | ||||
|  | ||||
| private: | ||||
|     uint8_t spreadingFactor = TTN_DEFAULT_SF; | ||||
|     uint8_t frequencySubband = TTN_DEFAULT_FSB; | ||||
|     message_cb_t messageCallback; | ||||
|  | ||||
|     bool decodeKeys(const char *devEui, const char *appEui, const char *appKey); | ||||
| }; | ||||
|  | ||||
| @ -112,12 +112,16 @@ bool TheThingsNetwork::join(const char *devEui, const char *appEui, const char * | ||||
|  | ||||
| bool TheThingsNetwork::join() | ||||
| { | ||||
|     int result = 0; | ||||
|     // empty queue | ||||
|     while (xQueueReceive(result_queue, &result, 0) == pdTRUE) | ||||
|         ; | ||||
|  | ||||
|     hal_enterCriticalSection(); | ||||
|     LMIC_startJoining(); | ||||
|     hal_wakeUp(); | ||||
|     hal_leaveCriticalSection(); | ||||
|  | ||||
|     int result = 0; | ||||
|     while (true) | ||||
|     { | ||||
|         xQueueReceive(result_queue, &result, portMAX_DELAY); | ||||
| @ -130,6 +134,11 @@ bool TheThingsNetwork::join() | ||||
|  | ||||
| ttn_response_t TheThingsNetwork::sendBytes(const uint8_t *payload, size_t length, port_t port, bool confirm) | ||||
| { | ||||
|     int result = 0; | ||||
|     // empty queue | ||||
|     while (xQueueReceive(result_queue, &result, 0) == pdTRUE) | ||||
|         ; | ||||
|  | ||||
|     hal_enterCriticalSection(); | ||||
|     if (LMIC.opmode & OP_TXRXPEND) | ||||
|     { | ||||
| @ -141,9 +150,28 @@ ttn_response_t TheThingsNetwork::sendBytes(const uint8_t *payload, size_t length | ||||
|     hal_wakeUp(); | ||||
|     hal_leaveCriticalSection(); | ||||
|  | ||||
|     int result = 0; | ||||
|     xQueueReceive(result_queue, &result, portMAX_DELAY); | ||||
|     return result == EV_TXCOMPLETE ? TTN_SUCCESSFUL_TRANSMISSION : TTN_ERROR_SEND_COMMAND_FAILED; | ||||
|  | ||||
|     if (result == EV_TXCOMPLETE) | ||||
|     { | ||||
|         bool hasRecevied = (LMIC.txrxFlags & (TXRX_DNW1 | TXRX_DNW2)) != 0; | ||||
|         if (hasRecevied && messageCallback != NULL) | ||||
|         { | ||||
|             port_t port = 0; | ||||
|             if ((LMIC.txrxFlags & TXRX_PORT)) | ||||
|                 port = LMIC.frame[LMIC.dataBeg - 1]; | ||||
|             messageCallback(LMIC.frame + LMIC.dataBeg, LMIC.dataLen, port); | ||||
|         } | ||||
|  | ||||
|         return hasRecevied ? TTN_SUCCESSFUL_RECEIVE : TTN_SUCCESSFUL_TRANSMISSION; | ||||
|     } | ||||
|  | ||||
|     return  TTN_ERROR_SEND_COMMAND_FAILED; | ||||
| } | ||||
|  | ||||
| void TheThingsNetwork::onMessage(message_cb_t callback) | ||||
| { | ||||
|     messageCallback = callback; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -190,9 +218,7 @@ void onEvent (ev_t ev) { | ||||
|  | ||||
|     if (ev == EV_TXCOMPLETE) { | ||||
|         if (LMIC.txrxFlags & TXRX_ACK) | ||||
|             ESP_LOGI(TAG, "Received ack\n"); | ||||
|         if (LMIC.dataLen) | ||||
|             ESP_LOGI(TAG, "Received %d bytes of payload\n", LMIC.dataLen); | ||||
|             ESP_LOGI(TAG, "ACK received\n"); | ||||
|     } | ||||
|  | ||||
|     int result = ev; | ||||
|  | ||||
| @ -25,6 +25,7 @@ | ||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include "rom/ets_sys.h" | ||||
| #include "lmic.h" | ||||
|  | ||||
| // ----------------------------------------  | ||||
| @ -500,13 +501,14 @@ static void txlora () { | ||||
|     // select LoRa modem (from sleep mode) | ||||
|     //writeReg(RegOpMode, OPMODE_LORA); | ||||
|     opmodeLora(); | ||||
|     // can take a moment to change; so try five times | ||||
|     // can take a moment to change; so try ten times | ||||
|     u1_t reg; | ||||
|     for (int i = 0; i < 5; i++) | ||||
|     for (int i = 0; i < 10; i++) | ||||
|     { | ||||
|         reg = readReg(RegOpMode); | ||||
|         if ((reg & OPMODE_LORA) != 0) | ||||
|             break; | ||||
|         ets_delay_us(100); | ||||
|     } | ||||
|     ASSERT((reg & OPMODE_LORA) != 0); | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user