diff --git a/src/ir_Electrolux.cpp b/src/ir_Electrolux.cpp index a7a8406c2..8b219ec93 100644 --- a/src/ir_Electrolux.cpp +++ b/src/ir_Electrolux.cpp @@ -6,7 +6,6 @@ // Brand: Electrolux, Model: Electrolux EACM EZ/N3 #include "ir_Electrolux.h" -#include #include #include "IRac.h" #include "IRrecv.h" @@ -20,7 +19,7 @@ const uint16_t kElectroluxAcBitMark = 752; const uint16_t kElectroluxAcHdrSpace = 2700; const uint16_t kElectroluxAcOneSpace = 2149; const uint16_t kElectroluxAcZeroSpace = 756; -const uint16_t kElectroluxAcFreq = 38000; // Hz. (Guessing the most common frequency.) +const uint16_t kElectroluxAcFreq = 38000; // Hz. (Guessing the most common frequency.) const uint16_t kElectroluxAcOverhead = 3; #if SEND_ELECTROLUX_AC @@ -30,9 +29,11 @@ const uint16_t kElectroluxAcOverhead = 3; /// @param[in] data containing the IR command. /// @param[in] nbits Nr. of bits to send. usually kElectroluxBits /// @param[in] repeat Nr. of times the message is to be repeated. -void IRsend::sendElectroluxAc(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { +void IRsend::sendElectroluxAc(const uint64_t data, const uint16_t nbits, const uint16_t repeat) +{ enableIROut(kElectroluxAcFreq); - for (uint16_t r = 0; r <= repeat; r++) { + for (uint16_t r = 0; r <= repeat; r++) + { uint64_t send_data = data; // Header mark(kElectroluxAcHdrMark); @@ -42,10 +43,10 @@ void IRsend::sendElectroluxAc(const uint64_t data, const uint16_t nbits, const u send_data >>= 32; // Footer mark(kElectroluxAcBitMark); - space(kDefaultMessageGap); // A 100% made up guess of the gap between messages. + space(kDefaultMessageGap); // A 100% made up guess of the gap between messages. } } -#endif // SEND_ELECTROLUX +#endif // SEND_ELECTROLUX #if DECODE_ELECTROLUX_AC // Function should be safe up to 64 bits. @@ -57,10 +58,11 @@ void IRsend::sendElectroluxAc(const uint64_t data, const uint16_t nbits, const u /// @param[in] nbits The number of data bits to expect. /// @param[in] strict Flag indicating if we should perform strict matching. /// @return A boolean. True if it can decode it, false if it can't. -bool IRrecv::decodeElectroluxAc(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { - - if (results->rawlen < 2 * nbits + kElectroluxAcOverhead - offset) //rawlen = 68, nbits = 104 - return false; // Too short a message to match. +bool IRrecv::decodeElectroluxAc(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) +{ + + if (results->rawlen < 2 * nbits + kElectroluxAcOverhead - offset) // rawlen = 68, nbits = 104 + return false; // Too short a message to match. if (strict && nbits != kElectroluxAcBits) return false; @@ -73,16 +75,15 @@ bool IRrecv::decodeElectroluxAc(decode_results *results, uint16_t offset, const if (!matchSpace(results->rawbuf[offset++], kElectroluxAcHdrSpace)) return false; - - // Data Section #1 // e.g. data_result.data = 0xED000004, nbits = 32 data_result = matchData(&(results->rawbuf[offset]), 32, kElectroluxAcBitMark, kElectroluxAcOneSpace, kElectroluxAcBitMark, kElectroluxAcZeroSpace); offset += data_result.used; - if (data_result.success == false) return false; // Fail - data <<= 32; // Make room for the new bits of data. + if (data_result.success == false) + return false; // Fail + data <<= 32; // Make room for the new bits of data. data |= data_result.data; // Footer @@ -97,15 +98,15 @@ bool IRrecv::decodeElectroluxAc(decode_results *results, uint16_t offset, const results->address = 0; return true; } -#endif // DECODE_ELECTROLUX +#endif // DECODE_ELECTROLUX /// Class constructor /// @param[in] pin GPIO to be used when sending. /// @param[in] inverted Is the output signal to be inverted? /// @param[in] use_modulation Is frequency modulation to be used? IRElectroluxAc::IRElectroluxAc(const uint16_t pin, const bool inverted, - const bool use_modulation) - : _irsend(pin, inverted, use_modulation) { stateReset(); } + const bool use_modulation) + : _irsend(pin, inverted, use_modulation) { stateReset(); } /// Reset the internal state to a fixed known good state. /// @note The state is powered off. @@ -114,17 +115,18 @@ void IRElectroluxAc::stateReset(void) { _.raw = 0xF3008005; } #if SEND_ELECTROLUX_AC /// Send the current internal state as an IR message. /// @param[in] repeat Nr. of times the message will be repeated. -void IRElectroluxAc::send(const uint16_t repeat) { +void IRElectroluxAc::send(const uint16_t repeat) +{ _irsend.sendElectroluxAc(getRaw(), kElectroluxAcBits, repeat); } -#endif // SEND_ELECTROLUX_AC +#endif // SEND_ELECTROLUX_AC /// Set up hardware to be able to send a message. void IRElectroluxAc::begin(void) { _irsend.begin(); } /// Turn on/off the Power Airwell setting. /// @param[in] on The desired setting state. -void IRElectroluxAc::setPower(const bool on) { _.Power = on; } +void IRElectroluxAc::setPower(const bool on) { _.Power = on; } /// Get the power toggle setting from the internal state. /// @return A boolean indicating the setting. @@ -140,28 +142,42 @@ bool IRElectroluxAc::getTempModeFahrenheit(void) const { return _.TempModeFahren /// Set the temperature. /// @param[in] degrees The temperature in celsius or fahrenheit. -void IRElectroluxAc::setTemp(const uint8_t degrees) { - if(getTempModeFahrenheit()) { +void IRElectroluxAc::setTemp(const uint8_t degrees) +{ + if (getTempModeFahrenheit()) + { uint8_t temp = max(kElectroluxAcMinFTemp, degrees); temp = min(kElectroluxAcMaxFTemp, temp); _.Temp = (temp - kElectroluxAcMinFTemp); } - else { + else + { uint8_t temp = max(kElectroluxAcMinTemp, degrees); temp = min(kElectroluxAcMaxTemp, temp); +#ifndef UNIT_TEST temp = map(temp, kElectroluxAcMinTemp, kElectroluxAcMaxTemp, kElectroluxAcMinFTemp, kElectroluxAcMaxFTemp); +#else + temp = temp * 9 / 5 + 32; +#endif _.Temp = temp - kElectroluxAcMinFTemp; } } /// Get the current temperature from the internal state. /// @return The current temperature in Celsius. -uint8_t IRElectroluxAc::getTemp(void) const { - if(getTempModeFahrenheit()) { +uint8_t IRElectroluxAc::getTemp(void) const +{ + if (getTempModeFahrenheit()) + { return _.Temp + kElectroluxAcMinFTemp; } - else { + else + { +#ifndef UNIT_TEST uint8_t temp = map(_.Temp + kElectroluxAcMinFTemp, kElectroluxAcMinFTemp, kElectroluxAcMaxFTemp, kElectroluxAcMinTemp, kElectroluxAcMaxTemp); +#else + uint8_t temp = ((_.Temp + kElectroluxAcMinFTemp) - 32) * 5 / 9; +#endif return temp; } } @@ -169,9 +185,10 @@ uint8_t IRElectroluxAc::getTemp(void) const { /// Set the speed of the fan. /// @param[in] speed The desired setting. /// @note The speed is locked to Low when in Dry mode. -void IRElectroluxAc::setFan(const uint8_t speed) { +void IRElectroluxAc::setFan(const uint8_t speed) +{ _.Fan = (_.Mode == kElectroluxModeAuto) ? kElectroluxFanAuto - : std::min(speed, kElectroluxFanAuto); + : std::min(speed, kElectroluxFanAuto); } /// Get the current fan speed setting. @@ -180,16 +197,18 @@ uint8_t IRElectroluxAc::getFan(void) const { return _.Fan; } /// Set the desired operation mode. /// @param[in] mode The desired operation mode. -void IRElectroluxAc::setMode(const uint8_t mode) { - switch (mode) { - case kElectroluxModeCool: - case kElectroluxModeDry: - case kElectroluxModeFan: - case kElectroluxModeAuto: - _.Mode = mode; - break; - default: - _.Mode = kElectroluxModeAuto; +void IRElectroluxAc::setMode(const uint8_t mode) +{ + switch (mode) + { + case kElectroluxModeCool: + case kElectroluxModeDry: + case kElectroluxModeFan: + case kElectroluxModeAuto: + _.Mode = mode; + break; + default: + _.Mode = kElectroluxModeAuto; } } @@ -201,17 +220,19 @@ uint8_t IRElectroluxAc::getMode(void) const { return _.Mode; } /// @param[in] nr_of_mins Number of minutes to set the timer to. /// (< 60 is disable). /// @note The A/C protocol only supports one hour increments. -void IRElectroluxAc::setOnOffTimer(const uint16_t nr_of_hours) { - uint8_t hours = std::min((uint8_t)(nr_of_hours / 60), kElectroluxTimerMax); +void IRElectroluxAc::setOnOffTimer(const uint16_t nr_of_mins) +{ + uint8_t hours = std::min((uint8_t)(nr_of_mins / 60), kElectroluxTimerMax); // The time can be changed in sleep mode, but doesn't set the flag. _.TimerEnable = hours > 0; - _.Timer = std::max(kElectroluxTimerMin, hours); // Hours + _.Timer = std::max(kElectroluxTimerMin, hours); // Hours } /// Get the current On/Off Timer time. /// @return The number of minutes it is set for. 0 means it's off. /// @note The A/C protocol only supports one hour increments. -uint16_t IRElectroluxAc::getOnOffTimer(void) const { +uint16_t IRElectroluxAc::getOnOffTimer(void) const +{ if (_.TimerEnable) return _.Timer * 60; else @@ -228,8 +249,9 @@ bool IRElectroluxAc::getQuiet(void) const { return _.Quiet; } /// Get a copy of the internal state as a valid code for this protocol. /// @return A valid code for this protocol based on the current internal state. -uint64_t IRElectroluxAc::getRaw(void) { - checksum(); // Ensure correct settings before sending. +uint64_t IRElectroluxAc::getRaw(void) +{ + checksum(); // Ensure correct settings before sending. return _.raw; } @@ -240,10 +262,11 @@ void IRElectroluxAc::setRaw(const uint64_t state) { _.raw = state; } /// Calculate the checksum for a given state. /// @param[in] state The value to calc the checksum of. /// @return The 4-bit checksum stored in a uint_8. -uint8_t IRElectroluxAc::calcChecksum(const uint64_t state) { +uint8_t IRElectroluxAc::calcChecksum(const uint64_t state) +{ uint32_t data = GETBITS64(state, kElectroluxAcChecksumSize + kElectroluxAcChecksumOffset, kElectroluxAcBits - 4); uint8_t result = 0; - for (; data; data >>= 4) // Add each nibble together. + for (; data; data >>= 4) // Add each nibble together. result += GETBITS8(data, 0, 4); return (result ^ 0xF) & 0xF; } @@ -251,76 +274,101 @@ uint8_t IRElectroluxAc::calcChecksum(const uint64_t state) { /// Verify the checksum is valid for a given state. /// @param[in] state The array to verify the checksum of. /// @return true, if the state has a valid checksum. Otherwise, false. -bool IRElectroluxAc::validChecksum(const uint64_t state) { +bool IRElectroluxAc::validChecksum(const uint64_t state) +{ // Validate the checksum of the given state. return (GETBITS8(state, kElectroluxAcChecksumOffset, - kElectroluxAcChecksumSize) == calcChecksum(state)); + kElectroluxAcChecksumSize) == calcChecksum(state)); } /// Convert a stdAc::opmode_t enum into its native mode. /// @param[in] mode The enum to be converted. /// @return The native equivalent of the enum. -uint8_t IRElectroluxAc::convertMode(const stdAc::opmode_t mode) { - switch (mode) { - case stdAc::opmode_t::kCool: return kElectroluxModeCool; - case stdAc::opmode_t::kDry: return kElectroluxModeDry; - case stdAc::opmode_t::kFan: return kElectroluxModeFan; - default: return kElectroluxModeAuto; +uint8_t IRElectroluxAc::convertMode(const stdAc::opmode_t mode) +{ + switch (mode) + { + case stdAc::opmode_t::kCool: + return kElectroluxModeCool; + case stdAc::opmode_t::kDry: + return kElectroluxModeDry; + case stdAc::opmode_t::kFan: + return kElectroluxModeFan; + default: + return kElectroluxModeAuto; } } /// Convert a stdAc::fanspeed_t enum into it's native speed. /// @param[in] speed The enum to be converted. /// @return The native equivalent of the enum. -uint8_t IRElectroluxAc::convertFan(const stdAc::fanspeed_t speed) { - switch (speed) { - case stdAc::fanspeed_t::kMin: - case stdAc::fanspeed_t::kLow: - return kElectroluxFanLow; - case stdAc::fanspeed_t::kMedium: - case stdAc::fanspeed_t::kMediumHigh: - return kElectroluxFanMedium; - case stdAc::fanspeed_t::kHigh: - case stdAc::fanspeed_t::kMax: - return kElectroluxFanHigh; - default: - return kElectroluxFanAuto; +uint8_t IRElectroluxAc::convertFan(const stdAc::fanspeed_t speed) +{ + switch (speed) + { + case stdAc::fanspeed_t::kMin: + case stdAc::fanspeed_t::kLow: + return kElectroluxFanLow; + case stdAc::fanspeed_t::kMedium: + case stdAc::fanspeed_t::kMediumHigh: + return kElectroluxFanMedium; + case stdAc::fanspeed_t::kHigh: + case stdAc::fanspeed_t::kMax: + return kElectroluxFanHigh; + default: + return kElectroluxFanAuto; } } /// Convert a native mode into its stdAc equivalent. /// @param[in] mode The native setting to be converted. /// @return The stdAc equivalent of the native setting. -stdAc::opmode_t IRElectroluxAc::toCommonMode(const uint8_t mode) { - switch (mode) { - case kElectroluxModeCool: return stdAc::opmode_t::kCool; - case kElectroluxModeDry: return stdAc::opmode_t::kDry; - case kElectroluxModeFan: return stdAc::opmode_t::kFan; - default: return stdAc::opmode_t::kAuto; +stdAc::opmode_t IRElectroluxAc::toCommonMode(const uint8_t mode) +{ + switch (mode) + { + case kElectroluxModeCool: + return stdAc::opmode_t::kCool; + case kElectroluxModeDry: + return stdAc::opmode_t::kDry; + case kElectroluxModeFan: + return stdAc::opmode_t::kFan; + default: + return stdAc::opmode_t::kAuto; } } /// Convert a native fan speed into its stdAc equivalent. /// @param[in] speed The native setting to be converted. /// @return The stdAc equivalent of the native setting. -stdAc::fanspeed_t IRElectroluxAc::toCommonFanSpeed(const uint8_t speed) { - switch (speed) { - case kElectroluxFanHigh: return stdAc::fanspeed_t::kMax; - case kElectroluxFanMedium: return stdAc::fanspeed_t::kMedium; - case kElectroluxFanLow: return stdAc::fanspeed_t::kMin; - default: return stdAc::fanspeed_t::kAuto; +stdAc::fanspeed_t IRElectroluxAc::toCommonFanSpeed(const uint8_t speed) +{ + switch (speed) + { + case kElectroluxFanHigh: + return stdAc::fanspeed_t::kMax; + case kElectroluxFanMedium: + return stdAc::fanspeed_t::kMedium; + case kElectroluxFanLow: + return stdAc::fanspeed_t::kMin; + default: + return stdAc::fanspeed_t::kAuto; } } /// Convert the current internal state into its stdAc::state_t equivalent. /// @param[in] prev Ptr to the previous state if required. /// @return The stdAc equivalent of the native settings. -stdAc::state_t IRElectroluxAc::toCommon(const stdAc::state_t *prev) const { +stdAc::state_t IRElectroluxAc::toCommon(const stdAc::state_t *prev) const +{ stdAc::state_t result{}; // Start with the previous state if given it. - if (prev != NULL) { + if (prev != NULL) + { result = *prev; - } else { + } + else + { // Set defaults for non-zero values that are not implicitly set for when // there is no previous state. // e.g. Any setting that toggles should probably go here. @@ -350,9 +398,10 @@ stdAc::state_t IRElectroluxAc::toCommon(const stdAc::state_t *prev) const { /// Convert the internal state into a human readable string. /// @return The current internal state expressed as a human readable String. -String IRElectroluxAc::toString(void) const { +String IRElectroluxAc::toString(void) const +{ String result = ""; - result.reserve(120); // Reserve some heap for the string to reduce fragging. + result.reserve(120); // Reserve some heap for the string to reduce fragging. result += addBoolToString(_.Power, kPowerStr, false); result += addModeToString(_.Mode, kElectroluxModeAuto, kElectroluxModeCool, 0xFF, kElectroluxModeDry, kElectroluxModeFan); @@ -363,17 +412,20 @@ String IRElectroluxAc::toString(void) const { result += addBoolToString(getQuiet(), kQuietStr); - if(getPower()) { + if (getPower()) + { result += irutils::addLabeledString(irutils::minsToString(getOnOffTimer()), kOffTimerStr); } - else { + else + { result += irutils::addLabeledString(irutils::minsToString(getOnOffTimer()), kOnTimerStr); } return result; } /// Calculate and set the checksum values for the internal state. -void IRElectroluxAc::checksum(void) { +void IRElectroluxAc::checksum(void) +{ _.Sum = calcChecksum(_.raw); } diff --git a/src/ir_Electrolux.h b/src/ir_Electrolux.h index d3f7ee92e..64d89c11a 100644 --- a/src/ir_Electrolux.h +++ b/src/ir_Electrolux.h @@ -15,56 +15,57 @@ #endif #include "IRremoteESP8266.h" #include "IRsend.h" -#include "map" #ifdef UNIT_TEST #include "IRsend_test.h" #endif -union ElectroluxAcProtocol{ - uint64_t raw; // The state of the IR remote in native IR code form. - struct { - uint8_t Sum :4; - uint8_t :4; - uint8_t :5; - uint8_t TempModeFahrenheit :1; - uint8_t :1; - uint8_t Quiet :1; - uint8_t Timer :4; - uint8_t TimerEnable :1; - uint8_t Mode :3; - uint8_t Temp :5; - uint8_t Fan :2; - uint8_t Power :1; - uint64_t :0; - }; +union ElectroluxAcProtocol +{ + uint64_t raw; // The state of the IR remote in native IR code form. + struct + { + uint8_t Sum : 4; + uint8_t : 4; + uint8_t : 5; + uint8_t TempModeFahrenheit : 1; + uint8_t : 1; + uint8_t Quiet : 1; + uint8_t Timer : 4; + uint8_t TimerEnable : 1; + uint8_t Mode : 3; + uint8_t Temp : 5; + uint8_t Fan : 2; + uint8_t Power : 1; + uint64_t : 0; + }; }; // Constants -const uint8_t kElectroluxAcMinTemp = 16; // 16C -const uint8_t kElectroluxAcMaxTemp = 32; // 32C -const uint8_t kElectroluxAcMinFTemp = 60; // 60F -const uint8_t kElectroluxAcMaxFTemp = 90; // 90F -const uint8_t kElectroluxTimerMax = 12; // 12H -const uint8_t kElectroluxTimerMin = 1; // 1H +const uint8_t kElectroluxAcMinTemp = 16; // 16C +const uint8_t kElectroluxAcMaxTemp = 32; // 32C +const uint8_t kElectroluxAcMinFTemp = 60; // 60F +const uint8_t kElectroluxAcMaxFTemp = 90; // 90F +const uint8_t kElectroluxTimerMax = 12; // 12H +const uint8_t kElectroluxTimerMin = 1; // 1H const uint64_t kElectroluxAcKnownGoodState = 0xF3008005; const uint8_t kElectroluxAcChecksumOffset = 0; const uint8_t kElectroluxAcChecksumSize = 4; // Fan -const uint8_t kElectroluxFanLow = 2; // 0b11 -const uint8_t kElectroluxFanMedium = 1; // 0b01 -const uint8_t kElectroluxFanHigh = 0; // 0b00 -const uint8_t kElectroluxFanAuto = 3; // 0b11 +const uint8_t kElectroluxFanLow = 2; // 0b11 +const uint8_t kElectroluxFanMedium = 1; // 0b01 +const uint8_t kElectroluxFanHigh = 0; // 0b00 +const uint8_t kElectroluxFanAuto = 3; // 0b11 // Modes -const uint8_t kElectroluxModeCool = 0; // 0b000 -const uint8_t kElectroluxModeDry = 1; // 0b001 -const uint8_t kElectroluxModeFan = 2; // 0b010 -const uint8_t kElectroluxModeAuto = 4; // 0b100 +const uint8_t kElectroluxModeCool = 0; // 0b000 +const uint8_t kElectroluxModeDry = 1; // 0b001 +const uint8_t kElectroluxModeFan = 2; // 0b010 +const uint8_t kElectroluxModeAuto = 4; // 0b100 - -class IRElectroluxAc { - public: +class IRElectroluxAc +{ +public: explicit IRElectroluxAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); void stateReset(); @@ -75,7 +76,7 @@ class IRElectroluxAc { /// @note This will produce a 65ms IR signal pulse at 38kHz. /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } -#endif // SEND_ELECTROLUX_AC +#endif // SEND_ELECTROLUX_AC void begin(); void on(void); void off(void); @@ -104,17 +105,16 @@ class IRElectroluxAc { stdAc::state_t toCommon(const stdAc::state_t *prev = NULL) const; String toString(void) const; - #ifndef UNIT_TEST - private: - IRsend _irsend; ///< Instance of the IR send class -#else // UNIT_TEST +private: + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST /// @cond IGNORE - IRsendTest _irsend; ///< Instance of the testing IR send class + IRsendTest _irsend; ///< Instance of the testing IR send class /// @endcond -#endif // UNIT_TEST +#endif // UNIT_TEST ElectroluxAcProtocol _; void checksum(void); }; -#endif // IR_ELECTROLUX_AC_H_ \ No newline at end of file +#endif // IR_ELECTROLUX_AC_H_ \ No newline at end of file diff --git a/tools/serial_parser.py b/tools/serial_parser.py index 124915103..115d58e41 100644 --- a/tools/serial_parser.py +++ b/tools/serial_parser.py @@ -1,99 +1,100 @@ -import enum +#!/usr/bin/python3 +"""Automaticly get data from ESP8266's Raw data output and calculating average time for zero, one and space""" +# +# Copyright 2024 Andrey Kravchenko (StellaLupus) import serial import serial.tools import serial.tools.list_ports -def substring_after(str: str, searchStr: str): - return str[str.index(searchStr) + len(searchStr):] -def getPort(): +def get_port(): + """Allow user to select com port to connect device""" ports = sorted(serial.tools.list_ports.comports()) print("Available ports to listing:") - for id, portInfo in enumerate(ports): - print("{}. - {}: {} [{}]".format(id, portInfo.device, portInfo.description, portInfo.hwid)) + for id, port_info in enumerate(ports): + print("{}. - {}: {} [{}]".format(id, port_info.device, + port_info.description, + port_info.hwid)) print("Select port: ", end="") - selectId = int(input()) - if selectId < len(ports) and selectId >= 0: - return ports[selectId] + select_id = int(input()) + if select_id < len(ports) and select_id >= 0: + return ports[select_id] else: - print("Unrecognized port number") - return getPort() - -zero = 756 -one = 2149 -space = 752 -interv = 0.2 - -def getBitFromInterv(value: int): - if(value > zero - zero * interv and value < zero + zero * interv): - return 0 - elif(value > one - one * interv and value < one + one * interv): - return 1 - else: - return 2 - -def bitListToInt(bitlist): + print("Unrecognized port number") + return get_port() + + +ZERO_T = 756 +ONE_T = 2149 +SPACE_T = 752 +PRECISION = 0.25 + + +def get_bit_from_interv(value: int): + """Returning zero or one from value or 2 if not recognized""" + if value > ZERO_T - ZERO_T * PRECISION and value < ZERO_T + ZERO_T * PRECISION: + return 0 + elif value > ONE_T - ONE_T * PRECISION and value < ONE_T + ONE_T * PRECISION: + return 1 + else: + return 2 + + +def bit_list_to_int(bit_list): + """Convert list of bits to int""" out = 0 - for bit in bitlist: + for bit in bit_list: out = (out << 1) | bit return out def main(): - port = getPort() + """Main method""" + port = get_port() print("Selected port:" + port.device) ser = serial.Serial( - port=port.device, - baudrate=115200, + port=port.device, + baudrate=115200, ) - zSum = 0 - zCnt = 0 - oSum = 0 - oCnt = 0 - sSum = 0 - sCnt = 0 + ZERO_SUM = 0 + ZERO_COUNT = 0 + ONE_SUM = 0 + ONE_CNT = 0 + SPACE_SUM = 0 + SPACE_CNT = 0 while True: - try: - dataStr = ser.readline().decode() - except: - continue - #print(dataStr) - if("uint16_t rawData" in dataStr): - dataStrArray = str(dataStr[dataStr.index('{') + 1:dataStr.index('}')]).split(",") - data = [int(i.strip()) for i in dataStrArray] - data = data[2:] - clearData = [i for idi, i in enumerate(data) if idi % 2 == 1] - bitData = [getBitFromInterv(i) for i in data] - clearBitData = [getBitFromInterv(i) for i in clearData] - - - - for idd, d in enumerate(data): - if(idd % 2 == 0): - sSum += d - sCnt += 1 - else: - if(getBitFromInterv(d) == 0): - zSum += d - zCnt += 1 - elif(getBitFromInterv(d) == 1): - oSum += d - oCnt += 1 - - # print("zero = " + str(zSum/zCnt) + " one = " + str(oSum/oCnt) + " space = " + str(sSum/sCnt))\ - - - - # print("Data = ", end="") - # print(data) - # print("0b"+ "".join([str(i) for i in bitData])) - # print("ClearData = ", end="") - #print(clearData) - print("".join([str(i) for i in clearBitData])) - - -if __name__ == '__main__': - main() \ No newline at end of file + try: + data_str = ser.readline().decode() + except: + continue + if "uint16_t rawData" in data_str: + data_str_array = str(data_str[data_str.index("{") + + 1:data_str.index("}")]).split(",") + data = [int(i.strip()) for i in data_str_array] + data = data[2:] + clear_data = [i for idi, i in enumerate(data) if idi % 2 == 1] + bit_data = [get_bit_from_interv(i) for i in data] + clear_bit_data = [get_bit_from_interv(i) for i in clear_data] + + for idd, d in enumerate(data): + if idd % 2 == 0: + SPACE_SUM += d + SPACE_CNT += 1 + else: + if get_bit_from_interv(d) == 0: + ZERO_SUM += d + ZERO_COUNT += 1 + elif get_bit_from_interv(d) == 1: + ONE_SUM += d + ONE_CNT += 1 + + print("Bit data = " + "".join([str(i) for i in bit_data])) + print("Clear bit data = " + + "".join([str(i) for i in clear_bit_data])) + + +if __name__ == "__main__": + main()