31. Integrazione dispositivi
MALDA supporta l'interazione con dispositivi fisici tramite comunicazione seriale (USB) e API HTTP/REST (WiFi). Questo consente di controllare Arduino, ESP32, Raspberry Pi, dispositivi per la smart home e altra attrezzatura IoT.
31.1 Panoramica
Perché l'integrazione dei dispositivi?
L'integrazione dei dispositivi consente ai programmi MALDA di:
- Controllare hardware fisico (robot, sensori, attuatori)
- Costruire applicazioni IoT e automazione della smart home
- Creare sistemi multi-dispositivo coordinati da actor
- Combinare agenti AI con l'interazione nel mondo fisico
Metodi di comunicazione
MALDA supporta due metodi di comunicazione principali:
- Comunicazione seriale: connessione USB diretta ai dispositivi (Arduino, microcontroller)
- HTTP/REST: comunicazione di rete per i dispositivi con WiFi (ESP32, Raspberry Pi, dispositivi per la smart home)
Quando usare ciascun metodo
| Metodo | Ideale per | Vantaggi | Limitazioni |
|---|---|---|---|
| Seriale | Dispositivi collegati via USB, progetti semplici | Bassa latenza, setup semplice, nessuna rete richiesta | Richiede connessione fisica, raggio limitato |
| HTTP/REST | Dispositivi WiFi, più dispositivi, controllo remoto | Wireless, scalabile, funziona su rete/internet | Richiede setup di rete, latenza leggermente più alta |
31.2 Comunicazione seriale
La classe SerialConnection offre comunicazione seriale a basso livello per i dispositivi collegati via USB.
Costruttore
var serial = new SerialConnection();
Crea una nuova istanza di connessione seriale. La connessione si stabilisce con il metodo connect().
Metodi
connect(portName, baudRate)→bool: Apre la connessione seriale sulla porta specificatadisconnect(): Chiude la connessione serialewrite(data): Invia una stringa di dati al dispositivoread()→string: Legge tutti i dati disponibili dal dispositivoread(byteCount)→string: Legge il numero specificato di bytereadLine()→string: Legge una riga (fino al carattere di newline)
Proprietà
isConnected(bool): Verifica se la connessione è attiva
Esempio
var serial = new SerialConnection();
var connected = serial.connect("COM3", 9600);
if (connected) {
serial.write("Hello Arduino\n");
var response = serial.readLine();
print("Response: " + response);
serial.disconnect();
}
Nomi delle porte
I nomi delle porte variano a seconda del sistema operativo:
- Windows:
"COM3","COM4", ecc. - Linux:
"/dev/ttyUSB0","/dev/ttyACM0", ecc. - macOS:
"/dev/cu.usbserial-*","/dev/cu.usbmodem*", ecc.
31.3 Dispositivi HTTP/REST
Per i dispositivi con WiFi, usa la classe RestClient (vedi 28. Client REST Web per la documentazione completa). Funziona con qualsiasi dispositivo che espone API HTTP/REST.
Esempio: dispositivo ESP32
var device = new RestClient("http://192.168.1.100");
// Read sensor value
var response = device.get("/sensor/temperature");
if (response.ok) {
var data = parseJSON(response.body);
print("Temperature: " + data.value);
}
// Control actuator
device.post("/relay/1", {"state": "on"});
Autenticazione
Molti dispositivi richiedono autenticazione:
var device = new RestClient("http://192.168.1.100");
device.setAuth("Bearer", "your-api-token");
31.4 Integrazione Arduino
La classe ArduinoConnection offre un'interfaccia di alto livello per controllare dispositivi Arduino, con supporto sia alla modalità seriale sia a quella HTTP.
Costruttore
ArduinoConnection supporta due modalità:
// HTTP mode (WiFi-enabled devices like ESP32)
var arduino = new ArduinoConnection("http://192.168.1.100");
// Serial mode (USB connection)
var arduino = new ArduinoConnection("COM3", 9600);
Connessione
connect()→bool: Stabilisce la connessione ad Arduinodisconnect(): Chiude la connessioneisConnected(bool): Verifica lo stato della connessione
I/O digitale
digitalWrite(pin, value): Imposta il pin digitale HIGH (true) o LOW (false)digitalRead(pin)→bool: Legge il valore del pin digitale
I/O analogico
analogRead(pin)→int: Legge il pin analogico (0-1023)analogWrite(pin, value): Scrive un valore PWM (0-255) sul pin
Configurazione dei pin
pinMode(pin, mode): Configura la modalità del pin.modedeve essere:"INPUT": Input digitale"OUTPUT": Output digitale"INPUT_PULLUP": Input digitale con resistenza di pull-up interna
Esempio: controllo Arduino di base
// Connect via serial
var arduino = new ArduinoConnection("COM3", 9600);
arduino.connect();
// Configure pin 13 as OUTPUT (LED)
arduino.pinMode(13, "OUTPUT");
// Blink LED
for (var i = 0; i < 5; i = i + 1) {
arduino.digitalWrite(13, true);
sleep(500);
arduino.digitalWrite(13, false);
sleep(500);
}
// Read analog sensor
var sensorValue = arduino.analogRead(0);
print("Sensor value: " + sensorValue);
arduino.disconnect();
Setup dello sketch Arduino
Per usare Arduino con MALDA, carica lo sketch bridge sulla scheda Arduino. Lo sketch ascolta i comandi e li esegue.
Vedi Examples/Arduino/arduino_bridge.ino per lo sketch completo.
Protocollo:
- Comandi:
DIGITAL_WRITE:pin:value\n - Risposte:
OK:value\noERROR:message\n
31.5 ESP32/ESP8266
I dispositivi ESP32 e ESP8266 si possono controllare via HTTP/REST dopo aver caricato lo sketch bridge.
Setup WiFi
Modifica lo sketch ESP32 per configurare le credenziali WiFi:
const char* ssid = "YourWiFiSSID";
const char* password = "YourWiFiPassword";
Endpoint REST API
Il bridge ESP32 espone i seguenti endpoint:
GET /ping: Health checkPOST /digital/write:{"pin": 5, "value": 1}GET /digital/read?pin=5: Restituisce{"value": 1}GET /analog/read?pin=0: Restituisce{"value": 512}POST /analog/write:{"pin": 3, "value": 128}POST /pin/mode:{"pin": 5, "mode": "OUTPUT"}
Esempio: controllo ESP32
// Connect to ESP32 via WiFi
var esp32 = new ArduinoConnection("http://192.168.1.100");
esp32.connect();
// Control LED
esp32.pinMode(2, "OUTPUT");
esp32.digitalWrite(2, true);
// Read sensor
var distance = esp32.analogRead(0);
print("Distance: " + distance);
31.6 Raspberry Pi
Raspberry Pi si può controllare via API HTTP o connessione seriale.
Controllo via API HTTP
Se Raspberry Pi esegue un web server che espone una REST API:
var pi = new RestClient("http://raspberrypi.local:8080");
var status = pi.get("/status");
Comunicazione seriale
Per la comunicazione seriale diretta:
var pi = new SerialConnection();
pi.connect("/dev/ttyUSB0", 115200);
pi.write("command\n");
var response = pi.readLine();
31.7 Dispositivi per la smart home
Molti dispositivi per la smart home espongono REST API che si possono controllare con RestClient.
Esempio Philips Hue
var hue = new RestClient("http://192.168.1.50");
hue.setAuth("Bearer", "your-api-key");
// Turn on light
hue.put("/api/username/lights/1/state", {
"on": true,
"bri": 254,
"hue": 10000
});
// Dim light
hue.put("/api/username/lights/1/state", {
"bri": 128
});
// Turn off
hue.put("/api/username/lights/1/state", {
"on": false
});
Esempio SmartThings
var smartThings = new RestClient("https://api.smartthings.com");
smartThings.setAuth("Bearer", "your-token");
// Get devices
var devices = smartThings.get("/devices");
// Control device
smartThings.post("/devices/device-id/commands", {
"commands": [{
"component": "main",
"capability": "switch",
"command": "on"
}]
});
Esempio Home Assistant
var homeAssistant = new RestClient("http://homeassistant.local:8123");
homeAssistant.setHeader("Authorization", "Bearer your-token");
// Get states
var states = homeAssistant.get("/api/states");
// Control entity
homeAssistant.post("/api/services/light/turn_on", {
"entity_id": "light.living_room"
});
31.8 Coordinamento multi-dispositivo
Il modello ad actor di MALDA è ideale per coordinare più dispositivi. Ogni dispositivo può essere controllato dal proprio actor, abilitando operazioni concorrenti e coordinate.
Usare gli actor per il controllo dei dispositivi
actor DeviceController {
var device;
var deviceId;
function DeviceController(id, url) {
deviceId = id;
device = new ArduinoConnection(url);
}
on connect() {
device.connect();
print("Device " + deviceId + " connected");
}
on control(value) {
device.digitalWrite(5, value);
}
}
// Create multiple device controllers
var devices = [];
for (var i = 0; i < 5; i = i + 1) {
devices.append(spawn DeviceController(i, "http://192.168.1." + (100 + i)));
}
// Connect all devices concurrently
for (var i = 0; i < devices.length; i = i + 1) {
send devices[i].connect();
}
Pattern di coordinamento
Pattern comuni per i sistemi multi-dispositivo:
- Actor coordinatore: actor centrale che coordina tutti i dispositivi
- Actor dispositivo: un actor per dispositivo per un controllo isolato
- Message passing: i dispositivi comunicano tramite messaggi degli actor
- Gestione dello stato: ogni actor dispositivo mantiene il proprio stato
Esempio: sistema multi-robot
actor Robot {
var robotId;
var arduino;
var coordinator;
function Robot(id, url, coord) {
robotId = id;
arduino = new ArduinoConnection(url);
coordinator = coord;
}
on move(direction) {
if (direction == "forward") {
arduino.digitalWrite(5, true);
arduino.digitalWrite(6, true);
}
send coordinator.robotMoved(robotId, direction);
}
}
actor Coordinator {
var robots = [];
on registerRobot(robot) {
robots.append(robot);
}
on startAll() {
for (var i = 0; i < robots.length; i = i + 1) {
send robots[i].move("forward");
}
}
}
var coordinator = spawn Coordinator();
var robot1 = spawn Robot(1, "http://192.168.1.100", coordinator);
var robot2 = spawn Robot(2, "http://192.168.1.101", coordinator);
send coordinator.registerRobot(robot1);
send coordinator.registerRobot(robot2);
send coordinator.startAll();
31.9 Esempi
Esempi completi sono disponibili nella directory Examples/Devices/:
- basic_arduino.malda: controllo Arduino semplice (blink del LED, lettura del sensore)
- multi_robot_soccer.malda: gioco di coordinamento multi-robot con gli actor
- smart_home.malda: esempi di controllo di dispositivi per la smart home
Tutorial passo-passo: primo progetto Arduino
- Carica lo sketch bridge: carica
arduino_bridge.inosul tuo Arduino - Trova il nome della porta: identifica la porta seriale del tuo Arduino (COM3, /dev/ttyUSB0, ecc.)
- Connetti in MALDA:
var arduino = new ArduinoConnection("COM3", 9600); arduino.connect(); - Controlla l'hardware:
arduino.pinMode(13, "OUTPUT"); arduino.digitalWrite(13, true);
31.10 Risoluzione dei problemi
Problemi di connessione seriale
- Porta non trovata: verifica il nome della porta e che il dispositivo sia collegato
- Permission denied (Linux/macOS): aggiungi l'utente al gruppo dialout:
sudo usermod -a -G dialout $USER - Timeout di connessione: controlla che il baud rate corrisponda alla configurazione del dispositivo
Problemi di connessione HTTP
- Connection refused: verifica l'indirizzo IP del dispositivo e che sia sulla stessa rete
- Timeout: controlla che il dispositivo sia acceso e che il WiFi sia connesso
- Errori di autenticazione: verifica che API key e token siano corretti
Errori comuni
"Arduino not connected": chiamaconnect()prima di usare il dispositivo"Invalid pin": verifica che i numeri di pin siano validi per il tuo dispositivo"Arduino error: ...": controlla che lo sketch del dispositivo sia caricato e in esecuzione