Categoria: Arduino

  • Connessione Joystick DB9 (C64) su Windows tramite Arduino e Python

    Con un modulo Arduino e qualche riga di Python è possibile utilizzare un Joystick del Commodore come periferica di input.

    Nel test ho utilizzato un Joystick Alberici Albatros.

    Materiale occorrente:

    • Joystick con connessione DB9
    • Connettore DB9 Maschio da collegare ad Arduino
    • Arduino
    • Python
    • Software Vjoy

    Ecco lo schema generale di funzionamento: Arduino legge l’input grezzo proveniente dal joystick e lo converte in un messaggio inviato tramite porta seriale, python processa questo messaggio e governa il virtual Joystick (che viene visto da Windows come una periferica di gioco fisica).

    Sketch Arduino:

    const int pinUp    = 2;
    const int pinDown  = 3;
    const int pinLeft  = 4;
    const int pinRight = 5;
    const int pinFire  = 6;
    
    unsigned long lastSend = 0;
    const unsigned long interval = 20; // ms (50 Hz)
    
    void setup() {
      pinMode(pinUp,    INPUT_PULLUP);
      pinMode(pinDown,  INPUT_PULLUP);
      pinMode(pinLeft,  INPUT_PULLUP);
      pinMode(pinRight, INPUT_PULLUP);
      pinMode(pinFire,  INPUT_PULLUP);
    
      Serial.begin(115200);
    }
    
    void loop() {
      if (millis() - lastSend >= interval) {
        lastSend = millis();
    
        int up    = !digitalRead(pinUp);
        int down  = !digitalRead(pinDown);
        int left  = !digitalRead(pinLeft);
        int right = !digitalRead(pinRight);
        int fire  = !digitalRead(pinFire);
    
        Serial.print("U:");
        Serial.print(up);
        Serial.print(" D:");
        Serial.print(down);
        Serial.print(" L:");
        Serial.print(left);
        Serial.print(" R:");
        Serial.print(right);
        Serial.print(" F:");
        Serial.println(fire);
      }
    }
    

    Programma python per processare i dati provenienti dalla seriale:

    import re
    import serial
    import pyvjoy
    
    # --- CONFIG ---
    PORT = "COM7"      # <-- cambia qui
    BAUD = 115200
    VJOY_ID = 1
    # --------------
    
    LINE_RE = re.compile(r"U:(\d)\s+D:(\d)\s+L:(\d)\s+R:(\d)\s+F:(\d)")
    
    AX_MIN = 0x0001
    AX_MAX = 0x8000
    AX_CEN = 0x4000
    
    def axis(neg, pos):
        if neg and not pos: return AX_MIN
        if pos and not neg: return AX_MAX
        return AX_CEN
    
    ser = serial.Serial(PORT, BAUD, timeout=1)
    j = pyvjoy.VJoyDevice(VJOY_ID)
    
    # reset iniziale
    j.reset()
    j.set_axis(pyvjoy.HID_USAGE_X, AX_CEN)
    j.set_axis(pyvjoy.HID_USAGE_Y, AX_CEN)
    j.set_button(1, 0)
    
    print("OK - leggo seriale e mando a vJoy (CTRL+C per uscire)")
    
    last = None
    try:
        while True:
            line = ser.readline().decode("ascii", errors="ignore").strip()
            m = LINE_RE.match(line)
            if not m:
                continue
    
            up, down, left, right, fire = map(int, m.groups())
            state = (up, down, left, right, fire)
            if state == last:
                continue
            last = state
    
            j.set_axis(pyvjoy.HID_USAGE_X, axis(left, right))
            j.set_axis(pyvjoy.HID_USAGE_Y, axis(up, down))  # su = min, giu = max
            j.set_button(1, 1 if fire else 0)
    
    except KeyboardInterrupt:
        pass
    finally:
        # rilascia tutto
        j.set_axis(pyvjoy.HID_USAGE_X, AX_CEN)
        j.set_axis(pyvjoy.HID_USAGE_Y, AX_CEN)
        j.set_button(1, 0)
        ser.close()
        print("\nChiudo.")
    

    Si consiglia di testarlo su WinUAE e Sensible Soccer 🙂

  • Free Protocol su Weintek HMI

    Ecco un esempio di come è possibile leggere dei dati dalla porta seriale di un HMI Weintek utilizzando il Free Protocol.

    Materiale software/hardware occorrente:

    • un modulo Arduino;
    • Arduino IDE;
    • Weintek Easybuilder Pro;
    • un cavo USB.

    Questo codice Arduino scrive dei dati sulla porta seriale, in questo caso un’onda sinusoidale.

    const unsigned long BAUD = 9600;
    const float PERIOD_MS = 20000.0f; 
    const float AMP = 100.0f; 			
    
    void setup() {
    
        Serial.begin(BAUD);
    
    }
    
    void loop() {
    	
        unsigned long t = millis();
        float n = (2.0f * PI) * ( (float)t / PERIOD_MS );
        float val = AMP * sin(n);
        Serial.println(val, 2);
        delay(100);
    
    }

    A scopo di diagnostica si può controllare l’output generato tramite il monitor seriale di Arduino IDE o anche tramite il programma HTERM.

    Attenzione a impostare correttamente il Baudrate, il numero di bit di dati, di stop e il controllo parità.

    Le impostazioni predefinite della comunicazione seriale di Arduino prevedono 8 bit per i dati, nessuna parità e un bit di stop.1

    In Easy Builder Pro creiamo un nuovo progetto, va bene il modello MT8050ie.

    Aggiungiamo un dispositivo di tipo Free Protocol e impostiamo anche qui i parametri di comunicazione.

    Come porta di comunicazione utilizziamo la COM 1 (RS-232).

    Impostiamo una macro che legga i dati dalla porta seriale, copiandoli poi su una variabile float dello HMI.

    Ci sono due passaggi:

    • lettura dei dati grezzi in ASCII dalla porta seriale (funzione INPORT);
    • conversione in formato float (funzione ASCII2FLOAT).
    macro_command main()
        
        //read ASCII from serial and save in LW-0
        char wResponse[6], receive_len
        INPORT(wResponse[0], "Free Protocol", 6, receive_len)
        if receive_len >= 6 then
            SetData(wResponse[0], "Local HMI", LW, 0, 6)
        end if
        
        //convert read to float and save in LW-10
        float output
        ASCII2FLOAT(wResponse[0], output, 6)
        SetData(output, "Local HMI", LW, 10, 1)
    
    end macro_command

    I dati della variabile float possono essere storicizzati (Data Storico > campionamento Dati > Nuovo … e specifichiamo l’indirizzo di memoria della variabile).

    Il file di progetto Easy Builder Pro è scaricabile da questo link.

    1. Il manuale di Arduino di Paolo Aliverti ed. LSWR 2^ Ed. pag. 377 ↩︎