Project #29 - DFRobot - RHT And MQ - Mk13
https://www.donluc.com/?p=3931
#DonLucElectronics #DonLuc #DFRobot #BLESensorBeacon #AmbientLight #SoilMoisture #SHT40 #FireBeetle2ESP32E #EEPROM #RTC #SD #Display #Adafruit #ESP32 #IoT #Arduino #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant
Humidity and Temperature Sensor - RHT03
The RHT03 (also known by DHT-22) is a low cost humidity and temperature sensor with a single wire digital interface. The sensor is calibrated and doesn't require extra components so you can get right to measuring relative humidity and temperature.
MQ Series Gas Sensor
The description of each MQ series gas sensor and its uses that follows will be helpful to anybody who wants to understand the foundations of gas sensing technology. The MQ Series Gas Sensor is a revolutionary technology designed for the detection of combustible gases, such as those used in industry and manufacturing. MQ sensor working principle involves detecting changes in electrical conductivity when specific gases come into contact with the sensor's sensing element. This variety of semiconductor gas sensors makes it possible to measure concentrations of gasses such as alcohol, methane, propane, butane, and carbon monoxide.
Pololu Carrier for MQ Gas Sensors
This carrier board is designed to work with any of the MQ-series gas sensors, simplifying the interface from 6 to 3 pins—ground, power and analog voltage output +3-5 Volt. This board has two mounting holes and provides convenient pads for mounting the gas sensor’s required sensitivity-setting resistor.
DL2405Mk03
1 x DFRobot FireBeetle 2 ESP32-E
1 x Adafruit SHARP Memory Display
1 x Adafruit MicroSD card breakout board+
1 x MicroSD 16 GB
1 x Adafruit DS3231 Precision RTC FeatherWing - RTC
1 x Battery CR1220
4 x Pololu Carrier for MQ Gas Sensors
1 x SparkFun Hydrogen Gas Sensor - MQ-8
1 x 4.7K Ohm
1 x Pololu Carbon Monoxide & Flammable Gas Sensor - MQ-9
1 x 22k Ohm
1 x SparkFun Carbon Monoxide Gas Sensor - MQ-7
1 x 10K Ohm
1 x SparkFun Alcohol Gas Sensor - MQ-3
1 x 220k Ohm
1 x Temperature and Humidity Sensor - RHT03
1 x PIR Motion Sensor (JST)
1 x Switch
1 x 1K Ohm
1 x Gravity: Analog Soil Moisture Sensor
1 x Gravity: Analog Ambient Light Sensor
1 x Fermion: SHT40 Temperature & Humidity Sensor
3 x Fermion: BLE Sensor Beacon
3 x CR2032 Coin Cell Battery
1 x 1 x Lithium Ion Battery - 1000mAh
1 x Green LED
1 x Slide Switch
1 x SparkFun Serial Basic Breakout - CH340G
1 x SparkFun Cerberus USB Cable
1 x USB 3.1 Cable A to C
DFRobot FireBeetle 2 ESP32-E
LED - 2
DSCK - 4
DMOSI - 16
DSS - 17
SCK - 22
MOSI - 23
MISO - 19
CS - 13
SCL - 21
SDA - 22
LED - 14
RHT - 25
PIR - 26
SWI - 3
MQ8 = A0
MQ9 = A1
MQ7 = A2
MQ3 = A3
VIN - +3.3V
GND - GND
DL2405Mk03p.ino
/****** Don Luc Electronics © ******
Software Version Information
Project #29 - DFRobot - RHT And MQ - Mk13
29-13
DL2404Mk03p.ino
1 x DFRobot FireBeetle 2 ESP32-E
1 x Adafruit SHARP Memory Display
1 x Adafruit MicroSD card breakout board+
1 x MicroSD 16 GB
1 x Adafruit DS3231 Precision RTC FeatherWing - RTC
1 x Battery CR1220
4 x Pololu Carrier for MQ Gas Sensors
1 x SparkFun Hydrogen Gas Sensor - MQ-8
1 x 4.7K Ohm
1 x Pololu Carbon Monoxide & Flammable Gas Sensor - MQ-9
1 x 22k Ohm
1 x SparkFun Carbon Monoxide Gas Sensor - MQ-7
1 x 10K Ohm
1 x SparkFun Alcohol Gas Sensor - MQ-3
1 x 220k Ohm
1 x Temperature and Humidity Sensor - RHT03
1 x PIR Motion Sensor (JST)
1 x Switch
1 x 1K Ohm
1 x Gravity: Analog Soil Moisture Sensor
1 x Gravity: Analog Ambient Light Sensor
1 x Fermion: SHT40 Temperature & Humidity Sensor
3 x Fermion: BLE Sensor Beacon
3 x CR2032 Coin Cell Battery
1 x 1 x Lithium Ion Battery - 1000mAh
1 x Green LED
1 x SparkFun Serial Basic Breakout - CH340G
1 x SparkFun Cerberus USB Cable
1 x USB 3.1 Cable A to C
*/
// Include the Library Code
// EEPROM Library to Read and Write EEPROM
// with Unique ID for Unit
#include "EEPROM.h"
// Wire
#include <Wire.h>
// Arduino
#include <Arduino.h>
// BLE Device
#include <BLEDevice.h>
// BLE Utils
#include <BLEUtils.h>
// BLEScan
#include <BLEScan.h>
// BLE Advertised Device
#include <BLEAdvertisedDevice.h>
// BLE Eddystone URL
#include <BLEEddystoneURL.h>
// BLE Eddystone TLM
#include <BLEEddystoneTLM.h>
// BLE Beacon
#include <BLEBeacon.h>
// DS3231 RTC Date and Time
#include <RTClib.h>
// SD Card
#include "FS.h"
#include "SD.h"
#include "SPI.h"
// SHARP Memory Display
#include <Adafruit_SharpMem.h>
#include <Adafruit_GFX.h>
// RHT Temperature and Humidity Sensor
#include <SparkFun_RHT03.h>
// ENDIAN_CHANGE
#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00) >> 8) + (((x)&0xFF) << 8))
// DS3231 RTC Date and Time
RTC_DS3231 rtc;
String sDate;
String sTime;
// MicroSD Card
const int chipSelect = 13;
String zzzzzz = "";
// SHARP Memory Display
#define SHARP_SCK 4
#define SHARP_MOSI 16
#define SHARP_SS 17
// Set the size of the display here, e.g. 144x168!
Adafruit_SharpMem display(SHARP_SCK, SHARP_MOSI, SHARP_SS, 144, 168);
// The currently-available SHARP Memory Display (144x168 pixels)
// requires > 4K of microcontroller RAM; it WILL NOT WORK on Arduino Uno
// or other <4K "classic" devices.
#define BLACK 0
#define WHITE 1
// LED Green
int iLEDGreen = 2;
// Define LED
int iLED = 14;
// Fermion: SHT40 Temperature & Humidity Sensor
// Temperature
float TemperatureData;
float Temperature;
// Humidity
float HumidityData;
float Humidity;
// Gravity: Analog Ambient Light Sensor
float Sensor_Data;
// SData => 1~6000 Lux
float SData;
// Gravity: Analog Soil Moisture Sensor
float SensorSM;
float SDataSM;
// In seconds
int scanTime = 5;
// BLE Scan
BLEScan *pBLEScan;
// RHT Temperature and Humidity Sensor
// RHT03 data pin Digital 25
const int RHT03_DATA_PIN = 25;
// This creates a RTH03 object, which we'll use to interact with the sensor
RHT03 rht;
float latestHumidity;
float latestTempC;
// Gas Sensors MQ
// Hydrogen Gas Sensor - MQ-8
int iMQ8 = A0;
int iMQ8Raw = 0;
int iMQ8ppm = 0;
// Two points are taken from the curve in datasheet.
// With these two points, a line is formed which is
// "approximately equivalent" to the original curve.
float H2Curve[3] = {2.3, 0.93,-1.44};
// Carbon Monoxide & Flammable Gas Sensor - MQ-9
int iMQ9 = A1;
int iMQ9Raw = 0;
int iMQ9ppm = 0;
// Carbon Monoxide Gas Sensor - MQ-7
int iMQ7 = A2;
int iMQ7Raw = 0;
int iMQ7ppm = 0;
// Alcohol Gas Sensor - MQ-3
int iMQ3 = A3;
int iMQ3Raw = 0;
int iMQ3ppm = 0;
// PIR Motion
// Motion detector
const int iMotion = 26;
// Proximity
int proximity = LOW;
String Det = "";
// Switch
int iSwitch = 3;
// Variable for reading the Switch status
int iSwitchState = 0;
// My Advertised Device Callbacks
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
// onResult
void onResult(BLEAdvertisedDevice advertisedDevice)
{
// Advertised Device
if (advertisedDevice.haveName())
{
// Name: Fermion: Sensor Beacon
if(String(advertisedDevice.getName().c_str()) == "SHT40"){
// strManufacturerData
std::string strManufacturerData = advertisedDevice.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
// strManufacturerData.length
for (int i = 0; i < strManufacturerData.length(); i++)
{
// cManufacturerData[i]
cManufacturerData[i];
}
// TemperatureData
TemperatureData = int(cManufacturerData[2]<<8 | cManufacturerData[3]);
// HumidityData
HumidityData = int(cManufacturerData[5]<<8 | cManufacturerData[6]);
}
// Name: Fermion: Sensor Beacon
if(String(advertisedDevice.getName().c_str()) == "Fermion: Sensor Beacon"){
// strManufacturerData
std::string strManufacturerData = advertisedDevice.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
// strManufacturerData.length
for (int i = 0; i < strManufacturerData.length(); i++)
{
// cManufacturerData[i]
cManufacturerData[i];
}
// Sensor_Data
Sensor_Data = int(cManufacturerData[2]<<8 | cManufacturerData[3]);
}
// Name: Fermion: Sensor Beacon
if(String(advertisedDevice.getName().c_str()) == "Soil Moisture"){
// strManufacturerData
std::string strManufacturerData = advertisedDevice.getManufacturerData();
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);
// strManufacturerData.length
for (int i = 0; i < strManufacturerData.length(); i++)
{
// cManufacturerData[i]
cManufacturerData[i];
}
// SensorSM
SensorSM = int(cManufacturerData[2]<<8 | cManufacturerData[3]);
}
}
}
};
// EEPROM Unique ID Information
#define EEPROM_SIZE 64
String uid = "";
// Software Version Information
String sver = "29-13";
void loop() {
// DS3231 RTC Date and Time
isRTC();
// RHT Temperature and Humidity Sensor
isRHT03();
// Gas Sensors MQ
isGasSensor();
// isPIR Motion
isPIR();
// ScanResults
isBLEScanResults();
// Fermion: SHT40 Temperature & Humidity Sensor
isSHT40();
// Gravity: Analog Ambient Light Sensor
isAmbientLight();
// Soil Moisture
isSoilMoisture();
// Delay 4 Second
delay(4000);
// Read the state of the Switch value
iSwitchState = digitalRead(iSwitch);
// The Switch is HIGH:
if (iSwitchState == HIGH) {
// Display Date, Time, Temperature, Humidity
isDisplayDTTH();
} else {
// Display Temperature, Humidity, MQ, PIR
isDisplayDTMQPIR();
}
// MicroSD Card
isSD();
// iLED HIGH
digitalWrite(iLED, HIGH );
// Delay 1 Second
delay(1000);
}
getAmbientLight.ino
// Gravity: Analog Ambient Light Sensor
// Ambient Light
void isAmbientLight(){
// Analog Ambient Light Sensor
// SData => 1~6000 Lux
SData = map(Sensor_Data, 1, 3000, 1, 6000);
}
getBLEScan.ino
// getBLEScan
// Setup BLE Scan
void isSetupBLEScan(){
// BLE Device
BLEDevice::init("");
// Create new scan
pBLEScan = BLEDevice::getScan();
// Set Advertised Device Callbacks
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
// Active scan uses more power, but get results faster
pBLEScan->setActiveScan(true);
// Set Interval
pBLEScan->setInterval(100);
// Less or equal setInterval value
pBLEScan->setWindow(99);
}
// BLE Scan Results
void isBLEScanResults(){
// Put your main code here, to run repeatedly:
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
// Delete results fromBLEScan buffer to release memory
pBLEScan->clearResults();
}
getDisplay.ino
// SHARP Memory Display
// SHARP Memory Display - UID
void isDisplayUID() {
// Text Display
// Clear Display
display.clearDisplay();
display.setRotation(4);
display.setTextSize(3);
display.setTextColor(BLACK);
// Don Luc Electronics
display.setCursor(0,10);
display.println( "Don Luc" );
display.setTextSize(2);
display.setCursor(0,40);
display.println( "Electronics" );
// Version
//display.setTextSize(3);
display.setCursor(0,70);
display.println( "Version" );
//display.setTextSize(2);
display.setCursor(0,95);
display.println( sver );
// EEPROM
display.setCursor(0,120);
display.println( "EEPROM" );
display.setCursor(0,140);
display.println( uid );
// Refresh
display.refresh();
delay( 100 );
}
// Display Date, Time, Temperature, Humidity, Ambient Light, Soil Moisture
void isDisplayDTTH() {
// Text Display Date
// Clear Display
display.clearDisplay();
display.setRotation(4);
display.setTextSize(2);
display.setTextColor(BLACK);
// Date
display.setCursor(0,5);
display.println( sDate );
// Time
display.setCursor(0,30);
display.println( sTime );
// Temperature
display.setCursor(0,55);
display.print( Temperature );
display.println( "C" );
// Humidity
display.setCursor(0,80);
display.print( Humidity );
display.println( "%" );
// Lux
display.setCursor(0,105);
display.println( SData );
// Soil Moisture
display.setCursor(0,130);
display.println( SDataSM );
// Refresh
display.refresh();
delay( 100 );
}
// Display Temperature, Humidity, MQ, PIR
void isDisplayDTMQPIR() {
// Text Display Date
// Clear Display
display.clearDisplay();
display.setRotation(4);
display.setTextSize(2);
display.setTextColor(BLACK);
// Temperature
display.setCursor(0,5);
display.print( latestTempC );
display.println( "C" );
// Humidity
display.setCursor(0,30);
display.print( latestHumidity );
display.println( "%" );
// MQ-8
display.setCursor(0,55);
display.print( "MQ-8: " );
display.print( iMQ8ppm );
display.println( " PPM" );
// MQ-9
display.setCursor(0,80);
display.print( "MQ-9: " );
display.print( iMQ9ppm );
display.println( " PPM" );
// MQ-7
display.setCursor(0,105);
display.print( "MQ-7: " );
display.print( iMQ7ppm );
display.println( " PPM" );
// MQ-3
display.setCursor(0,130);
display.print( "MQ-3: " );
display.print( iMQ3ppm );
display.println( "%" );
// PIR
display.setCursor(0,145);
display.println( Det );
// Refresh
display.refresh();
delay( 100 );
}
getEEPROM.ino
// EEPROM
// isUID EEPROM Unique ID
void isUID()
{
// Is Unit ID
uid = "";
for (int x = 0; x < 7; x++)
{
uid = uid + char(EEPROM.read(x));
}
}
getGasSensorMQ.ino
// Gas Sensors MQ
// Gas Sensor
void isGasSensor() {
// Read in analog value from each gas sensors
// Hydrogen Gas Sensor - MQ-8
iMQ8Raw = analogRead( iMQ8 );
// Carbon Monoxide & Flammable Gas Sensor - MQ-9
iMQ9Raw = analogRead( iMQ9 );
// Carbon Monoxide Gas Sensor - MQ-7
iMQ7Raw = analogRead( iMQ7 );
// Alcohol Gas Sensor - MQ-3
iMQ3Raw = analogRead( iMQ3 );
// Caclulate the PPM of each gas sensors
// Hydrogen Gas Sensor - MQ-8
iMQ8ppm = isMQ8( iMQ8Raw );
// Carbon Monoxide & Flammable Gas Sensor - MQ-9
iMQ9ppm = isMQ9( iMQ9Raw );
// Carbon Monoxide Gas Sensor - MQ-7
iMQ7ppm = isMQ7( iMQ7Raw );
// Alcohol Gas Sensor - MQ-3
iMQ3ppm = isMQ3( iMQ3Raw );
}
// Hydrogen Gas Sensor - MQ-8 - PPM
int isMQ8(double rawValue) {
// RvRo
double RvRo = rawValue * (3.3 / 4095);
double ppm = 3.027*exp(1.0698*( RvRo ));
return ppm;
//return (pow(4.7,( ((log(RvRo)-H2Curve[1])/H2Curve[2]) + H2Curve[0])));
}
// Carbon Monoxide & Flammable Gas Sensor - MQ-9
int isMQ9(double rawValue) {
double RvRo = rawValue * 3.3 / 4095;
double ppm = 3.027*exp(1.0698*( RvRo ));
return ppm;
}
// Carbon Monoxide Gas Sensor - MQ-7
int isMQ7(double rawValue) {
double RvRo = rawValue * 3.3 / 4095;
double ppm = 3.027*exp(1.0698*( RvRo ));
return ppm;
}
// Alcohol Gas Sensor - MQ-3
int isMQ3(double rawValue) {
double RvRo = rawValue * 3.3 / 4095;
double bac = RvRo * 0.21;
return bac;
}
getPIR.ino
// PIR Motion
// Setup PIR
void isSetupPIR() {
// Setup PIR Montion
pinMode(iMotion, INPUT_PULLUP);
}
// isPIR Motion
void isPIR() {
// Proximity
proximity = digitalRead(iMotion);
if (proximity == LOW)
{
// PIR Motion Sensor's LOW, Motion is detected
Det = "Motion Yes";
}
else
{
// PIR Motion Sensor's HIGH
Det = "No";
}
}
getRHT.ino
// RHT Temperature and Humidity Sensor
// Setup RHT Temperature and Humidity Sensor
void isSetupRTH03() {
// RHT Temperature and Humidity Sensor
// Call rht.begin() to initialize the sensor and our data pin
rht.begin(RHT03_DATA_PIN);
}
// RHT Temperature and Humidity Sensor
void isRHT03(){
// Call rht.update() to get new humidity and temperature values from the sensor.
int updateRet = rht.update();
// The humidity(), tempC(), and tempF() functions can be called -- after
// a successful update() -- to get the last humidity and temperature value
latestHumidity = rht.humidity();
latestTempC = rht.tempC();
}
getRTC.ino
// DS3231 RTC Date and Time
// Setup DS3231 RTC
void isSetupRTC() {
if (! rtc.begin()) {
while (1);
}
if (rtc.lostPower()) {
// Following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
}
// DS3231 RTC Date and Time
void isRTC(){
// Date and Time
sDate = "";
sTime = "";
// Date Time
DateTime now = rtc.now();
// sData
sDate += String(now.year(), DEC);
sDate += "/";
sDate += String(now.month(), DEC);
sDate += "/";
sDate += String(now.day(), DEC);
// sTime
sTime += String(now.hour(), DEC);
sTime += ":";
sTime += String(now.minute(), DEC);
sTime += ":";
sTime += String(now.second(), DEC);
}
getSD.ino
// MicroSD Card
// MicroSD Setup
void setupSD() {
// MicroSD Card
pinMode( chipSelect , OUTPUT );
if(!SD.begin( chipSelect )){
;
return;
}
uint8_t cardType = SD.cardType();
// CARD NONE
if(cardType == CARD_NONE){
;
return;
}
// SD Card Type
if(cardType == CARD_MMC){
;
} else if(cardType == CARD_SD){
;
} else if(cardType == CARD_SDHC){
;
} else {
;
}
// Size
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
}
// MicroSD Card
void isSD() {
zzzzzz = "";
// DFR|EEPROM Unique ID|Version|Date|Time|Temperature|Humidity|Lux|
// Soil Moisture|Temperature|Humidity|MQ8|MQ9|MQ7|MQ3|PIR|*\r
zzzzzz = "DFR|" + uid + "|" + sver + "|" + sDate + "|" + sTime + "|"
+ String(Temperature) + "C|" + String(Humidity) + "%|"
+ String(SData) + "|" + String(SDataSM) + "|" + String(latestTempC) + "C|"
+ String(latestHumidity) + "%|" + String(iMQ8ppm) +
" PPM|" + String(iMQ9ppm) + " PPM|" + String(iMQ7ppm) + " PPM|" +
String(iMQ3ppm) + "%|" + String(Det) + "|*\r";
// msg + 1
char msg[zzzzzz.length() + 1];
zzzzzz.toCharArray(msg, zzzzzz.length() + 1);
// Append File
appendFile(SD, "/dfrdata.txt", msg );
}
// List Dir
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
// List Dir
dirname;
File root = fs.open(dirname);
if(!root){
return;
}
if(!root.isDirectory()){
return;
}
File file = root.openNextFile();
while(file){
if(file.isDirectory()){
file.name();
if(levels){
listDir(fs, file.name(), levels -1);
}
} else {
file.name();
file.size();
}
file = root.openNextFile();
}
}
// Write File
void writeFile(fs::FS &fs, const char * path, const char * message){
// Write File
path;
File file = fs.open(path, FILE_WRITE);
if(!file){
return;
}
if(file.print(message)){
;
} else {
;
}
file.close();
}
// Append File
void appendFile(fs::FS &fs, const char * path, const char * message){
// Append File
path;
File file = fs.open(path, FILE_APPEND);
if(!file){
return;
}
if(file.print(message)){
;
} else {
;
}
file.close();
}
getSHT40.ino
// Fermion: SHT40 Temperature & Humidity Sensor
// SHT40 Temperature & Humidity
void isSHT40(){
// Fermion: SHT40 Temperature & Humidity Sensor
// Temperature
Temperature = (175 * TemperatureData/65535) - 45;
// Humidity
Humidity = (125 * HumidityData/65535) - 6;
}
getSoilMoisture.ino
// Gravity: Analog Soil Moisture Sensor
// Soil Moisture
void isSoilMoisture(){
// SDataSM => 0~900 Soil Moisture
SDataSM = map( SensorSM, 1, 3000, 0, 900);
}
setup.ino
// Setup
void setup()
{
// Give display time to power on
delay(100);
// EEPROM Size
EEPROM.begin(EEPROM_SIZE);
// EEPROM Unique ID
isUID();
// Give display
delay(100);
// Set up I2C bus
Wire.begin();
// Give display
delay(100);
// Setup BLE Scan
isSetupBLEScan();
// Setup DS3231 RTC
isSetupRTC();
//MicroSD Card
setupSD();
// RHT Temperature and Humidity Sensor
// Setup RTH03 Temperature and Humidity Sensor
isSetupRTH03();
// PIR Motion
// Setup PIR
isSetupPIR();
// SHARP Display Start & Clear the Display
display.begin();
// Clear Display
display.clearDisplay();
// Initialize digital pin iLED as an output
pinMode(iLED, OUTPUT);
// Outputting high, the LED turns on
digitalWrite(iLED, HIGH);
// Initialize the LED Green
pinMode(iLEDGreen, OUTPUT);
// iLEDGreen HIGH
digitalWrite(iLEDGreen, HIGH );
// Initialize the Switch
pinMode(iSwitch, INPUT);
// Don Luc Electronics
// Version
// EEPROM
isDisplayUID();
// Delay 5 Second
delay( 5000 );
}
People can contact us: http://www.donluc.com/?page_id=1927
Teacher, Instructor, E-Mentor, R&D and Consulting
-Programming Language
-Microcontrollers (PIC, Arduino, Raspberry Pi, Arm, Silicon Labs, Espressif, Etc...)
-IoT
-Wireless (Radio Frequency, Bluetooth, WiFi, Etc...)
-Robotics
-Automation
-Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
-Unmanned Vehicles Terrestrial and Marine
-Machine Learning
-Artificial Intelligence (AI)
-RTOS
-Sensors, eHealth Sensors, Biosensor, and Biometric
-Research & Development (R & D)
-Consulting
-Etc...
Follow Us
Luc Paquin – Curriculum Vitae - 2024
https://www.donluc.com/luc/
Web: https://www.donluc.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/@thesass2063
Twitter: https://twitter.com/labs_steam
Pinterest: https://www.pinterest.com/NeoSteamLabs/
Instagram: https://www.instagram.com/neosteamlabs/
LinkedIn: https://www.linkedin.com/in/jlucpaquin/
Don Luc