giovedì 16 ottobre 2014

Serial to Ethernet con Arduino

Per risolvere il problema di un amico che deve mandare il segnale di uno strumento di monitoraggio (uscita solo in seriale) su Internet per la misura remota ho provato a costruire un convertitore seriale-ethernet.
Esistono soluzioni commerciali decisamente piu' solide ma anche piu' costose (vedi http://www.moxa.com/product/Serial_Device_Servers.htm) ma cosi' si perde il divertimento

Lo strumento esce con una seriale RS-232 quindi la prima parte e' inserire un MAX 3232 (gia' visto in questo post) con uno shield ethernet su Arduino Uno per trasmettere i dati in Udp



Per semplicita' ho simulato tutto sul portatile (non avendo peraltro a disposizione lo strumento che e' in uso per monitoraggio). Il segnale seriale e' stato simulato con un semplice programma in Python che manda numeri progressivi sulla porta seriale (per ovvi motivi non ho una seriale reale sul portatile ed ho usato un cavo usb-seriale per il collegamento
---------------------------------------------
import serial
ser = serial.Serial('/dev/ttyUSB0',9600)
conta = 0
while True:
    ser.write(str(conta))
    conta = conta + 1
---------------------------------------------

sulla Arduino e' stato montato questo sketch che semplicemente legge la seriale (sui Pin 0 ed 1 di una Arduino Uno) e crea un pacchetto Udp che viene lanciato ad un server udp remoto
Attenzione: in fase di programmazione mediante cavo Usb il pin 0 deve essere disconnesso dal convertitore MAX 3232 perche' altrimenti si ha un conflitto e lo sketch non viene caricato sull'Arduino. Il collegamento Usb con la IDE Arduino usa il pin 0

il server e' sul 192.168.1.10:5005. L'Arduino era collegata tramite un cavo cross con lo stesso portatile che mandava il segnale seriale
-----------------------------------------------
#include <SPI.h>       
#include <Ethernet.h>
#include <EthernetUdp.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 2);
unsigned int localPort = 5005;
int ingresso = 0;

EthernetUDP Udp;

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);
  Udp.beginPacket({192, 168, 1, 10}, 5005);
  Udp.write("Pronto");
  Udp.endPacket();

}

void loop() {
if (Serial.available() > 0)
    {
    ingresso = Serial.read(); 
    Udp.beginPacket({192, 168, 1, 10}, 5005);
    Udp.write(ingresso);
    Udp.endPacket();
    }

}
-------------------------------------------------
Questo e' il server in Python che gestisce l'arrivo dei dati
-------------------------------------------------
import socket

UDP_IP = "192.168.1.10"
UDP_PORT = 5005

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
sock.bind((UDP_IP, UDP_PORT))

while True:
    data, addr = sock.recvfrom(1024) 
    print data
-------------------------------------------------
Capitolo costi:
una soluzione industriale va circa sui 150 euro

con la soluzione fatta in casa i costi sono qualcosa meno di 20 euro per una Arduino Uno (se si va sui cloni i prezzi calano rapidamente), uno shield ethernet originale va circa a 30 euro ma si trovano moduli anche sui 10 euro, il MAX3232 montato e' circa sui 5 euro
in totale si spende da un minimo di 30 ad un massimo di 55 euro (montaggio e scatola esclusa).