add MQTT and OTA update support #1
							
								
								
									
										81
									
								
								src/util.h
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								src/util.h
									
									
									
									
									
								
							@@ -1,5 +1,9 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
 | 
			
		||||
// TODO: reverse engineer builtin and custom bitmaps
 | 
			
		||||
 | 
			
		||||
// seems like our sign listens to messages on this address
 | 
			
		||||
@@ -246,6 +250,78 @@ enum class ExtendedChar {
 | 
			
		||||
    GreekSmallLetterPhi = 0xed,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
std::unordered_map<uint16_t, uint8_t> createUnicodeToCP437Map() {
 | 
			
		||||
    std::unordered_map<uint16_t, uint8_t> cp437_map;
 | 
			
		||||
 | 
			
		||||
    cp437_map[0x00E4] = 0x84;  // ä in UTF-16
 | 
			
		||||
    cp437_map[0xC3A4] = 0x84;  // ä in UTF-8
 | 
			
		||||
    cp437_map[0x00F6] = 0x94;  // ö in UTF-16
 | 
			
		||||
    cp437_map[0xC3B6] = 0x94;  // ö in UTF-8
 | 
			
		||||
    cp437_map[0x00FC] = 0x81;  // ü in UTF-16
 | 
			
		||||
    cp437_map[0xC3BC] = 0x81;  // ü in UTF-8
 | 
			
		||||
    cp437_map[0x00C4] = 0x8E;  // Ä in UTF-16
 | 
			
		||||
    cp437_map[0xC384] = 0x8E;  // Ä in UTF-8
 | 
			
		||||
    cp437_map[0x00D6] = 0x99;  // Ö in UTF-16
 | 
			
		||||
    cp437_map[0xC396] = 0x99;  // Ö in UTF-8
 | 
			
		||||
    cp437_map[0x00DC] = 0x9A;  // Ü in UTF-16
 | 
			
		||||
    cp437_map[0xC39C] = 0x9A;  // Ü in UTF-8
 | 
			
		||||
    cp437_map[0x00DF] = 0xE1;  // ß in UTF-16
 | 
			
		||||
    cp437_map[0xC39F] = 0xE1;  // ß in UTF-8
 | 
			
		||||
    cp437_map[0x20AC] = 0xB1;  // € in UTF-16
 | 
			
		||||
    cp437_map[0xE282AC] = 0xB1;  // € in UTF-8 (3 Bytes)
 | 
			
		||||
    cp437_map[0x00B5] = 0xE6;  // µ in UTF-16
 | 
			
		||||
    cp437_map[0xC2B5] = 0xE6;  // µ in UTF-8
 | 
			
		||||
 | 
			
		||||
    return cp437_map;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String convertToCP437(const String& input) {
 | 
			
		||||
    std::unordered_map<uint16_t, uint8_t> cp437_map = createUnicodeToCP437Map();
 | 
			
		||||
    String output = "";
 | 
			
		||||
    size_t len = input.length();
 | 
			
		||||
 | 
			
		||||
    for (size_t i = 0; i < len; i++) {
 | 
			
		||||
        char ch = input[i];
 | 
			
		||||
 | 
			
		||||
        // UTF-8 detection: check for 3 byte UTF-8
 | 
			
		||||
        if ((ch & 0xF0) == 0xE0) {
 | 
			
		||||
            if (i + 2 < len) {
 | 
			
		||||
                uint32_t utf8_char = ((uint8_t)input[i] << 16) | ((uint8_t)input[i + 1] << 8) | (uint8_t)input[i + 2];
 | 
			
		||||
                i += 2;  // skip 2 additional bytes
 | 
			
		||||
                if (cp437_map.find(utf8_char) != cp437_map.end()) {
 | 
			
		||||
                    output += static_cast<char>(cp437_map[utf8_char]);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // UTF-8 detection: check for 2 byte UTF-8
 | 
			
		||||
        else if ((ch & 0xE0) == 0xC0) {
 | 
			
		||||
            if (i + 1 < len) {
 | 
			
		||||
                uint16_t utf8_char = ((uint8_t)input[i] << 8) | (uint8_t)input[i + 1];
 | 
			
		||||
                i++;  // skip second byte
 | 
			
		||||
                if (cp437_map.find(utf8_char) != cp437_map.end()) {
 | 
			
		||||
                    output += static_cast<char>(cp437_map[utf8_char]);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // single UTF-16 character (or plain ANSI character)
 | 
			
		||||
        else if ((uint8_t)ch < 0x80) {  // keep ASCII as is
 | 
			
		||||
            output += ch;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            uint16_t utf16_char = (uint8_t)ch;  // UTF-16 range
 | 
			
		||||
            if (cp437_map.find(utf16_char) != cp437_map.end()) {
 | 
			
		||||
                output += static_cast<char>(cp437_map[utf16_char]);
 | 
			
		||||
            } else {
 | 
			
		||||
                output += '?';
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return output;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String hexDump(String in) {
 | 
			
		||||
    String out;
 | 
			
		||||
    for (size_t i = 0; i < in.length(); ++i) {
 | 
			
		||||
@@ -287,7 +363,6 @@ String hexDump(String in) {
 | 
			
		||||
 *   - stay time: 4
 | 
			
		||||
 *   - brightness: bright
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void sendTextToSign(
 | 
			
		||||
    const String &text,
 | 
			
		||||
    const Method method = Method::Cyclic,
 | 
			
		||||
@@ -307,7 +382,9 @@ void sendTextToSign(
 | 
			
		||||
 | 
			
		||||
    Serial.println("Sending text: \"" + text + "\"");
 | 
			
		||||
 | 
			
		||||
    String toSend = "~" + String(SIGN_ADDRESS, DEC) + "~f01" + (char) method + "\\" + (char) brightness + "\\Y" + String(speed, DEC) + "\\Z" + String(stayTime, DEC) + "\\" + (char) fontType + text + "\r\r\r";
 | 
			
		||||
    String translatedText = convertToCP437(text);
 | 
			
		||||
 | 
			
		||||
    String toSend = "~" + String(SIGN_ADDRESS, DEC) + "~f01" + (char) method + "\\" + (char) brightness + "\\Y" + String(speed, DEC) + "\\Z" + String(stayTime, DEC) + "\\" + (char) fontType + translatedText + "\r\r\r";
 | 
			
		||||
 | 
			
		||||
    Serial1.print(toSend);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user