//! The following wiring is assumed:
//! - SDA => GPIO1
//! - SCL => GPIO2
// We output data on acceleration along the x axis and temperature
#![no_std]
#![no_main]
// Libraries
use esp32c3_hal::{
clock::ClockControl,
interrupt,
peripherals::{self, Peripherals, TIMG0, TIMG1,I2C0},
prelude::*,
gpio::{ Gpio5, Output, PushPull,IO},
riscv,
i2c::I2C,
timer::{Timer, Timer0, TimerGroup},
Rtc,
Delay,
};
use esp_backtrace as _;
use esp_println::println;
use core::cell::RefCell;
use critical_section::Mutex;
// Static variables
static TIMER0: Mutex<RefCell<Option<Timer<Timer0<TIMG0>>>>> = Mutex::new(RefCell::new(None));
static TIMER1: Mutex<RefCell<Option<Timer<Timer0<TIMG1>>>>> = Mutex::new(RefCell::new(None));
static i_2_c: Mutex<RefCell<Option<I2C<I2C0>>>> = Mutex::new(RefCell::new(None));
//main
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let mut system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
let timer_group0 = TimerGroup::new(
peripherals.TIMG0,
&clocks,
&mut system.peripheral_clock_control,
);
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(
peripherals.TIMG1,
&clocks,
&mut system.peripheral_clock_control,
);
let mut wdt1 = timer_group1.wdt;
// Disable watchdog timers
rtc.swd.disable();
rtc.rwdt.disable();
wdt0.disable();
wdt1.disable();
// Begining of the project
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
println!(" (Project is begining!!!)");
// Create a new peripheral object with the described wiring
// and standard I2C clock speed
let mut i2c = I2C::new(
peripherals.I2C0,
io.pins.gpio1,
io.pins.gpio2,
50u32.kHz(),
&mut system.peripheral_clock_control,
&clocks,
);
// Enable iterrapts
interrupt::enable(
peripherals::Interrupt::TG0_T0_LEVEL,
interrupt::Priority::Priority1,
)
.unwrap();
//Init timer
let mut timer0 = timer_group0.timer0;
// Start timer on 10 sec
timer0.start(10000u64.millis());
timer0.listen();
critical_section::with(|cs| {
TIMER0.borrow_ref_mut(cs).replace(timer0);
});
// Write comands of the sensor SCD30
let mut cmnd_trigger_continuous: [u8;5] = [0xC2, 0, 0x10, 0, 0];
let mut cmnd_set_interval: [u8;5] = [0xC2,0x46, 0, 0,0x0A];
let cmnd_get_temperature_offset: [u8;3] = [0xC2, 0x54, 0x03];
let cmnd_set_temperature_offset: [u8;5] = [0xC2, 0x54, 0x03, 0, 0 ];
let mut cmnd_set_altitude: [u8;5] = [0xC2, 0x51, 0x02, 0, 0 ];
// Set measurement interval
i2c.write(0x61, &cmnd_set_interval);
// Trigger continuous measurement with optional ambient pressure compensation
i2c.write(0x61, &cmnd_trigger_continuous);
// Place the I2C to global variable
critical_section::with(|cs| i_2_c.borrow_ref_mut(cs).replace(i2c));
// Unsafe
unsafe {
riscv::interrupt::enable();
}
// Loop
loop {}
}
#[interrupt]
fn TG0_T0_LEVEL() {
critical_section::with(|cs| {
esp_println::println!("Interrupt");
// Enabling the delay function
let peripherals = Peripherals::take();
let mut system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let mut delay = Delay::new(&clocks);
// Unnpackage the timer
let mut timer0 = TIMER0.borrow_ref_mut(cs);
let timer0 = timer0.as_mut().unwrap();
// The sensor data
let mut CO2: f32;
let mut temperature = 0.0;
let mut humidity = 0.0;
// Write comands of the sensor SCD30
let mut cmnd_trigger_continuous: [u8;5] = [0xC2, 0, 0x10, 0, 0];
let mut cmnd_set_interval: [u8;5] = [0xC2,0x46, 0, 0,0x0A];
let cmnd_get_redy_status: [u8;3] = [0xC2, 0x02, 0x02]; // Note that the read header should be send with a delay of > 3ms following the write sequence.
let cmnd_read_mesurment: [u8;3] = [0xC2, 0x03, 0x00]; //Note that the read header should be send with a delay of > 3ms following the write sequence
// Arrays of unsigned numbers 1 byte for data
let mut data = [0u8; 12];
let mut status = [0u8; 2];
let mut temperature_circuit = [0u8; 3];
// Unpackage the i2c
let mut i2c = i_2_c.borrow_ref_mut(cs);
let mut i2c = i2c.as_mut().unwrap();
// Requesting the status of data
i2c.write(0x61, &cmnd_get_redy_status);
delay.delay_ms(4u32);
i2c.read(0x61, &mut status).ok();
// Receive the data
if status[1] == 1 {
// Read measurement
i2c.write(0x61, &cmnd_read_mesurment);
delay.delay_ms(4u32);
// Requesting and reading data
i2c.read(0x61, &mut data).ok();
// Parsing CO2 data
CO2 = parsing_data(&data[0], &data[1], &data[2], &data[3] );
// Parsing temperature data
temperature = parsing_data(&data[4], &data[5], &data[6], &data[7] );
// Parsing humidity data
humidity = parsing_data(&data[8], &data[9], &data[10], &data[11] );
// Data output to the console
print_data( &CO2, &temperature, &humidity) ;
}
//Restart
timer0.clear_interrupt();
timer0.start(10000u64.millis());
});
}
// Functions
fn parsing_data( mmsb: &u8, mlsb: &u8, lmsb: &u8, llsb: &u8 ) -> f32 {
// Init parts of the message
let zero_byte: i32 ;
let first_byte: i32 ;
let second_byte: i32 ;
let third_byte: i32 ;
//
zero_byte = (*mmsb as i32) << 24;
first_byte = (*mlsb as i32) << 16;
second_byte = (*lmsb as i32) << 8;
third_byte = *llsb as i32;
// Return
(zero_byte | first_byte | second_byte | third_byte) as f32
}
fn print_data( CO2: &f32, temperature: &f32, humidity: &f32) {
// Data output to the console
println!(" Measurement:");
println!(" CO2 = {} ",CO2);
println!(" Temperature = {} ",temperature);
println!(" Humidity = {} ",humidity);
}