* Sends an IR mark for the specified number of microseconds. * The mark output is modulated at the PWM frequency if USE_NO_SEND_PWM is not defined. * The output is guaranteed to be OFF / inactive after after the call of the function. * This function may affect the state of feedback LED. * Period time is 26 us for 38.46 kHz, 27 us for 37.04 kHz, 25 us for 40 kHz. * On time is 8 us for 30% duty
| 1245 | * This disturbance is no problem, if the exceedance is small and does not happen too often. |
| 1246 | */ |
| 1247 | void IRsend::mark(uint16_t aMarkMicros) { |
| 1248 | |
| 1249 | #if defined(SEND_PWM_BY_TIMER) || defined(USE_NO_SEND_PWM) |
| 1250 | # if defined(LED_SEND_FEEDBACK_CODE) |
| 1251 | setFeedbackLED(true); |
| 1252 | # endif |
| 1253 | #endif |
| 1254 | |
| 1255 | #if defined(SEND_PWM_BY_TIMER) |
| 1256 | /* |
| 1257 | * Generate hardware PWM signal |
| 1258 | */ |
| 1259 | enableSendPWMByTimer(); // Enable timer or ledcWrite() generated PWM output |
| 1260 | customDelayMicroseconds(aMarkMicros); |
| 1261 | IRLedOff(); // disables hardware PWM and manages feedback LED |
| 1262 | return; |
| 1263 | |
| 1264 | #elif defined(USE_NO_SEND_PWM) |
| 1265 | /* |
| 1266 | * Here we generate no carrier PWM, just simulate an active low receiver signal. |
| 1267 | */ |
| 1268 | # if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && !defined(OUTPUT_OPEN_DRAIN) |
| 1269 | // Here we have no hardware supported Open Drain outputs, so we must mimicking it |
| 1270 | pinModeFast(sendPin, OUTPUT); // active state for mimicking open drain |
| 1271 | # elif defined(USE_ACTIVE_HIGH_OUTPUT_FOR_NO_SEND_PWM) || defined(USE_ACTIVE_HIGH_OUTPUT_FOR_SEND_PIN) // USE_ACTIVE_HIGH_OUTPUT_FOR_SEND_PIN is old and deprecated |
| 1272 | digitalWriteFast(sendPin, HIGH); // Set output to active high. |
| 1273 | # else |
| 1274 | digitalWriteFast(sendPin, LOW); // Set output to active low. |
| 1275 | # endif |
| 1276 | |
| 1277 | customDelayMicroseconds(aMarkMicros); |
| 1278 | IRLedOff(); |
| 1279 | # if defined(LED_SEND_FEEDBACK_CODE) |
| 1280 | setFeedbackLED(false); |
| 1281 | return; |
| 1282 | # endif |
| 1283 | |
| 1284 | #else // defined(SEND_PWM_BY_TIMER) |
| 1285 | |
| 1286 | unsigned long tMicros = micros(); |
| 1287 | unsigned long tMicrosOfEndOfNextPWMPause = tMicros; |
| 1288 | # if defined(LED_SEND_FEEDBACK_CODE) |
| 1289 | unsigned long tEndMicros = tMicros + (136 / CLOCKS_PER_MICRO) + aMarkMicros; // To compensate for call duration and activating of LED |
| 1290 | bool tFeedbackLedIsActive = false; |
| 1291 | #else |
| 1292 | unsigned long tEndMicros = tMicros + (112 / CLOCKS_PER_MICRO) + aMarkMicros; // To compensate for call duration - 112 is an empirical value |
| 1293 | #endif |
| 1294 | |
| 1295 | /*************************************************************************************************** |
| 1296 | * Generate the IR PWM with 30% duty cycle with a frequency of e.g. 38 kHz by software / bit banging |
| 1297 | **************************************************************************************************/ |
| 1298 | do { |
| 1299 | // digitalToggleFast(_IR_TIMING_TEST_PIN); |
| 1300 | /***************************************** |
| 1301 | * Output the PWM pulse - IR LED is active |
| 1302 | ****************************************/ |
| 1303 | noInterrupts(); // do not let interrupts extend the short on period |
| 1304 | # if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) || defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN) |
no test coverage detected