prologix_gpib_ethernet_controller_manager/
gpib_controller.rs1use std::io::{Read, Write};
2use std::net::{IpAddr, SocketAddr, TcpStream};
3use std::time::Duration;
4use crate::errors::GpibControllerError;
5
6const BUFFER_SIZE: usize = 4096;
7
8pub struct GpibController{
9 tcp_stream: TcpStream,
11 current_gpib_addr: u8,
17
18 buffer: [u8; BUFFER_SIZE]
20}
21
22impl GpibController{
23 pub fn send_raw_data(&mut self, message: &str) -> Result<usize, GpibControllerError>{
24 self.tcp_stream.write(message.as_ref()).map_err(|e| { GpibControllerError::TcpIoError(e)})
25 }
26
27 pub fn gpib_send_to_addr(&mut self, message: &str, gpib_addr: u8) -> Result<usize, GpibControllerError>{
28 self.set_address(gpib_addr)?;
29 self.send_raw_data(message)
30 }
31
32 pub fn read_data(&mut self) -> Result<&str, GpibControllerError>{
33 let bytes_received = self.tcp_stream.read(&mut self.buffer).map_err(|e| { GpibControllerError::TcpIoError(e)})?;
34 if bytes_received > BUFFER_SIZE{
35 Err(GpibControllerError::BufferTooSmall) } else {
37 Ok(std::str::from_utf8(&self.buffer[0..bytes_received])?)
38 }
39 }
40
41 pub fn try_new_from(ip_addr: IpAddr) -> Result<GpibController, GpibControllerError>{
42 let sock_addr: SocketAddr = SocketAddr::from((ip_addr, 1234u16));
43 let temp_tcp_stream = TcpStream::connect_timeout(&sock_addr, Duration::from_millis(1500))
44 .map_err(|e| { GpibControllerError::TcpIoError(e)})?;
45 temp_tcp_stream.set_write_timeout(Some(Duration::from_millis(1500)))?;
46 temp_tcp_stream.set_read_timeout(Some(Duration::from_millis(1500)))?;
47 let mut temp_controller = GpibController{
48 tcp_stream: temp_tcp_stream,
49 current_gpib_addr: 255,
50 buffer: [0u8; BUFFER_SIZE]
51 };
52
53 temp_controller.send_raw_data("++addr\n")?;
54
55 let addr: u8 = temp_controller.read_data()?.trim().parse()?;
56 temp_controller.current_gpib_addr = addr;
57 temp_controller.send_raw_data("++auto 1\n")?;
58 temp_controller.send_raw_data("++mode 1\n")?;
59 Ok(temp_controller)
60 }
61
62 pub fn set_address(&mut self, address: u8) -> Result<(), GpibControllerError>{
63 if self.current_gpib_addr == address{
64 return Ok(());
65 }
66 let mut temp_message: String = String::from("++addr ");
67 temp_message.push_str(&address.to_string());
68 self.send_raw_data(&temp_message)?;
69 self.current_gpib_addr = address;
70
71 Ok(())
72 }
73
74 pub fn gpib_send_and_listen_wrapper(&mut self, message: &str, gpib_address: u8, ignore_response: bool) -> Result<Option<String>, GpibControllerError>{
75 self.gpib_send_to_addr(message, gpib_address)?;
76
77 if ignore_response {
78 return Ok(None)
79 }
80 match self.read_data() {
81 Ok(s) => {
82 Ok(Some(s.to_string()))
83 }
84 Err(GpibControllerError::TcpIoError(_)) => {
85 Ok(None)
86 }
87 Err(e) => {
88 Err(e)
89 }
90 }
91 }
92
93}
94
95#[cfg(test)]
96mod gpib_controller_tests {
97 use super::*;
98
99 #[test]
100 fn test_gpib_controller() {
101 let mut controller: GpibController = GpibController::try_new_from(IpAddr::from([192,168,1,82])).unwrap();
102 controller.gpib_send_to_addr("*IDN?\n", 16).unwrap();
103 println!("{}", controller.read_data().unwrap())
104 }
105}
106
107
108