arduino_threads/
arduino_threads.rs1extern crate std_semaphore;
2extern crate serial;
3extern crate robust_arduino_serial;
4use std::io::ErrorKind;
5use std::env;
6use std::time::Duration;
7use std::thread;
8use std::sync::{Arc, Mutex};
9use std::sync::mpsc;
10use std_semaphore::Semaphore;
11use serial::prelude::*;
12use robust_arduino_serial::*;
13
14const SETTINGS: serial::PortSettings = serial::PortSettings {
17 baud_rate: serial::Baud115200,
18 char_size: serial::Bits8,
19 parity: serial::ParityNone,
20 stop_bits: serial::Stop1,
21 flow_control: serial::FlowNone,
22};
23
24
25fn main() {
26
27 let args: Vec<String> = env::args().skip(1).collect();
28
29 if args.len() < 1
30 {
31 panic!("Please provide a serial port as argument (ex: /dev/ttyACM0)");
32 }
33 let serial_port = &args[0];
34
35 println!("Opening port: {:?}", serial_port);
36 let mut port = serial::open(&serial_port).unwrap();
37 port.configure(&SETTINGS).unwrap();
38 port.set_timeout(Duration::from_millis(1)).unwrap();
40
41 loop
42 {
43 println!("Waiting for Arduino...");
44 write_order(&mut port, Order::HELLO).unwrap();
45 let received_order = match read_i8(&mut port) {
46 Ok(order) => Order::from_i8(order).unwrap(),
47 Err(ref e) if e.kind() == ErrorKind::TimedOut => {
48 thread::sleep(Duration::from_secs(2));
50 continue
51 }
52 Err(e) => {
53 panic!("An error occured reading serial port: {}", e)
54 }
55
56 };
57
58 if received_order == Order::ALREADY_CONNECTED
59 {
60 break;
61 }
62 thread::sleep(Duration::from_secs(1));
63 }
64
65 println!("Connected to Arduino");
66
67 let (command_sender, command_receiver) = mpsc::channel();
69 let command_queue = mpsc::Sender::clone(&command_sender);
70
71 let serial_arc = Arc::new(Mutex::new(port));
73 let serial_command = serial_arc.clone();
74
75 let exit_event = false;
77 let exit_arc = Arc::new(Mutex::new(exit_event));
79 let exit_listener = exit_arc.clone();
80 let exit_command = exit_arc.clone();
81
82 let n_allowed_messages = 2;
86 let semaphore = Arc::new(Semaphore::new(n_allowed_messages));
87 let semaphore_command = semaphore.clone();
88
89 let mut threads = vec![];
90
91 let command_thread = thread::spawn(move || {
94 let mut exit = false;
95 while !exit
96 {
97 semaphore.acquire();
100 let (order, num) = command_receiver.recv().unwrap();
101
102 println!("Sending: {:?}, {}", order, num);
103
104 let mut buffer = serial_command.lock().unwrap();
106
107 write_order(&mut *buffer, order).unwrap();
108 match order {
109 Order::MOTOR => write_i8(&mut *buffer, num as i8).unwrap(),
110 Order::SERVO => write_i16(&mut *buffer, num as i16).unwrap(),
111 _ => 0 };
113 exit = *exit_command.lock().unwrap();
114 }
115 println!("Command Thread exiting...");
116 });
117
118 threads.push(command_thread);
119
120 let listener_thread = thread::spawn(move || {
123
124 let mut exit = false;
125 let mut wait = false;
126 while !exit
127 {
128 if wait
130 {
131 thread::sleep(Duration::from_millis(100));
132 }
133
134 let mut buffer = serial_arc.lock().unwrap();
136
137 let received_order = match read_i8(&mut *buffer) {
139 Ok(order) => Order::from_i8(order).unwrap(),
140 Err(_) => {
141 wait = true;
142 continue
143 }
144
145 };
146 wait = false;
147
148 println!("Received: {:?}", received_order);
149
150 match received_order {
151 Order::RECEIVED => semaphore_command.release(),
152 _ => ()
153 }
154
155 exit = *exit_listener.lock().unwrap();
156 }
157 println!("Listener Thread exiting...");
158 });
159
160 threads.push(listener_thread);
161
162 thread::sleep(Duration::from_secs(1));
163 command_queue.send((Order::MOTOR, 42_i32)).unwrap();
165 command_queue.send((Order::SERVO, 120_i32)).unwrap();
166
167 thread::sleep(Duration::from_secs(2));
169
170 command_queue.send((Order::MOTOR, 0_i32)).unwrap();
172
173
174 {
176 *exit_arc.lock().unwrap() = true;
177 }
178
179 command_queue.send((Order::HELLO, 0_i32)).unwrap();
181
182 for t in threads
183 {
184 t.join().unwrap();
185 }
186}