1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! GPS data fetcher for mechatronics
//! ## EXAMPLES
//! ```
//!     let mut gps = GpsInfo::new();
//!     gps.get_data();
//! ```
//! ## Important info:
//! ```
//! Reads only GPGGA
//! ```



use rpi_embedded::uart::{Parity, Uart};
use std::thread;
use std::time::{Duration};


//Simple test checking if GPS is GPGGA

#[cfg(test)]
mod tests{
   use super::*;
   
   #[test]
    fn isitgpgga() {
        let mut gps1 = GpsInfo::new();
        let input = "$GPGGA";
        assert_eq!(true, gps1.isgpgga(input));
        
    }
}

enum BaudRate {
    A,
    B,
}
 
impl BaudRate{
    fn value(&self) -> u32{
        match *self {
            BaudRate::A => 9600,
            BaudRate::B => 115200,
        }
    }
}

struct GpsInfo{
    identifier: String,
    time: f64,
    latitude: f64,
    longitude: f64,
    ns: String,
    ew: String,
    sat_num: u16,
    altitude: f64,
    uart_serial: Uart,
    uart_baudrate: BaudRate,

}


impl GpsInfo {
    fn new() -> GpsInfo{

        println!("starting UART");

        let baudrate = BaudRate::A;

        let mut out = GpsInfo {
            identifier: "".to_string(),
            time: 0.0,
            latitude: 0.0,
            longitude: 0.0,
            ns: "".to_string(),
            ew: "".to_string(),
            sat_num: 0,
            altitude: 0.0,            
            uart_serial: Uart::new(baudrate.value(), Parity::None, 8, 1).expect("Failed to init uart serial"),
            uart_baudrate: BaudRate::A,
        };

        println!("starting UART");
        out.uart_serial.set_read_mode(1, Duration::default()).expect("Failed to set uart read mode");

        out

    }

    fn get_data(&mut self){

        loop{
        
            let res = self.uart_serial.read_line().expect("Fail in uart read");
            let mut v: Vec<&str> = res.split(',').collect();
            //println!("{}", v[0]);
            thread::sleep(Duration::from_millis(100));

            if self.isgpgga(v[0]){
                self.turn_vales(&mut v);
            }


        }
    }

    fn isgpgga(&mut self, data: &str) -> bool{
        let gppa: bool;
        if data.trim() == "$GPGGA"{
            gppa = true;
        }
        else{
            gppa = false;
        }
        return gppa;

    }


    //fn turn_vales(&mut self, data: &mut [&str]){
    fn turn_vales(&mut self, data: &mut Vec<&str>){
        self.identifier = data[0].to_string();
        self.time = data[1].parse::<f64>().unwrap();
        self.latitude = data[2].parse::<f64>().unwrap();
        self.longitude = data[4].parse::<f64>().unwrap();
        self.ns = data[3].to_string();
        self.ew = data[5].to_string();
        self.sat_num = data[7].parse::<u16>().unwrap();
        self.altitude = data[9].parse::<f64>().unwrap();
        println!("Ident:{} Time:{} Lat:{} Long:{} Alt:{} satnum:{} N/S:{} EW/:{}", self.identifier, self.time,self.latitude, self.longitude, self.altitude, self.sat_num, self.ns, self.ew);

    }
}


fn main() {
    let mut gps = GpsInfo::new();
    gps.get_data();
}