controllo alimentatore agilent via seriale

ciao a tutti,
vorrei controllare in maniera remota un alimentatore stabilizzato agilent, che supporta il controllo tramite SCPI,
ho collegato lo strumento via rs232 ad arduino e scritto questo codice:

#include <SoftwareSerial.h>

SoftwareSerial alimentatore(6, 7); // RX, TX

void setup()  
{
  pinMode(2,OUTPUT);
  pinMode(13,OUTPUT);
  // Open serial communications and wait for port to open:
  Serial.begin(9600);

  Serial.println("buongiorno alimentatore");

  // set the data rate for the SoftwareSerial port
  alimentatore.begin(9600);
  digitalWrite(2,HIGH);
}

void loop() // run over and over
{
  if (alimentatore.available()){
    Serial.write(alimentatore.read());
    digitalWrite(13,LOW);
    digitalWrite(2,HIGH);
  }
  if (Serial.available()){
    alimentatore.write(Serial.read());
    digitalWrite(13,HIGH);
    digitalWrite(2,LOW);
  }
}

riscontro il seguente problema: inviando istruzioni dal monitor seriale tutto funziona normalmente, finchè non uso una qualsiasi query.
in teoria ad esempio, se invio l’istruzione “*IDN?” lo strumento mi dovrebbe ritornare una stringa contenente le informazioni sullo strumento, ma sul monitor seriale non mi ritorna nulla, e in generale non mi viene inviato nulla.
infatti anche il led che ho messo di ‘debug’ per vedere se cmq ci sono dati sulla softserial , non si accende.
mi sapete aiutare?

Hai provato a collegare due pc tramite l'Arduino, per vedere se tutto funziona (penso ci voglia un cavo null modem)? Se funziona tutto può essere un problema dell'alimentatore, se non va è un problema dello sketch/circuito di Arduino.

Alberto

ho provato sullo stesso pc, collegando ad arduino la serialeUSB e la rs232, visualizzando i due monitor seriali corrispondenti e lo sketch funziona. anche l'alimentatore, inviando gli stessi comandi con matlab funziona

Che non sia un problema di handshaking, come hai collegato il tutto nella prova col pc
usb pc <-> usb Arduino <-> softserial pin <-> adatatore usb seriale 5V <-> usb pc
o
usb pc <-> usb Arduino <-> softserial pin <-> max232 <-> seriale pc
?

con il max232 e l'adattatore usb-rs232.

le istruzioni che non abbiano un ritorno funzionano: sono le query quelle che mi danno l'errore. l'errore 410 che mi da lo strumento dice che praticamente sovrascrivo il buffer di output e dunque vado in errore. quindi penso che lo strumento non svuoti automaticamente il buffer di output come fa normalmente, ma nè io nè il professore abbiamo capito perchè. abbiamo pensato che fosse perchè il cavo utilizzato avesse i pin 1-4-6 cortocircuitati invece che flottanti, ma anche provando il contrario non funziona

Se l'alimentatore collegato direttamente al pc trasmette e riceve è sicuramente un problema di handshaking, provate a collegare insieme i segnali DTR + DSR + DCD RTS + CTS sul connettore seriale del max232

cosa intendi per connettore seriale del max232?

Il connettore, presumo a 9 pin maschio connesso al max232 che si collega al connettore a 9 femmina pin sull'ailimentatore. il collegamento tra i pin 1 DCD + 4 DSR + 6 DTR è corretto e serve proprio per l'handshake aggiungere anche quello a 7 RTS + 8 CTS non guasta

Interessante il protocollo SCPI, non lo conoscevo, grazie.

Magari se posti la sigla del power supply agilent si può capire meglio come stanno le cose.

Ciao.

e3631a, le propve che sto facendo con questo alimentatore mi serviranno per poi controllare in remoto un tdr.

cmq il db9 sull alimentatore è maschio, dunque ho provato diverse soluzioni: 1. collegare db9 maschio al max232, con 1-4-6 & 7-8 prima cortocircuitati e poi flottanti, collegamento all'alimentatore tramite cavo rs232 femmina-femmina dell'hp, ma non funziona. 2.collegare db9 femmina al max232, con 1-4-6 & 7-8 prima cortocircuitati e poi flottanti, direttamente all'alimentatore, ma non funziona.

qualcuno ne sa venire a capo?

sulla user’s guide dello strumento ho trovato questo paragrafo

DTR/DSR Handshake Protocol
The power supply is configured as a DTE (Data Terminal Equipment)
device and uses the DTR (Data Terminal Ready) and DSR (Data Set Ready)
lines of the RS-232 interface to handshake. The power supply uses the DTR
line to send a hold-off signal. The DTR line must be TRUE before the power
supply will accept data from the interface. When the power supply sets the
DTR line FALSE, the data must cease within 10 characters.
To disable the DTR/DSR handshake, do not connect the DTR line and tie the
DSR line to logic TRUE. If you disable the DTR/DSR handshake, also select a
slower baud rate to ensure that the data is transmitted correctly.
The power supply sets the DTR line FALSE in the following cases:
1 When the power supply’s input buffer is full (when approximately 100
characters have been received), it sets the DTR line FALSE (pin 4 on the
RS-232 connector).

cosa significa? che devo lasciare DTR flottante e DSR a -9V?

l’errore che mi segnala l’alimentatore dice che sovrascrivo il buffer di output, che nel frattempo non si è liberato(non invia i dati ad arduino);
duqneu il problema è che l’output buffer dello strumento non si svuota, non invia dati sulla porta.

potrebbe essere un problema dello sketch che ho scritto?

Stai usando una seriale software e una hardware, questa la usi come debug, giusto. Credo che il problema possa dipendere dalla velocità di 9600, prova con 2400.

To disable the DTR/DSR handshake, do not connect the DTR line and tie the DSR line to logic TRUE.

Per disabilitare DTR/DSR, non collegare DTR e metti DSR a uno logico. TRUE è vero quindi 1 logico, ma non so se corrisponde a -9 o a +9, informati sulla interfaccia hardware RS232.

Poi dice che in caso di DTR/DSR disabilitato devi impostare la velocità bassa.

Il buffer dice che si riempie approsimativamente con 100 caratteri, quindi abbassa il baudrate anche sotto 2400, così dai il tempo alla logica di processare i dati senza che il buffer si riempia.

Ciao.

fatto tutto, collegato il dsr a uno logico (da -6 a -15 per rs232), baud 1200, ma come diceva un mio amico "cristo si è fermato al buffer". non leggo la risposta, o meglio, lo strumento tiene per sè la risposta nell'output buffer ma non la invia sulla seriale

Vedi questo documento http://www.google.it/url?q=http://cp.literature.agilent.com/litweb/pdf/E3631-90011.pdf&sa=U&ei=WeL3UOvrJYGHswaBzoHAAQ&ved=0CBwQFjAB&usg=AFQjCNH1PpZ_JiUhEnw6XXGdNBGalipxXw

C'è un codice sorgente in basic, penso possa essere utile per verificare la validità del tuo codice C++.

Poi se tu potessi fare la query usando la seriale hardware al fine di verificare che l'agilent non sia troppo schizzinoso verso quella software, potresti provare se avessi più di una seriale hardware ho se hai un display connesso ad arduino, ma anche connettendo alcuni led dovresti avere conferma di ricezione della query e comunque anche senza nulla il display E3631 non deve mostrare nessun errore. ah ho supposto che al momento visualizza l'errore, la supposta è giusta? :P

Ciao.

supposti giusto :slight_smile:

ma se il collegamento lo effetto sulla seriale hardware, posso rimanere collegato con la usb ad arduino?

e soprattutto, una volta che mando la query, come leggo la risposta?

ho scritto questo sketch giusto per vedere se lo strumento mi manda qualcosa:

#define baudRate 1200

boolean query = false;
String idn = "";
void setup(){
  pinMode(2,OUTPUT);  
  Serial.begin(baudRate);
  delay(10);
  Serial.println("*RST");
  delay(10);
  Serial.println("*CLS");
  delay(10);
  Serial.println("SYSTEM:REMOTE");
  delay(10);
  Serial.println("*IDN?");
  idn = Serial.readStringUntil('\n');
  idn.trim();
}

void loop(){ 
  if(idn != "" ){
    digitalWrite(2,HIGH);
  }
}

il led dovrebbe accendersi se idn è diverso dalla stringa vuota, dunque upload il codice, stacco la usb, attacco una pila da 9V alla vin, lo strumento va in remoto, ma il led che si dovrebbe accendere, indovinate, rimane inesorabilmente spento

In teoria potresi anche fare il collegamento in paralello ma credo che sia meglio di no, infatti ipotizzavo di usare un led per fare qualcosa del tipo

pseudocode:

result = query(x) if (result == 200) accendi led else spegni led

Ho anche fatto l'ipotesi di avere un display lcd collegato ad arduino così da stampare la risposta.

Si però se la supposizione è giusta ti dovresti accontentare di non vedere nessun messaggio di errore nel display dell'alimentatore, indi per cui si può pensare che effettivamente la RS232 dell'alimentatore è schizzionosa e vuole una connessione seriale hardware. In tal caso il problema rimane e dovrai trovare una alternativa, o una board con più seriali, o un altro atmega connesso tramite seriale all'alimentatore e alla board arduino tramite ISP o i2c.

Ma la seriale 9 pin sul pc non c'è l'hai vero? Nel mio pc recente c'è, se l'avessi potresti collegare PC con alimentatore e scrivere un programmino in basic, c, python o altro per sincerarti che non ci sono problemi con la comunicazione seriale.

Mi hai anticipato.

Nota che println, aggiunge un ritorno carrello \n alla fine della stringa, prova ad usare print.

In pratica invii un reset, un clear, abiliti il remote e *IDN?, che è la query e cosa dovresti avere in risposta?

Ciao.

Ciao.

collegando il pc con l'alimentatore problemi non ce ne sono, perchè usando matlab mi risponde alle query. così al comando *IDN? risponde inviando una stringa con l' "identità" dello strumento: produttore e versione firmware.

il println è "necessario" perchè essendo il linguaggio per comandare lo strumento scpi devo mandare stringhe tutte con NL alla fine

NL sarebbe New line '\n' o cr + lf '\r\n'. Su sistema unix il fine riga è '\n' su windows è '\r\n', può essere che con la connessione seriale tu usi un linguaggio compatibile con windows e non con unix. Se fosse così devi usare print e in coda aggiungere una print '\r\n'.

Il compilatore gcc è stato sviluppato per unix poi è stato portato su windows, e avr-gcc è un build di gcc specifico per architettura AVR, ovviamente il build è diverso per unix/linux da quello per windows. Non ho idea di cosa faccia avr-gcc per windows riguardo al fine riga, penso che lasci decidere al programmatore altrimenti alcuni programmi arduino funzionerebbero solo su windows o su linux dipende quale compilatore è stato usato.

Per sicurezza prova ad usare print("\r\n") dopo ogni comando inviato sempre con print(). Scusa controlla che sia veramente print e non write la funzione da usare.

Ciao.