[RISOLTO] Problema comunicazione seriale tra Arduino ed Inverter fotovoltaico

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

Ho dato un'occhiata e ho visto alcune cosette

  1. il programma in C# non lavora alla stessa maniera di quello in c per Arduino
    Completamente differente l'impostazione

  2. se un tuo dubbio è su come trasmetti perché del programma che va ci hai mostrato solo la parte di ricezione?

  3. se un altro tuo dubbio è sullo handshaking perché non ci dai delucidazioni sullo handshaking dell'inverter (o almeno qualche link)?

  4. quel programma per Arduino è un "venghino venghino siorri alla sagra della stringa"
    Per arduino questo non è bene
    Pur usando stringhe anche lui, quello in c# era molto meglio

  5. la parte di trasmissione poi mi ha fatto tremare i polsi
    Stai trasmettendo una costante stringa, te la cavavi con una #define e una print, e devi fare tutto quel teatro?

  6. e scusami per questo, ma sono convinto di doverlo dire (altrimenti lo dice Fabio, e lui è meno tenero di me)
    Nella tua presentazione non serve denigrare gli altri programmatori, specialmente se poi il tuo secondo post è messo così

io per queste cose ho sempre consigliato di gestire l'input carattere per carattere
vai a dare uno sguardo ad "aiutateci ad aiutarvi", che ci trovi varii link utili

e aggiungo, controlla bene, ma bene bene, lo handshaking, come dice giustamente il sindaco

per il sindaco: venghino siorri alla "sagra della stringa" mi sembra tanto ispirato dalla "fiera degli array"
vero?

Salvorhardin:

  1. il programma in C# non lavora alla stessa maniera di quello in c per Arduino
    Completamente differente l'impostazione

Infatti il programma fatto in C# voleva solamente testare se l'inverter rispondeva ad un collegamento via seriale visto che con Arduino non rispondeva. Poi sinceramente non mi sembrano cosi diversi...

Salvorhardin:
2) se un tuo dubbio è su come trasmetti perché del programma che va ci hai mostrato solo la parte di ricezione?

???
Il programma fatto in c# fa sia la trasmissione che la ricezione (ReadExisting riceve WriteLine trasmette)
Il programma in Arduino fa sia trasmissione che ricezione (Serial riceve Serial1 trasmette)

Salvorhardin:
3) se un altro tuo dubbio è sullo handshaking perché non ci dai delucidazioni sullo handshaking dell'inverter (o almeno qualche link)?

Perchè NON esiste documentazione di come trasmette e riceve dati da/per l'inverter. Quello che ho scoperto lo ho fatto sniffando i pacchetti. Il funzionamento non è documentato da nessuna parte. E' un protocollo proprietario.

Salvorhardin:
4) quel programma per Arduino è un "venghino venghino siorri alla sagra della stringa"
Per arduino questo non è bene
Pur usando stringhe anche lui, quello in c# era molto meglio

Non capisco cosa voglia dire quella tua frase. Se si riferisce al fatto che uso String, ho visto che spesso qui sul forum dite che è il diavolo e non ho capito il perchè... mi documenterò, ma non credo che il problema dipenda da quello.

Salvorhardin:
5) la parte di trasmissione poi mi ha fatto tremare i polsi
Stai trasmettendo una costante stringa, te la cavavi con una #define e una print, e devi fare tutto quel teatro?

Quella stringa deve essere costruita ad hoc, contiene anche un CRC che deve essere creato a seconda dei parametri che vengono richiesti e con un algoritmo un po' complesso.
Non mi sembrava il caso di mettere qui un sacco di codice non inerente al problema. Ho solo messo lo stretto necessario per non generare confusione

Salvorhardin:
6) e scusami per questo, ma sono convinto di doverlo dire (altrimenti lo dice Fabio, e lui è meno tenero di me)
Nella tua presentazione non serve denigrare gli altri programmatori, specialmente se poi il tuo secondo post è messo così

Ah ecco perchè una risposta così acida...
Come già detto non volevo offendere nessuno. Ho espresso il mio punto di vista.

Sono moderatore di forum e non è buona norma attaccare in questo modo un "nuovo" membro.
Dovresti essere un pochino più Googley a mio avviso

Grazie comunque del tempo che mi hai dedicato, anche se non mi hai dato nessun suggerimento
Buona giornata

Standardoil:
io per queste cose ho sempre consigliato di gestire l'input carattere per carattere
vai a dare uno sguardo ad "aiutateci ad aiutarvi", che ci trovi varii link utili

OK cercherò, grazie del consiglio

Standardoil:
e aggiungo, controlla bene, ma bene bene, lo handshaking, come dice giustamente il sindaco

La mia domanda (non quella del sindaco) era proprio quella... non so come fare... se lo sapessi probabilmente avrei già risolto e non avrei chiesto. Spero di trovare qualche dritta dove mi hai consigliato di sbirciare

Standardoil:
per il sindaco: venghino siorri alla "sagra della stringa" mi sembra tanto ispirato dalla "fiera degli array"
vero?

Come detto (credo) al sindaco, quel codice, sono un po' di righe prese qui un po' li dal programma totale, per farlo semplice e comprensibile quindi può (forse) sembrare un po' "strano" visto "da solo"... fatto sta che dovrebbe funzionare anche con solo quelle poche righe.

Grazie per il tuo aiuto e buona serata

gaggia:
La mia domanda (non quella del sindaco) era proprio quella... non so come fare...
Grazie per il tuo aiuto e buona serata

come configuri l'emulatore di terminale?

gaggia:
String, ho visto che spesso qui sul forum dite che è il diavolo

Non puoi fare allocazione/riallocazione dinamica affidabile in 2k condivisi con variabili statiche e stack processore. Con i microcontroller si deve ragionare a livello più basso (quasi quasi assembly), anche tante funzioni standard come sprintf non sono "ben viste", e se si includono un po'di librerie si arriva presto all'effetto che fa entrare nella mia soffitta.

Buongiorno,
ho letto alcune cose che hai scritto… caspita quanto materiale hai fornito alla community… complimenti.
Non ho però trovato nulla di risolutivo per il mio problema. Ho un po’ modificato il mio codice (lasciando le stringhe come erano)

void setup() {
   Serial.begin(9600);
   while (!Serial) {
      ; // Attendo finchè la connessione si è stabilita
   }
   Serial1.begin(19200);
   while (!Serial1) {
      ; // Attendo finchè la connessione si è stabilita
   }

   Serial.println("Init OK");
   
   // Aumento il valore di timeout rispetto allo standard
   Serial1.setTimeout(2000);
}

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;
   
   // Verifico se ci sono caratteri nel buffer di lettura
   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);
      }
   }   

   // Invio il pacchetto di test ogni 5 secondi
   if (now - lastSampleTime >= TempoLettura)
   {
      char Buffer[100];
      strcpy(Buffer,"{FB;01;26|64:DYR;DMT;DDY;THR;TMI|08DC}\r\n");
      lastSampleTime += TempoLettura;
      
      // Prima di inviare verifico non ci siano cose da leggere nel buffer di lettura
      if(Serial1.available() <= 0){
         Serial1.print(Buffer);
         // Mi rassicuro che sia stato inviata l'intera stringa
         Serial1.flush();
         // Attendo un tempo sufficiente perchè venga fatta la trasmissione
         delay(300);
         
      }
   }
}

Standardoil:
come configuri l’emulatore di terminale?

L’emulatore funziona correttamente con arduino… Quando arduino manda, l’emulatore riceve e se dall’emulatore invio arduino riceve…

baud: 19200
parity no
data bit: 8
stop bit: 1
buffer 8192
event control: CTS changes e character reception
DTR Control: enable
RTS Control: Enable
XON limit: 100
XOFF limit: 100
XON char: 11
XOFF char: 13
Read TimeOut: 1ms
Write TimeOut: 0

Non ci ho dedicato moltissimo tempo (sono un po’ incasinato)… ma non sono ancora riuscito a risolvere.

Buona giornata

Claudio_FF:
Non puoi fare allocazione/riallocazione dinamica affidabile in 2k condivisi con variabili statiche e stack processore. Con i microcontroller si deve ragionare a livello più basso (quasi quasi assembly), anche tante funzioni standard come sprintf non sono "ben viste", e se si includono un po'di librerie si arriva presto all'effetto che fa entrare nella mia soffitta.

Per un periodo ho scritto programmi in linguaggio macchina (Z80). Vecchi tempi... :slight_smile:
Ma se forniscono librerie, classi... come fanno a non essere affidabili? Se mi forniscono un compilatore do per scontato che faccia il lavoro come deve essere fatto. Strana questa cosa.

Grazie per il chiarimento.

gaggia:
... Strana questa cosa.

... non più di tanto ... devi considerare che NON sei su un PC dove c'è un sistema operativo ed un "garbage collector", sei su una piccola MCU con solo 2KBytes di SRAM, dove devi fare tutto tu e dove usare la classe "String", a causa dell'allocazione e riallocazione dinamica della memoria (ne crei varie, le riempi e le vuoti in tempi differenti con contenuti differenti, ecc. ecc.), porta quasi sempre ... a grossi problemi e sicuri mal di testa !!! :smiley:

Guglielmo

gpb01:
... non più di tanto ... devi considerare che NON sei su un PC dove c'è un sistema operativo ed un "garbage collector", sei su una piccola MCU con solo 2KBytes di SRAM, dove devi fare tutto tu e dove usare la classe "String", a causa dell'allocazione e riallocazione dinamica della memoria (ne crei varie, le riempi e le vuoti in tempi differenti con contenuti differenti, ecc. ecc.), porta quasi sempre ... a grossi problemi e sicuri mal di testa !!! :smiley:

Guglielmo

Innanzitutto grazie della risposta.
Si ma se le cose stanno così, perchè creare quelle librerie/classi e distribuirle in modo ufficiale? E' questo che mi sembra strano. Se una cosa c'è l'adopero, se non funziona come si deve, meglio che non ci sia. Almeno secondo me, forse mi sfugge qualcosa.

Ma quindi l'unico modo sicuro è utilizzare char * come puntatori senza utilizzare nessuna funzione? Nemmeno quelle standard C tipo sprintf? Ho capito bene?

C'è da qualche parte una lista di "funzioni sicure"?

Grazie

gaggia:
Ma quindi l’unico modo sicuro è utilizzare char * come puntatori senza utilizzare nessuna funzione? Nemmeno quelle standard C tipo sprintf? Ho capito bene?

NO, il problema nasce dal fatto che allocando e deallocando in contiuazione memoria (uso di malloc(), realloc() e free()) tu frammenti la memoria … e un problema più che noto a chi gioca con le allocazioni dinamiche di memoria e, sui sistemi dove c’è un sistema operativo, è suo compito trovare i vari “buchi” rimasti liberi in memoria e compattare questi spazi in modo da lasciare sempre (ovviamente nei limiti del possibile) blocchi di memoria allocabile.

Su Arduino questo non c’è (il sistema operativo) ed usare classi (stiamo parlando della classe String() e NON delle stringhe classiche del ‘C’ … sono due cose ben differenti!) che fa ampio uso delle suddette funzioni di gestione della memoria, può facilmente causare problemi.

Quindi, nessun problema nell’uso di <string.h>, delle funzioni in essa implementate e nell’uso delle classiche stringhe del ‘C’, ovvero char array terminati da 0x00 :slight_smile:

Guglielmo

gpb01:
Quindi, nessun problema nell’uso di <string.h>, delle funzioni in essa implementate e nell’uso delle classiche stringhe del ‘C’, ovvero char array terminati da 0x00 :slight_smile:

Guglielmo

Buongiorno e ancora grazie per le info che mi stai dando.
Ora è tutto chiaro come sole… mi ero fatto trarre in inganno da questa dichiarazione

Claudio_FF:
… anche tante funzioni standard come sprintf non sono “ben viste”, …

Guglielmo non è che riesci a darmi qualche dritta anche sul mio problema con la seriale? :slight_smile:

Grazie e buona domenica

gaggia:
Ora è tutto chiaro come sole… mi ero fatto trarre in inganno da questa dichiarazione

… anche tante funzioni standard come sprintf non sono “ben viste”, …

Contestualizzo… non è che non sono ben viste perché causano problemi reali (come la frammentazione), ma solo perché occupano spazio. Il loro uso è ok… però stampare sul serial monitor (o su LCD) usando due o tre Serial.print in fila, invece di passare attraverso un buffer in RAM da riempire con sprintf, può essere una buona idea :wink: Se ci si sposta su altri core con decine di k o più di RAM, anche la necessità di queste attenzioni viene meno.

Claudio_FF:
Contestualizzo... non è che non sono ben viste perché causano problemi reali (come la frammentazione), ma solo perché occupano spazio. Il loro uso è ok... però stampare sul serial monitor (o su LCD) usando due o tre Serial.print in fila, invece di passare attraverso un buffer in RAM da riempire con sprintf, può essere una buona idea :wink: Se ci si sposta su altri core con decine di k o più di RAM, anche la necessità di queste attenzioni viene meno.

Grazie Claudio della tua precisazione.
Piano piano capisco :slight_smile: Aver lavorato molti anni con compilatori su sistemi operativi e quantità di RAM notevole, mi ha fatto dimenticare l'ottimizzazione della memoria e determinate pratiche che evidentemente con Arduino sono necessarie.
Con il vostro aiuto ora le cose cose più chiare. Grazie

Purtroppo però, per il mio problema, queste nuove nozioni sono ininfluenti, visto che al codice String (che è solo in ricezione) non ci arrivo... ma sono comunque sempre molto importanti e per quando in quella parte di codice "arriverò" (speriamo presto) mi troverà preparato.

Buona domenica

gaggia:
L’emulatore funziona correttamente con arduino… Quando arduino manda, l’emulatore riceve e se dall’emulatore invio arduino riceve…

prova invece a collegarlo con l’inverter

credo che tu abbia problemi a collegare l’inverter, non arduino

Post Scriptum: io e mio fratello non siamo cattivi, ma alcuna cosa andavano dette

Salvorhardin:
prova invece a collegarlo con l’inverter
credo che tu abbia problemi a collegare l’inverter, non arduino
Post Scriptum: io e mio fratello non siamo cattivi, ma alcuna cosa andavano dette

Buongiorno Salvorhardin
beh… è una community libera e quindi tutti sono liberi di dire quello che pensano (nel rispetto sempre del regolamento). Se io ti son sembrato “maleducato/arrogante” ok a farmelo notare. Per lo stesso principio io mi son permesso di dire nella mia presentazione il mio pensiero che nel bene o nel male, nel giusto o nel torto è il mio pensiero. Io di certo non mi sono offeso per così poco e non ho certo pensato che tu sia cattivo… un po’ acidino si :wink: ma è difficile giudicare una persona che si conosce da anni figuriamoci uno sconosciuto…
Se ti va di aiutarmi ne sono felice e ti ringrazio.

Se io collego il PC con l’inverter con il programma fatto in c# tutto funziona correttamente, quindi il collegamento fisico è corretto (ma ricordiamoci che la device seriale non è la stessa di quella utilizzata con l’Arduino).
La stringa che mando e che ricevo è corretta. Quindi anche con la logica ci siamo.

Quando attacco Arduino all’emulatore tutto ok sia in trasmissione che in ricezione, quindi con l’elettronica ci siamo (almeno quello che c’è… ma c’è tutto?).

Per esclusione, il problema è chiaramente il collegamento tra Arduino e l’inverter. Visto che i parametri base di connessione tra l’Arduino e l’inverter sono gli stessi che ci sono tra il programma c# e l’inverter (che funziona) è chiaro che la connessione seriale dell’Arduino ha qualcosa di carente (per colpa hardware? per colpa software?) verso l’inverter.

Se Arduino avesse 100 possibilità di settare parametri vari per la connessione seriale, li proverei tutti fino a trovare quale funziona (metodo bovino quando non si sa che pesci pigliare), ma a quanto ho trovato io, si possono solo settare baud, bit di start, bit di stop e parità. Chiaramente è inutile far prove su questi pochi parametri perchè sono le uniche cose che so con certezza (visto che sono le stesse che funzionano in c#).

Forse la mia inesperienza con il protocollo seriale mi benda gli occhi su qualcosa che dovrei fare ma che non faccio.

Io sul mio device seriale (foto allegata) ho connesso solo Vcc-Gnd-Tx-Rx anche se ha 8 pin strip, ma visto che non trovo il mio multimetro non posso sapere se sono 4 a 4 uguali (Ad occhio sembra siano 4 connessioni differenti sul chip) o i 4 aggiunti contengono anche CTS, RTS (documentazione della scheda 0… l’avevo li da molto),… come vedete dalla foto non ci sono informazioni utili sulla scheda.
Forse l’inverter si aspetta anche il CTS e l’RTS? Come posso fare a capirlo? Il programma c# utilizza un “cavo” da usb a Rs232 (Aten UC-232A) che potrebbe gestire RTS e CTS… mentre la device Arduino con i solo 4 cavi è impossibile lo faccia… che sia per quello che funziona il programma in c#? Se la mia device avesse RTS e CTS Arduino li gestirebbe in autonomia?
Insomma un sacco di domande a cui (nonostante abbia fatto molte ricerche) non riesco aimè a rispondere.

Buona giornata

Due cose, la prima è che Arduino ha un buffer di ricezione di 64 byte (questo in caso di perdita dati in ricezione).

La seconda è che tra adattatore RS232 Arduino e inverter serva un cavo null-modem.

Claudio_FF:
Due cose, la prima è che Arduino ha un buffer di ricezione di 64 byte (questo in caso di perdita dati in ricezione).

Questo per ora non è un problema visto che non arriva nemmeno un byte :frowning:

Claudio_FF:
La seconda è che tra adattatore RS232 Arduino e inverter serva un cavo null-modem.

Ma è una supposizione/test da provare o una certezza che ci vuol quel tipo di cavo?
Qui nasce un piccolo problemino... anche il cavo è "proprietario"... non è un cavo normale... nel senso... lato Arduino è il classico DB-9, lato inverter è un rj45. Se trovo quel cavolo di multimetro posso fare un po' di test e fare un null-modem

Potrei ordinare Questo oppure Questo che dite?

Grazie

gaggia:
Ma è una supposizione/test da provare o una certezza che ci vuol quel tipo di cavo?

Se il DB9 maschio del PC si collega direttamente nel DB9 femmina dell'inverter (e funziona) E il DB9 maschio del PC si collega direttamente nel DB9 femmina dell'adattatore seriale/TTL (e funziona) ALLORA non si possono collegare direttamente i DB9 dell'inverter e dell'adattatore (tramite un gender changer dritto), bisogna come minimo invertire TX e RX. Il primo link dovrebbe essere l'oggetto giusto.