Last active
October 20, 2021 03:06
-
-
Save seanedwards/5136554508bea240cc460d3fc8763bdb to your computer and use it in GitHub Desktop.
UART Barcode Scanner Component for ESPHome
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <esphome.h> | |
| #include <sstream> | |
| class BarcodeReader : public Component, public UARTDevice, public CustomAPIDevice { | |
| public: | |
| BarcodeReader(UARTComponent *port) : UARTDevice(port) {} | |
| std::stringstream buffer; | |
| unsigned long millisendstr=0; | |
| void setup() override { | |
| millisendstr=millis(); | |
| } | |
| void loop() override { | |
| if (serialScanerEvent()) { | |
| std::string buf = buffer.str(); | |
| // 0x02 indicates a return code from something we wrote to the scanner. | |
| // We skip those ones. | |
| if (buf[0] != 0x02) { | |
| fire_homeassistant_event("esphome.barcode", {{"barcode", buffer.str()}}); | |
| ESP_LOGD("barcode", "barcode: %s", buffer.str().c_str()); | |
| } else { | |
| ESP_LOGD("barcode", "Command returned success."); | |
| } | |
| buffer.str(""); | |
| } | |
| } | |
| bool serialScanerEvent() { | |
| // | |
| if (available()>0) { | |
| // get the new byte: | |
| buffer.put((char)read()); | |
| // add it to the inputString: | |
| millisendstr=millis(); | |
| } | |
| return millis()-millisendstr>200 && buffer.tellp() > 0; | |
| } | |
| static std::vector<uint8_t> set_scanning(bool scanning) { | |
| return write(0x0002, {(uint8_t)scanning}); | |
| } | |
| static std::vector<uint8_t> write(uint16_t address, const std::vector<uint8_t>& data) { | |
| uint8_t* address_bytes = (uint8_t*)&address; | |
| ESP_LOGD("barcode", "Writing: 0x%02X%02X (%d bytes)", address_bytes[1], address_bytes[0], data.size()); | |
| std::vector<uint8_t> ret; | |
| // Head1 | |
| ret.push_back(0x7E); | |
| ret.push_back(0x00); | |
| // Types | |
| ret.push_back(0x08); | |
| // Lens | |
| ret.push_back((uint8_t)data.size()); | |
| // Address | |
| ret.push_back(address_bytes[1]); | |
| ret.push_back(address_bytes[0]); | |
| // Data | |
| ret.insert(ret.end(), data.begin(), data.end()); | |
| // CRC | |
| uint16_t crc = (uint16_t)crc_cal_by_bit(ret.data()+2, ret.size()-2); | |
| uint8_t* crc_bytes = (uint8_t*)&crc; | |
| ret.push_back(crc_bytes[1]); | |
| ret.push_back(crc_bytes[0]); | |
| return ret; | |
| } | |
| static unsigned int crc_cal_by_bit (unsigned char * ptr, unsigned char len) | |
| { | |
| unsigned int crc = 0; | |
| while (len-- != 0) { | |
| for (unsigned char i = 0x80; i != 0; i /= 2) { | |
| crc *= 2; | |
| if ((crc & 0x10000) != 0)//After the previous CRC is multiplied by 2, if the first bit is 1, divide by 0x11021 | |
| crc ^= 0x11021; | |
| if ((*ptr & i) != 0)//If the bit is 1, then CRC = CRC of the previous bit + bit/CRC_CCITT | |
| crc ^= 0x1021; | |
| } | |
| ptr++; | |
| } | |
| return crc; | |
| } | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <<: !include include/root.yaml | |
| esphome: | |
| name: scanner-001 | |
| platform: esp32 | |
| board: nodemcu-32s | |
| includes: | |
| - components/barcode.h | |
| on_boot: | |
| priority: -200 | |
| then: | |
| # Bit 7: | |
| # 0: No LED, 1: LED on successful decode | |
| # Bit 6: | |
| # 0: Silence, 1: Beeps | |
| # Bit 5-4: | |
| # 00: No target, 01: Standard, 10/11: Keep | |
| # Bit 3-2: | |
| # 00: No lighting, 01: Standard, 10/11: Keep | |
| # Bit 1-0: | |
| # 00: Manual mode | |
| # 01: Command mode | |
| # 10: Continuous mode | |
| # 11: Sensing mode | |
| - uart.write: !lambda # 87654321 | |
| return BarcodeReader::write(0x0000, {0B01010111}); | |
| # Save settings to flash | |
| - uart.write: [0x7E, 0x00, 0x09, 0x01, 0x00, 0x00, 0xDE, 0xC8] | |
| logger: | |
| level: VERY_VERBOSE | |
| uart: | |
| id: uart_bus | |
| tx_pin: GPIO25 | |
| rx_pin: GPIO26 | |
| baud_rate: 9600 | |
| parity: ODD | |
| custom_component: | |
| - id: reader | |
| lambda: |- | |
| auto scanner = new BarcodeReader(id(uart_bus)); | |
| return {scanner}; | |
| binary_sensor: | |
| - platform: gpio | |
| pin: | |
| number: GPIO0 | |
| mode: INPUT_PULLUP | |
| inverted: True | |
| name: "EN button" | |
| on_press: | |
| - logger.log: 'Hello World' | |
| - script.execute: scan | |
| #- uart.write: !lambda | |
| # return BarcodeReader::write(0x0000, {0B01010101}); | |
| #- uart.write: [0x7E, 0x00, 0x09, 0x01, 0x00, 0x00, 0xDE, 0xC8] | |
| internal: true | |
| script: | |
| - id: scan | |
| mode: single | |
| then: | |
| - uart.write: !lambda | |
| return BarcodeReader::set_scanning(true); | |
| - delay: 5s | |
| - uart.write: !lambda | |
| return BarcodeReader::set_scanning(false); | |
| status_led: | |
| pin: GPIO16 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment