Advertisement
Guest User

blinken2.rs

a guest
Jan 22nd, 2018
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 5.72 KB | None | 0 0
  1. #![allow(unused_mut)]
  2. #![allow(dead_code)]
  3.  
  4. use std::fs;
  5. use std::process;
  6. use std::io::prelude::*;
  7. use std::thread::sleep;
  8. use std::time::Duration;
  9. use std::error::Error;
  10.  
  11. // Struct defining how GPIO pins will be represented.
  12. // A GPIO pin object will be the pin's number, it's value sysfs handle, and its direction sysfs handle.
  13. struct GPIOPin {
  14.     number: u8,
  15.     value: fs::File,
  16.     direction: fs::File,
  17. }
  18.  
  19. // Function to export a GPIO pin and produce a GPIOPin object for it.
  20. fn gpioload(which:u8) -> GPIOPin {
  21.    
  22.     // where the GPIO export interface files are.
  23.     let exportpath = "/sys/class/gpio/export";
  24.     let unexportpath = "/sys/class/gpio/unexport";
  25.    
  26.     // where the in/out handle will be, when it is created.
  27.     let directionpath = format!("/sys/class/gpio/gpio{}/direction",which.to_string());
  28.  
  29.     // where the value handle will be, when it is created.
  30.     let valuepath = format!("/sys/class/gpio/gpio{}/value",which.to_string());
  31.    
  32.     // open the export files.
  33.     let mut export = match fs::File::create(&exportpath) {
  34.         Err(why) => {
  35.                     // gripe if opening it didn't work.
  36.                     println!("Error opening export: {}",why.description());
  37.                     process::exit(1);
  38.         },
  39.         Ok(file) => file,
  40.     };
  41.     let mut unexport = match fs::File::create(&unexportpath) {
  42.         Err(why) => {
  43.                     println!("Error opening unexport: {}",why.description());
  44.                     process::exit(1);
  45.         },
  46.         Ok(file) => file,
  47.     };
  48.  
  49.     // write the GPIO pin number to the export file.
  50.     match export.write_all(which.to_string().as_bytes()) {
  51.         Err(_why) => {
  52.  
  53.                     // If writing to export throws an error, first check if that's just because we tried to export a pin that's already exported.
  54.                     // If this is the case, unexporting will succeed, at which point we can just re-export it again and keep going.
  55.                     // Otherwise, error out for real.
  56.                     match unexport.write_all(which.to_string().as_bytes()) {
  57.                         Err(why) => {
  58.                                     println!("Error writing to export: {}",why.description());
  59.                                     process::exit(1);
  60.                         },
  61.                         Ok(_) => {
  62.                                 // If we were right about it already being exported (and we're re-exporting it), whine a little to the user about that.
  63.                                 println!("Channel {} already open, continuing anyway.",which.to_string());
  64.                                 match export.write_all(which.to_string().as_bytes()) {
  65.                                     Err(why) => {
  66.                                                 println!("Error writing to export: {}",why.description());
  67.                                                 process::exit(1);
  68.                                     },
  69.                                     Ok(_) => (),
  70.                                 }
  71.                         }
  72.                     }
  73.         }
  74.         Ok(_) => (),
  75.     }
  76.    
  77.     // wait around for 1/10 second for the gpio# directory to appear and populate.
  78.     sleep(Duration::new(0,100_000_000));
  79.    
  80.     // open the in/out handle.
  81.     let mut directionfile = match fs::File::create(&directionpath) {
  82.         Err(why) => {
  83.                     println!("Error opening {}: {}",&directionpath,why.description());
  84.                     process::exit(1);
  85.         },
  86.         Ok(file) => file,
  87.     };
  88.  
  89.     // open the value handle.
  90.     let mut valuefile = match fs::File::create(&valuepath) {
  91.         Err(why) => {
  92.                     println!("Error opening {}: {}",&valuepath,why.description());
  93.                     process::exit(1);
  94.         },
  95.         Ok(file) => file,
  96.     };
  97.  
  98.     // produce a fiddleable GPIO pin object to be assigned to a variable.
  99.     let mut result = GPIOPin {
  100.         number: which,
  101.         value: valuefile,
  102.         direction: directionfile,
  103.     };
  104.     return result;
  105. }
  106.  
  107. // Definition of methods for the GPIOPin object.
  108. // These allow simpler invocation of operations such as changing input/output direction and writing/reading the state.
  109. impl GPIOPin {
  110.  
  111.     // Takes no arguments, produces no outputs, and sets the pin to be an output.
  112.     fn setoutput(&mut self) {
  113.         match self.direction.write_all(b"out") {
  114.             Err(why) => {
  115.                         println!("Error setting pin {} as output: {}",self.number,why.description());
  116.                         process::exit(1);
  117.             },
  118.             Ok(_) => (),
  119.         }
  120.     }
  121.  
  122.     // Takes no arguments, produces no outputs, and sets the pin to be an input.
  123.     fn setinput(&mut self) {
  124.         match self.direction.write_all(b"in") {
  125.             Err(why) => {
  126.                         println!("Error setting pin {} as input: {}",self.number,why.description());
  127.                         process::exit(1);
  128.             },
  129.             Ok(_) => (),
  130.         }
  131.     }
  132.  
  133.     // Takes a boolean argument and sets the pin the the corresponding state, returning nothing.
  134.     fn output(&mut self,val:bool) {
  135.         if val {
  136.             match self.value.write_all(b"1") {
  137.                 Err(why) => {
  138.                             println!("Error setting state of pin {}: {}",self.number,why.description());
  139.                             process::exit(1);
  140.                 },
  141.                 Ok(_) => (),
  142.             }
  143.         } else {
  144.             match self.value.write_all(b"0") {
  145.                 Err(why) => {
  146.                             println!("Error setting state of pin {}: {}",self.number,why.description());
  147.                             process::exit(1);
  148.                 },
  149.                 Ok(_) => (),
  150.             }
  151.         }
  152.     }
  153.  
  154.     // Takes no arguments, produces a boolean value corresponding to the state of the pin.
  155.     fn input(&mut self) -> bool {
  156.         let mut statebuffer:Vec<u8> = vec![];
  157.         match self.value.read_to_end(&mut statebuffer) {
  158.             Err(why) => {
  159.                         println!("Error getting state of pin {}: {}",self.number,why.description());
  160.                         process::exit(1);
  161.             },
  162.             Ok(_) => (),
  163.         }
  164.         if statebuffer[0] == 49 {
  165.             return true;
  166.         } else if statebuffer[0] == 48 {
  167.             return false;
  168.         } else {
  169.             println!("Error getting state of pin {}: Got unknown symbol {}",self.number,statebuffer[0]);
  170.             process::exit(1);
  171.         }
  172.     }  
  173. }
  174.  
  175.  
  176. fn main() {
  177.  
  178.     // set the time between light state changes (1/2 flash period).
  179.     let wait = Duration::new(0,500_000_000);
  180.  
  181.     // load the GPIO pin to use.
  182.     let mut gpio18 = gpioload(18);
  183.  
  184.     // set the GPIO pin as an output.
  185.     gpio18.setoutput();
  186.  
  187.     // sit here and blink until either the program is interrupted or the stars die.
  188.     loop {
  189.  
  190.         // blink on, wait.
  191.         gpio18.output(true);
  192.         println!("on");
  193.         sleep(wait);
  194.  
  195.         // blink off, wait.
  196.         gpio18.output(false);
  197.         println!("off");
  198.         sleep(wait);
  199.     }
  200. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement