Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <WiFi.h>
- #include <WebServer.h>
- #include <DNSServer.h>
- // Define the radio pins
- int radioPin = 8; // GPIO8 for the encoded signal
- int audioPin = 10; // GPIO10 for the 1 kHz tone
- // Define the glyph structure and table
- typedef struct glyph {
- char ch;
- word col[7];
- } Glyph;
- const Glyph glyphtab[] PROGMEM = {
- { ' ', { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 } },
- { 'A', { 0x07fc, 0x0e60, 0x0c60, 0x0e60, 0x07fc, 0x0000, 0x0000 } },
- { 'B', { 0x0c0c, 0x0ffc, 0x0ccc, 0x0ccc, 0x0738, 0x0000, 0x0000 } },
- { 'C', { 0x0ffc, 0x0c0c, 0x0c0c, 0x0c0c, 0x0c0c, 0x0000, 0x0000 } },
- { 'D', { 0x0c0c, 0x0ffc, 0x0c0c, 0x0c0c, 0x07f8, 0x0000, 0x0000 } },
- { 'E', { 0x0ffc, 0x0ccc, 0x0ccc, 0x0c0c, 0x0c0c, 0x0000, 0x0000 } },
- { 'F', { 0x0ffc, 0x0cc0, 0x0cc0, 0x0c00, 0x0c00, 0x0000, 0x0000 } },
- { 'G', { 0x0ffc, 0x0c0c, 0x0c0c, 0x0ccc, 0x0cfc, 0x0000, 0x0000 } },
- { 'H', { 0x0ffc, 0x00c0, 0x00c0, 0x00c0, 0x0ffc, 0x0000, 0x0000 } },
- { 'I', { 0x0ffc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 } },
- { 'J', { 0x003c, 0x000c, 0x000c, 0x000c, 0x0ffc, 0x0000, 0x0000 } },
- { 'K', { 0x0ffc, 0x00c0, 0x00e0, 0x0330, 0x0e1c, 0x0000, 0x0000 } },
- { 'L', { 0x0ffc, 0x000c, 0x000c, 0x000c, 0x000c, 0x0000, 0x0000 } },
- { 'M', { 0x0ffc, 0x0600, 0x0300, 0x0600, 0x0ffc, 0x0000, 0x0000 } },
- { 'N', { 0x0ffc, 0x0700, 0x01c0, 0x0070, 0x0ffc, 0x0000, 0x0000 } },
- { 'O', { 0x0ffc, 0x0c0c, 0x0c0c, 0x0c0c, 0x0ffc, 0x0000, 0x0000 } },
- { 'P', { 0x0c0c, 0x0ffc, 0x0ccc, 0x0cc0, 0x0780, 0x0000, 0x0000 } },
- { 'Q', { 0x0ffc, 0x0c0c, 0x0c3c, 0x0ffc, 0x000f, 0x0000, 0x0000 } },
- { 'R', { 0x0ffc, 0x0cc0, 0x0cc0, 0x0cf0, 0x079c, 0x0000, 0x0000 } },
- { 'S', { 0x078c, 0x0ccc, 0x0ccc, 0x0ccc, 0x0c78, 0x0000, 0x0000 } },
- { 'T', { 0x0c00, 0x0c00, 0x0ffc, 0x0c00, 0x0c00, 0x0000, 0x0000 } },
- { 'U', { 0x0ff8, 0x000c, 0x000c, 0x000c, 0x0ff8, 0x0000, 0x0000 } },
- { 'V', { 0x0ffc, 0x0038, 0x00e0, 0x0380, 0x0e00, 0x0000, 0x0000 } },
- { 'W', { 0x0ff8, 0x000c, 0x00f8, 0x000c, 0x0ff8, 0x0000, 0x0000 } },
- { 'X', { 0x0e1c, 0x0330, 0x01e0, 0x0330, 0x0e1c, 0x0000, 0x0000 } },
- { 'Y', { 0x0e00, 0x0380, 0x00fc, 0x0380, 0x0e00, 0x0000, 0x0000 } },
- { 'Z', { 0x0c1c, 0x0c7c, 0x0ccc, 0x0f8c, 0x0e0c, 0x0000, 0x0000 } },
- { '0', { 0x07f8, 0x0c0c, 0x0c0c, 0x0c0c, 0x07f8, 0x0000, 0x0000 } },
- { '1', { 0x0300, 0x0600, 0x0ffc, 0x0000, 0x0000, 0x0000, 0x0000 } },
- { '2', { 0x061c, 0x0c3c, 0x0ccc, 0x078c, 0x000c, 0x0000, 0x0000 } },
- { '3', { 0x0006, 0x1806, 0x198c, 0x1f98, 0x00f0, 0x0000, 0x0000 } },
- { '4', { 0x1fe0, 0x0060, 0x0060, 0x0ffc, 0x0060, 0x0000, 0x0000 } },
- { '5', { 0x000c, 0x000c, 0x1f8c, 0x1998, 0x18f0, 0x0000, 0x0000 } },
- { '6', { 0x07fc, 0x0c66, 0x18c6, 0x00c6, 0x007c, 0x0000, 0x0000 } },
- { '7', { 0x181c, 0x1870, 0x19c0, 0x1f00, 0x1c00, 0x0000, 0x0000 } },
- { '8', { 0x0f3c, 0x19e6, 0x18c6, 0x19e6, 0x0f3c, 0x0000, 0x0000 } },
- { '9', { 0x0f80, 0x18c6, 0x18cc, 0x1818, 0x0ff0, 0x0000, 0x0000 } },
- { '*', { 0x018c, 0x0198, 0x0ff0, 0x0198, 0x018c, 0x0000, 0x0000 } },
- { '.', { 0x001c, 0x001c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 } },
- { '?', { 0x1800, 0x1800, 0x19ce, 0x1f00, 0x0000, 0x0000, 0x0000 } },
- { '!', { 0x1f9c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 } },
- { '(', { 0x01e0, 0x0738, 0x1c0e, 0x0000, 0x0000, 0x0000, 0x0000 } },
- { ')', { 0x1c0e, 0x0738, 0x01e0, 0x0000, 0x0000, 0x0000, 0x0000 } },
- { '#', { 0x0330, 0x0ffc, 0x0330, 0x0ffc, 0x0330, 0x0000, 0x0000 } },
- { '$', { 0x078c, 0x0ccc, 0x1ffe, 0x0ccc, 0x0c78, 0x0000, 0x0000 } },
- { '/', { 0x001c, 0x0070, 0x01c0, 0x0700, 0x1c00, 0x0000, 0x0000 } }
- };
- #define NGLYPHS (sizeof(glyphtab) / sizeof(glyphtab[0]))
- // Web server and DNS server
- WebServer server(80);
- DNSServer dnsServer;
- // Variables
- String text = "";
- String binaryString = "";
- bool isSending = false;
- unsigned long lastTransmitTime = 0;
- int currentBitIndex = 0;
- // Function to compile text into a binary string
- String compileTextToBinary(const char *text) {
- String binaryString = "";
- for (int i = 0; text[i] != '\0'; i++) {
- char ch = text[i];
- Serial.print(ch);
- Serial.print(" -> ");
- for (int j = 0; j < NGLYPHS; j++) {
- if (pgm_read_byte(&glyphtab[j].ch) == ch) {
- for (int x = 0; x < 7; x++) {
- word col = pgm_read_word(&glyphtab[j].col[x]);
- for (int y = 0; y < 14; y++) {
- binaryString += (col & (1 << y)) ? '1' : '0';
- Serial.print((col & (1 << y)) ? '1' : '0');
- }
- }
- break;
- }
- }
- Serial.println();
- }
- Serial.println("Total:" + binaryString);
- return binaryString;
- }
- // Function to transmit one bit
- void transmitBit(char bit) {
- digitalWrite(radioPin, bit == '1' ? HIGH : LOW);
- // Modulate GPIO10 with 1 kHz tone when GPIO8 is HIGH
- if (bit == '1') {
- tone(audioPin, 1000); // Generate 1 kHz tone
- } else {
- noTone(audioPin); // Turn off the tone
- }
- }
- // Web interface handlers
- void handleRoot() {
- String html = "<!DOCTYPE html>"
- "<html>"
- "<head>"
- "<title>Feld-Hell Transmitter</title>"
- "<style>"
- "body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; }"
- "textarea { width: 300px; height: 100px; margin-bottom: 20px; }"
- "#sendButton { padding: 10px 20px; font-size: 16px; cursor: pointer; border: none; border-radius: 5px; color: white; }"
- ".green { background-color: green; }"
- ".red { background-color: red; }"
- ".disabled { background-color: #ccc; cursor: not-allowed; }"
- "</style>"
- "<script>"
- "function toggleSend() {"
- "const text = document.getElementById('text').value.toUpperCase();"
- "const sendButton = document.getElementById('sendButton');"
- "const textArea = document.getElementById('text');"
- "if (sendButton.classList.contains('green')) {"
- "fetch('/send', {"
- "method: 'POST',"
- "headers: { 'Content-Type': 'application/x-www-form-urlencoded' },"
- "body: 'text=' + encodeURIComponent(text)"
- "}).then(response => {"
- "if (response.ok) {"
- "sendButton.classList.remove('green');"
- "sendButton.classList.add('red');"
- "sendButton.textContent = 'Stop Sending';"
- "textArea.disabled = true;"
- "textArea.classList.add('disabled');"
- "}"
- "});"
- "} else {"
- "fetch('/stop').then(response => {"
- "if (response.ok) {"
- "sendButton.classList.remove('red');"
- "sendButton.classList.add('green');"
- "sendButton.textContent = 'Send';"
- "textArea.disabled = false;"
- "textArea.classList.remove('disabled');"
- "}"
- "});"
- "}"
- "}"
- "</script>"
- "</head>"
- "<body>"
- "<h1>Feld-Hell Transmitter</h1>"
- "<textarea id=\"text\" placeholder=\"Enter text here\"></textarea><br>"
- "<button id=\"sendButton\" class=\"green\" onclick=\"toggleSend()\">Send</button>"
- "</body>"
- "</html>";
- server.send(200, "text/html", html);
- }
- void handleSend() {
- if (server.hasArg("text")) {
- text = server.arg("text");
- binaryString = compileTextToBinary(text.c_str());
- isSending = true;
- currentBitIndex = 0;
- lastTransmitTime = micros(); // Use micros() for precise timing
- server.send(200, "text/plain", "Sending started");
- } else {
- server.send(400, "text/plain", "Error: No text provided");
- }
- }
- void handleStop() {
- isSending = false;
- digitalWrite(radioPin, LOW); // Ensure the signal ends low
- noTone(audioPin); // Ensure the tone is turned off
- server.send(200, "text/plain", "Sending stopped");
- }
- void setup() {
- digitalWrite(LED_BUILTIN, LOW);
- // Start Serial communication
- Serial.begin(115200);
- while (!Serial) delay(100); // wait until serial is up
- // Set the radio and audio pins as output
- pinMode(radioPin, OUTPUT);
- pinMode(audioPin, OUTPUT);
- // Start Wi-Fi access point
- WiFi.softAP("Feld-Hell Transmitter");
- IPAddress IP = WiFi.softAPIP();
- Serial.println("Access Point IP: " + IP.toString());
- // Start DNS server for captive portal
- dnsServer.start(53, "*", IP);
- // Set up web server routes
- server.on("/", handleRoot);
- server.on("/send", HTTP_POST, handleSend);
- server.on("/stop", handleStop);
- // Start the web server
- server.begin();
- digitalWrite(LED_BUILTIN, HIGH);
- }
- void loop() {
- // Handle DNS and web server requests
- dnsServer.processNextRequest();
- server.handleClient();
- // Non-blocking transmission with precise timing
- if (isSending && (micros() - lastTransmitTime >= 4080)) {
- if (currentBitIndex < binaryString.length()) {
- transmitBit(binaryString[currentBitIndex]);
- currentBitIndex++;
- } else {
- // Restart transmission from the beginning
- currentBitIndex = 0;
- }
- lastTransmitTime = micros(); // Reset the timer
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement