Buongiorno,
vi spiego subito la situazione.
Volevo creare un datalogger per il mio inverter dell'impianto fotovoltaico (un vecchio progetto abbandonato). L'inverter (ormai vecchiotto anche lui) ha un ingresso seriale e quindi tramite un Arduino MEGA 2560 con una ethernet shield "applicata sopra" volevo creare un piccolo webserver che fornisse tutti i dati storici ed in realtime.
Tutto funziona correttamente, non è stato difficile fare la parte datalogger (sfrutto la SD sulla ethernetshield) e nemmeno la parte webserver. Il problema è nato per la cosa principale... il colloqui tra arduino e l'inverter.
Ho fatto come prima cosa un programma in C# e funziona tutto correttamente e molto facilmente.
Ecco il codice in c# che funziona correttamente
{
SerialPort m_SerialPort = new SerialPort();
m_SerialPort.PortName = "COM2";
m_SerialPort.BaudRate = 19200;
m_SerialPort.DataBits = 8;
m_SerialPort.Parity = Parity.None;
m_SerialPort.StopBits = StopBits.One;
// Queste due linee sono ininfluenti per il funzionamento
//m_SerialPort.Handshake = Handshake.None;
//m_SerialPort.NewLine = "\r\n";
m_SerialPort.Open();
string ValoreLetto = "";
bool Esci=false;
m_SerialPort.WriteLine("{FB;01;26|64:DYR;DMT;DDY;THR;TMI|08DC}");
while (!Esci)
{
ValoreLetto = ValoreLetto + m_SerialPort.ReadExisting();
if (ValoreLetto != "")
{
// Verifico se finisce per } Se non è così devo aspettare ancora
if (ValoreLetto.Substring(ValoreLetto.Length - 1) == "}")
{
Esci = true;
}
}
}
m_SerialPort.Close();
MessageBox.Show(ValoreLetto);
}
ed ecco cosa passa sulla seriale (sniffato tramite AccessPort). Si vede come l'inverter restituisce ciò che gli chiedo.
IRP_MJ_CREATE COM2 SUCCESS Port Opened
IOCTL_SERIAL_SET_BAUD_RATE COM2 SUCCESS Baud Rate: 19200
IOCTL_SERIAL_CLR_RTS COM2 SUCCESS
IOCTL_SERIAL_CLR_DTR COM2 SUCCESS
IOCTL_SERIAL_SET_LINE_CONTROL COM2 SUCCESS StopBits: 1, Parity: No, DataBits: 8
IOCTL_SERIAL_SET_CHARS COM2 SUCCESS EofChar: 0x1A, ErrorChar: 0x0, BreakChar: 0x0, EventChar: 0x1A, XonChar: 0x11, XoffChar: 0x13
IOCTL_SERIAL_SET_HANDFLOW COM2 SUCCESS ControlHandShake: 0x0, FlowReplace: 0x0, XonLimit: 1024, XoffLimit: 1024
IOCTL_SERIAL_SET_BAUD_RATE COM2 SUCCESS Baud Rate: 19200
IOCTL_SERIAL_CLR_RTS COM2 SUCCESS
IOCTL_SERIAL_CLR_DTR COM2 SUCCESS
IOCTL_SERIAL_SET_LINE_CONTROL COM2 SUCCESS StopBits: 1, Parity: No, DataBits: 8
IOCTL_SERIAL_SET_CHARS COM2 SUCCESS EofChar: 0x1A, ErrorChar: 0x0, BreakChar: 0x0, EventChar: 0x1A, XonChar: 0x11, XoffChar: 0x13
IOCTL_SERIAL_SET_HANDFLOW COM2 SUCCESS ControlHandShake: 0x0, FlowReplace: 0x0, XonLimit: 1024, XoffLimit: 1024
IOCTL_SERIAL_CLR_DTR COM2 SUCCESS
IOCTL_SERIAL_SET_TIMEOUTS COM2 SUCCESS ReadIntervalTimeout: -1, ReadTotalTimeoutMultiplier: -1, ReadTotalTimeoutConstant: -2, WriteTotalTimeoutMultiplier: 0, WriteTotalTimeoutConstant: 0
IOCTL_SERIAL_SET_WAIT_MASK COM2 SUCCESS Mask: RXCHAR RXFLAG CTS DSR RLSD BREAK ERR RING
IOCTL_SERIAL_SET_QUEUE_SIZE COM2 SUCCESS InSize: 4096, OutSize: 2048
IRP_MJ_WRITE COM2 Length: 39, Data: 7B 46 42 3B 30 31 3B 32 36 7C 36 34 3A 44 59 52 3B 44 4D 54 3B 44 44 59 3B 54 48 52 3B 54 4D 49 7C 30 38 44 43 7D 0A
IOCTL_SERIAL_WAIT_ON_MASK COM2 SUCCESS
IRP_MJ_READ COM2 SUCCESS Length: 1, Data: 7B
IOCTL_SERIAL_WAIT_ON_MASK COM2 SUCCESS
IOCTL_SERIAL_WAIT_ON_MASK COM2 SUCCESS
IRP_MJ_READ COM2 SUCCESS Length: 13, Data: 30 31 3B 46 42 3B 33 32 7C 36 34 3A 44
IRP_MJ_READ COM2 SUCCESS Length: 1, Data: 59
IRP_MJ_READ COM2 SUCCESS Length: 35, Data: 52 3D 31 34 3B 44 4D 54 3D 34 3B 44 44 59 3D 44 3B 54 48 52 3D 41 3B 54 4D 49 3D 33 39 7C 30 42 39 34 7D
IOCTL_SERIAL_SET_WAIT_MASK COM2 SUCCESS Mask:
IOCTL_SERIAL_CLR_DTR COM2 SUCCESS
IOCTL_SERIAL_PURGE COM2 SUCCESS Purge: RXABORT RXCLEAR
IOCTL_SERIAL_PURGE COM2 SUCCESS Purge: TXABORT TXCLEAR
IRP_MJ_CLOSE COM2 SUCCESS Port Closed
Ho riprodotto il tutto (almeno credo) con Arduino mega 2560+ethernet shield ma non funziona. Sostanzialmente ho collegato ai pin 18/19 una serial device.
Premetto che la serial device funziona correttamente.. Nel senso , connettendo l'arduino ad un terminal manda e riceve tutto correttamente, quindi suppongo che il problema sia solo di parametri di connessione.
Ecco il codice arduino (ide 1.8.12 windows)
void setup() {
Serial.begin(9600);
Serial1.begin(19200);
}
unsigned long TempoLettura = 5 * 1000UL;
String StringaTot="";
void loop()
{
int nBytesAvail=0;
int nBytes=0;
byte cData[100];
unsigned long now = millis();
static unsigned long lastSampleTime = 0 - TempoLettura;
// Leggo dalla porta seriale 1 se arriva qualcosa ed in caso stampo. L'inverter manda sempre stringhe che iniziano per { e finiscono per }
if ((nBytesAvail=Serial1.available()) > 0) {
nBytes = Serial1.readBytes(cData, nBytesAvail);
String AppenaLetta=String((char *)cData).substring(0,nBytes);
AppenaLetta.replace("\n","");
AppenaLetta.replace("\r","");
StringaTot += AppenaLetta;
int Posi=StringaTot.indexOf("}");
if(Posi != -1){
Serial.println(StringaTot.substring(0,Posi+1));
StringaTot=StringaTot.substring(Posi+1);
}
}
// Ogni 5 secondo invio un pacchetto
if (now - lastSampleTime >= TempoLettura)
{
char Buffer[100];
strcpy(Buffer,"{FB;01;26|64:DYR;DMT;DDY;THR;TMI|08DC}\r\n");
lastSampleTime += TempoLettura;
Serial1.write(Buffer,strlen(Buffer));
Serial.println("Send");
}
}
Per sniffare ciò che passa, ho attaccato la seriale del PC all'uscita Serial1 dell'arduino e utilizzato sempre AccessPort. Ecco cosa passa
IOCTL_SERIAL_SET_BAUD_RATE COM6 SUCCESS Baud Rate: 19200
IOCTL_SERIAL_SET_RTS COM6 SUCCESS
IOCTL_SERIAL_SET_DTR COM6 SUCCESS
IOCTL_SERIAL_SET_LINE_CONTROL COM6 SUCCESS StopBits: 1, Parity: No, DataBits: 8
IOCTL_SERIAL_SET_CHARS COM6 SUCCESS EofChar: 0x0, ErrorChar: 0x0, BreakChar: 0x0, EventChar: 0x0, XonChar: 0x11, XoffChar: 0x13
IOCTL_SERIAL_SET_HANDFLOW COM6 SUCCESS ControlHandShake: 0x1, FlowReplace: 0x40, XonLimit: 4096, XoffLimit: 1024
IOCTL_SERIAL_PURGE COM6 SUCCESS Purge: TXABORT RXABORT TXCLEAR RXCLEAR
IOCTL_SERIAL_WAIT_ON_MASK COM6 SUCCESS
IRP_MJ_READ COM6 SUCCESS Length: 2, Data: 7B 46
IOCTL_SERIAL_WAIT_ON_MASK COM6 SUCCESS
IRP_MJ_READ COM6 SUCCESS Length: 1, Data: 42
IOCTL_SERIAL_WAIT_ON_MASK COM6 SUCCESS
IRP_MJ_READ COM6 SUCCESS Length: 2, Data: 3B 30
IOCTL_SERIAL_WAIT_ON_MASK COM6 SUCCESS
IRP_MJ_READ COM6 SUCCESS Length: 2, Data: 31 3B
********************* TOLTI ALTRIMENTI NON POTEVO INVIARE IL POST MA SONO TUTTI UGUALI A SOPRA E SOTTO *********************
IOCTL_SERIAL_WAIT_ON_MASK COM6 SUCCESS
IRP_MJ_READ COM6 SUCCESS Length: 1, Data: 30
IOCTL_SERIAL_WAIT_ON_MASK COM6 SUCCESS
IRP_MJ_READ COM6 SUCCESS Length: 1, Data: 38
IOCTL_SERIAL_WAIT_ON_MASK COM6 SUCCESS
IRP_MJ_READ COM6 SUCCESS Length: 4, Data: 44 43 7D 0D
IOCTL_SERIAL_WAIT_ON_MASK COM6 SUCCESS
IRP_MJ_READ COM6 SUCCESS Length: 1, Data: 0A
Ho il sospetto che il problema sia il fatto che invece di inviare la stringa tutto in un colpo, la invia un po' di byte alla volta e che l'inverter non lo supporti...
Anche quel ControlHandShake diverso e i vari IOCTL_SERIAL_SET_CHARS diversi mi insospettiscono.
Ma non ho trovato nessun modo per modificare quei valori in Arduino e quindi per fare prove a riguardo.
Qualcuno mi sa aiutare? Come posso risolvere
Grazie
