Flipper Zero
This commit is contained in:
parent
36403d810b
commit
ea28282d1c
25
README.md
25
README.md
|
@ -404,6 +404,16 @@ If `IR_SEND_PIN` is specified (as constant), it reduces program size and improve
|
|||
### List of public IR code databases
|
||||
http://www.harctoolbox.org/IR-resources.html
|
||||
|
||||
### Flipper Zero
|
||||
[Flipper IRDB Database](https://github.com/Lucaslhm/Flipper-IRDB)
|
||||
|
||||
| [Flipper decoding](https://github.com/flipperdevices/flipperzero-firmware/tree/release/lib/infrared/encoder_decoder) | [IRremote decoding](https://github.com/Arduino-IRremote/Arduino-IRremote/tree/master/src) |
|
||||
|-|-|
|
||||
| Samsung32 | Samsung |
|
||||
| NEC | NEC |
|
||||
| NECext | ONKYO |
|
||||
| [\<start bit>\<VendorID:16>\<VendorID parity:4>\<Genre1:4>\<Genre2:4>\<Command:10>\<ID:2>\<Parity:8>\<stop bit>](https://github.com/flipperdevices/flipperzero-firmware/blob/027ea9ea36da137144548295c016d99255af53c3/lib/infrared/encoder_decoder/kaseikyo/infrared_decoder_kaseikyo.c#L26)<br/>and ID is MSB of address.<br/>address: 8A 02 20 00<br/>command: 56 03 00 00<br/>-> **IRremote:**<br/>Address 0x6A8, sendPanasonic (for 02 20) and Command 0x35 | \<start bit>\<VendorID:16>\<VendorID parity:4>\<Address:12>\<Command:8>\<Parity of VendorID parity, Address and Command:8>\<stop bit> |
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
|
@ -763,15 +773,18 @@ If you can provide **examples of using a periodic timer for interrupts** for the
|
|||
<br/>
|
||||
|
||||
# Timer and pin usage
|
||||
The **receiver sample interval of 50 µs is generated by a timer**. On many boards this must be a hardware timer. On some boards where a software timer is available, the software timer is used.<br/>
|
||||
Every pin can be used for receiving.
|
||||
The **receiver sample interval of 50 µs is generated by a timer**. On many boards this must be a hardware timer. On some boards where a software timer is available, the software timer is used.
|
||||
|
||||
Every pin can be used for receiving.<br/>
|
||||
If software PWM is selected, which is default, every pin can also be used for sending. Sending with software PWM does not require a timer!
|
||||
|
||||
The TinyReceiver example uses the **TinyReceiver** library, which can **only receive NEC codes, but does not require any timer** and runs even on a 1 MHz ATtiny85.
|
||||
|
||||
The code for the timer and the **timer selection** is located in [private/IRTimer.hpp](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/private/IRTimer.hpp). It can be adjusted here.<br/>
|
||||
The code for the timer and the **timer selection** is located in [private/IRTimer.hpp](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/private/IRTimer.hpp). The selected timer can be adjusted here.
|
||||
|
||||
**Be aware that the hardware timer used for receiving should not be used for analogWrite()!**.<br/>
|
||||
|
||||
| Board/CPU | Receive<br/>& PWM Timers| Hardware-PWM Pin | analogWrite()<br/>pins occupied by timer |
|
||||
| Board/CPU | Receive<br/>& send PWM Timer<br/>Default timer is **bold** | Hardware-Send-PWM Pin | analogWrite()<br/>pins occupied by timer |
|
||||
|-|-|-|-|
|
||||
| [ATtiny84](https://github.com/SpenceKonde/ATTinyCore/blob/v2.0.0-devThis-is-the-head-submit-PRs-against-this/avr/extras/ATtiny_x4.md) | **1** | **6** | |
|
||||
| [ATtiny85 > 4 MHz](https://github.com/SpenceKonde/ATTinyCore/blob/v2.0.0-devThis-is-the-head-submit-PRs-against-this/avr/extras/ATtiny_x5.md) | **0**, 1 | **0**, 4 | **0**, 1 & 4 |
|
||||
|
@ -787,9 +800,9 @@ The code for the timer and the **timer selection** is located in [private/IRTime
|
|||
| [ATmega64, ATmega128, ATmega1281, ATmega2561](https://github.com/MCUdude/MegaCore#supported-microcontrollers) | **1** | **13** |
|
||||
| [ATmega8515, ATmega162](https://github.com/MCUdude/MajorCore#pinout ) | **1** | **13** |
|
||||
| ATmega168, **ATmega328** | 1, **2** | 9, **3** | 9 & 10, **3 & 11** |
|
||||
| ATmega1280, ATmega2560 | 1, **2**, 3, 4, 5 | 5, 6, **9**, 11, 46 | |
|
||||
| ATmega1280, **ATmega2560** | 1, **2**, 3, 4, 5 | 5, 6, **9**, 11, 46 | 5, 6, **9**, 11, 46 |
|
||||
| ATmega4809 | **TCB0** | **A4** | |
|
||||
| Leonardo (Atmega32u4) | 1, 3, **4_HS** | 5, **9**, 13 | |
|
||||
| Leonardo (Atmega32u4) | 1, 3, **4_HS** | 5, **9**, 13 | 5, **9**, 13 |
|
||||
| Zero (SAMD) | **TC3** | \*, **9** | |
|
||||
| [ESP32](http://esp32.net/) | **Ledc chan. 0** | All pins | |
|
||||
| [Sparkfun Pro Micro](https://www.sparkfun.com/products/12640) | 1, **3** | **5**, 9 | |
|
||||
|
|
|
@ -145,8 +145,13 @@
|
|||
#define VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP 6 // Shutdown after 6 times (60 seconds) VCC below VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT or 1 time below VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT
|
||||
#endif
|
||||
|
||||
#if !defined(VOLTAGE_USB_LOWER_THRESHOLD_MILLIVOLT)
|
||||
#define VOLTAGE_USB_LOWER_THRESHOLD_MILLIVOLT 4300
|
||||
#if !defined(VOLTAGE_USB_POWERED_LOWER_THRESHOLD_MILLIVOLT)
|
||||
#define VOLTAGE_USB_POWERED_LOWER_THRESHOLD_MILLIVOLT 4300 // Assume USB powered above this voltage
|
||||
#endif
|
||||
|
||||
#if !defined(VOLTAGE_USB_POWERED_UPPER_THRESHOLD_MILLIVOLT)
|
||||
#define VOLTAGE_USB_POWERED_UPPER_THRESHOLD_MILLIVOLT 4950 // Assume USB powered below this voltage, because of the loss in USB cable. If we have > 4950, we assume to be powered by VIN.
|
||||
// In contrast to e.g. powered by VIN, which results in almost perfect 5 volt supply
|
||||
#endif
|
||||
|
||||
extern long sLastVCCCheckMillis;
|
||||
|
|
|
@ -540,11 +540,12 @@ uint16_t getVoltageMillivoltWith_1_1VoltReference(uint8_t aADCChannelForVoltageM
|
|||
}
|
||||
|
||||
/*
|
||||
* Return true if sVCCVoltageMillivolt is > 4.3 V
|
||||
* Return true if sVCCVoltageMillivolt is > 4.3 V and < 4.95 V
|
||||
*/
|
||||
bool isVCCUSBPowered() {
|
||||
readVCCVoltageMillivolt();
|
||||
return (sVCCVoltageMillivolt > VOLTAGE_USB_LOWER_THRESHOLD_MILLIVOLT);
|
||||
return (VOLTAGE_USB_POWERED_LOWER_THRESHOLD_MILLIVOLT < sVCCVoltageMillivolt
|
||||
&& sVCCVoltageMillivolt < VOLTAGE_USB_POWERED_UPPER_THRESHOLD_MILLIVOLT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -602,7 +603,6 @@ bool isVCCUndervoltageMultipleTimes() {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return true if VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT (3 V) reached
|
||||
*/
|
||||
|
|
|
@ -105,7 +105,8 @@ uint32_t sMillisOfLastReceivedIRFrame = 0;
|
|||
#if defined(USE_SERIAL_LCD) || defined(USE_PARALLEL_LCD)
|
||||
#define USE_LCD
|
||||
# if defined(__AVR__) && defined(ADCSRA) && defined(ADATE)
|
||||
// For cyclically display of VCC
|
||||
// For cyclically display of VCC and isVCCUSBPowered()
|
||||
#define VOLTAGE_USB_POWERED_LOWER_THRESHOLD_MILLIVOLT 4250
|
||||
#include "ADCUtils.hpp"
|
||||
#define MILLIS_BETWEEN_VOLTAGE_PRINT 5000
|
||||
#define LCD_VOLTAGE_START_INDEX 11
|
||||
|
@ -114,13 +115,12 @@ bool ProtocolStringOverwritesVoltage = false;
|
|||
# endif
|
||||
#define LCD_IR_COMMAND_START_INDEX 9
|
||||
|
||||
#endif // defined(USE_SERIAL_LCD) || defined(USE_PARALLEL_LCD)
|
||||
|
||||
void printsVCCVoltageMillivoltOnLCD();
|
||||
void printIRResultOnLCD();
|
||||
size_t printByteHexOnLCD(uint16_t aHexByteValue);
|
||||
void printSpacesOnLCD(uint_fast8_t aNumberOfSpacesToPrint);
|
||||
|
||||
uint16_t sVCCMillivolt;
|
||||
#endif // defined(USE_SERIAL_LCD) || defined(USE_PARALLEL_LCD)
|
||||
|
||||
void setup() {
|
||||
#if FLASHEND >= 0x3FFF // For 16k flash or more, like ATtiny1604. Code does not fit in program memory of ATtiny85 etc.
|
||||
|
@ -180,8 +180,8 @@ void setup() {
|
|||
Serial.println(F(" us are subtracted from all marks and added to all spaces for decoding"));
|
||||
#endif
|
||||
|
||||
#if defined(USE_LCD) && defined(__AVR__) && defined(ADCSRA) && defined(ADATE)
|
||||
getVCCVoltageMillivoltSimple(); // to initialize ADC mux and reference
|
||||
#if defined(USE_LCD) && defined(ADC_UTILS_ARE_AVAILABLE)
|
||||
readVCCVoltageMillivolt();
|
||||
#endif
|
||||
|
||||
#if defined(USE_SERIAL_LCD)
|
||||
|
@ -201,7 +201,7 @@ void setup() {
|
|||
#endif
|
||||
|
||||
#if defined(USE_LCD) && defined(ADC_UTILS_ARE_AVAILABLE)
|
||||
sVCCMillivolt = getVCCVoltageMillivoltSimple();
|
||||
readVCCVoltageMillivolt();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -236,10 +236,10 @@ void loop() {
|
|||
|
||||
if ((IrReceiver.decodedIRData.protocol == UNKNOWN || digitalRead(DEBUG_BUTTON_PIN) == LOW)
|
||||
#if defined(USE_LCD) && defined(ADC_UTILS_ARE_AVAILABLE)
|
||||
&& sVCCMillivolt > 4222
|
||||
|| isVCCUSBPowered()
|
||||
#endif
|
||||
) {
|
||||
// Print more info, but only if we are connected to USB, i.e. VCC is > 4222 mV, because this may take to long to detect some fast repeats
|
||||
) {
|
||||
// Print more info, but only if we are connected to USB, i.e. VCC is > 4300 mV, because this may take to long to detect some fast repeats
|
||||
IrReceiver.printIRSendUsage(&Serial);
|
||||
IrReceiver.printIRResultRawFormatted(&Serial, false); // print ticks, this is faster :-)
|
||||
}
|
||||
|
@ -266,10 +266,17 @@ void loop() {
|
|||
} // if (IrReceiver.decode())
|
||||
|
||||
/*
|
||||
* Check for attention every 10 minute, after the current measurement was finished
|
||||
* Check if generating attention beep every minute, after the current measurement was finished
|
||||
*/
|
||||
if (millis() - sMillisOfLastReceivedIRFrame >= MILLIS_BETWEEN_ATTENTION_BEEP) {
|
||||
if ((millis() - sMillisOfLastReceivedIRFrame) >= MILLIS_BETWEEN_ATTENTION_BEEP
|
||||
#if defined(USE_LCD) && defined(ADC_UTILS_ARE_AVAILABLE)
|
||||
&& !isVCCUSBPowered()
|
||||
#endif
|
||||
) {
|
||||
sMillisOfLastReceivedIRFrame = millis();
|
||||
#if defined(USE_LCD) && defined(ADC_UTILS_ARE_AVAILABLE)
|
||||
printsVCCVoltageMillivoltOnLCD();
|
||||
#endif
|
||||
IrReceiver.stop();
|
||||
tone(TONE_PIN, 2200);
|
||||
delay(50);
|
||||
|
@ -284,18 +291,25 @@ void loop() {
|
|||
* Periodically print VCC
|
||||
*/
|
||||
sMillisOfLastVoltagePrint = millis();
|
||||
sVCCMillivolt = getVCCVoltageMillivoltSimple();
|
||||
char tVoltageString[5];
|
||||
dtostrf(sVCCMillivolt / 1000.0, 4, 2, tVoltageString);
|
||||
myLCD.setCursor(LCD_VOLTAGE_START_INDEX - 1, 0);
|
||||
myLCD.print(' ');
|
||||
myLCD.print(tVoltageString);
|
||||
myLCD.print('V');
|
||||
readVCCVoltageMillivolt();
|
||||
printsVCCVoltageMillivoltOnLCD();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if defined(USE_LCD)
|
||||
void printsVCCVoltageMillivoltOnLCD() {
|
||||
# if defined(ADC_UTILS_ARE_AVAILABLE)
|
||||
char tVoltageString[5];
|
||||
dtostrf(sVCCVoltageMillivolt / 1000.0, 4, 2, tVoltageString);
|
||||
myLCD.setCursor(LCD_VOLTAGE_START_INDEX - 1, 0);
|
||||
myLCD.print(' ');
|
||||
myLCD.print(tVoltageString);
|
||||
myLCD.print('V');
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
* LCD output for 1602 LCDs
|
||||
* 40 - 55 Milliseconds per initial output
|
||||
|
@ -305,7 +319,6 @@ void loop() {
|
|||
*
|
||||
*/
|
||||
void printIRResultOnLCD() {
|
||||
#if defined(USE_LCD)
|
||||
static uint16_t sLastProtocolIndex = 4711;
|
||||
static uint16_t sLastProtocolAddress = 4711;
|
||||
static uint16_t sLastCommand = 0;
|
||||
|
@ -421,10 +434,8 @@ void printIRResultOnLCD() {
|
|||
myLCD.print(' ');
|
||||
}
|
||||
} // IrReceiver.decodedIRData.protocol == UNKNOWN
|
||||
#endif // defined(USE_LCD)
|
||||
}
|
||||
|
||||
#if defined(USE_LCD)
|
||||
size_t printByteHexOnLCD(uint16_t aHexByteValue) {
|
||||
myLCD.print(F("0x"));
|
||||
size_t tPrintSize = 2;
|
||||
|
@ -440,4 +451,4 @@ void printSpacesOnLCD(uint_fast8_t aNumberOfSpacesToPrint) {
|
|||
myLCD.print(' ');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // defined(USE_LCD)
|
||||
|
|
|
@ -87,9 +87,10 @@
|
|||
// 01000000 00100100 0110Dev_ Sub_Dev_ Fun____ XOR( B2, B3, B4) - Byte 0,1 and vendor parity showing Panasonic vendor code 0x2002.
|
||||
// 1. interpretation: <start bit><VendorID:16><VendorID parity:4><Device:4><Subdevice:8><Function:8><Parity:8><stop bit>
|
||||
// see: http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?26152
|
||||
// 2. interpretation: <start bit><VendorID:16><VendorID parity:4><Genre1:4><Genre2:4><Command:10><ID:2><Parity:8><stop bit>
|
||||
// 2. interpretation (Flipper Zero style): <start bit><VendorID:16><VendorID parity:4><Genre1:4><Genre2:4><Command:10><ID:2><Parity:8><stop bit>
|
||||
// see: https://www.mikrocontroller.net/articles/IRMP_-_english#KASEIKYO
|
||||
// Implemented is: <start bit><VendorID:16><VendorID parity:4><Address:12><Command:8><Parity of VendorID parity, Address and Command:8><stop bit>
|
||||
// Implemented is Samsung style: <start bit><VendorID:16><VendorID parity:4><Address:12><Command:8><Parity of VendorID parity, Address and Command:8><stop bit>
|
||||
// which is derived from Samsung remotes and may not be optimal for Denon kind of Kaseikyo protokol usage.
|
||||
//
|
||||
#define KASEIKYO_VENDOR_ID_BITS 16
|
||||
#define KASEIKYO_VENDOR_ID_PARITY_BITS 4
|
||||
|
@ -126,7 +127,7 @@ KASEIKYO_HEADER_SPACE, KASEIKYO_BIT_MARK, KASEIKYO_ONE_SPACE, KASEIKYO_BIT_MARK,
|
|||
************************************/
|
||||
|
||||
/**
|
||||
* Address can be interpreted as sub-device << 8 + device
|
||||
* Address can be interpreted as sub-device << 4 + 4 bit device
|
||||
*/
|
||||
void IRsend::sendKaseikyo(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, uint16_t aVendorCode) {
|
||||
// Set IR carrier frequency
|
||||
|
|
|
@ -72,6 +72,10 @@
|
|||
// https://www.mikrocontroller.net/articles/IRMP_-_english#SAMSUNG48
|
||||
// LSB first, 1 start bit + 16 bit address + 16 or 32 bit data + 1 stop bit.
|
||||
// Here https://forum.arduino.cc/t/klimaanlage-per-ir-steuern/1051381/10 the address (0xB24D) is also 8 bits and then 8 inverted bits
|
||||
//
|
||||
// Here https://github.com/flipperdevices/flipperzero-firmware/blob/master/lib/infrared/encoder_decoder/samsung/infrared_decoder_samsung.c#L18
|
||||
// Address is 8 bit + same 8 bit if data is 8 bit and ~8 bit.
|
||||
//
|
||||
// IRP notation: {38k,5553}<1,-1|1,-3>(8,-8,D:8,S:8,F:8,~F:8,1,^110)+ ==> 8 bit + 8 bit inverted data - Samsung32
|
||||
// IRP notation: {38k,5553}<1,-1|1,-3>(8,-8,D:8,S:8,F:16,1,^110)+ ==> 16 bit data - still Samsung32
|
||||
// IRP notation: {38k,5553}<1,-1|1,-3>(8,-8,D:8,S:8,F:8,~F:8,G:8,~G:8,1,^110)+ ==> 2 x (8 bit + 8 bit inverted data) - Samsung48
|
||||
|
@ -84,7 +88,7 @@
|
|||
|
||||
// except SAMSUNG_HEADER_MARK, values are like NEC
|
||||
#define SAMSUNG_UNIT 560 // 21.28 periods of 38 kHz, 11.2 ticks TICKS_LOW = 8.358 TICKS_HIGH = 15.0
|
||||
#define SAMSUNG_HEADER_MARK (8 * SAMSUNG_UNIT) // 4500 | 180
|
||||
#define SAMSUNG_HEADER_MARK (8 * SAMSUNG_UNIT) // 4500 | 180 periods
|
||||
#define SAMSUNG_HEADER_SPACE (8 * SAMSUNG_UNIT) // 4500
|
||||
#define SAMSUNG_BIT_MARK SAMSUNG_UNIT
|
||||
#define SAMSUNG_ONE_SPACE (3 * SAMSUNG_UNIT) // 1690 | 33.8 TICKS_LOW = 25.07 TICKS_HIGH = 45.0
|
||||
|
@ -93,8 +97,7 @@
|
|||
#define SAMSUNG_AVERAGE_DURATION 55000 // SAMSUNG_HEADER_MARK + SAMSUNG_HEADER_SPACE + 32 * 2,5 * SAMSUNG_UNIT + SAMSUNG_UNIT // 2.5 because we assume more zeros than ones
|
||||
#define SAMSUNG_REPEAT_DURATION (SAMSUNG_HEADER_MARK + SAMSUNG_HEADER_SPACE + SAMSUNG_BIT_MARK + SAMSUNG_ZERO_SPACE + SAMSUNG_BIT_MARK)
|
||||
#define SAMSUNG_REPEAT_PERIOD 110000 // Commands are repeated every 110 ms (measured from start to start) for as long as the key on the remote control is held down.
|
||||
#define SAMSUNG_REPEAT_DISTANCE (SAMSUNG_REPEAT_PERIOD - SAMSUNG_AVERAGE_DURATION)
|
||||
#define SAMSUNG_MAXIMUM_REPEAT_DISTANCE (SAMSUNG_REPEAT_DISTANCE + (SAMSUNG_REPEAT_DISTANCE / 4)) // Just a guess
|
||||
#define SAMSUNG_MAXIMUM_REPEAT_DISTANCE (SAMSUNG_REPEAT_PERIOD + (SAMSUNG_REPEAT_PERIOD / 4)) // 137000 - Just a guess
|
||||
|
||||
struct PulseDistanceWidthProtocolConstants SamsungProtocolConstants = { SAMSUNG, SAMSUNG_KHZ, SAMSUNG_HEADER_MARK,
|
||||
SAMSUNG_HEADER_SPACE, SAMSUNG_BIT_MARK, SAMSUNG_ONE_SPACE, SAMSUNG_BIT_MARK, SAMSUNG_ZERO_SPACE, PROTOCOL_IS_LSB_FIRST,
|
||||
|
@ -165,6 +168,12 @@ void IRsend::sendSamsung(uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumb
|
|||
// Send 8 command bits and then 8 inverted command bits LSB first
|
||||
tSendValue.UBytes[2] = aCommand;
|
||||
tSendValue.UBytes[3] = ~aCommand;
|
||||
if (aAddress < 0x100) {
|
||||
// This makes it flipper IRDB compatible
|
||||
// https://github.com/flipperdevices/flipperzero-firmware/blob/master/lib/infrared/encoder_decoder/samsung/infrared_decoder_samsung.c#L18
|
||||
// Duplicate address byte, if data is 8 bit and 8 bit inverted and address is 8bit
|
||||
tSendValue.UBytes[1] = aAddress;
|
||||
}
|
||||
} else {
|
||||
// Send 16 command bits
|
||||
tSendValue.UWords[1] = aCommand;
|
||||
|
|
Loading…
Reference in New Issue