The Alpha Geek – Geeking Out

Display

1 2 3 7

Project #29 – DFRobot – BLE Sensor Beacon – Mk12

——

#DonLucElectronics #DonLuc #DFRobot #BLESensorBeacon #AmbientLight #SoilMoisture #SHT40 #FireBeetle2ESP32E #EEPROM #RTC #SD #Display #Adafruit #ESP32 #IoT #Arduino #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

BLE Sensor Beacon

——

BLE Sensor Beacon

——

BLE Sensor Beacon

——

Fermion: BLE Sensor Beacon

Fermion: BLE Sensor Beacon, a wireless beacon that broadcasts sensor data via Bluetooth, with built-in 11-bit ADC acquisition and I2C write/read functionality, can be connected to digital or analogue sensors for data acquisition and broadcasting. Sensor data broadcasted by the beacon can be accessed within the beacon’s broadcast range using mobile phones, ESP32 and other devices that support BLE reception.

Fermion: BLE sensor beacons integrate low-power Bluetooth 5.3 technology with self-configurable data formats, such as iBeacon, Eddystone, user-defined, and more. The data format of the beacon broadcast, the content of the broadcast, the broadcast interval and so on can be configured through the graphical interface, without the need for any code programming to complete a Bluetooth beacon. After the configuration is completed, the device power supply is running as a Bluetooth beacon, which will automatically collect sensor data and broadcast to the outside world according to the configuration information. It is suitable for IoT sensor nodes, such as smart farms, offices, factories, warehouses and other scenarios in the data collection node.

DL2405Mk02

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
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 – 12
DMOSI – 4
DSS – 16
SCK – 22
MOSI – 23
MISO – 19
CS – 13
SCL – 21
SDA – 22
LED – 14
VIN – +3.3V
GND – GND

——

DL2405Mk02p.ino

/****** Don Luc Electronics © ******
Software Version Information
Project #29 - DFRobot - BLE Sensor Beacon - Mk12
29-12
DL2404Mk02p.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
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>

// 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  12
#define SHARP_MOSI 4
#define SHARP_SS   16
// 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;

// 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-12";

void loop() {

  // DS3231 RTC Date and Time
  isRTC();
  
  // ScanResults
  isBLEScanResults();

  // Fermion: SHT40 Temperature & Humidity Sensor
  isSHT40();

  // Gravity: Analog Ambient Light Sensor
  isAmbientLight();

  // Soil Moisture
  isSoilMoisture();

  // Delay 4 Second
  delay(4000);

  // Display Date, Time, Temperature, Humidity
  isDisplayDTTH();

  // 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 );

}

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));
  }
  
}

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|*\r
  zzzzzz = "DFR|" + uid + "|" + sver + "|" + sDate + "|" + sTime + "|" 
  + String(Temperature) + "C|" + String(Humidity) + "%|" 
  + String(SData) + "|" + String(SDataSM) + "|*\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();

  // 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 );

  // Don Luc Electronics
  // Version
  // EEPROM
  isDisplayUID();
  
  // Delay 5 Second
  delay( 5000 );

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Teacher, Instructor, E-Mentor, R&D and Consulting

  • Programming Language
  • Single-Board 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

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

Project #29 – DFRobot – Display – Mk11

——

#DonLucElectronics #DonLuc #DFRobot #SHT40 #FireBeetle2ESP32E #EEPROM #RTC #SD #Display #Adafruit #ESP32 #IoT #Arduino #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Display

——

Display

——

Display

——

Adafruit SHARP Memory Display Breakout – 1.3″ 168×144 Monochrome

The 1.3″ 168×144 SHARP Memory LCD display is a cross between an eInk (e-Paper) display and an LCD. It has the ultra-low power usage of eInk and the fast-refresh rates of an LCD. This model has a gray background, and pixels show up as black-on-gray for a nice e-Reader type display. It does not have a backlight, but it is daylight readable. For dark/night reading you may need to illuminate the LCD area with external LEDs.

The bare display is 3 Volt powered and 3 Volt logic, so we placed it on a fully assembled & tested breakout board with a 3 Volt regulator and level shifting circuitry. Now you can use it safely with 3 Volt or 5 Volt power and logic. There are four mounting holes so you can easily attach it to a box.

The display is “Write Only” which means that it only needs 3 pins to send data. However, the downside of a write-only display is that the entire 168×144 bits must be buffered by the microcontroller driver. That means you cannot use this with an ATmega328 or ATmega32u4. You must use a high-RAM chip such as ATSAMD21, Teensy 3, ESP8266, ESP32, etc. On those chips, this display works great and looks wonderful.

DL2405Mk01

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
1 x Fermion: SHT40 Temperature & Humidity Sensor
1 x Fermion: BLE Sensor Beacon
1 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

DFRobot FireBeetle 2 ESP32-E

LED – 2
DSCK – 12
DMOSI – 4
DSS – 16
SCK – 22
MOSI – 23
MISO – 19
CS – 13
SCL – 21
SDA – 22
LED – 14
VIN – +3.3V
GND – GND

——

DL2405Mk01p.ino

/****** Don Luc Electronics © ******
Software Version Information
Project #29 - DFRobot - Display - Mk11
29-11
DL2404Mk01p.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
1 x Fermion: SHT40 Temperature & Humidity Sensor
1 x Fermion: BLE Sensor Beacon
1 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>

// 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  12
#define SHARP_MOSI 4
#define SHARP_SS   16
// 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;
// In seconds
int scanTime = 5;
// BLE Scan
BLEScan *pBLEScan;

// 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]);
   
        }        
      }
    }
};

// EEPROM Unique ID Information
#define EEPROM_SIZE 64
String uid = "";

// Software Version Information
String sver = "29-11";

void loop() {

  // DS3231 RTC Date and Time
  isRTC();
  
  // ScanResults
  isBLEScanResults();

  // Fermion: SHT40 Temperature & Humidity Sensor
  isSHT40();

  // Delay 3 Second
  delay(3000);

  // Display Date, Time, Temperature, Humidity
  isDisplayDTTH();

  // MicroSD Card
  isSD();

  // iLED HIGH
  digitalWrite(iLED, HIGH );

  // Delay 1 Second
  delay(1000);

}

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
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( "%" );
    // 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));
  }
  
}

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|*\r
  zzzzzz = "DFR|" + uid + "|" + sver + "|" + sDate + "|" + sTime + "|" 
  + String(Temperature) + "C|" + String(Humidity) + "%|*\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;

}

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();

  // 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 );

  // Don Luc Electronics
  // Version
  // EEPROM
  isDisplayUID();
  
  // Delay 5 Second
  delay( 5000 );

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Teacher, Instructor, E-Mentor, R&D and Consulting

  • Programming Language
  • Single-Board 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

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

Project #26 – Radio Frequency – Universally Unique IDentifier – Mk27

——

#DonLucElectronics #DonLuc #RadioFrequency #Bluetooth #UUID #Display #SparkFun #Adafruit #BME280 #CCS811 #Arduino #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Universally Unique IDentifier

——

Universally Unique IDentifier

——

Universally Unique IDentifier

——

Universally Unique IDentifier

A Universally Unique IDentifier (UUID) is a 128-bit label used for information in computer systems. When generated according to the standard methods, UUIDs are, for practical purposes, unique. Their uniqueness does not depend on a central registration authority or coordination between the parties generating them, unlike most other numbering schemes. While the probability that a UUID will be duplicated is not zero, it is generally considered close enough to zero to be negligible.

Thus, anyone can create a UUID and use it to identify something with near certainty that the identifier does not duplicate one that has already been, or will be, created to identify something else. Information labeled with UUIDs by independent parties can therefore be later combined into a single database or transmitted on the same channel, with a negligible probability of duplication. Adoption of UUIDs is widespread, with many computing platforms providing support for generating them and for parsing their textual representation.

DL2307Mk08

2 x SparkFun Thing Plus – ESP32 WROOM
1 x SparkFun BME280 – Temperature, Humidity, Barometric Pressure, and Altitude
1 x SparkFun Air Quality Breakout – CCS811
1 x Adafruit SHARP Memory Display Breakout
1 x Adalogger FeatherWing – RTC + SD
1 x 8 GB MicroSD Memory Card
1 x CR1220 3V Lithium Coin Cell Battery
2 x Lithium Ion Battery – 850mAh
2 x SparkFun Cerberus USB Cable

SparkFun Thing Plus – ESP32 WROOM (Server)

LED – LED_BUILTIN
SDA – Digital 23
SCL – Digital 22
RX2 – Bluetooth
TX2 – Bluetooth
VIN – +3.3V
GND – GND

——

DL2307Mk08ps.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #26 - Radio Frequency - Universally Unique IDentifier - Mk27
26-27
DL2307Mk08ps.ino
2 x SparkFun Thing Plus - ESP32 WROOM
1 x SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude
1 x SparkFun Air Quality Breakout - CCS811
1 x Adafruit SHARP Memory Display Breakout
1 x Adalogger FeatherWing - RTC + SD
1 x 8 GB MicroSD Memory Card
1 x CR1220 3V Lithium Coin Cell Battery
2 x Lithium Ion Battery - 850mAh
2 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// BLE Device
#include <BLEDevice.h>
// BLE Utils
#include <BLEUtils.h>
// BLE Serve
#include <BLEServer.h>
// Two Wire Interface (TWI/I2C)
#include <Wire.h>
// SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude
#include <SparkFunBME280.h>
// SparkFun CCS811 - eCO2 & tVOC
#include <SparkFunCCS811.h>

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID            "7c394dc4-49a8-4c22-8a5b-b1612d8c13c1"
#define CHARACTERISTIC_UUID     "a4c4cec2-f394-4f7a-b9de-89047feca74b"
#define CHARACTERISTIC_TEM_UUID "74bd92c6-89d0-4387-823e-97e7e0fb7a2b"
#define CHARACTERISTIC_HUM_UUID "1b63f246-b97f-4d2e-b8eb-f69e20a23a34"
#define CHARACTERISTIC_BAR_UUID "43788175-37a7-4280-93c6-c690324d088e"
#define CHARACTERISTIC_ALT_UUID "609deed9-a72d-45c3-aaba-14a73b0d8fda"
#define CHARACTERISTIC_ECO_UUID "ab17aace-c0b9-4bd3-bb93-7715d9afaeea"
#define CHARACTERISTIC_VOC_UUID "6a8bf86a-9d40-457c-9f7f-f13a3d6803f1"
// Makes the chracteristic globlal
static BLECharacteristic *pCharacteristicTEM;
static BLECharacteristic *pCharacteristicHUM;
static BLECharacteristic *pCharacteristicBAR;
static BLECharacteristic *pCharacteristicALT;
static BLECharacteristic *pCharacteristicECO;
static BLECharacteristic *pCharacteristicVOC;

// SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude
BME280 myBME280;
float BMEtempC = 0;
float BMEhumid = 0;
float BMEpressure = 0;
float BMEaltitudeM = 0;
String FullString = "";

// SparkFun CCS811 - eCO2 & tVOC
// Default I2C Address
#define CCS811_ADDR 0x5B 
CCS811 myCCS811(CCS811_ADDR);
float CCS811CO2 = 0;
float CCS811TVOC = 0;
String FullStringA = "";

// Software Version Information
String sver = "26-27";

void loop() {

  // SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude
  isBME280();

  // SparkFun CCS811 - eCO2 & tVOC
  isCCS811();

  // Delay 1 sec
  delay(1000);

}

getBME280.ino

// SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude
// isBME280 - Temperature, Humidity, Barometric Pressure, and Altitude
void isBME280(){

  // Temperature Celsius
  BMEtempC = myBME280.readTempC();
  // Humidity
  BMEhumid = myBME280.readFloatHumidity();
  // Barometric Pressure
  BMEpressure = myBME280.readFloatPressure();
  // Altitude Meters
  BMEaltitudeM = (myBME280.readFloatAltitudeMeters(), 2);

  // setValue takes uint8_t, uint16_t, uint32_t, int, float, double and string
  pCharacteristicTEM->setValue(BMEtempC);
  pCharacteristicHUM->setValue(BMEhumid);
  pCharacteristicBAR->setValue(BMEpressure);
  pCharacteristicALT->setValue(BMEaltitudeM);

  // FullString
  FullString = "Temperature = " + String(BMEtempC,2) + " Humidity = "
  + String(BMEhumid,2) + " Barometric = " + String(BMEpressure,2) 
  + " Altitude Meters = " + String(BMEaltitudeM,2) + "\r\n";

  // FullString Bluetooth Serial + Serial
  for(int i = 0; i < FullString.length(); i++)
  {

    // Serial
    Serial.write(FullString.c_str()[i]);
    
  }

}

getCCS811.ino

// CCS811 - eCO2 & tVOC
// isCCS811 - eCO2 & tVOC
void isCCS811(){

  // This sends the temperature & humidity data to the CCS811
  myCCS811.setEnvironmentalData(BMEhumid, BMEtempC);

  // Calling this function updates the global tVOC and eCO2 variables
  myCCS811.readAlgorithmResults();

  // eCO2 Concentration
  CCS811CO2 = myCCS811.getCO2();
  
  // tVOC Concentration
  CCS811TVOC = myCCS811.getTVOC();

  // setValue takes uint8_t, uint16_t, uint32_t, int, float, double and string
  pCharacteristicECO->setValue(CCS811CO2);
  pCharacteristicVOC->setValue(CCS811TVOC);

  // FullStringA
  FullStringA = "TVOCs = " + String(CCS811TVOC,2) + " eCO2 = "
  + String(CCS811CO2,2) + "\r\n";

  // FullStringA Bluetooth Serial + Serial
  for(int i = 0; i < FullStringA.length(); i++)
  {

    // Serial
    Serial.write(FullStringA.c_str()[i]);
    
  }


}

setup.ino

// Setup
void setup()
{
  
  // Serial Begin
  Serial.begin(115200);
  Serial.println("Starting BLE work!");

  // Give display time to power on
  delay(100);
  
  // Wire - Inialize I2C Hardware
  Wire.begin();

  // Give display time to power on
  delay(100);

  // SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude 
  myBME280.begin();

  // CCS811 - eCO2 & tVOC
  myCCS811.begin();

  // Initialize digital pin LED_BUILTIN as an output
  pinMode(LED_BUILTIN, OUTPUT);
  // Turn the LED on HIGH
  digitalWrite(LED_BUILTIN, HIGH);

  // BLE Device Init
  BLEDevice::init("Don Luc Electronics Server");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristicTEM = pService->createCharacteristic(
                                         CHARACTERISTIC_TEM_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
                                       
  pCharacteristicHUM = pService->createCharacteristic(
                                         CHARACTERISTIC_HUM_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  
  pCharacteristicBAR = pService->createCharacteristic(
                                         CHARACTERISTIC_BAR_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  
  pCharacteristicALT = pService->createCharacteristic(
                                         CHARACTERISTIC_ALT_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  
  pCharacteristicVOC = pService->createCharacteristic(
                                         CHARACTERISTIC_VOC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  
  pCharacteristicECO = pService->createCharacteristic(
                                         CHARACTERISTIC_ECO_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  
  pCharacteristic->setValue("Luc Paquin");
  pService->start();

  // This still is working for backward compatibility
  // BLEAdvertising *pAdvertising = pServer->getAdvertising();
  // BLE Advertising
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  // Functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x06);
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();

}

——

SparkFun Thing Plus – ESP32 WROOM (Client)

LED – Digital 21
SCK – Digital 13
MOSI – Digital 12
SS – Digital 27
MISO – Digital 19
MOSI – Digital 18
SCK – Digital 5
CS – Digital 33
SDA – Digital 23
SCL – Digital 22
RX2 – Bluetooth
TX2 – Bluetooth
VIN – +3.3V
GND – GND

——

DL2307Mk08pr.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #26 - Radio Frequency - Universally Unique IDentifier - Mk27
26-27
DL2307Mk08pr.ino
2 x SparkFun Thing Plus - ESP32 WROOM
1 x SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude
1 x SparkFun Air Quality Breakout - CCS811
1 x Adafruit SHARP Memory Display Breakout
1 x Adalogger FeatherWing - RTC + SD
1 x 8 GB MicroSD Memory Card
1 x CR1220 3V Lithium Coin Cell Battery
2 x Lithium Ion Battery - 850mAh
2 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Bluetooth BLE Device
#include "BLEDevice.h"
// SHARP Memory Display
#include <Adafruit_SharpMem.h>
// Adafruit GFX Library
#include <Adafruit_GFX.h>
// Date and Time
#include "RTClib.h"
// SD Card
#include "FS.h"
#include "SD.h"
#include "SPI.h"

// SHARP Memory Display
// any pins can be used
#define SHARP_SCK  13
#define SHARP_MOSI 12
#define SHARP_SS   27
// 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
// 1/2 of lesser of display width or height
int minorHalfSize;

// The remote service we wish to connect to.
static BLEUUID serviceUUID("7c394dc4-49a8-4c22-8a5b-b1612d8c13c1");
// The characteristic of the remote service we are interested in.
static BLEUUID    charUUID("a4c4cec2-f394-4f7a-b9de-89047feca74b");
// Use the same UUID as on the server
static BLEUUID    charTEMUUID("74bd92c6-89d0-4387-823e-97e7e0fb7a2b");
static BLEUUID    charHUMUUID("1b63f246-b97f-4d2e-b8eb-f69e20a23a34");
static BLEUUID    charBARUUID("43788175-37a7-4280-93c6-c690324d088e");
static BLEUUID    charALTUUID("609deed9-a72d-45c3-aaba-14a73b0d8fda");
static BLEUUID    charECOUUID("ab17aace-c0b9-4bd3-bb93-7715d9afaeea");
static BLEUUID    charVOCUUID("6a8bf86a-9d40-457c-9f7f-f13a3d6803f1");
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLERemoteCharacteristic* pRemoteCharacteristicTEM;
static BLERemoteCharacteristic* pRemoteCharacteristicHUM;
static BLERemoteCharacteristic* pRemoteCharacteristicBAR;
static BLERemoteCharacteristic* pRemoteCharacteristicALT;
static BLERemoteCharacteristic* pRemoteCharacteristicECO;
static BLERemoteCharacteristic* pRemoteCharacteristicVOC;

static BLEAdvertisedDevice* myDevice;
float TEMValue;
float HUMValue;
float BARValue;
float ALTValue;
float ECOValue;
float VOCValue;

int iLED = 21;

// Date and Time
// PCF8523 Precision RTC 
RTC_PCF8523 rtc;
String dateRTC = "";
String timeRTC = "";

// microSD Card
const int chipSelect = 33;
String zzzzzz = "";

// Software Version Information
String sver = "26-27";

void loop() {

  // Bluetooth BLE
  isBluetoothBLE();

  // Date and Time 
  isRTC();

  // Display Environmental
  isDisplayEnvironmental();

  // microSD Card
  isSD();

}

getBluetoothBLE.ino

// Bluetooth BLE
// isBluetoothBLE
void isBluetoothBLE(){

  // If the flag "doConnect" is true then we have scanned for 
  // and found the desired
  // BLE Server with which we wish to connect.  Now we connect to it.
  // Once we are connected we set the connected flag to be true.
  if (doConnect == true) {
    if (connectToServer()) {
      Serial.println("We are now connected to the BLE Server.");
    } else {
      Serial.println("We have failed to connect to the server; there is nothin more we will do.");
    }
    doConnect = false;
  }

  // If we are connected to a peer BLE Server, update the characteristic each time we are reached
  // with the current time since boot.
  if (connected) {
    String newValue = "Time since boot: " + String(millis()/1000);
    //Serial.println("Setting new characteristic value to \"" + newValue + "\"");

    // Set the characteristic's value to be the array of bytes that is actually a string.
   // pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());//***********JKO
  }else if(doScan){
    BLEDevice::getScan()->start(0);  // this is just example to start scan after disconnect, most likely there is better way to do it in arduino
  }

  // read the Characteristics and store them in a variable
  // This also makes the print command do float handling
  TEMValue = pRemoteCharacteristicTEM->readFloat();
  HUMValue = pRemoteCharacteristicHUM->readFloat();
  BARValue = pRemoteCharacteristicBAR->readFloat();
  ALTValue = pRemoteCharacteristicALT->readFloat();
  ECOValue = pRemoteCharacteristicECO->readFloat();
  VOCValue = pRemoteCharacteristicVOC->readFloat();
  
}
// Notify Callback
static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify) {
    Serial.print("Notify callback for characteristic ");
    Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
    Serial.print(" of data length ");
    Serial.println(length);
    Serial.print("data: ");
    Serial.println((char*)pData);
}
// My Client Callback
class MyClientCallback : public BLEClientCallbacks {
  void onConnect(BLEClient* pclient) {
  }

  void onDisconnect(BLEClient* pclient) {
    connected = false;
    Serial.println("onDisconnect");
  }
};
// Connect To Server
bool connectToServer() {
    Serial.print("Forming a connection to ");
    Serial.println(myDevice->getAddress().toString().c_str());

    BLEClient*  pClient  = BLEDevice::createClient();
    Serial.println(" - Created client");

    pClient->setClientCallbacks(new MyClientCallback());

    // Connect to the remove BLE Server.
    // if you pass BLEAdvertisedDevice instead of address,
    //it will be recognized type of peer device address (public or private)
    pClient->connect(myDevice);  
    Serial.println(" - Connected to server");
    //set client to request maximum MTU from server (default is 23 otherwise)
    pClient->setMTU(517); 

    // Obtain a reference to the service we are after in the remote BLE server.
    BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
    if (pRemoteService == nullptr) {
      Serial.print("Failed to find our service UUID: ");
      Serial.println(serviceUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our service");

    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
    if (pRemoteCharacteristic == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic");
    // Temperature Obtain a reference to the characteristic in the service
    // of the remote BLE server.
    pRemoteCharacteristicTEM = pRemoteService->getCharacteristic(charTEMUUID);
    if (pRemoteCharacteristicTEM == nullptr) {
      Serial.print("Failed to find our characteristic UUID Temperature: ");
      Serial.println(charTEMUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    // Humidity Obtain a reference to the characteristic in the service
    // of the remote BLE server.
    pRemoteCharacteristicHUM = pRemoteService->getCharacteristic(charHUMUUID);
    if (pRemoteCharacteristicHUM == nullptr) {
      Serial.print("Failed to find our characteristic UUID Temperature: ");
      Serial.println(charHUMUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }

    Serial.println(" - Found our characteristic");

    // Barometric Obtain a reference to the characteristic in the service
    // of the remote BLE server.
    pRemoteCharacteristicBAR = pRemoteService->getCharacteristic(charBARUUID);
    if (pRemoteCharacteristicBAR == nullptr) {
      Serial.print("Failed to find our characteristic UUID Barometric: ");
      Serial.println(charBARUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }

    Serial.println(" - Found our characteristic");
    
    // Altitude Obtain a reference to the characteristic in the service
    // of the remote BLE server.
    pRemoteCharacteristicALT = pRemoteService->getCharacteristic(charALTUUID);
    if (pRemoteCharacteristicALT == nullptr) {
      Serial.print("Failed to find our characteristic UUID Altitude: ");
      Serial.println(charALTUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }

    // eCO2 Concentration Obtain a reference to the characteristic in the service
    // of the remote BLE server.
    pRemoteCharacteristicECO = pRemoteService->getCharacteristic(charECOUUID);
    if (pRemoteCharacteristicECO == nullptr) {
      Serial.print("Failed to find our characteristic UUID eCO2 Concentration: ");
      Serial.println(charECOUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }

    Serial.println(" - Found our characteristic");
    
    // tVOC Concentration Obtain a reference to the characteristic in the service
    // of the remote BLE server.
    pRemoteCharacteristicVOC = pRemoteService->getCharacteristic(charVOCUUID);
    if (pRemoteCharacteristicVOC == nullptr) {
      Serial.print("Failed to find our characteristic UUID tVOC Concentration: ");
      Serial.println(charVOCUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    
    
    Serial.println(" - Found our characteristic");
    // Read the value of the characteristic.
    if(pRemoteCharacteristic->canRead()) {
      std::string value = pRemoteCharacteristic->readValue();
      Serial.print("The characteristic value was: ");
      Serial.println(value.c_str());
    }

    if(pRemoteCharacteristic->canNotify())
      pRemoteCharacteristic->registerForNotify(notifyCallback);

    connected = true;
    return true;
    
}
/**
 * Scan for BLE servers and find the first one that advertises the service we are looking for.
 */
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
 /**
   * Called for each advertising BLE server.
   */
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    Serial.print("BLE Advertised Device found: ");
    Serial.println(advertisedDevice.toString().c_str());

    // We have found a device, let us now see if it contains the service we are looking for.
    if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {

      BLEDevice::getScan()->stop();
      myDevice = new BLEAdvertisedDevice(advertisedDevice);
      doConnect = true;
      doScan = true;

    } // Found our server
  } // onResult
}; // MyAdvertisedDeviceCallbacks

getDisplay.ino

// Display
// SHARP Memory Display - UID
void isDisplayUID() {

    // Text Display 
    // Clear Display
    display.clearDisplay();
    display.setRotation(2);
    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,100);   
    display.println( sver );
    display.setCursor(0,125);   
    display.println( dateRTC );
    display.setCursor(0,150);   
    display.println( timeRTC );
    // Refresh
    display.refresh();
    delay( 5000 );
    
}
// Display Environmental
void isDisplayEnvironmental(){

    // Text Display Environmental
    // Clear Display
    display.clearDisplay();
    display.setRotation(2);
    display.setTextSize(2);
    display.setTextColor(BLACK);
    // Temperature Celsius
    display.setCursor(0,5);
    display.print( "T: " );
    display.print( TEMValue );    
    display.println( "C" );
    // Humidity
    display.setCursor(0,25);
    display.print( "H: " );
    display.print( HUMValue );
    display.println( "%" );
    // Pressure
    display.setCursor(0,45);
    display.print( "B: " );
    display.print( BARValue );
    display.println( "" );
    // Altitude Meters
    display.setCursor(0,65);
    display.print( "A: " );   
    display.print( ALTValue );
    display.println( "M" );
    // eCO2 Concentration
    display.setCursor(0,85);
    display.print( "C: " );
    display.print( ECOValue );
    display.println( "ppm" );
    // tVOC Concentration
    display.setCursor(0,105);
    display.print( "V: " );
    display.print( VOCValue );
    display.println( "ppb" );
    // Date
    display.setCursor(0,125);
    display.println( dateRTC );
    // Time
    display.setCursor(0,145);
    display.println( timeRTC );
    // Refresh
    display.refresh();
    delay( 100 );

}

getRTC.ino

// Date & Time
// PCF8523 Precision RTC 
void setupRTC() {

  // Date & Time
  // pcf8523 Precision RTC   
  if (! rtc.begin()) {
    while (1);
  }  
  
  if (! rtc.initialized()) {
    // 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(2023, 7, 24, 11, 0, 0));
  }
  
}
// Date and Time RTC
void isRTC () {

  // Date and Time
  dateRTC = "";
  timeRTC = "";
  DateTime now = rtc.now();
  
  // Date
  dateRTC = now.year(), DEC; 
  dateRTC = dateRTC + "/";
  dateRTC = dateRTC + now.month(), DEC;
  dateRTC = dateRTC + "/";
  dateRTC = dateRTC + now.day(), DEC;
  
  // Time
  timeRTC = now.hour(), DEC;
  timeRTC = timeRTC + ":";
  timeRTC = timeRTC + now.minute(), DEC;
  timeRTC = timeRTC + ":";
  timeRTC = timeRTC + 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();

    if(cardType == CARD_NONE){
        ; 
        return;
    }

    //Serial.print("SD Card Type: ");
    if(cardType == CARD_MMC){
        ; 
    } else if(cardType == CARD_SD){
        ; 
    } else if(cardType == CARD_SDHC){
        ; 
    } else {
        ; 
    } 

    uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  
}
// microSD Card
void isSD() {

  zzzzzz = "";

  // BLE|Version|Date|Time|Temperature Celsius|Humidity|Barometric Pressure
  //|Altitude Meters|eCO2 Concentration|tVOC Concentration|*
  zzzzzz = "BLE|" + sver + "|" + dateRTC + "|" + timeRTC + "|" + TEMValue 
  + "|" + HUMValue + "|" + BARValue + "|" + ALTValue + "|" + ECOValue
  + "|" + VOCValue + "|*\r";

  char msg[zzzzzz.length() + 1];

  zzzzzz.toCharArray(msg, zzzzzz.length() + 1);

  appendFile(SD, "/espdata.txt", msg );
  
}
// List Dir
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    
    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){
    
    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){
    
    path;
    
    File file = fs.open(path, FILE_APPEND);
    
    if(!file){
        return;
    }
    
    if(file.print(message)){
        ;  
    } else {
        ;  
    }
    
    file.close();
    
}

setup.ino

// Setup
void setup()
{
  
  // Serial
  Serial.begin(115200);
  Serial.println("Starting Arduino BLE Client application...");

  // Initialize digital pin iLED as an output
  pinMode(iLED, OUTPUT);
  // Turn the LED on HIGH
  digitalWrite(iLED, HIGH);

  // SHARP Display start & clear the display
  display.begin();
  display.clearDisplay();

  // Date & Time RTC
  // PCF8523 Precision RTC 
  setupRTC();
  
  // Date & Time
  isRTC();

  // Display UID
  isDisplayUID();

  // microSD Card
  setupSD();

  // Bluetooth BLE
  BLEDevice::init("");
  
  // Give display time to power on
  delay(100);
  
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setInterval(1349);
  pBLEScan->setWindow(449);
  pBLEScan->setActiveScan(true);
  pBLEScan->start(5, false);

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Programming Language
  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Wireless (Radio Frequency, Bluetooth, WiFi, Etc…)
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Machine Learning
  • RTOS
  • Research & Development (R & D)

Instructor, E-Mentor, STEAM, and Arts-Based Training

  • Programming Language
  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

Luc Paquin – Curriculum Vitae – 2023
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/

Don Luc

Project #26 – Radio Frequency – Bluetooth Server and Client – Mk26

——

#DonLucElectronics #DonLuc #RadioFrequency #Bluetooth #Display #SparkFun #BME280 #CCS811 #Arduino #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Bluetooth Server and Client

——

Bluetooth Server and Client

——

Bluetooth Server and Client

——-

Bluetooth Server and Client

Connect the SparkFun BME280 and CCS811 this is the “Server” board. Upload SparkFun Thing Plus the Server code to the board using the USB cable. When uploading is complete, disconnect this board from the computer. Now, connect the Lithium Ion battery to the “Server”. Next, connect the second SparkFun Thing Plus to your computer and upload the Client code to the board. We have two Arduino sketches to upload to the SparkFun Thing Plus boards. Upload the first sketch to the Server SparkFun Thing Plus and the second sketch to the Client SparkFun Thing Plus.

DL2307Mk07

2 x SparkFun Thing Plus – ESP32 WROOM
1 x SparkFun BME280 – Temperature, Humidity, Barometric Pressure, and Altitude
1 x SparkFun Air Quality Breakout – CCS811
1 x Adafruit SHARP Memory Display Breakout
2 x Lithium Ion Battery – 850mAh
2 x SparkFun Cerberus USB Cable

SparkFun Thing Plus – ESP32 WROOM (Server)

LED – LED_BUILTIN
SDA – Digital 23
SCL – Digital 22
RX2 – Bluetooth
TX2 – Bluetooth
VIN – +3.3V
GND – GND

——

DL2307Mk07ps.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #26 - Radio Frequency - Bluetooth Server and Client - Mk26
26-26
DL2307Mk07ps.ino
2 x SparkFun Thing Plus - ESP32 WROOM
1 x SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude
1 x SparkFun Air Quality Breakout - CCS811
1 x Adafruit SHARP Memory Display Breakout
2 x Lithium Ion Battery - 850mAh
2 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// BLE Device
#include <BLEDevice.h>
// BLE Utils
#include <BLEUtils.h>
// BLE Serve
#include <BLEServer.h>
// Two Wire Interface (TWI/I2C)
#include <Wire.h>
// SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude
#include <SparkFunBME280.h>
// SparkFun CCS811 - eCO2 & tVOC
#include <SparkFunCCS811.h>

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID            "7c394dc4-49a8-4c22-8a5b-b1612d8c13c1"
#define CHARACTERISTIC_UUID     "a4c4cec2-f394-4f7a-b9de-89047feca74b"
#define CHARACTERISTIC_TEM_UUID "74bd92c6-89d0-4387-823e-97e7e0fb7a2b"
#define CHARACTERISTIC_HUM_UUID "1b63f246-b97f-4d2e-b8eb-f69e20a23a34"
#define CHARACTERISTIC_BAR_UUID "43788175-37a7-4280-93c6-c690324d088e"
#define CHARACTERISTIC_ALT_UUID "609deed9-a72d-45c3-aaba-14a73b0d8fda"
#define CHARACTERISTIC_ECO_UUID "ab17aace-c0b9-4bd3-bb93-7715d9afaeea"
#define CHARACTERISTIC_VOC_UUID "6a8bf86a-9d40-457c-9f7f-f13a3d6803f1"
// Makes the chracteristic globlal
static BLECharacteristic *pCharacteristicTEM;
static BLECharacteristic *pCharacteristicHUM;
static BLECharacteristic *pCharacteristicBAR;
static BLECharacteristic *pCharacteristicALT;
static BLECharacteristic *pCharacteristicECO;
static BLECharacteristic *pCharacteristicVOC;

// SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude
BME280 myBME280;
float BMEtempC = 0;
float BMEhumid = 0;
float BMEpressure = 0;
float BMEaltitudeM = 0;
String FullString = "";

// SparkFun CCS811 - eCO2 & tVOC
// Default I2C Address
#define CCS811_ADDR 0x5B 
CCS811 myCCS811(CCS811_ADDR);
float CCS811CO2 = 0;
float CCS811TVOC = 0;
String FullStringA = "";

// Software Version Information
String sver = "26-26";

void loop() {

  // SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude
  isBME280();

  // SparkFun CCS811 - eCO2 & tVOC
  isCCS811();

  // Delay 1 sec
  delay(1000);

}

getBME280.ino

// SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude
// isBME280 - Temperature, Humidity, Barometric Pressure, and Altitude
void isBME280(){

  // Temperature Celsius
  BMEtempC = myBME280.readTempC();
  // Humidity
  BMEhumid = myBME280.readFloatHumidity();
  // Barometric Pressure
  BMEpressure = myBME280.readFloatPressure();
  // Altitude Meters
  BMEaltitudeM = (myBME280.readFloatAltitudeMeters(), 2);

  // setValue takes uint8_t, uint16_t, uint32_t, int, float, double and string
  pCharacteristicTEM->setValue(BMEtempC);
  pCharacteristicHUM->setValue(BMEhumid);
  pCharacteristicBAR->setValue(BMEpressure);
  pCharacteristicALT->setValue(BMEaltitudeM);

  // FullString
  FullString = "Temperature = " + String(BMEtempC,2) + " Humidity = "
  + String(BMEhumid,2) + " Barometric = " + String(BMEpressure,2) 
  + " Altitude Meters = " + String(BMEaltitudeM,2) + "\r\n";

  // FullString Bluetooth Serial + Serial
  for(int i = 0; i < FullString.length(); i++)
  {

    // Serial
    Serial.write(FullString.c_str()[i]);
    
  }

}

getCCS811.ino

// CCS811 - eCO2 & tVOC
// isCCS811 - eCO2 & tVOC
void isCCS811(){

  // This sends the temperature & humidity data to the CCS811
  myCCS811.setEnvironmentalData(BMEhumid, BMEtempC);

  // Calling this function updates the global tVOC and eCO2 variables
  myCCS811.readAlgorithmResults();

  // eCO2 Concentration
  CCS811CO2 = myCCS811.getCO2();
  
  // tVOC Concentration
  CCS811TVOC = myCCS811.getTVOC();

  // setValue takes uint8_t, uint16_t, uint32_t, int, float, double and string
  pCharacteristicECO->setValue(CCS811CO2);
  pCharacteristicVOC->setValue(CCS811TVOC);

  // FullStringA
  FullStringA = "TVOCs = " + String(CCS811TVOC,2) + " eCO2 = "
  + String(CCS811CO2,2) + "\r\n";

  // FullStringA Bluetooth Serial + Serial
  for(int i = 0; i < FullStringA.length(); i++)
  {

    // Serial
    Serial.write(FullStringA.c_str()[i]);
    
  }


}

setup.ino

// Setup
void setup()
{
  
  // Serial Begin
  Serial.begin(115200);
  Serial.println("Starting BLE work!");

  // Give display time to power on
  delay(100);
  
  // Wire - Inialize I2C Hardware
  Wire.begin();

  // Give display time to power on
  delay(100);

  // SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude 
  myBME280.begin();

  // CCS811 - eCO2 & tVOC
  myCCS811.begin();

  // Initialize digital pin LED_BUILTIN as an output
  pinMode(LED_BUILTIN, OUTPUT);
  // Turn the LED on HIGH
  digitalWrite(LED_BUILTIN, HIGH);

  // BLE Device Init
  BLEDevice::init("Don Luc Electronics Server");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristicTEM = pService->createCharacteristic(
                                         CHARACTERISTIC_TEM_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
                                       
  pCharacteristicHUM = pService->createCharacteristic(
                                         CHARACTERISTIC_HUM_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  
  pCharacteristicBAR = pService->createCharacteristic(
                                         CHARACTERISTIC_BAR_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  
  pCharacteristicALT = pService->createCharacteristic(
                                         CHARACTERISTIC_ALT_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  
  pCharacteristicVOC = pService->createCharacteristic(
                                         CHARACTERISTIC_VOC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  
  pCharacteristicECO = pService->createCharacteristic(
                                         CHARACTERISTIC_ECO_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  
  pCharacteristic->setValue("Luc Paquin");
  pService->start();

  // This still is working for backward compatibility
  // BLEAdvertising *pAdvertising = pServer->getAdvertising();
  // BLE Advertising
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  // Functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x06);
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();

}

——

SparkFun Thing Plus – ESP32 WROOM (Client)

LED – Digital 21
SCK – Digital 13
MOSI – Digital 12
SS – Digital 27
RX2 – Bluetooth
TX2 – Bluetooth
VIN – +3.3V
GND – GND

——

DL2307Mk07pr.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #26 - Radio Frequency - Bluetooth Server and Client - Mk26
26-26
DL2307Mk07pr.ino
2 x SparkFun Thing Plus - ESP32 WROOM
1 x SparkFun BME280 - Temperature, Humidity, Barometric Pressure, and Altitude
1 x SparkFun Air Quality Breakout - CCS811
1 x Adafruit SHARP Memory Display Breakout
2 x Lithium Ion Battery - 850mAh
2 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Bluetooth BLE Device
#include "BLEDevice.h"
// SHARP Memory Display
#include <Adafruit_SharpMem.h>
// Adafruit GFX Library
#include <Adafruit_GFX.h>

// SHARP Memory Display
// any pins can be used
#define SHARP_SCK  13
#define SHARP_MOSI 12
#define SHARP_SS   27
// 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
// 1/2 of lesser of display width or height
int minorHalfSize;

// The remote service we wish to connect to.
static BLEUUID serviceUUID("7c394dc4-49a8-4c22-8a5b-b1612d8c13c1");
// The characteristic of the remote service we are interested in.
static BLEUUID    charUUID("a4c4cec2-f394-4f7a-b9de-89047feca74b");
// Use the same UUID as on the server
static BLEUUID    charTEMUUID("74bd92c6-89d0-4387-823e-97e7e0fb7a2b");
static BLEUUID    charHUMUUID("1b63f246-b97f-4d2e-b8eb-f69e20a23a34");
static BLEUUID    charBARUUID("43788175-37a7-4280-93c6-c690324d088e");
static BLEUUID    charALTUUID("609deed9-a72d-45c3-aaba-14a73b0d8fda");
static BLEUUID    charECOUUID("ab17aace-c0b9-4bd3-bb93-7715d9afaeea");
static BLEUUID    charVOCUUID("6a8bf86a-9d40-457c-9f7f-f13a3d6803f1");
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLERemoteCharacteristic* pRemoteCharacteristicTEM;
static BLERemoteCharacteristic* pRemoteCharacteristicHUM;
static BLERemoteCharacteristic* pRemoteCharacteristicBAR;
static BLERemoteCharacteristic* pRemoteCharacteristicALT;
static BLERemoteCharacteristic* pRemoteCharacteristicECO;
static BLERemoteCharacteristic* pRemoteCharacteristicVOC;

static BLEAdvertisedDevice* myDevice;
float TEMValue;
float HUMValue;
float BARValue;
float ALTValue;
float ECOValue;
float VOCValue;

int iLED = 21;

// Software Version Information
String sver = "26-26";

void loop() {

  isBluetoothBLE();

  isDisplayEnvironmental();
 
}

getBluetoothBLE.ino

// Bluetooth BLE
void isBluetoothBLE(){

  // If the flag "doConnect" is true then we have scanned for 
  // and found the desired
  // BLE Server with which we wish to connect.  Now we connect to it.
  // Once we are connected we set the connected flag to be true.
  if (doConnect == true) {
    if (connectToServer()) {
      Serial.println("We are now connected to the BLE Server.");
    } else {
      Serial.println("We have failed to connect to the server; there is nothin more we will do.");
    }
    doConnect = false;
  }

  // If we are connected to a peer BLE Server, update the characteristic each time we are reached
  // with the current time since boot.
  if (connected) {
    String newValue = "Time since boot: " + String(millis()/1000);
    //Serial.println("Setting new characteristic value to \"" + newValue + "\"");

    // Set the characteristic's value to be the array of bytes that is actually a string.
   // pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());//***********JKO
  }else if(doScan){
    BLEDevice::getScan()->start(0);  // this is just example to start scan after disconnect, most likely there is better way to do it in arduino
  }

  // read the Characteristics and store them in a variable
  // This also makes the print command do float handling
  TEMValue = pRemoteCharacteristicTEM->readFloat();
  HUMValue = pRemoteCharacteristicHUM->readFloat();
  BARValue = pRemoteCharacteristicBAR->readFloat();
  ALTValue = pRemoteCharacteristicALT->readFloat();
  ECOValue = pRemoteCharacteristicECO->readFloat();
  VOCValue = pRemoteCharacteristicVOC->readFloat();
  
}
// Notify Callback
static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify) {
    Serial.print("Notify callback for characteristic ");
    Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
    Serial.print(" of data length ");
    Serial.println(length);
    Serial.print("data: ");
    Serial.println((char*)pData);
}
// My Client Callback
class MyClientCallback : public BLEClientCallbacks {
  void onConnect(BLEClient* pclient) {
  }

  void onDisconnect(BLEClient* pclient) {
    connected = false;
    Serial.println("onDisconnect");
  }
};
// Connect To Server
bool connectToServer() {
    Serial.print("Forming a connection to ");
    Serial.println(myDevice->getAddress().toString().c_str());

    BLEClient*  pClient  = BLEDevice::createClient();
    Serial.println(" - Created client");

    pClient->setClientCallbacks(new MyClientCallback());

    // Connect to the remove BLE Server.
    // if you pass BLEAdvertisedDevice instead of address,
    //it will be recognized type of peer device address (public or private)
    pClient->connect(myDevice);  
    Serial.println(" - Connected to server");
    //set client to request maximum MTU from server (default is 23 otherwise)
    pClient->setMTU(517); 

    // Obtain a reference to the service we are after in the remote BLE server.
    BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
    if (pRemoteService == nullptr) {
      Serial.print("Failed to find our service UUID: ");
      Serial.println(serviceUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our service");

    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
    if (pRemoteCharacteristic == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic");
    // Temperature Obtain a reference to the characteristic in the service
    // of the remote BLE server.
    pRemoteCharacteristicTEM = pRemoteService->getCharacteristic(charTEMUUID);
    if (pRemoteCharacteristicTEM == nullptr) {
      Serial.print("Failed to find our characteristic UUID Temperature: ");
      Serial.println(charTEMUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    // Humidity Obtain a reference to the characteristic in the service
    // of the remote BLE server.
    pRemoteCharacteristicHUM = pRemoteService->getCharacteristic(charHUMUUID);
    if (pRemoteCharacteristicHUM == nullptr) {
      Serial.print("Failed to find our characteristic UUID Temperature: ");
      Serial.println(charHUMUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }

    Serial.println(" - Found our characteristic");

    // Barometric Obtain a reference to the characteristic in the service
    // of the remote BLE server.
    pRemoteCharacteristicBAR = pRemoteService->getCharacteristic(charBARUUID);
    if (pRemoteCharacteristicBAR == nullptr) {
      Serial.print("Failed to find our characteristic UUID Barometric: ");
      Serial.println(charBARUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }

    Serial.println(" - Found our characteristic");
    
    // Altitude Obtain a reference to the characteristic in the service
    // of the remote BLE server.
    pRemoteCharacteristicALT = pRemoteService->getCharacteristic(charALTUUID);
    if (pRemoteCharacteristicALT == nullptr) {
      Serial.print("Failed to find our characteristic UUID Altitude: ");
      Serial.println(charALTUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }

    // eCO2 Concentration Obtain a reference to the characteristic in the service
    // of the remote BLE server.
    pRemoteCharacteristicECO = pRemoteService->getCharacteristic(charECOUUID);
    if (pRemoteCharacteristicECO == nullptr) {
      Serial.print("Failed to find our characteristic UUID eCO2 Concentration: ");
      Serial.println(charECOUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }

    Serial.println(" - Found our characteristic");
    
    // tVOC Concentration Obtain a reference to the characteristic in the service
    // of the remote BLE server.
    pRemoteCharacteristicVOC = pRemoteService->getCharacteristic(charVOCUUID);
    if (pRemoteCharacteristicVOC == nullptr) {
      Serial.print("Failed to find our characteristic UUID tVOC Concentration: ");
      Serial.println(charVOCUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    
    
    Serial.println(" - Found our characteristic");
    // Read the value of the characteristic.
    if(pRemoteCharacteristic->canRead()) {
      std::string value = pRemoteCharacteristic->readValue();
      Serial.print("The characteristic value was: ");
      Serial.println(value.c_str());
    }

    if(pRemoteCharacteristic->canNotify())
      pRemoteCharacteristic->registerForNotify(notifyCallback);

    connected = true;
    return true;
    
}
/**
 * Scan for BLE servers and find the first one that advertises the service we are looking for.
 */
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
 /**
   * Called for each advertising BLE server.
   */
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    Serial.print("BLE Advertised Device found: ");
    Serial.println(advertisedDevice.toString().c_str());

    // We have found a device, let us now see if it contains the service we are looking for.
    if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {

      BLEDevice::getScan()->stop();
      myDevice = new BLEAdvertisedDevice(advertisedDevice);
      doConnect = true;
      doScan = true;

    } // Found our server
  } // onResult
}; // MyAdvertisedDeviceCallbacks

getDisplay.ino

// Display
// SHARP Memory Display - UID
void isDisplayUID() {

    // Text Display 
    // Clear Display
    display.clearDisplay();
    display.setRotation(2);
    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,100);   
    display.println( sver );
    // Refresh
    display.refresh();
    delay( 5000 );
    
}
// Display Environmental
void isDisplayEnvironmental(){

    // Text Display Environmental
    // Clear Display
    display.clearDisplay();
    display.setRotation(2);
    display.setTextSize(2);
    display.setTextColor(BLACK);
    // Temperature Celsius
    display.setCursor(0,5);
    display.print( "T: " );
    display.print( TEMValue );    
    display.println( "C" );
    // Humidity
    display.setCursor(0,25);
    display.print( "H: " );
    display.print( HUMValue );
    display.println( "%" );
    // Pressure
    display.setCursor(0,45);
    display.print( "B: " );
    display.print( BARValue );
    display.println( "" );
    // Altitude Meters
    display.setCursor(0,65);
    display.print( "A: " );   
    display.print( ALTValue );
    display.println( "M" );
    // eCO2 Concentration
    display.setCursor(0,85);
    display.print( "C: " );
    display.print( ECOValue );
    display.println( "ppm" );
    // tVOC Concentration
    display.setCursor(0,105);
    display.print( "V: " );
    display.print( VOCValue );
    display.println( "ppb" );
    // Refresh
    display.refresh();
    delay( 100 );

}

setup.ino

// Setup
void setup()
{
  
  // Serial
  Serial.begin(115200);
  Serial.println("Starting Arduino BLE Client application...");

  // Initialize digital pin iLED as an output
  pinMode(iLED, OUTPUT);
  // Turn the LED on HIGH
  digitalWrite(iLED, HIGH);

  // SHARP Display start & clear the display
  display.begin();
  display.clearDisplay();

  // Display UID
  isDisplayUID();

  // Bluetooth BLE
  BLEDevice::init("");
  
  // Give display time to power on
  delay(100);
  
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setInterval(1349);
  pBLEScan->setWindow(449);
  pBLEScan->setActiveScan(true);
  pBLEScan->start(5, false);

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Programming Language
  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Wireless (Radio Frequency, Bluetooth, WiFi, Etc…)
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Machine Learning
  • RTOS
  • Research & Development (R & D)

Instructor, E-Mentor, STEAM, and Arts-Based Training

  • Programming Language
  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

Luc Paquin – Curriculum Vitae – 2023
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/

Don Luc

Project #12: Robotics – 9DOF – Mk27

——

#DonLucElectronics #DonLuc #Robotics #Magnetometer #Accelerometer #Gyroscope #MicroOLED # #Arduino #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

9DOF

——

9DOF

——

9DOF

——

SparkFun 9 Degrees of Freedom – Sensor Stick

The SparkFun 9DOF Sensor Stick is a very small sensor board with 9 degrees of freedom. It includes the ADXL345 accelerometer, the HMC5883L magnetometer, and the ITG-3200 MEMS gyro. The “Stick” has a simple I2C interface and a mounting hole for attaching it to your project. Also, the board is a mere allowing it to be easily mounted in just about any application.

DL2305Mk03

1 x SparkFun RedBoard Qwiic
1 x ProtoScrewShield
1 x SparkFun 9 Degrees of Freedom – Sensor Stick
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x Thumb Joystick
1 x SparkFun Thumb Joystick Breakout
2 x Pololu DRV8834 Low-Voltage Stepper Motor Driver Carrier
2 x Electrolytic Decoupling Capacitors – 100uF/25V
2 x Pololu Stepper Motor Bipolar, 2.8V, 1.7 A/Phase
2 x Pololu Universal Aluminum Mounting Hub for 5mm Shaft, M3 Holes
1 x SparkFun Solderable Breadboard – Large
1 x SparkFun Cerberus USB Cable

SparkFun RedBoard Qwiic

SDA – Analog A5
SCL – Analog A4
JH – Analog A0
JV – Analog A1
JS – Digital 2
DIR – Digital 7
SPR – Digital 8
DIL – Digital 9
SPL – Digital 10
LED – Digital 13
VIN – +3.3V
VIN – +5V
GND – GND

——

DL2305Mk03p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #12: Robotics - 9DOF - Mk27
12-27
DL2305Mk03p.ino
1 x SparkFun RedBoard Qwiic
1 x ProtoScrewShield
1 x SparkFun 9 Degrees of Freedom - Sensor Stick
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x Thumb Joystick
1 x SparkFun Thumb Joystick Breakout
2 x Pololu DRV8834 Low-Voltage Stepper Motor Driver Carrier
2 x Electrolytic Decoupling Capacitors - 100uF/25V
2 x Pololu Stepper Motor Bipolar, 2.8V, 1.7 A/Phase
2 x Pololu Universal Aluminum Mounting Hub for 5mm Shaft, M3 Holes
1 x SparkFun Solderable Breadboard - Large
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Arduino
#include <Arduino.h>
// DRV8834 Stepper Motor Driver
#include <BasicStepperDriver.h>
#include <MultiDriver.h>
// Wire communicate with I2C / TWI devices
#include <Wire.h>
// SparkFun Micro OLED
#include <SFE_MicroOLED.h>
// Accelerometer
#include <ADXL345.h>
// Magnetometer
#include <HMC58X3.h>
// MEMS Gyroscope
#include <ITG3200.h>
// Debug
#include "DebugUtils.h"
// FreeIMU
#include <CommunicationUtils.h>
#include <FreeIMU.h>

// DRV8834 Stepper Motor Driver
// Stepper motor steps per revolution.
// Most steppers are 200 steps or 1.8 degrees/step
#define MOTOR_STEPS 200
// Target RPM for X axis stepper motor
#define MOTOR_X_RPM 800
// Target RPM for Y axis stepper motor
#define MOTOR_Y_RPM 800
// Since microstepping is set externally,
// make sure this matches the selected mode
// If it doesn't, the motor will move at a
// different RPM than chosen
// 1=full step, 2=half step etc.
#define MICROSTEPS 1
// X Stepper motor
#define DIR_X 7
#define STEP_X 8
// Y Stepper motor
#define DIR_Y 9
#define STEP_Y 10
// BasicStepperDriver
BasicStepperDriver stepperX(MOTOR_STEPS, DIR_X, STEP_X);
BasicStepperDriver stepperY(MOTOR_STEPS, DIR_Y, STEP_Y);
// Pick one of the two controllers below
// each motor moves independently
MultiDriver controller(stepperX, stepperY);

// Joystick
#define JH A0
#define JV A1
#define JS 2

// Variable for reading the button
int JSState = 0;
// Adjusted Value
int adjustedValue = 0;
int adjustedValue2 = 0;

// LED Yellow
int iLED = 13;

// SparkFun Micro OLED
#define PIN_RESET 9
#define DC_JUMPER 1
// I2C declaration
MicroOLED oled(PIN_RESET, DC_JUMPER);

// Set the FreeIMU object
FreeIMU my3IMU = FreeIMU();

// Yaw Pitch Roll
float ypr[3];
float Yaw = 0;
float Pitch = 0;
float Roll = 0;

// Software Version Information
String sver = "12-27";

void loop() {
  
  // Button
  isButton();

  // Joystick
  isThumbJoystick();
  
  // Stepper
  isStepper();

  // isFreeIMU
  isFreeIMU();

  // Micro OLED
  isMicroOLED();
 
}

getButton.ino

// Button
// Button Setup
void isButtonSetup() {
  
  // Make the button line an input
  pinMode(JS, INPUT_PULLUP);
  // Initialize digital pin iLED as an output
  pinMode(iLED, OUTPUT);
  
}

// Button
void isButton(){

  // Read the state of the button
  JSState = digitalRead(JS);

  // Check if the button is pressed.
  // If it is, the JSState is HIGH:
  if (JSState == HIGH) {
    
    // Button
    // Turn the LED on HIGH 
    digitalWrite(iLED, HIGH);
    
  } else {
    
    // Button
    // Turn the LED on LOW 
    digitalWrite(iLED, LOW);
    
  }

}

getFreeIMU.ino

// FreeIMU
// isFreeIMUSetup
void isFreeIMUSetup(){

  // Pause
  delay(5);
  // Initialize IMU
  my3IMU.init();
  // Pause
  delay(5);
  
}
// isFreeIMU
void isFreeIMU(){

  // FreeIMU
  // Yaw Pitch Roll
  my3IMU.getYawPitchRoll(ypr);
  // Yaw
  Yaw = ypr[0];
  // Pitch
  Pitch = ypr[1];
  // Roll
  Roll = ypr[2];

}

getMicroOLED.ino

// SparkFun Micro OLED
// Micro OLED Setup
void isMicroOLEDSetup() {

  // Initialize the OLED
  oled.begin();
  // Clear the display's internal memory
  oled.clear(ALL);
  // Display what's in the buffer (Splash Screen SparkFun)
  oled.display();

  // Delay 1000 ms
  delay(1000);

  // Clear the buffer.
  oled.clear(PAGE);
  
}
// Micro OLED
void isMicroOLED() {

  // Text Display FreeIMU
  // Clear the display
  oled.clear(PAGE);
  // Set cursor to top-left
  oled.setCursor(0, 0);
  // Set font to type 0
  oled.setFontType(0);
  // Horizontal
  oled.print("H: ");
  oled.print( adjustedValue );
  // Vertical
  oled.setCursor(0, 11);
  oled.print("V: ");
  oled.print( adjustedValue2 );
  // Yaw
  oled.setCursor(0, 21);
  oled.print("Y: ");
  oled.print(Yaw);
  // Pitch
  oled.setCursor(0, 31);
  oled.print("P: ");
  oled.print(Pitch);
  // Roll
  oled.setCursor(0, 41);
  oled.print("R: ");
  oled.print(Roll);
  oled.display();

}

getStepper.ino

// Stepper
// isStepperSetup
void isStepperSetup() {    
  
  // Set stepper target motors RPM.
  stepperX.begin(MOTOR_X_RPM, MICROSTEPS);
  stepperY.begin(MOTOR_Y_RPM, MICROSTEPS);

}
// Stepper
void isStepper() {

  // Stepper => Controller rotate
  controller.rotate(adjustedValue, adjustedValue2);
  
}

getThumbJoystick.ino

// Thumb Joystick
void isThumbJoystick() {

  // Joystick JH
  // Horizontal
  // Joystick Pot Values JH
  int potValue = analogRead(JH);
  int potValues = 0;
  // Adjusted Value
  potValues = map(potValue, 0, 1023, 1000, -1000);
  if (potValues > 300) {

    adjustedValue = potValues;

  } else if (potValues < -300) {

    adjustedValue = potValues;

  } else {

    adjustedValue = 0;

  }

  // Joystick JV
  // Vertical
  // Joystick Pot Values JV
  int potValue2 = analogRead(JV);
  int potValues2 = 0;
  // Adjusted Value2
  potValues2 = map(potValue2, 0, 1023, 1000, -1000);
  if (potValues2 > 300) {

    adjustedValue2 = potValues2;

  } else if (potValues2 < -300) {

    adjustedValue2 = potValues2;

  } else {

    adjustedValue2 = 0;

  }

}

setup.ino

// Setup
void setup()
{
  
  // Wire communicate with I2C / TWI devices
  Wire.begin();

  // Setup Micro OLED
  isMicroOLEDSetup();

  // isFreeIMUSetup
  isFreeIMUSetup();
   
  // Button Setup
  isButtonSetup();
  
  // DRV8834 Stepper Motor Driver
  isStepperSetup();

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Programming Language
  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Wireless (Radio Frequency, Bluetooth, WiFi, Etc…)
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Machine Learning
  • RTOS
  • Research & Development (R & D)

Instructor, E-Mentor, STEAM, and Arts-Based Training

  • Programming Language
  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

Luc Paquin – Curriculum Vitae – 2023
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/

Don Luc

Project #12: Robotics – Micro OLED – Mk26

——

#DonLucElectronics #DonLuc #Robotics #MicroOLED #AdafruitMETROM0Express #Arduino #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Micro OLED

——

Micro OLED

——

Micro OLED

——-

Micro OLED

Micro OLED displays are silicon-based OLED display that use a monocrystalline silicon wafer as the actively driven backplane, so it is easier to achieve high PPI (Pixel Density), a high degree of integration, and small size. This ensures they are easy to carry, have good anti-seismic performance, and have ultra-low power consumption.

DL2305Mk02

1 x Adafruit METRO M0 Express
1 x ProtoScrewShield
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x Thumb Joystick
1 x SparkFun Thumb Joystick Breakout
2 x Pololu DRV8834 Low-Voltage Stepper Motor Driver Carrier
2 x Electrolytic Decoupling Capacitors – 100uF/25V
2 x Pololu Stepper Motor Bipolar, 2.8V, 1.7 A/Phase
2 x Pololu Universal Aluminum Mounting Hub for 5mm Shaft, M3 Holes
1 x SparkFun Solderable Breadboard – Large
1 x SparkFun Cerberus USB Cable

Adafruit METRO M0 Express

SCL – Digital 21
SDA – Digital 20
JH – Analog A0
JV – Analog A1
JS – Digital 2
DIR – Digital 7
SPR – Digital 8
DIL – Digital 9
SPL – Digital 10
LED – Digital 13
VIN – +3.3V
VIN – +5V
GND – GND

——

DL2305Mk02p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #12: Robotics - Micro OLED - Mk26
12-26
DL2305Mk02p.ino
1 x Adafruit METRO M0 Express
1 x ProtoScrewShield
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x Thumb Joystick
1 x SparkFun Thumb Joystick Breakout
2 x Pololu DRV8834 Low-Voltage Stepper Motor Driver Carrier
2 x Electrolytic Decoupling Capacitors - 100uF/25V
2 x Pololu Stepper Motor Bipolar, 2.8V, 1.7 A/Phase
2 x Pololu Universal Aluminum Mounting Hub for 5mm Shaft, M3 Holes
1 x SparkFun Solderable Breadboard - Large
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Arduino
#include <Arduino.h>
// DRV8834 Stepper Motor Driver
#include <BasicStepperDriver.h>
#include <MultiDriver.h>
// Wire communicate with I2C / TWI devices
#include <Wire.h>
// SparkFun Micro OLED
#include <SFE_MicroOLED.h>

// DRV8834 Stepper Motor Driver
// Stepper motor steps per revolution.
// Most steppers are 200 steps or 1.8 degrees/step
#define MOTOR_STEPS 200
// Target RPM for X axis stepper motor
#define MOTOR_X_RPM 800
// Target RPM for Y axis stepper motor
#define MOTOR_Y_RPM 800
// Since microstepping is set externally,
// make sure this matches the selected mode
// If it doesn't, the motor will move at a
// different RPM than chosen
// 1=full step, 2=half step etc.
#define MICROSTEPS 1
// X Stepper motor
#define DIR_X 7
#define STEP_X 8
// Y Stepper motor
#define DIR_Y 9
#define STEP_Y 10
// BasicStepperDriver
BasicStepperDriver stepperX(MOTOR_STEPS, DIR_X, STEP_X);
BasicStepperDriver stepperY(MOTOR_STEPS, DIR_Y, STEP_Y);
// Pick one of the two controllers below
// each motor moves independently
MultiDriver controller(stepperX, stepperY);

// Joystick
#define JH A0
#define JV A1
#define JS 2

// Variable for reading the button
int JSState = 0;
// Adjusted Value
int adjustedValue = 0;
int adjustedValue2 = 0;

// LED Yellow
int iLED = 13;

// SparkFun Micro OLED
#define PIN_RESET 9
#define DC_JUMPER 1
// I2C declaration
MicroOLED oled(PIN_RESET, DC_JUMPER);

// Software Version Information
String sver = "12-26";

void loop() {
  
  // Button
  isButton();

  // Joystick
  isThumbJoystick();
  
  // Stepper
  isStepper();

  // Micro OLED
  isMicroOLED();
 
}

getButton.ino

// Button
// Button Setup
void isButtonSetup() {
  
  // Make the button line an input
  pinMode(JS, INPUT_PULLUP);
  // Initialize digital pin iLED as an output
  pinMode(iLED, OUTPUT);
  
}

// Button
void isButton(){

  // Read the state of the button
  JSState = digitalRead(JS);

  // Check if the button is pressed.
  // If it is, the JSState is HIGH:
  if (JSState == HIGH) {
    
    // Button
    // Turn the LED on HIGH 
    digitalWrite(iLED, HIGH);
    
  } else {
    
    // Button
    // Turn the LED on LOW 
    digitalWrite(iLED, LOW);
    
  }

}

getMicroOLED.ino

// SparkFun Micro OLED
// Setup Micro OLED
void isMicroOLEDSetup() {

  // Initialize the OLED
  oled.begin();
  // Clear the display's internal memory
  oled.clear(ALL);
  // Display what's in the buffer (Splash Screen SparkFun)
  oled.display();

  // Delay 1000 ms
  delay(1000);

  // Clear the buffer.
  oled.clear(PAGE);
  
}
// Micro OLED
void isMicroOLED() {

  // Text Display FreeIMU
  // Clear the display
  oled.clear(PAGE);
  // Set cursor to top-left
  oled.setCursor(0, 0);
  // Set font to type 0
  oled.setFontType(0);
  // Horizontal
  oled.print("Horizontal");
  // Horizontal
  oled.setCursor(0, 13);
  oled.print( adjustedValue );
  // Vertical
  oled.setCursor(0, 24);
  oled.print("Vertical");
  // Vertical
  oled.setCursor(0, 37);
  oled.print( adjustedValue2 );
  oled.display();

}

getStepper.ino

// Stepper
// isStepperSetup
void isStepperSetup() {    
  
  // Set stepper target motors RPM.
  stepperX.begin(MOTOR_X_RPM, MICROSTEPS);
  stepperY.begin(MOTOR_Y_RPM, MICROSTEPS);

}
// Stepper
void isStepper() {

  // Stepper => Controller rotate
  controller.rotate(adjustedValue, adjustedValue2);
  
}

getThumbJoystick.ino

// Thumb Joystick
void isThumbJoystick() {

  // Joystick JH
  // Horizontal
  // Joystick Pot Values JH
  int potValue = analogRead(JH);
  int potValues = 0;
  // Adjusted Value
  potValues = map(potValue, 0, 1023, 1000, -1000);
  if (potValues > 300) {

    adjustedValue = potValues;

  } else if (potValues < -300) {

    adjustedValue = potValues;

  } else {

    adjustedValue = 0;

  }

  // Joystick JV
  // Vertical
  // Joystick Pot Values JV
  int potValue2 = analogRead(JV);
  int potValues2 = 0;
  // Adjusted Value2
  potValues2 = map(potValue2, 0, 1023, 1000, -1000);
  if (potValues2 > 300) {

    adjustedValue2 = potValues2;

  } else if (potValues2 < -300) {

    adjustedValue2 = potValues2;

  } else {

    adjustedValue2 = 0;

  }

}

setup.ino

// Setup
void setup()
{
  
  // Wire communicate with I2C / TWI devices
  Wire.begin();

  // Setup Micro OLED
  isMicroOLEDSetup();
   
  // Button Setup
  isButtonSetup();
  
  // DRV8834 Stepper Motor Driver
  isStepperSetup();

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Programming Language
  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Wireless (Radio Frequency, Bluetooth, WiFi, Etc…)
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Machine Learning
  • RTOS
  • Research & Development (R & D)

Instructor, E-Mentor, STEAM, and Arts-Based Training

  • Programming Language
  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

Luc Paquin – Curriculum Vitae – 2023
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/

Don Luc

Project #16: Sound – SparkFun ProtoShield Kit – Mk23

——

#DonLucElectronics #DonLuc #Sound #Arduino #MicroOLED #ProtoShield #SparkFunQwiicMP3 #SparkFunRedBoardQwiic #Project #Programming #Electronics #Microcontrollers #Consultant

——

SparkFun ProtoShield Kit

——

SparkFun ProtoShield Kit

——

SparkFun ProtoShield Kit

——

SparkFun ProtoShield Kit

The SparkFun ProtoShield Kit lets you customize your own Arduino shield using whatever circuit you can come up with and then test it to make sure everything is working the way it should. The SparkFun ProtoShield Kit is based off the Arduino R3’s footprint that allows you to easily incorporate it with favorite Arduino-based device.

One of our favorite features with this version of the ProtoShield Kit is the solderable-like breadboard prototyping area. Half of this area was designed with a breadboard in mind. On the underside of the shield you will be able to see open jumper pads between each through hole to make a connection like a breadboard. Once you add a component, simply add a solder jumper between holes to make a connection. For those that prefer the standard prototyping pads.

DL2301Mk04

1 x SparkFun RedBoard Qwiic
1 x SparkFun ProtoShield Kit
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x SparkFun Qwiic MP3 Trigger
1 x microSD Card – 2GB
1 x Panel Mount 10K potentiometer
1 x Knob
2 x Rocker Switch – SPST (Round)
1 x Qwiic Cable – 50mm
1 x Qwiic Cable – 100mm
1 x Dayton Audio Reference 3″ Full-Range Drive
1 x SparkFun Cerberus USB Cable

——

SparkFun RedBoard Qwiic

PO1 – Analog A0
SDA – Analog A4
SCL – Analog A5
SW0 – Digital 8
SW1 – Digital 7
VIN – +5V
VIN – +3.3V
GND – GND

——

DL2301Mk04p.ino

/* ***** Don Luc Electronics © *****
Software Version Information
#16 - Sound - SparkFun ProtoShield Kit - Mk23
16-04
DL2301Mk04p.ino
1 x SparkFun RedBoard Qwiic
1 x SparkFun ProtoShield Kit
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x SparkFun Qwiic MP3 Trigger
1 x microSD Card - 2GB
1 x Panel Mount 10K potentiometer
1 x Knob
2 x Rocker Switch - SPST (Round)
1 x Qwiic Cable - 50mm
1 x Qwiic Cable - 100mm
1 x Dayton Audio Reference 3" Full-Range Drive
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// Wire communicate with I2C / TWI devices
#include <Wire.h>
// SparkFun MP3 Trigger
#include "SparkFun_Qwiic_MP3_Trigger_Arduino_Library.h"
// SparkFun Micro OLED
#include <SFE_MicroOLED.h>

// SparkFun MP3 Trigger
MP3TRIGGER mp3;
int iSongCount = 0;
int x = 0;

// Volume
int iVolume = A0;
int iVolumeLevel = 0;

// EQ Setting Normal
byte bEQSetting = 0;

// Play Next
const int iPlayNext = 8;
// Variable for reading the iPlayNext status
int iPlayNextState = 0;

// Play Previous
const int iPlayPrevious = 7;
// Variable for reading the iPlayPrevious status
int iPlayPreviousState = 0;

// SparkFun Micro OLED
#define PIN_RESET 9
#define DC_JUMPER 1
// I2C declaration
MicroOLED oled(PIN_RESET, DC_JUMPER);

// iLED ProtoShield
int iLED = 13;

// Software Version Information
String sver = "16-23";

void loop()
{
    
  // SparkFun MP3 Trigger
  if (mp3.isPlaying() == false) {

    if ( x > iSongCount ) {

      x = 0;
      
    } else {

      x = x + 1;
      
    }
    
    // Play Track
    mp3.playTrack( x );

  } else {

    // Volume
    isVolume();

    // Play Next
    isPlayNext();

    // Play Previous
    isPlayPrevious();

  }

  // Micro OLED
  isMicroOLED();
    
}

getMP3.ino

// MP3
// Setup MP3
void isSetupMP3(){

  // Check to see if Qwiic MP3 is present on the bus
  if (mp3.begin() == false)
  {
    
    // Qwiic MP3 failed to respond. Please check wiring and possibly the I2C address. Freezing...
    while (1);
    
  }

  if (mp3.hasCard() == false)
  {
    
    // Qwiic MP3 is missing its SD card. Freezing...
    while (1);
    
  }

  // Song Count
  iSongCount = mp3.getSongCount();

  // EQ Setting
  // 0 Normal
  // 1 Pop
  // 2 Rock
  // 3 Jazz
  // 4 Classic
  // 5 Bass
  bEQSetting = 5;
  bEQSetting = mp3.getEQ();

  // Initialize the iPlayNext
  pinMode( iPlayNext, INPUT);

  // Initialize the iPlayPrevious
  pinMode( iPlayPrevious, INPUT);

}
// Volume
void isVolume() {

  // Volume
  iVolumeLevel = analogRead( iVolume );
  // (0-1023 for 10 bits or 0-4095 for 12 bits)
  iVolumeLevel = map(iVolumeLevel, 0, 1023, 0, 10);

  // Volume can be 0 (off) to 31 (max)
  // Volume can be 0 (off) to 10 (Breakfast)
  mp3.setVolume( iVolumeLevel );
  
}
// Play Next
void isPlayNext() {

  // Read the state of the iPlayNext value
  iPlayNextState = digitalRead( iPlayNext );

  if ( iPlayNextState == HIGH ) {

    mp3.stop();
    
    if ( x > iSongCount ) {

      x = 0;
      
    } else {

      x = x + 1;
      
    }
    
    // Play Track
    mp3.playTrack( x );  
    
  } 

}
// Play Previous
void isPlayPrevious() {

  // Read the state of the iPlayPrevious value
  iPlayPreviousState = digitalRead( iPlayPrevious );

  if ( iPlayPreviousState == HIGH ) {

    mp3.stop();
    
    if ( x > iSongCount ) {

      x = 0;
      
    } else {

      x = x - 1;
      
    }
    
    // Play Track
    mp3.playTrack( x );
    
  } 

}

getMicroOLED.ino

// SparkFun Micro OLED
// Setup Micro OLED
void isSetupMicroOLED() {

  // Initialize the OLED
  oled.begin();
  // Clear the display's internal memory
  oled.clear(ALL);
  // Display what's in the buffer (splashscreen)
  oled.display();

  // Delay 1000 ms
  delay(1000);

  // Clear the buffer.
  oled.clear(PAGE);
  
}
// Micro OLED
void isMicroOLED() {

  // Text Display FreeIMU
  // Clear the display
  oled.clear(PAGE);
  // Set cursor to top-left
  oled.setCursor(0, 0);
  // Set font to type 0
  oled.setFontType(0);
  // Song
  oled.print("Song");
  // Song Name
  oled.setCursor(0, 13);
  String songName = mp3.getSongName();
  oled.print( songName );
  // Song Count
  oled.setCursor(0, 24);
  oled.print("Song Count");
  // Song Count
  oled.setCursor(0, 37);
  iSongCount = mp3.getSongCount();
  oled.print( iSongCount );
  oled.display();

}

setup.ino

// Setup
void setup()
{
   
  // Initialize digital pin iLED ProtoShield as an output
  pinMode(iLED, OUTPUT);
  // Turn the LED on (HIGH is the voltage level)
  digitalWrite(iLED, HIGH);
  
  // Wire communicate with I2C / TWI devices
  Wire.begin();

  // SparkFun MP3 Trigger Setup
  isSetupMP3();

  // Setup Micro OLED
  isSetupMicroOLED();

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Programming Language
  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Wireless (Radio Frequency, Bluetooth, WiFi, Etc…)
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Machine Learning
  • RTOS
  • Research & Development (R & D)

Instructor, E-Mentor, STEAM, and Arts-Based Training

  • Programming Language
  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

Luc Paquin – Curriculum Vitae – 2023
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/

Don Luc

Project #26 – Radio Frequency – GPS Receiver – Mk07

——

#DonLucElectronics #DonLuc #RadioFrequency #Moteino #Send #Receive #GPSReceiver #OpenLog #Display #FreeIMU #Magnetometer #Accelerometer #Gyroscope #Arduino #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

GPS Receiver

——

GPS Receiver

——

GPS Receiver

——

GPS Receiver – GP-20U7 (56 Channel)

The GP-20U7 is a compact GPS receiver with a built-in high performances all-in-one GPS chipset. The GP-20U7 accurately provides position, velocity, and time readings as well possessing high sensitivity and tracking capabilities. Thanks to the low power consumption this receiver requires, the GP-20U7 is ideal for portable applications such as tablet PCs, smart phones, and other devices requiring positioning capability.

This 56-channel GPS module, that supports a standard NMEA-0183 and uBlox 7 protocol, has low power consumption of 40mA@3.3V (Max), an antenna on board, and -162dBm tracking sensitivity. With 56 channels in search mode and 22 channels “All-In-View” tracking, the GP-20U7 is quite the work horse for its size.

DL2212Mk02

2 x Moteino R2 (RFM12B)
1 x GPS Receiver – GP-20U7 (56 Channel)
1 x SparkFun OpenLog
1 x microSD Card – 16GB
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x SparkFun 9 Degrees of Freedom – Sensor Stick
2 x Lithium Ion Battery – 1 Ah
1 x SparkFun Cerberus USB Cable

Moteino R2 (Receive)

TX0 – Digital 1
TR0 – Digital 2
LED – Digital 9
TR1 – Digital 10
TR2 – Digital 11
TR3 – Digital 12
TR4 – Digital 13
SDA – Analog A4
SCL – Analog A5
VIN – +3.3V
GND – GND

——

DL2212Mk02pr.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #26 - Radio Frequency - GPS Receiver - Mk07
26-07
Receive
DL2212Mk02pr.ino
2 x Moteino R2 (RFM12B)
1 x GPS Receiver - GP-20U7 (56 Channel)
1 x SparkFun OpenLog
1 x microSD Card - 16GB
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x SparkFun 9 Degrees of Freedom - Sensor Stick
2 x Lithium Ion Battery - 1Ah
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// RFM12B Radio
#include <RFM12B.h>
// Two Wire Interface (TWI/I2C)
#include <Wire.h>
// SparkFun Micro OLED
#include <SFE_MicroOLED.h>

// You will need to initialize the radio by telling it what ID
// it has and what network it's on
// The NodeID takes values from 1-127, 0 is reserved for sending 
// broadcast messages (send to all nodes)
// The Network ID takes values from 0-255
// By default the SPI-SS line used is D10 on Atmega328. 
// You can change it by calling .SetCS(pin) where pin can be {8,9,10}
// Network ID used for this unit
#define NODEID        1
// The network ID we are on
#define NETWORKID    99
// Serial
#define SERIAL_BAUD  115200

// Encryption is OPTIONAL
// to enable encryption you will need to:
// - provide a 16-byte encryption KEY (same on all nodes that talk encrypted)
// - to call .Encrypt(KEY) to start encrypting
// - to stop encrypting call .Encrypt(NULL)
uint8_t KEY[] = "ABCDABCDABCDABCD";

// Need an instance of the RFM12B Radio Module
RFM12B radio;

// Process Message
// Message
String msg = "";
int firstClosingBracket = 0;
// Yaw Pitch Roll
String sYaw = "";
String sPitch = "";
String sRoll = "";
float Yaw = 0;
float Pitch = 0;
float Roll = 0;

// LED
int iLED = 9;

// SparkFun Micro OLED
#define PIN_RESET 9
#define DC_JUMPER 1
// I2C declaration
MicroOLED oled(PIN_RESET, DC_JUMPER);

// Software Version Information
String sver = "26-07";

void loop() {

  // is RFM12B Radio
  isRFM12BRadio();

  // Micro OLED
  isMicroOLED();

}

getFreeIMU.ino

// FreeIMU
// isFreeIMU
void isFreeIMU(){

  // FreeIMU
  // msg = "<IMU|Yaw|Pitch|Roll|GPS Status|Latitude|Longitude|Date|Time|*"
  // msg = "<IMU|" + sYaw + "|" + sPitch + "|" + sRoll + "|" + GPSSt 
  // + "|" + TargetLat + "|" TargetLon + "|" + TargetDat +"|" + TargetTim + "|*"
  firstClosingBracket = 0;
  // "<IMU|"
  firstClosingBracket = msg.indexOf('|');
  msg.remove(0, 5);
  // Yaw
  firstClosingBracket = msg.indexOf('|');
  sYaw = msg;
  sYaw.remove(firstClosingBracket);
  Yaw = sYaw.toFloat();
  // Pitch
  firstClosingBracket = firstClosingBracket + 1;
  msg.remove(0, firstClosingBracket );  
  firstClosingBracket = msg.indexOf('|');
  sPitch = msg;
  sPitch.remove(firstClosingBracket);
  Pitch = sPitch.toFloat();
  // Roll
  firstClosingBracket = firstClosingBracket + 1;
  msg.remove(0, firstClosingBracket );  
  firstClosingBracket = msg.indexOf('|');
  sRoll = msg;
  sRoll.remove(firstClosingBracket);
  Roll = sRoll.toFloat();

}

getMicroOLED.ino

// SparkFun Micro OLED
// Setup Micro OLED
void isSetupMicroOLED() {

  // Initialize the OLED
  oled.begin();
  // Clear the display's internal memory
  oled.clear(ALL);
  // Display what's in the buffer (splashscreen)
  oled.display();

  // Delay 1000 ms
  delay(1000);

  // Clear the buffer.
  oled.clear(PAGE);
  
}
// Micro OLED
void isMicroOLED() {

  // Text Display FreeIMU
  // Clear the display
  oled.clear(PAGE);
  // Set cursor to top-left
  oled.setCursor(0, 0);
  // Set font to type 0
  oled.setFontType(0);
  // FreeIMU
  oled.print("FreeIMU");
  oled.setCursor(0, 12);
  // Yaw
  oled.print("Y: ");
  oled.print(Yaw);
  oled.setCursor(0, 25);
  // Pitch
  oled.print("P: ");
  oled.print(Pitch);
  oled.setCursor(0, 39);
  // Roll
  oled.print("R: ");
  oled.print(Roll);
  oled.display();

}

getRFM12BRadio.ino

// RFM12B Radio
void isSetupRFM12BRadio()
{

  // RFM12B Radio
  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
  // Encryption
  radio.Encrypt(KEY);
  // Transmitting
 
}
// is RFM12 BRadio
void isRFM12BRadio()
{

  // Receive
  if (radio.ReceiveComplete())
  {
    
    // CRC Pass
    if (radio.CRCPass())
    {
        
      // Message
      msg = "";
      
      // Can also use radio.GetDataLen() if you don't like pointers
      for (byte i = 0; i < *radio.DataLen; i++)
      {
        
       //Serial.print((char)radio.Data[i]);
        msg = msg + (char)radio.Data[i];
        
      }
      
      // Serial
      Serial.println( msg );
      
      // Turn the LED on HIGH
      digitalWrite( iLED , HIGH);
      
      // FreeIMU
      // Yaw Pitch Roll
      isFreeIMU();

      // ACK Requested
      if (radio.ACKRequested())
      {
        
        // Send ACK
        radio.SendACK();
        
      }

      // Turn the LED on LOW
      digitalWrite( iLED , LOW);
    
    }
    else
    {
      
      // BAD-CRC

    }

  } 
  
}

setup.ino

// Setup
void setup()
{

  // Serial
  Serial.begin(SERIAL_BAUD);

  // Give display time to power on
  delay(100);
  
  // Set up I2C bus
  Wire.begin();

  // Setup Micro OLED
  isSetupMicroOLED();

  // LED
  pinMode( iLED , OUTPUT);

  // RFM12B Radio
  isSetupRFM12BRadio();

}

——

Moteino R2 (Send)

TR0 – Digital 2
GPT – Digital 3
GPR – Digital 4
LED – Digital 9
TR1 – Digital 10
TR2 – Digital 11
TR3 – Digital 12
TR4 – Digital 13
SDA – Analog A4
SCL – Analog A5
VIN – +3.3V
GND – GND

——

DL2212Mk02ps.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #26 - Radio Frequency - GPS Receiver - Mk07
26-07
Send
DL2212Mk02ps.ino
2 x Moteino R2 (RFM12B)
1 x GPS Receiver - GP-20U7 (56 Channel)
1 x SparkFun OpenLog
1 x microSD Card - 16GB
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x SparkFun 9 Degrees of Freedom - Sensor Stick
2 x Lithium Ion Battery - 1Ah
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// RFM12B Radio
#include <RFM12B.h>
// Sleep
#include <avr/sleep.h>
// Two Wire Interface (TWI/I2C)
#include <Wire.h>
// Includes and variables for IMU integration
// Accelerometer
#include <ADXL345.h>
// Magnetometer
#include <HMC58X3.h>
// MEMS Gyroscope
#include <ITG3200.h>
// Debug
#include "DebugUtils.h"
// FreeIMU
#include <CommunicationUtils.h>
#include <FreeIMU.h>
// GPS Receiver
#include <TinyGPS++.h>
// Software Serial
#include <SoftwareSerial.h>

// You will need to initialize the radio by telling it what ID
// it has and what network it's on
// The NodeID takes values from 1-127, 0 is reserved for sending 
// broadcast messages (send to all nodes)
// The Network ID takes values from 0-255
// By default the SPI-SS line used is D10 on Atmega328. 
// You can change it by calling .SetCS(pin) where pin can be {8,9,10}
// Network ID used for this unit
#define NODEID        2
// The network ID we are on
#define NETWORKID    99
// The node ID we're sending to
#define GATEWAYID     1
// # of ms to wait for an ack
#define ACK_TIME     50
// Serial
#define SERIAL_BAUD  115200

// Encryption is OPTIONAL
// to enable encryption you will need to:
// - provide a 16-byte encryption KEY (same on all nodes that talk encrypted)
// - to call .Encrypt(KEY) to start encrypting
// - to stop encrypting call .Encrypt(NULL)
uint8_t KEY[] = "ABCDABCDABCDABCD";

// Wait this many ms between sending packets
int interPacketDelay = 1000;
// Input
char input = 0;

// Need an instance of the RFM12B Radio Module
RFM12B radio;
// Send Size
byte sendSize = 0;
// Payload
char payload[100];
// Request ACK
bool requestACK = false;

// LED
int iLED = 9;

// Set the FreeIMU object
FreeIMU my3IMU = FreeIMU();

// Yaw Pitch Roll
String zzzzzz = "";
String sYaw = "";
String sPitch = "";
String sRoll = "";
float ypr[3];
float Yaw = 0;
float Pitch = 0;
float Roll = 0;

// GPS Receiver
#define gpsRXPIN 4
// This one is unused and doesnt have a conection
#define gpsTXPIN 3
// The TinyGPS++ object
TinyGPSPlus gps;
// Latitude
float TargetLat;
String sLat = "";
// Longitude
float TargetLon;
String sLon = "";
// GPS Date, Time
// GPS Date
String TargetDat;
// GPS Time
String TargetTim;
// GPS Status
String GPSSt = "";

// The serial connection to the GPS device
SoftwareSerial tGPS(gpsRXPIN, gpsTXPIN);

// Software Version Information
String sver = "26-07";

void loop()
{

  // isGPS
  isGPS();
  
  // isFreeIMU
  isFreeIMU();

  // is RFM12B Radio
  isRFM12BRadio();

  // Inter Packet Delay
  delay(interPacketDelay);
  
}

getFreeIMU.ino

// FreeIMU
// isFreeIMU
void isFreeIMU(){

  // FreeIMU
  // Yaw Pitch Roll
  my3IMU.getYawPitchRoll(ypr);
  // Yaw
  Yaw = ypr[0];
  // Pitch
  Pitch = ypr[1];
  // Roll
  Roll = ypr[2];

}

getGPS.ino

// GPS Receiver
// Setup GPS
void setupGPS() {

  // Setup GPS
  tGPS.begin( 9600 );
  
}
// isGPS
void isGPS(){

  // Receives NEMA data from GPS receiver
  // This sketch displays information every time a new sentence is correctly encoded
  while ( tGPS.available() > 0)
    
    if (gps.encode( tGPS.read() ))
    {
     
       // GPS Vector Pointer Target
       displayInfo();
       // GPS Date, Time
       displayDTS();
       
    }
  
  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
   
     while(true);
    
  }

}
// GPS Vector Pointer Target
void displayInfo(){

  // Location
  if (gps.location.isValid())
  {
    
     // Latitude
     TargetLat = gps.location.lat();
     // Longitude
     TargetLon = gps.location.lng();
     // GPS Status 2
     GPSSt = "Yes";
    
  }
  else
  {

     // GPS Status 0
     GPSSt = "No";
    
  }

}
// GPS Date, Time
void displayDTS(){

  // Date
  TargetDat = ""; 
  if (gps.date.isValid())
  {
    
     // Date
     // Year
     TargetDat += String(gps.date.year(), DEC);
     TargetDat += "/";
     // Month
     TargetDat += String(gps.date.month(), DEC);
     TargetDat += "/";
     // Day
     TargetDat += String(gps.date.day(), DEC);
    
  }

  // Time
  TargetTim = "";
  if (gps.time.isValid())
  {
    
     // Time
     // Hour
     TargetTim += String(gps.time.hour(), DEC);
     TargetTim += ":";
     // Minute
     TargetTim += String(gps.time.minute(), DEC);
     TargetTim += ":";
     // Secound
     TargetTim += String(gps.time.second(), DEC);
    
  }

}

getRFM12BRadio.ino

// RFM12B Radio
void isSetupRFM12BRadio(){

  // RFM12B Radio
  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
  // Encryption
  radio.Encrypt(KEY);
  // Sleep right away to save power
  radio.Sleep();
  // Transmitting
  Serial.println("Transmitting...\n\n");
  
}
// is RFM12 BRadio
void isRFM12BRadio(){

  // sYaw, sPitch, sRoll ""
  sYaw = "";
  sPitch = "";
  sRoll = "";
  // Latitude and Longitude
  sLat = "";
  sLon = "";
  
  // sYaw, sPitch, sRoll concat
  sYaw.concat(Yaw);
  sPitch.concat(Pitch);
  sRoll.concat(Roll);

  // Latitude and Longitude
  sLat.concat( TargetLat );
  sLon.concat( TargetLon );

  // zzzzzz ""
  zzzzzz = "";

  // zzzzzz = "<IMU|Yaw|Pitch|Roll|GPS Status|Latitude|Longitude|Date|Time|*"
  // zzzzzz = "<IMU|" + sYaw + "|" + sPitch + "|" + sRoll + "|" + GPSSt 
  // + "|" + TargetLat + "|" TargetLon + "|" + TargetDat +"|" + TargetTim + "|*"
  zzzzzz = "<IMU|" + sYaw + "|" + sPitch + "|" + sRoll + "|" + GPSSt + "|" 
  + sLat + "|" + sLon + "|" + TargetDat + "|" + TargetTim + "|*";

  // sendSize Length
  sendSize = zzzzzz.length();

  // sendSize
  payload[sendSize];

  // sendSize, charAt
  for(byte i = 0; i < sendSize+1; i++){

    payload[i] = zzzzzz.charAt(i);
    
  }
    
  // payload
  Serial.print(payload);
  
  // Request ACK
  requestACK = sendSize;
  
  // Wakeup
  radio.Wakeup();
  
  // Turn the LED on HIGH
  digitalWrite( iLED , HIGH);
  
  // Send
  radio.Send(GATEWAYID, payload, sendSize, requestACK);

  // Request ACK
  if (requestACK)
  {
    
    Serial.print(" - waiting for ACK...");
    if (waitForAck()){
      
      Serial.print("Ok!");
      
    }
    else Serial.print("nothing...");
    
  }

  // Turn the LED on LOW
  digitalWrite( iLED , LOW);

  // Sleep
  radio.Sleep();

  // Serial
  Serial.println();
  
}
// Wait a few milliseconds for proper ACK, return true if received
static bool waitForAck(){
  
  // Now
  long now = millis();

  // ACK
  while (millis() - now <= ACK_TIME){
    

    if (radio.ACKReceived(GATEWAYID)){
      
      return true;

    }

  }
  
  return false;
  
}

setup.ino

// Setup
void setup(){

  // Serial
  Serial.begin(SERIAL_BAUD);

  // GPS Receiver
  // Setup GPS
  setupGPS();

  // LED
  pinMode( iLED , OUTPUT);

  // Set up I2C bus
  Wire.begin();

  // RFM12B Radio
  isSetupRFM12BRadio();

  // Pause
  delay(5);
  // Initialize IMU
  my3IMU.init();
  // Pause
  delay(5);

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Programming Language
  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Wireless (Radio Frequency, Bluetooth, WiFi, Etc…)
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Machine Learning
  • RTOS
  • Research & Development (R & D)

Instructor, E-Mentor, STEAM, and Arts-Based Training

  • Programming Language
  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

Luc Paquin – Curriculum Vitae – 2023
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/

Don Luc

Project #26 – Radio Frequency – OpenLog – Mk06

——

#DonLucElectronics #DonLuc #RadioFrequency #Moteino #Send #Receive #OpenLog #Display #FreeIMU #Magnetometer #Accelerometer #Gyroscope #Arduino #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

OpenLog

——

OpenLog

——

OpenLog

——

SparkFun OpenLog

The SparkFun OpenLog is an open source data logger that works over a simple serial connection and supports microSD cards up to 32GB. The OpenLog can store or “Log” huge amounts of serial data and act as a black box of sorts to store all the serial data that your project generates, for scientific or debugging purposes.

The SparkFun OpenLog uses an ATmega328 running at 16MHz thanks to the onboard resonator. The OpenLog draws approximately 2-3mA in idle mode. During a full record OpenLog can draw 10 to 20mA depending on the microSD card being used.

All data logged by the OpenLog is stored on the microSD card. Any 512MB to 32GB microSD card should work. OpenLog supports both FAT16 and FAT32 SD formats.

DL2212Mk01

2 x Moteino R2 (RFM12B)
1 x SparkFun OpenLog
1 x microSD Card – 16GB
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x SparkFun 9 Degrees of Freedom – Sensor Stick
2 x Lithium Ion Battery – 1 Ah
1 x SparkFun Cerberus USB Cable

Moteino R2 (Receive)

TX0 – Digital 1
TR0 – Digital 2
LED – Digital 9
TR1 – Digital 10
TR2 – Digital 11
TR3 – Digital 12
TR4 – Digital 13
SDA – Analog A4
SCL – Analog A5
VIN – +3.3V
GND – GND

——

DL2212Mk01pr.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #26 - Radio Frequency - OpenLog - Mk06
26-06
Receive
DL2212Mk01pr.ino
2 x Moteino R2 (RFM12B)
1 x SparkFun OpenLog
1 x microSD Card - 16GB
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x SparkFun 9 Degrees of Freedom - Sensor Stick
2 x Lithium Ion Battery - 1Ah
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// RFM12B Radio
#include <RFM12B.h>
// Two Wire Interface (TWI/I2C)
#include <Wire.h>
// SparkFun Micro OLED
#include <SFE_MicroOLED.h>

// You will need to initialize the radio by telling it what ID
// it has and what network it's on
// The NodeID takes values from 1-127, 0 is reserved for sending 
// broadcast messages (send to all nodes)
// The Network ID takes values from 0-255
// By default the SPI-SS line used is D10 on Atmega328. 
// You can change it by calling .SetCS(pin) where pin can be {8,9,10}
// Network ID used for this unit
#define NODEID        1
// The network ID we are on
#define NETWORKID    99
// Serial
#define SERIAL_BAUD  115200

// Encryption is OPTIONAL
// to enable encryption you will need to:
// - provide a 16-byte encryption KEY (same on all nodes that talk encrypted)
// - to call .Encrypt(KEY) to start encrypting
// - to stop encrypting call .Encrypt(NULL)
uint8_t KEY[] = "ABCDABCDABCDABCD";

// Need an instance of the RFM12B Radio Module
RFM12B radio;

// Process Message
// Message
String msg = "";
int firstClosingBracket = 0;
// Yaw Pitch Roll
String sYaw = "";
String sPitch = "";
String sRoll = "";
float Yaw = 0;
float Pitch = 0;
float Roll = 0;

// LED
int iLED = 9;

// SparkFun Micro OLED
#define PIN_RESET 9
#define DC_JUMPER 1
// I2C declaration
MicroOLED oled(PIN_RESET, DC_JUMPER);

// Software Version Information
String sver = "26-06";

void loop() {

  // is RFM12B Radio
  isRFM12BRadio();

  // Micro OLED
  isMicroOLED();

}

getFreeIMU.ino

// FreeIMU
// isFreeIMU
void isFreeIMU(){

  // FreeIMU
  // IMU Yaw Pitch Roll
  // msg = "<IMU|1000|1000|1000|*";
  // msg = "<IMU|" + sYaw + "|" + sPitch + "|" + sRoll + "|*"
  firstClosingBracket = 0;
  // "<IMU|"
  firstClosingBracket = msg.indexOf('|');
  msg.remove(0, 5);
  // Yaw
  firstClosingBracket = msg.indexOf('|');
  sYaw = msg;
  sYaw.remove(firstClosingBracket);
  Yaw = sYaw.toFloat();
  // Pitch
  firstClosingBracket = firstClosingBracket + 1;
  msg.remove(0, firstClosingBracket );  
  firstClosingBracket = msg.indexOf('|');
  sPitch = msg;
  sPitch.remove(firstClosingBracket);
  Pitch = sPitch.toFloat();
  // Roll
  firstClosingBracket = firstClosingBracket + 1;
  msg.remove(0, firstClosingBracket );  
  firstClosingBracket = msg.indexOf('|');
  sRoll = msg;
  sRoll.remove(firstClosingBracket);
  Roll = sRoll.toFloat();

}

getMicroOLED.ino

// SparkFun Micro OLED
// Setup Micro OLED
void isSetupMicroOLED() {

  // Initialize the OLED
  oled.begin();
  // Clear the display's internal memory
  oled.clear(ALL);
  // Display what's in the buffer (splashscreen)
  oled.display();

  // Delay 1000 ms
  delay(1000);

  // Clear the buffer.
  oled.clear(PAGE);
  
}
// Micro OLED
void isMicroOLED() {

  // Text Display FreeIMU
  // Clear the display
  oled.clear(PAGE);
  // Set cursor to top-left
  oled.setCursor(0, 0);
  // Set font to type 0
  oled.setFontType(0);
  // FreeIMU
  oled.print("FreeIMU");
  oled.setCursor(0, 12);
  // Yaw
  oled.print("Y: ");
  oled.print(Yaw);
  oled.setCursor(0, 25);
  // Pitch
  oled.print("P: ");
  oled.print(Pitch);
  oled.setCursor(0, 39);
  // Roll
  oled.print("R: ");
  oled.print(Roll);
  oled.display();

}

getRFM12BRadio.ino

// RFM12B Radio
void isSetupRFM12BRadio()
{

  // RFM12B Radio
  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
  // Encryption
  radio.Encrypt(KEY);
  // Transmitting
 
}
// is RFM12 BRadio
void isRFM12BRadio()
{

  // Receive
  if (radio.ReceiveComplete())
  {
    
    // CRC Pass
    if (radio.CRCPass())
    {
        
      // Message
      msg = "";
      
      // Can also use radio.GetDataLen() if you don't like pointers
      for (byte i = 0; i < *radio.DataLen; i++)
      {
        
       //Serial.print((char)radio.Data[i]);
        msg = msg + (char)radio.Data[i];
        
      }
      
      // Serial
      Serial.println( msg );
      
      // Turn the LED on HIGH
      digitalWrite( iLED , HIGH);
      
      // FreeIMU
      // Yaw Pitch Roll
      isFreeIMU();
  
      // ACK Requested
      if (radio.ACKRequested())
      {
        
        // Send ACK
        radio.SendACK();
        
      }

      // Turn the LED on LOW
      digitalWrite( iLED , LOW);
    
    }
    else
    {
      
      // BAD-CRC

    }

  } 
  
}

setup.ino

// Setup
void setup()
{

  // Serial
  Serial.begin(SERIAL_BAUD);

  // Give display time to power on
  delay(100);
  
  // Set up I2C bus
  Wire.begin();

  // Setup Micro OLED
  isSetupMicroOLED();

  // LED
  pinMode( iLED , OUTPUT);

  // RFM12B Radio
  isSetupRFM12BRadio();

}

——

Moteino R2 (Send)

TR0 – Digital 2
LED – Digital 9
TR1 – Digital 10
TR2 – Digital 11
TR3 – Digital 12
TR4 – Digital 13
SDA – Analog A4
SCL – Analog A5
VIN – +3.3V
GND – GND

——

DL2212Mk01ps.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #26 - Radio Frequency - OpenLog - Mk06
26-06
Send
DL2212Mk01ps.ino
2 x Moteino R2 (RFM12B)
1 x SparkFun OpenLog
1 x microSD Card - 16GB
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x SparkFun 9 Degrees of Freedom - Sensor Stick
2 x Lithium Ion Battery - 1Ah
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// RFM12B Radio
#include <RFM12B.h>
// Sleep
#include <avr/sleep.h>
// Two Wire Interface (TWI/I2C)
#include <Wire.h>
// Includes and variables for IMU integration
// Accelerometer
#include <ADXL345.h>
// Magnetometer
#include <HMC58X3.h>
// MEMS Gyroscope
#include <ITG3200.h>
// Debug
#include "DebugUtils.h"
// FreeIMU
#include <CommunicationUtils.h>
#include <FreeIMU.h>

// You will need to initialize the radio by telling it what ID
// it has and what network it's on
// The NodeID takes values from 1-127, 0 is reserved for sending 
// broadcast messages (send to all nodes)
// The Network ID takes values from 0-255
// By default the SPI-SS line used is D10 on Atmega328. 
// You can change it by calling .SetCS(pin) where pin can be {8,9,10}
// Network ID used for this unit
#define NODEID        2
// The network ID we are on
#define NETWORKID    99
// The node ID we're sending to
#define GATEWAYID     1
// # of ms to wait for an ack
#define ACK_TIME     50
// Serial
#define SERIAL_BAUD  115200

// Encryption is OPTIONAL
// to enable encryption you will need to:
// - provide a 16-byte encryption KEY (same on all nodes that talk encrypted)
// - to call .Encrypt(KEY) to start encrypting
// - to stop encrypting call .Encrypt(NULL)
uint8_t KEY[] = "ABCDABCDABCDABCD";

// Wait this many ms between sending packets
int interPacketDelay = 1000;
// Input
char input = 0;

// Need an instance of the RFM12B Radio Module
RFM12B radio;
// Send Size
byte sendSize = 0;
// Payload
char payload[100];
// Request ACK
bool requestACK = false;

// LED
int iLED = 9;

// Set the FreeIMU object
FreeIMU my3IMU = FreeIMU();

// Yaw Pitch Roll
String zzzzzz = "";
String sYaw = "";
String sPitch = "";
String sRoll = "";
float ypr[3];
float Yaw = 0;
float Pitch = 0;
float Roll = 0;

// Software Version Information
String sver = "26-06";

void loop()
{

  // isFreeIMU
  isFreeIMU();

  // is RFM12B Radio
  isRFM12BRadio();

  // Inter Packet Delay
  delay(interPacketDelay);
  
}

getFreeIMU.ino

// FreeIMU
// isFreeIMU
void isFreeIMU(){

  // FreeIMU
  // Yaw Pitch Roll
  my3IMU.getYawPitchRoll(ypr);
  // Yaw
  Yaw = ypr[0];
  // Pitch
  Pitch = ypr[1];
  // Roll
  Roll = ypr[2];

}

getRFM12BRadio.ino

// RFM12B Radio
void isSetupRFM12BRadio(){

  // RFM12B Radio
  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
  // Encryption
  radio.Encrypt(KEY);
  // Sleep right away to save power
  radio.Sleep();
  // Transmitting
  Serial.println("Transmitting...\n\n");
  
}
// is RFM12 BRadio
void isRFM12BRadio(){

  // sYaw, sPitch, sRoll ""
  sYaw = "";
  sPitch = "";
  sRoll = "";

  // sYaw, sPitch, sRoll concat
  sYaw.concat(Yaw);
  sPitch.concat(Pitch);
  sRoll.concat(Roll);

  // zzzzzz ""
  zzzzzz = "";

  // zzzzzz = "<IMU|1000|1000|1000|*";
  // zzzzzz = "<IMU|" + sYaw + "|" + sPitch + "|" + sRoll + "|*"
  zzzzzz = "<IMU|" + sYaw + "|" + sPitch + "|" + sRoll + "|*";

  // sendSize Length
  sendSize = zzzzzz.length();

  // sendSize
  payload[sendSize];

  // sendSize, charAt
  for(byte i = 0; i < sendSize+1; i++){

    payload[i] = zzzzzz.charAt(i);
    
  }
    
  // payload
  Serial.print(payload);
  
  // Request ACK
  requestACK = sendSize;
  
  // Wakeup
  radio.Wakeup();
  
  // Turn the LED on HIGH
  digitalWrite( iLED , HIGH);
  
  // Send
  radio.Send(GATEWAYID, payload, sendSize, requestACK);

  // Request ACK
  if (requestACK)
  {
    
    Serial.print(" - waiting for ACK...");
    if (waitForAck()){
      
      Serial.print("Ok!");
      
    }
    else Serial.print("nothing...");
    
  }

  // Turn the LED on LOW
  digitalWrite( iLED , LOW);

  // Sleep
  radio.Sleep();

  // Serial
  Serial.println();
  
}
// Wait a few milliseconds for proper ACK, return true if received
static bool waitForAck(){
  
  // Now
  long now = millis();

  // ACK
  while (millis() - now <= ACK_TIME){
    

    if (radio.ACKReceived(GATEWAYID)){
      
      return true;

    }

  }
  
  return false;
  
}

setup.ino

// Setup
void setup(){

  // Serial
  Serial.begin(SERIAL_BAUD);

  // LED
  pinMode( iLED , OUTPUT);

  // Set up I2C bus
  Wire.begin();

  // RFM12B Radio
  isSetupRFM12BRadio();

  // Pause
  delay(5);
  // Initialize IMU
  my3IMU.init();
  // Pause
  delay(5);

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Programming Language
  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Wireless (Radio Frequency, Bluetooth, WiFi, Etc…)
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Machine Learning
  • RTOS
  • Research & Development (R & D)

Instructor, E-Mentor, STEAM, and Arts-Based Training

  • Programming Language
  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

Luc Paquin – Curriculum Vitae – 2023
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/

Don Luc

Project #26 – Radio Frequency – Display – Mk05

——

#DonLucElectronics #DonLuc #RadioFrequency #Moteino #Send #Receive #Display #FreeIMU #Magnetometer #Accelerometer #Gyroscope #Arduino #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

Display

——

Display

——

Display

——

SparkFun Micro OLED Breakout

The SparkFun Qwiic Micro OLED Breakout is a Qwiic-enabled version of our popular Micro OLED display. The small monochrome, blue-on-black OLED screen presents incredibly clear images for your viewing pleasure. It’s the OLED display is crisp, and you can fit a deceivingly large amount of graphics on there. This breakout is perfect for adding graphics to your next project and displaying diagnostic information without resorting to a serial output, all with the ease of use of our own Qwiic Connect System.

This version of the Micro OLED Breakout is exactly the size of its non-Qwiic sibling, featuring a screen that is 64 pixels wide and 48 pixels tall and measuring 0.66″ across. But it has also been equipped with two Qwiic connectors, making it ideal for I2C operations. We’ve also added two mounting holes and a convenient Qwiic cable holder incorporated into a detachable tab on the board that can be easily removed thanks to a v-scored edge.

DL2211Mk09

2 x Moteino R2 (RFM12B)
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x SparkFun 9 Degrees of Freedom – Sensor Stick
2 x Lithium Ion Battery – 1 Ah
1 x SparkFun Cerberus USB Cable

Moteino R2 (Receive)

TR0 – Digital 2
LED – Digital 9
TR1 – Digital 10
TR2 – Digital 11
TR3 – Digital 12
TR4 – Digital 13
SDA – Analog A4
SCL – Analog A5
VIN – +3.3V
GND – GND

——

DL2211Mk09pr.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #26 - Radio Frequency - Display - Mk05
26-05
Receive
DL2211Mk09pr.ino
2 x Moteino R2 (RFM12B)
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x SparkFun 9 Degrees of Freedom - Sensor Stick
2 x Lithium Ion Battery - 1Ah
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// RFM12B Radio
#include <RFM12B.h>
// Two Wire Interface (TWI/I2C)
#include <Wire.h>
// SparkFun Micro OLED
#include <SFE_MicroOLED.h>

// You will need to initialize the radio by telling it what ID
// it has and what network it's on
// The NodeID takes values from 1-127, 0 is reserved for sending 
// broadcast messages (send to all nodes)
// The Network ID takes values from 0-255
// By default the SPI-SS line used is D10 on Atmega328. 
// You can change it by calling .SetCS(pin) where pin can be {8,9,10}
// Network ID used for this unit
#define NODEID        1
// The network ID we are on
#define NETWORKID    99
// Serial
#define SERIAL_BAUD  115200

// Encryption is OPTIONAL
// to enable encryption you will need to:
// - provide a 16-byte encryption KEY (same on all nodes that talk encrypted)
// - to call .Encrypt(KEY) to start encrypting
// - to stop encrypting call .Encrypt(NULL)
uint8_t KEY[] = "ABCDABCDABCDABCD";

// Need an instance of the RFM12B Radio Module
RFM12B radio;

// Process Message
// Message
String msg = "";
int firstClosingBracket = 0;
// Yaw Pitch Roll
String sYaw = "";
String sPitch = "";
String sRoll = "";
float Yaw = 0;
float Pitch = 0;
float Roll = 0;

// LED
int iLED = 9;

// SparkFun Micro OLED
#define PIN_RESET 9
#define DC_JUMPER 1
// I2C declaration
MicroOLED oled(PIN_RESET, DC_JUMPER);

// Software Version Information
String sver = "26-05";

void loop() {

  // is RFM12B Radio
  isRFM12BRadio();

  // Micro OLED
  isMicroOLED();

}

getFreeIMU.ino

// FreeIMU
// isFreeIMU
void isFreeIMU(){

  // FreeIMU
  // IMU Yaw Pitch Roll
  // msg = "<IMU|1000|1000|1000|*";
  // msg = "<IMU|" + sYaw + "|" + sPitch + "|" + sRoll + "|*"
  firstClosingBracket = 0;
  // "<IMU|"
  firstClosingBracket = msg.indexOf('|');
  msg.remove(0, 5);
  // Yaw
  firstClosingBracket = msg.indexOf('|');
  sYaw = msg;
  sYaw.remove(firstClosingBracket);
  Yaw = sYaw.toFloat();
  // Pitch
  firstClosingBracket = firstClosingBracket + 1;
  msg.remove(0, firstClosingBracket );  
  firstClosingBracket = msg.indexOf('|');
  sPitch = msg;
  sPitch.remove(firstClosingBracket);
  Pitch = sPitch.toFloat();
  // Roll
  firstClosingBracket = firstClosingBracket + 1;
  msg.remove(0, firstClosingBracket );  
  firstClosingBracket = msg.indexOf('|');
  sRoll = msg;
  sRoll.remove(firstClosingBracket);
  Roll = sRoll.toFloat();

}

getMicroOLED.ino

// SparkFun Micro OLED
// Setup Micro OLED
void isSetupMicroOLED() {

  // Initialize the OLED
  oled.begin();
  // Clear the display's internal memory
  oled.clear(ALL);
  // Display what's in the buffer (splashscreen)
  oled.display();

  // Delay 1000 ms
  delay(1000);

  // Clear the buffer.
  oled.clear(PAGE);
  
}
// Micro OLED
void isMicroOLED() {

  // Text Display FreeIMU
  // Clear the display
  oled.clear(PAGE);
  // Set cursor to top-left
  oled.setCursor(0, 0);
  // Set font to type 0
  oled.setFontType(0);
  // FreeIMU
  oled.print("FreeIMU");
  oled.setCursor(0, 12);
  // Yaw
  oled.print("Y: ");
  oled.print(Yaw);
  oled.setCursor(0, 25);
  // Pitch
  oled.print("P: ");
  oled.print(Pitch);
  oled.setCursor(0, 39);
  // Roll
  oled.print("R: ");
  oled.print(Roll);
  oled.display();

}

getRFM12BRadio.ino

// RFM12B Radio
void isSetupRFM12BRadio()
{

  // RFM12B Radio
  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
  // Encryption
  radio.Encrypt(KEY);
  // Transmitting
  Serial.println("Listening...");
  
}
// is RFM12 BRadio
void isRFM12BRadio()
{

  // Receive
  if (radio.ReceiveComplete())
  {
    
    // CRC Pass
    if (radio.CRCPass())
    {
      
      // Serial
      Serial.print('[');
      Serial.print(radio.GetSender());
      Serial.print("] ");
      
      // Message
      msg = "";
      
      // Can also use radio.GetDataLen() if you don't like pointers
      for (byte i = 0; i < *radio.DataLen; i++)
      {
        
        Serial.print((char)radio.Data[i]);
        msg = msg + (char)radio.Data[i];
        
      }

      // Turn the LED on HIGH
      digitalWrite( iLED , HIGH);
      
      // FreeIMU
      // Yaw Pitch Roll
      isFreeIMU();
  
      // ACK Requested
      if (radio.ACKRequested())
      {
        
        // Send ACK
        radio.SendACK();
        Serial.print(" - ACK Sent");
        
      }

      // Turn the LED on LOW
      digitalWrite( iLED , LOW);
    
    }
    else
    {
      
      // BAD-CRC
      Serial.print("BAD-CRC");

    }

    // Serial
    Serial.println();

  } 
  
}

setup.ino

// Setup
void setup()
{

  // Serial
  Serial.begin(SERIAL_BAUD);

  // Give display time to power on
  delay(100);
  
  // Set up I2C bus
  Wire.begin();

  // Setup Micro OLED
  isSetupMicroOLED();

  // LED
  pinMode( iLED , OUTPUT);

  // RFM12B Radio
  isSetupRFM12BRadio();

}

——

Moteino R2 (Send)

TR0 – Digital 2
LED – Digital 9
TR1 – Digital 10
TR2 – Digital 11
TR3 – Digital 12
TR4 – Digital 13
SDA – Analog A4
SCL – Analog A5
VIN – +3.3V
GND – GND

——

DL2211Mk09ps.ino

/* ***** Don Luc Electronics © *****
Software Version Information
Project #26 - Radio Frequency - Display - Mk05
26-05
Send
DL2211Mk09ps.ino
2 x Moteino R2 (RFM12B)
1 x SparkFun Micro OLED Breakout (Qwiic)
1 x SparkFun 9 Degrees of Freedom - Sensor Stick
2 x Lithium Ion Battery - 1Ah
1 x SparkFun Cerberus USB Cable
*/

// Include the Library Code
// RFM12B Radio
#include <RFM12B.h>
// Sleep
#include <avr/sleep.h>
// Two Wire Interface (TWI/I2C)
#include <Wire.h>
// Includes and variables for IMU integration
// Accelerometer
#include <ADXL345.h>
// Magnetometer
#include <HMC58X3.h>
// MEMS Gyroscope
#include <ITG3200.h>
// Debug
#include "DebugUtils.h"
// FreeIMU
#include <CommunicationUtils.h>
#include <FreeIMU.h>

// You will need to initialize the radio by telling it what ID
// it has and what network it's on
// The NodeID takes values from 1-127, 0 is reserved for sending 
// broadcast messages (send to all nodes)
// The Network ID takes values from 0-255
// By default the SPI-SS line used is D10 on Atmega328. 
// You can change it by calling .SetCS(pin) where pin can be {8,9,10}
// Network ID used for this unit
#define NODEID        2
// The network ID we are on
#define NETWORKID    99
// The node ID we're sending to
#define GATEWAYID     1
// # of ms to wait for an ack
#define ACK_TIME     50
// Serial
#define SERIAL_BAUD  115200

// Encryption is OPTIONAL
// to enable encryption you will need to:
// - provide a 16-byte encryption KEY (same on all nodes that talk encrypted)
// - to call .Encrypt(KEY) to start encrypting
// - to stop encrypting call .Encrypt(NULL)
uint8_t KEY[] = "ABCDABCDABCDABCD";

// Wait this many ms between sending packets
int interPacketDelay = 1000;
// Input
char input = 0;

// Need an instance of the RFM12B Radio Module
RFM12B radio;
// Send Size
byte sendSize = 0;
// Payload
char payload[100];
// Request ACK
bool requestACK = false;

// LED
int iLED = 9;

// Set the FreeIMU object
FreeIMU my3IMU = FreeIMU();

// Yaw Pitch Roll
String zzzzzz = "";
String sYaw = "";
String sPitch = "";
String sRoll = "";
float ypr[3];
float Yaw = 0;
float Pitch = 0;
float Roll = 0;

// Software Version Information
String sver = "26-05";

void loop()
{

  // isFreeIMU
  isFreeIMU();

  // is RFM12B Radio
  isRFM12BRadio();

  // Inter Packet Delay
  delay(interPacketDelay);
  
}

getFreeIMU.ino

// FreeIMU
// isFreeIMU
void isFreeIMU(){

  // FreeIMU
  // Yaw Pitch Roll
  my3IMU.getYawPitchRoll(ypr);
  // Yaw
  Yaw = ypr[0];
  // Pitch
  Pitch = ypr[1];
  // Roll
  Roll = ypr[2];

}

getRFM12BRadio.ino

// RFM12B Radio
void isSetupRFM12BRadio(){

  // RFM12B Radio
  radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
  // Encryption
  radio.Encrypt(KEY);
  // Sleep right away to save power
  radio.Sleep();
  // Transmitting
  Serial.println("Transmitting...\n\n");
  
}
// is RFM12 BRadio
void isRFM12BRadio(){

  // sYaw, sPitch, sRoll ""
  sYaw = "";
  sPitch = "";
  sRoll = "";

  // sYaw, sPitch, sRoll concat
  sYaw.concat(Yaw);
  sPitch.concat(Pitch);
  sRoll.concat(Roll);

  // zzzzzz ""
  zzzzzz = "";

  // zzzzzz = "<IMU|1000|1000|1000|*";
  // zzzzzz = "<IMU|" + sYaw + "|" + sPitch + "|" + sRoll + "|*"
  zzzzzz = "<IMU|" + sYaw + "|" + sPitch + "|" + sRoll + "|*";

  // sendSize Length
  sendSize = zzzzzz.length();

  // sendSize
  payload[sendSize];

  // sendSize, charAt
  for(byte i = 0; i < sendSize+1; i++){

    payload[i] = zzzzzz.charAt(i);
    
  }
    
  // payload
  Serial.print(payload);
  
  // Request ACK
  requestACK = sendSize;
  
  // Wakeup
  radio.Wakeup();
  
  // Turn the LED on HIGH
  digitalWrite( iLED , HIGH);
  
  // Send
  radio.Send(GATEWAYID, payload, sendSize, requestACK);

  // Request ACK
  if (requestACK)
  {
    
    Serial.print(" - waiting for ACK...");
    if (waitForAck()){
      
      Serial.print("Ok!");
      
    }
    else Serial.print("nothing...");
    
  }

  // Turn the LED on LOW
  digitalWrite( iLED , LOW);

  // Sleep
  radio.Sleep();

  // Serial
  Serial.println();
  
}
// Wait a few milliseconds for proper ACK, return true if received
static bool waitForAck(){
  
  // Now
  long now = millis();

  // ACK
  while (millis() - now <= ACK_TIME){
    

    if (radio.ACKReceived(GATEWAYID)){
      
      return true;

    }

  }
  
  return false;
  
}

setup.ino

// Setup
void setup(){

  // Serial
  Serial.begin(SERIAL_BAUD);

  // LED
  pinMode( iLED , OUTPUT);

  // Set up I2C bus
  Wire.begin();

  // RFM12B Radio
  isSetupRFM12BRadio();

  // Pause
  delay(5);
  // Initialize IMU
  my3IMU.init();
  // Pause
  delay(5);

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Technology Experience

  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi,Espressif, etc…)
  • IoT
  • Wireless (Radio Frequency, Bluetooth, WiFi, Etc…)
  • Robotics
  • Camera and Video Capture Receiver Stationary, Wheel/Tank and Underwater Vehicle
  • Unmanned Vehicles Terrestrial and Marine
  • Machine Learning
  • RTOS
  • Research & Development (R & D)

Instructor, E-Mentor, STEAM, and Arts-Based Training

  • IoT
  • PIC Microcontrollers
  • Arduino
  • Raspberry Pi
  • Espressif
  • Robotics

Follow Us

Luc Paquin – Curriculum Vitae – 2023
https://www.donluc.com/luc/

Web: https://www.donluc.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/channel/UC5eRjrGn1CqkkGfZy0jxEdA
Twitter: https://twitter.com/labs_steam
Pinterest: https://www.pinterest.com/NeoSteamLabs/
Instagram: https://www.instagram.com/neosteamlabs/

Don Luc

1 2 3 7
Categories
Archives