├── .github └── FUNDING.yml ├── Example ├── main_esp32_arduino.cpp └── main_stm32_freertos.c ├── LICENSE.TXT ├── Port ├── ask_hal_avr_arduino.c ├── ask_hal_esp32_arduino.c ├── ask_hal_stm32_freertos.c └── ask_hal_stm32_none.c ├── README.md ├── ask.c ├── ask.h ├── ask_config.h └── ask_hal.h /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [nimaltd] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: nimaltd 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: #nimaltd 10 | issuehunt: #nimaltd 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /Example/main_esp32_arduino.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ask.h" 3 | #include "ask_hal.h" 4 | 5 | void setup() 6 | { 7 | Serial.begin(115200); 8 | Serial.printf("START\r\n"); 9 | 10 | ask433.fn_init_rx = ask_init_rx433; 11 | ask433.fn_init_tx = ask_init_tx433; 12 | ask433.fn_micros = ask_micros_433; 13 | ask433.fn_read_pin = ask_read_pin_433; 14 | ask433.fn_write_pin = ask_write_pin_433; 15 | ask433.fn_delay_ms = ask_delay_ms_433; 16 | ask433.fn_delay_us = ask_delay_us_433; 17 | ask_init(&ask433); 18 | 19 | ask315.fn_init_rx = ask_init_rx315; 20 | ask315.fn_init_tx = ask_init_tx315; 21 | ask315.fn_micros = ask_micros_315; 22 | ask315.fn_read_pin = ask_read_pin_315; 23 | ask315.fn_write_pin = ask_write_pin_315; 24 | ask315.fn_delay_ms = ask_delay_ms_315; 25 | ask315.fn_delay_us = ask_delay_us_315; 26 | ask_init(&ask315); 27 | } 28 | 29 | void loop() 30 | { 31 | delay(1); 32 | // sender 33 | /* 34 | uint8_t data[5]; 35 | data[0] = 0x3b; 36 | data[1] = 0x53; 37 | data[2] = 0x91; 38 | delay(2000); 39 | ask_send_bytes(&ask433, data, 3, 1380, 5); 40 | delay(2000); 41 | data[2] = 0x92; 42 | ask_send_bytes(&ask433, data, 3, 1380, 5); 43 | */ 44 | 45 | // receiver 46 | if (ask_available(&ask433)) 47 | { 48 | uint8_t data[5]; 49 | Serial.println("\r\n---- 433 MHz Receive ----"); 50 | Serial.printf("Len: %d ---- Bit time: %d ---- ", ask_read_bytes(&ask433, data), ask_read_time_of_bit(&ask433)); 51 | Serial.printf("Data: 0x%02X%02X%02X\r\n", data[0], data[1], data[2]); 52 | ask_wait(&ask433); 53 | } 54 | if (ask_available(&ask315)) 55 | { 56 | uint8_t data[5]; 57 | Serial.println("\r\n---- 315 MHz Receive ----"); 58 | Serial.printf("Len: %d ---- Bit time: %d ---- ", ask_read_bytes(&ask315, data), ask_read_time_of_bit(&ask315)); 59 | Serial.printf("Data: 0x%02X%02X%02X\r\n", data[0], data[1], data[2]); 60 | ask_wait(&ask315); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Example/main_stm32_freertos.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * File Name : freertos.c 5 | * Description : Code for freertos applications 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2021 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under Ultimate Liberty license 13 | * SLA0044, the "License"; You may not use this file except in compliance with 14 | * the License. You may obtain a copy of the License at: 15 | * www.st.com/SLA0044 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Includes ------------------------------------------------------------------*/ 22 | #include "FreeRTOS.h" 23 | #include "task.h" 24 | #include "main.h" 25 | #include "cmsis_os.h" 26 | 27 | /* Private includes ----------------------------------------------------------*/ 28 | /* USER CODE BEGIN Includes */ 29 | #include "ask.h" 30 | #include "ask_hal.h" 31 | /* USER CODE END Includes */ 32 | 33 | /* Private typedef -----------------------------------------------------------*/ 34 | /* USER CODE BEGIN PTD */ 35 | 36 | /* USER CODE END PTD */ 37 | 38 | /* Private define ------------------------------------------------------------*/ 39 | /* USER CODE BEGIN PD */ 40 | 41 | /* USER CODE END PD */ 42 | 43 | /* Private macro -------------------------------------------------------------*/ 44 | /* USER CODE BEGIN PM */ 45 | 46 | /* USER CODE END PM */ 47 | 48 | /* Private variables ---------------------------------------------------------*/ 49 | /* USER CODE BEGIN Variables */ 50 | 51 | /* USER CODE END Variables */ 52 | /* Definitions for myTask_Main */ 53 | osThreadId_t myTask_MainHandle; 54 | const osThreadAttr_t myTask_Main_attributes = { 55 | .name = "myTask_Main", 56 | .stack_size = 1024 * 4, 57 | .priority = (osPriority_t) osPriorityNormal, 58 | }; 59 | 60 | /* Private function prototypes -----------------------------------------------*/ 61 | /* USER CODE BEGIN FunctionPrototypes */ 62 | 63 | /* USER CODE END FunctionPrototypes */ 64 | 65 | void StartTask_Main(void *argument); 66 | 67 | void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ 68 | 69 | /** 70 | * @brief FreeRTOS initialization 71 | * @param None 72 | * @retval None 73 | */ 74 | void MX_FREERTOS_Init(void) { 75 | /* USER CODE BEGIN Init */ 76 | 77 | /* USER CODE END Init */ 78 | 79 | /* USER CODE BEGIN RTOS_MUTEX */ 80 | /* add mutexes, ... */ 81 | /* USER CODE END RTOS_MUTEX */ 82 | 83 | /* USER CODE BEGIN RTOS_SEMAPHORES */ 84 | /* add semaphores, ... */ 85 | /* USER CODE END RTOS_SEMAPHORES */ 86 | 87 | /* USER CODE BEGIN RTOS_TIMERS */ 88 | /* start timers, add new ones, ... */ 89 | /* USER CODE END RTOS_TIMERS */ 90 | 91 | /* USER CODE BEGIN RTOS_QUEUES */ 92 | /* add queues, ... */ 93 | /* USER CODE END RTOS_QUEUES */ 94 | 95 | /* Create the thread(s) */ 96 | /* creation of myTask_Main */ 97 | myTask_MainHandle = osThreadNew(StartTask_Main, NULL, &myTask_Main_attributes); 98 | 99 | 100 | /* USER CODE BEGIN RTOS_THREADS */ 101 | /* add threads, ... */ 102 | /* USER CODE END RTOS_THREADS */ 103 | 104 | /* USER CODE BEGIN RTOS_EVENTS */ 105 | /* add events, ... */ 106 | /* USER CODE END RTOS_EVENTS */ 107 | 108 | } 109 | 110 | 111 | /* USER CODE BEGIN Header_StartTask_Main */ 112 | /** 113 | * @brief Function implementing the myTask_Main thread. 114 | * @param argument: Not used 115 | * @retval None 116 | */ 117 | /* USER CODE END Header_StartTask_Main */ 118 | 119 | void StartTask_Main(void *argument) 120 | { 121 | /* USER CODE BEGIN StartTask_Main */ 122 | /* Infinite loop */ 123 | uint8_t data[5]; 124 | ask433.fn_init_rx = ask_init_rx433; 125 | ask433.fn_init_tx = ask_init_tx433; 126 | ask433.fn_micros = ask_micros_433; 127 | ask433.fn_read_pin = ask_read_pin_433; 128 | ask433.fn_write_pin = ask_write_pin_433; 129 | ask433.fn_delay_ms = ask_delay_ms_433; 130 | ask433.fn_delay_us = ask_delay_us_433; 131 | ask_init(&ask433); 132 | for(;;) 133 | { 134 | osDelay(1); 135 | if (ask_available(&ask433)) 136 | { 137 | ask_read_bytes(&ask433, data); 138 | ask_wait(&ask433); 139 | } 140 | } 141 | /* USER CODE END StartTask_Main */ 142 | } 143 | 144 | /* Private application code --------------------------------------------------*/ 145 | /* USER CODE BEGIN Application */ 146 | 147 | /* USER CODE END Application */ 148 | 149 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 150 | -------------------------------------------------------------------------------- /LICENSE.TXT: -------------------------------------------------------------------------------- 1 | Software License Terms 2 | 3 | This software is dual-licensed: 4 | 5 | 1. GNU General Public License v2 (GPLv2): 6 | - You may redistribute and/or modify this software under the terms of GPLv2 as published by the Free Software Foundation. 7 | - This license does not provide any warranty of any kind, including but not limited to MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 8 | - See for details. 9 | 10 | 2. Commercial License: 11 | - The commercial license removes all GPLv2 restrictions and allows you to redistribute your closed-source products with the Library embedded. 12 | - This license includes access to software maintenance, such as updates and upgrades. Customers who purchase this license are eligible to receive updates whenever 13 | they are released. However, the software provider is not obligated to release updates on a specific schedule. 14 | - The commercial license is available in two models: 15 | - Single-Product License: Allows usage in one specific product. 16 | - Company-Wide License: Allows usage across all products of the company. 17 | - No Warranty: The software is provided "AS IS" without any warranties, express or implied, including but not limited to the implied warranties of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, or NON-INFRINGEMENT. 18 | - Liability Disclaimer: In no event shall the copyright holder or contributors be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software. 19 | 20 | By using this software under the commercial license, you agree to these terms and acknowledge that no additional guarantees or obligations are provided beyond what is explicitly stated in this document. 21 | 22 | --- 23 | 24 | Copyright © Nima Askari, 2025. All rights reserved. 25 | For inquiries, contact: nima.askari@gmail.com All rights reserved 26 | -------------------------------------------------------------------------------- /Port/ask_hal_avr_arduino.c: -------------------------------------------------------------------------------- 1 | 2 | #include "ask_hal.h" 3 | #include 4 | 5 | ask_t ask433; 6 | //################################################################################## 7 | #define RX433_PIN 2 8 | //################################################################################## 9 | inline void ask_write_pin_433(bool data) 10 | { 11 | 12 | } 13 | //################################################################################## 14 | inline bool ask_read_pin_433(void) 15 | { 16 | return digitalRead(RX433_PIN); 17 | } 18 | //################################################################################## 19 | inline uint32_t ask_micros_433(void) 20 | { 21 | return micros(); 22 | } 23 | //################################################################################## 24 | void extirq433(void) 25 | { 26 | ask_pinchange_callback(&ask433); 27 | } 28 | //################################################################################## 29 | void ask_init_rx433(void) 30 | { 31 | pinMode(RX433_PIN, INPUT); 32 | attachInterrupt(digitalPinToInterrupt(RX433_PIN), extirq433, CHANGE); 33 | } 34 | //################################################################################## 35 | void ask_init_tx433(void) 36 | { 37 | 38 | } 39 | //################################################################################## 40 | inline void ask_delay_ms_433(uint32_t delay_ms) 41 | { 42 | delay(delay_ms); 43 | } 44 | //################################################################################## 45 | inline void ask_delay_us_433(uint32_t delay_us) 46 | { 47 | delayMicroseconds(delay_us); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /Port/ask_hal_esp32_arduino.c: -------------------------------------------------------------------------------- 1 | 2 | #include "ask_hal.h" 3 | #include 4 | 5 | ask_t ask433; 6 | //################################################################################## 7 | #define RX433_PIN 27 8 | #define TX433_PIN 25 9 | //################################################################################## 10 | inline void ask_write_pin_433(bool data) 11 | { 12 | digitalWrite(TX433_PIN, data); 13 | } 14 | //################################################################################## 15 | inline bool ask_read_pin_433(void) 16 | { 17 | return digitalRead(RX433_PIN); 18 | } 19 | //################################################################################## 20 | inline uint32_t ask_micros_433(void) 21 | { 22 | return micros(); 23 | } 24 | //################################################################################## 25 | void IRAM_ATTR extirq433(void) 26 | { 27 | ask_pinchange_callback(&ask433); 28 | } 29 | //################################################################################## 30 | void ask_init_rx433(void) 31 | { 32 | pinMode(RX433_PIN, INPUT); 33 | attachInterrupt(RX433_PIN, extirq433, CHANGE); 34 | } 35 | //################################################################################## 36 | void ask_init_tx433(void) 37 | { 38 | pinMode(TX433_PIN, OUTPUT); 39 | } 40 | //################################################################################## 41 | inline void ask_delay_ms_433(uint32_t delay_ms) 42 | { 43 | delay(delay_ms); 44 | } 45 | //################################################################################## 46 | inline void ask_delay_us_433(uint32_t delay_us) 47 | { 48 | delayMicroseconds(delay_us); 49 | } 50 | 51 | 52 | ask_t ask315; 53 | //################################################################################## 54 | #define RX315_PIN 14 55 | #define TX315_PIN 26 56 | //################################################################################## 57 | inline void ask_write_pin_315(bool data) 58 | { 59 | digitalWrite(TX315_PIN, data); 60 | } 61 | //################################################################################## 62 | inline bool ask_read_pin_315(void) 63 | { 64 | return digitalRead(RX315_PIN); 65 | } 66 | //################################################################################## 67 | inline uint32_t ask_micros_315(void) 68 | { 69 | return micros(); 70 | } 71 | //################################################################################## 72 | void IRAM_ATTR extirq315(void) 73 | { 74 | ask_pinchange_callback(&ask315); 75 | } 76 | //################################################################################## 77 | void ask_init_rx315(void) 78 | { 79 | pinMode(RX315_PIN, INPUT); 80 | attachInterrupt(RX315_PIN, extirq315, CHANGE); 81 | } 82 | //################################################################################## 83 | void ask_init_tx315(void) 84 | { 85 | pinMode(TX315_PIN, OUTPUT); 86 | } 87 | //################################################################################## 88 | inline void ask_delay_ms_315(uint32_t delay_ms) 89 | { 90 | delay(delay_ms); 91 | } 92 | //################################################################################## 93 | inline void ask_delay_us_315(uint32_t delay_us) 94 | { 95 | delayMicroseconds(delay_us); 96 | } 97 | -------------------------------------------------------------------------------- /Port/ask_hal_stm32_freertos.c: -------------------------------------------------------------------------------- 1 | 2 | #include "ask_hal.h" 3 | #include "main.h" 4 | #include "cmsis_os.h" 5 | 6 | ask_t ask433; 7 | 8 | //################################################################################## 9 | #define RX433_PIN GPIO_PIN_7 10 | #define RX433_GPIO GPIOC 11 | #define TX433_PIN GPIO_PIN_6 12 | #define TX433_GPIO GPIOC 13 | extern TIM_HandleTypeDef htim2; // config in cubemx, 1 us tick, use 32 bit timer 14 | //################################################################################## 15 | inline void ask_write_pin_433(bool data) 16 | { 17 | HAL_GPIO_WritePin(TX433_GPIO, TX433_PIN, (GPIO_PinState)data); 18 | } 19 | //################################################################################## 20 | inline bool ask_read_pin_433(void) 21 | { 22 | return HAL_GPIO_ReadPin(RX433_GPIO, RX433_PIN); 23 | } 24 | //################################################################################## 25 | inline uint32_t ask_micros_433(void) 26 | { 27 | return htim2.Instance->CNT; 28 | } 29 | //################################################################################## 30 | void ask_init_rx433(void) 31 | { 32 | // config gpio and timer in cubemx 33 | HAL_TIM_Base_Start(&htim2); 34 | } 35 | //################################################################################## 36 | void ask_init_tx433(void) 37 | { 38 | // config in cubemx 39 | } 40 | //################################################################################## 41 | inline void ask_delay_ms_433(uint32_t delay_ms) 42 | { 43 | osDelay(delay_ms); 44 | } 45 | //################################################################################## 46 | inline void ask_delay_us_433(uint32_t delay_us) 47 | { 48 | uint32_t time = htim2.Instance->CNT; 49 | while (htim2.Instance->CNT - time < delay_us); 50 | } 51 | //################################################################################## 52 | void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 53 | { 54 | if (GPIO_Pin == RX433_PIN) 55 | { 56 | ask_pinchange_callback(&ask433); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Port/ask_hal_stm32_none.c: -------------------------------------------------------------------------------- 1 | 2 | #include "ask_hal.h" 3 | #include "main.h" 4 | 5 | ask_t ask433; 6 | 7 | //################################################################################## 8 | #define RX433_PIN GPIO_PIN_7 9 | #define RX433_GPIO GPIOC 10 | #define TX433_PIN GPIO_PIN_6 11 | #define TX433_GPIO GPIOC 12 | extern TIM_HandleTypeDef htim2; // config in cubemx, 1 us tick, use 32 bit timer 13 | //################################################################################## 14 | inline void ask_write_pin_433(bool data) 15 | { 16 | HAL_GPIO_WritePin(TX433_GPIO, TX433_PIN, (GPIO_PinState)data); 17 | } 18 | //################################################################################## 19 | inline bool ask_read_pin_433(void) 20 | { 21 | return HAL_GPIO_ReadPin(RX433_GPIO, RX433_PIN); 22 | } 23 | //################################################################################## 24 | inline uint32_t ask_micros_433(void) 25 | { 26 | return htim2.Instance->CNT; 27 | } 28 | //################################################################################## 29 | void ask_init_rx433(void) 30 | { 31 | // config gpio and timer in cubemx 32 | HAL_TIM_Base_Start(&htim2); 33 | } 34 | //################################################################################## 35 | void ask_init_tx433(void) 36 | { 37 | // config in cubemx 38 | } 39 | //################################################################################## 40 | inline void ask_delay_ms_433(uint32_t delay_ms) 41 | { 42 | HAL_Delay(delay_ms); 43 | } 44 | //################################################################################## 45 | inline void ask_delay_us_433(uint32_t delay_us) 46 | { 47 | uint32_t time = htim2.Instance->CNT; 48 | while (htim2.Instance->CNT - time < delay_us); 49 | } 50 | //################################################################################## 51 | void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 52 | { 53 | if (GPIO_Pin == RX433_PIN) 54 | { 55 | ask_pinchange_callback(&ask433); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Remote Receiver/Sender (EV1527,PT2262,PT2264,...) for All MCUs and platforms 2 | 3 | * WebSite: https://www.github.com/NimaLTD 4 | * Instagram: https://www.instagram.com/github.NimaLTD 5 | * LinkedIn: https://www.linkedin.com/in/NimaLTD 6 | * Youtube: https://www.youtube.com/channel/UCUhY7qY1klJm1d2kulr9ckw 7 | 8 | This is a Library for decoding ASK RF remotes. 9 | 10 | ## How to Use 11 | 12 | Include "ask_hal.h" in your source code and implement these functions: 13 | 14 | * fn_init_rx: init rx pin as input and enable pin change interrupt. 15 | * fn_init_tx: init tx pin as output. 16 | * fn_pinchange_callback: pin change callback. 17 | * fn_micros: return startup system timer in microseconds. 18 | * fn_write_pin: write tx pin to 0 and 1. 19 | * fn_read_pin: read rx pin. 20 | * fn_delay_ms: delay in miliseconds. 21 | * fn_delay_us: delay in microseconds. 22 | 23 | Or use one of `.c` files provided in `Port` folder if it suits your platform. 24 | 25 | ## Ported Platforms 26 | 27 | * [x] STM32 HAL 28 | * [x] ESP32 Arduino 29 | * [ ] ESP8266 Arduino 30 | * [x] AVR Arduino 31 | * [ ] PIC 32 | -------------------------------------------------------------------------------- /ask.c: -------------------------------------------------------------------------------- 1 | 2 | #include "ask_config.h" 3 | #include "ask.h" 4 | #include 5 | 6 | //################################################################################################################ 7 | bool ask_init(ask_t *ask) 8 | { 9 | ask->lock = false; 10 | if (ask->fn_micros == NULL) 11 | return false; 12 | if (ask->fn_delay_ms == NULL) 13 | return false; 14 | ask->detect_busy = false; 15 | if (ask->fn_init_rx != NULL) 16 | ask->fn_init_rx(); 17 | if (ask->fn_read_pin != NULL) 18 | ask->enable_rx = true; 19 | if (ask->fn_init_tx != NULL) 20 | ask->fn_init_tx(); 21 | if (ask->fn_write_pin != NULL) 22 | { 23 | if (ask->fn_delay_us == NULL) 24 | return false; 25 | ask->fn_write_pin(false); 26 | } 27 | return true; 28 | } 29 | //################################################################################################################ 30 | void ask_pinchange_callback(ask_t *ask) 31 | { 32 | if (!ask->enable_rx) 33 | return; 34 | if (!ask->detect_end) 35 | { 36 | if (!ask->detect_begin) 37 | { 38 | if ((ask->fn_micros() - ask->time > _ASK_MIN_NEW_FRAM_DETECT_TIME_) && ask->fn_read_pin()) 39 | { 40 | ask->detect_begin = true; 41 | ask->index = 0; 42 | } 43 | } 44 | else 45 | { 46 | if ((ask->fn_micros() - ask->time > _ASK_MIN_NEW_FRAM_DETECT_TIME_) && ask->fn_read_pin()) 47 | { 48 | ask->detect_end = true; 49 | } 50 | else 51 | { 52 | ask->buffer[ask->index] = ask->fn_micros() - ask->time; 53 | if (ask->index < (_ASK_MAX_BYTE_LEN_ * 16 + 1)) 54 | ask->index++; 55 | } 56 | } 57 | } 58 | ask->time = ask->fn_micros(); 59 | } 60 | //################################################################################################################ 61 | bool ask_available(ask_t *ask) 62 | { 63 | if (ask->lock == true) 64 | return false; 65 | ask->lock = true; 66 | if (ask->index > (_ASK_MAX_BYTE_LEN_ * 16 + 1)) 67 | { 68 | ask->detect_begin = false; 69 | ask->detect_end = false; 70 | ask->lock = false; 71 | return false; 72 | } 73 | if (ask->detect_end && !ask->detect_busy) 74 | { 75 | do 76 | { 77 | if (ask->index < (_ASK_MIN_BYTE_LEN_ * 16 + 1)) 78 | break; 79 | memset(ask->buffer_byte, 0, _ASK_MAX_BYTE_LEN_); 80 | ask->buffer_time = ask->buffer[0] + ask->buffer[1]; 81 | if (ask->buffer[0] > ask->buffer[1]) 82 | { 83 | ask->buffer_time_high[0] = ask->buffer[0] - ((_ASK_TOLERANCE_ * ask->buffer[0]) / 100); 84 | ask->buffer_time_high[1] = ask->buffer[0] + ((_ASK_TOLERANCE_ * ask->buffer[0]) / 100); 85 | ask->buffer_time_low[0] = ask->buffer[1] - ((_ASK_TOLERANCE_ * ask->buffer[1]) / 100); 86 | ask->buffer_time_low[1] = ask->buffer[1] + ((_ASK_TOLERANCE_ * ask->buffer[1]) / 100); 87 | } 88 | else if (ask->buffer[0] < ask->buffer[1]) 89 | { 90 | ask->buffer_time_high[0] = ask->buffer[1] - ((_ASK_TOLERANCE_ * ask->buffer[1]) / 100); 91 | ask->buffer_time_high[1] = ask->buffer[1] + ((_ASK_TOLERANCE_ * ask->buffer[1]) / 100); 92 | ask->buffer_time_low[0] = ask->buffer[0] - ((_ASK_TOLERANCE_ * ask->buffer[0]) / 100); 93 | ask->buffer_time_low[1] = ask->buffer[0] + ((_ASK_TOLERANCE_ * ask->buffer[0]) / 100); 94 | } 95 | else 96 | break; 97 | ask->data_bit = 0; 98 | memset(ask->data_byte, 0, _ASK_MAX_BYTE_LEN_); 99 | for (uint16_t i = 0; i < ask->index - 1 ; i+=2) 100 | { 101 | // detect 0 data 102 | if ((ask->buffer[i] > ask->buffer_time_low[0]) && (ask->buffer[i] < ask->buffer_time_low[1]) 103 | && (ask->buffer[i+1] > ask->buffer_time_high[0]) && (ask->buffer[i+1] < ask->buffer_time_high[1])) 104 | { 105 | ask->data_bit++; 106 | } 107 | // detect 1 data 108 | else if ((ask->buffer[i+1] > ask->buffer_time_low[0]) && (ask->buffer[i+1] < ask->buffer_time_low[1]) 109 | && (ask->buffer[i] > ask->buffer_time_high[0]) && (ask->buffer[i] < ask->buffer_time_high[1])) 110 | { 111 | ask->data_byte[ask->data_bit / 8] |= 0x80 >> (ask->data_bit % 8); 112 | ask->data_bit++; 113 | } 114 | else 115 | break; 116 | } 117 | if (ask->data_bit % 8 != 0) 118 | break; 119 | if ((ask->data_bit > (_ASK_MAX_BYTE_LEN_ * 8)) || (ask->data_bit < (_ASK_MIN_BYTE_LEN_ * 8))) 120 | break; 121 | ask->detect_busy = true; 122 | ask->lock = false; 123 | return true; 124 | 125 | } while (0); 126 | 127 | ask->detect_begin = false; 128 | ask->detect_end = false; 129 | ask->lock = false; 130 | return false; 131 | } 132 | else if (ask->detect_busy) 133 | { 134 | ask->lock = false; 135 | return true; 136 | } 137 | ask->lock = false; 138 | return false; 139 | } 140 | //################################################################################################################ 141 | void ask_wait(ask_t *ask) 142 | { 143 | while (ask_available(ask)) 144 | { 145 | ask_reset_available(ask); 146 | ask->fn_delay_ms(200); 147 | } 148 | } 149 | //################################################################################################################ 150 | void ask_reset_available(ask_t *ask) 151 | { 152 | while (ask->lock == true) 153 | ask->fn_delay_ms(1); 154 | ask->lock = true; 155 | memset(ask->buffer, 0, sizeof(ask->buffer)); 156 | ask->detect_begin = false; 157 | ask->detect_end = false; 158 | ask->detect_busy = false; 159 | ask->lock = false; 160 | } 161 | //################################################################################################################ 162 | uint8_t ask_read_bytes(ask_t *ask, uint8_t *data) 163 | { 164 | while (ask->lock == true) 165 | ask->fn_delay_ms(1); 166 | ask->lock = true; 167 | memcpy(data, ask->data_byte, ask->data_bit / 8); 168 | ask->lock = false; 169 | return ask->data_bit / 8; 170 | } 171 | //################################################################################################################ 172 | uint16_t ask_read_time_of_bit(ask_t *ask) 173 | { 174 | return ask->buffer_time; 175 | } 176 | //################################################################################################################ 177 | void ask_send_bytes(ask_t *ask, uint8_t *data, uint8_t len, uint32_t bit_time_micros, uint8_t try_to_send) 178 | { 179 | if (ask->fn_write_pin == NULL) 180 | return; 181 | while (ask->lock == true) 182 | ask->fn_delay_ms(1); 183 | ask->lock = true; 184 | if (ask->fn_read_pin != NULL) 185 | ask->enable_rx = false; 186 | ask->fn_write_pin(true); 187 | ask->fn_delay_ms(bit_time_micros * 8 / 1000); 188 | for (uint8_t t = 0; t < try_to_send; t++) 189 | { 190 | ask->fn_write_pin(false); 191 | ask->fn_delay_ms(bit_time_micros * 8 / 1000); 192 | for (uint8_t byte = 0; byte < len; byte++) 193 | { 194 | for (int8_t bit = 7; bit > -1; bit--) 195 | { 196 | if (data[byte] & (1<fn_write_pin(true); 199 | ask->fn_delay_us(bit_time_micros * 75 / 100); 200 | ask->fn_write_pin(false); 201 | ask->fn_delay_us(bit_time_micros * 25 / 100); 202 | } 203 | else 204 | { 205 | ask->fn_write_pin(true); 206 | ask->fn_delay_us(bit_time_micros * 25 / 100); 207 | ask->fn_write_pin(false); 208 | ask->fn_delay_us(bit_time_micros * 75 / 100); 209 | } 210 | } 211 | } 212 | ask->fn_write_pin(true); 213 | ask->fn_delay_us(bit_time_micros * 25 / 100); 214 | ask->fn_write_pin(false); 215 | } 216 | if (ask->fn_read_pin != NULL) 217 | ask->enable_rx = true; 218 | ask->lock = false; 219 | } 220 | //################################################################################################################ 221 | int16_t ask_checkChannelLast4Bit(uint8_t *newCode, uint8_t *refrence, uint8_t len) 222 | { 223 | if (len < 1) 224 | return -1; 225 | uint8_t maskNew[len]; 226 | uint8_t maskRef[len]; 227 | memcpy(maskNew, newCode, len); 228 | memcpy(maskRef, refrence, len); 229 | maskNew[len - 1] &= 0xF0; 230 | maskRef[len - 1] &= 0xF0; 231 | if (memcmp(maskNew, maskRef, len) != 0) 232 | return -1; 233 | return newCode[len - 1] & 0x0F; 234 | } 235 | //################################################################################################################ 236 | int16_t ask_checkChannelLast8Bit(uint8_t *newCode, uint8_t *refrence, uint8_t len) 237 | { 238 | if (len < 1) 239 | return -1; 240 | if (memcmp(newCode, refrence, len - 1) != 0) 241 | return -1; 242 | return newCode[len - 1]; 243 | } 244 | //################################################################################################################ 245 | -------------------------------------------------------------------------------- /ask.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASK_H_ 2 | #define _ASK_H_ 3 | 4 | 5 | /* 6 | * Author: Nima Askari 7 | * WebSite: https://www.github.com/NimaLTD 8 | * Instagram: https://www.instagram.com/github.NimaLTD 9 | * LinkedIn: https://www.linkedin.com/in/NimaLTD 10 | * Youtube: https://www.youtube.com/channel/UCUhY7qY1klJm1d2kulr9ckw 11 | */ 12 | 13 | /* 14 | * Version: 3.0.2 15 | * 16 | * History: 17 | * 18 | * (3.0.2): Fixed some bugs. 19 | * 20 | * (3.0.1): Fixed some bugs. Changed some functions. Add ask_wait(). 21 | * 22 | * (3.0.0): Easy to port all mcu and platform. (STM32, ESP8266, ESP32, AVR, ARDUINO , ...) 23 | * Can use 2 frequency at the same time. 24 | * 25 | * 26 | * */ 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #include 33 | #include 34 | #include "ask_config.h" 35 | 36 | typedef struct 37 | { 38 | uint16_t buffer[_ASK_MAX_BYTE_LEN_ * 16 + 2]; 39 | uint8_t buffer_byte[_ASK_MAX_BYTE_LEN_]; 40 | uint16_t buffer_time; 41 | uint16_t buffer_time_low[2]; 42 | uint16_t buffer_time_high[2]; 43 | uint8_t data_byte[_ASK_MAX_BYTE_LEN_]; 44 | uint8_t data_bit; 45 | uint32_t time; 46 | uint16_t index; 47 | bool detect_begin; 48 | bool detect_end; 49 | bool detect_busy; 50 | bool enable_rx; 51 | bool lock; 52 | 53 | void (*fn_init_rx)(void); 54 | void (*fn_init_tx)(void); 55 | uint32_t (*fn_micros)(void); 56 | void (*fn_write_pin)(bool); 57 | bool (*fn_read_pin)(void); 58 | void (*fn_delay_ms)(uint32_t); 59 | void (*fn_delay_us)(uint32_t); 60 | 61 | }ask_t; 62 | 63 | bool ask_init(ask_t *ask); // init ask structure 64 | void ask_pinchange_callback(ask_t *ask); // external pin change callback 65 | bool ask_available(ask_t *ask); // return true if data is available 66 | void ask_wait(ask_t *ask); // Wait for the key release and reset available 67 | void ask_reset_available(ask_t *ask); // reset data and ready for next data 68 | uint8_t ask_read_bytes(ask_t *ask, uint8_t *data); // read data 69 | uint16_t ask_read_time_of_bit(ask_t *ask); // return readed data bit time in microseconds 70 | void ask_send_bytes(ask_t *ask, uint8_t *data, uint8_t len, uint32_t bit_time_micros, uint8_t try_to_send); // send data 71 | int16_t ask_checkChannelLast4Bit(uint8_t *newCode, uint8_t *refrence, uint8_t len); // compare and return channel, return -1 if failed 72 | int16_t ask_checkChannelLast8Bit(uint8_t *newCode, uint8_t *refrence, uint8_t len); // compare and return channel, return -1 if failed 73 | 74 | #ifdef __cplusplus 75 | } 76 | #endif 77 | #endif 78 | -------------------------------------------------------------------------------- /ask_config.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASK_CONFIG_H_ 2 | #define _ASK_CONFIG_H_ 3 | 4 | #define _ASK_MIN_BYTE_LEN_ 3 // byte 5 | #define _ASK_MAX_BYTE_LEN_ 3 // byte 6 | #define _ASK_MIN_NEW_FRAM_DETECT_TIME_ 5000 // us 7 | #define _ASK_TOLERANCE_ 40 // % 8 | 9 | #if (_ASK_MAX_BYTE_LEN_ < _ASK_MIN_BYTE_LEN_) 10 | #error SELECT CORRECT ASK MIN/MAX BYTE LENGHT 11 | #endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /ask_hal.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASK_HAL_H_ 2 | #define _ASK_HAL_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | #include 8 | #include "ask.h" 9 | 10 | extern ask_t ask433; 11 | extern ask_t ask315; 12 | 13 | void ask_write_pin_433(bool data); 14 | bool ask_read_pin_433(void); 15 | uint32_t ask_micros_433(void); 16 | void ask_init_rx433(void); 17 | void ask_init_tx433(void); 18 | void ask_delay_ms_433(uint32_t delay_ms); 19 | void ask_delay_us_433(uint32_t delay_us); 20 | 21 | void ask_write_pin_315(bool data); 22 | bool ask_read_pin_315(void); 23 | uint32_t ask_micros_315(void); 24 | void ask_init_rx315(void); 25 | void ask_init_tx315(void); 26 | void ask_delay_ms_315(uint32_t delay_ms); 27 | void ask_delay_us_315(uint32_t delay_us); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | #endif 33 | --------------------------------------------------------------------------------