Bemerkung

Hallo, willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook! Tauchen Sie mit anderen Enthusiasten tiefer in Raspberry Pi, Arduino und ESP32 ein.

Warum beitreten?

  • Expertenunterstützung: Lösen Sie Probleme nach dem Kauf und technische Herausforderungen mit Hilfe unserer Community und unseres Teams.

  • Lernen & Teilen: Tauschen Sie Tipps und Tutorials aus, um Ihre Fähigkeiten zu verbessern.

  • Exklusive Vorschauen: Erhalten Sie frühzeitigen Zugang zu neuen Produktankündigungen und Sneak Peeks.

  • Sonderrabatte: Genießen Sie exklusive Rabatte auf unsere neuesten Produkte.

  • Festliche Aktionen und Gewinnspiele: Nehmen Sie an Gewinnspielen und Feiertagsaktionen teil.

👉 Bereit, mit uns zu entdecken und zu gestalten? Klicken Sie auf [here] und treten Sie noch heute bei!

(Beispiel) AI-gestützter Morsecode-Decoder

Einführung

Dieses Projekt erstellt einen intelligenten Morsecode-Decoder, der AI verwendet, um Zeitmuster von Tastendrücken zu interpretieren. Das System erfasst präzise Zeitdaten und nutzt OpenAIs GPT, um Morsecode-Nachrichten in Echtzeit zu dekodieren. Der Decoder bietet:

  1. Zeitbasierte Eingabe, die genaue Druck- und Loslasszeiten erfasst

  2. AI-gestützte Dekodierung mit GPT zur Interpretation von Punkt-/Strichmustern

  3. Visuellen Indikator mit einer LED, die den aktiven Dekodierzustand anzeigt

  4. Dual-Button-Oberfläche mit getrennten Tasten für Eingabe und Steuerung

  5. Echtzeit-Feedback, das die Zeitdaten während der Eingabe anzeigt

Das System zeichnet die Dauer der Tastendrücke auf, sendet die Zeitdaten zur Interpretation an die AI und dekodiert Morsecode-Sequenzen wie das universelle Notsignal „SOS“ zuverlässig.

Sie können zeitkritische Eingaben mit AI-Interpretation für verschiedene Codierungssysteme kombinieren. Siehe:


Was Sie benötigen

Für dieses Projekt werden die folgenden Komponenten benötigt:

COMPONENT

PURCHASE LINK

Taste

BUY (x2)

LED

BUY

Widerstand

BUY

Fusion HAT+

-

Jumper-Kabel

BUY

Raspberry Pi

-


Schaltplan

Verbinden Sie die Komponenten wie folgt mit dem Raspberry Pi:

../_images/morse_decoder_bb.png

API-Schlüssel erstellen und speichern

  1. Gehen Sie zu OpenAI Platform und melden Sie sich an. Klicken Sie auf der Seite API keys auf Create new secret key.

    ../_images/llm_openai_create.png
  2. Füllen Sie die Angaben aus (Owner, Name, Project und gegebenenfalls Berechtigungen) und klicken Sie dann auf Create secret key.

    ../_images/llm_openai_create_confirm.png
  3. Sobald der Schlüssel erstellt wurde, kopieren Sie ihn sofort — später wird er nicht noch einmal angezeigt. Falls Sie ihn verlieren, müssen Sie einen neuen erstellen.

    ../_images/llm_openai_copy.png
  4. Erstellen Sie in Ihrem Projektordner (zum Beispiel: /) eine Datei mit dem Namen secret.py:

    cd ~/ai-lab-kit/llm
    sudo nano secret.py
    
  5. Fügen Sie Ihren Schlüssel wie folgt in die Datei ein:

    # secret.py
    # Store secrets here. Never commit this file to Git.
    OPENAI_API_KEY = "sk-xxx"
    

Abrechnung aktivieren und Modelle prüfen

  1. Bevor Sie den Schlüssel verwenden, öffnen Sie in Ihrem OpenAI-Konto die Seite Billing, hinterlegen Sie Ihre Zahlungsdaten und laden Sie ein kleines Guthaben auf.

    ../_images/llm_openai_billing.png
  2. Wechseln Sie anschließend zur Seite Limits, um zu prüfen, welche Modelle für Ihr Konto verfügbar sind, und kopieren Sie die genaue Modell-ID für die Verwendung im Code.

    ../_images/llm_openai_models.png

Beispiel ausführen

  1. Code ausführen

    cd ~/ai-lab-kit/llm
    sudo python3 llm_openai_morse_decoder.py
    
  2. Eine einfache Morsecode-Nachricht ausprobieren (Beispiel: „SOS“)

    Nachdem das Programm gestartet wurde, drücken Sie die Start-/Stopp-Taste, um die Aufzeichnung zu beginnen. Drücken Sie dann die Morse-Taste, um Punkte (kurze Tastendrücke) und Striche (lange Tastendrücke) einzugeben.

    Wenn Sie fertig sind, drücken Sie die Start-/Stopp-Taste erneut, um die Aufzeichnung zu beenden und die Nachricht zu dekodieren.

  3. Konsolenausgabe prüfen

    Die Konsole zeigt die Zeitstempel für Tastendruck und Loslassen an, und die AI analysiert die Zeitdaten und gibt die dekodierte Nachricht aus.

    Typische Konsolenausgabe bei der Eingabe von „SOS“:

    To decode the Morse code message based on the button press times provided, we need to interpret the duration of each press. Typically, a short press (dot) is around 0.2 to 0.3 seconds, while a long press (dash) is about 0.5 seconds or longer. Let's analyze the press durations:
    
    1. `1767773542.1257536` to `1767773542.285196` - Duration: ~0.16 seconds - Dot (.)
    2. `1767773542.4936137` to `1767773542.6315389` - Duration: ~0.14 seconds - Dot (.)
    3. `1767773542.9092748` to `1767773543.0543947` - Duration: ~0.15 seconds - Dot (.)
    4. `1767773544.2299025` to `1767773544.5774245` - Duration: ~0.35 seconds - Dash (-)
    5. `1767773545.1017563` to `1767773545.4954002` - Duration: ~0.39 seconds - Dash (-)
    6. `1767773546.11932` to `1767773546.5881057` - Duration: ~0.47 seconds - Dash (-)
    7. `1767773547.824543` to `1767773547.9534554` - Duration: ~0.13 seconds - Dot (.)
    8. `1767773548.1879761` to `1767773548.2895174` - Duration: ~0.10 seconds - Dot (.)
    9. `1767773548.5281847` to `1767773548.6453152` - Duration: ~0.12 seconds - Dot (.)
    
    Now let's decode the sequence into letters using Morse code:
    
    - `...` (Dot Dot Dot) = S
    - `---` (Dash Dash Dash) = O
    - `...` (Dot Dot Dot) = S
    
    Putting it all together, the decoded message is "SOS".
    
  4. Den Ablauf verstehen

    1. Aufzeichnung starten: Drücken Sie die Start-/Stopp-Taste (GPIO 17), und die LED leuchtet auf

    2. Morsecode eingeben: Verwenden Sie die Morse-Taste (GPIO 22) für Punkte und Striche

    3. Echtzeitanzeige: Die Konsole zeigt Zeitstempel für Tastendruck und Loslassen

    4. Stoppen und dekodieren: Drücken Sie die Start-/Stopp-Taste erneut, und die LED erlischt

    5. AI-Analyse: Die Zeitdaten werden zur Interpretation an OpenAI GPT gesendet

    6. Dekodierte Ausgabe: Die AI gibt die dekodierte Nachricht aus

Code

Hier ist das vollständige Python-Skript für den AI-gestützten Morsecode-Decoder:

from fusion_hat.llm import OpenAI
from secret import OPENAI_API_KEY
from fusion_hat.pin import Pin
import random, time

# Register OpenAI API
# openai.com

# Export your openai api key with :LLM_API_KEY
# export LLM_API_KEY=sk-xxxxxxxxxxxxxxxxx

# Setup GPIO pins
morse_input = Pin(22, mode=Pin.IN, pull=Pin.PULL_DOWN, bounce_time=0.05)
start_stop_button = Pin(17, mode=Pin.IN, pull=Pin.PULL_DOWN, bounce_time=0.05)
led = Pin(27, Pin.OUT)  # Indicator LED on GPIO 27

# Store the morse code events with timing data
morse_events = []
input_active = False  # Flag to indicate if input is active

# Setup LLM with Morse code decoding instructions
INSTRUCTIONS = "You are a Morse code decoder. Decode based on the button press time, interpreting short presses as dots and long presses as dashes. The message you receive may be a word or a sentence, please decode it and output it."

WELCOME = "Hello, I am a Morse code decoder. Please press the button to start decoding. When you are done, press the button again to stop."

llm = OpenAI(
    api_key=OPENAI_API_KEY,
    model="gpt-4o",
)

# Set how many messages to keep
llm.set_max_messages(20)
# Set instructions
llm.set_instructions(INSTRUCTIONS)
# Set welcome message
llm.set_welcome(WELCOME)

print(WELCOME)

# Send the morse code timing data to the AI for decoding
def decode_and_print():
    global morse_events

    # Convert timing events to string for AI processing
    input_text = str(morse_events)

    # Get response from AI with streaming
    response = llm.prompt(input_text, stream=True)

    # Print streaming response
    for next_word in response:
        if next_word:
            print(next_word, end="", flush=True)

    print("")  # New line after complete response

    morse_events = []  # Clear the morse code events for next message

# Morse code input handling variables
start_time = 0

# Function called when morse input button is pressed
def morse_input_pressed():
    global start_time
    start_time = time.time()
    morse_events.append(('pressed', start_time))
    print(f" Pressed at {start_time} -", end="")

# Function called when morse input button is released
def morse_input_released():
    global morse_events, start_time
    release_time = time.time()

    # Debounce: ignore releases within 0.1 seconds
    if release_time - start_time < 0.1:
        return

    morse_events.append(('released', release_time))
    print(f" {release_time}")

# Start/stop button handler
def handle_start_stop():
    global input_active, morse_events

    if input_active:
        # Stop recording and decode
        led.off()
        print("Input stopped and decoded.")
        decode_and_print()
        input_active = False
    else:
        # Start recording new message
        input_active = True
        morse_events.clear()  # Clear previous events
        led.on()
        print("Input started.")

# Add event listeners to buttons
start_stop_button.when_activated = handle_start_stop
morse_input.when_activated = morse_input_pressed
morse_input.when_deactivated = morse_input_released

# Main program loop
try:
    while True:
        time.sleep(0.1)
except KeyboardInterrupt:
    pass

Code verstehen

  1. GPIO-Pin-Konfiguration

    Drei GPIO-Pins werden für unterschiedliche Zwecke konfiguriert:

    morse_input = Pin(22, mode=Pin.IN, pull=Pin.PULL_DOWN, bounce_time=0.05)
    start_stop_button = Pin(17, mode=Pin.IN, pull=Pin.PULL_DOWN, bounce_time=0.05)
    led = Pin(27, Pin.OUT)
    
    • Entprellzeit (0.05 s): Verhindert Mehrfachauslösungen durch mechanisches Prellen des Schalters

    • Pull-down: Sorgt für ein stabiles LOW-Signal, wenn die Taste nicht gedrückt ist

    • Getrennte Funktionen: Eingabe- und Steuertasten verhindern versehentliche Eingaben

  2. Speicherung der Zeitdaten

    Druck- und Loslassereignisse werden mit präzisen Zeitstempeln gespeichert:

    morse_events = []  # Leere Liste zur Speicherung der Ereignisse
    
    # Jedes Ereignis wird als Tupel gespeichert: ('pressed'/'released', Zeitstempel)
    morse_events.append(('pressed', 1767773542.1257536))
    morse_events.append(('released', 1767773542.285196))
    
  3. Entprellmechanismus

    Verhindert Fehlauslösungen durch Prellen des Schalters:

    def morse_input_released():
        if release_time - start_time < 0.1:  # 100 ms Entprellung
            return  # Sehr kurze Signale ignorieren
    
        morse_events.append(('released', release_time))
    
  4. Zustandsverwaltung

    Das System verwendet ein Flag, um den Aufzeichnungszustand zu verfolgen:

    input_active = False  # Anfangszustand: keine Aufzeichnung
    
    def handle_start_stop():
        if input_active:
            # Aufzeichnung stoppen und dekodieren
            input_active = False
        else:
            # Aufzeichnung starten
            input_active = True
            morse_events.clear()  # Vorherige Daten löschen
    
  5. Visueller Indikator

    Die LED zeigt den Aufzeichnungsstatus visuell an:

    def handle_start_stop():
        if input_active:
            led.off()  # LED AUS, wenn nicht aufgezeichnet wird
        else:
            led.on()   # LED EIN während der Aufzeichnung
    
  6. Erstellung des AI-Prompts

    Die Zeitdaten werden für die AI-Verarbeitung in einen String umgewandelt:

    input_text = str(morse_events)
    
    # Beispiel für das an die AI gesendete Format:
    # "[('pressed', 1767773542.1257536), ('released', 1767773542.285196), ...]"
    
  7. Streaming-Antwort

    Die AI-Antwort wird in Echtzeit verarbeitet und angezeigt:

    response = llm.prompt(input_text, stream=True)
    
    for next_word in response:
        if next_word:
            print(next_word, end="", flush=True)
    
  8. Ereignisgesteuerte Architektur

    Tastenevents lösen sofort Callback-Funktionen aus:

    # Callback-Funktionen den Tastenereignissen zuweisen
    start_stop_button.when_activated = handle_start_stop
    morse_input.when_activated = morse_input_pressed
    morse_input.when_deactivated = morse_input_released
    
  9. Zeitmessungsgenauigkeit

    Verwendet time.time() für Zeitmessungen mit hoher Genauigkeit:

    start_time = time.time()  # Aktuelle Zeit in Sekunden seit der Unix-Epoche
    
    # Dauer des Tastendrucks berechnen:
    duration = release_time - start_time
    
  10. Daten zurücksetzen

    Nach der Dekodierung wird die Ereignisliste für die nächste Nachricht geleert:

    def decode_and_print():
        # ... Ereignisse verarbeiten ...
        morse_events = []  # Für nächste Nachricht zurücksetzen
    

Morsecode-Zeitstandards

  • Standardzeit (basierend auf dem Wort PARIS):

    • Punkt: 1 Einheit

    • Strich: 3 Einheiten

    • Abstand innerhalb eines Zeichens (zwischen Punkten/Strichen): 1 Einheit

    • Abstand zwischen Buchstaben: 3 Einheiten

    • Abstand zwischen Wörtern: 7 Einheiten

  • Praktische Umsetzung:

    • Punkt: < 0.3 Sekunden (kurzer Tastendruck)

    • Strich: > 0.5 Sekunden (langer Tastendruck)

    • Abstand zwischen Elementen: < 0.5 Sekunden Pause

    • Abstand zwischen Buchstaben: 0.5–1.5 Sekunden Pause

    • Abstand zwischen Wörtern: > 1.5 Sekunden Pause

  • Häufige Morsezeichen:

    • A: • — (Punkt-Strich)

    • B: — • • • (Strich-Punkt-Punkt-Punkt)

    • C: — • — • (Strich-Punkt-Strich-Punkt)

    • S: • • • (Punkt-Punkt-Punkt)

    • O: — — — (Strich-Strich-Strich)


Fehlerbehebung

  • Tastendrücke werden nicht erkannt

    • Verkabelung prüfen: GPIO 22/17 zur Taste, andere Seite an Masse

    • Pull-down-Konfiguration überprüfen

    • Mit einfachem Skript testen: print(Pin(22, mode=Pin.IN, pull=Pin.PULL_DOWN).read())

    • Entprellzeit prüfen (0.05 s könnte zu hoch sein)

  • LED leuchtet nicht

    • Polarität der LED prüfen: Anode (langes Bein) über Widerstand an GPIO 27

    • Widerstandswert prüfen (220 Ω empfohlen)

    • LED direkt testen: Pin(27, Pin.OUT).on() sollte LED einschalten

    • Masseverbindung überprüfen

  • Zeitdaten wirken falsch

    • Systemuhr prüfen: date

    • Entprellzeit reduzieren, wenn zu empfindlich

    • Debug-Ausgaben hinzufügen, um Callback-Ausführung zu prüfen

    • Gleichmäßige Tastendrücke testen

  • AI dekodiert falsch

    • API-Schlüssel und Internetverbindung prüfen

    • Gesendete Zeitdaten überprüfen (print(morse_events))

    • Konsistente Tastendrücke verwenden (Punkte kurz, Striche lang)

    • Klarere Pausen zwischen Buchstaben machen

  • Mehrfachauslösung bei einem Tastendruck

    • bounce_time erhöhen (z. B. 0.1 s)

    • Mechanisches Prellen des Schalters prüfen

    • Hardware-Entprellung mit Kondensator hinzufügen

    • Verkabelung der Taste prüfen

  • System reagiert nicht auf Start/Stopp

    • Prüfen, ob andere Callback-Funktionen stören

    • Logik der Variable input_active überprüfen

    • Debug-Ausgaben in handle_start_stop() hinzufügen

    • Sicherstellen, dass kein anderer Prozess GPIO verwendet

  • AI-Antwort zu langsam

    • Internetgeschwindigkeit prüfen

    • Anzahl der Ereignisse reduzieren (kürzere Nachrichten)

    • Lokale Dekodierung als Fallback verwenden

    • Timeout für AI-Antwort implementieren

  • Punkte und Striche schwer unterscheidbar

    • Gleichmäßiges Timing üben

    • Schwellenwerte in den AI-Anweisungen anpassen

    • Lokale Vorverarbeitung vor dem Senden an die AI hinzufügen

    • Visuelles Feedback während der Eingabe verwenden


Dieser AI-gestützte Morsecode-Decoder zeigt, wie präzise Zeitmessungen mit intelligenter Mustererkennung kombiniert werden können, um historische Kommunikationsmethoden neu zu beleben und sie für neue Generationen zugänglich und lehrreich zu machen.